TowardsDataScience-博客中文翻译-2016-2018-二十四-

TowardsDataScience 博客中文翻译 2016~2018(二十四)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

独立于语言的文档聚类

原文:https://towardsdatascience.com/language-independent-document-clustering-3907dafb32fd?source=collection_archive---------6-----------------------

我探索了一种新颖的独立于语言的文档聚类方法。关键是,它适用于任何语言的任何文本。数据发生变化时,过程保持不变。

让我用要点来说明这种方法:

  1. 从可用数据中构建单词向量。
  2. 建立文档词向量的词簇。
  3. 找出最能代表文档的聚类。
  4. 聚集这些集群(相似的集群聚集在一起)。
  5. 具有相似簇的文档放在一起。

现在,我们将浏览流程和代码。我们将从创建单词向量开始。在那之前

在自然语言处理(NLP)中,90%的工作是预处理——某研究人员

因此,请确保您对数据做了所有需要做的预处理。因为这是一个概念验证,所以我排除了进行预处理的部分。

我们将使用 gensim python 包来构建单词向量。下面的函数创建向量,并以二进制格式保存它们。

# Create wordvectors
def create_vectors(filename):
    sentences = []
    with bz2.open(filename, 'rt') as df:
        for l in df:
            sentences.append(" ".join(l.split(",")).split())
    model = Word2Vec(sentences, size=25, window=5, min_count=1, workers=4)
    model.save(r"filename.vec") # Line changed refer code on github
    return model

一旦单词向量准备好了,我们就可以进入下一步,这是一个非常有趣的步骤。我从博客这里偷来的。它非常简单而且有效!

假设我们有一个包含 n 个单词的文档。我们将从第一个单词开始,并在模型中查找该单词的向量(单词向量),该向量进入一个聚类,然后向前移动,我们以概率 1/(1+n)将该单词分配给预先创建的聚类或新的聚类。如果我们决定分配给一个现有的聚类,我们就把这个词分配给最相似的聚类。这种方法创建的簇或多或少地将单词分成有意义的组,请看。

Language Independent Document Clustering

更多例子在本笔记本这里

以下函数是上述算法的实现,也称为中餐厅流程。

Python Implementation of CRP

我已经把代码放在 github 上了,还有一个附带的笔记本,你可以看看。https://github.com/kaustubhn/doc_clust

丰富

对上述算法的几点改进建议。

  1. 更多数据
  2. 更好的预处理
  3. 多维向量(我们使用 25 维)
  4. 匹配聚类的更好方法(除了余弦方法)

注意:这是一个非常实验性的方法,到目前为止还有很多不清楚和不明确的地方,我会继续改进和完善这个方法。感谢您的评论。

要取得联系,请发微博给我,地址是 kaustubhn

使用 Spark 进行大规模图挖掘:第 1 部分

原文:https://towardsdatascience.com/large-scale-graph-mining-with-spark-750995050656?source=collection_archive---------5-----------------------

本教程分为两部分:

Part 1 (你来了!):无监督学习的图。

第二部 (点击此处) :如何施展神奇的图形力量。我们将讨论标签传播、火花图框架和结果。回购与样本图和笔记本在这里:https://github.com/wsuen/pygotham2018_graphmining

我也将在 PyGotham 2018 上就这个话题发表演讲。😃

如果您是一名工程师,您很可能使用过图形数据结构来实现搜索和查找算法。你也用它们来解决机器学习问题吗?

你为什么关注图表

对于数据科学家来说,图表是一个非常迷人的研究主题。对于机器学习问题来说,标记数据并不总是可用的。图在这些无人监管的环境中非常强大,因为它们通过利用数据的底层子结构来充分利用你拥有的数据

对于一些机器学习问题,图表可以帮助你在没有标签的地方得到标签数据!

我将教你如何在图中找到相关数据点的,使用一套被称为社区检测的方法。我们将使用 Spark GraphFrames 来处理我从 2017 年 9 月的通用抓取数据集中创建的大型 web 图。

Hey Boromir, have you tried community detection?

图表 101

是用于表示对象之间成对关系的数据结构。图形由节点(也称为顶点)和组成。它们也可以是有向的或无向的。例如,Twitter 关注可以是一个有向图;这种关系是单向的。我关注另一个用户,并不意味着他们也关注我!

Example of a directed graph.

我专注于网络图表。网络图捕捉不同网站之间的链接关系。每个网页都是一个节点。如果从一个页面到另一个页面有一个 html 链接,在这两个节点之间画一条边。

当你对越来越多的页面这样做时,你会注意到子结构的出现。在真实的 web 数据上,这些子结构可能非常大和复杂!

这是一个新闻网站下所有页面的样本图。

  • 每个淡蓝色的点代表一个单独的网页,或节点
  • 每条深蓝色的线代表两页之间的链接,一条

Subpage structure of a news site, generated by me using Gephi.

即使在这个级别,您也可以看到密集的集群、社区、页面。您可以发现具有较高中心度的节点(有大量其他页面链接到它们的页面)。

如果单个网站的连接如此密集,想象一下我们可以从成千上万个网站中挖掘出什么!

图表为什么有用?

好吧,那个蓝色水母看起来很酷,但是为什么要做这些呢?

-你呢

有许多机器学习问题,其中标签(关于数据点是属于一个类还是另一个类的信息)不可用。无监督学习问题依赖于寻找数据点之间的相似性来将数据分类成组或聚类。与监督方法形成对比,在监督方法中,数据用适当的类别进行标注,您的模型学习使用这些标签来区分类别。

Source: http://beta.cambridgespark.com/courses/jpm/01-module.html

当你不容易获得更多数据时,无监督学习是非常有用的,因此你可以利用你所拥有的数据的更多价值。标签可能不可用;即使有,也可能太费时或太贵而无法获得。在一个机器学习问题的开始,我们也可能不知道我们到底在寻找多少类对象!

这就是为什么我们希望我们的工具包中有图表:

图表让我们在无人监管的环境下从数据中获得更多价值。我们可以从图中得到聚类。

无监督学习与人类的学习方式并无不同!你最初是怎么学会分辨狗和猫的?我猜对大多数人来说,没有人会让年轻的自己坐下来,用精确的分类学术语定义什么是狗或猫。你的父母也没有给你一个由数以千计的猫和狗的照片组成的语料库,每张照片都有标签,并要求你画出一个准确划分这两类动物的界限。

如果你的童年和我一样,你可能见过几只猫,见过几只狗。与此同时,你幼小的心灵识别出这两种动物之间的显著差异,以及每种动物的相关共同特征。我们的大脑不可思议地从我们的环境中吸收信息,综合这些数据,并在我们一生中遇到的完全不同的事物之间形成共同点。

集群有很多令人兴奋的应用。我的工作中出现了一些例子:

  • 预测没有标签可供学习的数据集的类别标签
  • 受众细分和分类生成分组。
  • 为相似的网站建立一个推荐者。
  • 发现异常
  • 使用集群作为半监督机器学习集合的一部分。聚类可以帮助您将已知标签扩展到附近的数据点,以增加训练数据的大小,或者如果立即需要标签,可以直接使用聚类,直到辅助系统可以对其进行分类。

关键在于:在无监督学习中,集群就是社区!而社区就是集群!

图形社区也是集群!

唯一的区别是,你没有使用工程化的特性,而是依靠你的图中的底层网络结构来派生集群。您可以使用图形中的边来度量数据点之间的相似性,而不是使用预定义的距离度量。

我之前提到过他们,所以我应该适当地介绍一下社区。没有一个唯一的定义。一个一般的描述:一个社区是一个图的子结构,其中结构内的节点比子结构外的节点彼此连接得更紧密。找到这些社区或集群的过程被称为社区检测

Zachary karate club. Image from: KONECT, April 2017., dataset from original 1977 Zachary study.

扎卡里空手道俱乐部数据集模拟了空手道俱乐部各成员之间的关系。有一次,俱乐部的两名成员发生了冲突,俱乐部最终分裂成多个社区。您可以看到用 4 种颜色表示的社区。

想想无监督聚类算法是如何工作的。您依赖于这样一个事实,即在您选择的特征空间中,一些数据点比其他数据点更接近。数据越接近,越相似。然后,根据选择的距离度量,将数据分配到相似对象的集群中。

图表可以帮助您实现相似的聚类,而没有像传统聚类那样选择特征的麻烦。

等等,为什么会这样?

我们来深入挖掘一下!我们做了哪些假设,让我们依靠社区检测来找到相关节点?

最重要的一条:

节点之间的边不是随机的。

如果你的图形是随机的,这些都不会起作用。然而,现实生活中的大多数图表都不是随机的;这些边缘以某种方式相关联。两种机制有助于解释为什么会出现这种情况:

  1. 影响。连接的节点倾向于共享或传播特征。想象你的几个朋友学会了使用 Spark 是多么的神奇。从与他们的联系中,你可能也更倾向于开始使用 Spark。“我所有的朋友都在做这件事,所以我也要做。”
  2. 同宗拥有共同特征或某种关系的节点更有可能连接起来。例如,如果你和我都对 python 和图形感兴趣,我们更有可能在图形上联系在一起。这也叫做分类混合“物以类聚,人以群分。”

在现实生活中,这些机制能够并且确实相互作用!

研究人员利用这些现象用图表来模拟有趣的问题。例如,Farine 等人根据动物最强联系的位置预测了狒狒的位置——这是对行为生态学的影响的一个很好的应用。

Farine, Damien R., et al. “Both nearest neighbours and long-term affiliates predict individual locations during collective movement in wild baboons.” Scientific reports 6 (2016): 27704

同性在社交网络研究中被频繁使用。Adamic 和 Glance 在 2004 年大选期间对政治博客做了一项有趣的研究。他们制作了一张图表,展示不同博客之间的相互引用;蓝色节点代表自由派博客,红色节点代表保守派博客。也许不出所料,他们发现博客倾向于引用其他具有相同政治倾向的博客。

Adamic, Lada A., and Natalie Glance. “The political blogosphere and the 2004 US election: divided they blog.” Proceedings of the 3rd international workshop on Link discovery. ACM, 2005.

即使在个人层面上,同性恋也是有意义的。你自己的朋友网络很有可能是由和你同龄、住在同一个城镇、有相同爱好或上过同一所学校的人组成的。你是工作中同性恋的活生生的例子。请随意将它添加到您的简历中!

我们已经讨论了图表如何利用数据的底层网络特征来返回聚类。在 web 图中,这些聚类对于推荐系统、受众细分、异常检测等应用非常有用。

第 2 部分(此处发布)中,我们将深入社区检测技术,并学习如何从我们使用公共爬行数据集创建的网络图中获得聚类。

承认

感谢 Yana Volkovich 博士深化了我对图论的学习,是一位伟大的导师。也感谢我的其他同事,他们对我的演讲给予了反馈。

参考

亚当,拉达,和娜塔莉·葛拉。"政治博客圈和 2004 年美国大选:分裂他们的博客."第三届链接发现国际研讨会会议录。美国计算机学会,2005 年。

常用抓取数据集(2017 年 9 月)。

Farine,Damien R .等,“最近邻居和长期附属者都预测野生狒狒在集体运动中的个体位置。”科学报道6(2016):27704

Fortunato,Santo。“图中的社区检测”物理报告 486.3–5(2010):75–174。格文、米歇尔和马克·EJ·纽曼。"社会和生物网络中的社区结构."美国国家科学院学报 99.12(2002):7821–7826。莱斯科维克、朱雷、阿南德·拉贾拉曼和杰弗里·大卫·厄尔曼。海量数据集的挖掘。剑桥大学出版社,2014 年。Raghavan,Usha Nandini,Réka Albert 和 Soundar 鸠摩罗王。"在大规模网络中检测社区结构的近似线性时间算法."物理审查**E 76.3(2007):036106。

扎卡里空手道俱乐部网络数据集— KONECT,2017 年 4 月。**

使用 Spark 进行大规模图挖掘:第 2 部分

原文:https://towardsdatascience.com/large-scale-graph-mining-with-spark-part-2-2c3d9ed15bb5?source=collection_archive---------1-----------------------

分为两部分的教程:

第一部分 :无监督学习的图形。

第二部分(你来了!):如何施展神奇的图形力量。我们将讨论标签传播、火花图框架和结果。回购样品图和笔记本在这里:https://github.com/wsuen/pygotham2018_graphmining

在第 1 部分中(这里是),我们看到了如何用图解决无监督的机器学习问题,因为社区是集群。我们可以利用节点之间的边作为相似性或关系的指标,就像特征空间中的距离用于其他类型的聚类一样。

在这里,我们深入探讨社区检测的方法。我们构建并挖掘了一个大型 web 图,学习如何在 Spark 中实现一种称为标签传播算法(LPA)的社区检测方法。

使用标签传播检测社区

虽然有许多社区检测技术,但我只关注一种:标签传播。对于其他方法的概述,我推荐 Santo Fortunato 的“图中社区检测”

Graph with communities. From Girvan, Michelle, and Mark EJ Newman. “Community structure in social and biological networks.” Proceedings of the national academy of sciences 99.12 (2002): 7821–7826.

进入标签传播算法(LPA)Raghavan,Albert,和鸠摩罗王(2007) 提出。LPA 是一种迭代的社区检测解决方案,其中信息基于底层的边结构在图中“流动”。LPA 是这样工作的:

Raghavan, Usha Nandini, Réka Albert, and Soundar Kumara. “Near linear time algorithm to detect community structures in large-scale networks.” Physical review E 76.3 (2007): 036106.

  1. 开始时,每个节点从自己的社区开始。
  2. 对于每次迭代,随机遍历所有节点。对于每个节点,用其大多数邻居的标签更新该节点的社区标签。随意打破任何联系。
  3. 如果节点现在用其邻居的多数标签来标记,则该算法已经达到停止标准。如果没有,重复步骤 2。

Image Source

Or just, you know, stay home? Image Source.

标签传播有意义直觉上。假设有一天在工作中,某人得了感冒,并“传播”疾病,直到你工作场所的每个人都像他们的邻居一样生病。与此同时,街对面的富宝员工感染并传播了 流感 。你和 FoobarCo 之间联系不多,所以当每个社区的成员都染上了当前的疾病时,“传播”就停止了。实现收敛!不过,抽鼻子和头痛真糟糕。

为什么用 LPA?

  • 带标签的数据很好,但不是必需的。使 LPA 适合我们的无监督机器学习用例。
  • 参数调整非常简单。LPA 使用 max_iterations 参数运行,使用默认值 5 可以得到一些好的结果。Raghavan 和她的合著者用几个标记网络测试了 LPA。他们发现至少 95%的节点在 5 次迭代中被正确分类。
  • 聚类的先验数量、聚类大小、不需要的其他度量。如果你不想假设你的图有一定的结构或层次,这是至关重要的。对于我的网络图的网络结构、我拥有的社区数据的数量或者这些社区的预期规模,我没有先验的假设。
  • 接近线性运行时。LPA 的每一次迭代都是 O(m ),边数是线性的。与一些先前的社区检测解决方案的 O(n log n)或 O(m+n)相比,整个步骤序列以接近线性的时间运行。
  • 可解释性。当有人问,你可以解释为什么一个节点被分组到某个社区。

Language communities in Belgium mobile network (red = French, green = Dutch). Image from Blondel, Vincent D., et al. “Fast unfolding of communities in large networks.” Journal of statistical mechanics: theory and experiment 2008.10 (2008): P10008..

工具选择

首先,快速而非详尽地分析一下工具领域。我根据图的大小、库是否能很好地与 Python 配合,以及生成简单可视化的难易程度来划分工具。

Some common graph-mining tools.

工具的非详尽菜单:

  • 对于适合单台机器的数据,networkxPython 包是易于使用的图形探索的好选择。它实现了最常见的算法(包括标签传播、PageRank、最大团检测等等!).简单的可视化也是可能的。
  • Gephi 是一个开放的图形分析工具。Gephi 不是一个 Python 包,而是一个独立的工具,具有健壮的 UI 和令人印象深刻的图形可视化功能。如果您正在处理较小的图形,需要强大的可视化,并且更喜欢使用 UI 而不是 Python,请尝试 Gephi。
  • Spark 有 2 个图库,【GraphX】GraphFrames。当您的图形数据太大而无法在单台机器上显示时(受限于分配给 Spark 应用程序的资源量),想要利用并行处理和 Spark 的一些内置容错功能时,Spark 是一个很好的解决方案。spark 的 Python API py Spark 非常适合集成到 scikit-learn、matplotlib 或 networkx 等其他库中。****
  • Apache Giraph 是 Google 创建的图形处理架构 Pregel 的开源实现。与之前的解决方案相比,Giraph 的准入门槛更高。虽然 Giraph 对于大规模图形分析部署来说非常强大,但我选择了同时具有 Scala 和 Python APIs 的更轻量级的工具。
  • Neo4j 是一个图形数据库系统。它有一个 Python 客户端,尽管你必须单独安装 Neo4j。因为我的分析只是一个概念验证,所以我想避免维护和部署一个与我现有代码不集成的完全独立的工具。
  • 最后,理论上你可以实现自己的解决方案。对于最初的数据科学探索,我不鼓励这样做。许多定制的图挖掘算法是针对非常具体的用例的(例如,只在图聚类方面超级高效,而不是其他方面)。如果你确实需要处理非常非常大的数据集,首先考虑对你的图进行采样,过滤感兴趣的子图,从例子中推断关系,基本上是从现有工具中获得更多收益的任何事情。

鉴于我正在处理的数据量,我选择了 Spark GraphFrames

记住:对你的项目来说最好的图形库取决于语言、图形大小、你如何存储你的图形数据以及个人偏好!

构建通用抓取 Web 图

太好了!我完全相信图表有多棒,它们是有史以来最酷的东西!如何开始在真实数据上使用社区检测?

-你呢

步伐

1.获取数据:通用抓取数据集是一个开放的网络抓取语料库,非常适合网络图形研究。抓取结果以 WARC (网络存档)格式存储。除了页面内容,数据集还包含爬网日期、使用的标题和其他元数据。****

我从 2017 年 9 月的抓取中抽取了 100 个文件。文件warc.paths.gz包含路径名;使用这些路径名,从 s3 下载相应的文件。

Indeed.

2.解析和清理数据:作为第一步,我们需要每个页面的 html 内容。对于每个页面,我们收集 URL 任何链接的 URL 来创建我们的图表。****

为了从原始的 WARC 文件中提取边缘,我写了一些数据清理代码,这些代码可能永远不会被公之于众。至少它完成了工作,所以我可以专注于更有趣的事情!我的解析代码是用 Scala 写的,但是我的演示是用 pyspark 写的。我使用了 WarcReaderFactory杰里科解析器。对于 python 来说,像 warc 这样的库看起来可以满足你的数据管理需求。

在我将所有的href链接从 html 内容中取出后,

  • 我在域名之间画了边,而不是完整的 URL。我没有创建medium.com/foo/barmedium.com/foobar,而是只创建了一个节点medium.com,它捕获与其他域之间的链接关系。
  • 我过滤掉了循环。循环是将节点连接到自身的边,对我的目的没有用。如果medium.com/foobar链接到同一个域,比如说medium.com/placeholderpage,则不画边。****
  • 我删除了许多最流行的资源链接,包括流行的 cdn、追踪器和资产。对于我的初步探索,我只想关注人们可能会访问的网页。****

3.初始化火花上下文:对于在家跟随的人,请参见https://github.com/wsuen/pygotham2018_graphmining*的演示。这个演示只能在你的本地机器上运行。你不会得到一个分布式集群的所有计算资源,但是你知道如何开始使用 Spark GraphFrames。*******

我将使用 Spark 2.3。导入pyspark和其他需要的库,包括graphframes。然后创建一个 SparkContext,这将允许您运行 pyspark 应用程序。

*****# add GraphFrames package to spark-submit
import os
os.environ['PYSPARK_SUBMIT_ARGS'] = '--packages graphframes:graphframes:0.6.0-spark2.3-s_2.11 pyspark-shell'import pyspark# create SparkContext and Spark Session
sc = pyspark.SparkContext("local[*]")
spark = SparkSession.builder.appName('notebook').getOrCreate()# import GraphFrames
from graphframes import ******

4.创建一个图表框架:一旦你有了干净的数据,你就可以把你的顶点和边加载到 Spark 数据框架中。

  • vertices包含每个节点的id和节点的name,后者表示域。
  • edges包含我的有向边,从源域src到源链接到的域dst
*****# show 10 nodes
vertices.show(10)+--------+----------------+
|      id|            name|
+--------+----------------+
|000db143|         msn.com|
|51a48ea2|tradedoubler.com|
|31312317|   microsoft.com|
|a45016f2|     outlook.com|
|2f5bf4c8|        bing.com|
+--------+----------------+
only showing top 5 rows# show 10 edges
edges.show(10)+--------+--------+
|     src|     dst|
+--------+--------+
|000db143|51a48ea2|
|000db143|31312317|
|000db143|a45016f2|
|000db143|31312317|
|000db143|51a48ea2|
+--------+--------+
only showing top 5 rows*****

然后你可以用你的顶点和边创建一个GraphFrame对象。瞧啊。你有图表!

*****# create GraphFrame
graph = GraphFrame(vertices, edges)*****

5.运行 LPA:一行代码可以让你运行 LPA。在这里,我用 5 次迭代运行 LPA(maxIter)。

*****# run LPA with 5 iterations
communities = graph.labelPropagation(maxIter=5)communities.persist().show(10)+--------+--------------------+-------------+
|      id|                name|        label|
+--------+--------------------+-------------+
|407ae1cc|             coop.no| 781684047881|
|1b0357be|  buenacuerdo.com.ar|1245540515843|
|acc8136a|   toptenreviews.com|1537598291986|
|abdd63cd| liberoquotidiano.it| 317827579915|
|db5c0434|          meetme.com| 712964571162|
|0f8dff85|           ameblo.jp| 171798691842|
|b6b04a58|             tlnk.io|1632087572480|
|5bcfd421|         wowhead.com| 429496729618|
|b4d4008d|investingcontrari...| 919123001350|
|ce7a3185|   pokemoncentral.it|1511828488194|
+--------+--------------------+-------------+
only showing top 10 rows*****

运行graph.labelPropagation()返回一个带有节点的数据帧和一个表示该节点属于哪个社区的label。您可以使用label了解社区规模的分布,并放大感兴趣的区域。例如,发现与pokemoncentral.it在同一个社区中的所有其他网站(老实说,谁不想呢?),过滤所有其他节点,其中label = 1511828488194

结果

当我在我的通用抓取 web 图表样本上运行 LPA 时,发生了什么?

  • 我从超过 1500 万个网站的原始数据开始。这是大量的节点,其中许多包含冗余信息。我描述的清理过程将图形压缩成更少、更有意义的边。
  • LPA 发现了超过 4700 个社区。然而,一半以上的社区只包含一个或两个节点。
  • 另一方面,最大的社区有超过 3500 个不同的网站!为了给出一个范围的概念,这大约是我的最终图形后过滤的 5%的节点。

社区规模的极端说明了 LPA 的一个缺点。太多的融合,可能会有太大的集群(由控制密集连接网络的某些标签引起)。融合太少,你可能会得到更多、更小、更没用的社区。我发现最有趣的集群最终处于两个极端之间。

收敛和小世界网络效应

在我的数据集中,LPA在 5 次迭代左右收敛。你可以看到社区的数量稳定在 4700 个左右。Raghavan 和她的同事也用他们的标号图证明了这个性质。****

解释这一点的一个可能机制是小世界网络效应——图形聚集的趋势,但与节点数量相比,路径长度也较短。换句话说,虽然图有簇,但是你也期望能够在 5-6 次跳跃内从一个朋友旅行到你网络中的另一个朋友。许多真实世界的图形,包括互联网和社交网络,都具有这一特性。你可能也知道这是六度分离现象。

Number of communities levels off after 5 iterations.

样本集群

粗略地看,我们来看一些样本集群。与传统的无监督聚类一样,社区可以是不同站点的混合,尽管没有 LPA 我们不会发现一些感兴趣的主题!从左至右:

  • 电子学习网站:与电子学习页面相关或链接的网站。我该去找一些新的数据科学 MOOCs 了!
  • 臭虫网站:与房地产和臭虫相关的网站。所有这些网站都使用相同的模板/图片,只是域名略有不同。我不认为我会知道真相。
  • 星球大战社区:谈论星球大战电影、事件和纪念品的网站经常互相链接。

值得强调的是,我们在没有文本处理和特征选择、手动标记、域名特征或者甚至不知道要查找多少社区的情况下获得了这个集群。我们通过利用网络图的底层网络结构发现了兴趣社区!********

从这里去哪里

我几乎没有触及网络图形社区的表面。未来的研究可以有很多方向。例如:

  • 分层并传播元数据:如果我们向数据中添加边权重、链接类型或外部标签等信息,我们能在图中多好地传播这些信息?**
  • 删除/添加节点并测量对社区的影响:我很好奇添加或删除高边缘中心性的节点如何改变 LPA 的有效性和最终社区的质量。
  • 观察 web graph 随时间的演变:每个月都有一个新的通用抓取数据集!看看随着时间的推移会出现什么样的集群会很有趣。反过来,有哪些社群不变?众所周知,互联网不是静态的。

用于演示的Github repo包含一个 10k 节点的小型样本 web 图。此外,还有使用 Docker 进行设置和运行 pyspark 笔记本的说明。我希望这将有助于启动 web 图数据的实验,并学习 Spark GraphFrames 来解决您自己的数据科学问题。

探索愉快!

We’re pioneers! Graph pioneers. 😃 Image Source.

承认

感谢博士 Yana Volkovich 深化了我对图论的学习,是我的良师益友。也感谢我的其他同事,他们对我的演讲给予了反馈。

参考

***亚当,拉达,和娜塔莉·葛拉。"政治博客圈和 2004 年美国大选:分裂他们的博客."第三届链接发现国际研讨会会议录。美国计算机学会,2005 年。

常用抓取数据集(2017 年 9 月)。Farine,Damien R .等人,“最近的邻居和长期的附属者都预测野生狒狒在集体运动中的个体位置。”科学报道6(2016):27704

Fortunato,Santo。“图中的社区检测”物理报告 486.3–5(2010):75–174。格文、米歇尔和马克·EJ·纽曼。"社会和生物网络中的社区结构."美国国家科学院学报 99.12(2002):7821–7826。莱斯科维克、朱雷、阿南德·拉贾拉曼和杰弗里·大卫·厄尔曼。挖掘海量数据集。剑桥大学出版社,2014 年。Raghavan,Usha Nandini,Réka Albert 和 Soundar 鸠摩罗王。"在大规模网络中检测社区结构的近似线性时间算法."物理审查**E 76.3(2007):036106。

扎卡里空手道俱乐部网络数据集— KONECT,2017 年 4 月。*****

使用 Datashader 进行大规模可视化和制图

原文:https://towardsdatascience.com/large-scale-visualizations-and-mapping-with-datashader-d465f5c47fb5?source=collection_archive---------3-----------------------

旧金山商业鸟瞰图。

如果你曾经试图用 Matplotlib 或 Seaborn 创建一个超过 100,000 点的群体图或关系图,你会对在加载图时摆弄拇指的场景并不陌生。

当最终绘制该图时,由于点的数量或不同类别绘制的顺序,结果可能不会揭示太多数据。

计算效率和过度绘制只是绘制大型数据集的众多问题中的两个。幸运的是, Datashader 是一个以有意义的方式快速表示大型数据集的绝佳选择。

官方数据显示:

“这个过程中的计算密集型步骤是用 Python 编写的,但使用 Numba 透明地编译成机器代码,并使用Dask灵活地分布在内核和处理器之间,提供了高度优化的渲染管道,即使在标准硬件上也可以使用极大的数据集。”

对于那些感兴趣的人,Youtube 上有一个很棒的视频揭示了传统可视化中的问题以及 Datashader 如何帮助解决这些问题。

数据清理

我们正在使用的数据集来自 T21,包括旧金山所有的纳税企业。

“企业位置”列包含每个企业的位置数据,格式如下:

加利福尼亚州旧金山市汤森路 153 号,邮编:94107 (37.77982,-122.391555)

因此,采取了以下步骤来清理数据:

  1. 删除所有没有“商业地点”的条目,因为没有纬度和经度。
  2. 删除所有“城市”不在旧金山的条目。
  3. 删除所有带有“业务结束日期”的条目。如果该字段不是 NA,则意味着该业务不再有效。
  4. 编写助手函数,用 regex 解析出纬度和经度。

地图的 Web 墨卡托坐标

为了在 Datashader 中绘制这些点,我们必须首先将纬度和经度坐标转换为 Web 墨卡托坐标。

web 墨卡托坐标系用于 Web 制图应用程序。它的受欢迎程度可以归因于它被谷歌地图采用。为了用 Datashader 绘图,我们必须将纬度、经度对投影到这个新平面上。Datashader 有一个内置的方法可以帮我们做到这一点:lnglat_to_meters

然后,我们将第 1 个和第 99 个百分点作为地图显示的界限。选择这些百分点值是为了在确定地图边界时剔除异常值。这些坐标然后被再次投影到 Web 墨卡托平面。

地图设置

将坐标投影到新平面后,我们可以开始设置地图。

我们设置了部分对象“导出”和“cm”。“导出”有助于将创建的图导出到预定路径,而“cm”有助于颜色映射。

画布对象 ds。Canvas()设置了预定的宽度和高度。包含地图边界的 SF 对象也被传入。

我们之前使用的 pandas 数据帧被转换为 Dask 数据帧,并且使用传入的 x,y 对在画布上生成点(在本例中为东距和北距列)。

测绘

现在设置已经完成,我们可以开始用一行代码绘制和导出图,如下所示。色彩映射图,标准化都是可以轻易改变的参数。

绘制旧金山 10 万家企业,清晰勾勒出这些企业所在的街道。金融区和教会区似乎是商业最集中的地方。

最古老的企业位于哪里?我们可以对商业时代排名前十的企业进行筛选。

Distribution of oldest businesses in SF

不出所料,最古老的企业主要集中在金融区。

不同的业务类别呢?让我们画出餐饮服务企业和房地产企业的分布图。

Left: Distribution of Food Service businesses Right: Distribution of Real Estate businesses

里士满和日落区的餐饮服务相对较少。然而,似乎有相当多的房地产企业在这些地区,因为他们是住宅区。

在地图数据上叠加点

不过,黑色背景已经够了。你如何在实际地图上覆盖这些点?Datashader 与 Holoviews、Geoviews 和 Bokeh 结合使用使这变得非常容易。

Viewing business positions when zoomed in on the map.

聚合器函数中也可以使用其他列。例如,我们可以使用每个区域的业务年龄平均值来确定点的显示。

最终的图确实显示了旧金山东北部地区的老企业密度更高(深蓝色点)。

使用 Datashader 还可以做更多的事情,在这个例子中只绘制了 100,000 个点。进一步的定制选项和实际的大数据正在等待使用 Datashader 及其附带包的进一步项目的探索。例如,GPS 数据非常有趣,因为它们通常包含数百万(或数十亿)个点,并且可以追踪和分析路线。

结果代码可以在 Github 上找到,也可以在 LinkedIn 上自由连接!感谢阅读,节日快乐!

基于 Python 的潜在语义分析和情感分类

原文:https://towardsdatascience.com/latent-semantic-analysis-sentiment-classification-with-python-5f657346f6a3?source=collection_archive---------2-----------------------

photo credit: Pexels

自然语言处理,LSA,情感分析

潜在语义分析 (LSA)是一种通过应用于大型文本语料库的统计计算来提取和表示单词的上下文使用意义的理论和方法。

LSA 是一种信息检索技术,它分析和识别非结构化文本集合中的模式以及它们之间的关系。

LSA 本身是一种在文档集合中发现同义词的不受监督的方式。

首先,我们来看看潜在语义分析是如何在自然语言处理中用于分析一组文档和它们所包含的术语之间的关系的。然后我们进一步对情感进行分析和分类。我们将在此过程中回顾特征选择的卡方。我们开始吧!

数据

数据集包括超过 50 万条亚马逊美食评论,可以从 Kaggle 下载。

import pandas as pddf = pd.read_csv('Reviews.csv')
df.head()

Figure 1

TFIDF

TF-IDF 是一种信息检索技术,它衡量术语的频率(TF)及其逆文档频率(IDF)。每个单词都有各自的 TF 和 IDF 得分。一个单词的 TF 和 IDF 得分的乘积被称为该单词的 TFIDF 权重。

简单来说,TFIDF 得分(权重)越高的词越稀有,反之亦然。

from sklearn.feature_extraction.text import TfidfVectorizertfidf = TfidfVectorizer()
tfidf.fit(df['Text'])

Figure 2

X = tfidf.transform(df['Text'])
df['Text'][1]

Figure 3

参考上面的句子,我们可以检查这个句子中几个词的 tf-idf 得分。

print([X[1, tfidf.vocabulary_['peanuts']]])

T11【0.37995462060339136】

print([X[1, tfidf.vocabulary_['jumbo']]])

【0.530965343023095】

print([X[1, tfidf.vocabulary_['error']]])

【0.2302711360436964】

在“花生”、“jumbo”、“错误”三个词中,tf-idf 给“jumbo”的权重最高。为什么?这表明“jumbo”是一个比“peanut”和“error”更罕见的词。这就是如何使用 tf-idf 来表明文档集合中单词或术语的重要性。

情感分类

为了对情绪进行分类,我们删除了中性分数 3,然后将分数 4 和 5 分组为正(1),将分数 1 和 2 分组为负(0)。经过简单的清理,这就是我们将要处理的数据。

import numpy as npdf.dropna(inplace=True)
df[df['Score'] != 3]
df['Positivity'] = np.where(df['Score'] > 3, 1, 0)
cols = ['Id', 'ProductId', 'UserId', 'ProfileName', 'HelpfulnessNumerator', 'HelpfulnessDenominator', 'Score', 'Time', 'Summary']
df.drop(cols, axis=1, inplace=True)
df.head()

Figure 4

列车测试分离

from sklearn.model_selection import train_test_splitX = df.Text
y = df.Positivity
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 0)print("Train set has total {0} entries with {1:.2f}% negative, {2:.2f}% positive".format(len(X_train),
                                                                             (len(X_train[y_train == 0]) / (len(X_train)*1.))*100,
                                                                            (len(X_train[y_train == 1]) / (len(X_train)*1.))*100))

训练集共有 426308 个条目,其中 21.91%为负数,78.09%为正数

print("Test set has total {0} entries with {1:.2f}% negative, {2:.2f}% positive".format(len(X_test),
                                                                             (len(X_test[y_test == 0]) / (len(X_test)*1.))*100,
                                                                            (len(X_test[y_test == 1]) / (len(X_test)*1.))*100))

测试集共有 142103 个条目,其中 21.99%为阴性,78.01%为阳性

你可能已经注意到我们的班级是不平衡的,负面和正面的比例是 22:78。

对抗不平衡类的策略之一是使用决策树算法,因此,我们使用随机森林分类器来学习不平衡数据并设置class_weight=balanced

首先,定义一个函数来打印出准确度分数。

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.ensemble import RandomForestClassifier
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_scoredef accuracy_summary(pipeline, X_train, y_train, X_test, y_test):
    sentiment_fit = pipeline.fit(X_train, y_train)
    y_pred = sentiment_fit.predict(X_test)
    accuracy = accuracy_score(y_test, y_pred)
    print("accuracy score: {0:.2f}%".format(accuracy*100))
    return accuracy

为了进行有效的情感分析或解决任何自然语言处理问题,我们需要很多特性。很难计算出所需功能的确切数量。所以我们准备试试,一万到三万。并打印出与特征数量相关的准确度分数。

cv = CountVectorizer()
rf = RandomForestClassifier(class_weight="balanced")
n_features = np.arange(10000,30001,10000)def nfeature_accuracy_checker(vectorizer=cv, n_features=n_features, stop_words=None, ngram_range=(1, 1), classifier=rf):
    result = []
    print(classifier)
    print("\n")
    for n in n_features:
        vectorizer.set_params(stop_words=stop_words, max_features=n, ngram_range=ngram_range)
        checker_pipeline = Pipeline([
            ('vectorizer', vectorizer),
            ('classifier', classifier)
        ])
        print("Test result for {} features".format(n))
        nfeature_accuracy = accuracy_summary(checker_pipeline, X_train, y_train, X_test, y_test)
        result.append((n,nfeature_accuracy))
    return resulttfidf = TfidfVectorizer()
print("Result for trigram with stop words (Tfidf)\n")
feature_result_tgt = nfeature_accuracy_checker(vectorizer=tfidf,ngram_range=(1, 3))

Figure 5

不错!

在我们完成这里之前,我们应该检查分类报告。

from sklearn.metrics import classification_reportcv = CountVectorizer(max_features=30000,ngram_range=(1, 3))
pipeline = Pipeline([
        ('vectorizer', cv),
        ('classifier', rf)
    ])
sentiment_fit = pipeline.fit(X_train, y_train)
y_pred = sentiment_fit.predict(X_test)print(classification_report(y_test, y_pred, target_names=['negative','positive']))

Figure 6

特征选择的卡方检验

特征选择是机器学习中的一个重要问题。我将向您展示在我们的大规模数据集上进行基于卡方检验的特征选择是多么简单。

我们将计算所有特征的卡方得分,并可视化前 20 名,这里术语或单词或 N-grams 是特征,正面和负面是两个类别。给定一个特征 X,我们可以用卡方检验来评估它区分类的重要性。

from sklearn.feature_selection import chi2
import matplotlib.pyplot as plt
%matplotlib inlineplt.figure(figsize=(12,8))
scores = list(zip(tfidf.get_feature_names(), chi2score))
chi2 = sorted(scores, key=lambda x:x[1])
topchi2 = list(zip(*chi2[-20:]))
x = range(len(topchi2[1]))
labels = topchi2[0]
plt.barh(x,topchi2[1], align='center', alpha=0.5)
plt.plot(topchi2[1], x, '-o', markersize=5, alpha=0.8)
plt.yticks(x, labels)
plt.xlabel('$\chi^2$')
plt.show();

Figure 7

我们可以观察到,具有高χ2 的特征可以被认为与我们正在分析的情感类别相关。

例如,卡方检验选出的前 5 个最有用的特征是“不”、“失望”、“非常失望”、“不买”和“最差”。我想它们大多来自负面评论。卡方检验选择的下一个最有用的特征是“棒极了”,我假设它主要来自正面评论。

今天到此为止。源代码可以在 Github 上找到。我很高兴听到任何问题或反馈。

在 1 周或更短时间内推出 AI

原文:https://towardsdatascience.com/launch-with-ai-in-1-week-a4f4f45cc177?source=collection_archive---------10-----------------------

https://www.reddit.com/r/spaceporn/comments/81q31g/twin_engine_atlas_v_with_four_solid_rocket_motors/

无论你是一家新的创业公司还是现有的企业,这里有一种方法可以让人工智能产品或服务在 1 周或更短时间内投入生产。你当然不一定要相信我的话,我会和你分享一些工具,你可以用它们来真正加快速度。

第一天

挑一个可以用机器学习解决的问题。这听起来很明显,但是相信我,并不总是这样。我已经写了很多关于机器学习的好的和坏的用例,所以看看这些或者做一些研究,确保你正在处理一些可能的事情。

想想标记产品图片、推荐内容、让数据更容易搜索或对推文进行分类,而不是预测股市或制造无人驾驶汽车。

对于机器学习和人工智能来说,实际上有很多非常好的用例,关键是要想得简单,随着时间的推移,你可以变得更复杂。

让我们来看看一个新闻聚合网站的想法,它让你的用户可以根据主题、人物和内容进行搜索。

首先,坐下来决定你想让你的用户浏览哪类新闻。也许它们是科学、体育、政治、健康、技术和犯罪。

你可以用第一天剩下的时间收集数据。走出去,在这些类别中尽可能多地抓取文章,并按照类别名称将它们组织到文件夹中。

每个类别都有相同数量的例子,这一点很重要。

第二天

确保每个类别中有 100-500 篇文章(越多越好)。现在有趣的部分来了。访问 https://machinebox.io 下载 Classificationbox。你必须注册你的邮箱,安装 Docker,然后运行一个终端命令。不会超过几分钟。

一旦 Classificationbox 启动并运行,克隆这个开源工具,让你从你电脑上的文本文件中创建一个机器学习模型。在你的文件夹上运行textclass,里面有文章样本。

/training-data
    /sports
        sports-example1.txt
        sports-example2.txt
        sports-example3.txt
    /politics
        politics-example1.txt

几秒钟后,你就会有一个可以自动对新闻文章进行分类的机器学习模型。假设数据集是好的,你的准确率应该在 90%以上。如果不是,考虑稍微清理一下数据集,或者简单地给每个类别增加 100 个左右的样本。

还不到上午 10 点,你就已经有了一个准备投入生产的机器学习模型。但是让我们继续。

下一件你想做的事情是让你的文章变得可搜索,但是当你开始聚集数百万篇文章时,如果你试图索引每一个单词,你会很快碰壁。此外,如果你搜索单词Radcliffe,你希望能够返回相关的结果,无论那个人是在搜索丹尼尔·雷德克里夫的地方还是新闻。

再次,访问机器框并下载文本框。Textbox 是一个关键字和命名实体提取工具,它将为每篇新闻文章提供一点不错的元数据,可以在弹性搜索中很好地工作。这里有一些关于如何做到这一点的细节,但重点是:

  • 按人员、地点、时间等过滤搜索。
  • 轻松构建整个数据集的可视化,并查看趋势。
  • 以惊人的速度处理和分析数据
  • 还有更多…

第三天

文章有时附有人物和地点的照片。您可能希望能够标记文章中的人物,标记图像中的事物,以进一步改进搜索和分类。

机器箱有两个工具让这变得非常简单;面框标签框。继续下载这两个。

虽然 Tagbox 可以使用自定义标签进行教学,但它也预先准备了成千上万个标签,因此它真的很容易开始,无需投入任何工作。当您开始编写应用程序的 web 服务部分时,您可以轻松地将每张照片传递到 Tagbox,并将响应存储在弹性搜索中。你甚至可以选择前两个标签,或者高于某个置信度的标签。

你可能也想开始识别文章中照片上的人。第一步是将每张照片传入 Facebox,然后将面纹存储到数据库中。你可以在这里阅读更多关于面纹是如何工作的

一旦你建立了一个很好的面部指纹数据集,你就可以在任何时候浏览并教 Facebox 这些人是谁。它不仅会在你给它的新照片中识别你教它的这些人,而且你可以通过简单地更新你数据库中面纹与name的关系,将时间上的学习应用到你已经处理过的照片上。

现在你已经准备好了机器学习模型,你可以在第三天下午开始构建 web 应用程序。

第 4/5 天

用这两天的时间构建 web 应用程序,汇总新闻故事,决定如何向客户显示信息,集成弹性搜索,也许还要处理客户登录。

然后,为每一个新的文章建立一个流,通过不同的机器盒子,并处理输出。

部署到您最喜欢的托管站点。

第二周

现在,你已经有了一个集成了多个机器学习模型的产品,可以做任何事情,从根据文章的写作方式对新闻文章进行自动分类,到使用照片和文章本身的内容来改进搜索。

你还可以做更多的事情。你可以开始推荐文章,人们更有可能根据他们是谁点击,检测并清除假新闻,或者建立自己的语言检测模型来进行自动翻译。

关键是,你应该能够在不到一周的时间内推出一个带有人工智能的产品或服务,即使你是从零开始。

什么是机器盒子?

Machine Box 将最先进的机器学习功能放入 Docker 容器中,这样像您这样的开发人员就可以轻松地将自然语言处理、面部检测、对象识别等融入其中。到您自己的应用程序中。

盒子是为规模而建的,所以当你的应用真正起飞时,只需添加更多的盒子

启动和扩展数据科学团队:业务利益相关者行动手册

原文:https://towardsdatascience.com/launching-and-scaling-data-science-teams-business-stakeholder-playbook-d3bac9b40d8?source=collection_archive---------22-----------------------

与您的数据科学团队互动的最佳实践行动手册

这篇文章旨在成为与数据科学团队互动的最佳实践指南。本节摘自我关于启动和扩展数据科学团队的 摘要 ,并包含与 数据科学 IC 数据科学经理 行动手册的部分重叠。我的目标是一名业务利益相关方(PM、运营总监、业务分析师、CMO),他们非常依赖他们的数据科学团队,但在与个人沟通和与团队工作流集成方面存在困难。这篇文章是为那些提出以下问题的人写的:“我知道我需要与我在 __________ 的数据科学团队合作取得更好的结果,但是我不知道如何获得这些结果,或者我可以做些什么来改善这些结果。”

四句话总结:知道什么是可能的,什么是你想要的。在全公司范围内强制协调“业务影响”。发展商业智能技能。推广数据文化。

知道什么是可能的,你想要什么

(此部分与数据科学 IC 行动手册的“发现您自己的问题”部分有很多重叠)

我问我的受访者:“在你合作的团队中,什么最让你沮丧?”商业利益相关者和 IC 数据科学家经常给出的答案是同一个硬币的两面。利益相关方:

  • “很难理解他们在做什么或如何工作,很难让他们交流他们在做什么。”
  • “对于两周和两个月的项目缺乏共识。一切都承诺过多,兑现不足。”
  • "他们给出了一个学术性的答案,而不是务实的."
  • “我们聊了很多。五周过去了,我们仍在努力解决数据管道问题。”

来自数据科学家:

  • "利益相关者不知道数据集做什么和不存在什么."
  • “他们不明白工作的复杂性,也不明白为什么事情要花这么长时间。当我们建立一个测试时,他们没有意识到它必须出现在三个不同团队的路线图上,他们也不理解我们给他们的测试指标。"
  • “我们总是遇到非范围内的问题”
  • “他们不知道什么是科技债务,也不知道为什么我们有时需要清理这些债务。对他们来说一切都是临时的。他们无法解读数据科学的结果。”
  • “没有什么东西是以一种让我们看得见的方式组织起来的”

过于简单地说:利益相关者因为无法理解他们的数据科学家而感到沮丧,数据科学家因为感觉被误解而感到沮丧。 XKCD 再次引用:“在 CS【数据科学】中,很难解释容易和几乎不可能之间的区别”。作为一个非技术利益相关者,你必须意识到:除非你投入了工作,否则你将不知道你的数据科学团队能够做什么。举个例子:我花了大约六周的时间,为 Wayfair US 编写了一个推荐算法,将“实际”性能提升到贝叶斯“实际与预期”性能。Wayfair Germany 团队认为不值得要求同样的算法——他们认为这对一小部分业务来说过于重要。实际上,为 wayfair.de 构建这个算法需要用四行代码(或类似代码)将WHERE storeid=”wayfair.com”更改为WHERE storeid=”wayfair.de”。如果你是一个商业利益相关者,你必须足够了解什么是微不足道的要求。

另一方面,数据科学家和利益相关者都认为,引发一连串问题的因素尚不可知。如果你的团队基于现有的数据,他们应该能够很快得出结论。其他问题则要困难得多—如果数据不存在,这可能需要前端团队收集工作,DBA 编写工作,ETL 团队添加到管道中/清理/标准化工作。A/B 测试将需要与店面和所有其他团队进行更多的协作,以便安排他们自己的测试。了解存在哪些数据集,以及数据科学团队在响应您的请求时面临哪些依赖关系。

务实/学术方面的紧张气氛经常出现。可以肯定的是,数据科学家的责任是产生对你来说被理解和有价值的工作。话虽如此,你的技术界限限制了数据科学家所能做的工作。如果你依赖于数据科学家,你需要培养一种起码的能力来理解他们构建了什么以及他们如何评估成功。回归、分类、聚类、均方误差、f1 评分、交叉验证和 p 值并不一定是你的第二天性,但你应该足够熟悉,能够理解为什么你的数据科学家建立了他们所做的工作。一位股东对他们的 DS 团队说:“不要提出我不理解和不同意的建议。”发展你的背景,了解你的团队的建议。

迫使全公司在“业务影响”上保持一致

(此部分与数据科学经理行动手册中的“有意安排优先级流程”部分有很多重叠)

“知道什么是可能的,你需要什么”填补你的数据科学团队能够做什么、什么是容易的、什么是几乎不可能的盲点。认识到你也拥有不对称信息,你知道商业环境。为了让您的数据科学团队与公司保持一致,您必须填补他们对工作价值的盲点。这必须是利益相关方主导的对话;如果您的团队不能就数据科学项目的“业务影响”达成一致,您甚至无法尝试有效地分配数据科学资源。来自分析学的 SVP:“你需要通过练习将任何东西转换成一种通用货币。你可以将任何事情转化为投资回报,挑战在于剔除扯淡的商业案例和分配项目,因为轮到某人获得数据科学资源了。”重复一下数据科学经理剧本,优先化可能有点政治性(“这是一个足够小的公司,知道你是否过度使用或未充分使用数据科学资源”)到高度政治性(“我们支持的每个团队都平等地使用我们的时间”)。您的公司需要根据投资回报(在这种情况下,是数据科学家的时间)进行优先排序。您必须知道如何估计所需的数据科学资源,并以一种可以与他人的潜在项目进行比较的方式,提供真实的点对点业务结果影响。

让您的数据科学家参与到对话中。通过在优先级会谈期间将 DS 团队带入房间,您可以填补他们业务环境中的空白,允许他们在未来开发自己的项目。我采访过的运作最好的团队有一个共同点:项目可以以精英管理/自上而下的方式产生,数据科学家应该提出一些工作建议。伟大组织中的人知道如何消除彼此的盲点。

此外,与您的团队分享过去项目的成果。数据科学家可以感觉他们在一个模型上努力工作,成功地实现它,然后:无线电静默。让您的数据科学团队更好地了解没有该解决方案会发生什么。他们创造了一些重要的东西,但往往没有意识到他们带来的成功。事实上,尽可能向上游发送结果。当一个业务利益相关者将一美元的成功归功于构建模型的数据科学团队、构建管道的 ETL 工程师、存储代码的 DBA 以及现场设置代码的前端工程师时,这种反应是会传染的。这是一种让每个人都感到兴奋并准备好赢得下一场胜利的沟通方式。

发展商业智能技能

如果“知道什么是可能的”部分是关于了解你的数据科学家的能力,这是关于帮助他们(或者至少,不打扰他们)做其他事情。商业智能意味着拥有在 SQL 中提取数据并自己执行基本分析的技术能力,并且能够围绕报告自助处理事实问题。数据科学家的一个一贯的挫折是缺乏利益相关者的分析能力:门槛越低,需要清除的障碍就越高,以获得对解决方案的认可。

这篇文章是为“非技术”商业领袖写的。我已经看到太多的利益相关者倾向于这个短语,好像它是一个骄傲的徽章。不要认为“非技术”是一成不变的,非技术经理有不同的等级,你和你的团队应该每天努力提高你的技术敏锐度。您的团队必须在您的数据科学支持下帮助迭代解决方案,如果您无法从 SQL 中提取数据来确认其工作,他们就无法为问题构建复杂的解决方案。

我采访的一位数据科学家曾在几个地方工作过,他热爱自己目前的工作,因为没有人会问:“你能帮我们实现这个目标吗?”他可以要求业务分析师自己获取数据,每个人都同意输入数据——来自数据库的特定 SQL 查询作为基本事实。另一位 DS 经理觉得自己被拉向了相反的方向,她一直觉得自己工作的一部分是保护自己的团队免受应由另一个团队承担的特别报告任务。

也许证明开发这些技能的最简单的方法是通过查看项目积压和您的数据科学部门的工资。高水平的数据科学家是昂贵的。不要让他们做你的临时报告——让他们自由地做你雇他们做的工作。

推广数据文化

我为这些文章采访的许多人都是前 Wayfair 员工,他们加入了其他科技公司。他们分享的一个令人惊讶的观察结果是,你能从创始人身上看出多少公司的 DNA。我们大多数人都觉得 Wayfair 在很大程度上是由试图找出如何销售家具的工程师经营的。Airbnb 以产品驱动著称。其他公司更注重高层次的商业/营销。我采访过的一家公司有着深厚的新闻调查传统,另一家公司在结束会议时会问这样如何能让客户更开心。数据科学团队成功与否的一个重要预测因素是公司的“数据文化”:对话在多大程度上基于分析,决策在多大程度上基于分析。

我参加过这两类公司的会议。在拥有良好数据文化的公司,任何业务建议都需要数据来支持,或者需要生成数据的计划。在另一种情况下,有人会为一个重大问题编写一个非凡的、有证据支持的解决方案,但会遭到拒绝,“我不知道 CRO 会怎么想——我们需要在 30 秒内做出一些我们可以向他解释的东西,否则就太复杂了。”你必须建立一个生态系统,在这个生态系统中,决策是由事实驱动的,而不是由个性驱动的,信息是不断被寻找和利用的。

我采访过的许多公司天生就有良好的数据文化。然而,我与一家缺乏数据文化的公司进行了一些最具启发性的对话:首席运营官进来后发现了一家老派公司,他们的思维模式是:“我们已经在这里 50 年了,从来不需要数据科学家。”创建数据文化尤其困难,因为该公司一直做得很好,而且对过去的成功存在巨大的确认偏差。他们的 DS 团队被雇佣更多是为了应对竞争对手的行动,而不是出于内部的愿望,他们随后在组织中被牵制。首席运营官分享了两个教训:数据科学团队必须被邀请参加会议,那些最兴奋地接受数据科学见解的人已经是最有自我服务能力的人了。他最需要的利益相关者是:“能够帮助我为事情做商业案例,并愿意接受和支持数据科学团队的人。帮助建立全公司感兴趣的人的联盟。”

在一个没有数据文化的公司,你需要一个来自技术方面的第一信徒。从首席运营官的角度来看,首先有一个利益相关者愿意加入数据科学并与之互动是非常必要的。“你花时间在电脑上精通技术,这是你需要添加到技能组合中的新事物。没有强迫任何人,但它最终会通过收养或替代发生。”尽你的一份力量在你的公司建立数据文化,因为它正以这样或那样的方式发生着。

启动和扩展数据科学团队:DS 个人贡献者行动手册

原文:https://towardsdatascience.com/launching-and-scaling-data-science-teams-ds-individual-contributor-playbook-3fe596eef63d?source=collection_archive---------17-----------------------

构建数据科学职业生涯的最佳实践行动手册

本文旨在为个人贡献者的数据科学职业生涯提供最佳实践指南。这一节摘自我关于启动和扩展数据科学团队的 摘要 。我的目标是一位数据科学家,他通过行业外的任何来源开发了一个标准工具包。在我看来,有大量的资源可以将 ICs 从零扩展到 Kaggle master/面试就绪。这篇文章是那些资源的延续,对于问这个问题的数据科学家来说:“我已经学会了技巧。我已经通过面试了。这是我在 ______ 的第一天。现在怎么办?”

四句话总结:把自己嵌入业务中。寻找自己的问题。迭代求解。知道你什么时候完成。

融入企业

像 Spotify 和网飞这样的推荐算法在很大程度上依赖于过去对用户行为的观察来提供未来的内容推荐。这种“协同过滤”方法在稳定状态下工作得很好,但是当用户或内容是全新的,或者当所有用户/内容都是新的(例如,服务的第一天)时就失败了。这被称为“冷启动”问题,这个名字来源于一辆在低温下不能很好启动的汽车,但当它加速时却能很好地工作。

同样的事情也存在于数据科学家的第一天工作中。Kaggle 和在线课程为数据科学家提供了一个完全包容的数据集,其中包含经过清理和良好记录的数据以及明确定义的目标(最小化预测房价的均方误差,最大化图像预测标签的 F1 分数)。这并不是工业中项目的建议、优先排序或评估方式。这可能是一个显而易见的观察结果,但重点仍然是:这些信息是没有给出的,你有责任发展商业头脑和关系来发现它。你需要将自己融入到业务中。

嵌入意味着了解坐在你上游的人:数据库管理员、机器学习工程师、基础设施工程师等。记住他们的名字,他们坐在哪里,知道什么是快速请求,什么不是。了解如何将您的请求放在他们的优先列表中(空闲时的快速请求,票务系统/电子邮件中的较大请求?).了解他们是如何被评估的,他们关心的指标是什么。了解什么会惹恼他们,不要去做。

嵌入意味着了解商业利益相关者:坐在你下游并依赖你工作的人。了解他们想做什么,熟悉你为他们所做工作的业务应用。告诉他们什么是有帮助的,他们的盲点是什么,他们希望他们的解决方案是什么形式。

嵌入意味着非常广泛地理解业务环境。组织内的各种孤岛是什么,他们试图优化哪些部分?是什么让 CEO 夜不能寐?公司范围内的重要权衡是什么?为了让公司发挥潜力,需要发生什么,你的工作如何配合?

将自己嵌入到团队的工具箱中。数据科学家通常只有“Macbook Pro”经验:个人对给定数据集编写的一次性分析/模型构建/预测。你必须从 Macbook Pro 数据科学转向行业数据科学。从本地小的.csv文件,到跨分布式服务器持续运行的数据管道。了解如何在协作环境中构建防弹模型,这可能意味着管理代码库的 Git、依赖关系的 Docker、作业调度的 Airflow、模型部署的 AWS 以及一般的软件工程。特别是对于学者来说,工程最佳实践可能是一个巨大的盲点。很有可能,在完成一个项目之前,您需要学习一些与编写 xgboost 分类器完全无关的工具。弄清楚那些工具是什么,比任何人都学得好。

最后,嵌入到您团队的工作流程中。就像你的团队有偏好的工具一样,他们也有使用这些工具的偏好方式。你的团队是如何工作的?项目是如何优先化、分配、完成、沟通和评估的?数据科学 MOOCs 不会强迫你问这个问题。了解别人能为你的项目做出什么贡献,以及你能为别人做出什么贡献。最终,你的长期成功取决于持续的技能发展。了解你的团队是如何获取知识、分享知识和相互发展的。想想如何兑现你的承诺。扩大您团队的总知识库,使某人能够更好地完成工作。

来源自己的问题

我采访的一位数据科学家告诉我:“你经常坐在技术问题和业务问题之间。如果你不能翻译它们,你就不能在这个领域取得成功。”数据科学家和业务利益相关者之间的一个持续挑战是缺乏知识重叠:业务利益相关者不知道技术上什么是可能的,数据科学家对业务的了解不足以解决重要的问题。你将自己嵌入到业务中来建立这种知识。下一步是采取行动,主动寻找数据科学解决方案能够给公司底线带来巨大变化的机会。再说一次,这不是卡格尔教你的一课。

没有 XKCD 的参考,任何科技文章都是不完整的。“在 CS(数据科学)中,很难解释容易和几乎不可能之间的区别。”从这个角度考虑你的公司所面临的挑战,并把为重要问题寻找技术上简单的解决方案视为你的责任。这一点对我个人来说很重要,因为我不认为我在工作的头几年学到了这一点。尤其是在一个庞大的公司,已经有了一个人可能不知道的更多列数据和一年的积压票据,很难认为你想出的主意实际上是对你时间的最好利用。

在我为 Wayfair 编写推荐算法的第二年,我终于明白了这一点。我们的想法是显示分段的邮政编码特定排序——这个想法是,即使我们以前从未见过一个人,他们来自的邮政编码可能是我们可以利用的东西;与普通人相比,他们的偏好可能与所在地区的其他人更相似。不幸的是,我们没有在任何地方记录这些数据,也没有办法重新创建这些数据。这让我很失望,但直到一位 ETL 工程师说“如果你放入一张票,我们就可以记录它”,我才意识到甚至有可能改变我的数据集。一周后,我们开始记录数据,两个月后,我们推出了新的分类,这是一个巨大的胜利。

这里的要点是,您需要与 DBA/ETL 团队保持足够的协调,知道可以添加什么,知道业务问题是什么,并且足够有创造力/足够现实,知道记录一条新数据可以让您首次解决某个问题。商业知识会比技术知识让你走得更远,但前提是你要将你的商业知识付诸行动。

换句话说,业务利益相关者对他们的数据科学团队的一致抱怨是,他们倾向于采用过于学术和科学的方法来解决问题。许多经理和利益相关者经常持批评态度,认为他们在协作流程中的角色是控制个人贡献者的数据科学马力,并为他们指明正确的方向。不要强迫别人把你从一个学术练习拉回到一个实用的解决方案,要成为实用解决方案的推动力。

迭代求解

一旦你确定了一个重要问题的实用解决方案,就带头与业务涉众一起迭代以得到一个实际上对他们有效的解决方案,然后是一个更好的版本。这个等式的迭代部分很重要,因为这也不是数据科学教育的一部分。你不能去参加 Kaggle 比赛,然后说,“我知道你要求的是均方差,但是绝对误差在这种情况下更有意义吗?”或者,“此栏似乎主要是 2016 年的垃圾数据—还有其他地方可以找到当前数据吗?”或许最重要的是,

这仍然是你对这个问题的想法吗?这看起来像是你的团队可以接受的好的解决方案的开始吗?我完全跑题了吗?我们在为正确的事情优化吗?

一位经历过这种痛苦的 IC 说:“你可以在一个项目上走得很远,同时做出一个别人不同意的假设。”迭代方法是数据科学和商业领袖之间积极工作关系的关键。利益相关者反复遇到的一个挫折是科学家缺乏数据灵活性。一位非技术项目经理对他的数据科学团队有这样的看法:

真正聪明的人,有能力,有技能。我们给他们工具和数据。他们告诉我们‘数据在说一些具体的东西,所以这是我们必须做的。’他们对我们的投入很固执。不要做“幕后的巫师”。不要拿出一个我不理解不认同的推荐。

最后一句话有点矛盾,(你要么不理解,要么不同意……但不能两者都理解),但它阐明了一个极其重要的真理。不管你的工作在分析上有多正确,如果你工作的团队不理解你的解决方案,你都不会接受。永远不要低估一个非 STEM 背景的同事无法区分你所说的是观点还是事实;“我们应该这样做”可以有多种含义。记住,理解的责任在交流者身上。

我采访的一位 IC 说“我根据利益相关者的反馈来评估项目的成功。如果我建立了一个伟大的模型,但没有人使用它,没有人得到帮助。“我的利益相关者觉得我有用吗,他们的衡量标准有所改进吗?”“这是一种正确的思维方式,但 ICs 应该更进一步:将为评估成功的方法做出贡献以及就您的工作对您的利益相关者进行教育视为您的责任。商界的一个老生常谈是,在没有就观众将会收到的内容进行指导的情况下,永远不要进入最终演示。在数据科学中同样如此。表述项目的一个好方法是:

“问题,老办法,新办法,改进。”

与业务利益相关者一起工作,不断地进行压力测试,以确保你正在做的工作仍然适合这个框架。

转向迭代过程对你培养的声誉也很重要。再一次,从教育/Kaggle 竞争的角度来看,你只有一次机会找到解决方案,你的客户并不重要。在一家公司解决问题根本不是一次性的表现,所以不要把它当成一次性的。借用一个体育比喻来说:你应该尽可能多地打出积极的结果,而不仅仅是一个本垒打。避开“头戴式耳机,低头,带有 zenburn 配色方案的垂直屏幕,窗帘后面的向导”的描述。巩固并增加你人际关系中的开放文化。尽你的一份力量去赢得尊重和信誉,人们会信任你的意见和优先安排你的工作和时间的能力。

知道你什么时候完成

我问我采访的数据科学家:“你如何知道一个解决方案何时完成?”许多人不知道。一个 IC 说,“老实说,这取决于数据科学家个人。如果你一直致力于一个问题,我认为没有人会阻止你,直到它成为一个问题。”DS 经理经常指出这是一种挫折,一位经理说,“我的团队一直在进行超参数调优,我对此也感到内疚。看不到大局是一个大问题。”另一位经理说:“我必须确保人们用他们的时间为商业价值做出贡献,而不是建造自舔冰淇淋甜筒。在这一行,人们不想成为 PM-y,他们不想做除了写代码以外的任何事情。”要知道这是数据科学家当之无愧的刻板印象。你是如何成为例外的?

几乎所有的集成电路表示,时间管理是他们可以努力的事情,他们缺乏对何时进入下一个项目的意识。发展这个框架。这里的一些必读资源是机器学习:技术债务的高息信用卡和这个 Reddit 关于“你有哪些不受欢迎的数据科学观点”的帖子。山羊安德烈·卡帕西写道:“在伸手拿火箭筒之前,应该总是先试一试 BB 枪。”

做一些必要的工作来理解时间和复杂性的权衡,并且有意识地说出你的决定。一位数据科学主管告诉我:

存在更多代码、低质量代码和复杂性的成本。这些成本会随着时间的推移而增加。如果你想做一件更复杂的事情,那很好,但是告诉我你为什么要支付这个费用。可以用 tensorflow,但不要先用。

就这一点而言,我以前见过一个用于 126 个数据点的递归神经网络。126 个数据点要用 Excel 分析。从那个相同的 Reddit 线程,

商业知识会比技术知识让你走得更远。对于很多问题,xgboost +贝叶斯优化会非常快地让你获得 95%的价值,你可以通过识别新的机会并快速而不是完美地解决它们来产生更大的影响。此外,对于任何刚刚开始探索数据科学的组织来说,实施几个“足够好”的模型将比构建一个极其精确的模型在短期内提供更多的价值。

我从一位数据科学项目经理那里得到了一个很好的建议,她以前和软件工程师一起工作,她觉得他们在迭代和有效工作方面做得更好:当你估计你将在一个项目上花费的时间时,把它作为一个决策树来做。强迫自己提前定义停止点,当事情足够好,增加的一小时或一天可以更好地利用时。这又回到了“迭代”部分:如果线性回归现在已经足够好了,可以轻松地删除项目的第二和第三部分。

启动和扩展数据科学团队:DS 经理行动手册

原文:https://towardsdatascience.com/launching-and-scaling-data-science-teams-ds-manager-playbook-af047a992311?source=collection_archive---------19-----------------------

构建和管理数据科学团队的最佳实践行动手册

这篇文章旨在成为管理数据科学团队的最佳实践指南。本节摘自我的 摘要 关于启动和扩展数据科学团队的内容,并包含与 数据科学 IC 剧本的部分重叠。我的目标是一名数据科学家,他作为个人贡献者取得了成功,目前正在努力解决经典的管理问题:我如何扩展、聘用、评估和沟通?在数据科学领域,考虑到合格候选人背景的巨大差异,这是一个更加棘手的问题。这篇文章是为那些问这个问题的人写的:“作为一个数据科学 IC,我已经取得了成功,也承担了责任。我的任务是在 ________ 发展和领导一个团队。现在怎么办?”

四句话总结:不断调整你的组织结构。最大化团队的知识转移。有意识地安排你的优先顺序。强调解决方案的最低复杂度。

持续调整您的组织结构

在我剧本的所有句子四句话总结中,这是迄今为止最笼统/定义不清/晦涩难懂的。我很抱歉。然而,有一个原因:弄清楚如何建立一个数据科学团队真的很难;没有固定的“最佳实践”,它高度依赖于公司和员工,而且完全可以肯定的是,无论您现在有什么设置,都不是六个月前或六个月后的正确设置。我找到的资源和我采访过的经理给出了不同的、通常是矛盾的解决方案。我已经研究了如何建立一个数据科学团队足够长的时间,以确信没有正确的答案。作为一名经理,你能做的最好的事情就是不断调整你的组织结构、数据架构、工作流程和文化,以确保你积极地扩展你的团队来满足你公司当前和未来的需求。

数据科学组织最大的问题:你的团队是集中式的还是嵌入式的?集中式:坐在一起工作的数据科学团队,扮演内部顾问的角色。DS 团队的“时间”是分配给业务涉众的资源。嵌入式:个体数据科学家坐在特定的产品团队中,他们的日常工作在团队中高度迭代,他们的项目范围有限。DraftKings 有一个集中的团队,Zillow 也是。Wayfair 两样都有。 Airbnb 因为这个原因从集中式迁移到混合式:

我们从集中式模型开始,被它提供的相互学习的机会所吸引,并在度量、方法和过去工作的知识上保持一致。虽然这都是真的,但我们最终是在决策业务中,并且发现我们无法成功地做到这一点,因为我们的合作伙伴团队不完全了解如何与我们互动,我们团队中的数据科学家不了解他们要解决的问题的完整背景,也不知道如何使其可行。

Chuong Do 有一篇关于集中式/嵌入式的优秀文章,强调了这两种方法的一些主要缺点。分散化可能会导致知识孤岛、更少的协作机会、更难实现标准(从代码库到雇佣),以及难以共享基础设施/最佳实践。集中化可能会导致团队缺乏业务背景或合作伙伴的支持,还可能导致“数据科学被视为一种支持功能,回答产品经理的问题,而不是作为真正的思维伙伴运营,并从数据知情的角度积极推动对话。”

在采访 DS 经理时,我普遍发现每个人都认为他们有一个混合解决方案,该方案吸收了集中化和嵌入式的最佳部分。这既是不可能的,也是努力的目标。要认识到,在非常成功的公司里,非常有才华的人对实现这一点的最佳方式意见不一,所以作为经理,你的职责是在这个时候为你的团队做出最佳决策,并完全适应这种结构可能不再有意义的时候。以下是我对构建一个组织结构的想法,并警告说它们可能会在未来发生变化。

从一个集中的团队开始。当你开始雇佣数据科学家时,你会有许多需要支持的业务团队,而数据科学家太少,无法嵌入。在拥有小团队的小公司,知识共享/业务背景/跨职能协作更容易。办公室可以很小,你知道每个人在做什么。“知识筒仓”风险较小。

当算法密集型项目变得足够大,以至于永远需要数据科学家时,嵌入数据科学家。Wayfair 慢慢将数据科学家嵌入他们的定价、推荐和营销团队;认识到这些业务部门是如此基于算法和分析,他们需要由面向业务的数据科学家领导。Zillow 的 Zestimate 团队也是如此。Wayfair 和 Zillow 都有一个集中的数据科学团队来支持他们的其他业务。要小心,从招聘和资源管理的角度来看,嵌入数据科学家更难——这些 IC 需要有高水平的商业敏锐度,他们不会在其他任何事情上工作。因此,在为嵌入式结构招聘员工时,时机更为关键。

嵌入式数据科学家应该尽可能长时间地向中央数据科学部门报告。嵌入肯定会导致业务环境的知识孤岛。这里的目标是尽可能长时间地调整其他一切。数据科学家如何工作、协作、共享代码和结果、评估成功。这是针对知识转移、的优化,我们稍后会谈到。

当你捉襟见肘时,向外看,扩大你的团队规模。但是要非常挑剔,尤其是更早的时候。永远不要低估糟糕招聘的复合成本。要深思熟虑,不仅要评估人才,还要看是否是合适的人才。你需要一个研究型的雇员来不断完善业务的核心部分,还是需要一个快速行动的 IC 来支持许多团队,完成许多 2-3 天的问题来获得 90%的正确答案,然后继续下一件事?在接下来的六个月里,这些需求会有什么变化?

最后,根据你的非技术业务团队的能力和支持做出人事决策。他们能力如何?在这家公司做分析师意味着什么:轻 Excel 技能还是重 SQL?您公司的其他部门与数据科学团队的关系如何?业务利益相关者是强烈要求 DS 解决方案,还是抗拒改变?我交谈过的大多数公司都是技术型的(< 10 年历史,裸露的砖块,免费的十字架,站立的桌子,桌上足球),并希望获得更多的数据科学支持,但我与一家 40 多年历史的媒体公司进行了一些最有趣的对话,该公司以不使用技术和自动化而自豪。我从首席运营官那里得到的建议是:

我们不希望这些人在组织中四处游荡,寻找需要解决的问题。最坏的想法是把它们抓来放走。你必须有一个与愿意接受数据文化的利益相关者高度接触的模型。花点时间与目标团队坐下来,听听他们的痛点、机会点,以及对他们的评估。让他们问:“你能给我们展示一下你在做什么吗,它是如何令人沮丧的,我们每天都在做什么,我们是如何获胜的。”

首席运营官的经历让我大开眼界;在我工作过的所有地方,企业都想要更多的数据科学资源。这不是普遍真理。作为一名经理,你需要了解企业的数据文化,以及利益相关者为你的 ICs 提供成功所需的环境和支持的能力。你必须在 DS 团队和公司其他人之间建立信任点,这需要雇佣能够与你的利益相关者合作的 ICs。你的数据科学家越是以商业为导向,你的公司越是技术能力强和开放,这就变得越容易。

最大化您团队的知识转移

我开始我的项目是为了传达这一点,我怎么强调都不为过。IC 数据科学家可以像对待个人运动一样对待他们的工作,而你的工作就是让他们像团队一样工作。Kaggle 和大多数数据科学教育资源都是个人行为。你不能假设一个具有定义的工作流和编码标准的协作团队会自己出现,事实上,我见过相反的情况——个人并肩工作,在他们的本地机器上,用 Python 2.7、3.5 和 r 多次解决相同的问题。

你的目标必须是增加团队成员之间的知识转移和指导,这将产生更好的代码和更强大的团队。这需要从“个人贡献者”到“团队成员”的文化转变。没有这种转变,你就无法培养出工业级的数据科学团队。你必须强调,集成电路评估将不仅仅基于项目,还基于开发其他项目和改进团队工作流程、标准和工具。从代码审查开始。

代码审查:通常,人们认为这是一种在网站崩溃之前检测有缺陷代码的方法。这当然是好的,也是必要的,(当我忘记在“ORDER BY”中的“DESC”来对产品排名进行排序时,我会喜欢代码审查,这导致 Wayfair 在四个小时内从最差到最好地推荐项目,这在当时是一个 20 万美元的错误),但当代码不能关闭网站时,或者没有人在技术上像编写它的人一样有能力时,代码审查通常被视为没有必要。

这错过了代码审查最好的部分:这是一个学习机会,一个专门的“双向道”知识转移,迫使团队成员学习其他人如何编写代码。团队中最没有经验的成员可以从审查别人的代码中学到很多他们不理解的东西,而最有经验的成员可以学习如何指导。代码评审不应该只是回答这个问题,“这会破坏网站吗?”。审查应侧重于:

  • 这段代码是否可读、有弹性、注释良好、符合团队标准?是正确的抽象/参数化/模块化水平吗?(计算机科学原理)
  • 这些数据科学和统计方法是否合理?(数据科学原理)
  • 这些连接是否有效,这些表的结构是否针对日常插入进行了优化,它们的设计是否正确(基于它们应该是读的还是读/写的)?这对以任何方式使用 Hive/HDFS/Presto 或 ETL 的团队来说都是必不可少的。(数据库管理员原则)
  • 这项工作是正确的,可操作的,令人信服的,表达良好的,可实施的吗?(商业原则)

为了使知识转移和代码审查有效,团队必须对“好”的样子有一套共同的信念。因此,管理人员必须以协作、灵活的方式定义一套团队标准和工作流程——同时告诫人们,鼓励个人寻找更有效、更强大的方法来改进这些标准和工作流程。对这个问题的答案进行逆向工程:“如果我团队中的一名数据科学家想出了一种更好的方法来做某事,那么这种知识如何每天以非选择退出的方式传递给其他人?”Domino 写道:目标是以模块化的方式实现复合协作。“当高绩效的数据科学团队站在前人的肩膀上时,他们的工作效率最高。”这是我理想世界中的一个团队工作流程/标准集的例子:

我们的团队使用相同版本的库 Python、Scikit Learn、Presto、Tensorflow 和作为 SQL IDE 的 DBeaver、作为 Python IDE 的 Jupyter 以及用于作业调度的 Airflow。在所有这些领域,人们有不同的偏好和不同的知识基础。这是一种优势——帮助我们提出新的和改进的管道和标准。就像个人因对业务产生积极影响而受到鼓励和奖励一样,他们应该不断寻找更有效或更强大的方法来改善团队的工作流程和习惯。将有代码审查,无论是业务案例,效率案例,以及代码是否写得正确。(符合 PEP8 标准,棉绒)。只有格式正确的代码才会被提交。代码审查被看作是一个教授和学习以及捕捉错误的机会。回购是在项目层面上组织的,人们通过协作工作,让新的集成电路达到速度,并让有经验的集成电路有能力承担教学/领导角色。

关于业务背景和过去团队项目的知识也必须转移。公司有许多名称的解决方案:站立,讲故事活动,学习学院,午餐和学习,头脑风暴会议,知识仓库,维基。Airbnb 有一篇关于数据民主化的博文,他们所有的项目都以一页纸开始,上面写着“项目的意义是什么,我将如何去做,我将如何衡量成功”。

这些解决方案中的任何一个都可以在给定的时间点上为一个团队工作,但是我与之交谈的许多人都警告说它们不能很好地扩展。关于讲故事活动:“我们曾经有两个团队,每个月做一次报告。现在有九个团队——我的人已经工作了六个月,但我不知道三个团队在做什么。”在头脑风暴会议上:“当我们还小的时候,这很有效,现在我有一些我没见过的人给我建议,告诉我如何解决他们以前没见过的问题。”午餐时,他学到:“一旦事情变得太大,人们就不再去了”。

代码评审必须以非选择退出的方式执行,当你的组织规模扩大到原来的三倍时,知识转移也必须如此。您的工作是让您的团队支持有效的流程,并传达数据科学 IC 工作的一个重要部分是记录他或她试图解决的问题、他们如何解决问题以及解决方案的成功。

有意识地安排你的优先顺序

IC 数据科学家和商业利益相关者的一个普遍共识是,他们不知道项目是如何优先排序的。优先级划分的范围从高度数据驱动(“我们根据每个数据科学家周的估计收入增长来考虑所有事情”)到故意不根据数据驱动(“没有必要确定优先级,我们只是做重要的事情,事情不需要被证明是合理的或优先的”)到有点政治性(“这是一个足够小的公司,知道你是否过度使用或未充分使用数据科学资源”)到高度政治性(“我们支持的每个团队都平等地使用我们的时间”)。同样,IC 数据科学家扮演的角色从“我选择我的项目”到“我不选择我的项目,十个项目被分配给十个人,他们不知道为什么。”

作为数据科学领导者,您必须迫使您的公司在“业务影响”是什么以及如何衡量它这两个问题上保持一致,并且您必须确保您的 ICs 和业务利益相关方之间关于优先顺序的对话是自下而上和自上而下的。您必须引入数据科学团队通常不具备的透明度。一位 DS 经理告诉我,“每个项目都有不同的价值,我们无法相互比较。”如果你不能比较项目,除了政治上的,你怎么可能分配它们?在同样的程度上,你必须认识到,在数据科学中,很难解释容易和几乎不可能之间的区别。您的数据科学家对于要做的业务问题肯定有不完善的信息,您的利益相关者对于解决方案需要做多少工作肯定有不完善的信息。您必须从业务利益相关者和 ICs 处获取项目,汇总关于这些项目的预期成本/收益的完整信息集,汇集这些数据,并以一种对各方都显而易见的方式呈现这些数据。

这一过程的关键是确定您的数据科学团队是合作伙伴,而不是服务提供商。你的团队必须通过证明他们的价值来建立信任和权威:寻找好的项目,获得巨大的成功,并就此进行报告。这允许团队开始文化:“如果你有一个想法,我们会和你一起工作,但我们有一个桌子上的座位。”你应该避免门票系统和政治,团队资源按比例分配给依赖的利益相关者。做到这一点的最佳方式是证明你和你的团队有足够的业务背景,可以与他人合作——如果你给我们解决这些问题的空间,我们会的。

强调解决方案的最低复杂度

数据科学 IC 行动手册了解何时完成 部分与本部分高度重叠。翻新:通过学术或在线方式接受教育的 IC 数据科学家没有接受评估其算法复杂性的培训。许多 IC 承认他们不知道问题何时解决,大多数表示时间管理是他们正在努力改进的。你的工作是建立准确性与时间和复杂性之间权衡的框架,并帮助你的直接下属找出他们应该继续前进的时间。认识到你的集成电路有一种自然的倾向,那就是花费太长的时间来构建太复杂的解决方案。设置护栏是这项工作的一个重要部分,培养团队的常识和直觉以正确的方式开始解决问题也是如此。

你必须平衡这些标准和个人发展:认识到人们确实需要学习和成长的空间,这需要用新技术解决新问题。众所周知,数据科学组织深受对工具的执着之苦,我一直站在这两方:在我职业生涯的早期,我故意将自己放在较低优先级的点击流项目上,以学习分布式计算原理/Hadoop/Hive,当队友们做了同样的事情,为了构建卷积神经网络而构建卷积神经网络时,我感到沮丧(我们稍后将弄清楚图像分类如何改善业务)。目前,这种对工具的执着是 Tensorflow、Spark Streaming、GANs 和 RNNs,但过去是其他东西,将来也会是其他东西。多米诺称之为“一种‘银弹’思维文化,一些数据科学家认为只要获得 Spark Streaming 和 TensorFlow 就能解决他们的所有问题……在许多情况下,数据科学家将他们的工具争论作为一种荣誉徽章,这个徽章被包装在他们的身份中。”一个 IC 告诉我,“我知道 Tensorflow 不是解决我的问题的正确方法,但总是有同行的压力要使用这个很酷的东西。该公司的博客帖子和学习学院不是为了减少随机森林分类器的客户流失。这个行业发展如此之快,我需要跟上。”另一个人说,她衡量自己的个人成长,她实施了哪些新技术。

这两位数据科学家都不是不讲道理。拥有 Tensorflow 和 Spark Streaming 的经验可以在简历上产生很大的影响,你不会学到用同样的工具解决稍微不同的问题。DS 经理必须意识到具有正确工具/复杂性的解决方案与作为学习机会的解决方案之间的矛盾。您必须在工程解决方案与团队快乐和发展之间找到适当的平衡。像其他事情一样,认识到这是你需要有意识的、透明的和灵活的事情。一个很好的解决方案是给你的团队一个明确定义的时间段,让他们可以用他们想学的工具做他们想做的事情,但也给他们提供指导和阻力:“如果你想做一个更复杂的思考,告诉我你为什么要支付这个成本。”与你的团队交谈,确保他们感觉像是在学习,当你有机会让某人用对他们来说是新的解决方案或技术解决实际问题时,相应地分配“延伸”项目。

启动和扩展数据科学团队:项目摘要

原文:https://towardsdatascience.com/launching-and-scaling-data-science-teams-project-summary-1761572eaa99?source=collection_archive---------18-----------------------

将数据科学融入组织的最佳实践行动手册

这是一个关于公司内数据科学领导力和组织的秋季学期独立项目的最终成果。我在哈佛商学院读 MBA 的第二年,技术与运营(TOM)部门的Kris ferre IRA是我的导师。我采访了 13 家公司的 29 个人(DS 个人贡献者、DS 经理、非技术业务领导)。我利用这些采访制定了启动和扩展数据科学团队和职业的最佳实践行动手册:一份针对 数据科学家 ,一份针对 数据科学经理 ,一份针对 业务利益相关者

介绍

这个项目的想法是在我开始一份新工作时产生的。数据科学入门总是一个混乱的过程,但我喜欢按照这个顺序开始:数据、代码库、工作流。深入一个数据集需要你张开双臂去寻找任何地方,任何人都在记录你可能感兴趣的东西,并找出公司具体的细微差别。它会问这样的问题:“重定向邮件存储在哪个数据库中?那个服务器的登录信息是什么?agent_iduu_idagentuu_id有什么区别?为什么order_id一栏出现负数和重复数?”概括地说,我将每天使用哪些表和数据库,并最终记住它们?

接下来是代码库:在我之前的那些人是如何用他们挖掘的数据建立管道、预测、解决方案和分析的?他们已经解决了哪些我不需要自己解决的问题?

最后,工作流程:这个团队如何编写代码?他们坚持自己的标准是什么?他们如何对项目进行优先排序,验证和交流结果,分享知识,他们如何让自己变得更好?

我发现的数据集是标准的——大部分是结构化的 SQL 表,分布在几个文件系统中,还有一些额外的文本和图像数据。然而,代码库和工作流程与我习惯的非常不同。团队成员在他们的本地机器上编写、测试和保存代码。代码库是个人的(“Ian 的 git repo”),而不是基于项目的(“定价算法 v2”)。团队成员用 R 和 Python 解决同样的问题。团队坐在一起,却不在一起工作。

我以前在类似的项目中用类似的数据集做过类似的工作,但是从组织上来说,这是一个很大的不同。我过去的团队有一个标准化的工作流程,共享一套开发工具,共享一套编码标准。团队设计和工作流程旨在增加团队成员之间的知识转移和指导,从而产生更好的代码、更好的业务成果和更强大的团队。对你的评估不仅基于你作为个人贡献者的工作,还基于你作为团队成员的工作;基于发展他人和改进团队工作流程、标准和工具的评估。

我的经历迫使我意识到,尽管有许多令人难以置信的方法来培养数据科学家,但在如何在公司内组建和扩大数据科学团队方面,几乎没有资源或专家。将数据科学团队整合到更广泛的组织中可能会导致困难、误解和运营效率低下。个人贡献者数据科学家(ICs)、数据科学管理和非技术业务领导者都有机会帮助弥合组织之间的信息鸿沟,并改变围绕数据科学家/数据科学团队工作的文化。

我调查了依赖数据科学团队解决核心问题的公司的 ICs、数据科学管理和非技术业务利益相关方。我试图找出他们是如何工作、沟通、协作、区分优先次序和评估的——以及这个过程中的盲点和偏差。我利用这些对话编写了三份启动和扩展数据科学团队和职业的最佳实践指南:一份针对数据科学家,一份针对数据科学管理,一份针对依赖于数据科学团队的业务利益相关者。但是,要理解当今数据科学团队的问题,我们必须理解我们是如何走到这一步的。

数据科学的兴起

“数据科学”的兴起是迅速的,并且有据可查。根据 Google Trends 的数据,这个词开始流行是在 2012 年,也是哈佛商业评论将“数据科学家”命名为 21 世纪最性感的 T2 工作的时候。一个产生数百万个数据点的现代公司必须有一个数据科学团队,并且普遍存在人才短缺的问题。HBR 的文章描述了 2012 年的挑战:

如果利用大数据取决于雇佣稀缺的数据科学家,那么经理们面临的挑战是学会如何识别人才,将人才吸引到企业,并使其富有成效。这些任务都不像其他既定的组织角色那样简单。首先,没有提供数据科学学位的大学项目。对于该角色在组织中的位置、数据科学家如何增加最大价值以及如何衡量他们的绩效,也没有达成共识。

很明显,情况发生了很大变化:六年后,现在有 160 多所大学授予“数据科学”学位。但是许多挑战和机遇依然存在。数据科学家仍然可以来自任何地方。成为一名数据科学家的过程是很容易实现的,很少有令人满意的/高薪的工作是这样的。除了付费学位,还有吴恩达的 Coursera 机器学习课程、edx.orgMITx、HarvardX、ColumbiaX 或 UCSanDiegoX 的课程、物理基于网络的教科书、 Youtube 频道个人博客公司博客等等。

一系列教育选择的价格点和数据科学家背景的多样性导致了广泛的技能组合、兴趣和解决问题的风格。在一家公司内,这对于思想的多样性是一个巨大的积极因素,会带来非常积极的内部学习环境。这也会导致商业敏锐度/背景、兴趣和一般工作经验的巨大差异。有些杰出的数据科学家从未在 Outlook 中预定过会议室,从未将某人转移到密件抄送:或进行过绩效评估。Kaggle 有一位竞赛特级大师,他是十七岁 ;说明了开源教育是如何精英化的,也说明了一个 17 岁的孩子在这种特定的人才评估中可能是最棒的。

卡格尔

Kaggle 是一个基于数据科学挑战的网站,在这里不同天赋水平的用户可以聚集在一起,竞争建立精确的模型。一家对招募数据科学家感兴趣的公司发布了一个测试和训练数据集,解释了相关功能,并要求用户预测一个输出。一个竞争的例子: Airbnb “挑战你预测一个新用户将在哪个国家进行他或她的第一次预订”,通过发布关于用户、浏览器会话和国家数据的伪装数据。提交的格式是高度指定的,评估指标也是如此。个人提交预测,最准确的会登上公共排行榜的首位。排名靠前的提交经常被微小的数量分开。公司可以利用竞争领导者来发现和招募顶尖人才。

Kaggle 竞赛可以成为开发和展示建模技能的重要资源。Kaggle 的问题是 Kaggle 的吸引力:它给你所有你需要的数据,告诉你要预测什么。实际上,这是最难做到的部分。我采访的一位数据科学经理说:

真正起作用的是你如何收集数据,制定问题,并告诉模型它需要学习或预测什么。我见过一些数据科学类型的人在数据科学环境中效率很低。Kaggle 是狗屎,不是数据科学家做的,大多数系统不是这样。我们大部分时间都在问,需要解决的问题是什么,你是如何制定的?一旦你进入模型拟合阶段,实现是微不足道的,我发现旋钮调谐的回报相当低。

Kaggle 风格的竞赛(和大多数面试)也不评估时间和复杂性的权衡,因为它们本质上是根据单一标准评估的。行业数据科学解决方案必须权衡复杂性。众所周知,网飞举办了一场比赛来改进他们的推荐算法,他们也因没有实现获胜的算法而出名:“我们测量的额外准确性收益似乎并不证明将它们引入生产环境所需的工程努力是合理的。”Kaggle 没有强迫竞争对手开发一个框架,来评估通过另外一百行代码或在一个项目上再花两天时间来解锁 0.1%的收益是否有意义。

出色地将数据转化为对某一指标的预测是一项关键技能。然而,正如马克斯·伍尔夫写的:“建模只是一个非常复杂的系统的一部分(通常也是最简单的部分)”。如果你能做到这一点,并且只能做到这一点,你就是数据科学中相当于球门线往回跑的人,你忽略了剩下的 90%。不管来源如何,数据科学教育可以让 IC 在构建和调整复杂模型方面极具天赋,但对第一天的工作毫无准备。那么,如何发展、扩大和管理数据科学家团队呢?

成为一名数据科学经理并不容易,也没有多少人拥有领导数据科学团队的相关经验。如果你认为现代数据科学已经存在了不到十年,本质上,没有人有十年的管理经验。由于该行业刚刚起步,最佳实践很难获得。资源有限。很少有榜样可以教你如何领导,还有许多持续的挑战。

数据科学经理的任务是组建一个 IC 团队,了解他们的背景、动机、优势和劣势。当构建他们的团队和数据架构时,他们必须面对困难的决策。“所有权”的问题会不断出现。领导者必须帮助填补数据科学家的空白:你如何为你的员工提供成功所需的商业环境?你如何建立项目优先化、代码标准、时间和复杂性权衡的框架?你如何教导你的团队取得成功?管理人员必须调整组织、数据平台、项目工作流程和整体文化,以建立一个优秀的团队;尽管我们知道这个问题没有确定的答案:“理想的数据科学团队是什么样的?”

数据科学家的领导还必须指定业务利益相关者与数据科学部门互动的方式。当一个部门有一个请求时,这项工作是如何沟通、区分优先级、执行和报告的?最终产品是什么样的,谁对最终产品负责?虽然这应该是微不足道的,但通常很难就项目何时完成达成一致。业务方面的个人如何支持数据科学家,反之亦然,如何促进这些对话?

企业利益相关者和数据科学团队之间的关系因公司而异。“非技术”是一个谱,不同公司差异巨大。公司“数据文化”的力量和业务利益相关者的分析理解水平高度预示着数据科学团队的适应程度。如果你是一名数据科学经理,你如何确保你的团队的工作甚至可以被必要的利益相关者消费/实现?

商业利益相关者也面临着一场艰苦的战斗。数据科学家听起来总是像在说一种不同的语言。如果你第一次与数据科学团队互动,你会觉得他们是完全不同的物种。你如何弥合这一差距?你知道“数据科学”涉及使用数据来推动业务,但你如何了解这个团队能为你做什么,更不用说他们是否能真正执行该计划。你如何对你所要求的事情进行优先排序,结果你如何做出更好的决定?数据科学家如何帮助您取得成功,您如何帮助他们取得成功?

我希望这些最佳实践行动手册能有所帮助:

以多种语言启动 ParallelDots AI APIs

原文:https://towardsdatascience.com/launching-paralleldots-ai-apis-in-multiple-languages-d786926e72f6?source=collection_archive---------14-----------------------

随着持续数十年的数字化浪潮,数字化形式的文本数据量呈指数级增长。理解和分析这些数据变成了一种练习,就像从消防水管里喝水一样。在 ParallelDots AI APIs,我们旨在让您的生活更简单,并帮助您提供工具,通过几个 API 调用或舒适的 excel 表格中的简短公式来有效地分析这些数据。我们的客户一直敦促我们将我们的服务扩展到多种语言——这正是我们所做的。我们现在为真正的全球客户群提供以下关键 API 语言选项(情感分析、情绪分析和关键字生成器):

如何使用我们的多语言 API?

请按照以下步骤使用 API:

有问题吗?—请随时联系我们 apis@paralleldots.com 公司

你也可以点击查看演示

定价

多语言 API 面向利基市场,作为我们高级 API 的一部分提供。定价计划的详情如下:

  • 需要信用卡
  • 每月免费 100 次点击
  • 每月 100 到 100 万次点击——每 1000 次点击收取 2 美元

结论

这一新举措使我们离成为全球客户群首选文本分析解决方案的使命更近了一步。这是对我们最近提高模型准确性的举措的补充,通过新的 API 添加了更多的分析选项,并添加了新的交付选项(通过 Excel 插件)。如果您是一家寻求解决特定文本分析用例的企业,我们将很乐意通过提供定制的解决方案来帮助您。

最后,如果您有任何问题,或者希望我们专门为您选择的任何特定语言提供 API,请联系我们 apis@paralleldots.com。

法律与词序:法律技术中的自然语言处理

原文:https://towardsdatascience.com/law-and-word-order-nlp-in-legal-tech-bd14257ebd06?source=collection_archive---------6-----------------------

法律的核心是语言,所以长期以来,基于自然语言运行的软件在法律职业的某些领域发挥作用也就不足为奇了。但是在过去的几年里,人们对将现代技术应用于更广泛的问题越来越感兴趣,所以这篇文章着眼于自然语言处理在当今法律领域的应用。

法律 NLP 前景

自然语言处理的应用,以及更普遍的人工智能,在法律行业中并不是一件新鲜事。搜索在线法律内容的最早系统出现在 20 世纪 60 年代和 70 年代,法律专家系统是 20 世纪 70 年代和 80 年代讨论的一个热门话题(例如,参见 Richard Susskind 的《法律中的专家系统,牛津大学出版社,1987 年)。但在过去几年中,人们对该领域的兴趣大幅上升,正如你可能预料的那样,包括越来越多的初创公司声称在特定的法律应用背景下应用深度学习技术。

在最近的一个项目中,我不得不回顾 NLP 是如何被应用在法律技术中的。这是一个人口密集的空间:斯坦福大学的一个网站列出了 1084 家“改变法律运作方式”的公司。在回顾这样的风景时,有一张地图会有所帮助。方便的是,法律实践是一种结构良好的活动,对于典型的律师事务所面临的许多特定任务,可以提供点解决方案。我认为 NLP 在五个法律活动领域发挥着越来越大的作用:

  • 法律研究:寻找与法律决定相关的信息
  • 电子发现:确定文档与信息请求的相关性
  • 合同审查:检查合同是否完整并避免风险
  • 文档自动化:生成日常法律文档
  • 法律建议:利用问答对话提供量身定制的建议

这些简短的定义隐藏了一些复杂性,我将在下面依次考虑每个领域时解开这些复杂性。

法律研究

法律研究是寻找支持法律决策所需信息的过程。在实践中,这通常意味着搜索成文法(由立法机关制定)和判例法(由法院制定),以找到与手头某一具体事项相关的内容。

这是你在法庭剧和访谈节目中看到的律师办公室墙壁上整齐排列的厚厚装订书籍的主要目的。然而,这些书经常被称为“布满灰尘的大部头书”是有原因的:在法律图书馆的桌子上仔细阅读书页早已被电子搜索和检索机制所取代。

LexisNexis (当时简称 LEXIS)最早出现在 20 世纪 70 年代初,最初提供俄亥俄州和纽约州判例法的全文搜索;它就从那里开始生长。到 20 世纪 70 年代末,律师们能够通过 1200 波特的调制解调器从专用终端使用拨号服务访问数据库。到了 20 世纪 90 年代末,这些数据都出现在了网上。今天,Lexis Nexis 声称拥有超过 30TB 的内容。 Westlaw ,法律数据库领域的另一个巨头,也成立于 20 世纪 70 年代中期,并于 1996 年被汤姆森公司(现为汤姆森路透)收购。再加上沃尔特斯·克鲁瓦彭博法律,你就有了这个领域的四大老牌供应商。大多数律师事务所都会订阅部分或全部这些服务。

尽管事实上主要的参与者已经非常成熟,但是,一些新的参与者已经通过提供旨在提高搜索精度和召回率的更智能的技术占领了一些市场份额,超过了使用“传统技术”所能达到的效果,在这里“传统技术”相当于良好的老式布尔搜索和手工构建的索引。显然,搜索结果的质量很大程度上取决于提出正确的查询。两个案例正文(成立于 2013 年,出资 2080 万美元;此处提供的所有资金数据均来源于 2018 年 11 月底左右的 Crunchbase)和 CaseMine (成立于 2013 年,资金情况不明)提供的界面可以让你通过上传一段话甚至整个简介来找到相关材料,为搜索提供上下文,从而支持“按文档查询”。在每种情况下,这种功能都通过一系列简洁的 UI 特性得到了增强,从而方便了搜索任务。这不仅避免了在适当详细的搜索查询上花费精力的需要,还增加了通过典型查询没有找到的附加相关材料将被定位的可能性。

采用稍微不同的方法,使用 IBM Watson 的 Ross Intelligence (成立于 2014 年,融资 1310 万美元)和使用 Vincent 产品的 vLex (成立于 1998 年,融资 400 万欧元)提供自然语言查询界面,因此“你可以像与另一位律师交谈一样提出你的研究问题”。

当然,四大已经迅速建立了自己的“人工智能”解决方案。2018 年 7 月,LexisNexis 推出了 Lexis Analytics ,这是一款法律研究工具,其中包括机器学习和 NLP 初创公司 Ravel Law 的收购。几乎与此同时,汤森路透推出了 WestSearch Plus ,这是一个新的搜索引擎,声称使用了最先进的人工智能。

电子发现

电子发现,或称 e-discovery,是为响应法律诉讼或调查中的出示请求而识别和收集以电子方式存储的信息的过程。面对可能驻留在典型硬盘上的成千上万的文件,这里的一个关键问题是将这些内容分成相关的(或“响应性的”,在该领域的术语中)和不相关的。在最近与苹果公司的专利纠纷中,三星收集并处理了大约 3.6TB,即 11,108,653 份文件;在 20 个月的时间里处理这些证据的费用据说超过 1300 万美元。

如今,市场份额之争围绕着优化技术展开,这些技术用于尽可能快速高效地对文档是否相关进行分类。这一过程被称为“技术辅助审查”(TAR),多年来一直是 TREC 法律轨道的活动焦点。与法律研究一样,传统方法包括关键字或布尔搜索,然后是人工审查。更现代的方法使用机器学习进行文档分类,在法律专业中称为“预测编码”。您希望最大限度地提高精确度和召回率,同时将所涉及的工作量(就一个人必须注释或审阅的文档数量而言)保持在一个合理的水平。法律界对各种技术的利弊存在一些争论,特别是围绕什么算作合理的种子集,以及被动学习还是主动学习更好,其中前者涉及随机选择文档进行人工标记,而后者涉及对不确定或假设相关的示例进行有意的机器选择。(此处见,此处。)

这个领域最大的玩家可能是extero(成立于 2004 年,融资 1 亿美元;Exterro 的博客是电子发现的有用信息源。他们的最新技术称为智能标签,避免了用户提供人类标记文档的初始种子集的需要,从审查过程的一开始就选择最相关的文档进行审查。 DISCO (成立于 2012 年,融资 5060 万美元)在其“优先审查”流程中也有类似的基于深度学习的解决方案。

Everlaw (成立于 2010 年;另一方面,资助 3460 万美元)似乎仍在使用一种方法,即必须首先标记初始种子集(他们建议 200 个文档)。UI 功能可能是重要的差异化因素: Relativity (成立于 2001 年,融资 1.25 亿美元),之前被称为 kCura,也提供了一个手机应用程序,这样你就可以“在通勤途中或沙发上编写文档”。律师也是全天候的。

有趣的是,通用的 NLP 提供商也正在进入这个领域。OpenText 推出了一个名为 Axcelerate 的电子发现平台;以翻译产品和服务闻名的 SDL 提供了一个[多语言电子发现解决方案](https://www.sdl.com/software-and-services/integrations/solutions-forediscovery. html),通过翻译可以访问外语案例相关内容。

合同审查

律师的一个常见活动是审查合同,提出意见和修改,并建议他们的客户是否签署或谈判更好的条款。这些合同可能相对简单,如保密协议,也可能非常复杂,长达数百页。

自动合同审查系统可用于审查就其包含的内容种类而言相对标准化和可预测的文件。这个过程包括将合同分解成单个的条款,然后对每个条款进行评估,要么提取关键信息,要么与某个标准进行比较(该标准可能只是公司持有的此类合同的其他实例的集合)。因此,举例来说,一个合同审查系统可能会指出没有涵盖贿赂的条款,或者指出涵盖价格上涨的条款没有规定百分比限制。

合同审查可能是在单个合同的层面上,或者说,在对公司收购进行尽职调查的情况下,它可能涉及审查数千份存档的合同。在后一种情况下,该技术还开始纳入被称为法律分析的方面,聚合整个数据集的信息以检测异常和异常值,并生成图表或表格,以便于跨文档进行比较。

在过去的几年里,合同审查引起了人们极大的兴趣。早期的方法再次使用关键术语和标题的存在来指导信息提取,很可能许多产品仍然使用一些基于规则的技术;然而,毫不奇怪,几乎所有最近进入该领域的人都在使用更复杂的机器学习技术。

这里最大的三家 140 强企业是 Kira Systems (成立于 2015 年,融资约 6500 万美元) Seal Software (成立于 2010 年,融资 4300 万美元)和 LawGeex (成立于 2014 年,融资 2150 万美元)。Kira 为涵盖一系列合同类型的约 500 种常见条款提供了预建模型;您可以指出哪些与正在审查的合同相关,还可以为尚未考虑的条款构建定制模型。Seal 提供了类似的功能,但增加了一个逻辑引擎,允许您将业务逻辑应用于从已审核的合同中提取的数据;LawGeex 强调将合同与预先定义的公司政策进行比较的能力。

新进入者和小进入者的一个典型策略似乎是从关注非常具体的文档类型开始,如 NDA、房地产租赁和隐私政策,然后随着公司赢得客户和吸引力而增加处理的文档的范围。勒弗顿(2012 年资助;融资 1500 万欧元,19 从 DFKI 剥离出来,主要专注于房地产文件。它以拥有大量房地产投资组合的公司为目标,用 20 种语言处理合同。其他值得一看的较小公司有 eBrevia (成立于 2012 年,融资 430 万美元) Eigen Technologies (成立于 2014 年,融资 1300 万美元) LegalSifter (成立于 2013 年,融资 620 万美元) Luminance (成立于 2003 年,融资 1300 万美元),但还有许多其他公司。

毫不奇怪,通用文本分析公司也被这个用例所吸引:参见 ABBYY 合同文本分析Ayfie 合同分析OpenText Perceptiv

ContractProbe 和 T2 privacy policy check 都有在线演示,可以让你上传文件进行审核。这些产品比上面讨论的产品要简单得多,但是它们让我们了解了合同评审应用程序的功能。

文件自动化和法律咨询

文档自动化系统和法律咨询应用程序之间有一个模糊的界限,所以我将把这两个类别放在一起考虑。

法律顾问是交互式系统,它根据系统提出的一系列问题,根据用户的情况和要求提出建议。在许多情况下,输出是某种法律文档,因此法律建议通常相当于文档自动化。

另一方面,文档自动化系统通常使用某种填空模板机制来创建符合特定标准的法律文档。在某些情况下,生成文档所需的数据是通过反复的问答对话框获得的:如果您愿意,可以称之为聊天机器人。在这种情况下,文档自动化系统具有与法律咨询系统提供的界面相同的界面。

最受公众关注的法律顾问是 DoNotPay,这是一个互动工具,其最初的重点是[帮助普通公众对停车罚单提出上诉](https://www.theguardian.com/technology/2016/jun/28/chatbot-ai-lawyerdonotpay- parking-tickets-london-new-york)。从那时起,应用程序的范围已经大大扩展了;在撰写本文时,DoNotPay 应用程序支持 [14 种不同的用例](https://www.artificiallawyer.com/2018/10/12/the-genius-of-donotpay-givingyou- what-is-already-yours/),包括对抗不公平的银行、信用卡和透支费用,当司机走错路时从优步和 Lyft 获得退款,以及为延迟的包裹交付申请退款。

斯坦福大学的学生约书亚·白劳德为了回应自己的停车罚单经历,创造了 DoNotPay 但是律师事务所也对提供法律咨询系统感兴趣。自动化在这方面有明显的优势,使那些可能负担不起或不愿意支付法律服务费用的人能够获得法律服务。

因此,例如,澳大利亚律师事务所 Norton Rose Fulbright 在 2017 年底发布了一款针对隐私法问题的聊天机器人。该工具使用 IBM Watson 构建,回答了关于数据泄露的标准问题。该公司后来扩展了应用程序,以处理 GDPR 查询。

Neota Logic ,从 2010 年开始,提供了一个创造专家顾问的平台;事实上,这项技术的应用范围比这要广得多,因为它还可以用于工作流自动化和相关任务,包括文档自动化,这是我接下来要谈到的。

法律文档自动化应用已经存在很长时间了,可以说是最早的商业自然语言生成系统之一。一些研究人员不愿意将这些基于模板的系统称为 NLG,但事实是,所使用的技术与当今领先的商业 NLG 供应商提供的技术相似。

如上所述,这些系统通常通过填写表格或通过问答会话从用户处收集相关数据来工作。然后,通过条件文档组装和模板槽填充的组合,以基于规则的方式使用累积的数据来制作定制的文档。

这一类别中最著名的是汤森路透的合同快递,其目标市场是希望提高效率的律师事务所。还有其他一些著名的参与者,包括 Rocket Lawyer (成立于 2008 年,融资 4620 万美元),它更关注消费者,以及 Neota Logic(如上所述),它们既提供通用的智能文档自动化工具,也提供更加面向最终用户的特定应用程序调用 PerfectNDA

更一般地说,许多组织将其文档自动化产品定位于诉诸司法领域,使定制的法律文档易于为公众所用。两个这样的例子是 A2J 作者helpesellegal

也有公司提供旨在帮助起草专利的产品:参见规范涡轮专利

最后判决

如同在许多其他领域一样,法律专业的工作性质更普遍地受到 NLP 和 AI 的威胁。2016 年初,德勤发现[法律部门 39%的工作将在未来十年实现自动化](https://www.legaltechnology.com/latest-news/deloitte-insight-100000-legalroles- to-be-automated)。最近,麦肯锡[估计 22%的律师工作和 35%的法律助理工作可以自动化](https://www.linkedin.com/pulse/how-much-what-lawyers-do-can-automatedlook- new-research-peter-nussey/)。正如在其他领域常见的那样,你经常会看到积极的一面,通常的说法是“技术解放了工人,让他们做更有趣的事情”。但是技术吸收的利与弊是该行业偶尔激烈辩论的焦点,理查德·特罗曼斯将其描述为由想要保持现状的保守派和想要改变的进步派组成。当然,变革的一个主要障碍是法律职业传统上是以计费时间为基础的。在这种情况下,如果一项技术提高了效率,它也会减少你可以在时钟上投入的时间。另一方面,面对世界各地诉诸司法运动日益增长的需求,传统方法的中断是不可避免的。

我得说陪审团已经不在这个案子上了。

如果你想收到关于商业 NLP 世界正在发生的事情的简短每周简讯, 在 NLP 中注册本周。

延迟加载 R 中的数据

原文:https://towardsdatascience.com/lazy-loading-data-in-r-2b100acb63fc?source=collection_archive---------5-----------------------

最近,我发现自己需要加载和处理大型数据文件以显示在闪亮的仪表板上,但是一次性加载和处理整个文件需要很长时间。这将迫使用户在显示结果之前盯着空白屏幕看一段时间。我想出了一个粗略的解决方案来“延迟加载”数据,并根据需要处理它们。当我说延迟加载时,我的意思是只加载/处理用户当前需要的部分并缓存它们。想象一下 YouTube,一边看一边加载部分视频。

我觉得有两个关键的 R 概念值得解释,因为它们真正塑造了延迟加载技术:环境和方法调度。

环境和方法分派

在高层次上,我创建了一个定制的环境对象,并在需要时基于索引重写了[方法调度进程。

环境

r 不支持引用调用。在像C++这样的语言中,引用(指针)可以作为参数传递给函数。不过有一个解决方法,使用环境。环境是 R 的秘密“引用调用”。在这里,我使用它们来缓存我的使用环境的结果。当一个环境被传递给一个函数时,它被自动地通过引用传递,因为环境是而不是复制到 R 中的(更多在这里)。让我们看一个例子

A human can have only one age. And celebrating birthdays globally increments age by one, no matter where you are.

数组和方法分派

下一块是法派,具体是[上的法派。这非常类似于 Java 中的运算符重载。

A demonstration of method dispatch

第 11 行的输出并不是我们所期望的数组类对象的输出。定义一个[方法调度是将对象伪装成数组的简单方法。另请注意第 32 行,其中方法分派是用函数中的一些操作定义的,以支持返回结果之前的处理。

为什么要关心定义[方法调度呢?老实说,没关系。有了这种语法糖,代码读起来就简单多了。我喜欢让我的代码尽可能的干净和简单。

惰性装载

正如我之前提到的,我将延迟加载称为一种仅在需要时加载或处理数据的技术。想象一下 YouTube 或网飞,视频分部分加载,而且只加载用户想看的部分。如果任何一方要求用户等待完整视频下载后再播放,那将是一场灾难。从磁盘加载和处理大文件也是类似的概念。

Very generic lazy loader

这里我创建了一个接受inputsFUN的构造函数。inputs可能是一个数组,一个列表,或者另一个对象,基于你的用例。这里我做了一个数组。而FUN是一个函数,你可以用它来处理inputs中的每个元素。为了启用缓存,我还定义了一个returns数组。同样,这可以是任何东西,而不仅仅是一个数组。在第 8 行定义自定义类对于以后创建方法分派很重要。例如,如果我想延迟处理(平方一个数)一个数的数组,这将是理想的。

inputs <- 1:10
FUN <- function(x) x * x

我们期望的returns

returns <- c(1, 4, 9, 16, 25, 36, 49, 64, 81, 100)

对于 lazy process,当我从新对象lazy.object[idx]请求任何项目时,我希望它会返回该索引的结果。为了帮助索引,我定义了[方法分派。

你会注意到我所做的就是调用FUN并传递我想要处理的项目。如果您正在处理数组,那么您可以跳过 sapply,但是对于其他类型,这是合适的。对于列表,我会使用lapply

现在,为了缓存结果以备将来使用,我们对方法 dispatch 做了一点小小的修改。

Notice no processing message for code in line 25

第 3–7 行检查returns[i]是否为 NA,只有当它为 NA 时才进行计算。为了演示,我修改了函数,以便在调用它时打印消息。

为了更清楚地了解情况,我还为对象定义了一个print方法分派。

Notice line 24, with populated values in positions 3:8

如您所见,当创建对象时,ll有一个空的returns数组。当ll[3:8]被计算时,结果被缓存。同样,虽然我使用了数组和一个简单的函数,但是可以很容易地修改它来支持复杂的对象和函数。

趣味中的多重争论

有时你需要做的不仅仅是计算平方,也许是两个数的和。因此,您的函数需要两个(或者可能更多)输入。有两种方法可以实现这一点:

  1. 为环境中的第二个输入定义一个新的inputs,并将两个值传递给该函数
  2. 使用带有多个参数的 R 的[

我将在下面介绍这两种方法,并说明我认为每种方法的最佳用途。

定义另一个input

我发现这种方法在两个输入相差很大或者依赖于索引时最有用。您将定义输入并更新方法分派。

对于更多的输入,这变得有些费力,但仍然比让用户等待要高一步。

传递带切片索引的参数

方法分派就像 r 中的任何其他函数一样,因此,像任何其他函数一样,可以向它传递多个参数。这个方法实际上要求你把...放在两个地方,这样你就完成了!当我对一些指数有相同的输入集时,我会使用这种方法。比如每个数字加 5。

Notice line 26

两种方法都很棒,但我个人更喜欢第二种。只是工作量更少:P

缓存失效

我想说这是一个高级主题,大多数普通读者可以跳过这一部分。如果输入有可能在运行时改变,那么我们需要一种方式通知加载器缓存的结果不再有效,需要重新计算。您可以创建一个新的对象,并重新计算或复制有效的结果,但有一个更简单的方法。为每个索引使用一个标志。

Cache invalidation

通过向每个索引添加一个有效的标志,加载程序只需检查是否设置了标志,并在需要时重新计算。我将[<-方法分派定义为语法糖。但要点是通过将有效标志设置为内部的FALSE来使索引无效。之后每个命令的输出有助于更好地理解该过程。

最后的话

当输入很大并且需要某种耗时的预处理时,这种技术非常有用。可以把这想象成一种有助于简化某些流程的设计模式。如有任何问题,请随时与我联系!

附:这是我的第一篇博客。请务必分享和评论!😄

惰性神经网络

原文:https://towardsdatascience.com/lazy-neural-networks-8b0de07fd578?source=collection_archive---------11-----------------------

对于困难的问题,神经网络有时可能缺乏鲁棒性,因此它们可能无法对分类不足的例子和边缘情况进行准确的预测。即使选择了合适的架构,这种情况仍然存在。我讨论了如何将注意力从模型架构转移到智能数据选择策略和成本函数设计上,这通常是一个更有用的策略。

在我进入解决方案之前,我认为讨论深度学习的一些首要主题是重要的。

培训目标

请记住,当我们创建一个神经网络时,我们实际上是在设计一个实验。我们有数据、模型架构和培训目标。你提供的数据是模型的范围,损失函数基本上是神经网络如何根据这个目标来评估自己。最后一点至关重要。损失函数基本上在训练期间向架构提供反馈,有效地陈述-是架构内参数的当前状态,做出准确反映我们的训练目标的预测,数字越低越好。

数据分类是使用深度学习解决的常见问题。无论你试图对猫和狗、路上的汽车还是购买行为进行分类。这种问题的训练目标是简单地最小化错误分类的例子的数量。当前的范例是使用称为交叉熵的损失函数,其训练目标是最小化总输出。在数学上,这表示为:

或者在第一种情况下,可以直观地表示为:

Cross-Entropy Loss (CE)

虽然你们中大多数熟悉深度学习的人可能厌倦了人们解释交叉熵,但我想强调几件事。看上面曲线的形状,试着想象训练时发生了什么。参数被随机初始化,然后随着数据的传递而更新。由于损耗越低越好,如果这些随机初始化的权重导致预测概率 p 接近于零,那么损耗输出将会非常高(曲线趋于无穷大)。如果参数是完美的,使得它以 100%的准确度预测训练集中的一切,那么输出是零,不能再低了。如果它在任何中间位置,它将总是试图瞄准这个零值。这是因为我们的训练目标是最小化总损失,并且许多小值的总和优于许多大值的总和。

上面的方法似乎不需要修改。我们有一个连续的函数,告诉神经网络不断尝试改进,直到它完美为止。一会儿我将回到为什么这种方法会有问题。

神经网络变懒

数据对于深度学习模型至关重要。但是得出数据越多越好的结论未免过于简单化了。少量高质量的例子对于一个有效的模型来说是绰绰有余的。然而,理解整个训练过程对于拥有一个健壮的模型是很重要的。

神经网络不是用常识初始化的。他们从不知道正在学习什么开始,通过查看数据来逐渐更新参数,然后基于给出最佳总体性能的内容进行评估,标准是我们为其定义的总损失。类别不平衡可能导致网络在不确定的情况下简单地预测主导类别。不确定性本身可能来自于数据的微小变化。

如果您将数据视为模型的世界,大量简单、分类良好的示例可以增强模型的信念,即根本不存在这种类型的变体。例如,一个被训练来识别人的物体检测器可能很难定位一个远处的人,如果它被训练的只是护照照片的话。

即使你的数据集中有一些可变性,大量简单的例子也能强化一个网络对其宇宙的信念。再次考虑交叉熵损失曲线。神经网络可能不会尝试从困难的例子中学习,因为其总损失的风险太高。这样做的不幸后果可能是一个网络说“什么也不做”、“站着不动”或“不知道”。在另一种情况下,想象你正试图训练一个网络玩石头、剪子、布。它可能会知道大多数人总是玩摇滚,然后不断地输出纸张,而实际上你想让它学习更复杂的关系。这就是为什么简单地添加更多的数据并不总是理想的,因为这个概念可能会进一步加强。

一个更有用的方法是问这个问题我的神经网络哪里不好,并使这些情况在你的数据集中得到更多的体现。这种想法被称为自举硬负挖掘。历史上,计算机视觉使用这种方法处理懒惰模型的问题。在对象检测问题中,背景和前景类可能在 1000:1 的比例上占主导地位,并且从未学会将学习集中在对象本身上。关键思想是通过选择检测器触发错误警报的那些例子来逐渐增加或引导背景例子集。这种策略导致迭代训练算法,该算法在给定当前样本集的情况下更新检测模型,然后使用更新的模型来寻找新的误报以添加到受限制的训练集中之间交替。该过程通常从一个训练集开始,该训练集包括所有对象示例和一个小的随机背景示例集[1]。

这里的要点是,更多的数据可能是有用的,但不要简单地将其扔在你的网络上,并期待更好的结果。

数学直觉

我不认为要成为一名优秀的机器学习实践者,你需要广泛的数学技能,当然不是与编程或一般问题解决技能相比。我甚至不认为你不能阅读论文,除非你理解了正在被证明的东西背后的神秘的数学解释。然而,我想说的是,能够在深度学习中可视化重复出现的数学概念确实为你提供了另一种工具,用于理解为什么神经网络最终可能不健壮,以及是否有改进的空间。

当你阅读报纸时,很难直观地理解正在发生的事情。了解一些数学函数可视化的基本技巧可以让它变得更简单。

让我们暂时忘记深度学习功能,只想象一个简单的正弦曲线。最简单的修改是将它乘以一个常数,在这种情况下,这个常数小于 1。效果是相同的形状,但值被缩放。

Effect of scaling by a constant

接下来想象我们的正弦曲线乘以一个变化的函数,在这种情况下是一条简单的线( y = x )。正弦波通常在–1 和 1 之间振荡。通过将其乘以另一个函数,它现在被迫在该函数的正值和负值之间振荡,在这种情况下为 -xx

Effect of scaling by another function

焦损

鉴于这种认识,让我们回到交叉熵损失曲线:

Cross-Entropy Loss (CE)

如果我们记得我们正在做一个由数据、架构和损失函数组成的三个组件的实验;除了另外两个为什么不改变损失函数?如果我们不想让自己的神经网络变懒,如何改变这个功能?更具体地说,我们如何减少大量简单例子的贡献,这样参数就不会在这些例子中被细化?我们怎样才能迫使它发现更复杂的关系,这些关系只存在于更难描述的例子中?通过将两个函数相乘(如正弦函数所示),应该可以按照我们想要的方式正确地计算示例的成本,从而对交叉熵损失进行整形。

这就是焦点损失函数所实现的。在论文中首次介绍了密集物体的焦点损失 检测 (2017),以解决计算机视觉中的类别不平衡问题,作为硬负挖掘和多阶段模型的更简单替代方案。基本上,目标是识别图像中的对象,相对于人们试图预测的对象类别,背景和前景类别之间存在巨大的类别不平衡。基本上,很难让网络尝试对对象进行分类,因为神经网络认为丢失的风险太高。

焦点损失只是将交叉熵损失乘以一个比例因子,该比例因子随着正确类别的置信度增加而衰减到零[2]。

如果我们分别表示交叉熵损失和比例因子:

Cross-Entropy Loss and the scaling factor for case when gamma is 2

现在我们一起来比较一下未缩放的版本:

Comparison between Focal Loss and Cross-Entropy Loss

您可以直观地看到,无论概率是 0.7 还是 0.99,靠近曲线下端的分类良好的示例都将返回相似的值。换句话说,对于这个范围内的例子,它不会尝试改进它的参数,但当它不在这个范围内时,它会这样做。因此,它将迫使网络学习更复杂的关系,这些关系只出现在困难的例子中——使它不懒惰。

有趣的是,这个看似简单的变化直到 2017 年才引入深度学习社区。理论上,任何人都需要意识到这是如何缩放函数背后的一点数学直觉(如所展示的),以及意识到损失函数与数据和架构相比起着重要的作用。

总结

  • 训练神经网络包括选择数据、合适的结构和损失函数。
  • 神经网络会变得懒惰并强化它们的信念
  • 不要盲目地添加更多的数据,而是使用谨慎的策略,如硬负挖掘。
  • 当试图生成更鲁棒的网络时,不要忽略损失函数。
  • 焦点丢失是一种让网络专注于更难的例子和学习更复杂的关系的策略。

参考文献

  • [1]使用在线硬示例挖掘训练基于区域的对象检测器(Abhinav Shrivastava 等人)(2016 年)
  • [2]密集物体探测的焦点损失(宗-林逸等人)(2017 年)

LDA 主题建模:一种解释

原文:https://towardsdatascience.com/lda-topic-modeling-an-explanation-e184c90aadcd?source=collection_archive---------2-----------------------

Photo by Patrick Tomasso on Unsplash

背景

主题建模是在一组文档中识别主题的过程。这对于搜索引擎、客户服务自动化以及任何其他了解文档主题很重要的情况都很有用。有多种方法可以做到这一点,但在这里我将解释一种:潜在狄利克雷分配(LDA)。

该算法

LDA 是一种无监督学习的形式,它将文档视为单词包(即顺序无关紧要)。LDA 的工作方式是首先做出一个关键的假设:生成文档的方式是挑选一组主题,然后为每个主题挑选一组单词。现在你可能会问“好吧,那么它是如何找到主题的?”答案很简单:它逆向工程这个过程。为此,它为每个文档 m 执行以下操作:

  1. 假设所有文档中都有 k 个主题
  2. 通过给每个单词分配一个主题,在文档 m 中分布这些 k 主题(这种分布称为α,可以是对称的,也可以是非对称的,稍后会详细介绍)。
  3. 对于文档 m 中的每个单词 w ,假设其主题是错误的,但是每隔一个单词被分配正确的主题。
  4. 基于以下两点从概率上给单词 w 分配一个主题:
    -文档 m
    -
    有多少次单词 w 在所有文档中被分配了一个特定的主题(这种分布被称为 β ,稍后将详细介绍)
  5. 对每个文档重复这个过程几次,你就完成了!

模型

Smoothed LDA from https://en.wikipedia.org/wiki/Latent_Dirichlet_allocation

上面是所谓的 LDA 模型的板块图,其中:
α是每个文档的主题分布,
β是每个主题的单词分布,
θ是文档 m、 的主题分布,φ是主题 k、 z 是文档 m 中第 n 个单词的主题,以及的主题

调整模型

在上面的板模型图中,可以看到 w 是灰色的。这是因为它是系统中唯一可观察的变量,而其他变量是潜在的。正因为如此,要调整模型,有一些事情你可以弄乱,下面我重点介绍两个。

α是一个矩阵,其中每行是一个文档,每列代表一个主题。行 i 和列 j 中的值表示文档 i 包含主题 j 的可能性。对称分布意味着每个主题均匀地分布在整个文档中,而非对称分布则倾向于某些主题。这将影响模型的起点,当您大致了解主题如何分布以改善结果时,可以使用它。

β是一个矩阵,其中每行代表一个主题,每列代表一个单词。行 i 和列 j 中的值表示主题 i 包含单词 j 的可能性。通常每个单词在整个主题中均匀分布,这样就不会有主题偏向某些单词。这可以被利用,虽然为了偏向某些主题,以有利于某些词。例如,如果你知道你有一个关于苹果产品的主题,那么在其中一个主题中偏向“iphone”和“ipad”这样的词会有所帮助,以便推动模型找到那个特定的主题。

结论

本文并不打算成为一个成熟的 LDA 教程,而是给出 LDA 模型如何工作以及如何使用它们的概述。有许多实现方式,例如 Gensim 易于使用且非常有效。关于使用 Gensim 库进行 LDA 建模的很好的教程可以在这里找到。

有什么想法或发现我错过了什么?让我知道!

快乐话题造型!

LDA2vec:主题模型中的词嵌入

原文:https://towardsdatascience.com/lda2vec-word-embeddings-in-topic-models-4ee3fc4b2843?source=collection_archive---------4-----------------------

了解有关 LDA2vec 的更多信息,LDA 2 vec 是一种结合狄利克雷分布的潜在文档级主题向量混合来学习密集单词向量的模型。

Originally published at https://www.datacamp.com/community/tutorials/lda2vec-topic-model.

这篇博文会给大家介绍一下 lda2vec,这是 Chris Moody 在 2016 年发表的一个话题模型。lda2vec 使用主题和文档向量扩展了 Mikolov 等人在 2013 年描述的 word2vec 模型,并结合了单词嵌入和主题模型的思想。

主题模型的一般目标是产生可解释的文档表示,这些表示可用于发现未标记文档集合中的主题或结构。这种可解释文档表示的一个例子是:文档 X 20%是主题 a,40%是主题 b,40%是主题 c。

今天的帖子将从介绍潜在的狄利克雷分配(LDA)开始。LDA 是一个概率主题模型,它将文档视为一个单词包,所以您将首先探索这种方法的优点和缺点。

另一方面,lda2vec 在单词嵌入的基础上构建文档表示。您将了解更多关于单词嵌入的知识,以及为什么单词嵌入目前是自然语言处理(NLP)模型中的首选构件。

最后,您将了解更多关于 lda2vec 背后的一般思想。

潜在狄利克雷分配:简介

主题模型接受一个未标记文档的集合,并试图在这个集合中找到结构或主题。注意,主题模型通常假设单词的使用与主题的出现相关。例如,您可以提供一个包含一组新闻文章的主题模型,该主题模型会根据单词的用法将文档分成若干个组。

主题模型是自动探索和构建大量文档的好方法:它们根据文档中出现的单词对文档进行分组或聚类。由于关于相似主题的文档倾向于使用相似的子词汇表,因此得到的文档簇可以被解释为讨论不同的“主题”。

潜在狄利克雷分配(LDA)是概率主题模型的一个例子。这到底意味着什么,您将在下面的章节中学习:您将首先理解 LDA 如何从一个单词包描述开始来表示不同的文档。然后,您将看到如何使用这些表示在文档集合中查找结构。

词汇袋

传统上,文本文档在 NLP 中被表示为一个单词包。

这意味着每个文档都被表示为一个长度等于词汇表大小的固定长度向量。这个向量的每个维度对应于一个单词在文档中的出现次数。能够将可变长度的文档简化为固定长度的向量使它们更适合用于各种机器学习(ML)模型和任务(聚类、分类等)。

The image above illustrates how a document is represented in a bag-of-word model: the word “document” has a count of 1, while the word “model” occurs twice in the text.

虽然单词袋导致稀疏和高维的文档表示,但是如果有大量数据可用,则在主题分类上通常会获得良好的结果。你可以随时阅读最近脸书关于主题分类的论文。

固定长度的文档表示意味着您可以轻松地将不同长度的文档输入到 ML 模型中(SVM 模型、k-NN 模型、随机森林模型等等)。这允许您对文档执行聚类或主题分类。文档的结构信息被移除,并且模型必须发现哪些向量维度在语义上是相似的。例如,在不同维度上映射“猫”和“猫”不太直观,因为模型被迫学习这些不同维度之间的相关性。

LDA 模型

当训练 LDA 模型时,您从一组文档开始,并且这些文档中的每一个都由一个固定长度的向量(单词包)来表示。LDA 是一种通用的机器学习(ML)技术,这意味着它也可以用于其他无监督的 ML 问题,其中输入是固定长度向量的集合,目标是探索这些数据的结构。

要实现 LDA 模型,首先要定义文档集合中的“主题”数量。这听起来很简单,但是如果您正在处理大量的文档,就没有听起来那么直观了。

在具有 M 个主题的 N 个文档上训练 LDA 模型对应于找到最佳解释数据的文档和主题向量。

请注意,本教程将不会详细涵盖 LDA 背后的全部理论(参见 Blei 等人的这篇论文),因为重点是更好地理解一般概念。

假设文档中的词汇由 V 个单词组成。

在 LDA 模型中, N 个文档中的每一个都将由长度为 M 的向量来表示,该向量详细描述了哪些主题出现在该文档中。一个文档可以由 75%的“主题 1”和 25%的“主题 2”组成。通常,LDA 会产生带有大量零的文档向量,这意味着每个文档中出现的主题数量有限。这与文档通常只讨论有限数量的主题的想法是一致的。这极大地提高了这些文档向量的可解释性。

每一个 M 主题都由一个长度为 V 的向量表示,该向量详细描述了给定一个关于该主题的文档中可能出现的单词。因此,对于主题 1,“学习”、“建模”和“统计”可能是一些最常见的词。这意味着你可以说这是“数据科学”的话题。对于主题 2,“GPU”、“计算”和“存储”可能是最常见的词。你可以把这解释为“计算”主题。

下图直观地展示了 LDA 模型。该模型的目标是找到解释不同文档的原始单词包表示的主题和文档向量。

需要注意的是,您依赖于主题向量是可解释的这一假设,否则模型的输出几乎是垃圾。本质上,你是在假设,给定足够的数据,该模型将找出哪些单词倾向于同现,并将它们聚类到不同的“主题”中。

LDA 是一个简单的概率模型,效果很好。文档向量通常是稀疏的、低维的和高度可解释的,突出了文档中的模式和结构。您必须确定文档集合中出现的主题数量的准确估计值。此外,您必须手动为不同的主题向量分配不同的命名者“主题”。由于单词袋模型被用于表示文档,LDA 可能遭受与单词袋模型相同的缺点。LDA 模型学习文档向量,该向量预测文档内部的单词,而不考虑任何结构或这些单词在局部级别上如何交互。

单词嵌入

单词袋表示的一个问题是,该模型负责计算文档向量中的哪些维度是语义相关的。有人可能会认为,利用单词在语义上如何相互关联的信息将会提高模型的性能,而这正是单词嵌入所承诺的。

对于单词嵌入,单词被表示为固定长度的向量或嵌入。存在几种不同的模型来构建嵌入,但是它们都基于分布假设。这意味着“一个词是由它的朋友来描述的”。

单词嵌入的目标是从大型无监督文档集中捕获语言中的语义和句法规则,如维基百科。出现在相同上下文中的单词由彼此非常接近的向量来表示。

Image taken from “Visualizing Word Embeddings with t-SNE

上图是使用 t 分布随机邻域嵌入(t-SNE)将单词嵌入空间投影到 2D 空间。t-SNE 是一种降维方法,可以用来可视化高维数据。该方法将单词嵌入作为输入,并将它们投影到二维空间,该空间可以容易地在绘图中可视化。只调查单词空间的一个子部分,集中在接近“教师”的单词上。不是通过向量中的无信息维度来表示单词,而是可以使用单词嵌入通过语义相关的向量来表示单词。

当使用单词嵌入时,ML 模型可以通过将信息嵌入到向量表示中来利用来自大量文档(也称为“语料库”)的信息。这对于单词袋模型是不可能的,当没有大量数据可用时,单词袋模型会损害模型性能。单词嵌入导致文档表示不再是固定长度的。相反,文档由可变长度的单词向量嵌入序列表示。虽然一些深度学习技术,如长短期记忆(LSTM)、具有自适应池的卷积网络等,能够处理可变长度的序列,但通常需要大量数据来正确训练它们。

word2vec

正如您在简介中看到的,word2vec 是由 Mikolov 等人开发的非常流行的单词嵌入模型。注意,在分布式语义领域中还存在其他几种单词嵌入模型。虽然获得高质量的单词嵌入需要一些技巧,但是本教程将只关注 word2vec 背后的核心思想。

在 word2vec 中使用下面的训练过程来获得单词嵌入。

1.在文本中选择一个(枢纽)单词。当前中枢单词的上下文单词是出现在中枢单词周围的单词。这意味着你在一个固定长度的单词窗口内工作。中枢词和上下文词的组合构成了一组词-上下文对。下面的图片取自 lda2vec 上的克里斯·穆迪的博客。在这个文本片段中,“awesome”是中枢单词,它周围的单词被作为上下文单词,产生 7 个单词-上下文对。

Image taken from “Introducing our Hybrid lda2vec Algorithm

2.存在 word2vec 模型的两个变体:a .在单词袋体系结构(CBOW)中,基于一组周围的上下文单词来预测中枢单词(即,给定‘谢谢’,‘这样’,‘你’,‘顶’该模型必须预测‘棒极了’)。这被称为单词包架构,因为上下文单词的顺序并不重要。b .在 skip-gram 架构中,中枢词用于预测周围的上下文词(即给定‘牛逼’预测‘谢谢’、‘这样’、‘你’、‘顶’)。下图描述了两种不同的 word2vec 架构。注意,使用了相对简单的(两层)神经模型(与计算机视觉中的深度神经模型相比)。

Image taken from “Efficient Estimation of Word Representations in Vector Space” (Mikolov et al., 2013)

通过在大型语料库上训练该模型,您将获得对语义信息进行编码的单词嵌入(投影层中的权重)以及一些有趣的属性:可以执行向量运算,例如国王-男人 + 女人 = 女王。

例如,与简单的独热编码表示相比,字向量是有用的表示。它们允许将大型语料库中的统计信息编码到其他模型中,如主题分类或对话系统。单词向量通常是密集的、高维的和不可解释的。考虑下面这个例子:[ -0.65,-1.223,…, -0.252,+3.2]。虽然在 LDA 中,维度大致对应于主题,但是对于词向量来说,情况通常不是这样。每个单词被分配一个上下文无关的单词向量。然而,单词的语义高度依赖于上下文。word2vec 模型学习单词向量,该向量预测不同文档中的上下文单词。结果,特定于文档的信息在单词嵌入中混合在一起。

lda2vec

受潜在狄利克雷分配(LDA)的启发,word2vec 模型被扩展为同时学习单词、文档和主题向量。

Lda2vec 是通过修改 skip-gram word2vec 变体获得的。在原始的 skip-gram 方法中,模型被训练为基于中枢单词来预测上下文单词。在 lda2vec 中,将主词向量和文档向量相加以获得上下文向量。该上下文向量然后被用于预测上下文单词。

在下一节中,您将看到这些文档向量是如何构造的,以及如何像 LDA 中的文档向量一样使用它们。

lda2vec 架构

在 word2vec 模型中集成上下文向量的想法并不新鲜。例如,段落向量也探索了这个想法,以便学习可变长度文本片段的固定长度表示。在他们的工作中,对于每个文本片段(一个段落的大小),学习一个密集的向量表示,类似于学习的单词向量。

这种方法的缺点是上下文/段落向量类似于典型的单词向量,使得它们不太容易被解释为例如 LDA 的输出。

lda2vec 模型通过处理文档大小的文本片段并将文档向量分解成两个不同的部分,比段落向量方法更进了一步。本着与 LDA 模型相同的精神,文档向量被分解成文档权重向量和主题矩阵。文档权重向量表示不同主题的百分比,而主题矩阵由不同的主题向量组成。因此,通过组合文档中出现的不同主题向量来构建上下文向量。

考虑下面的例子:在最初的 word2vec 模型中,如果中枢单词是“法语”,那么可能的上下文单词可能是“德语”、“荷兰语”、“英语”。在没有任何全局(文档相关)信息的情况下,这些将是最合理的猜测。

通过在 lda2vec 模型中提供额外的上下文向量,可以更好地猜测上下文单词。

如果文档向量是“食物”和“饮料”主题的组合,那么“长棍面包”、“奶酪”和“葡萄酒”可能更合适。如果文档向量类似于“城市”和“地理”主题,那么“巴黎”、“里昂”和“格勒诺布尔”可能更合适。

请注意,这些主题向量是在单词空间中学习的,这便于解释:您只需查看与主题向量最接近的单词向量。此外,对文档权重向量进行约束,以获得稀疏向量(类似于 LDA ),而不是密集向量。这使得不同文档的主题内容的解释变得容易。

简而言之,lda2vec 的最终结果是一组稀疏的文档权重向量,以及易于解释的主题向量。

虽然性能与传统的 LDA 相似,但是使用自动微分方法使得该方法可扩展到非常大的数据集。此外,通过结合上下文向量和词向量,您可以获得“专门的”词向量,这些词向量可以在其他模型中使用(并且可能优于更多的“通用的”词向量)。

lda2vec 库

Lda2vec 是一种相当新的专门的 NLP 技术。由于它建立在现有方法的基础上,任何 word2vec 实现都可以扩展到 lda2vec。Chris Moody 在 Chainer 中实现了该方法,但也可以使用其他自动微分框架(CNTK,Theano,…)。Tensorflow 实现也公开发布。

lda2vec Python 模块的概述可以在这里找到。由于训练 lda2vec 可能是计算密集型的,建议对较大的语料库使用 GPU 支持。此外,为了加速训练,不同的单词向量通常用预先训练的 word2vec 向量来初始化。

最后,讨论了作为主题模型的 lda2vec,但是也可以更一般地定义向 word2vec 模型添加上下文向量的想法。例如,考虑由来自不同地区的不同作者编写的文档。然后,作者和区域向量也可以被添加到上下文向量,从而产生一种无监督的方法来获得文档、区域和作者向量表示。

结论

这篇博文只提供了 LDA、word2vec 和 lda2vec 的快速概述。注意,原作者还发表了一篇关于 lda2vec 技术细节的很棒的博文

传单 Javascript 库点坐标样式和设计

原文:https://towardsdatascience.com/leaflet-javascript-library-point-coordinate-styling-and-design-9c2be3383a7f?source=collection_archive---------5-----------------------

传单上高度可定制的地图标记

在我们软件开发旅程中的某个时刻,我们大多数参与地理空间技术的人都遇到过被称为“传单”的开源库。

这只是一个简单的文章来解释它的默认标记转换成你喜欢的图像,图标等。希望在这篇文章结束时,改变这一点:

Default leaflet marker

将触手可及。不要再谷歌“如何定制传单标记”只是为了得到一堆复杂但不可用的回复。

对于初学者来说,你需要包括在基本传单库,可以在这里找到:【http://leafletjs.com/download.html】T2,并初始化一个基本的地图和标记。在本例中,我将使用可从 http://cdn.leafletjs.com/leaflet/v1.2.0/leaflet.zip下载的传单 v1.2.0,并在一个简单的 html 页面上包含 fleet . CSS、fleet . js 和 images 文件夹:

在这种情况下,上面的代码转换成下面的新加坡地图视图:

Image by Author | A rendered map view of Singapore by leaflet.js

默认图标:

这行代码:

L.marker([1.2800945, 103.85094909999998]).addTo(map);

在地图上创建默认标记,如下所示:

I 型标记器。圆形标记器

要将其转换为活页中的简单圆,代码的变化如下:

Image by Author | Note: The method pointToLayer is used and for simplicity, the marker is given a white fill with a black border.

此外,你可以改变上述标记的半径、颜色或不透明度,但这不是本演示的重点(没有双关语)。

标记类型 II。图像图标

虽然圆形点作为标记在某些地图可视化中可能是理想的,但有时更具体的图标/图像可能更合适。在这种情况下,应该使用下面的方法,而不是上面提到的方法:

Image by Author | (left) The image icon is rendered in the map above | (right) Preview of image file “ERP.png” stated in the code snippet

标记类型 III。编码图像(base64)图标

更进一步,我尝试使用 base64 作为 iconUrl 参数的替代,猜猜会发生什么?它也工作得非常好!

Image by Author | (left) The image icon is rendered in the map above as a base64 encoded string | (right) Preview of encoded image file stated in the code snippet

就个人而言,当使用的标记是一次性的,并且开发人员发现没有必要在项目中包含实际的图像文件时,我建议使用 base64 字符串来替代图像路径。我推荐的一个 base64 图像编码器工具是:https://www.base64-image.de/

标记类型 IV。类名和字体图标

最后,如果你是使用字体图标的大多数开发者之一(例如,字体-awesome),那么在这种情况下使用 L.divIcon 将是最合适的:

Image by Author | Note that for the font icon above to render correctly, the class name “fa fa-star” in font-awesome.css has to be included

当你发现默认的传单图标不适合你的视觉化时,这些是你可以使用的一些图标定制风格。希望这篇文章对你正在进行的网络地理空间可视化之旅有所帮助!

感谢阅读。

[## 通过我的推荐链接加入灵媒——李思欣·崔

获得李思欣·崔和其他作家在媒体上的所有帖子!😃您的会员费直接…

geek-cc.medium.com](https://geek-cc.medium.com/membership)

精益创业和机器学习

原文:https://towardsdatascience.com/lean-startup-and-machine-learning-39a96efecb2a?source=collection_archive---------17-----------------------

大约十年前,创造了这个术语。从那时起,它已经成为最有影响力的创业方法之一,尤其是那些基于网络的软件公司。精益在互联网革命中成熟。我们现在正处于一场不同革命的尖端——一场由机器学习算法引入的革命。可以有把握地认为,在不久的将来,大多数或所有的软件都将包含一些机器学习的元素。但是精益与机器学习在原理和实践上有多兼容呢?(有趣的视角见这里)

经验证的学习和机器学习

根据精益创业哲学,大多数创业公司的失败不是因为产品的质量,而是因为对客户的错误假设,即创业公司最终为一个不存在的客户制造了完美的产品。为了避免这种命运,创业公司应该首先通过运行实验来了解他们的客户,从而验证和完善他们的假设。这个过程被称为经验证的学习。在精益中,经验证的学习是通过执行重复的假设检验来完成的。

假设总是关于给定产品功能定义的顾客反应的断言。为了进行一个实验,首先需要从功能上定义产品(基本上是一个特性列表)——这定义了一个可行的产品。此外,还需要定义客户对产品反应的量化措施。功能性产品的定义仍然留下了许多(主要是技术性的)选择。这些选择应该以最小化创业中最有价值的商品(通常是时间)的支出的方式做出;这样的选择定义了最小可行产品(MVP)。然后,人们将着手建立 MVP,把它带给客户,记录他们的反应,并确定假设的有效性。实验通常设置为分割测试,将当前基线产品作为对照,将提议的变更作为处理。

请注意,精益中没有产品方面的不确定性——给定一个功能定义,人们就可以确定是否能制造出符合该定义的产品。对于传统软件来说确实如此。传统软件产品的行为完全由您提供的指令(即代码)决定。因此,给定其行为的完整规范,您可以“逆向”工作,并找出您需要提供什么指令来构建一个具有所需行为的软件。从某种意义上说,MVP 基本上是你为此目的所需的最小指令集。一个软件的行为可以基于上下文表现出不同的变化。然而,这种可能的变化的数量通常是相当小的,并且提供作为所有这种变化的总和的功能定义是有意义的。

然而,机器学习有着本质的不同。在机器学习中,产品是通过将一组指令(算法)与一些数据(训练数据)相结合而生成的模型。因此,模型的行为不仅由算法决定,还由训练数据决定。在机器学习中,不可能事先(在访问训练数据之前)对产品的行为做出精确的断言。此外,机器学习算法从海量数据中学习复杂的规则。基于上下文的行为的可能变化的集合是非常大的。因此,即使人们可以访问训练数据,通过手动列出其行为的所有可能变化来从功能上定义机器学习产品仍然是不可行或不明智的——如果你已经确切知道算法将从数据中学习什么,那么你就不需要首先训练算法。

当涉及到机器学习产品时,这为验证学习提出了一个基本问题。简而言之,如果不能保证假设的前提条件得到满足,就不能用实验来检验假设的有效性——人们无法判断测试失败是因为假设无效还是因为前提条件没有得到满足。在统计假设检验中,这被称为混杂。

就其原始形式而言,精益实验不适合在机器学习领域或任何其他具有显著产品端不确定性的领域中进行验证学习。正如我们上面所讨论的,这个难题的根本原因是由于精益提出通过重复的分割测试来验证假设,作为验证学习的手段。

分裂测试是有效学习的最有价值的部分

有效学习的目标实际上是从经验证据中了解客户。为此,分割测试是一个非常严格的工具。那么当初为什么会选择它呢?我相信,这是精益创业方法找到自己的 MVP 的一个例子。

当精益创业作为一种具体的方法被创建时,它的主要“客户”是基于网络的软件公司。在这个领域,分割测试是产品优化的普遍工具(在你非常了解你的客户的情况下,对产品做一些小的改变)。这个熟悉的工具只是为了有效的学习而改变用途。

当时,最明显的具有重大产品方面不确定性的领域大多是登月计划,如寻找癌症的治疗方法。就像现在一样,当时还不清楚精益原则对这种登月计划是否有用。因此,用不太知名的工具使形式主义复杂化是没有意义的。换句话说,分裂测试是验证学习的 MVP。

是时候转向了

机器学习改变一切——软件的首要目标是从执行指令转变为从数据中学习。对于精益创业方法来说,这代表了其最重要的客户群的巨大转变。分裂测试与机器学习产品的不兼容性意味着,很快它将不再是用于验证学习目的的“可行产品”。现在是寻找其他选择的时候了;是时候转向了。

关于灵感,让我们转向有效学习的原始灵感来源——科学研究。精益从科学方法中借鉴了很多通过实验学习的方法。然而,在科学上,实验是昂贵的。使用实验作为统计假设检验的手段只在少数情况下使用,例如当需要监管机构的批准时(如药物的临床试验)或当没有真正的潜在理论基础时。

在更成熟的科学领域,人们通常不会从一个实验到另一个实验去验证假设,而是试图建立理论。我将在下面的段落中对这个过程进行简单的描述。接下来的事情有点像漫画;不完全准确,但符合我们的目的。

理论基本上是对大量实验事实的解释。但是通常最简单的解释不是从直接可观察到的物体方面获得的,而是从某些概念物体方面获得的。例如,原子理论可以解释各种实验事实。然而,你在实验中实际观察到的不是原子本身,而是探测器上的一些闪烁。现在我们需要一种方法,一张地图,把原子和眨眼联系起来。地图是理论世界(由原子组成)和可观察世界(由眨眼组成)之间的桥梁。

该图将用于将理论结果转换成关于特定实验装置的可观察量的预测。如果理论的预测与所有现有的观察一致,并且有一些新的预测,那么根据新预测的重要性,可能会委托进行新的实验。如果发现理论的任何预测与现有的观察结果不一致,那么就需要对理论进行修改。

如上图所示的地图不是简单的表格,而是复杂的实体。它们是实验装置的精确模型;例如上述例子中的检测器。事实上,探测器物理本身就是一个子领域。

一个重要的问题是,我们为什么需要这样的地图?我们为什么不简单地从理论到实验呢?原因有很多,但最重要的一个,也是与我们的讨论最相关的一个原因是,这些地图提供了关注点的分离。理论的目标是提供尽可能简单的解释;人们应该能够用在上海、旧金山或圣保罗进行的实验来检验理论的有效性,而不必担心每个实验设置的细节。另一方面,实验的作用是能够比较试图解释同一现象的多种相互竞争的理论。如果包括每个实验设置的细节的负担被放在理论本身上,那么以上都不可能。在理论和实验之间放置一张地图,提供了理论世界和现实世界之间必要的分离。

现在,在上面的讨论中,如果我们用产品世界代替理论世界,用客户世界代替现实世界,我们将立即注意到经验证的学习的相似性。验证学习的目标是找到一个将产品配置与客户反应联系起来的地图。由于没有更好的术语,我将简单地称之为客户地图。找到产品/市场的契合度就相当于找到了客户地图的最佳第一近似值。在产品优化阶段,我们使用这个客户图为合适的客户制造合适的产品。在产品优化阶段,还会进一步完善客户地图。

一种新的有效学习 MVP

如何着手构建客户地图?一般来说,为每个产品配置进行实验是非常低效的,因为我们想知道客户的反应。这或多或少是重复分割测试采用的方法。相反,我们需要的是一种能够从数据中归纳的工具。碰巧的是,在精益创业引入以来的十年里,我们已经完善了一个工具,这个工具就是所谓的机器学习。

机器学习是精益创业中验证学习的完美工具。为了使这种说法更加具体,让我举一个例子来说明这在概念上是如何工作的。正如我们已经讨论过的,客户地图应该将产品配置与客户反应联系起来。推荐系统就是这样一种机器学习算法。推荐系统中映射的质量显然取决于用于训练它的数据的质量。因此,在第一阶段,应该选择产品配置以减少映射中的不确定性,而在后一阶段,我们使用映射来生成给定客户的最佳产品配置。这恰恰是语境土匪解决的问题。情境强盗是一种强化学习算法。强化学习是机器学习的一个子领域。在上下文 bandit 算法中,两个阶段被称为探索和利用。因此,推荐系统结合上下文强盗可以成为有效学习的工具。这种设置是重复分割测试的一个非常好的替代。

我刚才描述的验证学习方法与机器学习产品完全兼容,因为它不需要建立不受产品不确定性影响的假设。因此,它没有重复分割测试固有的混淆问题。

这种方法也不需要产品的功能定义。这种方法中的产品配置可以仅仅是技术规格。对于机器学习算法,这相当于选择算法类型、参数选择、训练数据集等。然而,有一个产品的功能定义对理解它与顾客的关系是有用的。事实上,在该方法中提供功能性产品定义是可能的。产品的功能完全由它在与当前客户地图一起使用时产生的响应来定义——本质上,这是我们对客户将如何对产品做出反应的最佳猜测。这不是传统产品定义中的功能列表。但它可能更有用,因为它可以使用行为分析工具进行分析,以深入了解客户对产品的看法。

总而言之,机器学习产品完全符合精益的原则。然而,为了在实践中实现这种兼容性,我们需要放弃一些用于验证学习的过时工具,并用现代机器学习工具来代替它们。在迁移过程中出现的中心实体是客户地图,它的确定成为经验证学习的主要目标,取代了通过重复分割测试进行的假设验证。

通过分享来学习

原文:https://towardsdatascience.com/learn-by-sharing-4461cc93f8c1?source=collection_archive---------4-----------------------

为什么我要离开图书馆去写一个数据科学博客

传统教育很简单:坐下,闭嘴,听老师讲课。课后去图书馆反复阅读同样的单词,试图理出我们日常生活中意义不大的抽象话题。即使作为一名研究生,我仍然被例行公事地讲课,并被期望在课外花大部分时间独自思考我的研究。虽然这可能对需要简单的考试信息回流的科目(查看你的历史)很有效,但它完全不适合现代技术科目,如数据科学。

考虑到这一点,这里有一个激进的建议:当你想理解一个概念时,不要去看书,你应该去你的博客,试着向别人解释清楚。这个想法很简单:如果你不能把一个话题教给别人,那么你自己也不会明白。

Well said

当我开始研究生课程时,我决定采取一种新的教育方法。我不再被动地坐在课堂上,而是打算每次演讲至少问一个问题。这个小小的调整对我的课堂参与产生了深远的影响。我把我的问题集中在如何实现我们所涉及的概念上,这些概念经常在没有任何实际例子的情况下出现。这种积极的参与让我在课堂上更容易集中注意力,也更容易将话题应用到我的研究和作业中的问题上。

课外,我花更少的时间独自学习,花更多的时间在实验室实施数据科学技术。我还努力与其他学生就课堂内容展开对话。在这个过程中,我不是通过死记硬背,而是通过向他人解释来理解这些主题。通过这些讨论,我的同事和我会尝试使用这些技术来解决我们的问题。无论我们是失败还是成功,我们都会回来进行更多的辩论,形成一个富有成效的反馈循环。幸运的是,我在一个实验室里,有比我聪明的学生和教授——永远不要成为房间里最聪明的人是一个好主意——每天我都通过看到实践来学习新的东西。

这学期有更多的数据科学和人工智能(AI)研究生课程,我需要加强我的分享游戏。我的目标是每周至少写一篇博文,解释课堂上涉及的一个话题。我没有太多的时间去开发一些很酷的应用程序,比如股票探索工具(T0)或 T2 体重追踪工具(T3)Python 工具,但是我可以把平时花在复习课程材料上的时间用来写我所学到的东西。这既是为了测试我是否真正理解了材料,也是为了让其他人受益!

当信息——至少是无害的信息——被自由分享时,社区得到了最好的服务。有些人认为,因为他们努力学习他们所知道的,其他人也必须这样做,他们拒绝透露任何会使其他人学习更容易的事情。我强烈反对这种观点:仅仅因为我们为教育支付了几万美元并不意味着我们应该保密。相反,我相信教育的民主化,相信帮助别人从我的(许多)错误和(有限但不断增长的)经验中吸取教训。在技术领域,特别是数据科学,互联网扩大了获取信息的渠道,现在任何人都有可能学习和实践尖端技术。正规机构不再垄断知识,我想在降低这些令人兴奋的新领域的壁垒方面发挥一小部分作用。

Libraries may own books, but nobody owns knowledge

试图解释概念有助于我们自己更好地理解它们。为普通观众翻译一个主题需要真正的理解,而不是死记硬背。我们都经历过这样的情况:我们详尽地研究了一个主题,并认为我们完全理解了这个想法,但当我们必须在一个基本的情况下应用它时,却完全空白了。此外,一个领域中最成功的人往往不是最聪明的,而是那些能够最好地交流发现并展示其相关性的人。尼尔·德格拉斯·泰森是世界上最著名的物理学家,不是因为他发表了最杰出的论文,而是因为他为广大读者解释了艰难的概念。清晰的书面和口头交流技能是课堂上无法教授的一大优势!

这些每周一次的帖子通常是关于数据科学和机器学习的,重点是现实世界的例子和隐喻。我的目标的一个很好的指示器是这个相关性对因果关系帖子。虽然隐喻可能会过度简化概念,但我的意图是为学习这些概念提供一个高层次的框架。在深入细节之前,先记下基本的想法是很有用的。具体的细节可以通过应用它们来解决问题来填充(或者如果你喜欢这种方式,可以写在一本书里)。如果你等不及我的帖子,我建议看看数据怀疑论播客,它为普通观众提供了大量数据科学话题。更好的是,开始你自己的博客!写作是思考你的想法的最好方式,分享知识对社区中的每个人都有好处。

一如既往,我欢迎反馈和建设性的批评。我可以在推特上通过 @koehrsen_will 联系到我。

学习数据科学—信息图

原文:https://towardsdatascience.com/learn-data-science-infographic-7a472063feb?source=collection_archive---------0-----------------------

在 2012 年被《哈佛商业评论》评为“21 世纪最性感的工作”后,Glassdoor 将其评为 2016 年“年度最佳工作”。

然而,在这四年中,对数据科学家的态度发生了很大变化:2012 年,大多数文章都集中在试图解释什么是数据科学家以及他们具体做什么。当时,在谷歌上简短搜索“如何成为数据科学家”几个字,就会发现这个概念对不同的人有不同的含义。2016 年,这个搜索仍然给你各种各样的文章和广泛的观点。然而,尽管数据科学家曾经是一个实际存在的人,但现在越来越多的文章专注于解释为什么数据科学家是独角兽。

因为尽管数据科学家的定义并不固定,但还没有多少人达到设定的高期望值。招聘信息显示,公司正在寻找拥有沟通技能、创造力、聪明、好奇心、技术专长……这些能力有时被描述的方式让人们看起来不可能成为数据科学家。

随着需求取代供应,数据科学团队而非数据科学家的趋势正在上升,随之而来的是对数据科学是什么和如何的重新强烈关注。然而,就像数据科学家的定义一样,数据科学的定义是多方面的,对于那些想学习数据科学的人来说,有很多建议。然而,这些信息可能依赖于行业和环境,也可能是个人的。

数据科学 8 步指南
为了指导你通过这一信息和建议的丛林,DataCamp 修改了它的“8 步成为数据科学家”信息图:它现在提供了你学习数据科学需要通过的 8 个步骤的更新视图。这八个步骤中的一些对某些人来说会比其他人容易,这取决于背景和个人经历等因素。

然而,我们的目标仍然是让这成为对学习数据科学感兴趣的每个人或者已经成为数据科学家或数据科学团队成员但希望获得更多资源以进一步完善的每个人的可视化指南。

Learn Data Science

(点击这里下载完整信息图)

如果你正在考虑学习数据科学,或者刚刚开始学习,不要被信息图中呈现的八个步骤吓到。

数据科学是一场马拉松,而不是短跑。

学习数据科学需要时间和个人投资,但这个过程一点也不枯燥!

别忘了,有很多课程其他资源可以帮助你走上正确的道路。

递归神经网络如何工作

原文:https://towardsdatascience.com/learn-how-recurrent-neural-networks-work-84e975feaaf7?source=collection_archive---------0-----------------------

https://pixabay.com

你肯定遇到过翻译自然语言的软件(Google Translate)或者把你的语音转换成文本的软件(Apple Siri ),可能一开始你很好奇它是如何工作的。

在过去的几年里,这些系统背后的科学已经有了相当大的进步。例如,在 2016 年末,谷歌在他们的谷歌翻译背后引入了一个新系统,该系统使用了最先进的机器学习技术。改进是显著的,你可以亲自测试一下

另一个惊人的例子是百度最近的文本转语音:

Credits to Dhruv Pathasarathy for the amazing demo.

那么以上都有什么共同点呢?他们处理序列数据来做出预测。好吧,但是这和众所周知的猫图像识别器有什么不同呢?

想象一下你想说如果照片里有只猫。你可以使用多张有猫和没有猫的照片来训练一个前馈神经网络(典型的是 CNN-卷积神经网络)。

在这个网络中,信息只在一个方向上移动,即从输入节点向前,通过隐藏节点(如果有的话)到达输出节点。网络中没有循环或环路。— 维基百科

这些网络主要用于模式识别,如下所示:

Feedforward neural network

相反,为了成功处理序列数据,你需要使用递归(反馈)神经网络。它能够“记忆”部分输入,并使用它们进行准确的预测。这些网络是语音识别、翻译等的核心。因此,让我们深入进行更详细的解释。

什么是递归神经网络?

训练典型的神经网络包括以下步骤:

  1. 从数据集中输入一个示例。
  2. 该网络将采用该示例,并使用随机初始化的变量(称为权重和偏差)对其进行一些复杂的计算。
  3. 将产生一个预测结果。
  4. 将该结果与预期值进行比较会给我们一个错误。
  5. 通过相同的路径将误差传播回来将调整变量。
  6. 重复步骤 1-5,直到我们有信心说我们的变量是定义良好的。
  7. 预测是通过将这些变量应用到一个新的看不见的输入中来实现的。

当然,这是对神经网络的一个非常天真的解释,但是,至少,给出了一个很好的概述,并且可能对这个领域的新手有用。

递归神经网络的工作方式类似,但为了清楚地了解这种差异,我们将通过最简单的模型,使用基于前一个单词预测序列中的下一个单词的任务。

首先,我们需要使用大型数据集来训练网络。出于目的,我们可以选择任何大型文本(列夫·托尔斯泰的《战争与和平》是一个不错的选择)。当完成训练后,我们可以输入句子“拿破仑是……的皇帝”,并期望根据书中的知识做出合理的预测。

那么,我们如何开始?如上所述,我们一次输入一个例子,产生一个结果,这两个结果都是单词。前馈网络的不同之处在于,在评估结果之前,我们还需要了解以前的输入。因此,您可以将 RNNs 视为多个前馈神经网络,从一个网络向另一个网络传递信息。

让我们检查以下模式:

Recurrent neural network

这里 x_1,x_2,x_3,…,x_t 表示来自文本的输入单词, y_1,y_2,y_3,…,y_t 表示预测的下一个单词, h_0,h_1,h_2,h_3,…,h_t 保存前一个输入单词的信息。

由于纯文本不能用于神经网络,我们需要将单词编码成向量。最好的方法是使用单词嵌入 ( word2vecGloVe )但是出于本文的目的,我们将使用独热编码向量。这些是( V,1) 向量( V 是我们词汇表中的字数),其中所有的值都是 0,除了在第 i 个位置的那个。例如,如果我们的词汇是苹果、杏、香蕉、…、国王、…斑马,单词是香蕉,那么向量就是【0,0,1,…,0,…,0】

通常,词汇表包含所有英语单词。这就是为什么有必要使用单词嵌入。

让我们定义训练所需的等式:

  • 1)—保存序列中前面单词的信息。可以看到, h_t 是用之前的 h_(t-1) 向量和当前的词向量 x_t 计算出来的。我们还将非线性激活函数 f (通常为 tanhsigmoid )应用于最终求和。假设 h_0 是一个零向量是可以接受的。
    1. —计算给定时间步长 t 的预测字向量。我们使用 softmax 函数产生一个 (V,1) 向量,所有元素的总和为 1。这种概率分布为我们提供了词汇表中最有可能的下一个单词的索引。
  • 3)-在每个时间步 t 使用交叉熵损失函数来计算预测字和实际字之间的误差。

如果你想知道这些 W 的是什么,它们中的每一个都代表了网络在某一阶段的权重。如上所述,权重是用随机元素初始化的矩阵,使用来自损失函数的误差进行调整。我们使用更新权重的反向传播算法来进行这种调整。我将在以后的文章中解释这个过程,但是,如果你对它是如何工作的感到好奇,迈克尔·尼尔森的书是必读的。

一旦我们获得了正确的权重,预测句子“拿破仑是……的皇帝”中的下一个单词就非常简单了。在 RNN 的不同时间步长插入每个字将产生h1、H2、H3、H4。我们可以利用 h_4x _ 5(“of”这个词的向量)推导出 y_5 。如果我们的训练是成功的,我们应该期望在 y_5 中最大数字的索引与我们的词汇表中单词“France”的索引相同。

标准 RNN 的问题

不幸的是,如果你实现了上面的步骤,你不会对结果感到高兴。这是因为最简单的 RNN 模型有一个主要缺点,称为消失梯度问题,这使得它不精确。

简而言之,问题来自于这样一个事实,即在训练期间的每个时间步,我们都使用相同的权重来计算 y_t 。该乘法也在反向传播期间完成。我们越往后退,误差信号就变得越大或越小。这意味着网络在记忆序列中距离较远的单词时会遇到困难,并且只根据最近的单词做出预测。

这就是为什么更强大的型号像 T4 LSTM T5 和 T6 GRU T7 会出现。解决了上述问题,它们已经成为实现递归神经网络的公认方法。

奖金

最后,我想与所有让我更好地了解 RNNs 的资源分享我的列表:

热身:

更深入:

高级(抓住细节):

我希望这篇文章能让你对递归神经网络有一个很好的理解,并能对你激动人心的深度学习之旅有所贡献。

还有哪些 AI 内容?在 LinkedIn 上关注我获取每日更新。

感谢您的阅读。如果你喜欢这篇文章,给它一些掌声👏。希望你有一个伟大的一天!

用这个玩具数据集学习 RCNNs

原文:https://towardsdatascience.com/learn-rcnns-with-this-toy-dataset-be19dce380ec?source=collection_archive---------6-----------------------

这里有一个数据集,旨在帮助展示递归卷积神经网络(RCNN)何时会优于非递归卷积神经网络(CNN)。

一点入门知识

递归模型是专门设计用于使用一系列数据进行预测的模型(例如,使用过去 3 天的一系列数据点的股票市场预测器)。

卷积模型是专为处理图像数据而设计的模型。

因此,递归卷积模型是一种专门设计用于使用一系列图像(通常也称为视频)进行预测的模型。

数据集

The aptly named Sliding Square toy dataset

从 Kaggle 这里下载,也可以在 my Github 上找到。

任务

预测方块的下一个位置!

输入

作为一个 CNN 你只能得到一个单一的帧作为输入:

Input to CNN (single image)

作为一个 RCNN 你得到多个帧作为输入:

Input to RCNN (multiple sequencial images)

直觉

为什么 CNN 会在这个数据集上表现不佳?

看看上面 CNN 的输入(单帧)。你能自信地预测滑动方块的下一个位置是什么吗?我假设你的回答是“不”。这是因为它是完全模糊的,也就是说,它可能向左或向右移动,没有办法根据一张图片就知道。

Ambiguity in trying to predict the next position based on a single frame.

为什么 RCNN 应该在这个数据集上表现良好?

尝试使用上面的 RCNN 输入(两帧)预测下一个位置。现在很容易了吧?正方形移动的方向现在不再模糊。

Showing how using multiple frames disambiguates the next position.

CNN 与 RCNN 的性能测试

查看这本笔记本,看看在这个数据集上构建和训练简单 CNN 和 RCNN (Keras 模型)的代码。

为了评估性能,我们使用来自数据集的随机帧样本,并让每个模型尝试预测正方形的下一个位置。

下面是每个模型预测误差的频率表。例如,你可以看到,对于 7 次测试,CNN 得到了完全正确的正方形位置(零误差)。

frequency chart of prediction errors for a sample of test data

CNN 错误分数是怎么回事?

你可能会注意到 CNN 犯了很多+/- 4 的错误。当我们考察其中一个预测时,一切都揭晓了:

CNN prediction (always predicts it to be the same position as the input)

CNN 似乎总是预测这个正方形与它在输入图像中的位置相同。你可能觉得这很奇怪,因为方块的下一个位置只能是左边或者右边。为什么它会预测它会在一个它根本不会在的地方!?一个字… 一致性!一般来说,对于机器学习模型来说,最好总是有点错误,而不是有时非常错误。在大多数学习算法中,这种偏好是通过平方误差来实现的,如下所示:

How consistent errors are encouraged by squaring the original error. See how both models have the same Sum(Error) but Model B has a significantly higher Sum(Error x Error)

CNN 已经学会猜测与输入相同的位置,因为这样它总是离正确答案最多+/-5。如果它总是猜测方块向右移动:一半的时间它是完全正确的,但另一半的预测会相差 10 %!(这不太一致)

自然 RCNN 是在其元素

从误差图中可以看出,RCNN 的误差远不及 CNN。这是因为它在计算正方形移动的方向上没有问题。

RCNN not having any trouble in predicting the next position of the square.

希望这给了你更多关于何时使用 RCNNs 而不是标准 CNN 的直觉。

所有用于生成玩具数据集的代码以及测试模型的代码都可以在我的 Github 上找到:

[## ZackAkil/理解递归卷积神经网络

理解-递归卷积神经网络-使用合成生成的视频数据来学习如何/何时…

github.com](https://github.com/ZackAkil/understanding-recurrent-convolutional-neural-networks)

在 15 分钟内了解大数据分析的火花!

原文:https://towardsdatascience.com/learn-spark-essentials-in-15-mins-cf1495882ae0?source=collection_archive---------8-----------------------

我向你保证,这个简短的教程将为你节省大量阅读长篇文档的时间。准备好搭乘大数据列车了吗?我们开始吧!

基本概念

RDD : 火花的基本抽象。它将数据对象分布到多台机器上,并在内存中处理,这比在像 R 或 Python 这样的单台机器上处理要快。但是它没有组织在命名的列中。

Dataframe :构建在 rdd 之上,可以拥有一个包含列名和数据类型的模式。它比 rdd 更快,因为它为 Spark 提供了更多的数据信息。

惰性评估:当你使用转换时,Spark 实际上并不执行数据,直到你调用一个动作。

转换:选择、过滤/where、排序/排序依据、连接、分组依据、聚集

动作:显示、获取、计数、收集、描述、缓存、打印模式

基本语法

创建一个 Rdd

# 1\. Read external data in Spark as Rdd
rdd = sc.textFile("path")# 2\. Create rdd from a list
rdd = sc.parallelize(["id","name","3","5"])# 3\. Dataframe to rdd
rdd = df.rdd

创建数据框架

# 1\. Read in Spark as Dataframe directly 
#  header and schema are optionaldf = sqlContext.read.csv("path", header = True/False, schema=df_schema)# 2.1 rdd to dataframe with column names
df = spark.createDataFrame(rdd,["name","age"])# 2.2 rdd to dataframe with schemafrom pyspark.sql.types import *df_schema = StructType([
**... **   StructField("name", StringType(), True),
**... **   StructField("age", IntegerType(), True)])df = spark.createDataFrame(rdd,df_schema)

转换:

# Basic transformations:# 1\. select. Index column by df.column_name or use "column_name"
df.select(df.name)
df.select("name")# 2\. filter/where they are the same
 df.filter(df.age>20)
 df.filter("age>20")
 df.where("age>20")
 df.where(df.age>20)# 3\. sort/orderBy 
 df.sort("age",ascending=False)
 df.sort(df.age.desct())# 4\. groupBy and agg
df.groupBy("gender").agg(count("name"),avg("age"))# 5\. join
df1.join(df.2, (df1.x1 == df2.x1) & (df1.x2 == df2.x2),'left')# 6\. create a new column from existing column
df.withColumn("first_name",split(name,'_')[0])

在 Spark 中编写 SQL

1\. Run sqlContext=sqlContext(sc) before create a dataframe
2\. Create a dataframe called df
3\. Run df.createOrReplaceTempView("table1") to create a temp table
4\. talbe2=sqlContext("select id, name from table1")If you are writing multiple lines, use """ like this:
talbe2=sqlContext.sql("""
select id, name 
from table1
where age>20
""")

动作:

1\. Show: show first n rows of a dataframe (but not rdd) without cells being truncated
df.show(5, truncate=False)2\. Take: display a list of first few rows of dataframe or rdd
df.take(5)3\. collect: collect all the data of a dataframe or rdd
df.collect()4\. count: count number of rows
df.count()6\. printSchema: show column names, data types and whether they are nullable.
df.printSchema()7\. cache : cache the data in memory if it's going to be reused a lot. Use unpersist() to uncache data and free memory.
df.cache()
df.unpersist()# Transformations and actions can be connected and executed in sequence from left to right. 
df1.filter("age>10").join(df2,df1.x==df2.y).sort("age").show()

外卖:

  1. 如果可能的话,使用并寻找在数据帧上使用的函数,而不是 rdd,因为在数据帧上速度更快
  2. 使用 collect()时要小心,除非你需要下载整个数据;使用显示/拍摄
  3. 如果您以后会经常用到这些数据,请将其缓存起来。

No spam, I’ll be mindful of your time and attention

给我几个掌声,如果你觉得有帮助,就跟我来吧!

您可能对如何通过使用数据科学节省租金感兴趣:

[## 如何分析季节性和趋势,以节省你的公寓租金。

当我在寻找一个新的公寓出租时,我开始想知道:是否有一个数据驱动的决策策略…

zhenliu.org](https://zhenliu.org/2017/11/29/how-to-analyze-seasonality-and-trends-to-save-money-on-your-apartment-lease/)

学习构建机器学习服务,原型化真实的应用程序,并将您的工作部署给用户

原文:https://towardsdatascience.com/learn-to-build-machine-learning-services-prototype-real-applications-and-deploy-your-work-to-aa97b2b09e0c?source=collection_archive---------2-----------------------

在这篇文章中,我将向读者展示如何将他们的机器学习模型公开为 RESTful web 服务原型真实的应用程序,方法是为这些服务附加一个前端,并使用容器部署他们的应用程序。

我认为这三个方面代表了数据科学家为了使他们的工作有意义和有影响力而应该具备的关键技能。

我将在本教程中介绍的 3 个工具是:

  1. Jupyter 笔记本(在 JupyterLab 中)带内核网关(把机器学习工作流变成 web 服务);
  2. Azle (快速前端原型库);
  3. Docker (在隔离的、可移植的容器内部署应用);

为什么数据科学家要把他们的机器学习变成 web 服务?

定期创建机器学习代码的端点迫使我们思考抽象。我们需要不断地向团队的其他成员公开我们的工作。这是让我们的工作流程对产品问题负责,并邀请非从业者参与机器学习对话的原因。

数据科学家为什么要做前端应用的原型?

我们不是为数据科学家做机器学习,而是为产品的最终用户做机器学习。这意味着我们需要认识到我们的模型将如何被消费,而不仅仅是被创造出来。将我们的数据管道连接到前端,可以让团队中的其他人了解机器学习的能力,并让我们的机器学习受益于非技术反馈。

为什么数据科学家要将他们的工作隔离在容器中?

容器化使得应用程序便携可复制。可移植性对于任何应用程序都是一个挑战,但是机器学习软件特别容易受到依赖性问题的影响。多亏了一系列用定制代码拼凑起来的开源库,数据科学才成为可能。如果没有容器,当我们改变环境时,很难保证事情会一致地运行。这有助于我们更有效地协作,并允许我们更无缝地在组织内外共享应用程序。

让我们开始吧…

****挑战:比方说我开了一家专门做鲜花的公司。我定期雇人进货,并在进货前给花贴上标签。虽然大多数鲜花都是从批发商那里贴上标签的,但这足以证明我需要培训员工如何识别鲜花。培训员工既费时又费钱。

****解决方案:我将创建一个应用程序,帮助快速培训我的员工。由于的研究显示竞争导致更好的学习,我的应用程序将允许新员工在基于照片和测量识别花朵方面与人工智能竞争。

****模型:低保真度模型帮助我们探索想法,而不会将自己局限于特定的工程实践或协议。在本教程中,我将使用虹膜数据集创建一个应用程序,帮助用户训练识别鸢尾花,并与做同样事情的“人工智能”竞争。

我们的应用程序将包含 3 个部分。我们的第一部分将允许用户在测量时看到随机的鸢尾花。这将是他们的培训区域,用于练习将花卉尺寸与他们的标签联系起来。

我们的第二部分将允许用户挑战我们的 AI,看谁(或什么)能得到更多正确的猜测。

我们的第三部分将显示当前的记分牌,其中包含基于我的学员和 AI 表现的实时分数。我将与新员工一起审查这些报告,以评估他们的培训情况。

构建整个应用程序超出了本文的范围。我们将专注于构建第一部分,剩下的代码留给您自己去探索。

到本文结束时,我们将已经构建了以下机器学习应用程序的前端和后端:

Machine Learning Application Built Using Azle andJupyterLab

后端对前端

我们既需要后端进行处理,也需要前端为用户提供交互。我们的后端将包括我们在 Jupyter 笔记本中原型化的机器学习,而前端将是使用 Azle 构建的 web 应用程序。

由于我们正在构建一个识别鸢尾花的应用程序,因此编写一个数据管道来收集和验证鸢尾花数据,训练和验证一个能够对鸢尾花进行分类的模型,并将该模型部署为前端消费的服务是有意义的。因为快速原型是我的目标,所以我将利用现有的机器学习管道来坐在我的 Jupyter 笔记本中。Google 的 Tensorflow 教程有一个使用深度学习对鸢尾花进行分类的端到端例子。由于虹膜数据集很小,而且我的应用程序不需要可解释性,深度学习应该可以正常工作。

安装 JupyterLab

我们将使用 JupyterLab 作为我们的开发环境。JupyterLab 允许我们在浏览器中使用 IDE,这在进行机器学习工作和 web 应用程序开发时非常方便。

T5 下载和安装 JupyterLab

安装完成后,在桌面(或者任何你喜欢的位置)创建一个新文件夹,命名为 flower_power。打开终端,进入新的 flower_power 目录。进入后,运行以下命令打开 JupyterLab:

jupyter lab

这将在您的默认浏览器中自动打开 JupyterLab 作为一个新选项卡:

在启动器中选择一个新的 Python 3 笔记本。重命名笔记本 flower_power.ipynb

如果你是机器学习的新手,请花时间跟随 Tensorflow 的教程,将它的代码添加到 flower_power 笔记本的连续单元格中。这是对机器学习中常见任务的一个很好的概述。如果您已经知道该练习,只需将代码添加到每个单元格中,并在笔记本上单击以确保满足所有依赖关系。或者你可以简单的 在 GitHub 这里下载Jupyter 的完整笔记本。只需使用 Jupyter 的上传工具来加载文件。

现在,我们的 JupyterLab 已经可以使用 flower_power.ipynb 笔记本了:

The flower_power.ipynb Jupyter Notebook

学习将 Jupyter 细胞作为 REST 终点

除了在浏览器中实现数据科学,Jupyter 还可以将我们的机器学习变成一种 web 服务。通过添加 Jupyter 内核网关,我们可以将笔记本中的任何单元格作为端点公开。请将端点视为笔记本电脑和任何需要使用其输出的应用程序之间的网关。创建端点意味着我们在机器学习中所做的工作可以向应用程序及其开发者公开。

安装 Jupyter 内核网关

在您的终端中运行以下命令:

pip install jupyter_kernel_gateway

我们将很快看到如何使用网关。此时,我们希望选择笔记本中的单元格作为端点。这很简单,只需在单元格的开头添加以下注释:

# GET /my_path

我们将用端点的名称替换“my_path”。首先,让我们创建一个函数,它从 flower_power.ipynb 笔记本中的测试数据集中返回一朵随机的鸢尾花:

这个函数从 3 个可能的选项中随机选择一个花的名称,选择随机选择的 URL,并检索与花相关的数据。

我们将使用一个端点调用这个函数,这样我们的应用程序就可以获取一个随机的花名称、它的图像 URL 和与它的 4 个测量值相关联的数据

我通过进入维基百科的虹膜数据集页面并简单地在数据集部分右键单击适当的图像,将图像 URL 添加到上述函数中。我选择了 C opy 图像地址并将 url 粘贴到上面的函数中,分别为 url_1url_2url_3

我们希望将这个函数变成一个端点,使它可以在浏览器中从我们的 web 应用程序中调用。如上所示,我们通过在代码周围包装以下内容来使用内核网关:

  • 一个得到** 注释的单元格的第一行;**
  • 输出 JSON 的打印** 命令。**

现在,当我们启动内核网关(稍后)时,这段代码将通过将浏览器指向以下 URL 来执行:

localhost:9090/get _ random _ flower

先不要担心 9090 端口,稍后我将展示如何设置它。这个端点将运行上面创建的 show_random_iris ()函数,并将结果添加到名为 res 的字典中(因为我们使用的是 JSON,所以请确保将 import json 添加到笔记本的顶部单元格中)。我们得到的是一个看起来像这样的 JSON 响应 :

必须将 GET 注释添加到您想要作为端点的 Jupyter 单元格的第一行。如果您在 GET 行上放置任何注释或代码,该单元格将失败。

为了检查我们的端点,让设置 Jupyter 内核网关。因为我们已经安装了 Jupyter gateway,所以我们只需要在包含 flower_power.ipynb 笔记本的 s ame 目录中的终端中输入以下命令:

jupyter kernelgateway --KernelGatewayApp.api='kernel_gateway.notebook_http' --KernelGatewayApp.ip=0.0.0.0 --KernelGatewayApp.port=9090 --KernelGatewayApp.seed_uri=flower_power.ipynb --KernelGatewayApp.allow_origin='*'

该命令执行以下操作:

  • 启动 Jupyter 网关;
  • ****设置基础 URL 为 localhost(0 . 0 . 0 . 0);
  • ****向浏览器公开端口 9090(你可以把这个改成任何可用的端口);
  • ****将flower _ power . ipynb 笔记本分配给网关;
  • ****允许来自任何地方的输入流量(记住,我们只是在做原型)

运行该命令将产生与 Tensorflow(忽略)和我们注册的资源(端点)相关的输出。最后一行应为:

Jupyter Kernel Gateway at [http://0.0.0.0:9090](http://0.0.0.0:9090)

在浏览器中打开一个新标签,指向:

localhost:9090/get _ random _ flower

您应该会看到返回的数据。持续点击刷新查看终端输出,每次返回不同的花朵。我们现在调用 python 代码,放在 Jupyter 笔记本里,全部通过我们的浏览器。您现在已经构建了一个服务。因为我们的机器学习将用 Python 编写,所以创建一个机器学习服务也没什么不同。我们只需通过浏览器选择我们希望调用的功能。

为了检查我们的端点,我们应该使用开发人员常用的工具来做同样的事情。一个这样的工具是 Swagger 。Swagger 是一款帮助开发人员设计、构建、记录和使用 RESTful Web 服务的软件。将服务端点传递给团队中的开发人员是一种常见的方式。Jupyter 内核网关的一个很棒的特性是它自动生成一个 swagger.json 端点,我们可以使用 SwaggerUI 来访问它。

这使得开发人员可以使用不同的 API 端点来“混搭”应用程序。作为数据科学家,我们希望我们的模型成为混搭的一部分,这样我们的组织就可以看到机器学习为他们的产品带来的价值。您组织内的开发人员可能会安装他们自己的 Swagger UI(或类似的东西),因此您可以简单地将您的 Swagger 端点交给他们。

对于我们自己的检查,让我们从 Dockerhub 下载 Swagger UI 并运行 UI 应用程序,检查我们刚刚用内核网关创建的端点。如果没有安装 Docker, 下载****先安装 Docker 。安装并运行 Docker 后,在终端中打开一个新标签,运行 Docker pull 命令下载 DockerUI:

docker pull swaggerapi/swagger-ui

在您的控制台中键入 docker images 以查看以下内容:

这显示了我们新图像的名称,swaggerapi/swagger-ui。我们现在可以使用这个名称来运行它的容器:

docker run -p 80:8080 swaggerapi/swagger-ui

…然后在我们的浏览器 80 端口上打开 swagger-ui** 。**

在浏览器的新选项卡中,导航到以下 URL:

[http://localhost](http://localhost):80

在屏幕的顶部是探索栏,在这里我们添加到我们的 swagger.json 文件的路径;我们的 Jupyter 内核网关暴露的那个。将以下内容添加到此栏中(确保 URL 中包含 http://):

[http://localhost:9090/_api/spec/swagger.json](http://localhost:9090/_api/spec/swagger.json)

因为我们只是点击我们创建的服务中的现有端点,所以端口仍然是 9090。按回车键,看看会发生什么。您应该会在屏幕上看到以下内容:

这是我们在 Swagger 内部公开的 GET 端点。点击获取按钮,然后在试出** 然后在上执行😗*

这些信息对你的开发者很有用。他们可以看到如何通过终端中的 curl 命令访问我们的 API,看到完整的请求 URL** ,看到响应主体,以及与该响应相关的任何。我们还可以看到成功代码 200,显示我们的端点按预期工作。**

因为我们没有在端点上设置任何参数,所以没有什么可查询的。通常,开发人员会运行查询来决定如何最好地将我们的机器学习引入应用程序。我们将在稍后构建 Flower Power 应用程序时展示如何设置和传递参数。

我们现在对数据科学家如何在他们的 Jupyter 笔记本中为任何代码创建 web 服务有所了解。虽然我们在这里只使用了一个简单的例子,但这种方法向我们团队内外的利益相关者公开了所有类型的机器学习功能。

我们现在准备开始原型化一个真正的应用程序。虽然这通常属于开发人员的权限范围,但有充分的理由让数据科学家自己去做。真正的应用程序给了我们的机器学习“腿”,并消除了机器学习如何为组织的产品做出贡献的许多模糊性。

当然,数据科学家已经有足够多的工作要做,不用深入研究 HTML、CSS 和 JavaScript,更不用说为工程大规模 web 应用程序定制框架了。我们需要的是一个快速前端原型库,基于直观的语法,可以轻松连接到 API 端点。

一些机器学习从业者会争辩说他们的专业排除了学习前端开发的时间/需要;我发现这通常源于对学习如何开发软件的恐惧,而不是真正相信他们不需要这样做。重要的是要认识到原型软件和开发产品软件是不同的艺术形式。有了正确的高级库,原型软件对领域专家来说是非常有益的。在当今信息驱动的经济中,没有什么比快速将他们的愿景转化为人们可以使用的现实工具的能力更能赋予专业人员权力。

学习用 Azle 构建应用程序原型

太多时候,数据科学家孤立地致力于改进他们的机器学习模型,只在对模型满意后才把结果扔出围栏。这增加了项目投资回报率低的风险,因为真空中的机器学习永远不会受益于现实世界的反馈。应用程序的前端是真正的用户对学习算法产生的输出的唯一接触点。数据科学家需要根据人们对产品的触摸和感受来通知他们的管道

Azle 是一个前端原型库,专门为快速制作应用程序而设计。它似乎在灵活性和易用性之间找到了合适的抽象层次。它使用函数来添加样式 内容绑定事件,并与 API 端点交互,从而更容易构建全功能、数据驱动的应用程序。

所有的 web 应用程序都是从一个 html 模板开始的,这个模板最终会包含使应用程序前端成为可能的元素。我们的第一步是使用 Azle 提供的模板。您可以将以下内容复制并粘贴到名为 index.html的文件中:

HTML template for Azle.

我们所有的 Azle 函数都可以添加到底部的

Azle 是一种直观的语言,我们根据*正在做的事情编写代码。Azle 预装了极简风格,所以我们不必花太多时间让我们的应用程序看起来更现代。它还使用了布局,使得在屏幕上排列内容变得容易。*

我们来看看 Azle 中一些常见的函数。点击任何一个按钮来玩实际代码:

添加内容

az.**add_button**(target_class, target_instance, {
    "this_class" : "my_button",
    "text" : "CLICK ME"
})

拨弄

az.**add_dropdown**(target_class, target_instance, {
    "this_class" : "my_dropdown",
    "options" : ["option A", "option B", "option C", "option D"],
    "title" : "choose option..."
})

拨弄

az.**add_slider**("target_class", 1, {
    "this_class" : "my_slider",
    "default_value" : 4,
    "min_value" : 0,
    "max_value" : 10
})

小提琴

注意,每个函数使用一个目标类目标实例作为前两个参数。这告诉 Azle 在哪里放置内容,或者我们希望样式化哪些内容。例如,在上面的滑块中,我们首先创建一个部分来存放我们的应用程序,然后将滑块添加到第一个部分:

az.add_slider(**"my_sections", 1,** {}) 

第三个参数是一个包含我们希望传递的属性的对象。在我们的第一个 slider 示例中,我们传入了一个类名(“this_class”)和默认值。每个内容和样式都有其预期的属性,可以在 Azle 的文档中找到。

样式内容

我们也可以样式我们添加的任何内容。如上所述,通过使用 target_class 和 target instance,并将样式属性作为第三个参数传递给一个样式对象来完成样式化。例如,上面的按钮样式:

az.**style_button**('my_button', 1, {
    "background" : "hotpink",
    "border-radius" : "6px",
    "width" : "200px",
    "color" : "black",
    "cursor" : "wait"
})

拨弄

请注意,Azle 样式遵循标准的 CSS 样式化文档的方法。

添加事件

我们可以将事件绑定到我们的 UI 元素上。事件是像点击、悬停和选择这样的事情。这里我们使用 Azle 的 add_event 函数向按钮添加一个点击事件:

az.**add_event**("my_button", 1, {
    "type" : "click",
    "function" : "alert('you clicked me')"
})

瞎搞

要查看 Azle 中所有可用的事件,请参见这里

抓取值

通常,我们希望在调用事件之前从输入或下拉列表中获取一个值。这是使用 Azle 的 grab_value ()函数完成的:

az.**grab_value**("my_dropdown", 1)

例如,我们可以添加一个按钮,其文本来自下拉菜单中的选择:

az.**add_button**("my_sections", 1, {
    "this_class" : "my_button",
    "text" : **az.grab_value**("my_dropdown", 1)
})

拨弄

呼叫端点

调用端点是我们从 REST APIs 发送和获取数据的方式。Azle 的 call_api ()函数要求提供基 url** ,我们需要传递的任何参数,以及一旦收到响应就调用的函数😗*

拨弄

添加视觉效果

Azle 与 D3.js 配合得很好,正如我在这里讨论的。还可以查看一下 azle_d3 示例应用

下面是预览视频,展示了如何使用 Azle 将 D3 视觉效果绑定到应用程序中的 UI 元素:

我们对 Azle 的简短访问向我们展示了创建更完整的应用程序所需的部分,包括前端内容、样式、事件和视觉效果,以及调用端点的能力。请务必查看文档,其中包含入门教程。

让我们开始创建我们的应用程序。

创造花的力量

在开始时创建模拟的整个应用程序超出了本文的范围。我们将只构建应用程序的第一部分然后看看其他部分需要考虑什么。GitHub 项目包含完整的代码。

下面是我们在开头看到的视频,展示了完整的应用程序:

为了开始原型化我们的应用程序,我们像往常一样从前面显示的 html 模板开始,在底部的

最快的开始方式是简单地将 html 模板保存到您的桌面并右键单击该文件,选择打开方式,然后选择您的浏览器,如下所示:

然而,将所有文件放在我们的 ide 中会更方便,对我们来说 IDE 就是 JupyterLab。这样我们可以根据需要打开终端,安装库,对我们的 flower_power.ipynb 进行修改,重启我们的机器学习服务,原型化我们的前端;所有这些都在一个浏览器屏幕上。当构建真实世界的软件时,这是非常有益的。我们将使用这种方法。

如果您从一开始就已经在名为 flower power 的文件夹中启动并运行了 JupyterLab,并且将 flower_power.ipynb 选项卡作为您的第一个 JupyterLab 文件打开。

让我们打开其他选项卡,这样我们就有了一个完整的原型开发环境。点击新启动器图标,选择其他选项下的终端,让打开一个终端:

这样做两次**,这样我们就有 2 个终端打开。让我们也为我们的 Azle 应用程序创建一个 index.html 文件。点击其他下的文本文件…**

…并将文件重命名为index.html。将此文件作为 JupyterLab 环境中的第 4 个选项卡打开。

让我们在主目录中创建两个文件夹,一个叫做 d3_visuals ,另一个叫做 scripts 。我们在 JupyterLab 中通过单击“新建文件夹”按钮来创建文件夹:

…然后右键单击新创建的文件夹,并将其重命名。您现在应该有一个如下所示的目录结构:

**flower_power** ├── **scripts** ├── **d3_visuals**
├── flower_power.ipynb
├── index.html

您还应该为您的原型开发环境打开 4 个选项卡:

A prototyping environment for building machine learning applications.

我们稍后将添加 2 个额外的文件到 d3_visuals 和 scripts 文件夹中,但是现在让我们开始构建我们的应用程序。

我们需要在另一个浏览器选项卡中查看我们的应用程序,这意味着我们需要“启动 web 服务器”通过在 JupyterLab 中打开我们的第一个终端选项卡并运行以下命令,我们可以很容易地做到这一点:

python3 -m http.server

这将显示…

Serving HTTP on 0.0.0.0 port 8000 …

由于我们在与 index.html 文件相同的目录中运行这个命令,这意味着我们可以通过打开一个新的浏览器选项卡并导航到 http://localhost:8000/ 来查看我们的应用程序。

****注:关于使用不同于 8000 的端口,请参见最后的附加部分。

当然,我们还没有添加任何东西到我们的 index.html 文件中,所以没有什么可展示的。让我们添加一些 Azle 函数。

我们从应用程序主体的基本样式开始。我们将添加一个极简的字体(任何来自谷歌字体),一个“滚动到顶部”按钮,并设置我们的应用程序的宽度:

Azle 应用程序也需要部分。章节就像它们听起来一样;显示特定上下文的应用程序的不同部分。让我们为“花的力量”创建 4 个部分;1 个用于顶部导航/标题栏,另外 3 个用于我们在开始时创建的 3 个样机设计。

由于我们的应用程序中有一些部分我们现在有东西要看,所以我们可以在新的浏览器标签中打开http://localhost:8000/来查看我们的应用程序。我们目前有一个由 4 部分组成的应用程序,如下所示:

让我们设置我们的部分的高度,以符合我们的样机。我们将把第一部分的高度设置得更短,这样它就可以作为我们的导航/标题栏:

花之力量的顶端现在看起来像这样:

在我们的导航栏中,我们将需要一个徽标,一个标题,以及几个按钮,允许用户滚动到特定部分。每当我们想在屏幕上安排内容时,我们就使用 Azle 的布局。让我们在第一部分中添加一个布局,然后添加图像、文本和按钮:

我不会在本文中详细介绍每个 Azle 函数,但是,鉴于 Azle 的高度直观的语法,您应该能够理解哪个函数在做什么。记住,你使用 Azle 越多,你就能越快地对如何快速组装应用程序有一个直觉。

让我们也添加我们的按钮到我们布局中的第三个单元格:

虽然上面的可能看起来有点吓人,但它非常简单。我们首先将按钮标题存储在 Azle 的 hold_value 对象中。然后我们使用 Azle 的 call_multiple 函数在一组函数上迭代 3 次。反勾号内的函数(在 JavaScript 中称为“模板字符串”)是我们添加按钮、样式化按钮和添加滚动事件的地方。

让我们将第三个单元格的内容向右对齐:

最后,每当我们完成向布局添加内容时,我们应该将布局的边框设置为 0** 以移除边框。返回之前在“banner_layout”目标类上使用的 style_layout 函数,并删除边框:**

我们的顶部横幅现在看起来像这样:

对于剩余的部分,我不会遍历所有代码,而是简单地指出重要的 Azle 函数,因为它们与调用我们的机器学习服务有关。完整的源代码可以看 GitHub 项目。你可以复制并粘贴必要的代码到你的 index.html 文件中,或者简单的克隆整个项目并继续这样做。

为了构建 section 2,我们添加并样式化一个布局,添加文本、按钮、图像和可视化。第 2 部分如下所示:

注意:我们的应用程序部分不需要精确地跟随模型(这就是为什么它们被称为低保真度模型)。快速原型制作的美妙之处在于,我们可以快速调整设计以适应不断变化的需求。

如果你刷新你的 index.html 页面,你将看不到任何花或可视化。为此,我们需要调用我们之前创建的第一个端点,因为该端点返回了 Iris URL 及其数据。我们还需要添加一个新的脚本到脚本文件夹,和一个 D3 视觉到 d3 _ 视觉文件夹。

如果您从 GitHub 克隆了 flower_power 项目,那么您已经拥有了所有必需的文件夹和文件。如果没有,查看 GitHub 上的项目文件,并将必要的文件夹和文件添加到您的 JupyterLab 项目中。您的完整目录结构应该如下所示:

**flower_power** ├── **scripts** └── wrapped_functions.js
├── **d3_visuals** └── barchart.html
├── flower_power.ipynb
├── index.html

现在我们只需要启动并运行我们的 REST 服务。在第二个终端选项卡中,运行我们之前看到的用于启动内核网关的命令:

jupyter kernelgateway --KernelGatewayApp.api='kernel_gateway.notebook_http' --KernelGatewayApp.ip=0.0.0.0 --KernelGatewayApp.port=9090 --KernelGatewayApp.seed_uri=flower_power.ipynb --KernelGatewayApp.allow_origin='*'

现在点击 index.html 页面上的刷新。第一部分应该返回一个随机虹膜图像及其数据可视化成一个有角度的条形图。

至此,JupyterLab 中的原型环境已经完成并正在运行。你有:

  • 终端 1 :运行网络服务器托管 index.html
  • 终端 2 :运行 Jupyter 内核网关,将笔记本电池暴露为 REST 端点
  • flower_power.ipynb :一个 Jupyter 笔记本,里面装着你的 Python 或者 R 代码
  • ****index.html:用 Azle 构建的 web 应用

你可以使用同样的设置将你的机器学习变成真正的软件原型。由于大多数数据科学家和其他机器学习实践者使用 Jupyter 环境,这种设置使您能够快速将全功能前端附加到您的 Python 和/或 R 代码。

第 2 部分中的一个重要功能是当用户单击 SHOW IRIS 按钮时调用 REST 端点的能力。我们已经知道如何添加事件,因为我们之前在回顾 Azle 函数时已经看过了。我们添加按钮,然后附加一个点击事件:

此时,我们需要添加当用户单击按钮时调用的函数(上面只显示了一个空字符串)。之前我们看了 Azle 的 call_api ()函数。我们用它来调用我们创建的任何端点。您可以在 wrapped_functions.js 的 scripts 文件夹中找到这个函数。

在 Azle 中,每当我们想要将许多函数组合成一个单独的命名函数时,我们就使用包装函数。例如,如果我们想创建一个名为“fetch_random_iris”的包装函数,它应该是这样的:

通过这种方式,我们可以将多个函数组合在上面的花括号中,并通过调用fetch_random_iris()来调用它们。

首先,让我们看看当用户点击我们的 SHOW IRIS 按钮时我们想要调用的函数组,然后我们将这些函数添加到我们的包装函数中。

下面这组函数做 3 件事:

  • 调用我们当前由 Jupyter 内核网关公开的第一个端点;
  • 当数据返回时,调用“call_function ”;
  • 用户点击后旋转按钮。

让我们将这些添加到我们的包装函数 fetch_random_iris 中:

注意,我们在 fetch_random_iris 包装函数中添加了一个“call_function”参数。您可以将任意数量和类型的参数传递到包装的函数中。这里,我们传递一个“回调”,这是一个一旦 API 返回数据就会被调用的函数。

在 Azle 中,我们这样调用包装函数:

az.call_wrapped_function.fetch_random_iris()

因此,我们可以将它添加到上面的 click 事件中,这样当用户单击 SHOW IRIS 按钮时,它将运行 fetch_random_iris()。

注意,我们仍然需要在上面的 fetch_random_iris 调用中添加回调函数作为参数。我们还有一个 D3 可视化的条形图,一旦数据返回,就会绘制出来。这由回调函数处理,回调函数是另一个包装函数。如前所述,我不会遍历本文中的所有代码。我鼓励你浏览一下 GitHub 项目,看看完整的代码。

上面我也提到了 Azle 和 D3。看看我的文章关于如何使用 Azle 给你的应用程序添加 D3 视觉效果。

应用程序的其余部分遵循相同的方法。我们检查低保真度模型,添加布局和 UI 元素,根据需要绑定事件,将函数分组为包装函数,并使用 call_api 函数发送和接收来自我们的机器学习服务的数据。

下面是第三节:

第 4 节:

正如我们在开始时看到的,这里是最终结果:

有了真正的应用在手,就该出货了!

学习对你的机器学习应用进行分类

当我们“发布”一个应用程序时,我们将所有东西打包并放在服务器上。这允许其他人访问该应用程序,而不是让它只驻留在我们的本地机器上。将一个应用程序安装到远程服务器上有其自身的技术挑战。仅仅因为我们的应用程序在我们的笔记本电脑上运行良好并不意味着它在其他地方也能运行良好。人们使用不同的运行时环境、不同版本的库、不同版本的编程语言等。

为了让这变得更容易,Docker 把一种叫做集装箱化的技术变成了一种易于使用的产品。Docker 允许我们获取本地环境的快照,并将其精确配置传送到任何服务器上。这意味着我们可以使用 Docker 来封装我们的 Flower Power 应用程序所依赖的不同东西:

  • Python 3
  • 像熊猫和 Numpy 这样的图书馆
  • 张量流
  • Jupyter 内核网关

决定使用本文前面描述的 SwaggerUI 的读者已经接触过 Docker。如果您还没有, 下载****安装 Docker 然后再进行下一步。

安装 Docker 后,我们准备好编写** 一个 Docker 文件。Docker 文件是一个告诉 Docker 如何构建“映像”的文件图像指定如何构建容器。图像的实例是一个容器。Docker 中的一个关键概念是所谓的基础图像。基础映像允许我们使用已经打包好的语言和库来启动我们的容器。换句话说,如果它们包含在我们的基本映像中,我们不需要在 docerkfile 中明确列出所有的依赖项。我们将使用 jupyter/datascience-notebook 作为我们的基础映像,因为许多机器学习库都包含在这个映像中。**

让我们写下我们的 Dockerfile :

你可以参考 Docker 的教程来了解为什么 Docker 文件看起来是这样的。这里我们将只指出几个要点:

  • 从允许我们带来我们的基本形象;
  • RUN 允许我们安装额外的依赖项;
  • CMD 是我们可以运行终端命令的地方。在这里,我们只是运行我们之前运行的用于启动内核网关的相同命令。

有了 Dockerfile 在手,我们现在可以建立我们的形象:

docker build -t flower_power .

我们只是运行 docker build 命令,并将我们的图像命名为 flower power。

我们确保通过运行以下命令构建了我们的映像:

docker images

这应该会在终端中显示:

然后我们运行集装箱:

docker run -p 9090:8888 flower_power

在这里,我们将端口 9090 暴露给外部世界。虽然终端会发出一条消息说“Jupyter Kernel Gateway athttp://0 . 0 . 0 . 0:8888”,但这是来自容器内部的。我们的访问实际上是通过端口 9090。

我们可以通过在终端中键入以下命令来确保我们的映像正在运行:

docker ps

我们现在有了一个运行的容器。部署可以非常简单,只需将 Dockerfile 转移到另一个服务器上,并在那里运行构建和运行命令。Docker 将提取所有必要的依赖项,并通过我们指定的端点公开我们的机器学习。我们的前端应用程序可以在我们部署机器学习的同一台服务器上,也可以在更高的另一台服务器上。这就是创建一个机器学习服务的意义,该服务可以部署到服务器上,并由其他应用程序使用。想想这些可能性。

设置远程服务器非常简单。您可以使用像 DigitalOcean 这样的服务来创建一个 droplet,然后使用传输协议(例如 scp 或 sftp)将您的 docker 文件传输到该 droplet。

需要注意的一点是,我们需要更改 Azle 的 call_api() 函数使用的 URL,因为它将在一个新的 IP 地址上调用我们部署的机器学习服务,而不是本地主机。

当然,部署可以比这复杂得多,但基本思想是相同的。无论是持续集成和部署、集成测试、微服务,还是任何其他相关概念,都可以归结为将打包的代码推送到服务器上并消费端点。

就是这样!在本文中,我们设置了一个具有机器学习管道的 Jupyter 笔记本,使用 Jupyter 的内核网关公开了端点,使用 SwaggerUI 查看了这些端点,使用 Azle 创建了一个前端应用程序来使用我们的端点,并将我们的机器学习打包到一个可以部署到服务器的容器中。这是对数据科学在现实项目中如何发生的更现实的审视。

因此,去构建和部署你的机器学习服务,并创建有趣的应用程序来使用它们。这些技能造就了全面发展的数据科学家,他们知道如何将自己的工作带入生活。

附言

如果你在这些步骤中有任何问题,请在评论区提问。

奖金票据

使用 Azle 实现原生 Python/R 可视化

数据科学家经常依赖 Python 的 Matplotlib 或 R 的 ggplot2 产生的视觉效果。当这些视觉效果被暴露为数据 URIs 时,Azle 可以使用它们。数据 URIs 是图像嵌入 web 应用程序的方式,而不是指向源 URL。例如,下面是我们通常如何用 matplotlib 生成一个图:

import numpy as np
import matplotlib.pyplot as pltt = np.arange(0., 5., 0.2)plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^')
plt.savefig('lines.png')

产生了这个:

为了让 Azle 使用这个图,我们只需将我们的 matplotlib 图转换成数据 URI** ,并使用内核网关公开序列化的输出。**

下面是一个例子,我们使用 Azle 的 call_api 函数获取我们的编码图,然后使用 add_image 函数绘制该图:

为了在 Docker 容器中工作,我们需要通过挂载一个卷来创建一个数据文件夹。为此,我们可以在主文件夹中创建数据目录,并将这一行添加到 Docker run 命令中:

sudo docker run -p 9191:9191 -it -v /path_to_dockerfile/data:/data testing

同样的方法也可以用在 R 中。下面是我们如何使用 knitr 库在 R 中对图形进行编码:

library(knitr)file_name = 'lines.png'
uri=image_uri(file_name)
cat(uri)

构建更完整的应用程序

我们只展示了笔记本使用 GET 响应来自 Azle 的请求的基本方式。根据应用程序的复杂程度,Jupyter 的内核网关支持所有的 CRUD 操作。查看这里关于如何更全面地定义你的 web api 的更多细节。

C 构建 URL

有两种方法可以构造一个 URL 来调用 REST API:

  1. ****作为 URL 路径的一部分(即/api/resource/parametervalue)
  2. ****作为查询参数(即/api/resource?parameter=value)

与基于 SOAP 的 web 服务不同,RESTful web APIs 没有“官方”标准。[14]这是因为 REST 是一种 的架构风格 ,而不像 SOAP 是一种 的协议

A 使冲突端口无效

  • 如果你同时运行 Jupyter 笔记本和内核网关,你可以指定你的笔记本端口以避免冲突(或者只是设置你的内核网关端口为 Jupyter 默认的 8888 以外的端口)。例如,您可以使用以下命令将任何笔记本设置为端口 8889:
jupyter notebook --port=8889

M 取端点在 R

如果在 Jupyter 中使用 R 内核而不是 Python,可以如下处理请求:

# GET /my_pathreq <- fromJSON(REQUEST)
args <- req$argsparameter_name = args$parameter_name# do something with parameter_nameprint(toJSON(parameter_name))

确保将 jsonlite 库添加到笔记本的顶部。

library(jsonlite)

快乐大厦!

如果你喜欢这篇文章,你可能也会喜欢:

** [## 用 D3.js 从玩具视觉过渡到真实应用

我们经常孤立地学习技术和方法,与数据科学的真正目标脱节;至…

towardsdatascience.com](/combining-d3-with-kedion-graduating-from-toy-visuals-to-real-applications-92bf7c3cc713) [## 机器学习工作流的 GUI 化:快速发现可行的流水线

前言

towardsdatascience.com](/gui-fying-the-machine-learning-workflow-towards-rapid-discovery-of-viable-pipelines-cab2552c909f) [## 创建 R 和 Python 库的分步指南(在 JupyterLab 中)

r 和 Python 是当今机器学习语言的支柱。r 提供了强大的统计数据和快速…

towardsdatascience.com](/step-by-step-guide-to-creating-r-and-python-libraries-e81bbea87911)**

通过在 tensorflow 中实现来学习 Word2Vec

原文:https://towardsdatascience.com/learn-word2vec-by-implementing-it-in-tensorflow-45641adaf2ac?source=collection_archive---------0-----------------------

嗨!

我觉得理解一个算法最好的方法就是实现它。因此,在这篇文章中,我将通过在张量流中实现来教你单词嵌入。

这篇文章背后的想法是避免所有的介绍和通常与 word embeddeds/word 2 vec 相关的闲聊,直接进入事情的实质。因此,许多国王-男人-女人-王后的例子将被跳过。

我们如何进行这些嵌入?

有许多获得单词嵌入的技术,我们将讨论一种已经很出名的技术,唯一的一种,word2vec。与普遍的看法相反,word2vec 不是一个的网络,它只有 3 层!

注意:word2vec 有很多技术细节,为了更容易理解,我将跳过这些细节。

word2vec 的工作原理:

word2vec 背后的想法是:

  1. 以一个 3 层神经网络为例。(1 个输入层+ 1 个隐藏层+ 1 个输出层)
  2. 给它一个单词,训练它预测它的相邻单词。
  3. 移除最后一层(输出层),保留输入层和隐藏层。
  4. 现在,从词汇表中输入一个单词。隐藏层给出的输出是输入单词的‘单词嵌入’

就是这样!仅仅做这个简单的任务就能让我们的网络学习有趣的单词表达。

让我们开始实现它来充实这种理解。

(完整代码可在这里获得。我建议您理解这篇文章中的内容,然后使用其中的代码。)

这是我们将要处理的原始文本:

(为了简化,我故意把句号隔开,并在最后避开了它们。一旦你理解了,就可以随意使用记号赋予器

import numpy as np
import tensorflow as tfcorpus_raw = 'He is the king . The king is royal . She is the royal  queen '# convert to lower case
corpus_raw = corpus_raw.lower()

我们需要将它转换成一个输入输出对,这样如果我们输入一个单词,它应该预测相邻的单词:它前后的 n 个单词,其中 n 是参数,这里有一个例子,来自 Chris McCormick 在 word2vec 上发表的一篇令人惊叹的文章。

A training sample generation with a window size of 2.

注意:如果单词在句子的开头或结尾,窗口将忽略外面的单词。

在此之前,我们将创建一个字典,将单词翻译成整数,将整数翻译成单词。这个以后会派上用场的。

words = []for word in corpus_raw.split():
    if word != '.': # because we don't want to treat . as a word
        words.append(word)words = set(words) # so that all duplicate words are removedword2int = {}
int2word = {}vocab_size = len(words) # gives the total number of unique wordsfor i,word in enumerate(words):
    word2int[word] = i
    int2word[i] = word

这些字典允许我们做的是:

print(word2int['queen'])
-> 42 (say)print(int2word[42])
-> 'queen'

现在,我们想要一个句子列表作为单词列表:

# raw sentences is a list of sentences.
raw_sentences = corpus_raw.split('.')sentences = []for sentence in raw_sentences:
    sentences.append(sentence.split())

这会给我们一个句子列表,每个句子都是一个单词列表。

print(sentences)
-> [['he', 'is', 'the', 'king'], ['the', 'king', 'is', 'royal'], ['she', 'is', 'the', 'royal', 'queen']]

现在,我们将生成我们的训练数据:

(这可能会变得难以阅读。参考代码链接)

data = []WINDOW_SIZE = 2for sentence in sentences:
    for word_index, word in enumerate(sentence):
        for nb_word in sentence[max(word_index - WINDOW_SIZE, 0) : min(word_index + WINDOW_SIZE, len(sentence)) + 1] : 
            if nb_word != word:
                data.append([word, nb_word])

这基本上给出了一个单词列表,单词对。(我们考虑窗口大小为 2)

print(data)[['he', 'is'],
 ['he', 'the'], ['is', 'he'],
 ['is', 'the'],
 ['is', 'king'], ['the', 'he'],
 ['the', 'is'],
 ['the', 'king'],.
.
.
]

我们有训练数据。但是它需要用计算机能理解的方式来表达,比如用数字。这就是我们的格言派上用场的地方。

让我们更进一步,把这些数字转换成一个热矢量。

i.e., 
say we have a vocabulary of 3 words : pen, pineapple, apple
where 
word2int['pen'] -> 0 -> [1 0 0]
word2int['pineapple'] -> 1 -> [0 1 0]
word2int['apple'] -> 2 -> [0 0 1]

为什么是一个热点载体?:稍后告知

# function to convert numbers to one hot vectors
def to_one_hot(data_point_index, vocab_size):
    temp = np.zeros(vocab_size)
    temp[data_point_index] = 1
    return tempx_train = [] # input word
y_train = [] # output wordfor data_word in data:
    x_train.append(to_one_hot(word2int[ data_word[0] ], vocab_size))
    y_train.append(to_one_hot(word2int[ data_word[1] ], vocab_size))# convert them to numpy arrays
x_train = np.asarray(x_train)
y_train = np.asarray(y_train)

所以现在我们有 x_train 和 y_train:

print(x_train)
->
[[ 0\.  0\.  0\.  0\.  0\.  0\.  1.]
 [ 0\.  0\.  0\.  0\.  0\.  0\.  1.]
 [ 0\.  0\.  0\.  0\.  0\.  1\.  0.]
 [ 0\.  0\.  0\.  0\.  0\.  1\.  0.]
 [ 0\.  0\.  0\.  0\.  0\.  1\.  0.]
 [ 0\.  0\.  0\.  0\.  1\.  0\.  0.]
 [ 0\.  0\.  0\.  0\.  1\.  0\.  0.]
 [ 0\.  0\.  0\.  0\.  1\.  0\.  0.]
 [ 0\.  0\.  0\.  1\.  0\.  0\.  0.]
 [ 0\.  0\.  0\.  1\.  0\.  0\.  0.]
 [ 0\.  0\.  0\.  0\.  1\.  0\.  0.]
 [ 0\.  0\.  0\.  0\.  1\.  0\.  0.]
 [ 0\.  0\.  0\.  1\.  0\.  0\.  0.]
 [ 0\.  0\.  0\.  1\.  0\.  0\.  0.]
 [ 0\.  0\.  0\.  1\.  0\.  0\.  0.]
 [ 0\.  0\.  0\.  0\.  0\.  1\.  0.]
 [ 0\.  0\.  0\.  0\.  0\.  1\.  0.]
 [ 0\.  0\.  0\.  0\.  0\.  1\.  0.]
 [ 0\.  1\.  0\.  0\.  0\.  0\.  0.]
 [ 0\.  1\.  0\.  0\.  0\.  0\.  0.]
 [ 0\.  0\.  1\.  0\.  0\.  0\.  0.]
 [ 0\.  0\.  1\.  0\.  0\.  0\.  0.]
 [ 0\.  0\.  0\.  0\.  0\.  1\.  0.]
 [ 0\.  0\.  0\.  0\.  0\.  1\.  0.]
 [ 0\.  0\.  0\.  0\.  0\.  1\.  0.]
 [ 0\.  0\.  0\.  0\.  1\.  0\.  0.]
 [ 0\.  0\.  0\.  0\.  1\.  0\.  0.]
 [ 0\.  0\.  0\.  0\.  1\.  0\.  0.]
 [ 0\.  0\.  0\.  0\.  1\.  0\.  0.]
 [ 0\.  1\.  0\.  0\.  0\.  0\.  0.]
 [ 0\.  1\.  0\.  0\.  0\.  0\.  0.]
 [ 0\.  1\.  0\.  0\.  0\.  0\.  0.]
 [ 1\.  0\.  0\.  0\.  0\.  0\.  0.]
 [ 1\.  0\.  0\.  0\.  0\.  0\.  0.]]

两者都有形状:

print(x_train.shape, y_train.shape)
->
(34, 7) (34, 7)# meaning 34 training points, where each point has 7 dimensions

制作张量流模型

# making placeholders for x_train and y_trainx = tf.placeholder(tf.float32, shape=(None, vocab_size))
y_label = tf.placeholder(tf.float32, shape=(None, vocab_size))

从上图中可以看出,我们将训练数据转换成嵌入式表示。

EMBEDDING_DIM = 5 # you can choose your own numberW1 = tf.Variable(tf.random_normal([vocab_size, EMBEDDING_DIM]))b1 = tf.Variable(tf.random_normal([EMBEDDING_DIM])) #biashidden_representation = tf.add(tf.matmul(x,W1), b1)

接下来,我们利用嵌入维度中的信息,对邻居进行预测。为了进行预测,我们使用 softmax。

W2 = tf.Variable(tf.random_normal([EMBEDDING_DIM, vocab_size]))b2 = tf.Variable(tf.random_normal([vocab_size]))prediction = tf.nn.softmax(tf.add( tf.matmul(hidden_representation, W2), b2))

总结一下:

input_one_hot  --->  embedded repr. ---> predicted_neighbour_probpredicted_prob will be compared against a one hot vector to correct it.

现在,剩下的就是训练它:

sess = tf.Session()init = tf.global_variables_initializer()sess.run(init) #make sure you do this!# define the loss function:
cross_entropy_loss = tf.reduce_mean(-tf.reduce_sum(y_label * tf.log(prediction), reduction_indices=[1]))# define the training step:
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(cross_entropy_loss)n_iters = 10000# train for n_iter iterationsfor _ in range(n_iters):
    sess.run(train_step, feed_dict={x: x_train, y_label: y_train}) print('loss is : ', sess.run(cross_entropy_loss, feed_dict={x: x_train, y_label: y_train}))

在训练中,你会得到损失的显示:

loss is :  2.73213
loss is :  2.30519
loss is :  2.11106
loss is :  1.9916
loss is :  1.90923
loss is :  1.84837
loss is :  1.80133
loss is :  1.76381
loss is :  1.73312
loss is :  1.70745
loss is :  1.68556
loss is :  1.66654
loss is :  1.64975
loss is :  1.63472
loss is :  1.62112
loss is :  1.6087
loss is :  1.59725
loss is :  1.58664
loss is :  1.57676
loss is :  1.56751
loss is :  1.55882
loss is :  1.55064
loss is :  1.54291
loss is :  1.53559
loss is :  1.52865
loss is :  1.52206
loss is :  1.51578
loss is :  1.50979
loss is :  1.50408
loss is :  1.49861
.
.
.

它最终在持续亏损的基础上稳定下来。即使不能得到高精度,我们也不在乎。我们感兴趣的只是 W1 和 b1,也就是隐藏的表示。

让我们来看看它们:

print(sess.run(W1))
print('----------')
print(sess.run(b1))
print('----------')->[[-0.85421133  1.70487809  0.481848   -0.40843448 -0.02236851]
 [-0.47163373  0.34260952 -2.06743765 -1.43854153 -0.14699034]
 [-1.06858993 -1.10739779  0.52600187  0.24079895 -0.46390489]
 [ 0.84426647  0.16476244 -0.72731972 -0.31994426 -0.33553854]
 [ 0.21508843 -1.21030915 -0.13006891 -0.24056002 -0.30445012]
 [ 0.17842589  2.08979321 -0.34172744 -1.8842833  -1.14538431]
 [ 1.61166084 -1.17404735 -0.26805425  0.74437028 -0.81183684]]
----------[ 0.57727528 -0.83760375  0.19156453 -0.42394346  1.45631313]----------

为什么是一个热点载体?

again from Chris McCormick’s article (do read it)

当我们将 one hot vectors 乘以W1时,我们基本上可以访问W1的行,它实际上是由输入 one hot vector 表示的单词的嵌入式表示。所以W1本质上是作为一个查找表。

在我们的例子中,我们还包括了一个偏见术语b1,所以你必须添加它。

vectors = sess.run(W1 + b1) # if you work it out, you will see that it has the same effect as running the node hidden representationprint(vectors)
->
[[-0.74829113 -0.48964909  0.54267412  2.34831429 -2.03110814]
 [-0.92472583 -1.50792813 -1.61014366 -0.88273793 -2.12359881]
 [-0.69424796 -1.67628145  3.07313657 -1.14802659 -1.2207377 ]
 [-1.7077738  -0.60641652  2.25586247  1.34536338 -0.83848488]
 [-0.10080346 -0.90931684  2.8825531  -0.58769202 -1.19922316]
 [ 1.49428082 -2.55578995  2.01545811  0.31536022  1.52662396]
 [-1.02735448  0.72176981 -0.03772151 -0.60208392  1.53156447]]

如果我们想要“女王”的代表,我们要做的就是:

print(vectors[ word2int['queen'] ])# say here word2int['queen'] is 2-> 
[-0.69424796 -1.67628145  3.07313657 -1.14802659 -1.2207377 ]

那么我们能用这些美丽的载体做什么呢?

这里有一个快速函数,可以找到与给定向量最近的向量。请注意,这是一个肮脏的实现。

def euclidean_dist(vec1, vec2):
    return np.sqrt(np.sum((vec1-vec2)**2)) def find_closest(word_index, vectors):
    min_dist = 10000 # to act like positive infinity
    min_index = -1 query_vector = vectors[word_index] for index, vector in enumerate(vectors): if euclidean_dist(vector, query_vector) < min_dist and not np.array_equal(vector, query_vector): min_dist = euclidean_dist(vector, query_vector)
            min_index = index return min_index

我们现在将使用“king”、“queen”和“royal”查询这些向量

print(int2word[find_closest(word2int['king'], vectors)])
print(int2word[find_closest(word2int['queen'], vectors)])
print(int2word[find_closest(word2int['royal'], vectors)])->queen
king
he

有趣的是,我们的嵌入了解到

king is closest to queen
queen is closest to king
royal is closest to he

第三个是由于我们的语料库(还是蛮不错的)。更大的语料库将导致更好的结果。(注意:由于权重的随机初始化,您可能会得到不同的结果。如果需要,运行几次

让我们画出它们的向量!

首先,让我们用我们最喜欢的降维技术将维数从 5 减少到 2:tSNE(tee SNE!)

from sklearn.manifold import TSNEmodel = TSNE(n_components=2, random_state=0)
np.set_printoptions(suppress=True)
vectors = model.fit_transform(vectors)

然后,我们需要对结果进行规范化,以便在 matplotlib 中更方便地查看它们

from sklearn import preprocessingnormalizer = preprocessing.Normalizer()
vectors =  normalizer.fit_transform(vectors, 'l2')

最后,我们将绘制 2D 归一化向量

import matplotlib.pyplot as pltfig, ax = plt.subplots()for word in words:
    print(word, vectors[word2int[word]][1])
    ax.annotate(word, (vectors[word2int[word]][0],vectors[word2int[word]][1] ))plt.show()

哇!shequeen近而kingroyalqueen等距离我们需要一个更大的语料库来看一些更复杂的关系。

注意:在发表这篇文章后,我意识到这个例子是不正确的,因为要得到有意义的向量收敛,我们需要一个非常大的语料库。数据量小,容易受到突然的“冲击”。然而,出于教学目的,我将保持这种写作的完整性。为了有效地实现 word2vec,请尝试使用一些类似于text 8的语料库 gensim

为什么会这样?

我们给了神经网络预测邻居的任务。但是我们还没有具体说明网络应该如何预测它。因此,神经网络计算出单词的隐藏表示形式,以帮助它完成预测相邻单词的任务。预测相邻单词本身并不是一项有趣的任务。我们关心这个隐藏的表示。

为了形成这些表示,网络使用上下文/邻居。在我们的语料库中,kingroyal作为邻居出现,royalqueen作为邻居出现。

为什么预测邻居是一项任务?

嗯,其他任务也设法形成一个好的表示。预测这个单词是否是一个有效的 n-gram,如这里的所示也可以得到好的向量!

我们试图预测给定单词的相邻单词。这就是所谓的跳过克模型。我们可以使用中间词的相邻词作为输入,并要求网络预测中间词。这就是所谓的连续词汇袋模型。

延伸阅读:

这绝不是对 word2vec 的完整理解。w2v 的部分魅力在于它对我刚刚谈到的内容做了两处修改。这些是:

  • 负采样
  • 分级 Softmax

负采样:它表明,不是反向传播正确输出向量中的所有 0(对于 10 密耳的 vocab 大小,有 10 密耳减去 1 个零),而是我们只反向传播它们中的一些(比如 14 个)

分级 Softmax: 计算 10mill 的 vocab 的 Softmax 非常耗时且计算量大。分级 Softmax 提出了一种使用霍夫曼树的更快的计算方法

为了保持这篇文章的简洁,我避免了过多的探究。我绝对推荐多读点进去。

结束语:

  • 单词向量超级酷
  • 不要把这个 tensorflow 代码用于实际使用。只是为了理解。使用像 gensim 这样的库

我希望这能帮助人们更好地理解这些美景。如果是的话,让我知道!

如果我犯了错误,告诉我。

我很乐意通过推特linkedin 或/和电子邮件与你联系。

再见!

学习新的数据科学语言

原文:https://towardsdatascience.com/learning-a-new-data-science-language-aa7656be730a?source=collection_archive---------2-----------------------

Source: Wikimedia Commons

在不断变化的数据科学工具生态系统中,您经常发现自己需要学习一门新语言,以便跟上最新的方法或更有效地与同事协作。我做 R 程序员已经有几年了,但是想要过渡到 Python 以便充分利用深度学习库和工具,比如 PySpark。此外,我加入了 Zynga 的数据科学团队,在那里 Python 是首选语言。虽然只有几个星期,但是我已经开始掌握使用这种新语言进行探索性数据分析和预测性建模的诀窍了。这不是我第一次尝试快速掌握一门新的数据科学语言,但却是最成功的一次。我想分享一些我作为一名数据科学家开始使用新编程语言的指导方针。

关注结果,而不是语义 虽然在深入研究编程之前了解编程语言的基础很有用,但我发现在掌握这门语言之前只需要简单介绍一下。在用 Python 编码之前,我从头开始通读了数据科学的第二章,它提供了 Python 的速成课程。我的下一步是整理出我希望能够用 Python 完成的任务列表,包括:

  • 读取和写入 CSV 文件中的数据
  • 对数据帧执行基本操作,例如显示数据类型
  • 绘制直方图和折线图
  • 连接到数据库并将数据拉入数据帧
  • 创建逻辑回归模型
  • 评估模型的度量,例如准确性和提升

我不再关注语言的语义,比如理解 Python 中列表和元组的区别,而是开始着手执行日常的数据科学任务。我知道如何在 R 中完成这些任务,并且需要学习如何将这些技能翻译成一种新的语言。比如我了解到 R 中的 summary() 类似于熊猫 dataframes 的 describe()

我很快发现,在 Python 中执行数据科学任务通常需要利用许多不同的库。当使用 PandasSciKit-Learn 库时,上述任务更容易执行。这引出了我在学习 Python 时学到的下一课。

学习生态系统,而不是语言Tidyverse 这样的工具让 R 比基础语言多得多,其他数据科学语言也有类似的库,为语言提供了有用的扩展。我没有只专注于学习基础语言,而是将学习库作为我最初学习 Python 过程的一部分。作为起点,我探索了下面的库。

  1. 熊猫 :提供类似 r 的 dataframe 功能。
  2. 框架查询 : 支持在数据框架上使用 SQL。
  3. SciKit-Learn :为 ML 模型提供标准接口。
  4. Pandas-gbq:Python 的 BigQuery 接口。

使用这些库可以更容易地完成我已经熟悉的其他语言的任务。像 framequery 这样的库在学习一门新语言时很有用,因为在熟悉 Pandas 处理数据帧的方式之前,您可以使用 SQL 处理数据帧。我发现它很容易使用,因为它类似于我已经在 r 中使用的 sqldf 库。

使用跨语言库通过在一种新的语言中重新应用你已经知道的库来引导你的学习过程是很棒的。我在学习过程的早期探索的一个库是 Keras deep learning 库,我以前在 R 中使用过这个库。下面是用这些语言建立 Keras 模型的一个例子:

**# Creating a Keras model in R** model <- keras_model_sequential() %>%
  layer_dense(units = 64, activation = "relu",
              input_shape = 10) %>%
  layer_dense(units = 64, activation = "relu") %>%
  layer_dense(units = 1)**# Creating the same Keras model in Python** model = models.Sequential()
model.add(layers.Dense(64, activation='relu', 
          input_shape=10))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(1))

能够在我已经熟悉的库的基础上构建有助于加快我的学习过程。 Plotly 是另一个我以前在 R 中使用过的库,现在我正在 Python 中使用它。

使用真实世界的数据 样本数据集,例如 sklearn 中的糖尿病数据集,对于开始使用一门新语言或一个新的库来说是非常棒的,但是直到你需要将这些方法应用于一个新问题时,你才会真正了解你正在做的事情的细节。例如,您可能需要执行多类分类,而不是从示例数据集中重新应用二元分类。在学习一门新语言时,尽早应用来自组织的数据集是很有帮助的。

使用真实世界的数据非常有用,原因有很多,例如:

  1. 规模:训练数据集通常很小,使用真实世界的数据往往涉及大得多的数据集,需要采样等方法。
  2. 表示:使用来自您组织的数据意味着您需要定义如何为建模标记实例和编码特征。
  3. 管理:您需要将数据放入内存并执行数据管理任务,比如处理缺失值。
  4. 评估:使用来自您组织的现有数据集意味着您可以将新语言中的结果与其他实现中的先前结果进行比较,例如将 R 的 glmsklearn.linear_model 进行比较。

这条指导方针与第一条相似,它有助于获得真实世界的数据并专注于产生结果。

如果可能的话,从本地开始 学习分布式计算语言时,比如 Spark 的 scala,让一个环境启动并运行起来通常是很困难的。我的建议是,如果没有必要,不要把分布式系统或虚拟化作为出发点。例如,使用 Spark,您可以在本地设置一个机器实例,并使用类似于 Zeppelin 的工具来提供一个交互式前端。当你学习一门新语言时,你不应该担心部署问题,比如将代码推送到服务器。在本地运行代码通常意味着有更多的调试工具可用。

对于 Python 入门,我也有同样的建议。Jupyter 笔记本使使用 Python 变得容易,但是一旦你熟悉了这种语言,它会更有用。首先,我推荐使用 IDE,比如 PyCharm 。一旦你准备好开始与队友合作,像 JupyterLab 这样的工具会提供很好的环境。

早动手 学习一门新语言的时候,不去尝试,你不会知道自己不懂的东西。这与我的第一条指导方针有关,它有助于及早发现你在知识方面的差距。在学习 Python 时,我发现将阅读和编程结合起来会更有效,而不是将一堆阅读内容放在前面。一旦我进入代码,我就确定了我需要学习的新领域,比如发现 Pandas 是我需要使用的第一个库之一。

在学习一门新的语言或库时,有几种不同的方法可以让你亲自动手。我和 R 在读深度学习的时候,用提供的笔记本开始做样题。此外,一些公司提供 Jupyter 笔记本电脑,新员工可以在入职过程中使用。我通常采用的方法是使用现有的数据集,同时用一种新语言重新实现一个模型。

推动您的知识
一旦您学习了该语言的一些基础知识,并了解了如何执行常见的数据科学任务,尝试该语言的一些新功能将非常有用。例如,当我第一次学习 R 时,我编写了使用函数作为参数和在数据帧上使用 apply 的基本示例。我对函数式编程比较陌生,这些例子帮助我了解了新的编程习惯。应用是一个非常有用的功能,我现在可以在熊猫上利用它了。

这一点我会留到以后的学习过程中去做,因为这对于掌握一门新的语言来说并不是必需的,但对于掌握一门语言来说却是必不可少的。如果你已经熟悉了几种编程语言,这是你可以更早开始的一步。

寻求反馈 拥有反馈渠道非常好,无论是您组织中的另一位数据科学家还是在线论坛。你可能会学到你还没有发现的新的库或语言特性。当你在一家小公司或从事独立项目时,这更具挑战性。在我的上一份工作中,当我在一家初创公司担任唯一的数据科学家时,我发现 rstats subreddit 是一个征求反馈的有用地方。也有不同语言的编程社区,这是学习的好地方。我参加了用户!2016 年的会议,这对于使用 R. Python 与科学家和实践者交流来说是一件非常棒的事情。Python 也有类似的会议,但我还没有参加过。

结论 学习一门新的数据科学语言需要时间,但它有助于你制定一个如何利用时间的计划。我的总体建议是深入研究,用真实数据对应用问题进行编码。你会发现自己的差距,并以此来指导你的学习过程。

本·韦伯是 Zynga 的首席数据科学家。我们正在招聘

学习学习的算法

原文:https://towardsdatascience.com/learning-about-algorithms-that-learn-to-learn-9022f2fa3dd5?source=collection_archive---------2-----------------------

当我第一次听说元学习时,它的前提让我很兴奋:建造不仅能够学习,而且能够学习如何学习的机器。元学习的梦想愿望是算法能够根据性能信号修改其架构和参数空间的基本方面,算法能够在面对新环境时利用积累的经验。简而言之:当未来学家为我们编织普遍胜任的人工智能的梦想时,符合这一描述的组件是这些愿景不可或缺的组成部分。

这篇博文的目标是从这些崇高的高度,从我们想象的一些抽象的自我修改代理可以做的事情,下降到该领域今天的实际位置:它的成功,它的局限性,以及我们离强大的多任务智能还有多远。

为什么人类可以做我们做的事情?

具体来说:在许多强化学习任务中,相对于人类需要的时间,算法需要惊人长的时间来学习任务;目前玩 Atari 游戏的技术水平需要大约 83 小时(或 1800 万帧)的游戏时间才能达到人类的中等表现,大多数人在接触游戏几个小时后就可以达到这一水平。

A figure from the recent Rainbow RL paper

这种差异导致机器学习研究人员将问题框定为:人脑为这样的任务带来了什么工具和能力,以及我们如何以统计和信息论的方式构想这些工具?具体来说,元学习研究者似乎有两种主要策略,大致对应于关于这些工具是什么的两种理论。

  1. 习得先验:在这个镜头中,人类可以快速学习新任务,因为我们可以重复使用我们在过去任务中已经学到的信息,比如物体如何在空间中移动的直观物理学,或者在视频游戏中失去一条生命会导致奖励降低的元知识。
  2. 习得策略:这是一种想法,即在我们的一生中(也许是在进化的时间尺度上),我们不仅收集关于世界的客体层面的知识,而且还发展了一种神经结构,这种结构在接受输入并将其转化为输出或策略方面更有效,即使在非常新颖的环境中也是如此。

现在,很明显,这两个想法并不相互排斥,它们之间甚至没有硬性的界限:我们与世界互动的一些硬编码策略可能基于关于世界的深刻先验,比如这样的事实(至少对于与这篇博客帖子相关的所有目的而言)世界有一个因果结构。也就是说,我发现这些想法非常不同,值得将它们分为这两个标签,并将其视为相关轴的两极。

不要放弃我的(一次)机会

在深入元学习之前,了解一下一次性学习相关领域的概念基础是很有用的。其中元学习的问题是“我如何才能建立一个快速学习新任务的模型”,而单镜头学习的问题是“我如何才能在只看到一个类的例子后,建立一个可以学习如何对该类进行分类的模型”。

让我们在概念层面上思考一下,是什么让一次性学习变得困难。如果我们试图只在相关类的一个例子上训练一个普通模型,它几乎肯定会过拟合。如果一个模型只看到一幅画,比如说,字母 3,它不会理解一幅图像可以经历什么样的像素变化而仍然保持本质上的 3。例如,如果模型只显示了这个序列中的前 3 个,那么如何先验地知道第二个 3 是同一物种的一个例子呢?理论上,我们对网络学习感兴趣的类别标签与构成字母的线条粗细有关系,这难道不是可能的吗?这对我们来说似乎很傻,但只有一个三的例子,对网络来说这不是一个微不足道的推论。

拥有更多 3s 的例子有助于解决这个问题,因为我们可以了解图像的哪些特征定义了它的基本三维性——两个凸起形状的存在,主要是垂直方向——以及哪些类型的修改是不相关的——线条的粗细,角度的锐度。为了一次性学习成功,我们必须激励网络学习什么样的属性通常将一个数字与另一个数字区分开,而不需要每个数字的具体允许变化的例子。

一次学习中的常见技术是学习嵌入空间,其中计算该空间中两个示例的表示之间的欧几里德相似性是计算这两个示例是否属于同一类的良好代理。直觉上,这需要学习在这个分布(在我的例子中:数字上的分布)中,阶级分化最强的内部维度,并学习如何压缩和转换输入到那些最相关的维度。

我发现把这个问题记在心里是一个有用的基础,尽管不是试图学习如何总结存在于类分布中的共享信息和模式,而是试图学习存在于任务分布中的规律,每个任务都有其自己的内部结构或目标。

如果要求构建一个神经网络元参数的排序,从最少到最抽象,它会是这样的:

  1. 通过使用超参数化梯度下降,网络学习表示在任务的全部分布中是有用的。 MAML爬虫就是很好的直接例子,而共享层次的元学习是一种有趣的方法,它将表示学习为主策略控制的显式子策略。
  2. 网络学习优化其自身梯度下降操作的参数。这些参数是:学习率、动量和自适应学习率算法的权重。在这里,我们开始走上修改学习算法本身的轨道,但以有限的、参数化的方式。这就是学习通过梯度下降学习通过梯度下降所做的。是的,那是报纸的真正标题。
  3. 学习内环优化器的网络本身就是网络。也就是说:其中梯度下降用于更新神经优化器网络参数,使得它们跨任务表现良好,但是其中在每个单个任务内从输入数据到输出预测的映射完全由网络进行,而没有任何损失或梯度的显式计算。这就是一个简单的神经注意力元学习者的工作方式。

为了让这篇文章不那么庞大,我将主要关注 1 和 3,来说明这个范围的两个概念。

任何其他名字的任务

另一个简短的旁白——我保证是最后一个——我希望它能澄清一个可能会令人困惑的话题。通常,在元学习的讨论中,你会看到提到“任务分配”的想法。你可能会注意到这是一个很难定义的概念,你是对的。当一个问题是一个任务,或者分布在多个任务上时,似乎没有一个明确的标准。例如:我们是否应该将 ImageNet 视为一项任务——物体识别——或多项任务——区分狗是一项任务,区分猫是另一项任务?为什么玩一个雅达利游戏是一个任务,而不是几个任务组成的游戏的个人水平?

我能从所有这些中提取的是:

  • “任务”的概念与已经建立的数据集是非常复杂的,因为把在一个数据集上学习看作一个单一的任务是很自然的
  • 对于任何给定的任务分布,这些任务彼此之间的差异可能非常显著(即,每个任务学习不同振幅的正弦波,而每个任务玩不同的 Atari 游戏)
  • 因此,不要马上说“啊,这个方法可以推广到,所以这是一个很好的指标,它通常可以在一些任意不同的任务分布上表现良好”。这当然不是该方法有效的方向上的坏的 T2 证据,但是它确实需要批判性的思考来考虑网络为了在所有任务中表现良好实际上需要展示多大的灵活性。

那些莫名其妙地以动物命名的

2017 年初,切尔西·芬恩和一个来自伯克利的团队发布了一项名为 MAML 的技术:模型不可知元学习

In case you didn’t think the joke was intentional, turn to the “Species of MAML” section of the paper

在习得策略和习得先验之间,这种方法倾向于后者。该网络的目标是训练一个模型,如果给定一个新任务的梯度步长更新,该模型可以很好地概括该任务。这个的伪代码算法是这样的

  1. 随机初始化网络的参数θ
  2. 从任务 t 的分布中选择某个任务 t。使用训练集中的 k 个示例(通常为 10 个),在当前参数集指示的位置执行一个梯度步骤,从而得到最终的参数集。
  3. 在测试数据集上评估这些最终参数的性能
  4. 然后,根据您的初始参数 theta 计算 task-t 测试集性能的梯度。然后基于该梯度更新那些参数。回到第一步,用你刚刚更新的θ作为这一步的初始θ

这是在做什么?在一个非常抽象的层面上,它是在参数空间中找到一个点,这个点在期望中最接近于它的分布中的许多任务的一个好的概括点。您可以认为这是在迫使模型在探索参数空间时保持某种程度的不确定性和谨慎。简而言之:当一个网络认为其梯度完全代表人口分布时,它可能会陷入一个损失特别低的区域,MAML 将更有动力在多个山谷的顶点附近找到一个区域,每个山谷在预期的所有任务中都包含合理的低损失。正是这种对谨慎的激励,帮助 MAML 避免了在新任务中只给出少量例子时,模型可能会出现的过度拟合。

2018 年初,该文献又增加了一个新版本,名为《爬行动物》。正如你可能从它的名字中猜到的那样——早期 MAML 的一个游戏——爬行动物从 MAML 的前提开始,但找到了一种计算它的初始参数更新循环的方法,这种方法在计算上更有效。在 MAML 显式地采用测试集损失相对于初始参数θ的梯度的情况下,爬虫代之以在每个任务上执行 SGD 更新的几个步骤,然后使用更新结束时的权重和初始权重之间的差,作为用于更新初始权重的“梯度”。

g1 here represents the gradient update you get from only performing one gradient descent step per task

从直觉上来说,这种做法有点奇怪,因为,天真地说,这似乎和把所有任务混合在一起进行训练没有什么不同。然而,作者认为,由于对每个任务采取 SGD 的多个步骤,每个任务的损失函数的二阶导数受到影响。为此,他们将其更新分解为两部分:

  1. 一个将结果推向“联合训练损失”的术语,即如果你只是在混合任务上训练,你会得到的结果,以及
  2. 将初始化推向一个点的术语,在该点上,后续 SGD 小批次的梯度彼此接近:即,小批次之间的梯度方差较低。作者推测,这一术语导致快速学习时间,因为它鼓励在每项任务中处于更稳定和低方差的训练区域。

我选择 MAML/爬行动物组作为事物“习得先验”的代表,因为理论上,网络通过学习内部表征而成功,这些表征要么对任务的全部分布进行分类有用,要么在参数空间中接近广泛有用的表征。

为了阐明这一点,看一下上图。它将 MAML 与一个刚刚经过预训练的网络进行了比较,当时两者都经过了一系列由不同相位和振幅的正弦波组成的回归任务的训练。在这一点上,两者都“微调”到一个新的特定任务:红色显示的曲线。紫色三角形表示少量渐变步骤中使用的数据点。例如,与训练前的网络相比,MAML 了解到正弦波具有周期性结构:在 K=5 时,它能够更快地将左手峰移动到正确的位置,而无需实际观察该空间区域的数据。虽然很难说我们的(有些生硬的)解释是否是引擎盖下发生的事情的完美机械匹配,但我们可以推断,MAML 在弄清楚正弦波彼此不同的两个相关方面——相位和振幅——以及如何从给定的数据中学习这些表示方面做得更好。

一路向下的网络

对于一些人来说,甚至使用已知的算法如梯度下降来学习全局先验的想法。谁说我们设计的学习算法是最有效的?我们能不能学一个更好的?

这是 RL(快速强化学习通过慢速强化学习)采用的方法。这个模型的基本结构是一个递归神经网络(技术上:一个 LTSM 网络)。由于 rnn 具有存储状态信息的能力,并根据该状态给出不同的输出,因此理论上它们有可能学习任意的可计算算法:换句话说,它们有可能是图灵完全的。以此为基础,RL 的作者构建了一个 RNN,使得 RNN 接受训练的每个“序列”实际上是一系列给定 MDP 的经历(MDP =马尔可夫决策过程)。对于这个解释,你可以把每个 MDP 看作是定义了一组可能的行动和这些行动在环境中产生的潜在回报。然后,在许多序列上训练 RNNs 如 RNN 通常所做的那样,在这种情况下,这些序列对应于许多不同的 MDP,并且优化 RNN 的参数,以在所有序列/试验的总和上产生低遗憾。后悔是一个衡量你在一系列事件中的总回报的指标,所以除了激励网络在试验结束时达到一个好的政策,它还激励更快的学习,这样你在坏的低回报政策下采取的探索行动就更少了。

A diagram showing the internal workings of the RNN over multiple trials, corresponding to multiple different MDPs.

在试验中的每一点,网络采取的动作是由在多个任务中学习的权重矩阵和隐藏状态的内容参数化的函数,隐藏状态的内容作为数据的函数更新,并充当一种动态参数集。因此,RNN 正在多个任务中学习如何更新其隐藏状态的权重,以及控制如何利用它的权重。然后,在一个给定的任务中,隐藏状态可以捕获关于网络有多确定的信息,是否是时候探索或利用,等等,作为它在特定任务中看到的数据的函数。从这个意义上来说,RNN 正在学习一种算法,这种算法可以确定如何最好地探索空间,并更新其最佳策略的概念,并且学习这种算法,以便在任务分配上表现良好。作者将 RL 架构与对他们尝试的任务来说渐近最优的算法进行了比较,RL 的表现相当。

我们能放大这个吗?

这只是一个非常压缩的领域介绍,我敢肯定,有我错过的想法,或我说错了概念。如果你想要一个额外的(更好的)视角,我强烈推荐切尔西·芬恩的这篇博客文章,它是 MAML 论文的第一作者。

我花了几个星期的时间,试图从概念上压缩这些论文的分布,并产生适用于所有论文的广泛理解,这给我留下了一系列一般性的问题:

  • 这些方法在高度多样化的任务中表现如何?这些论文中的大部分都针对具有相对较低多样性水平的任务分布进行了概念验证测试:具有不同参数的正弦曲线、具有不同参数的多股武装匪徒、来自不同语言的字符识别。对我来说,在这些任务分配上表现良好并不一定能概括为,例如,不同复杂程度和不同形式的任务,比如图像识别结合问题回答结合逻辑谜题。
    然而,人类大脑确实从这些高度多样化的任务集中形成了它的先验,在它们之间来回传递关于世界的信息。我在这里的主要问题是:只要你投入更多的单元和计算,这些方法会像宣传的那样对这些更多样化的任务起作用吗?或者在任务多样性曲线的某个点上是否存在非线性效应,使得在这些低多样性下有效的方法在高多样性下根本无效。
  • 这些方法对大量计算的依赖程度如何?这些论文大部分是在小而简单的数据集上运行的部分原因是,当你的每一次训练运行都涉及(有效地)将模型训练到关于元参数功效的数据点的内部循环时,测试在时间和计算上可能非常昂贵。鉴于摩尔定律最近似乎在放缓,谷歌以外的任何地方有多大可能研究这些算法的有用规模版本,其中一个困难问题的每个内循环迭代可能需要数百小时的 GPU 时间?
  • 这些方法与寻找明确编码世界先验的方法相比如何?语言是人类武器库中一个非常有价值的工具。用机器学习的术语来说,这基本上是高度压缩的信息,嵌入在我们知道如何从概念上操纵的空间中,我们可以从一个人转移到另一个人。没有人能够独自从经验中提炼出所有的知识,所以我怀疑我们是否能够真正解决整合世界知识的模型问题,除非我们找到了学习算法的类似方法。

了解数据科学—构建图像分类器(第 2 部分)

原文:https://towardsdatascience.com/learning-about-data-science-building-an-image-classifier-part-2-a7bcc6d5e825?source=collection_archive---------1-----------------------

注意:这篇文章也可以叫做“我在哪里做得很快。ai 的第三课并意识到有很多东西我可以添加到我的模型中”。

第一部分,我建立了一个 VGG 模型:

[## 了解数据科学—构建图像分类器

嗨!我叫 Gabi,正在学习数据科学。我计划写下我正在学习的东西,以帮助我组织…

medium.com](https://medium.com/@gabrieltseng/learning-about-data-science-building-an-image-classifier-3f8252952329)

我在这篇文章中创建的模型概要:

I trained the ResNet and Inception V3 models, and used their outputs (and the output of the VGG model trained in part 1) as inputs for a classifier, which I then used to combine the three models and output my final predictions.

内容:

  1. 我对自己创建的第一个 VGG 网络实施了丢弃和批量归一化,但这最终对网络的改进作用不大
  2. 训练 ResNet50 和 Inception V3 我使用 Keras 的应用程序来创建和加载预训练的 ResNet 50 和 Inception V3 网络,并对它们进行微调。
  3. 优化 sklearn 算法 把 3 个模型结合起来,我用的是 sklearn。

我注意到我的验证准确性高于我的训练准确性:

A comparison of the training and validation accuracies for the first 5 epochs when training my model. This is the final model I trained, including the data augmentation and training all the way to the first convolutional layer.

这表明拟合不足,即模型过于受限,无法正确拟合训练数据。这可能是因为在完全连接的块中添加了一个层:

From part 1: A fully connected block, adding a fully connected layer followed by a dropout layer

丢弃层通过将一半的权重随机设置为 0 来防止过度拟合(在训练时,这不会发生在验证集上)。一种矫正方法是去除脱落层。

  1. 去除漏层和批量标准化

定义和动机:

Dropout 随机将某个权重比率设置为 0。这样做的后果是,它会导致欠拟合,因为我的模型正在训练的一半重量被忽略了。

批处理规范化类似于我在第 1 部分中添加的均值预处理层,除了批处理规范化不只是在开始时规范化数据集,而是在层之间进行。这很有用,因为在模型中,值可能会变得非常大,从而扭曲权重。批量标准化可以避免这种情况,从而防止过度拟合。

我编写了以下方法来实现丢弃和批处理规范化:

vgg_bn returns a VGG model with a defined dropout, and (optionally) with batch normalization. Lines 24–26 adjust the weights, multiplying them by 0.5/(1-dropout). Adding batch normalization doesn’t increase the number of layers in the model, so the weights can be directly copied over by enumerating over both models’ layers using zip()

我使用它能得到的最好结果是批量标准化和 0.5 的丢弃率(事实证明,删除丢弃率会导致显著的过度拟合,并显著降低验证的准确性)。

这就是说,改进是微不足道的(99%对 98.5%的验证准确率只代表多了一张正确分类的图像),并且没有反映在 Kaggle 中,表明该模型没有显著改进。

The best result so far!

幸运的是,我还有一招!

2。与 ResNet 组装

如果我训练不同的模型,它们可能会拾取稍微不同的东西,因此在它们之间,可能所有的图像都被正确分类。因此,我可以训练多个模型,然后组合它们的输出;这被称为集合。

具体来说,我要训练 ResNet50,它在 2015 年赢得了 ImageNet 比赛(VGG 在 2014 年获胜)。

2.a.i .实施 ResNet

ResNet-50 在映像网 2015 年的比赛中胜出(VGG 在 2014 年的比赛中胜出)。我的希望是,这两个模型中的差异将允许它们相互补偿,并最终产生更强的结果。

ResNet50 是一个 res idual net 的作品,它远比卷积网络(107 层到 VGG 的 38 层)更深入。形象化 ResNet 的一个好方法是卷积块的集合(回想一下,集合是不同模型的输出组合)。

Keras 实际上已经预装了一些模型(包括重量),作为其应用的一部分;我想构建自己的 ResNet 模型,这样我就可以包含一个预处理层(使用 fast.ai weights ),但我也将从这里开始绘制。

The definition for the Lambda layer is a little different than for the VGG model, see why here.

2.a.ii 培训结果网

为了训练 ResNet,我使用了与 VGG 相同的图像数据生成器。我分两个阶段训练 ResNet,首先训练(随机初始化的)最后一层,然后也训练最后一个卷积块。

The vertical red line marks where I allow more layers to be trained.

在学习率下降的情况下,对更多的时期(另外 40 个时期)训练 ResNet,将验证准确率提高到 97%。

2.b .盗梦空间 V3

在尝试让 ResNet 模型工作了很长时间之后,我意识到 lambda 层对它的性能没有什么帮助。因此,我添加了 Inception V3 模型,它也是由 Keras 预加载的,并根据 ImageNet 数据进行了训练:

然后,我将这个 V3 模型与数据进行拟合:

A plot of accuracy against epochs when training the Inception V3 model. The red line marks where I allowed more layers to be trained.

2.b .组合模型

我打算使用 Keras 合并层来合并这两个模型。然而,有一个问题:VGG 模型是顺序模型,而 ResNet 和 V3 模型是功能模型。我在 ResNet 和 VGG 中引入的 lambda 层可以自动预处理图像,这意味着 Keras 不想将模型从顺序模型更改为功能模型(否则,它应该能够),所以我要做的是使用 Scikit-learn 来组合模型。

为此,我将使用 VGG 和雷斯内特的输出作为我的线性回归的输入:

This method takes the outputs of the models in the input array ‘model’, and turns them into X data- features- with which a scikit learn linear regression can be trained. The classes of the batches — the true Y values — is also returned. The shape of X is printed to make sure everything is going okay; the number of rows should increase by 1 for every model trained, and the number of columns should stay constant.

我使用 make_xy 制作了以下几对特征:

X_train 和 Y_train,基于训练数据。

基于验证数据的 X_valid 和 Y_valid。

然后,我用 k 近邻、支持向量机和逻辑回归算法进行了实验。

具有 10 个邻居的 k 个最近邻居产生最高的 AUC-ROC 得分(0.9866)。

The AUC-ROC of the knn algorithm when ensembled from the X and Y data.

结论,我学到了什么

我从集合中最大的收获是,许多差的模型不能弥补一个强的模型;当 ResNet 和 V3 达到大约 90%的准确率时,我开始尝试组合这些模型,这降低了我的最终分数,而不是提高了它。

我的第二个观点是模特需要很长的训练时间!我在训练我的 VGG 模型时使用了提前停止回调,但没有在 Inception V3 的 ResNet 中使用它,因为这些模型并不总是具有不断增加的准确性,提前停止通常会缩短它们的训练。不使用早期停止意味着我没有为大约 20 个时期训练我的模型,而是最终为接近 50 或 60 个时期训练它们。

我也有过快降低学习速度的倾向,并假设模型已经收敛;实验(和耐心)让我大大提高了模型的能力。

最后,我认识到这个过程可能会令人沮丧!我花了很多时间在最终没有改善我的最终结果的路径上,但是最终得到一个更强的模型是非常棒的。

在现实世界中学习和表演

原文:https://towardsdatascience.com/learning-and-performing-in-the-real-world-7e53eb46d9c3?source=collection_archive---------3-----------------------

又名强化学习

为了与复杂的环境互动,生物实体需要产生一个“正确”的动作序列,以实现延迟的未来回报。这些生命实体,或者说角色,能够感知环境,并对环境和代理先前历史的一系列状态做出反应。见图:

The reinforcement learning loop: an agent performs actions in an environment, and gets rewards. Learning has to occur through sparse rewards

我们想要学习执行一些任务的场景是:

  • 环境中的演员
  • 演员有他/她想要实现的目标
  • 循环:演员感知自身和环境
  • 循环:演员动作影响自身和环境
  • 延迟奖励或惩罚——我们达到目标了吗?
  • 学习:如何最大化奖励和最小化惩罚

这些动作促使演员更接近多个目标,即使实现一个目标也可能需要不确定的步骤。代理需要学习模型状态和行动的正确顺序,通过与世界互动和执行在线学习来获得延迟的奖励。

人工智能(AI)的最新工作使用强化学习算法,利用稀疏和零星的奖励对代理的行为进行建模。该领域的最新进展允许训练智能体在复杂的人工环境中执行,甚至在相同的背景下超越人类的能力[Mnih2013,-2016]。该领域一些令人兴奋的最新成果是在执行强化学习任务的同时学习语言——见这里

形式主义

为了学习在现实世界中表演,给定一系列状态 s 我们想要获得一系列动作 a,以最大化奖励或获胜概率。

基本需求(假设我们不知道游戏规则,只知道我们可以执行的一系列可能的操作):

  • 需要能够评估一个状态——我们是赢了,还是输了,离奖励有多远?
  • 需要能够从状态、行动 {s,a} 对预测结果——假设我们决定采取行动 a ,我们期望什么回报或结果?玩心理游戏
  • 需要记住一系列可以延续很长时间的配对

在棋盘游戏中,如国际象棋、围棋等,整个游戏是完全可观察的,而在现实世界中,如自动驾驶机器人汽车,只有一部分环境是可见的,这两种游戏有很大的不同。

完全可观测的

AlphaZero 的论文展示了一种完全可观察游戏的优雅方法。

alpha zero😗***

One (AZ1): a 函数 f (神经网络)基于参数θ输出动作概率 a 和动作值 v (对出招值的预测)。**

a,v = f(θ,s)

二(AZ2): 一个预测模型,可以评估不同走法和自我玩法(脑子里的玩法场景)的结果。AlphaZero 中的蒙特卡罗树搜索。这些游戏结果、移动概率 a 和值 v 然后被用于更新函数 f

这两种成分为学习玩这些桌上游戏提供了一种非常简单和优雅的方式,并且在相对较短的时间内在没有人类支持的情况下学习。

部分可观察的

但是非完全可观察博弈呢?比如第一人称射击游戏(Doom)?还是学习驾驶的自动驾驶汽车?

只有环境的一部分是可见的,因此预测行动的结果和下一个状态是一个困难得多的问题。

有太多可能的选项需要搜索。搜索树太大了。我们可以使用 AZ2,但我们需要聪明和快速地评估哪些选项,因为有太多的选项,而我们只有有限的时间来决定下一步的行动!

可能没有其他玩家可以与之竞争。这里的代理人必须与自己竞争,或者与自己的预测竞争,从其预见事件的能力或不预见事件的能力中获得中间报酬。

我们如何做到这一点?

建议

不幸的是,尽管近年来做出了努力,RL 算法仅在小的人工场景中工作,而没有扩展到更复杂或真实生活的环境中。原因是,目前这些系统的大部分参数都是基于过于稀疏的奖励,用耗时的强化学习来训练的。在现实世界的场景中,模型变得非常大(有许多参数),几乎不可能在短时间内进行训练。

我们需要的是能够训练一个模型大脑熟悉环境,并且能够预测行动和事件组合。有了这个预先训练好的模型大脑,用于实现特定目标的强化学习分类器,以及一小组可训练的参数,使用稀疏奖励来训练要容易得多。我们需要一个预先训练好的神经网络,至少可以处理视觉输入。它需要在视频序列上进行训练,并且需要能够提供输入的未来表示的预测。

为了超越这些限制,我们正在研究一种具有以下特征的合成模型大脑:

  • 活跃在环境中,能够感知和行动
  • 感觉序列、动作和奖励的记忆
  • 注意:只关注重要的数据
  • 预测:预测演员和环境的未来状态,这样我们就可以进行在线学习——通过预测,我们可以了解我们知道或不知道什么,并在我们需要学习时有一个“惊喜”信号(见这个这个)。预测也不需要监督信号,因为它们可以针对实际的未来事件及其结果进行误差测试。

关键是能够预测结果——函数 f (AZ1)需要有预测能力,换句话说,它需要有预见未来的能力。

A proposal for a neural network that can understand the world and act in it. This network uses video and can predict future representation based on a combination of the state s and its own associative memory. A multi-head attention can recall memories and combine them with state s to predict the best action to take.

在左边,你可以看到一个可以理解世界并在其中行动的神经网络的提案。该网络使用视频,并且可以基于状态 s 和它自己的关联存储器的组合来预测未来的表示。多头注意力可以回忆起记忆,并将它们与状态结合起来,以预测要采取的最佳行动。

该模型能够在多种条件下运行良好:

  • 持续学习:我们需要这个模型能够同时学习多项任务,并且学习时不会忘记,所以旧的任务不会被忘记
  • 一次性学习和迁移学习:我们需要这个模型能够从真实的和合成的例子中学习
  • 虚拟重放:该模型是可预测的,即使在事件被目睹后也能预测不同的结果。它可以在脑海中播放和回放可能的动作,并选择最好的一个。关联存储器充当搜索树。

我们如何训练这个合成大脑?

  • 大部分是无人监督的,或者自我监督的
  • 这里或那里几乎没有监督,但不能保证什么时候

但是设计和训练预测神经网络是人工智能领域当前的挑战。

我们在过去争论过一种的新型神经网络,它已经被证明在学习 RL 任务中更加有效。

我们还喜欢胶囊的预测能力,它不需要地面实况表示,但能够根据前一层预测下一层输出。

注 1: 这是一篇[的好文章](http://A great summary of DL work and success or lack thereof https://www.alexirpan.com/2018/02/14/rl-hard.html),讲述了为什么 RL 工作得好或者不好,以及与之相关的问题。我同意现在很多学习效率很低,也没有迁移学习的成功案例。这就是为什么我们应该推行预训练网络、课程学习和将任务分解成许多更简单的任务,每个任务都有简单的奖励的方法。如果你的搜索空间如此之大,一个解决所有问题的方法是很难的!

关于作者

我在硬件和软件方面都有将近 20 年的神经网络经验(一个罕见的组合)。在这里看关于我:传媒网页学者LinkedIn 等等…

从图像中学习艺术风格

原文:https://towardsdatascience.com/learning-artistic-styles-from-images-fa14c60890c1?source=collection_archive---------7-----------------------

Neural Style Transfer with my face and various other styles.

目前,科技领域正在进行一场军备竞赛,深度学习和人工智能已经成为下一个行业级术语。每个人都希望通过人工智能的成功和创新应用,取得下一个巨大的商业成功。

一个这样的突破是使用深度学习神经网络从数学上分离图像的内容和风格。很自然地,我们会想到将一幅图像的内容和另一幅图像的风格融合到一幅图像中。这个想法在 2015 年被 Gatys 成功实施。等人在他们的论文“一种艺术风格的神经算法”

从那以后,对基本思想有了许多见解和改进。该算法的现代迭代现在被称为神经风格转移,自 2015 年问世以来取得了很大进展。你可以在本文这里阅读更多关于改进的内容。

神经风格转移?

Image A provides the content. Image B is the final result, taking the semantic contents from Image A and the style from the smaller image.

转换风格背后的核心思想是拍摄两幅图像,比如一张人的照片和一幅画,并合成一幅同时匹配照片的语义内容 表示和相应艺术作品的风格表示的图像

如上所述——我们将对图像的风格和内容表示进行数学量化。使用一个空白的或者随机生成的图像(也称为模仿品),我们逐步地将它与期望的样式和内容表示相匹配。

深度学习脱颖而出!

那么深度学习到底是如何在这里发挥作用的呢?能够将风格和内容从图像中分离出来是怎么回事——这是人们有时很难辨别的。

显然,用于深度学习的神经网络真的很擅长提出图像特征的高级和低级表示。为了形象化,让我们看看 CNN 的图片。

Style and content representations taken at each layer of a Neural Network.

研究网络每一层的要素表示,您会发现每一层都会逐渐产生一个抽象概念,即样式(顶部一行图像)和语义内容(底部一行图像)。

在卷积神经网络(CNN)中,每一层都用来进一步抽象我们提供给它的图像的像素表示。最初,我们将向 CNN 提供一幅图像。但是 CNN 并不像我们人类那样将这张图像视为图像,而是将图像视为值的矩阵(更准确地说是张量)。

A matrix representation of the image of the letter a. Pixel values closer to 1 correspond to colors closer to black white values closer to 0 correspond to a lighter hue. Image taken from http://pippin.gimp.org/image_processing/chap_dir.html

在每一层,将内核应用于图像的一个小块,在整个图像上移动,最终生成图像的中间矢量表示。虽然这些生成的向量可能实际上没有任何意义,但它们允许我们捕捉图像的特征。你可以看看这篇文章,深入了解 CNN 是如何做到这一点的。

自然,这些图像绝不是风格和内容的确切定义,但这是神经网络如何感知它的。

定义内容和风格

现在我们已经大致了解了图像的抽象特征在哪里(图层之间的矢量表示)。但是我们如何让他们离开 CNN 呢?

这就是我们前面提到的论文的关键贡献发挥作用的地方。

该论文的工作基于一个流行且强大的架构(当时),被称为 VGG ,它赢得了 2014 年 ImageNet 分类挑战赛。

Layers of the VGG19 neural network, taken from https://ethereon.github.io/netscope/#/gist/3785162f95cd2d5fee77

在这种架构中,特别是在“conv4_2”层的中间向量最好地代表了图像的语义内容。而 style 最好由以下层的特征组合来表示:“conv1_1”、“conv2_1”、“conv3_1”、“conv4_1”和“conv5_1”。你会问,我们是如何选择特定的层的?真的只是试错。

Image taken from A Neural Algorithm for Artistic Style. The image structures captured by the style representations increase in size and complexity when including style features from higher layers of the network. This can be explained by the increasing receptive field sizes and feature complexity along the network’s processing hierarchy.

这个想法是,你在神经网络中的位置越低(越接近对物体进行分类),特征向量就越能代表图像的语义内容。而网络中的高层能够更好地捕捉图像的风格。

秘密成分

既然我们已经弄清楚了样式和内容表示,我们需要一种方法来迭代地匹配随机生成的白噪声图像(我们的仿作)和表示。

A randomly generated white noise image, which we will iteratively match to the style and content representations.

为了可视化在层级的不同层编码的图像信息,我们在白噪声图像上执行梯度下降,以找到与原始图像的特征响应相匹配的另一个图像。

因此,我们定义了内容表示和我们的仿作之间的平方误差损失:

The content loss

其中向量 P 是原始图像,向量 x 是生成的图像,并且 P_lF_l 在层 l 中它们各自的特征表示。

由此可以使用标准误差反向传播来计算生成图像的梯度 w.r.t.。因此,我们可以逐步更新随机白噪声图像,直到它在“conv4_2”层中给出与我们想要从中获取语义内容的图像相同的响应。

输入克矩阵

然而,风格并不直截了当。我们首先构建一个样式表示
,它计算不同滤波器响应之间的相关性。这是通过克矩阵完成的:

其中 G^l_ij 是层 l 中矢量化特征 ij 的内积。关于为什么 Gram 矩阵可以捕捉样式信息的更多信息可以在本文中找到。

通过最小化来自原始图像的 Gram 矩阵和要生成的图像的 Gram 矩阵的条目之间的均方距离,我们可以使用来自白噪声图像的梯度下降来找到与原始图像的风格表示相匹配的另一个图像。

风格的损失定义为:

其中 E_l 为:

GA 分别是 l 层中原始图像和生成图像的风格的 Gram 矩阵表示。然后,可以使用类似于上述内容表示的标准误差反向传播来计算梯度。

把它们放在一起

现在,我们已经拥有了生成图像所需的所有要素,给定了一个我们想要从中学习风格的图像和一个我们想要从中学习内容的图像。

为了生成将照片的内容与绘画风格混合的图像,我们共同最小化白噪声图像与网络的一层中的照片的内容表示和 CNN 的多层中的绘画风格表示的距离。

我们最小化以下损失函数:

其中αβ是用于在新图像的构建期间确定总体贡献的权重。

如果呢?

尽管这篇文章是在 2018 年写的,但所描述的技术并不新,而且已经存在多年了。

事实上,已经对现有模型进行了大量的改进和修改,极大地提升了它的许多方面的性能,例如提高风格转换的速度减少损失以生成更好的图像制作艺术(这是由论文的原作者制作的)等等。

最让我感兴趣的是,我曾经认为抽象和不可量化的东西——即图像的抽象风格和内容——现在可以用数学来表示。自然,这使人想知道同样的事情是否可以用于其他抽象的品质。不仅仅是图像,而是所有形式的媒介,无论是视频还是文本。

如果情感、动机和情节等抽象概念也可以量化,那会怎样?那我们该拿这些做什么?我们生活在令人兴奋的时代,我迫不及待地想看看更多的技术和人工智能能给我们的文化带来什么。

觉得这个有用?请随意击碎拍手,并检查我的其他作品。😄

李中清是 培育的人工智能研究员。AI 。他最近从莫纳什大学计算机科学专业毕业,撰写了关于人工智能和深度学习的文章。在 Twitter 上关注他@jamsawamsa

向杰弗里·辛顿学习反向传播

原文:https://towardsdatascience.com/learning-backpropagation-from-geoffrey-hinton-619027613f0?source=collection_archive---------6-----------------------

Image from this website

机器学习掌握的所有路径都要经过反向传播。

自从开始我的机器学习之旅以来,我最近第一次发现自己被难住了。我一直在稳步完成吴恩达广受欢迎的 ML 课程。

线性回归。检查。逻辑回归。检查。梯度下降。检查检查检查。

然后我们到了神经网络和用来训练它们的算法:反向传播。尽管安德鲁尽了最大努力,我还是不明白这项技术是如何工作的。尽管 Andrew 向我们保证这没什么,你可以在没有更深入理解的情况下使用神经网络,而且他自己也这样做了很多年,但我决心更好地理解这个概念。

为了做到这一点,我求助于大师 Geoffrey Hinton 和他合著的 1986 年《自然》论文,其中首次提出了反向传播(几乎 15000 次引用!).我会鼓励每个人读报纸。它很短,只有 4 页,在详细研究之后,我对反向传播有了更好的理解,现在我将试着传授给大家。

本质上,反向传播只是链式法则的巧妙应用。

链式法则是任何本科课程中教授的导数的一个基本性质。它指出,如果你有 3 个函数 fgh ,其中 fg 的函数,而 gh 的函数,那么 f 关于 h 的导数等于 f 关于的导数的乘积

The chain rule

现在让我们用这个来弄清楚反向传播是如何工作的。

假设我们正在使用下面的简单神经网络。这个网络有三层:蓝色的输入层,绿色的隐藏层和红色的输出层。前一层中的每个单元都连接到下一层中的每个单元。每个连接都有一个权重,每当一个单元向另一个单元发送信息时,该信息就会乘以该连接的权重。一个单元从上一层获得与其连接的所有输入的总和,对该总和执行逻辑函数,并将该值向前传递。

A 3–4–3 Neural Network

让我们想象我们被给予了 m 个训练的例子:

i-th input output pair

其中 xy 为三维向量, i 为第 I 个训练样本。对于输入 x ,我们将我们的神经网络的预测/输出称为 g ,它也是一个三维向量,每个向量元素对应一个输出单元。因此,对于每个培训示例,我们都有:

Vector form of training Input, output and neural network prediction

给定输入 x ,我们希望找到导致 g 等于(或至少非常相似)y 的权重值。

为此,我们将使用一个误差函数,我们定义为:

Total error for the Neural Network above

为了计算总误差,我们采用训练集中的每个案例 i ,并针对红色输出层中的每个单元,计算该单元的预测和真实输出之间的平方误差。如果我们对每种情况都这样做,我们将得到总误差。

由于网络预测的值 g 依赖于网络的权重,我们可以看到误差会随着权重的变化而变化,我们希望找到使 E 最小的权重。

我们可以使用梯度下降来实现。但是梯度下降要求我们找到 E 相对于每个权重的导数。这就是反向传播让我们实现的目标。

我们现在将考虑单一情况,而不是 3 个输出单元,假设我们有任意数量的输出单元 n 。对于这种情况,我们的错误现在变成了:

Error for a single case

为了方便起见,我们去掉了下标,因为它是常数。

我们现在可以问自己,当一个输出单位的预测变化时,这个误差是如何变化的。这是简单的导数:

The derivative of the total error with respect to each output unit (Note that we used the chain rule to the derivative of the squared term.)

有趣的是,似乎随着一个输出单位的预测值的变化,误差将以等于预测值和真实值之间的“误差”或差异的速率变化。酷!

现在,我们可能会问自己,当这些输出单元的总输入发生变化时,误差会如何变化。同样,这只是一个导数。让我们用 z 来表示一个输出单元的总输入。那么我们有兴趣发现:

Derivative of E with respect to the total input for output unit j

但是由于 gz 的函数,通过应用链式法则,我们可以将其重写为:

Applying the chain rule!!

还记得我们说过,每个单元在传递输入之前,都将逻辑函数应用于它的输入。这意味着 g 是一个逻辑函数, z 是它的输入,所以我们可以写:

Logistic function and it’s derivative

所以现在我们可以说:

The derivative of the total error with respect to the total input to an output unit

我们已经计算出,当一个输出单元的总输入发生变化时,误差是如何变化的。太神奇了!

我们现在可以找到误差对某些重量的导数。这就是我们梯度下降所需要的。

让我们将绿色单元的预测/输出称为g’,并且我们将绿色层中的单元 k 和红色/输出层中的单元 j 之间的连接的权重称为:

Weight of connection between unit k in green and unit j in red layers

考虑下面黄色输出单元的总输入 z 。我们可以通过计算每个绿色单元的输出,乘以连接绿色单元和黄色单元的红色箭头的重量,然后将它们相加来计算输入。

The red arrows represent the connections that are added up to get the total input of the yellow unit

而不是 4,如果我们有任意数量的绿色单元 n (这个 n 与我们之前定义的不同)我们就可以说:

Total input to output j

因此,我们似乎可以将 z 写成连接到它的重量的函数和连接到它的单元的输出的函数。

链式法则的时间到了。

我们自问,当连接到输出单元的砝码发生变化时,误差会如何变化。这可以写成:

The derivative of the total error with respect to weights connecting to an output unit

我们刚刚算出了误差相对于连接到输出层的权重的导数。这正是我们需要让梯度下降工作。

但是我们还没完。我们仍然需要计算出误差相对于连接第一层和第二层的权重的导数。

谢天谢地,链式法则也还没有完成。

我们计算当第 k 个绿色单元的输出变化时,误差如何变化:

The derivative of error with respect to the output of unit k in the green layer

由于有来自单位 kj 重量,我们认为:

The derivative of total error with respect to the output of unit k in the green layer

如果你仔细想想,我们又回到了起点。我们得到了误差对某个单位输出的导数。我们现在可以完全忽略红色输出层,将绿色层视为网络的最后一层,并重复上述所有步骤来计算 E 相对于传入权重的导数。

Image from this website

你会注意到我们计算的一阶导数等于预测值和真实输出值之间的“误差”。同样,最后一个导数也有这个误差项,乘以一些其他的项。该算法被称为反向传播,因为这种误差的一种形式从最后一层反向传播到第一层,并用于计算 E 相对于网络中每个权重的导数。

一旦计算出这些导数,我们就可以在梯度下降中使用它们来最小化 E 并训练我们的神经网络。

希望这篇文章能让你更好地理解反向传播是如何工作的。如果你有任何问题,请告诉我,我会尽力回答你。谢谢!

学习计算机视觉

原文:https://towardsdatascience.com/learning-computer-vision-41398ad9941f?source=collection_archive---------5-----------------------

最近我读了很多关于计算机视觉的书并做了很多实验,这里介绍了在这个领域中学习和使用什么是有趣的。

Image segmentation for autonomous driving

近年来,计算机视觉取得了很大进步。这些是我将在此提及的主题:

技术:

  • 人脸检测:Haar,HOG,MTCNN,Mobilenet
  • 人脸识别:CNN,Facenet
  • 物体识别:alexnet,inceptionnet,resnet
  • 迁移学习:在一个新的主题上用很少的资源重新训练大的神经网络
  • 图像分割:rcnn
  • 开始
  • 计算机视觉硬件:选什么,GPU 重要
  • 集成视觉的 UI 应用程序:ownphotos

应用:

  • 个人照片组织
  • 自动驾驶汽车
  • 自主无人机
  • 求解验证码/ OCR
  • 为基于图片的网站/应用程序过滤图片
  • 为应用程序自动标记图片
  • 从视频(电视节目、电影)中提取信息
  • 视觉问答
  • 艺术

关注的人:

课程:

  • 深度学习@ coursera
  • 机器学习@ coursera

相关字段:

  • 深度强化学习:参见以 cnn 为输入层的 ppo 和 dqn
  • 与 nlp 的互动:lstm 2 cnn

人脸检测

Face detection is about placing boxes around faces

人脸检测就是检测人脸的任务。有几种算法可以做到这一点。

https://github.com/nodefluxio/face-detector-benchmark】提供了这些方法的速度基准,并带有易于重用的实现代码。

哈尔分类器

haar features

它们是自 2000 年以来出现在 opencv 中的旧的计算机视觉方法。本文介绍了http://wearables . cc . gatech . edu/paper _ of _ week/viola 01 rapid . pdf

它是一个机器学习模型,具有专门为对象检测选择的特征。Haar 分类器速度快,但准确率低。

https://docs . opencv . org/3 . 4 . 3/D7/d8b/tutorial _ py _ face _ detection . html中查看更长的解释和如何使用它的示例

HOG:方向梯度直方图

Histogram of oriented gradients

HOG 是一种较新的生成目标检测特征的方法:从 2005 年开始使用。它是基于计算图像像素的梯度。这些特征然后被馈送到机器学习算法,例如 SVM。它比 haar 分类器有更好的精度。

它的一个实现在 dlib 中。它在人脸识别(https://github.com/ageitgey/face_recognition)库中。

MTCNN

一种利用细胞神经网络变异检测图像的新方法。精度更高,但速度稍慢。参见https://KP Zhang 93 . github . io/mt CNN _ face _ detection _ alignment/index . html

MobileNet

目前最好最快的人脸检测方法。基于通用移动网络架构。参见 https://arxiv.org/abs/1704.04861

目标检测

Object detection on many kind of objects

可以使用类似于面部检测的方法来实现对象检测。

这里有两篇文章介绍了实现这一目标的最新方法。这些方法有时甚至还提供对象的类别(实现对象识别) :

卷积神经网络

深度学习的最新进展已经看到新的架构取得了很大的成功。

使用许多卷积层的神经网络就是其中之一。卷积层利用图像的 2D 结构在神经网络的下一层中生成有用的信息。关于什么是卷积的详细解释,请参见https://towards data science . com/intuitive-understanding-convolutions-for-deep-learning-1 F6 f 42 faee 1

A convolution layer

物体识别

物体识别是将物体分类的一般问题(如猫、狗等)

基于卷积深度神经网络已经被用于在这个任务上获得很好的结果。

ILSVR 大会已经在 ImageNet(http://www.image-net.org/上举办了比赛,ImageNet 是一个数据库,里面有许多带有诸如猫、狗、..)

越成功的神经网络已经使用越来越多的层。

ResNet 架构是迄今为止最好的对象分类架构。

Resnet architecture

要对它进行适当的训练,需要使用数百万张图像,即使使用几十块昂贵的 GPU 也要花费大量时间。

这就是为什么在如此大的数据集上不需要每次都重新训练的方法非常有用的原因。迁移学习和嵌入就是这样的方法。

resnet 的预训练模型在https://github . com/tensor flow/tensor 2 tensor # image-class ification中提供

人脸识别

人脸识别就是要弄清楚谁是 T2,谁是 T3。

历史方法

解决该任务的传统方法是应用标准机器学习(例如 svm)的特征工程,或者应用深度学习方法进行对象识别。

这些方法的问题是它们需要每个人的大量数据。实际上,这些数据并不总是可用的。

Facenet

谷歌研究人员于 2015 年在 https://arxiv.org/abs/1503.03832推出了 Facenet。提出了一种不需要为每个人准备大量人脸样本的人脸识别方法。

它的工作方式是通过拍摄大量人脸的照片数据集(比如 http://vis-www.cs.umass.edu/lfw/的照片)。

然后采用现有的计算机视觉架构,如 inception(或 resnet ),然后用计算人脸嵌入的层来替换对象识别 NN 的最后一层。

对于数据集中的每个人,(阴性样本、阳性样本、第二个阳性样本)选择(使用试探法)三个一组的面部,并馈送给神经网络。这产生了 3 个嵌入。在这 3 个嵌入中,计算三元组损失,这最小化正样本和任何其它正样本之间的距离,并且最大化位置样本和任何其它负样本之间的距离。

Triplet loss

最终结果是,每个人脸(甚至是不存在于原始训练集中的人脸)现在都可以被表示为一个嵌入(128 个数的向量),它与其他人的人脸的嵌入有很大的距离。

然后,这些嵌入可以用于任何机器学习模型(即使是像 knn 这样简单的模型)来识别人。

关于 facenet 和 face embeddings 非常有趣的一点是,使用它,你可以只通过一些人的照片,甚至是一张照片来识别他们。

查看实现它的库:https://github.com/ageitgey/face_recognition

这是它的张量流实现:https://github.com/davidsandberg/facenet

这是人脸识别管道背后的想法的一个很酷的应用,而不是识别熊的脸:https://hypractive . github . io/2017/01/21/face net-for-bears . html

迁移学习

Retrain quickly an accurate neural network on a custom dataset

训练像 resnet 这样的非常深度的神经网络是非常耗费资源的,需要大量的数据。

计算机视觉是高度计算密集型的(在多个 gpu 上进行数周的训练),需要大量数据。为了解决这个问题,我们已经讨论过计算人脸的一般嵌入。另一种方法是利用现有网络,在另一个数据集上只重新训练它的几个 it 层。

下面是它的教程: codelab 教程。它建议你重新训练一个初始模型来训练未知的花类。

https://medium . com/@ 14 Prakash/transfer-learning-using-keras-d 804 b 2e 04 ef 8提出了在进行迁移学习时,应该重新训练哪一层的良好指南。

图象分割法

Image segmentation for autonomous driving

图像分割是一个令人印象深刻的新任务,近年来已经成为可能。它包括识别图像的每个像素。

该任务与目标检测相关。实现它的一种算法是 mask r-cnn,更多详情参见本文https://medium . com/@ Jonathan _ hui/image-segmentation-with-mask-r-CNN-ebe6d 793272

开始

Large scale GAN

由 ian goodfellow 介绍的生成式广告网络是一个由两部分组成的神经网络体系结构:一个鉴别器和一个生成器。

  • 鉴别器检测一张图片是否是一个类,它通常已经在一个对象分类数据集上进行过预训练。
  • 生成器为给定的类生成图像

生成器的权重在学习期间被调整,以便产生鉴别器不能从该类的真实图像中区分的图像。

这是迄今为止最大的氮化镓制作的图像的例子https://arxiv.org/abs/1809.11096

参见https://github.com/eriklindernoren/Keras-GAN的 keras 中 GAN 的实现

计算机视觉硬件

训练大模型,需要大量的资源。有两种方法可以实现这一点。首先是使用云服务,比如 google cloud 或者 aws。第二种方式是自己搭建一台带 GPU 的电脑。

只要 1000 美元,就有可能建造一台像样的机器来训练深度学习模型。

https://hypractive . github . io/2017/02/13/dl-computer-build . html中阅读更多详细信息

UI 中的视觉

Face dashboard of ownphotos

Ownphotos 是一个令人惊叹的用户界面,允许你导入照片,自动计算人脸嵌入,进行物体识别和人脸识别。

它使用:

应用程序

Visual question answering

计算机视觉有许多应用:

  • 个人照片组织
  • 自动驾驶汽车
  • 自主无人机
  • 求解验证码/ OCR
  • 为基于图片的网站/应用程序过滤图片
  • 为应用程序自动标记图片
  • 从视频(电视节目、电影)中提取信息
  • 视觉问答:结合自然语言处理和计算机视觉
  • 艺术:甘

结论

正如我们在这里看到的,有许多新的有趣的方法和应用的成功。

我认为人工智能中最有趣的是学习可以重复使用的算法,能够将这些方法应用到越来越多的任务中,而不需要太多的处理能力和数据:

  • 迁移学习:它使得重新利用预先训练好的大型神经网络成为可能
  • 嵌入(例如 facenet):无需对这些类进行训练就可以识别许多类

在通用数据集上学习数据科学是没有用的

原文:https://towardsdatascience.com/learning-data-science-on-generic-datasets-is-useless-163e9015041c?source=collection_archive---------26-----------------------

好吧,这绝对不是没用的。但它的用处远远超过了实际需要。本文将概述数据在学习数据科学中扮演的一些潜在角色,并反对使用通用(以及静态数据集)数据集。我们经常看到在可用的通用数据集上教授机器学习主题,如 mtcarsiris 。让我澄清一下,我们使用这些数据集是因为它们经过了惊人的清理、准备和强健,可以用来教授数据科学中的各种概念。不是每个人都有大量的数据…或者他们有吗?或许现在时机已经成熟,可以自动管理学习者自己的网上数据,帮助他们回答关于自己的问题,同时学习数据科学。随着我们继续发展数据科学教育,我建议我们转向使用可变和个人数据集进行学习。我的目标是将数据科学教育转变为一项技能培养活动,而不是自我探索和发现活动。其中一个想法围绕着使用已经可用的相关数据(你自己的!),另一个更深层次的观点直指数据甚至在学习过程中扮演的角色。本文将探讨一下为什么数据很重要

我们学数据科学不是无缘无故的。

最近我一直在纠结为什么我们应该学习数据科学。有时,冲进资本主义的监狱似乎是一种耸人听闻的恐慌。"T16 要是你有数据科学技能就好了!"“这架飞机上有机器学习的博士吗?!"这肯定是另一篇博文,但现在我将继续宣扬学习数据科学是自我发现的一种形式,如果培养得当,可以带来巨大的快乐。所以,让我们假设你正在学习成为一名数据科学家,不管是出于什么原因。当您真正处理数据时:

  • 你通常有一个实际的问题要解决,甚至可能有一个特定的结果。
  • 您将数据与您所拥有领域知识联系起来;无论是体育、医药、利润、游戏等等。
  • 你对正在处理的数据有预测和直觉。有时候这可以让你指出自己犯的错误(心率 9000?那不可能是对的!)。其他时候,你被你的直觉所迷惑,试图寻找根本不存在的意义。

处理数据的所有这些方面都与您拥有的数据密切相关。某些问题需要某些测试,这些测试需要某些数据配置。这些数据与你对自己领域的了解密切相关,通常用于支持对该领域真理的追求。你的直觉很重要!每次我们将经验 转化为数据,我们都在做决策。 我一直在用下面的例子来说明这一点:在测量美国的平均身高时,我们会把婴儿包括在内吗?我们如何定义我们处理的数据很重要,对使用什么数据有某种直觉也很重要。我不知道你,但是我对植物学和萼片长度完全没有直觉。

算法是一个过程,数据改变了这个过程。

  • 理解机器学习算法的部分核心是理解数据驱动的过程。这意味着您的流程与输入到系统中的数据密切相关。我并不是说算法会根据它拥有的数据从根本上改变它的步骤,而是说这个过程对于每个数据场景(算法在其中移动的空间)来说看起来是不同的。
  • 观察数据量很少或非常多的模型会发生什么,可以让您了解算法实际上是如何工作的。想想下面这个例子:你得知一只狗的名字是 Sparky,但却意外地假设这只狗的名字实际上是 Barky(一个错误,但是一个聪明的错误)。有一次你听到有人叫这只狗“斯巴基”,也许会认为他们搞错了,因为这只狗的名字真的叫巴克利。现在想象一下,你听到每个人都称这只狗为“Sparky”超过 1000 次。也许是你认识到自己错误的时候了!这是一个数据量如何改变结果甚至过程的例子。算法也是如此。能够处理我们看到的大量数据对于学习算法如何运行非常重要。
  • 如果我们的数据没有边缘情况,我们如何考虑它们?我们拥有的数据允许我们对涉及的算法的某些部分进行推理。如果您的数据不需要担心局部最小值,那么了解全局最小值可能就没有什么启发性了。我们掌握的数据实际上决定了我们可以探索的案例。我并不是说我们可以自动筛选出包含完美边缘案例的完美数据集,也可能是当前通用数据集包含边缘案例的情况。但我要说的是,这是我们必须承认的数据所扮演的重要角色。

您选择的数据和模型是一种委托关系。

数据不仅改变了算法过程,还决定了适合使用哪种算法。这并不是说你应该仅仅因为数据允许就使用一种算法。但是需要注意的是,数据的作用是限制你实际使用的算法。用于教授某些概念的通用数据集当然有合适的数据来解决手头的问题,但如果您的问题发生了变化(在处理真实数据时经常发生这种情况),该怎么办呢?我们能让我们的数据集自动适应我们提出的问题吗?除了拥有关于数据本身的领域知识,我建议我们需要更多自动适应的数据集,帮助我们学习帮助我们回答问题的概念。我知道,有点拗口。我们选择的数据和模型有着深厚的关系,这种关系不是一刀切的。我们用来学习数据科学的数据需要像数据和我们选择的模型之间的关系一样具有适应性、错综复杂、杂乱和微妙。

学习数据科学—第 1 部分:MOOC、Youtube、Ted

原文:https://towardsdatascience.com/learning-data-science-part-1-mooc-youtube-ted-20617dbb7f4b?source=collection_archive---------5-----------------------

Photo by Clint Patterson on Unsplash

我最近开始学习数据科学,大约两个月前。我没有统计学、数学、数据科学、工程学、经济学或任何类似的学位。说实话,学生时代数学和统计学不是我的强项。我更擅长语言。说有些人语言能力强于数学能力可能是一个神话,反之亦然,但这就是我的感受。

我在文学院学的是管理,在文学院学的是策展。我写了我的论文,但它更侧重于文献综述,而不是应用定量研究方法。我在时尚界做过跟单员和采购员。所以在我的整个教育和经历中,我对数学和统计并不是那么了解。

那我为什么还要学习数据科学呢?我对“从数据中获得洞察力”的概念很感兴趣。如此感兴趣,以至于我甚至决定克服我对数学和统计的长期恐惧。考虑到我们仅用两天(到目前为止甚至可能需要 10 分钟)就创建了与 2003 年相同数量的数据,而只有 1%的数据被分析,这个领域充满了各种可能性。“我需要成为它的一部分”,这就是我当时的想法,并且仍然相信它。

MOOC (Coursera 课程)

Coursera founders Andrew Ng and Daphne Koller

微积分一(我在数学课上没怎么注意,我确实需要复习。)
基础统计学(我听说过一两次,但不能说我什么都知道)
机器学习(这是吴恩达的著名课程,但在第 6 周左右,我意识到我真的需要更多关于编程、数学、统计的基础知识,所以我把它搁置了)
Python 适合所有人(这是一个强烈推荐的专业(5 门课程),如果你和我一样,来自非技术背景

Youtube 频道

有不同的类别,你可能会发现有用的。

第一种是“教程”型。
机器学习

  • Siraj Raval (众说纷纭,但我仍然认为这是一道不错的开胃菜)
  • Harrison Kinsley (也可能是褒贬不一)
    总的来说,它们对于起步来说是不错的,但我觉得这类 Youtube 教程可能在他们如何解决问题、如何处理问题上有点偏见。
  • 韦尔奇实验室(他们有很好的教程关于“学习看”、“神经网络揭秘”。教程是针对初学者的,所以我发现这些视频对掌握概念的基本原理非常有帮助。即使他们没有很多可用的视频,也绝对值得一去)

统计

数学

  • mathbff (当你遇到不熟悉的数学术语,或者记不住的数学规则时,这是一个很好的来源。三角测量法、导数、链式法则等..)

I find her videos strangely therapeutic

巨蟒巨蟒
巨蟒查克为大家遣散巨蟒

第二种是“会议”型。对于初学者来说,有些材料可能不容易消化,但看看即将出现的东西、最近的发展以及数据科学中的主题也无妨。

第三个是数据科学学校/训练营自己的 Youtube 频道

最后是 Ted 演讲。我太喜欢 Ted 演讲了。所以我把它和普通的会议类型分开。
各种主题的伟大演讲者,我总能发现新的东西,认识到我不知道的东西,受到鼓舞,受到激励,这让我想成为一个更好的人。它可能不会教你如何构建一个算法,但它可以告诉你为什么和为了什么。
顺便说一下,Ted Talks 有两个不同的名字。“TED Talks”和“Tedx Talks”。我谷歌了一下才知道区别。

Ted’s programs and initiatives

TED 和 TEDx 活动的不同之处在于,前者更多地采用全球化的方式,而后者通常专注于关注本地声音的本地社区。“官方上,TEDx 中的‘x’代表独立组织的 TED 活动——但它更多的是一个 TED 倍增。是这股力量带着 TED 穿越了这个星球,播种了所有这些社区。

如果你在 Youtube 上搜索“ted”,你会得到的第一个条目是“TED Talks”Youtube 页面。 https://www.youtube.com/user/TEDtalksDirector
拥有 790 万订阅用户,2488 个视频(01/10/2017)
在搜索结果的第 17 个条目上,有“TEDx Talks”页面。
https://www.youtube.com/user/TEDxTalks
拥有 890 万用户和 99031 个视频(2017 年 1 月 10 日)

无论如何,下面是一些我非常喜欢的演讲。

我计划更新这个列表,因为我找到了更多有用的资源。我希望它能对任何一个和我处境相似的人有所帮助。对于第 2 部分,我将列出播客和博客作为学习数据科学的来源。

学习数据科学—第 2 部分:播客、博客

原文:https://towardsdatascience.com/learning-data-science-part-2-podcasts-blogs-8bed327eb1b5?source=collection_archive---------7-----------------------

Photo by fabio on Unsplash

这是“学习数据科学”的第二部分,是我在尝试沉浸于数据科学时收集的链接和资源。我开始这样做是为了跟踪所有我觉得有用的学习资源,但如果它也能对任何人有所帮助,那就是“一举两得”。在第一部分“学习数据科学——第一部分:MOOC、Youtube、Ted ”中,我列出了大部分视频资源。尽管视觉辅助工具在学习时很有帮助,但我想有效地利用我的通勤时间,我经常在地铁里收不到信号,或者流式视频对我的移动数据使用来说有点太重。

播客

partial Derivative 的 Chris Albon 在 Metis 举办的现场演讲中总结了听播客如何帮助你,“揭开数据科学的神秘面纱”(现场演讲于 2017 年 9 月 27 日举行,但你仍然可以通过在他们的网站上注册来获得录音。我不确定是否会有录音,所以我在英国时间下午 3 点到凌晨 3 点看了 12 个小时的演讲…)。播客是关于“让你的大脑一遍又一遍地听到这些术语”。当然,30 分钟的播客不会让你成为专家,但你会听到实际的数据科学家如何谈论一个主题,他们如何将其应用于实际问题。在播客的一集之后,你会比以前更好地了解这个话题。

  • 数据怀疑论者(特别喜欢迷你剧集,主持人 Kyle Polich 向联合主持人 Linh Da 非常直观地解释了各种数据科学概念,没有数学或计算)
  • 偏导数(很难过看到 2017 年 9 月 5 日最后一集之后就停了。听着听着,我感觉就像在听数据科学家们在酒吧里就该领域最近的话题聊天。我在非常有趣和轻松的方式中学习如何在各种情况下应用特定的 ML 算法,有什么限制。再次,悲伤地看到它停止了)

The hosts of Partially Derivative: from left, Jonathon Morgan, Vidya Spandana, Chris Albon

  • 线性题外话(两位主持人之间的对话,凯蒂·马龙是数据科学家,本·贾菲是 UI 工程师。很好地结合了对数据科学的不同观点,如果您是精通技术的数据科学家新手,即使没有某个主题的专业知识,您也可以关注他们的谈话)
  • 学习机器 101 (这是一个非常有教育意义的播客,专注于机器学习,如果你感兴趣,我建议你从第一集开始听,因为它建立了你对该领域历史发展和理论的基本理解)
  • 统计+故事(这更像是一个统计和新闻播客。考虑到许多数据科学概念来自统计学,学习如何像统计学家一样思考是非常有用的)
  • 或多或少 (BBC 关于我们身边的数字和统计的播客。同样,我不是专门研究数据科学的,但看到统计数据和我们日常生活之间的联系非常有帮助。凭借一点自己的创造力,您可能会为您的数据科学项目找到一个好主题)

博客

有这么多好的博客,要跟上你感兴趣的每一个博客并不容易。这就是 RSS feeder 派上用场的地方。我最近发现了 Feedly ,它让我不用翻找书签,也不用查看是否有博客更新。您只需复制并粘贴博客地址,然后点击“关注”。然后你可以去 Feedly 查看你关注的所有博客的更新。(我是免费会员,我可以添加的来源仅限于 100 个)

出版商的博客

the O’Reilly tarsier

组织的博客

  • 脸书研究博客(他们有关于数据科学的博客,你可以访问各种主题的研究论文;自然语言处理,计算机视觉等。)
  • AWS AI 博客(作为新手,我还没机会用 AWS 跑模型。供我个人以后参考)
  • Tableau 博客(还是那句话,我没用过 Tableau,但是很感兴趣)
  • 彭博——图形(数据可视化非常酷的经济新闻故事。有时他们会分享方法,并展示他们是如何得出这些指标的)
  • GDS 博客(英国政府数字服务的数据博客)的数据。了解政府如何组织和使用数据的良好来源)

数据社区/门户

  • fivethirtyeeight(美国著名统计学家内特·西尔弗的网站。擅长政治和体育。有时他们在 Github 页面中有用于分析的数据集。)

Fiverthirtyeight styled graph is very famous, there’s even a style sheet replicating this style in Matplotlib

  • 分析 Vidhya (专注于数据科学的业务分析方面。可以找到教程、技巧和窍门。关于各种数据科学应用的分步教程非常有用)
  • 数据经济(本网站更关注数据科学的总体环境,将数据放在上下文中,而不是特定主题的教程)
  • KDnuggets (著名的数据门户网站,涵盖广泛的话题。新闻、教程等)
  • Dataquest 博客(这来自一个在线数据科学课程。擅长教程类型的文章。)

个人

  • Jer Thorp: blprnt.blg (数据艺术家,我在之前的帖子里已经介绍过了。最先进的数据可视化)

A map of hotels in Western Europe, showing the density in capital cities like Paris, London, Madrid and Rome (Image courtesy Jer Thorp; flickr.com/photos/blprnt/)

  • 数据科学 101 (“揭开数据科学的神秘面纱”的演讲者之一,Ryan Swanstrom。关于如何学习数据科学的良好资源)
  • 兰德尔·s·奥尔森博士(我第一次知道他是在他写的一篇 538 年的文章中。在他的个人博客中,他分享了数据科学的思维过程,以及他如何将数据科学应用于现实生活中的问题)

个人兴趣(时尚和零售领域的数据科学)

我很快就要在伦敦大会上开始一个新兵训练营课程,我想我会很忙来跟上所有的课程工作和项目,但如果可能的话,我会试着分享我的学习之旅。

学习奖励分配导致 RL 的艺术状态

原文:https://towardsdatascience.com/learning-distributions-over-rewards-leads-to-state-of-the-art-in-rl-5afbf70672e?source=collection_archive---------11-----------------------

最近在 DeepMind 中完成的工作“强化学习的分布式视角”展示了许多 Atari 游戏中具有特殊技巧的最新成果。他们训练了一个神经网络来提供可能的奖励分布,而不是单一的价值。

基本上这是一个很好的老深度 Q 网络。但是,它并没有逼近预期的未来回报值,而是生成了可能结果的整体分布。这种变化背后的主要动机是分布可能有几个峰值。仅仅将它们平均为一个期望值可能是不合适的,并导致不充分的结果。

他们用代表不同奖励值范围的分类变量的概率代替了 DQN 的输出。他们测试了不同数量的区间,分割了可能的值范围:5、11、21、51 和 51 个区间的表现远远优于其他区间。超出此范围的值被剪切到最后一个容器中。对学习算法进行了第二次修改,以处理分布贝尔曼方程。

与普通 DQN 相比,TensorFlow 实施所需的计算时间增加了约 25 %,但只需要一小部分训练步骤就可以实现卓越的性能。与 DQN 相比,在没有其他现代 RL 技术的情况下,这种方法几乎将具有超人性能的游戏数量增加了一倍:

您可以在原始论文中找到所有的数学和实现细节。虽然研究人员使用 DQN 作为基础,但更先进的模型可能会提供更好的性能。

它看起来像什么

行动中:

最初发表于 认知混乱

学习工程:融合科学和数据设计强大的学习体验

原文:https://towardsdatascience.com/learning-engineering-merging-science-and-data-to-design-powerful-learning-experiences-e3c5ddb477f5?source=collection_archive---------20-----------------------

学习是一个有机的过程,在这个过程中,知识的种子被缓慢而稳定地植入并铭刻在头脑中。这种知识的种子最终会在付诸行动时结出果实。正如本杰明·富兰克林所说:“告诉我,我会忘记;教我,我会记住;让我参与,我会学到。”。

工程包括应用实用的、科学的、经济的和社会的知识,这将有助于设计、建造、维护和各种形式的创造。工程学科兼收并蓄,有专门的工程流派领域。每一个都特别强调技术的独特领域及其用途。

自过去十年以来,不同领域的各种专家一直在努力将“学习”的艺术和“工程”的本质以教学培训模块的形式结合起来。这已经形成了一股强大的推动力,促使来自学习和工程领域的团队创建在线课程。

这种不断努力让不同的人拥有良好的专业知识,并尝试制作一些最好的在线培训课程,我们愿意称之为学习工程师。也就是说,创建一个稳定的学习工程学科是一项艰巨的任务。

那么,我们如何用通俗的语言描述一个学习型工程师在做什么呢?学习工程师是一群熟练的个人,他们通过人类行为和行动从基于证据的信息中得出结论。这种导致行动的证据然后被公式化,以基于各种工程环境场景创建准确、可靠并且更重要的是数据丰富的学习数据。

在宣布学习工程成为主流职业的紧迫性和必要性下,IEEE-SA(【http://standards.ieee.org/】)标准委员会 ICCom 强烈建议开展一项新的为期两年的行业联系()活动,为迅速发展的学习工程领域提供描述和支持。

虽然联盟已经成立,但现实情况是很难找到具备这种技能的人。但是在适当的时候,随着对这一学科的认识在市场上变得可用,将会有专家诞生。到目前为止,唯一的解决方案是让一个人拥有技术和科学工作背景,并与一位在教学设计方面有坚实基础的专家合作,帮助创建一个有弹性的在线课程材料。

这又带来了对工程设计和教学设计是否相同的进一步分析。让我们得到一些澄清。首先,学习工程师不属于支持角色。相反,他是一个学习工程师,一个成熟的贡献者,一个开发在线内容的积极分子。学习型工程师的角色是“学习”学习。另一方面,教学设计者是被赋予创建在线课程任务的专家。现在,基于发给他们的技术,教学设计者想出如何成功地写作业。

整个学工程的过程听起来很迷人。但是一个人如何进入这个领域呢?ICICLE 现在已经建立了特别兴趣小组(SIGs)来跟踪与人工智能以及自适应学习技术有关的项目。除此之外,SIG 还跟踪 xAPI &学习分析、学习数据标准、能力框架、LX(学习体验)设计和学习数据治理。这将有助于团队侦察学习工程在未来将如何塑造行业智慧和学术智慧。

学习工程师倾向于广泛参与包括学习 CMS(内容管理系统)和学习管理在内的技术。移动电子学习应用程序和创作工具是市场趋势的一些变体。除了上面提到的这些,学习工程师在准备独一无二的在线内容时,还会使用仪表盘来处理分析、视频和其他类似的流媒体内容。

在过去的五年中,有一个惊人的进步帮助维持了学习技术标准的过程。利用学习工程机制改变了我们使用学习技术的传统方式,并促使其进入数字化领域。因此,学习工程的项目标志着迎合市场变化的独特技能。据预测,到下一个十年,学习工程将成为教育部门(即教育技术公司、学校和大学)的一项成熟工作。

在所有方面,随着这些进步和技术被付诸实践以创造适应性学习体验,新手和教育工作者将需要某些参数,如透明度、公正性和经证明的效率。需要记住的是,为了学习工程的发展和可持续性,需要大量精通理论和环境的工程师,这将为有效的教学和学习过程增加更多的意义。

现在正在不断努力将这种独特的综合运用到工作中。麻省理工学院的在线教育政策倡议小组发布了一份报告(https://oepi.mit.edu/),陈述了各种学习科学如何应用于高等院校。弗吉尼亚大学也做出了类似的努力,他们将这一过程命名为杰弗逊教育加速器(【http://www.jeauva.com/】T2)。这项倡议的宗旨是通过帮助中型初创企业与学习科学研究人员建立联系,帮助他们吸收功效数据。

麦格劳希尔(McGraw Hill)等大型出版社创造了“学习科学公司”(Learning Science Company)这个名称,其主要关注点是深入研究数据集。反过来,这些数据集通过其 LearnSmart 技术开始积累。McGraw Hill 还渴望将更好的设计实践融入到产品设计流程中。皮尔逊也不落后,他专注于不同产品的功效,包括对不同产品和服务的一系列评估。

一个由 30 个教育学院院长组成的核心小组,有着相似的兴趣,他们聚集在一起,致力于在他们的员工进步到即兴发挥他们的计划后,利用实体化来表现他们的员工。除此之外,他们打算教他们的老师如何在课堂上应用学习科学,作为他们课程的一部分。

Kaplan 是一个令人敬畏的专业教育机构,它不仅仅参与了前面提到的努力。事实上,首席学习官 Bror Saxberg 一直在努力大规模地推行循证学习。Kaplan 的座右铭是详细说明学习策略和计划,以在学习者和学习组织之间获得适当的平衡。投入更多的时间和响应来验证学习证据收集方法的可靠性。在一个组织的不同部分实施受控跟踪,只关注了解对个人的成功有影响的过程。最后,努力在这个领域做出“学习工程”决策,面对现实世界给我们带来的所有限制和挑战。

希望,给你提供这些关于学习工程学的有价值的见解,可能会改变你对与工程科学合作学习这一概念的看法。因此,我们可以强烈地期望,在不久的将来,将适应过程和教育方法的发展和改进,这将通过利用工程科学始终如一地导致可重复的发展和随机应变的学习情况。所有这些都应与应对教学挑战相称。

向机器学习:关于数据产品,传统制造业能教给我们什么

原文:https://towardsdatascience.com/learning-from-machines-what-traditional-manufacturing-can-teach-us-about-data-products-e661f92c3594?source=collection_archive---------20-----------------------

从航空工程师转型为数据科学家的见解

Photo by Chris Leipelt on Unsplash

这是一个两部分系列探索机器学习(ML)产品的 第一部分 。在第一部分中,我将实物产品和 ML 产品的生产进行了比较。在 第二部分 中,我讨论了为什么这些相似之处应该告知数据科学家如何进行产品开发。

作为一个领域,数据科学非常新,管理该领域的规范仍在建立中。有大量的资源解释机器学习中涉及的数学、统计学和迭代逻辑。还有更多研究如何将机器学习作为一种工具 来指导决策和解决业务问题——例如 A/B 测试和预测客户流失——或者作为一种功能来优化用户体验——想想推荐系统和个性化的策划内容。但是,因为它在商业中不太常见,所以关于机器学习作为一种产品* 的讨论要少得多,因为它的主要目的是解决市场问题并直接产生收入,例如自动驾驶汽车、客户支持聊天机器人服务和自动化保险服务等。*

在这一系列文章中,我以一种新的方式构建了机器学习产品概念,利用我在航空航天制造领域的背景来进行对比,以告知数据科学家和产品经理应该如何处理 ML 产品的开发和维护。

工厂类比

虽然这似乎违反直觉,但开发和维护机器学习产品的过程与构建物理产品比开发软件应用程序有更多的共同点。软件开发生命周期中通常缺少的是一个关键组件:数据供应链。这种缺失使得软件开发在某些方面变得更简单,因为拥有对产品不可或缺的数据意味着需要在产品的整个生命周期中考虑它。

那是什么意思?让我们从一个简单的类比开始,我发现这个类比有助于我的非技术朋友理解机器学习产品和物理产品之间的联系。

当你想要生产一个实体产品时——让我们使用飞机无线电,因为我曾经在一家制造这些产品的公司工作过——你需要设计和建造工厂,培训员工如何组装无线电,管理制造无线电所需的零件供应,整合任何客户定制,制造无线电并将其交付给你的客户。同样,在构建 ML 产品时,您需要训练模型(即设计/构建工厂并培训工人),收集客户输入(定制)并丰富这些输入(管理零件供应)以生成预测(即收音机)。

因为有如此多高度相互依赖的活动部件,一个功能的故障会导致其他功能的故障。你可以拥有拥有高端设备和顶级劳动力技能的最先进工厂,但不可靠或不充分的供应链(即数据缺失或数据不正确)最终会让你的产品沉没。

Building a custom aircraft radio versus providing customer predictions

相比之下,开发软件产品的过程要复杂得多。这类似于设计和构建一种体验。以一个销售服装的网站为例。一旦建成,有一个维护方面涉及到保持其运作。您可能希望定期更换内容或添加新功能来增强用户体验,但您通常不会依赖外部来源的数据流来维持网站的运行。虽然会有实物库存的供应链,但这与网站运营是分开的;网站本身根本不需要专门的供应链。因此,供应管理方面在软件开发生命周期框架中并不存在。一旦数据产品依赖于持续的输入数据,框架就需要遵循物理产品的供应管理实践,否则您将被迫进行被动管理。

深入观察

回到实物产品的类比,让我们来看几个现实生活中的场景,说明为什么实物产品的比较如此有用,特别是在涉及供应链管理时。

有一段时间,我在一家生产无线电的航空公司做采购员。有一天,我们发现有一批坏的开关集成电路(一种电子芯片)。大部分产品都没有通过测试,我们需要购买更多的产品来生产一台不太受欢迎的收音机。当我与我们的供应商核实时,我发现他们不再销售这种芯片。更糟糕的是,其他供应商已经将其列为过时产品。制造商两年前就已经停止生产了,我们对此一无所知。我们已经做了 12 年的收音机。我们需要尽快更换芯片!

我们能够在一个子组件上做一个小的重新设计,以包含一个更新、更小的芯片。这需要暂停生产,直到新的设计到位,在重新开始生产之前重新测试产品,并加班加点完成订单,以兑现客户的承诺。对于一个更保守的行业,同样的产品销售几十年,这种情况并不少见。

Photo by Nicolas Thomas on Unsplash

虽然这可能不会立即显而易见,但这种情况实际上与数据科学家可能遇到的情况非常相似。最近,我在检查一个原型模型的数据更新。我想验证我们使用的所有外部上下文数据都是新鲜的,所以测试预测将是准确的。在检查中,我注意到有一个资源已经过时了,更糟糕的是,我们再也无法访问那个资源了。我们需要尽快替换数据集!

虽然我们能够找到新的可比数据来源,但这些数据并不完全匹配。就像前面的飞机无线电示例一样,替换需要重新培训和重新测试新的 ML 模型,并重新运行我们的所有评估指标来检查影响。幸运的是,这不是在真实环境中托管的;我只能想象不得不将生产模型离线以修复数据质量或数据检索紧急情况的噩梦。这将是难以置信的破坏性。有一些最佳实践和检查可以帮助防止这些问题,但是我将把这个讨论留到以后。

从这些例子中,物理和 ML 产品开发之间的一些更深层次的相似之处应该是显而易见的。两者:

  • 要求持续供应高质量的投入(或零件),以便持续生产/交付;
  • 受到供应链的摆布(特别是在产品依赖非内部生成的数据的情况下);
  • 随着时间的推移,要求根据需要重新设计,以满足可持续性和/或性能需求。在这两种情况下,这通常严重依赖于供应链。

更重要的是,这些例子暗示了管理开发的需要,要意识到供应链如何影响产品生命周期的各个阶段。就像在制造业中一样,依赖于数据供应的数据产品需要从一开始就考虑到这些数据来进行管理。这是我将在这个由两部分组成的系列的下一篇文章中讨论的内容,在这篇文章中,我将探索用于最小化风险的传统供应链管理方法,并将其转化为数据科学产品。

总之,机器学习和数据依赖系统的性质使你面临其他软件应用程序中通常看不到的独特风险,但这些风险不是该行业独有的。它们在制造业中以类似的形式存在,供应链战略的概念可以直接应用于数据科学。管理好数据风险就是确保你的 ML 产品持续成功。这就是数据供应策略的存在或缺乏能够成就或摧毁你的产品的地方。

嗨,我是 凯蒂·拉泽尔-费尔曼 。我是纽约市geo phy的数据科学家。对这个帖子有疑问或者对这个话题很好奇?欢迎在下面评论或者 联系我

人工智能学习金拉米,第一部分

原文:https://towardsdatascience.com/learning-gin-rummy-part-i-75aef02c94ba?source=collection_archive---------5-----------------------

在我关于主题的上一篇文章中,我描述并包含了一个手工构建的玩金拉米的系统的代码,该系统只考虑当前可见的牌,而不考虑对手已经捡起或埋在弃牌堆中的先前可见的牌的记忆。我的直觉是,如果你在策略中包含已知牌的历史,你应该可以玩得更好,并且可靠地击败我手工构建的策略。

理解手牌构建策略的关键首先是手牌和游戏状态的表示,其次是手牌评估函数。

表现

金拉米世界的表示是一个 4 x 13 的矩阵,对应于一副牌中的四种花色,以及花色中牌的值,从 a 到 k。例如,拿这手(赢的)十张牌来说:

这将由矩阵表示(其中 1 表示您有该卡):

游戏状态也是 4×13 矩阵,然而代替 0/1,有九种状态对应于哪个玩家持有哪些牌,哪些牌已经被放在弃牌堆中,哪些牌留在库存中(面朝下的牌堆)。这些状态是:

## Card states:          
## 0 Stock         
## 1 Player 0 card that was stock      
## 2 Player 0 card that was discard      
## 3 Player 1 card that was stock      
## 4 Player 1 card that was discard      
## 5 Player 0 top-discard       
## 6 Player 0 discard       
## 7 Player 1 top-discard       
## 8 Player 1 discard 

一个游戏状态的例子,玩家 0 刚刚用上面说明的那手牌赢了游戏:

最后,还有另一种表示方法,那就是股票牌的顺序(stockOrder),它表示为一副牌中 52 张牌的列表,这是一个 4 x 13 矩阵的简化版本。游戏开始时,洗牌相当于:

stockOrder = np.arange(52)

手动评估

手牌评估功能为手牌中的每张牌赋值,值越高的牌越有价值,有助于组成得分牌。价值较低的牌是你可以弃掉的牌。

手动构建的手牌评估函数背后的思想是,如果一张牌在花色中具有水平最近邻,以构成顺子得分(例如,上面手牌中的红心 4 到 7),则该牌获得更高的值。此外,如果一张牌有垂直的相邻牌(例如三个皇后),它的价值也更高。

手动构建的手牌评估函数使用卷积矩阵来评估手牌中的每张牌。

这意味着,根据水平相邻的牌,增加的价值最大,而相同价值不同花色的牌也很有价值。

战略

每回合,玩家必须做出两个决定:

  1. 取货:你是要正面朝上的丢弃,还是正面朝下的股票卡?
  2. 弃牌:你手里的 11 张牌你会弃哪张?

手工构建策略是拾取步骤的一个简单规则:

  1. 用最大弃牌评估当前手牌
  2. 如果最上面的弃牌是你手中价值最低的牌,则取牌。否则拾取丢弃。

更简单的规则是弃牌步骤:评估你手中的 11 张牌,弃掉价值最低的牌。

手工打造的策略有什么好的吗?

在我和我的两个孩子艾娃和卢卡参加的一场非正式锦标赛中,手工打造的策略极具竞争力。这是玩金拉米游戏的最佳策略吗?大概不会。手工构建的策略有点愚蠢,因为它忽略或“忘记”了以前玩过的牌。我知道如果我的对手在收集 a,我会尽量避免丢弃 a。手工构建的策略不会这样做。

我可以认真考虑一下,自己构建一个考虑历史牌的手牌评估函数的扩展,但我想开发一个自动学习这种手牌评估的系统。是时候学习人工智能技术了。下一篇将会讲述我是如何接近这个的。

用机器的方式学习人类。

原文:https://towardsdatascience.com/learning-humans-the-machine-way-26bb2137e1ec?source=collection_archive---------5-----------------------

我们到底是什么,在我们自己的大脑里发生了什么?仅仅是化学反应让人思考吗?还是不止如此。我们,人类,创造了这么多的指标来解决很多问题来生存和互相帮助。但是我们仍然会犯一些错误,比如迷失、失控和忽视。我们把随机时刻联系起来,让事情变得更复杂。背后的方程式是什么?是你周围的环境或人,还是你自己?在思考了所有这些之后,我开始分析机器是如何工作的,它们是如何进行繁重的计算的。它们是如何处理的?他们现在是如何获得思考“人工智能”的能力的当你能理解机器的时候,它会让你很高兴去关注上面提到的人类的问题。

source : MIT Technology Review

这个世界上的一切都可以局限在 0 和 1。这些 0 和 1 是这项技术背后的计算单位。当谈到我们人类的大脑时,我们将这些计算单元命名为神经元。那么这个计算单位是做什么的呢?这些能被削减成更多的子部分吗?答案是肯定的;我们甚至可以将这些计算单元分成更小的部分。而是你对理解事物的感知。让我们举一个计算机解一个简单的数学方程 a +b 的例子。计算机从来不识别实数,它唯一能理解的是二进制数 a 0 或 1。如果是 1,那么功率通过电路,如果是 0,那么通俗地说就不行了。但是,它能够理解所有复杂方程的媒介是“编程语言”

同样,神经元也从来不会体验到我们生活的情绪或环境。他们表现得像问题的解决者,有时是问题的创造者。他们在一瞬间把所有的事情和情况联系起来。我们能控制它吗?答案是否定的。因为它将在神经元控制中,让你循环通过事物。你解决问题的能力将与神经元之间的相互作用,以及它们连接的速度有关。就看你从小怎么培养他们了。“你是怎么训练他们的?”我们能训练他们吗?不,它们只是会适应你做事的方式,你通过它传递的等式。

即使对计算机来说,我们也不知道二进制在里面是如何工作的,我们传入方程。幸运的是,我们的大脑不是由铜层或玻璃纤维制成的。虽然我们可以训练它快速计算,但这需要几年的时间。机器擅长存储和速度,但大脑保持效率领先。

写这篇文章的原因是,有时候,我不明白为什么我在思考一个问题时会把事情变得更复杂,然后我意识到,不是我在思考这个问题。这是因为有很多化学反应和计算是我无法控制的。然后,当我试图理解计算机/机器时,我知道我可以验证我的一个鼓舞人心的人物所说的话。《人工智能的局限性》涉及到在计算机科学和生物学之间架起一座桥梁。"

我是一名充满激情的工程师,试图理解机器和人类。这篇文章可以帮助你更简单、更容易地解决你的问题。你所需要做的就是深入思考。为了让你把事情联系起来,我留下了这篇不完整的文章。敬请关注下一篇文章。

为机器学习和深度学习学习数学

原文:https://towardsdatascience.com/learning-maths-for-machine-learning-and-deep-learning-5509c097ee83?source=collection_archive---------2-----------------------

虽然我在攻读工程学位时确实学了很多数学,但当我想进入机器学习领域时,我已经忘记了大部分。毕业后,我从未真正需要过任何数学。我做了很多依赖逻辑的 web 编程,我可以诚实地说,每一个标题中带有“管理”一词的系统都让我损失了三分之一的数学知识!我已经为学习管理系统、内容管理系统和客户关系管理系统编写了扩展程序——我将让您来计算我在使用这些系统后获得了多少数学应用。目前,我已经掌握了很好的数据科学技能,可以使用各种 ML 和 DL 算法。我已经成功完成了许多 MOOCs 课程(例如,Udacity 的深度学习基础课程和吴恩达的新 Coursera 课程)。我会用 Scikit Learn,TensorFlow,Kera 的。….但是我对创造新的算法变种有粗略的想法。目前,我真的想创建一种新的交互式主题建模算法。由于缺乏数学知识,我感到进退两难。在我试图重新学习一些基础数学的旅行中,我遇到了几本由具有解释艺术的人写的书。这些书产生了巨大的不同,因为它们能够以非常简单的方式传达复杂的概念。我写这篇博客是为了分享这些伟大的资源,尤其是对程序员而言。这些书涵盖了微积分和线性代数。我还没有找到一本等效的概率和统计书籍——如果你知道一本,请留下评论或发推文。

汤普森使微积分变得简单

从一本 1914 年写的书里学微积分!书的 pdf 是免费的。这本书简直太棒了。英语是有点老的风格,但解释是永恒的。汤普森让微积分变得超级简单。成本函数的优化是 ML 和 DL 的核心,这本书将帮助你理解最小化的基础。那些渐变体面的更新规则将不再看起来像魔术。看看序言就知道了——它为这本书的其余部分定下了基调……

The Prologue from Calculus Made Easy by S. Thompson

P. N .克莱因的矩阵编码

大多数线性代数书从简单开始,但是像图像、基、维数、正交化、特征向量这样的概念是以完全抽象的方式介绍的。大多数线性代数书籍甚至没有介绍真实世界的应用,并且很难看出你在哪里或者为什么要使用数学。矩阵乘法是一个很好的例子,我学到了一些东西,但从来没有真正理解(即,为什么它不是一个元素一个元素地执行)。编码矩阵不一样!您实际上可以在提高 Python 编程技能的同时构建自己的线性代数库!这本书充满了实际的计算机科学应用(例如,固定白板照片的角度)。

Coding the Matrix — the best Linear Algebra book ever!

学习神经网络架构

原文:https://towardsdatascience.com/learning-neural-network-architectures-6109cb133caf?source=collection_archive---------12-----------------------

如何自动创建神经网络

上次我们谈到了学习的限制,以及消除对神经网络架构设计的需求将如何导致更好的结果和深度神经网络的使用。

在这里,我们将分析所有最近的学习神经网络架构的方法,并揭示利弊。这篇文章会随着时间的推移而发展,所以一定要不时登录以获取更新。

首先…

学习一个神经网络架构意味着什么?这意味着尝试以最佳方式组合所有的神经网络构建模块,以在某些任务中获得最高性能,比如说:对 ImageNet 图像进行分类。

这里你可以看到过去 10 年左右所有最近的神经网络架构。所有这些建筑都是人类凭直觉和原始脑力精心打造的。这是人类最大的智慧,但是正如你所想象的,它并不总是导致最好的解决方案。正如我们在这里提到的,这不是进步的方式,因为我们将受到人类思维所能想到的限制,并且永远不会完全搜索神经架构的大空间。想想最近象棋围棋的游戏发生了什么!人类被搜索最佳行动和策略的神经网络算法打得落花流水。

神经网络算法将在神经结构搜索领域击败人类,就像他们在围棋和国际象棋中击败人类一样!

所以要走的路真的是使用神经网络来寻找越来越好的神经架构。实际上,我们将使用相同的梯度下降技术来引导神经结构的巨大搜索。

但是正如你所看到的,有许多可能的神经构建模块,搜索空间是巨大的。想象我们已经尝试了所有可能的卷积层:不同数量的输入输出平面、膨胀、深度、池化、非线性等…搜索空间可以从 10 个⁴到 10 个⁸or 更多选项!这是一个巨大的空间。想象一下,我们花 1 个小时来训练和测试一个架构……那么我们将需要 10 个⁴小时,或者永恒!

梯度方法

基于控制器的方法,如 Zoph,Le (2017 )使用递归神经网络来创建新的架构,然后用强化学习来测试它们。

An overview of Neural Architecture Search

他们将神经网络的连接和结构编码成可变长度的字符串,并使用 RNN 控制器来生成新的架构。“子网络”是在数据集上训练的,以产生训练和验证精度。验证准确度被用作训练控制器的奖励信号。随着控制器随着时间的推移在搜索中改进,这又在接下来的迭代中产生更好的神经网络。

刘看着艾尔通。(2017) 使用启发式搜索,从简单的神经网络结构开始,逐步增加复杂度。本文基于Zoph et al(2018)的工作。在后一篇论文中,他们再次使用相同的 RNN 控制器来搜索架构:

Controller model architecture for recursively constructing one block of a convolutional cell.

该控制器产生一系列输出,这些输出对上图顶部的每个元素进行编码,基本上包括:使用前两层,对两个输入中的每一个应用哪种操作,以及用哪种方法将它们的两个输出合并成一个输出。

为了减少可能的参数组合数量,他们使用下图所示的固定构造块架构。该区块可以实现类残差层和类 Google net层。它们允许 RNN 控制器为每层找到多个块,通常是 5 个,这是有效性和搜索空间之间的一个很好的折衷。

Example constructed block

在这项工作中,他们还将可能的基本构建模块的数量限制在以下列表中:

  • 身份;1x7 然后 7x1 卷积;1×3 然后 3×1 卷积;3x3 平均池化;3x3 或 5x5 或 7x7 最大池化;1x1 或 3x3 卷积;3×3 或 5×5 或 7×7 深度方向可分离卷积;3x3 扩展卷积

Scalable architectures for image classification consist of two repeated motifs termed Normal Cell and Reduction Cell.

他们创造了如左图所示的架构。基于以前的架构历史,他们决定整体架构应由两种类型的单元组成:(1)返回相同维度的特征图的卷积单元或正常单元;以及(2)返回高度、宽度或缩减单元 l 缩减两次的特征图的卷积单元。注意,在这些架构中,每当空间激活大小减小时,它们还会将输出中的滤波器数量增加一倍,以保持大致恒定的隐藏状态维度。还要注意的是,左图中的这个架构有点类似于 ResNet 中的模块,包括普通和简化单元的选择。

为了训练控制器 RNN,他们使用强化学习。一旦 RNN 建造了一个建筑,它就被训练了。利用验证数据集中的准确性,产生奖励信号,并用于向 RNN 控制器提供反馈,最终训练它在建筑搜索方面越来越好。由于奖励信号是不可微分的,他们使用策略梯度方法,如加强,并通过使用以前验证奖励的移动平均值减去当前验证值。这有效地充当了验证准确性的增量改进度量。

有趣的是,在下图中你可以看到算法找到的最佳细胞。它们似乎是更复杂版本的 Inception-ResNet 层。

Architecture of the best convolutional cells (NASNet-A) with B = 5 blocks identified with CIFAR-10

结果很好!他们发现,与人类手工制作相比,大型和小型神经网络都非常高效和高性能。下面我们报告一个小模型的表格。

Performance on ImageNet classification on a subset of models operating in a constrained computational setting, i.e., < 1.5 B multiply-accumulate operations per image

最后,本文对强化学习搜索相对于随机搜索的性能做了一些有益的评论。在过去的努力中,击败随机搜索出人意料地困难。RL 搜索更好,可以找到很多更好的模型,但随机搜索的效果也令人惊讶。毕竟这就是创造我们人类大脑的东西,但在此之前只花了几十万年和 50 亿年…

Comparing the efficiency of random search (RS) to re- inforcement learning (RL) for learning neural architectures

总的来说,这是一个很有指导意义的模型搜索,但方法和结果可以用于许多不同类型的神经网络。我们希望在接下来的几年里看到这项技术得到更多的应用。一个缺点是所使用的模型架构非常类似于 ResNet 块架构。此外,构造的块仅捕获可能集合的子集。这当然都是为了减少搜索空间并使问题更易处理,但是它并没有例如推广到编码器-解码器架构或更小的应用。为此,人们将不得不创建新的构造块和基础网络。

此外,对体系结构的搜索计算量非常大,并且花费大量时间。你需要 500 个 GPU(贵的像英伟达 P100!)而且你需要在 4 天内测试 20,000 个神经网络才能找到结果

遗传搜索

遗传搜索是穷举搜索方法,创建不同的神经架构,然后逐一尝试。因此,它们经常受到无向导搜索的缓慢过程的限制。例如 Wierstra 等人(2005 年)、Floreano 等人(2008 年)、Stanley 等人(2009 年)。这些方法使用进化算法来搜索新的架构。

神经进化是一种最近在强化学习算法中获得成功的方法。它最近在强化学习任务中取得了成功,而其他算法(DQN、A2C 等)却没有取得成功。)失败了。

作为网络架构搜索进行修剪

最近,神经网络的修剪作为一种神经网络结构搜索技术被重新审视。本文展示了两个主要的见解:1)可以从修剪过的神经网络开始,并从头开始训练它;2)修剪因此可以被视为类似于网络结构搜索的优化神经网络结构的技术。

注意,修剪产生的结果不如上面讨论的基于梯度的搜索技术好。

关于作者

我在硬件和软件方面都有将近 20 年的神经网络经验(一个罕见的组合)。在这里看关于我:媒介网页学者LinkedIn 等等…

[学习笔记]循环网络中的辍学—第 2 部分

原文:https://towardsdatascience.com/learning-note-dropout-in-recurrent-networks-part-2-f209222481f8?source=collection_archive---------1-----------------------

喀拉斯和 PyTorch 的经常性辍学实施

在进行实验之前,我想详细检查一下实现,以便更好地理解和将来参考。由于篇幅限制,我用#...省略了对当前讨论不重要的行。

https://keras.io/img/keras-logo-small.jpg

克拉斯

这里我用的是 Tensorflow 1.3.0 自带的 Keras。

实现主要驻留在LSTM类中。我们从LSTM.get_constants类方法开始。为Recurrent.call方法中的每个批处理调用它,以提供丢弃掩码。(输入辍学率和经常性辍学率已作为实例属性存储在__init__。)

输入以 (样本,时间(用零填充),input_dim) 的形式排列。上面的代码块创建形状为 (samples,input_dim) 的输入掩码,然后随机将元素设置为零。因此,对于每个序列/样本,新的掩码被采样,与论文【1】中描述的一致。

注意创建了四个不同的掩模,对应于 LSTM 的四个门。只有 LSTM 支持这个设置。(更多细节见下文)。

同样,上面创建了四个形状为 (samples,hidden_units) 的循环遮罩。

接下来我们转向LSTM.step方法,该方法在每个时间步依次执行:

Keras 有 3 个 LSTM 实现,默认为实现 0:

实现:{0、1 或 2}之一。如果设置为 0,RNN 将使用使用更少、更大矩阵乘积的实现,从而在 CPU 上运行更快,但消耗更多内存。如果设置为 1,RNN 将使用更多的矩阵产品,但较小的,因此运行速度较慢(实际上可能在 GPU 上更快),同时消耗较少的内存。如果设置为 2(仅适用于 LSTM/GRU),RNN 会将输入门、忽略门和输出门组合成一个矩阵,从而在 GPU 上实现更省时的并行化。注意:RNN 辍学必须为所有门共享,导致稍微减少正规化。

实现 2 对应于捆绑权重 LSTM。上面的代码块实现了 dropout,就像这个公式[1]一样:

Dropout in Tied-weight LSTM

请注意它是如何只获取第一个遮罩并丢弃其余的(三个遮罩)的。这是因为这个公式要求所有门共享 RNN 辍学。

看来实施 01 在如何应用输入压差方面有所不同。在实现 0 中,转换后的输入在step 方法之外预计算,而在实现 1 中,输入被丢弃并在step内转换。

(注意每个门如何使用它自己的下降掩码,以及如何为每个门组合转换的输入和隐藏状态。)

就是这样。实现没有任何惊喜,所以你可以放心使用 [dropout](https://keras.io/layers/recurrent/#lstm) [recurrent_dropout](https://keras.io/layers/recurrent/#lstm) 参数。你唯一需要考虑的可能是是否使用实现 2 而不是 0 来加快速度。

(目前 Keras 似乎不提供[1]中描述的嵌入丢失。不过,我认为你绝对可以为此编写一个自定义层。)

http://pytorch.org/tutorials/_images/pytorch-logo-flat.png

PyTorch

正如在第 1 部分中提到的,PyTorch 不提供对变化的辍学的本地支持。我们将使用来自sales force/awd-lstm-lm项目的实现。(此部分针对 PyTorch 0.2.0 版本)

锁定输出 可用于对每个时间步长应用相同的下降掩码(如输入下降):

PyTorch 一般支持两种序列张量排列: (样本,时间,输入 _ dim)(时间,样本,输入 _dim)* 。上述代码块是为后一种安排而设计的。您可以很容易地修改它来支持这两种安排。m被创建为一个单一时间步长的下降遮罩,形状为 (1,样本,输入 _ 尺寸) 。因此,每个序列都要采样一个新的掩码,与 Keras 中的一样。*

接下来是 WeightDrop 类。在[2]中提出的这种压差形式更简单,性能更好,即使在捆绑权重设置中,每个门也允许不同的压差。相比之下,要实现传统的变分丢失,可能需要在 For 循环中将 LSTM/RNN 分解成单独的时间步长。

_setupweight drop中禁用参数展平(否则无法与 CUDA 配合使用),并将目标权重矩阵(通常为weight_hh_l0)重命名为带有_raw 后缀的矩阵。在forward中,目标权重被应用了一个删除遮罩,被复制并重命名为原始属性名(weight_hh_l0)。注意注册的参数是带有_raw后缀的权重矩阵(删除操作不会影响该权重矩阵)。

有两种类型的重量下降,由variational参数控制。在我们能够理解代码之前,我们首先需要知道权重矩阵是如何工作的:对于 LSTM nn.LSTM,有四个相关联的参数:weight_ih_l0weight_hh_l0bias_ih_l0bias_hh_l0。命名要足够明显:ih表示输入要隐藏;hh意为隐来隐去;l0表示第一层。如果以nn.LSTM(2, 8, num_layers=1) 为例,weight_hh_l0 (U) 会有一个 (32,8) 的形状,对应四个门和八个隐藏单元(32 = 8 * 4)。你应该能认出这是一只负重 LSTM。这暗示了隐藏状态矩阵 (h) 被整形 (8,batch_size) 。矩阵乘法 Uh 将产生一个 32 x batch_size 矩阵。每列代表一个单个序列的八个隐藏单元及其四个内部门的转换后的循环输入(注意 PyTorch 使用 Uh 而不是 hU ):

Internal Definition of LSTM

对于variational=True,创建形状为 (4 * hidden_units,1) 的遮罩。将任何一个元素设置为零意味着切断隐藏单元中一个门的所有循环连接。这似乎有点不可思议。如果我们希望 dropout out 与 Keras 绑定权重实现(下面的公式)一致,我们需要使用形状为 (1,hidden_units) 的遮罩。将任何一个元素设置为零意味着切断所有源自隐藏单元的循环连接。(记住,Keras 中的单个循环漏失遮罩是成形的(示例,hidden_units)。)有可能是我弄错了,或者是 bug,或者是作者故意这样做的。我还不确定。

(Reprise) Dropout in Tied-weight LSTM

对于variational=False,创建形状 (4 * hidden_units,hidden_units) 的遮罩。因此,不同的隐藏单元和不同的门使用不同的掩模。

WeightDropKeras 实现的一个重要区别是权重矩阵的丢弃掩码只能在每小批量采样一次。如果您试图对每个序列采样一次,那么它实际上是使用大小为 1 的小批量,失去了使用小批量的目的。根据小批量的大小,这种限制导致每个小批量内不同程度的变化减少。(记住,在 Keras 中,对每个序列采样新的缺失掩码。)因此,总是从variational=False配置开始似乎是个好主意。

最后,嵌入漏失:

这应该很简单。漏音遮罩的形状为 (num_words,1) ,漏音应用于字级。如[1]中所述,当字数和嵌入维数很大时,这种实现可能会有一些性能问题。但是我猜作者认为这是代码简单性和性能之间的一个适当的折衷。

把它放在一起

使用所有三个讨论过的辍学的示例模型:

(第 11–15 行)虽然 WeightDrop 不需要分割时间步,但是它需要分割 RNN 层。这是我们可以在图层之间应用locked roup的唯一方法。

(第 30 行)此处forward应用了嵌入 dropout。

(第 31,35 行)locked rout通过简单地传递张量和辍学率来应用。

待续

这个帖子很乱,很抱歉。用简单的英语从技术上写作很难…无论如何,在最后一部分,我将记录一些实验结果。所得结果与文献[1]的结果有些不同。我也会试着对此做一些解释。

* [## [学习笔记]循环网络中的辍学—第 1 部分

理论基础

becominghuman.ai](https://becominghuman.ai/learning-note-dropout-in-recurrent-networks-part-1-57a9c19a2307) [## [学习笔记]循环网络中的辍学—第 3 部分

一些实证结果比较

medium.com](https://medium.com/@ceshine/learning-note-dropout-in-recurrent-networks-part-3-1b161d030cd4)

参考

  1. y . gal 和 z . Ghahramani(2015 年)。在递归神经网络中基于理论的辍学应用。
  2. 梅里蒂,s .,凯斯卡尔,N. S .,&索彻,R. (2017)。规范和优化 LSTM 语言模型。*

[学习笔记]循环网络中的辍学—第 3 部分

原文:https://towardsdatascience.com/learning-note-dropout-in-recurrent-networks-part-3-1b161d030cd4?source=collection_archive---------5-----------------------

一些实证结果比较

在第一部分中,我们介绍了循环网络中变分丢失的理论基础。第二部分研究了 Keras 和 PyTorch 中的实现细节。现在是最后一部分,我们在公共数据集上比较不同的模型。

MC 辍学实施

Keras 没有一个参数或函数来启用测试时间的丢失。虽然你可以使用一个总是活跃的 lambda 层,我们不容易比较标准漏失近似和蒙特卡罗漏失的结果。

撰写核心论文[1],的 Yarin Gal 提供了一个 2017 年 2 月在 Github 上实现 MC dropout 的例子。这也是 Keras 开始为经常性辍学提供内置支持的时候。仅仅过了几个月,它就很快过时了。我挖了一下 似乎 已经让它与 Kera s 的最新版本 Tensorflow 1.3.0 一起工作了。

对于 PyTorch 来说,事情就简单多了。在前馈前使用model.eval()使能标准压差近似值,使用model.train()使能蒙特卡洛压差。

请注意,一些超参数是根据框架经验调整的。例如,在 Keras 中,学习率被设置为 1e-3,但在 PyTorch 中,它被设置为 1e-4。目的是避免模型永远收敛。因此,建议将重点放在同一框架中实现的模型之间的比较上。

康奈尔电影评论数据集

该数据集在论文[1]中用于评估不同的模型。有 10,620 个训练样本和 2,655 个测试/验证样本。这是一个回归问题。给定一个单词序列,模型需要预测用户给这部电影的分数。将分数归一化,使其以零为中心,单位方差为。在下面的讨论中,【原始 MSE】将对应于归一化分数的均方误差,将对应于原始分数的均方根误差(文中使用 RMSE)。

批量大小设置为 128,序列长度为 200(填充),与论文中相同。所有模型中隐藏单元的数量保持不变。唯一的区别是如何应用辍学。

Fig 3(b) in [1]: Naive Dropout LSTM over-fits eventually

论文中使用的退出概率似乎大多是 0.5 。正如你在上图中看到的,这可能与缓慢的收敛速度有关。变分 LSTM 需要数百个历元才能胜过其他两个模型。我没有太多的时间来训练这么多的纪元,所以在允许一些过度拟合的同时,降低了退出概率以提高速度。关于确切的概率,请参考本节末尾的电子表格。

克拉斯

评估了三种模型:

  1. 变量:使用输入压差、循环压差和输出压差。
  2. 无脱落:只有极低的重量衰减。
  3. 朴素漏失:使用时间步长独立输入漏失,输出漏失。

所有三种模型都没有嵌入丢失。

(向右修正图表的坐标轴标签:X 轴:" 原始 MSE 差异 ",Y 轴:" 计数"】**

图表“(MC —近似值)直方图”是每个样本的 MC 差值的原始 MSE 减去标准差值近似值的直方图。注:在变分和简单的 LSTM 模型中,MC 下降通常产生较低的原始 MSE。

天真的辍学者似乎是最好的执行者,并且不会随着时间的推移而过度适应。

PyTorch

测试了五个模型:

  1. 重量下降 [ 2 ]:使用输入下降、重量下降、输出下降、嵌入下降。
  2. 无脱落:香草单层 LSTM,无重量衰减。
  3. 朴素漏失:使用时间步长独立输入漏失,输出漏失。
  4. 变重量下降:与 变重量下降 相同,但参数设置为真。**
  5. 无经常性脱落的变化 ( 变量-2v w/o r-drop ):与重量脱落相同,但重量脱落概率设置为零。(无经常性辍学)

对于重量下降的 LSTM,MC 压差低于标准压差近似值。这也适用于没有经常性辍学的变分 LSTM。

在这种情况下,“无辍学”模型严重过度拟合。与 Keras 的结果相比,我们也许可以把 RMSE 的陡峭上升归因于没有重量衰减。然而,PyTorch 的“天真辍学”模式在 RMSE 也有缓慢上升的趋势。“重量下降变化”模型似乎有一些不合适的问题。

摘要

以下是实验及其结果的详细记录:

Spreadsheet Link

(似乎没有办法把谷歌电子表格嵌入到一个中等的帖子里。请使用表格下方的链接获取表格的网页版本。)

(尽管 MC dropout 在减重模型中的性能较差,但为了简单起见,我坚持使用 MC dropout:所有预测(除了“无脱落”模型)都是使用 10 轮 MC dropout 创建的。****

IMDB 电影评论数据集

这个数据集是一个二元分类问题。有 25000 个训练样本和 25000 个测试样本。目标是从给定的单词序列中预测用户是否喜欢这部电影。

批量大小为 128,序列长度为 80(填充)。

模型结构和之前差不多,这里就不赘述了。

克拉斯

和以前一样,MC 丢失通常产生较低的对数损失。

(epoch 17 后有一些数值问题,生成 NaNs 为 log loss。图表中省略了这些数据点。)

在这个数据集中,所有模型都随着时间的推移而过度拟合。

PyTorch

和以前一样,权重下降模型在 MC 丢失时表现更差,就像变分模型在经常性丢失时一样(不在直方图中)。

在这种情况下,“天真辍学”模型明显过度拟合。其他三个辍学模型都得到了类似的表现。

摘要

Spreadsheet Link

“变权重下降”在这个数据集中表现得令人惊讶,具有体面的验证损失,并且相当抗过拟合。

总体评论

  1. 我们可以从减肥模特身上得到一些不错的表现。然而,退出概率需要仔细调整。
  2. 我怀疑 MC dropout 性能的下降与嵌入 dropout 的使用有关。我会尝试使用更多的采样轮或只是在测试时间禁用嵌入丢失。
  3. 从 IMDB 数据集的结果来看,嵌入丢失似乎在防止过拟合方面有适度的贡献。
  4. 在 Jupyter notebook 中进行实验(链接到下面的代码)需要大量的手工劳动,并且只能在一定程度上进行管理。如果需要更全面的评估,我会使用类似于神圣的来自动化这个过程。

** [## ces hine/经常性辍学实验

通过在 GitHub 上创建一个帐户,为经常辍学实验的发展做出贡献。

github.com](https://github.com/ceshine/recurrent-dropout-experiments)**

参考资料:

  1. Gal,y .,& Ghahramani,Z. (2016)。作为贝叶斯近似的辍学:表示深度学习中的模型不确定性
  2. 梅里蒂,s .,凯斯卡尔,N. S .,&索彻,R. (2017)。规范和优化 LSTM 语言模型

以前的零件

** [## [学习笔记]循环网络中的辍学—第 1 部分

理论基础

becominghuman.ai](https://becominghuman.ai/learning-note-dropout-in-recurrent-networks-part-1-57a9c19a2307) [## [学习笔记]循环网络中的辍学—第 2 部分

喀拉斯和 PyTorch 的经常性辍学实施情况

medium.com](https://medium.com/towards-data-science/learning-note-dropout-in-recurrent-networks-part-2-f209222481f8)**

[学习笔记]带 Pytorch 的单次多盒检测器—第 1 部分

原文:https://towardsdatascience.com/learning-note-single-shot-multibox-detector-with-pytorch-part-1-38185e84bd79?source=collection_archive---------1-----------------------

最近我在尝试学习 Pytorch 以及一些物体检测深度学习算法。因此,为了一举两得,我决定阅读由 Max deGroot 撰写的单次多盒检测器论文以及其中一篇 Pytorch 实现。

诚然,我在理解论文中的一些观点时有些困难。看了实现,挠了一会儿头,我想我至少弄明白了其中的一部分。所以下面是我在第一遍和第二遍阅读后对一些混淆概念的笔记。

网络结构

SSD Architecture taken from the original paper

首先,单次多盒检测器(SSD)使用在 ILSVRC CLS-LOC 数据集上预训练的 VGG-16 结构,并增加一些额外的卷积层。相关代码位于 ssd.py :

base = {
    '300': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 
            'C', 512, 512, 512, 'M', 512, 512, 512],
    '512': [],
}
extras = {
    '300': [256, 'S', 512, 128, 'S', 256, 128, 256, 128, 256],
    '512': [],
}

“m”表示内核大小为 2、步幅为 2 的最大池。“c”表示相同的最大池化,但带有在原始结构中没有出现的ceil_mode=True。我的理解是ceil_mode=True处理输入高度或宽度不能被 2 整除的情况,所以在输出中会有一些单元格来自 1x2,2x1,1x1 max 池。不知道为什么会在那里,但应该没什么区别。

“S”表示一个stride=2padding=1卷积层,过滤器的数量在列表中紧随其后(例如,第一个“S”有 512 个过滤器)。

def vgg(cfg, i, batch_norm=False):
    layers = []
    in_channels = i
    for v in cfg:
        if v == 'M':
            layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
        elif v == 'C':
            layers += [nn.MaxPool2d(
                kernel_size=2, stride=2, ceil_mode=True)]
        else:
            conv2d = nn.Conv2d(
                in_channels, v, kernel_size=3, padding=1)
            if batch_norm:
                layers += [
                    conv2d, nn.BatchNorm2d(v), 
                    nn.ReLU(inplace=True)]
            else:
                layers += [conv2d, nn.ReLU(inplace=True)]
            in_channels = v
    pool5 = nn.MaxPool2d(kernel_size=3, stride=1, padding=1)
    conv6 = nn.Conv2d(
                512, 1024, kernel_size=3, padding=6, dilation=6)
    conv7 = nn.Conv2d(1024, 1024, kernel_size=1)
    layers += [pool5, conv6,
               nn.ReLU(inplace=True), conv7,
               nn.ReLU(inplace=True)]
    return layers

请注意,它向原始 VGG 结构添加了一个 conv6 (1024 个 3×3 卷积滤波器,膨胀=6,填充=6)和一个 conv7 (1024 个 1×1 卷积滤波器)层。

def add_extras(cfg, i, batch_norm=False):
    # Extra layers added to VGG for feature scaling
    layers = []
    in_channels = i
    flag = False
    for k, v in enumerate(cfg):
        if in_channels != 'S':
            if v == 'S':
                layers += [
                    nn.Conv2d(in_channels, cfg[k + 1],
                        kernel_size=(1, 3)[flag], stride=2,
                        padding=1)]
            else:
                layers += [
                   nn.Conv2d(
                     in_channels, v, kernel_size=(1, 3)[flag])]
            flag = not flag
        in_channels = v
    return layer

额外层的构建使用一个旋转的 3x3 和 1x1 内核大小,可选的“S”标志表示stride=2padding=1,正如我们已经提到的。

我们已经讨论了网络结构。现在是时候继续实际预测/检测物体的类别和位置了。

预测方案

Figure taken from the original paper

SSD 的一个关键概念是将神经网络中的中间层作为特征图。然后,它对要素地图运行 3x3 卷积过滤器,对默认框(Python 代码中的先前框)进行分类和预测偏移。每个位置有 4 或 6 个相应的默认框。自然地,较低层中的默认框较小,因为较低层捕获了输入图像的更精细的细节。

对于每个默认框,我们预测:

  1. 它属于某一类的概率
  2. 默认框中心的 x 和 y 偏移量
  3. 宽度和高度缩放到默认框的宽度和高度

中的默认框设置 ssd.py :

mbox = {
    # number of boxes per feature map location    
    '300': [4, 6, 6, 6, 4, 4],  
    '512': [],
} def multibox(vgg, extra_layers, cfg, num_classes):
    loc_layers = []
    conf_layers = []
    vgg_source = [24, -2]
    for k, v in enumerate(vgg_source):
        loc_layers += [
            nn.Conv2d(vgg[v].out_channels,
                      cfg[k] * 4, kernel_size=3, padding=1)]
        conf_layers += [
            nn.Conv2d(vgg[v].out_channels,
                      cfg[k] * num_classes, kernel_size=3,
                      padding=1)]
    for k, v in enumerate(extra_layers[1::2], 2):
        loc_layers += [
            nn.Conv2d(v.out_channels, cfg[k]
                      * 4, kernel_size=3, padding=1)]
        conf_layers += [
            nn.Conv2d(v.out_channels, cfg[k]
                      * num_classes, kernel_size=3, padding=1)]
    return vgg, extra_layers, (loc_layers, conf_layers) def build_ssd(phase, size=300, num_classes=21):
    if phase != "test" and phase != "train":
        print("Error: Phase not recognized")
        return
    if size != 300:
        print("Error: Sorry only SSD300 is supported currently!")
        return
    return SSD(
        phase, *multibox(vgg(base[str(size)], 3),
                         add_extras(extras[str(size)], 1024),
                         mbox[str(size)], num_classes),     
        num_classes
    )

SSD 使用 VGG 模型中的两个层— Conv4_3 和 Conv7/FC7,它们对应于层索引 24 和-2(即 relu 激活之前)。这种获得层次的方式有点不靠谱。如果我们决定在 VGG 构造中使用 use batch_norm=True,多框构造将会得到错误的层。额外的层也应该如此,但事实上batch_norm=True甚至还没有在add_extras()中实现。

对于额外的图层,我们在每两层中使用第二层作为特征地图。一个奇怪的部分是,因为最后一层 Conv11_2 具有形状(256,1,1),所以 3x3 卷积不是真正必要的。我猜这只是为了代码结构的简单。

注意,每个默认盒子应该有num_class + 4 (x,y,w,h)个输出。

锻炼

Table taken from the original paper

尝试验证 SSD300 中默认盒子的数量(实现的那个)。

解决办法

  1. Conv4_3: 38 * 38 * 4 = 5776
  2. Conv7: 19 * 19 * 6 = 2166
  3. Conv8_2: 10 * 10 * 6 = 600
  4. Conv9_2: 5 * 5 * 6 = 150
  5. Conv10_2: 3 * 3 * 4 = 36
  6. Conv11_2: 4

总计:5776+ 2166 + 600 + 150 + 36 + 4 = 8732

请注意,此计算包括填充单元格中的默认框,这些默认框将始终为零,因此基本上是无用的框。

附加练习:计算 SSD300 中有效默认框的数量。

待续

我们仍然没有讨论如何将这些默认框映射回输入图像中的实际位置,如何挑选与地面事实相匹配的正确默认框,以及如何构造损失函数来训练网络。这些问题将在下一篇文章中讨论。

(2017/07/28 更新:以下是该系列第二部的和第三部的链接。)

(2018/07/12 更新:有人私下问了我一个有趣的问题。在此人的允许下,该问答被转贴于此:

问:我试图阅读纸质 VGG-16 和固态硬盘,到处都提到固态硬盘使用 VGG-16 架构,但原始纸张中的固态硬盘架构图像从尺寸(38x38x512)开始,但 VGG-16 架构中唯一可用的尺寸是(224x224x64)、(112x112x128)、(56x56x256)等等,但没有它的(38 X 38 X 512)。

答:注意 VGG16 的(官方)输入图像尺寸是 224,SSD 的是 300。对于 224,特征映射如你所说演化为(224,224,64),(112,112,128),(56,56,256)和(28,28,512)。但如果将(300,300,3)图像输入放入 VGG16 架构。特征映射演变为(300,300,64),(150,150,128),(75,75,256),(38,38,512)。)

[学习笔记]带 Pytorch 的单次多盒检测器—第 2 部分

原文:https://towardsdatascience.com/learning-note-single-shot-multibox-detector-with-pytorch-part-2-dd96bdf4f434?source=collection_archive---------1-----------------------

平铺和匹配策略

在上一篇中,我们讨论了 SSD 的网络结构和预测方案。现在,我们继续将默认框和基本事实结合起来,这样就可以确定预测的质量(并通过训练进行改进)。

(提醒:本文使用的 SSD 纸py torch 实现

将默认框映射到输入图像上的坐标

data/config.py 中预先计算并硬编码了每个特征映射的默认框的参数:

#SSD300 CONFIGS                      
# newer version: use additional conv11_2 layer as last layer before multibox layers                       
v2 = {                           
    'feature_maps' : [38, 19, 10, 5, 3, 1],
    'min_dim' : 300,                                                    
    'steps' : [8, 16, 32, 64, 100, 300],                                                   
    'min_sizes' : [30, 60, 111, 162, 213, 264],                                                   
    'max_sizes' : [60, 111, 162, 213, 264, 315],                                                   
    'aspect_ratios' : [[2], [2, 3], [2, 3], [2, 3], [2], [2]],                                                   
    'variance' : [0.1, 0.2],                                                   
    'clip' : True,                                                   
    'name' : 'v2',                       
}

实际的映射发生在层/函数/prior_box.py (P.S .默认框在实现中称为 prior boxed):

from itertools import product as productclass PriorBox(object):
    def __init__(self, cfg):
        super(PriorBox, self).__init__()
        # self.type = cfg.name
        self.image_size = cfg['min_dim']
        self.variance = cfg['variance'] or [0.1] […] for v in self.variance:
            if v <= 0:
                raise ValueError(
                    'Variances must be greater than 0') def forward(self):
        mean = []
        if self.version == 'v2':
            for k, f in enumerate(self.feature_maps):
                for i, j in product(range(f), repeat=2):
                    f_k = self.image_size / self.steps[k]
                    # unit center x,y
                    cx = (j + 0.5) / f_k
                    cy = (i + 0.5) / f_k # aspect_ratio: 1
                    # rel size: min_size
                    s_k = self.min_sizes[k]/self.image_size
                    mean += [cx, cy, s_k, s_k] # aspect_ratio: 1
                    # rel size: sqrt(s_k * s_(k+1))
                    s_k_prime = sqrt(
                        s_k * (self.max_sizes[k]/self.image_size))
                    mean += [cx, cy, s_k_prime, s_k_prime] # rest of aspect ratios
                    for ar in self.aspect_ratios[k]:
                        mean += [
                            cx, cy, s_k*sqrt(ar), s_k/sqrt(ar)]
                        mean += [
                            cx, cy, s_k/sqrt(ar), s_k*sqrt(ar)]

        […]        # back to torch land
        output = torch.Tensor(mean).view(-1, 4)
        if self.clip:
            output.clamp_(max=1, min=0)
        return output

Layout of the four default boxes (from original paper)

(ITER tools . product创建输入可迭代对象的笛卡尔积。所以 product(range(4),repeat=2)得出(0,1,2,3)和(0,1,2,3)之间的所有组合,即(0,0),(0,1) …,(3,2),(3,3)。)

以第一张特征图(38x38)为例。f_k=300/8=37.5i+0.5j+0.5的范围从 0.537.5 。所以中心点坐标 cxcy 转化为(0.0133,0.0133),(0.0133,0.04) …,(1,0.9733),(1,1)。请注意,代码将坐标归一化为(0,1),并且记住大多数特征图都是零填充的(最外面的单元总是零)。可以自己验证一下倒数第二个(未填充)要素图中最外面的中心点离 0 和 1 有一点距离。并且最后的特征图只有一个中心点正好位于(0.5,0.5)。

现在我们有了每个默认框的中心点。接下来我们要计算宽度和高度。有六种默认的方框布局:

  1. 尺寸 (s_k,s_k) 的小方块
  2. 大小为 (sqrt(s_k * s_(k+1))、sqrt(s_k * s_(k+1))) 的大正方形
  3. 尺寸为 1:2 的矩形 (s_k * 0.7071,s_k * 1.414)
  4. 2:1 矩形尺寸 (s_k * 1.414,s_k * 0.7071)
  5. 尺寸为 (s_k * 0.5774,s_k * 1.7321) 的 1:3 矩形
  6. 3:1 大小的矩形 (s_k * 1.7321,s_k * 0.5774)

对于具有 4 个默认框的要素地图,仅使用前四种布局。矩形的面积与小正方形的面积相同。这和上图不一样,上图面积好像和大正方形一样。

s_k 来自以下公式,第一个特征图除外:

Formula (4) from the original paper

默认框实际上是根据经验设计的,如论文中所述:

在实践中,还可以设计默认框的分布,以最适合特定的数据集。如何设计最优的镶嵌也是一个公开的问题。

因此,您可以根据自己的需要自由修改 prior_box.py

找到最符合实际情况的默认框

这就是所谓的“文中匹配策略”。这个想法非常简单——如果任何一对基础真值框和默认框的 Jaccard overlap 大于一个阈值(0.5),那么它们就被认为是匹配的。在(希望)简单的英语中,如果重叠区域大于两个盒子覆盖区域的一半,这就是匹配。

The intersection need to be larger than half of the union. (Image from Wikipedia)

相关代码位于 layers/box_utils.py :

def intersect(box_a, box_b):
    """ We resize both tensors to [A,B,2] without new malloc:
    [A,2] -> [A,1,2] -> [A,B,2]
    [B,2] -> [1,B,2] -> [A,B,2]
    Then we compute the area of intersect between box_a and box_b.
    Args:
      box_a: (tensor) bounding boxes, Shape: [A,4].
      box_b: (tensor) bounding boxes, Shape: [B,4].
    Return:
      (tensor) intersection area, Shape: [A,B].
    """
    A = box_a.size(0)
    B = box_b.size(0)
    max_xy = torch.min(box_a[:, 2:].unsqueeze(1).expand(A, B, 2),
                       box_b[:, 2:].unsqueeze(0).expand(A, B, 2))
    min_xy = torch.max(box_a[:, :2].unsqueeze(1).expand(A, B, 2),
                       box_b[:, :2].unsqueeze(0).expand(A, B, 2))
    inter = torch.clamp((max_xy - min_xy), min=0)
    return inter[:, :, 0] * inter[:, :, 1]

(tensor . unsqueeze在指定位置插入一个尺寸为 1 的新尺寸。应该相当于numpy . expand _ dimstensor . expand以记忆高效的方式扩展大小 1 维。当组合 时,它们在功能上等同于张量。重复 ,但是 张量。重复 创建一个新的张量。)

( )张量钳位 限制一个张量的最大值和最小值。应该相当于numpy . clip。)

作者巧妙的计算了交集。通过展开张量,我们现在能够在没有任何 for 循环的情况下,在一次运行中计算 box_a(基本事实)和 box_b(默认盒子)的每个组合的交集。

def jaccard(box_a, box_b):
    """Compute the jaccard overlap of two sets of boxes.  
       The jaccard overlap is simply the intersection over 
       union of two boxes.  Here we operate on ground truth 
       boxes and default boxes.
       E.g.:
          A ∩ B / A ∪ B = A ∩ B / (area(A) + area(B) - A ∩ B)
       Args:
          box_a: (tensor) Ground truth bounding boxes, 
                 Shape:    [num_objects,4]
          box_b: (tensor) Prior boxes from priorbox layers, 
                 Shape: [num_priors,4]
       Return:
          jaccard overlap: (tensor) 
                           Shape: [box_a.size(0), box_b.size(0)]
    """
    inter = intersect(box_a, box_b)
    area_a = ((box_a[:, 2] - box_a[:, 0]) *
              (box_a[:, 3] - 
               box_a[:, 1])).unsqueeze(1).expand_as(inter)
    area_b = ((box_b[:, 2] - box_b[:, 0]) *
              (box_b[:, 3] - 
               box_b[:, 1])).unsqueeze(0).expand_as(inter)  
    union = area_a + area_b - inter
    return inter / union  # [A,B]

在这里,作者使用同样的技巧来计算每个盒子的面积,然后得到并集。

def match(threshold, truths, priors, variances, 
          labels, loc_t, conf_t, idx):
    """Match each prior box with the ground truth box of 
       the highest jaccard overlap, encode the bounding boxes,
       then return the matched indices corresponding to both 
       confidence and location preds.

       Args:
         threshold: (float) The overlap threshold 
                    used when mathing boxes.
         truths: (tensor) Ground truth boxes, 
                 Shape: [num_obj, num_priors].
         priors: (tensor) Prior boxes from priorbox layers, 
                 Shape: [n_priors,4].
         variances: (tensor) Variances corresponding 
                    to each prior coord,
                    Shape: [num_priors, 4].
         labels: (tensor) All the class labels for the image,
                 Shape: [num_obj].
         loc_t: (tensor) Tensor to be filled w/ endcoded 
                location targets.
         conf_t: (tensor) Tensor to be filled w/ matched 
                 indices for conf preds.
         idx: (int) current batch index
       Return:
         The matched indices corresponding to 
         1)location and 2)confidence preds.
    """
    # jaccard index
    overlaps = jaccard(
        truths,
        point_form(priors)
    )
    # (Bipartite Matching)
    # [num_objects, 1] best prior for each ground truth
    best_prior_overlap, best_prior_idx = overlaps.max(1)
    # [1, num_priors] best ground truth for each prior
    best_truth_overlap, best_truth_idx = overlaps.max(0)
    best_truth_idx.squeeze_(0)
    best_truth_overlap.squeeze_(0)
    best_prior_idx.squeeze_(1)
    best_prior_overlap.squeeze_(1)
    # ensure best prior    
    best_truth_overlap.index_fill_(0, best_prior_idx, 2)     
    for j in range(best_prior_idx.size(0)):
        best_truth_idx[best_prior_idx[j]] = j
    # Shape: [num_priors,4]
    matches = truths[best_truth_idx] 
    # Shape: [num_priors]         
    conf = labels[best_truth_idx] + 1
    # label as background
    conf[best_truth_overlap < threshold] = 0  
    loc = encode(matches, priors, variances)
    # [num_priors,4] encoded offsets to learn
    loc_t[idx] = loc    
    # [num_priors] top class label for each prior
    conf_t[idx] = conf

(tensor . max和 Tensor.min 在传递一个 *dim* 参数时返回两个张量:1。沿指定轴的实际最大/最小值。2.沿该轴的最大/最小值的索引)

(Tensor.squeeze _是 tensor . squeeze 的就地版本,返回一个去掉了所有尺寸为 1 的维度的张量。)

(tensor . index _ fill _用传递的索引值填充原始张量的元素)

还记得我们从那里得到的 prior_box.py 是(cx,cy,w,h)格式吗?这里我们用point_from将其转换成(xmin,ymin,xmax,ymax)格式。为了节省空间,代码没有公布(在这里找到)。

这部分代码可能是最令人困惑的:

# ensure best prior    
best_truth_overlap.index_fill_(0, best_prior_idx, 2)     
for j in range(best_prior_idx.size(0)):
    best_truth_idx[best_prior_idx[j]] = j

张量best _ prior _ idx包含每个基础事实框的最佳匹配默认框的索引。所以第一行代码要做的是确保每个基本事实框至少有一个默认框通过了阈值。

for 循环将变化从第一行传播回张量 best_truth_idx ,,该张量包含每个默认框的最佳匹配基础真值框的索引。这种循环的效果是,当存在更需要它的另一个基本事实时,迫使先前的框放弃原始的最佳匹配基本事实(否则没有用于该基本事实的默认框)。

请注意,我们将每个默认框与一个真实背景相匹配,并为所有最大 Jaccard 重叠小于阈值(即背景)的默认框分配一个特殊的标签/类别零

有一个encode函数将匹配的真实和默认框对转换成损失函数理解的格式。损失函数将在下一篇文章中讨论。

待续

我们讨论了如何将缺省框映射到实际坐标,以及如何匹配基础真值框和缺省框。这比我预期的要长,所以将会有第 3 部分讨论目标函数,最后是如何在测试阶段预测/检测。

(2017/07/28 更新:这里是该系列第三部的链接)

[学习笔记]带 Pytorch 的单次多盒检测器—第 3 部分

原文:https://towardsdatascience.com/learning-note-single-shot-multibox-detector-with-pytorch-part-3-f0711caa65ad?source=collection_archive---------3-----------------------

训练目标和推理

(提醒:本文使用的 SSD 论文py torch 实现。还有,第系列的第一和第系列的第二部分。)

训练目标/损失函数

每个深度学习/神经网络都需要一个可微分的目标函数来学习。在将基础事实和默认框配对,并将剩余的默认框标记为背景之后,我们准备好制定 SSD 的目标函数:

Overall Objective — Formula (1) from the original paper

这个目标函数有两个部分:

  1. 置信度损失:模型预测每个对象的类别有多准确
  2. 局部化损失:模型创建的边界框离地面真实框有多近。

信心丧失

Confidence Loss — formula (3) from the original paper

这是实际标签和预测标签之间的简单的 softmax 损失函数。当第 i 个默认框与第 j 个类别 p 的第 1 匹配时。注意,有一个特殊的类别对应于背景框(没有地面真相匹配)。背景框被视为 ,并且如我们稍后将看到的,被下采样以避免高度不平衡的训练数据集。

本地化损失

Localization Loss— Formula (2) from the original paper

Smooth L1 loss function from Fast R-CNN paper

定位损失仅在 盒上计算(具有匹配接地真值的盒)。它计算相对于中心点坐标的正确偏移和预测偏移之间的差异,以及相对于宽度和高度的正确比例和预测比例。消除绝对差异。

偏移和比例的差异根据默认框的宽度和高度进行归一化,并且比例在进行差异计算之前进行对数缩放。

代码

来自层/模块/multibox_loss.py :

def forward(self, predictions, targets):
    """Multibox Loss
       Args:
         predictions (tuple): A tuple containing loc 
                              preds, conf preds,
                              and prior boxes from SSD net.
           conf shape:
               torch.size(batch_size,num_priors,num_classes)
           loc shape: torch.size(batch_size,num_priors,4)
               priors shape: torch.size(num_priors,4) ground_truth (tensor): Ground truth boxes and 
                                labels for a batch,
             shape: [batch_size,num_objs,5] 
                    (last idx is the label).
    """
    loc_data, conf_data, priors = predictions
    num = loc_data.size(0)
    priors = priors[:loc_data.size(1), :]
    num_priors = (priors.size(0))
    num_classes = self.num_classes # match priors (default boxes) and ground truth boxes
    loc_t = torch.Tensor(num, num_priors, 4)
    conf_t = torch.LongTensor(num, num_priors)
    for idx in range(num):
        truths = targets[idx][:,:-1].data
        labels = targets[idx][:,-1].data
        defaults = priors.data
        match(self.threshold,truths,defaults,
              self.variance,labels,loc_t,conf_t,idx)
    if self.use_gpu:
        loc_t = loc_t.cuda()
        conf_t = conf_t.cuda()
    # wrap targets
    loc_t = Variable(loc_t, requires_grad=False)
    conf_t = Variable(conf_t,requires_grad=False) pos = conf_t > 0
    num_pos = pos.sum() # Localization Loss (Smooth L1)
    # Shape: [batch,num_priors,4]
    pos_idx = pos.unsqueeze(pos.dim()).expand_as(loc_data)
    loc_p = loc_data[pos_idx].view(-1,4)
    loc_t = loc_t[pos_idx].view(-1,4)
    loss_l = F.smooth_l1_loss(loc_p, loc_t, size_average=False) # Compute max conf across batch for hard negative mining
    batch_conf = conf_data.view(-1,self.num_classes)
    loss_c = log_sum_exp(batch_conf) - batch_conf.gather(
                 1,   conf_t.view(-1,1)) # Hard Negative Mining
    loss_c[pos] = 0 # filter out pos boxes for now
    loss_c = loss_c.view(num, -1)
    _,loss_idx = loss_c.sort(1, descending=True)
    _,idx_rank = loss_idx.sort(1)
    num_pos = pos.long().sum(1)
    num_neg = torch.clamp(
        self.negpos_ratio*num_pos, max=pos.size(1)-1)
    neg = idx_rank < num_neg.expand_as(idx_rank) # Confidence Loss Including Positive and Negative Examples
    pos_idx = pos.unsqueeze(2).expand_as(conf_data)
    neg_idx = neg.unsqueeze(2).expand_as(conf_data)
    conf_p =  conf_data[
       (pos_idx+neg_idx).gt(0)].view(-1,self.num_classes)
    targets_weighted = conf_t[(pos+neg).gt(0)]
    loss_c = F.cross_entropy(
        conf_p, targets_weighted, size_average=False) # Sum of losses: L(x,c,l,g) = (Lconf(x, c) + αLloc(x,l,g)) / N
    N = num_pos.data.sum()
    loss_l/=N
    loss_c/=N
    return loss_l,loss_c

挺长的,我们来分解一下:

# match priors (default boxes) and ground truth boxes
loc_t = torch.Tensor(num, num_priors, 4)
conf_t = torch.LongTensor(num, num_priors)
for idx in range(num):
    truths = targets[idx][:,:-1].data
    labels = targets[idx][:,-1].data
    defaults = priors.data
    match(self.threshold,truths,defaults,
          self.variance,labels,loc_t,conf_t,idx)
[...]
# wrap targets
loc_t = Variable(loc_t, requires_grad=False)
conf_t = Variable(conf_t,requires_grad=False)

num对应批量大小。idx参数被传递给match()以让match知道要写哪一行。

(设置 requires_grad=False 表示我们不需要在反向过程中计算这些变量的梯度。) 参考

*pos = conf_t > 0
num_pos = pos.sum()# Localization Loss (Smooth L1)
# Shape: [batch,num_priors,4]
pos_idx = pos.unsqueeze(pos.dim()).expand_as(loc_data)
loc_p = loc_data[pos_idx].view(-1,4)
loc_t = loc_t[pos_idx].view(-1,4)
loss_l = F.smooth_l1_loss(loc_p, loc_t, size_average=False)*

(tensor . view等价于numpy . shape,返回一个数据相同但大小不同的新张量。Tensor.view_as 的工作方式相同,但会自动将目标形状设置为传递的张量的形状。)

这部分计算本地化损失。

记住类标签 0 对应背景(负框),我们可以用> 0找到正框。pos扩展为(num,num_priors,4)用于选择阳性框。.view(-1, 4)做的是将张量从(num,num_priors,4)展平到(num * num_priors,4)。F出自import torch.nn.functional as F

*# Compute max conf across batch for hard negative mining
batch_conf = conf_data.view(-1,self.num_classes)
loss_c = log_sum_exp(batch_conf) - batch_conf.gather(
                 1, conf_t.view(-1,1))# Hard Negative Mining
loss_c[pos] = 0 # filter out pos boxes for now
loss_c = loss_c.view(num, -1)
_, loss_idx = loss_c.sort(1, descending=True)
_, idx_rank = loss_idx.sort(1)
num_pos = pos.long().sum(1)
num_neg = torch.clamp(
    self.negpos_ratio*num_pos, max=pos.size(1)-1)
neg = idx_rank < num_neg.expand_as(idx_rank)*

(tensor . gather沿 dim 指定的轴收集值。)

(tensor . sort类似于 Tensor.min 和 Tensor.max,它返回两个张量:1。已排序的值。2.排序值的原始索引)

对于置信损失 SSD 使用一种称为 硬负挖掘 的技术,即选择最困难的负框(它们具有更高的置信损失),因此负对正比率最多为 3:1。

log_sum_exp来自 layers/box_utils.py 。它计算log(c)的分母部分。batch_conf.gather计算分子部分,其中只有真实标签的预测概率是重要的。

该代码使用两种排序来查找每个盒子的等级。首先获取排序索引,然后获取排序索引的排序索引作为秩。num_negnum_priors — 1夹住,看起来怪怪的。实际的负数num_prior — num_pos似乎更合理。

*# Confidence Loss Including Positive and Negative Examples
pos_idx = pos.unsqueeze(2).expand_as(conf_data)
neg_idx = neg.unsqueeze(2).expand_as(conf_data)
conf_p =  conf_data[
      (pos_idx+neg_idx).gt(0)].view(-1,self.num_classes)
targets_weighted = conf_t[(pos+neg).gt(0)]
loss_c = F.cross_entropy(
          conf_p, targets_weighted, size_average=False)*

这部分应该很简单。收集预测和真实标签,然后传递给 cross_entropy 函数,得到总损失(还没有平均)。

*# Sum of losses: L(x,c,l,g) = (Lconf(x, c) + αLloc(x,l,g)) / N
N = num_pos.data.sum()
loss_l /= N
loss_c /= N
return loss_l, loss_c*

最后,计算两次损失的平均值,然后返还。现在我们有了训练网络所需的一切。

推理

训练完网络后,是时候使用我们的检测器了。SSD 设计的一个特殊问题是,如果超过阈值,我们可以将多个默认框匹配到一个真实框。因此,在预测时,我们可能会预测一个对象周围的多个高度重叠的框。这通常不是目标检测算法的期望输出。我们需要做一些后期处理。

SSD 使用的技术被称为非最大抑制(nms) 。基本思想是迭代地将最有把握的盒子添加到最终输出中。如果候选框与最终输出中同类的任何框高度重叠(Jaccard 重叠高于 0.45),则该框将被忽略。它还将每个图像的总预测盒数限制在 200 个。

实现(nms 函数)位于 layers/box_utils.py 。它有一些新的东西,如 Tensor.numeltorch.index_selectout 参数。但是您现在应该对工作流程相当熟悉了,所以我不会在这里详细分析代码。

谢谢大家!

就是这样!非常感谢您通读整个系列。有段时间没写过这么长的学习笔记/教程了,再来一遍感觉棒极了!

这个系列的目的真的是强迫自己钻到乱七八糟的细节里去,去理解到底是怎么回事。如果能对你有所帮助,我会很高兴。另外,如果我做错了什么或者错过了什么重要的事情,请随时告诉我。

[学习笔记]用于多标签文本分类的 StarSpace

原文:https://towardsdatascience.com/learning-note-starspace-for-multi-label-text-classification-81de0e8fca53?source=collection_archive---------1-----------------------

StarSpace 是一个雄心勃勃的模型,试图解决一系列与实体嵌入相关的问题。它由脸书人工智能研究所(FAIR)创建并开源。我还没有在论文中读到模型的细节,但是很容易假设它扩展了 FAIR 之前的文本嵌入库 fastText 。StarSpace 旨在成为一个直接有效的强基线,也就是说,你为新数据集或新问题训练的第一个模型。

在这篇文章中,我将写下我是如何(试图)让 StarSpace 处理来自 Kaggle 的有毒评论分类挑战的数据集的。该数据集表示多标签文本分类问题,即,可以将多个标签分配给单个评论。由于 fastText 不完全支持多标签分类,我认为 StarSpace 可能是一个不错的选择。

剧透/TL;博士;医生

我发现 StarSpace 在当前状态下存在两个主要问题,使其无法作为该数据集的基线:

  1. 没有predict命令:目前只提供test,给出描述性的模型评估。额外的工作需要你自己完成,以获得每个评论的标签概率的清晰输出。
  2. 评估度量是不可定制的:由于缺乏清晰的预测输出,我们依赖于来自test命令的模型评估。但是我看不出有什么方法可以让它显示我们关心的这个数据集的列级平均日志损失。

另外,StarSpace 的文档也不是很全面。这也是为什么我会写这篇文章的原因。

安装 StarSpace

Starspace 是用 C++写的,要自己搭建。在我的 Linux Mint 18.3 环境中,这非常简单。只需克隆 Git repo 并运行make:

git clone https://github.com/facebookresearch/Starspace.git
cd Starspace
make

将编译好的可执行文件starspace复制到你的路径中的某个地方(我个人使用~/bin/

在其他环境中,你可能需要跳过额外的关卡来满足需求。请查看链接以获取进一步的说明。

Python 环境

  • Python 3.6
  • pandas 0.22.0,joblib 0.11,tqdm 4.19.5(使用了非常基础的 API,所以确切的版本应该无关紧要。如果你遇到任何问题,请在这篇文章发表后检查是否有任何重大更新。)
  • 空间 2.0.5
  • sci kit-学习 0.19.1

准备数据集

不言而喻,您需要首先将数据集下载到您的计算机上。我通常将数据集放在项目根目录下的data子文件夹中,并将从原始数据集派生的所有内容放在cache子文件夹中。我们将在下面使用相同的设置。

下一步是清理和标记注释。在这里,我使用了来自 spacy,的英文分词器,删除换行符和一些其他标点符号,并将注释精简到 20,000 个字符。(清洗方案通常依赖于数据集。对于这个数据集,肯定有比这篇文章中简单的方案更好的方案。例如,你可以过滤掉停用词。)

在注释被标记化之后,我们将这些标记与它们相关联的标签结合起来,并以 StarSpace 可以识别的格式保存它们(这里我们使用 fastText 格式)。

我们使用 25%的训练数据集作为验证。结果分别保存到cache/train.txtcache/val.txt。注意因为我还没有找到一种容易提取预测的方法,所以这里不处理测试数据集。

快速文本格式非常简单。在连续的标记之间放置一个空格,每行一个注释/实例,并在末尾放置标签。标签用数字编码,并为无毒的评论创建一个虚拟标签(StarSpace 不接受空标签列表)。

例如,这是训练数据集中的第一条注释:

22256635,"Nonsense?  kiss off, geek. what I said is true.  I'll have your account terminated.",1,0,0,0,0,0

处理后,它变成:

Nonsense ? kiss off , geek . what I said is true . I 'll have your account terminated . __label__0

训练和评估模型

要训练模型,请在命令行中运行以下命令:

starspace train -ngrams 2 -minCount 10 -thread 4 -trainFile cache/train.txt -model cache/starspace.model

该模型使用 unigram 和 bigram,要求一个令牌至少出现 10 次才被考虑,并使用 4 个线程。更多参数可通过starspace -h找到。

StarSpace 将模型保存到cache/starspace.model,将文字嵌入和标签嵌入向量保存到cache/starspace.model.tsv。您可以分析或可视化这些嵌入向量,以获得进一步的见解。

要使用验证数据集评估模型,请运行以下命令:

starspace test -testFile cache/val.txt -model cache/starspace.model -predictionFile cache/starspace.pred

除了命令行输出之外,它还将逐例评估写入cache/starspace.pred。一个例子:

Example 68:
LHS:
IT 'S HER QUOTE . WHAT CAN'T YOU UNDERSTAND ? Here is the official press release Now , please , can we stop this nonsense ? 
RHS: 
__label__0 
Predictions: 
(--) [0.542934] __label__6 
(--) [0.055087] __label__4 
(--) [0.0467122]        __label__2 
(++) [-0.0127831]       __label__0 
(--) [-0.23463] __label__1

另一个例子:

Example 116:
LHS:
STOP , you had better stop putting all that stupid junk on my IP page . read it . you 'll see what i 'll do if you do it again . 
RHS: 
__label__0 
Predictions: 
(++) [0.529969] __label__0 
(--) [0.416814] __label__2 
(--) [0.388696] __label__4 
(--) [0.34913]  __label__3 
(--) [0.240833] __label__1

注意,数据集中的大多数评论都是没有毒性的( __label__6 ),所以我在这里真的是精挑细选了一些例子。

分配给每个标签的值的含义不清楚。我想答案可以在报纸上找到。

包扎

不幸的是,StarSpace 还没有准备好作为有毒评论数据集的基线。这篇文章尽我们所能记录了所需的步骤,以供将来参考。希望星际空间将继续发展,并真正为生产做好准备。我们会回来买更多的。

空腹学习:加州奥兰治县学校免费餐计划的数据研究

原文:https://towardsdatascience.com/learning-on-an-empty-stomach-data-study-on-school-free-meal-programs-in-orange-county-california-bd61c6ea3db3?source=collection_archive---------9-----------------------

夹在洛杉矶和圣地亚哥县之间的加利福尼亚州奥兰治县,可能是以美丽的海滩、职业运动队和几个电视节目的所在地而闻名。作为一个终身居民,很容易看到某些迷人的看法可能会推广到整个县,但整个画面远远超出了电视上看到的。

老实说,我是带着一种扭曲的世界观长大的,我的整个童年都是在尔湾度过的,那里被联邦调查局称为美国最安全的大城市,也被当地人称为泡沫。直到我在加州大学富勒顿分校上大学期间,开始在各种学校、施粥场和无家可归者收容所做志愿者,我的观点才发生转变。在此期间,我在大学附近的多所小学做志愿者。离我崭新的、最先进的商学院仅一英里的地方是一所小学,学生们在教室里上课,教室里没有空调,地板是泥土的,而不是地毯。我志愿参加的大多数教室几乎都有每个学生参加免费早餐计划,低收入家庭的学生排队领取他们早上分配的水果、蔬菜和牛奶(装在塑料袋里,必须用吸管戳)。这不是我从小到大习惯的事情,但很明显这是这里的例行公事,几个孩子贪婪地吃着他们的食物,好像他们从前一天就没有吃过东西。

这些经历与我自己的小学经历大相径庭。由于我在我访问过的少数几所学校中看到了如此巨大的差异,我想看看一些数据,看看所有 OC 学校的小学经历有多大的差异。在这份报告中,我把重点放在有资格享受免费餐计划的学生的百分比(T2)上作为我的变量,因为学生的资格是由他们家庭相对于贫困线的收入决定的。

为了设置场景,让我们来看看奥兰治县与加州其他县相比的情况:

在 58 个加州县中,奥兰治县公立学校学生享受免费餐的比例排在倒数第 18 位(仍为 39.9%)。虽然奥兰治县公立学校有资格享受免费餐的学生比例低于平均水平,但 OC 各学区之间的标准偏差很高(见下文)。

当查看每个加州县的标准偏差时,每个县的个别学校之间的免费餐计划合格比率的可变性,奥兰治县的可变性是显而易见的。奥兰治县的标准差为 28.8%,是加州所有县中标准差第二高的县。关于标准差,奥兰治县夹在阿拉米达县和康特拉科斯塔县之间,这两个县都是硅谷北部的相邻县。

看一下上面的图,其中三角形代表每个县的每个公立学校区,您可以看到 Orange County 在中线(两个蓝色阴影框之间的黑线)和第 75 百分位标记(由浅蓝色框右侧的黑线表示)之间存在明显的差距。当你看看其他人口稠密的地区,如洛杉矶和圣地亚哥,学校在整个范围内的分布相对均匀,不像奥兰治县。对于奥兰治县学区来说,对免费餐的依赖程度高和低的学区之间,几乎就像有一条想象中的边界。

泡沫的大小:学生注册的规模

泡泡的颜色:橙色越深=有资格享受免费餐的学生比例越高

列出的百分比:有资格享受免费餐的学生百分比

在 OC 最大的学区中,圣安娜拥有压倒性的高比率,80.3%的学生有资格享受免费餐。另一方面,右下方可以看到我的家乡尔湾市的失业率非常低,只有 10.3%。

这张图表显示,即使是最富裕的地区也有高度依赖免费和优惠膳食计划的学校。查看上图中的圆点,它们代表每个 OC 学区中有资格享受免费餐的学生比例最高的学校,您会发现圣安娜统一学校是享受免费餐计划的公立学校比例最高的学区(95.8%)。然而,最高值仅次于最高值的地区是 Placentia-yor ba Linda Unified(89.4%),Capistrano Unified (87.9%)紧随其后,位居第四。Placentia-Yorba Linda 和 Capistrano 的一些学校最依赖免费餐计划,尽管整个地区符合条件的学生比例中位数分别排名第 9 和第 6。这两个城市都是相对富裕的地区,约巴林达的家庭收入中值为 117,855 美元,T2 最近的一项研究将它列为全国第六富裕的城市,然而它仍然有一所对免费餐计划依赖程度最高的学校。

这个问题也没有减少,看看每个 OC 学区,自 2012 年以来,免费餐有了大量增加。正如你在上面看到的,许多 OC 学区看到有资格享受免费餐的学生增加了,一些学区看到超过 75%的学校注册了免费餐资格的增加。

在研究和撰写这篇文章后,我的主要收获是,即使在一些看起来最迷人的地区,也有许多人需要帮助。任何地区都不能被忽视。这是我第一篇关于食品不稳定和贫困的数据文章,但我计划写更多。如果你有任何意见,额外的数据,或者想要合作,请随时联系我。这里有一份对抗饥饿的顶级慈善机构名单(我目前通过第二丰收食物银行橘子郡志愿参与“供养美国”)。

感谢您阅读我最新的数据帖子。作为一名产品营销和数据分析专业人士,我对数据支持的讲故事充满热情。这些数据新闻帖子是我将真实数据与我个人的不同兴趣整合起来的方式,这些兴趣包括从旅行和娱乐到经济和社会问题的任何事情。
如果您有任何评论、故事想法或预期的数据项目,请随时发送电子邮件至 dwpwriting <至> gmail < dot > com 或通过
LinkedIn 联系我。

为什么以及如何开展数据科学学习项目

原文:https://towardsdatascience.com/learning-projects-e831fa94f09f?source=collection_archive---------9-----------------------

Stefan Steinbauer on Unsplash

有很多关于如何创建项目以建立数据科学组合的博客帖子。我推荐迈克尔·加拉尼克这首康纳·杜威的这首。不幸的是,这种方法现在对我不起作用,因为我的日常工作非常耗时。我需要根据不断变化的需求,在更小的副主题上更快地迭代。

我测试了许多不同的方法来实现这一点。我完成了几个 Udacity 纳米学位,完成了 Coursera 和 Udemy 的课程,参加了网络研讨会,读了一堆 O'Reilly 的书。需要明确的是:所有这些资源都可以为您提供支持,具体取决于您在数据科学之旅中的位置。然而,对我来说最有效的是学习项目。

学习项目是我为填补技能组合中的特定缺口而做的小型数据科学项目。它们不是为了给招聘人员或潜在雇主留下深刻印象。相反,他们为我提供了量身定制的挑战来提高我的能力。

在这篇博文中,我与你分享了我现在从想法选择到评估的过程。每次迭代之后,我都会不断地改进它,但是总的模式是成立的。我也给你一个我最近的学习项目作为一个切实的例子。

第一步:找到一个你关心的想法

学习项目的灵感到处都在等着。一位同事提到一个你不知道的概念。或者,你听播客,偶然发现一些东西。或者你第 1000 次谷歌某样东西,想把它记在脑子里。长话短说:想法是你的环境提供给你的,如果你有开放的心态

一旦你开始接触这些想法,你所需要的只是一个写下它们的地方。为此,我搭建了一个 Trello 板。我不认为有一个系统适合所有人,所以你可能需要做一些实验。但是,您的系统需要提供两件事情:

  1. 它必须随时可以被访问。
  2. 获得一个概述必须是简单的。

每当你有一个新的想法,添加一两句话作为一个新的项目来描述它。

当你准备好下一个项目时,检查你的清单。根据两个标准来标记想法:内在动机专业价值。如果你目前的工作需要掌握一些东西,那么这就是你的最高优先级。

这里有一点很重要:现在还不要考虑可行性或实际细节。总有办法调整一个想法。数据科学是创造解决方案,而不是过分强调问题。

我最近的一个学习项目开始于我路过一家电影院时,看到了最后的绝地的电影海报:

当我看着这张海报的风格时,我想知道这部系列电影的前几部给了它多少设计灵感。由于我是一名数据科学家,所以没过多久,我就决定训练一个 CNN 对一张电影海报的十年进行分类。

第二步:做一个快速的可行性检查

数据可用性是所有数据科学的瓶颈。学习项目在这里也不例外。当你决定了你的想法,检查通常的数据来源,看看是否有足够的数据可用。有三种可能的结果:

  1. 你需要的确切数据已经准备好了。如果是这样的话,对让它变得容易理解的人说声谢谢。享受这一刻。
  2. 您找到了与您需要的相似但不完全符合您想法的数据。在这种情况下,考虑一下你是否能在保持核心动机不变的情况下调整你的计划。
  3. 没有有用的数据源。一般来说,回到你的清单,选择另一个项目。不要删除你的想法。它可能会激发你新的想法,你可能会发现一个新的角度,或者新的数据可能会在某个时候变得可用。

就我而言,我已经知道 Kaggle 上的电影数据集,所以我开始在那里搜索。幸运的是,这个数据集包含了一段时间内成千上万部电影海报的链接。

第三步:明确你的学习目标

import pandas as pd等等很容易让人马上开始,但是等等!你有一个想法,你知道有数据可以解决它。但是,你确定你想从中带走什么吗?换句话说:退一步想想自己的学习目标。要不要在 Pytorch 建立自己的第一个神经网络?您想了解特定类型数据的缺陷吗?要不要测试一下不同种类的超参数优化(不要脸的自我推销)?

如果你的想法与许多不同的学习目标有关,那就专注于对你来说最重要的那一部分。我在攻读博士学位期间学到了一条规则:要么专注于一个新论点、一个新数据集,要么专注于一种新方法。太多的活动部件使得很难得出正确的结论。同样的道理也适用于学习项目。

我的电影海报项目的目标是测试我建立一个从图片输入到预测输出的基本管道有多容易。换句话说,我的主要目标是进行自我评估,找出我需要克服的弱点。

第四步:专注于你的学习目标

从现在开始,没有明确的指导方针。然而,记住你的学习目标。例如,当你想比较你的神经网络的两个不同的激活函数时(另一个无耻的自我推销,不要在数据探索上花太多时间。

实事求是地说:把必要的和关键的任务分开。尽可能做好前面的工作,但不要在这里研究或尝试新事物。相反,把你的大部分时间集中在后面的任务上。再说一次,学习项目并不意味着成为你的正式投资组合的一部分。他们的工作是推动你在学习曲线上走得更远。

例子:电影海报按年代分类

我的重点是建立一个基本的 CNN 管道,所以我没有花太多时间准备数据。相反,我删除了所有缺少值的行,而没有考虑是否有系统的原因。我还删除了所有具有非唯一链接的行,没有进一步检查。

从剩余的 24,812 部电影中,我选择了 800 部电影用于训练,200 部电影用于测试,这是从 20 世纪 50 年代开始的 60 年间的事情。随后,我写了一些代码,将相关的电影海报下载到traintest文件夹中,每个十年都有子文件夹。我意识到有些文件是空的,就额外写了代码删除 0 KB 的文件。完成这些步骤后,我的模型只剩下不到 800/200 个文件:

Images in train-folder:
00s: 788
50s: 768
60s: 754
70s: 771
80s: 760
90s: 779
Images in test-folder:
00s: 198
50s: 194
60s: 187
70s: 192
80s: 199
90s: 197

为了准备模型构建的文件,我使用了来自keras.preprocessing.imageImageDataGenerator及其flow_from_directory方法。要了解更多细节,请看维贾雅布哈斯卡尔 J的这篇优秀的博客文章或 Keras 博客上的一个例子

接下来,我用 Tensorflow 后端在 Keras 构建了一个标准的 CNN 架构。唯一的变化是我使用了 SELUs 作为激活函数,而不是 ReLUs 来反映我当前的知识。

然后,我花足够的时间进行微调,以获得大约 44%的验证准确率:

Epoch 1/7
145/144 [==============================] - 134s - loss: 2.6112 - acc: 0.2073 - val_loss: 2.3751 - val_acc: 0.2202
Epoch 2/7
145/144 [==============================] - 127s - loss: 1.6243 - acc: 0.3422 - val_loss: 1.6827 - val_acc: 0.3393
Epoch 3/7
145/144 [==============================] - 126s - loss: 1.2459 - acc: 0.5397 - val_loss: 1.8159 - val_acc: 0.3102
Epoch 4/7
145/144 [==============================] - 125s - loss: 0.8281 - acc: 0.7190 - val_loss: 1.7473 - val_acc: 0.4087
Epoch 5/7
145/144 [==============================] - 125s - loss: 0.4775 - acc: 0.8527 - val_loss: 2.0787 - val_acc: 0.4233
Epoch 6/7
145/144 [==============================] - 127s - loss: 0.2678 - acc: 0.9153 - val_loss: 2.6315 - val_acc: 0.4105
Epoch 7/7
145/144 [==============================] - 129s - loss: 0.1877 - acc: 0.9412 - val_loss: 2.7076 - val_acc: 0.4430

这个模型将上面的海报归类为 100%来自 60 年代。

这是一个非常简短的总结,但我相信您已经看到了为什么这不是一个包含在数据科学产品组合中的好选择的许多原因。同样,这不是学习项目的目的!我实现了我的学习目标,因为我意识到了这样一个管道的哪些部分是我最需要做的(图像预处理和生成器方法)。现在我可以开始另一个学习项目,这个项目是为在下一次迭代中解决这些弱点而定制的。

你完成了一个学习项目——现在呢?

首先恭喜自己!您进一步拓展了数据科学知识的范围。更重要的是,你培养了一种不断学习和成长的态度。

第二,确保充分利用你的工作:

  1. 写下你可以毫无困难地做的事情。它将帮助你评估你现在作为一名数据科学家的地位。它也显示了当你开始时,你已经从后面走了多远。
  2. 在追求你的学习目标的同时,写下你学到的东西。你买了多少?你应用的核心概念和技能是什么?特别注意你完成了多少学习目标,以及它是否符合你的期望。调整你即将到来的项目。
  3. 写下你在这个学习项目中注意到的弱点。它将帮助你决定哪个想法是下一个学习项目的最佳选择。
  4. 重复。

你的学习方法是什么?请在评论和 Twitter 上告诉我什么对你有用,或者在LinkedIn上联系我。

感谢阅读!如果你喜欢这篇文章,留下一些吧👏🏻并在 LinkedIn 或 Twitter 上分享。再次感谢,让我们继续学习!

关于如何优化深度神经网络学习速率的初级读本

原文:https://towardsdatascience.com/learning-rate-a6e7b84f1658?source=collection_archive---------6-----------------------

Victoire Joncheray on Unsplash

训练深度神经网络时的一个主要挑战是平衡最终解决方案的质量和达到最终解决方案所需的训练时间。学习率是优化这种平衡的最重要的超参数。

你可以认为小学习率和大学习率具有不同的个性:

  • 小学习率谨慎。也就是说,它使网络缓慢而小心地调整。
  • 学习率大就是浮躁。也就是说,它调整得很快,但可能会超调。

当你做深度学习时,你想让网络同时快速而精确地学习。在这篇文章中,我向你展示了三种不同的选择,在谨慎和浮躁之间找到平衡:

  1. 决定一个既不太低也不太高的学习率,即找到最佳的折衷。
  2. 一旦你接近一个最佳解决方案,在训练期间从高到低调整学习速率以减慢速度。
  3. 在高学习率和低学习率之间摇摆,创造一个混合体。

这篇文章是作为一个引子,并不涵盖细节。如果你想了解更多,我推荐 Pavel Surmenok 的这篇文章:

[## 估计深度神经网络的最佳学习速率

学习率是用于训练深度神经网络的最重要的超参数之一。

towardsdatascience.com](/estimating-optimal-learning-rate-for-a-deep-neural-network-ce32f2556ce0)

选择 1:折衷——固定学习率

最基本的方法是坚持默认值,并希望最好的结果。

第一个选项的更好实现是测试各种可能的值。根据损失的变化,你可以选择更高或更低的学习率。目标是找到仍能减少损失的最快速度。

鉴于这种选择的简单性,固定的学习率会让你走得比你预期的更远。然而,还有更好的选择。

选项 2:顺序——随着时间的推移,学习率降低

第二种选择是以高学习速率开始,以利用速度优势,然后切换到低学习速率,以优化结果。有两种主要的变化。

首先,你可以根据损失函数的变化来调整学习速率。也就是说,每当损失函数停止改进时,你就降低学习速率以进一步优化。

第二,您可以应用更平滑的函数形式,并根据训练时间调整学习速率。也就是说,学习率的降低与损失函数没有直接关系。

与固定学习率相比,这两种方法及其变体都是改进,因为它们结合了小学习率和大学习率的优点。然而,还有更大的改进余地。

选项 3:混合式学习率——走走停停

主要的想法是,由快转慢非常有帮助,我们应该在训练中不止一次地这样做。还有两个额外的优势:

  1. 跳回到高学习率有助于避免局部最优。
  2. 高学习率在穿过损失函数的平坦区域时更快。

综上所述,第三种选择是将第二种选择重复几次。

但是我们没有优化算法吗?

是的,因为最先进的优化算法,如亚当根据训练过程改变每个人体重的学习率。如果你想更多地了解亚当,我推荐这篇博文:

[## 深度学习的 Adam 优化算法简介

你的深度学习模型的优化算法的选择可能意味着良好结果之间的差异…

machinelearningmastery.com](https://machinelearningmastery.com/adam-optimization-algorithm-for-deep-learning/)

没有,因为即使是 Adam 也有两个与学习率相关的参数,分别是lr用于学习率和decay ( 参见 Keras 实现)。也就是说, Adam 需要一个学习速率来开始,以及它是否应该包括衰减函数的信息。如果你想使用这些参数,你需要考虑如何应用选项 1 和 2。

还有一种算法实现了选项 3。它被称为重启的随机梯度下降,并由马克·霍夫曼进行了精彩的解释:

[## 探索重新开始的随机梯度下降(SGDR)

这是我第一篇深度学习的博文。我在 2017 年 1 月左右开始了我的深度学习之旅,在我听说了…

medium.com](https://medium.com/38th-street-studios/exploring-stochastic-gradient-descent-with-restarts-sgdr-fa206c38a74e)

Jens Johnsson on Unsplash

你下一步应该做什么

我所知道的关于深度学习的最好的课程是由 fast.ai 公开提供的课程。还有同一个团队写的刚到 1.0 版本的 Python 包,如果你关心深度学习,到这里上第一堂课

总体来说,你对学习率和训练深度学习有什么看法?请在评论中或在 Twitter 上告诉我。我也很乐意在 LinkedIn 上联系。感谢阅读,留点👏🏻如果这对你有帮助,让我们继续学习吧!

学习率调度程序

原文:https://towardsdatascience.com/learning-rate-scheduler-d8a55747dd90?source=collection_archive---------10-----------------------

适应性学习率

在训练深度网络时,随着训练时期数量的增加,降低学习速率是有帮助的。这是基于直觉,即在高学习率的情况下,深度学习模型将拥有高动能。因此,它的参数向量会乱跳。因此,它不能停留在损失函数的更深和更窄的部分(局部最小值)。另一方面,如果学习速率非常小,那么系统的动能就会很低。因此,它会停留在损失函数的较浅和较窄的部分(假最小值)。

上图描述了高学习率将导致向量在局部最小值附近的随机往复运动,而低学习率将导致陷入错误的最小值。因此,知道何时降低学习速度可能很难找到答案。

我们的实验基于阶跃衰减的原理。这里,我们每隔几个历元就用一个常数因子降低学习率。典型值可能是每 5 个时期将学习速率减少一半,或者每 20 个时期减少 0.1。这些数字很大程度上取决于问题的类型和模型。你在实践中可能看到的一个启发是,在以固定的学习速率训练时观察验证误差,并且每当验证误差停止改善时,以一个常数(例如 0.5)降低学习速率。

在实践中,步长衰减是首选,因为它更容易解释超参数,如衰减分数和以历元为单位的步长计时。此外,还发现它提供了学习率值的稳定性,这反过来有助于随机梯度下降显示出快速收敛和高成功率。

实验步骤

实验结果

源代码

[## shree 6791/深度学习

深度学习——这个知识库由 Shreenidhi Sudhakar 实施的深度学习项目组成。

github.com](https://github.com/shree6791/Deep-Learning/blob/master/CNN/Cats and Dogs/keras/src/Intern Task 3.ipynb)

深度学习的学习速率表和自适应学习速率方法

原文:https://towardsdatascience.com/learning-rate-schedules-and-adaptive-learning-rate-methods-for-deep-learning-2c8f433990d1?source=collection_archive---------0-----------------------

当训练深度神经网络时,随着训练的进行降低学习速率通常是有用的。这可以通过使用预定义的学习率计划自适应学习率方法来完成。在本文中,我在 CIFAR-10 上训练了一个卷积神经网络,使用不同的学习速率计划和自适应学习速率方法来比较它们的模型性能。

学习费率表

学习率时间表旨在通过根据预定义的时间表降低学习率来调整训练期间的学习率。常见的学习率时间表包括基于时间的衰减阶跃衰减指数衰减。为了说明的目的,我构建了一个在 CIFAR-10 上训练的卷积神经网络,使用具有不同学习速率调度的随机梯度下降(SGD)优化算法来比较性能。

恒定学习率

在 Keras 的 SGD optimizer 中,恒定学习率是默认的学习率计划。默认情况下,动量和衰减率都设置为零。选择正确的学习速度是很棘手的。在我们的例子中,通过实验学习率的范围,lr=0.1显示了相对较好的开始性能。这可以作为我们试验不同学习速度策略的基准。

keras.optimizers.SGD(lr=0.1, momentum=0.0, decay=0.0, nesterov=**False**)

Fig 1 : Constant Learning Rate

基于时间的衰变

基于时间的衰减的数学形式是lr = lr0/(1+kt),其中lrk是超参数,t是迭代次数。查看 Keras 的源代码,SGD 优化器采用decaylr参数,并在每个时期以递减因子更新学习率。

lr *= (1\. / (1\. + self.decay * self.iterations))

动量是 SGD 优化器中的另一个参数,我们可以调整它以获得更快的收敛。与经典的 SGD 不同,动量法帮助参数向量以恒定的梯度下降在任何方向上建立速度,以防止振荡。动量的典型选择在 0.5 到 0.9 之间。

SGD optimizer 还有一个名为nesterov的参数,默认设置为 false。内斯特罗夫动量法是动量法的一个不同版本,它对凸函数有更强的理论收敛保证。在实践中,它比标准动量法稍微好一点。

在 Keras 中,我们可以通过在 SGD 优化器中设置初始学习率、衰减率和动量来实现基于时间的衰减。

learning_rate = 0.1
decay_rate = learning_rate / epochs
momentum = 0.8
sgd = SGD(lr=learning_rate, momentum=momentum, decay=decay_rate, nesterov=False)

Fig 2 : Time-based Decay Schedule

阶跃衰减

步长衰减计划每隔几个历元就将学习速率降低一个因子。阶跃衰减的数学形式为:

lr = lr0 * drop^floor(epoch / epochs_drop) 

一个典型的方法是每 10 个时期将学习率降低一半。为了在 Keras 中实现这一点,我们可以定义一个步长衰减函数,并使用 LearningRateScheduler 回调将步长衰减函数作为参数,并返回更新后的学习速率,以供 SGD optimizer 使用。

def step_decay(epoch):
   initial_lrate = 0.1
   drop = 0.5
   epochs_drop = 10.0
   lrate = initial_lrate * math.pow(drop,  
           math.floor((1+epoch)/epochs_drop))
   return lratelrate = LearningRateScheduler(step_decay)

题外话,回调是在训练程序的给定阶段应用的一组函数。在训练期间,我们可以使用回调来查看模型的内部状态和统计数据。在我们的示例中,我们通过扩展基类keras.callbacks.Callback来创建一个定制回调,以记录培训过程中的损失历史和学习率。

class LossHistory(keras.callbacks.Callback):
    def on_train_begin(self, logs={}):
       self.losses = []
       self.lr = []

    def on_epoch_end(self, batch, logs={}):
       self.losses.append(logs.get(‘loss’))
       self.lr.append(step_decay(len(self.losses)))

将所有东西放在一起,我们可以传递一个回调列表,该列表由LearningRateScheduler回调和我们的定制回调组成,以适应模型。然后,我们可以通过访问loss_history.lrloss_history.losses来可视化学习率时间表和损失历史。

loss_history = LossHistory()
lrate = LearningRateScheduler(step_decay)
callbacks_list = [loss_history, lrate]history = model.fit(X_train, y_train, 
   validation_data=(X_test, y_test), 
   epochs=epochs, 
   batch_size=batch_size, 
   callbacks=callbacks_list, 
   verbose=2)

Fig 3a : Step Decay Schedule

Fig 3b : Step Decay Schedule

指数衰减

另一个常见的时间表是指数衰减。其数学形式为lr = lr0 * e^(−kt),其中lrk为超参数,t为迭代次数。类似地,我们可以通过定义指数衰减函数并将其传递给LearningRateScheduler来实现这一点。事实上,使用这种方法可以在 Keras 中实现任何定制的衰减计划。唯一的区别是定义了不同的自定义衰减函数。

def exp_decay(epoch):
   initial_lrate = 0.1
   k = 0.1
   lrate = initial_lrate * exp(-k*t)
   return lratelrate = LearningRateScheduler(exp_decay)

Fig 4a : Exponential Decay Schedule

Fig 4b : Exponential Decay Schedule

现在让我们在我们的例子中使用不同的学习率时间表来比较模型的准确性。

Fig 5 : Comparing Performances of Different Learning Rate Schedules

自适应学习率方法

使用学习率时间表的挑战在于它们的超参数必须预先定义,并且它们严重依赖于模型和问题的类型。另一个问题是相同的学习速率被应用于所有的参数更新。如果我们有稀疏的数据,我们可能希望在不同程度上更新参数。

自适应梯度下降算法,如 Adadelta、 RMSprop Adam ,提供了经典 SGD 的替代方案。这些每参数学习率方法提供了启发式方法,而不需要为学习率调度手动调整超参数的昂贵工作。

简而言之, Adagrad 对更稀疏的参数执行较大的更新,对不太稀疏的参数执行较小的更新。它在稀疏数据和训练大规模神经网络方面具有良好的性能。然而,当训练深度神经网络时,它的单调学习速率通常被证明过于激进并且过早停止学习。 Adadelta 是 Adagrad 的扩展,旨在降低其激进的、单调递减的学习速率。 RMSprop 以非常简单的方式调整 Adagrad 方法,试图降低其激进的、单调递减的学习速率。 Adam 是对 RMSProp 优化器的更新,它类似于带有 momentum 的 RMSprop。

在 Keras 中,我们可以使用相应的优化器轻松实现这些自适应学习算法。通常建议将这些优化器的超参数保留为默认值(有时lr除外)。

keras.optimizers.Adagrad(lr=0.01, epsilon=1e-08, decay=0.0)keras.optimizers.Adadelta(lr=1.0, rho=0.95, epsilon=1e-08, decay=0.0)keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)

现在让我们看看使用不同的自适应学习率方法的模型性能。在我们的例子中,在其他自适应学习率方法中,Adadelta 给出了最好的模型精度。

Fig 6 : Comparing Performances of Different Adaptive Learning Algorithms

最后,我们比较了我们讨论过的所有学习速率表和自适应学习速率方法的性能。

Fig 7: Comparing Performances of Different Learning Rate Schedules and Adaptive Learning Algorithms

结论

在我研究的许多例子中,自适应学习率方法比学习率计划表现更好,并且在超参数设置中需要更少的努力。我们还可以使用 Keras 中的LearningRateScheduler来创建针对我们的数据问题的定制学习率计划。

作为进一步的阅读,Yoshua Bengio 的论文为深度学习的学习速率调优提供了非常好的实用建议,例如如何设置初始学习速率、小批量大小、纪元数量以及使用早期停止和动量。

源代码

参考资料:

数据科学家的学习资源

原文:https://towardsdatascience.com/learning-resources-for-data-scientists-2a48d9168625?source=collection_archive---------10-----------------------

Learning, learning and more learning!

我被问了很多次,为了学习更多关于数据科学或人工智能的知识,我去了哪些学习资源。这篇博文让我可以轻松地与他人分享我学习所依赖的资源,以及我是如何使用这些学习资源的。我将从我去的网站开始。

Arxiv.Org

期刊曾经是一个非常封闭的领域,每个学者都在竭尽全力让他们的研究发表在最负盛名的期刊上(或被称为学术界的第一梯队)。与现在相比,这些杂志的存在使在大学工作对我来说更有吸引力。但是这些期刊的受众非常有限,鉴于目前的情况,研究不再局限于大学,为了人类的进步,研究论文需要更广泛地分享。

这就是 Arxiv.Org 的的用武之地。它收藏在康奈尔大学图书馆,是许多学者和非学者研究的宝库。你会发现那里有很多研究,你可以从 Arxiv 学到很多关于数据科学、算法、计算机科学等的知识。使用它的关键是能够使用相关的关键字进行搜索。否则,另一种选择可能是 FB 集团或 Reddit,人们“推荐”某些研究论文,你可以根据推荐阅读。

我承认这些论文读起来很有挑战性,但是你必须告诉自己,这些论文不是要在一次阅读中完成的。你必须多读几遍,才能体会到你在之前的阅读中学到的东西,并与之前获得的其他相关知识联系起来。

所以,如果你想从事数据科学和人工智能,请做好准备。Arxiv.Org 将是你学习旅程中的好伙伴。

StackOverflow

鉴于开源运动如此之大,你不能逃避编程,尤其是大型科技公司开放了他们的机器学习框架,如 Tensorflow、PyTorch、Keras 等。

既然你不能逃避编程,你也不能逃避程序员最常见和最令人沮丧的任务,那就是调试!对于任何编写代码的人来说, StackOverflow 是一个可以去的地方,可以寻找那些曾经陷入相同错误的同事,并寻求解决方案。我确实经常去 StackOverflow(是的,我是一个糟糕的程序员。)来寻找可能的调试方法,通常我会从中获得一些关于如何调试的想法。最大的挑战是试图根据问题的“标题”来解读,你正在寻找的解决方案是否就在那里。所以很多时候,你要先浏览几个 Q & A 线程,才能找到可能的解决方案。

中型

博客自诞生以来已经走过了漫长的道路(大约 10 年前?).博客不仅仅是一个供人们写观点的地方,现在还有一些“产品”,如出版物,它整合了相似主题的博客,这样像我这样的新博客就很容易有现成的受众。准备好的观众鼓励更多的人贡献他们的观点和想法。

说回来,像 Medium(尤其是 Medium)这样的博客网站是一个学习的好地方。除了技术博客,他们展示了如何使用机器学习解决业务问题,代码和思维过程也显示了出来,在我看来,这是非常有价值的,因为数据科学家是解决方案的提供者,加强我们自己的思维过程并能够从不同角度看待挑战是非常重要的。所以我在 Medium 上订阅了一些出版物,并让 Medium“推荐”我喜欢阅读的博客。

我订阅的刊物有走向数据科学 e、黑客帝国成为人类数据驱动投资者

慕课

我从 MOOC 网站上捡了很多知识,比如 Coursera 、(特别) UdacityEdx 。鉴于世界各地的大学提供了大量的知识和材料,我喜欢这些网站。

目前,我正在学习 Udacity 上的强化学习模块。想象一下,在过去,这种高级模块在网上是没有的,如果我想了解它,我必须四处打听一本推荐的教科书,然后吃大约一个月的面包(便宜的),才能攒够买教科书的钱。现在,由于 MOOCs 网站,我可以很容易地获得这些策划材料。

需要注意的一点是,大多数模块都有非常简洁的视频,所以不要期望在完成模块后成为专家。它可以给你一个关键词列表,你需要进一步研究,以掌握这个主题。

YouTube

又一个生命救星,非常感谢大学和科技聚会/会议把讲座和谈话放在 YouTube 上!我喜欢它!现在 YouTube 上有很多大学讲座,如果我需要对某些主题的快速解释,我会去 YouTube 上寻找一个简短的视频,并以 1.5-2 倍的速度播放(另一个很棒的功能!).

世界知名的大学,如麻省理工学院和斯坦福大学,将他们的讲座放在网上,并允许任何可以上网的人“旁听”讲座,一起学习!多棒啊。所以我保留了一个播放列表的列表,希望可以浏览一下,了解更多关于计算机科学/数据科学/人工智能的知识。

播客

最近,我偶然看到几个关于数据科学和人工智能的播客。它们让我能够听取专家的不同意见,并让我有可能在漫长的会议旅途中学习。伴随着路过的风景,聆听其他相关领域专家的知识分享,是一种极大的放松。在这些巴士旅程中,我学到了很多知识,也让我接触到了新的概念。我相信这些曝光是由于小组成员/发言者的自发性。

结论

这些是我去学习和获取更多数据科学和人工智能知识的网站。毫无疑问,这些网站你可能听说过,但我在这里的分享更多的是创造一种意识,即你习惯的这些网站是你可以用来学习的网站,可以了解更多关于数据科学和人工智能的信息。

我希望这个博客对你有用。如果有,一定要分享。祝您的数据科学学习之旅愉快,请务必访问我的其他博客文章LinkedIn 个人资料

通过自然语言推理学习句子嵌入

原文:https://towardsdatascience.com/learning-sentence-embeddings-by-natural-language-inference-a50b4661a0b8?source=collection_archive---------1-----------------------

无监督学习方法看起来像是构建单词、句子或文档嵌入的正常方式,因为它更一般化,使得预训练的嵌入结果可以转移到其他 NLP 下游问题。例如,单词嵌入中的 skip-gram 和句子嵌入中的 skip-through 以及段落嵌入中的分布式词袋。

“closeup photo of person carrying professional video recorder” by Laura Lee Moreau on Unsplash

Conneau 等人指出,ImageNet(图像分类)中的监督学习在将结果转移到下游问题方面做得很好。有些特征可以以某种方式转移到下游。因此,Conneau 等人使用文本蕴涵数据来训练一个句子嵌入层,称为 InferSent。

看完这篇文章,你会明白:

  • 完美的设计
  • 体系结构
  • 履行
  • 拿走

完美的设计

该团队使用 SNLI(斯坦福自然语言推理)数据来训练自然语言推理(NLI)问题的模型。NLI 的目标是找出句子 1(前提)和句子 2(假设)之间的关系。有三个范畴,即蕴涵、矛盾和中性。下面是一个非常简单的例子:

“two apples and walnuts on white towel” by Alex Kotomanov on Unsplash

  1. 我吃水果。
  2. 我吃苹果。

直觉上,这种关系是隐含的。作者认为,NLI 是理解句子中语义关系的合适任务,因此它有助于为下游 NLP 问题的句子嵌入建立良好的嵌入。

体系结构

总体思路是,两个句子(前提输入和假设输入)将通过句子编码器(权重相同)进行转换。然后利用 3 种匹配方法来识别前提输入和假设输入之间的关系。

Conneau et al. (2017)

  1. 两个向量的连接
  2. 两个向量的逐元素乘积
  3. 两个向量的绝对元素差

在概述之后,可能会进入句子编码器的架构。Conneau 等人评估了 7 种不同的架构:

  1. 标准 LSTM
  2. 标准 GRU
  3. 前向和后向 GRU 的最后隐藏状态的串联
  4. 具有平均轮询的双向 LSTM
  5. 具有最大轮询的双向 LSTM
  6. 自我关注网络(用 BiLSTM 关注)
  7. 分层卷积网络

在首先得出最佳方法之前,我们可以认为用 BiLSTM 注意应该是最佳方法,因为注意机制有助于识别重要权重。实际上,在迁移学习中使用它可能是有害的。另一方面,采用平均轮询的 BiLSTM 可能由于无法定位重要部分而性能不佳。

5 Bi-directional LSTM with max polling (Conneau et al., 2017)

6 Self-attentive Network Architecture (Conneau et al., 2017)

Hierarchical convolutional networks (Conneau et al., 2017)

从实验结果来看,最大轮询的双向 LSTM 是最好的方法。

Conneau et al. (2017)

履行

有两种方法可以使用 InferSent。首先是在你的 NLP 问题中使用一个预先训练好的嵌入层。另一个是你自己发出的建筑噪音。

加载预训练嵌入

脸书研究小组提供了两个预训练模型,即版本 1(基于手套)和版本 2(基于快速文本)。

加载推断预训练模型和 GloVe(或 fastText)模型,然后您可以将句子编码为向量。

# Init InferSent Model
infer_sent_model = InferSent()
infer_sent_model.load_state_dict(torch.load(dest_dir + dest_file))# Setup Word Embedding Model
infer_sent_model.set_w2v_path(word_embs_model_path)# Build Vocab for InferSent model
model.build_vocab(sentences, tokenize=True)# Encode sentence to vectors
model.encode(sentences, tokenize=True)

列车嵌入

另一种方法是自己训练嵌入。你可以使用你自己的数据或原始数据集。因为这个推理器使用监督学习方法来生成句子嵌入,所以您首先需要有一个带注释的(带标签的)数据。

这是第一种方法的步骤。克隆人将原始的回购发送到本地。然后在控制台中执行“get_data.bash ”,以便下载和处理 SNLI(斯坦福自然语言推理)和 multi nli(NLI)语料库。确保您必须在当前文件夹而不是其他相对路径中执行以下 shell 脚本

./get_data.bash

之后,下载手套(和/或快速文本)

mkdir dataset/GloVe
curl -Lo dataset/GloVe/glove.840B.300d.zip http://nlp.stanford.edu/data/glove.840B.300d.zip
unzip dataset/GloVe/glove.840B.300d.zip -d dataset/GloVe/
mkdir dataset/fastText
curl -Lo dataset/fastText/crawl-300d-2M.vec.zip https://s3-us-west-1.amazonaws.com/fasttext-vectors/crawl-300d-2M.vec.zip
unzip dataset/fastText/crawl-300d-2M.vec.zip -d dataset/fastText/

正在下载预先训练好的模型。版本 1 通过使用 GloVe 来训练,而版本 2 利用了 fastText。

curl -Lo encoder/infersent1.pkl https://s3.amazonaws.com/senteval/infersent/infersent1.pkl
curl -Lo encoder/infersent2.pkl https://s3.amazonaws.com/senteval/infersent/infersent2.pkl

最后,您可以执行下面的命令来训练嵌入层。

python train_nli.py --word_emb_path ./glove.42B.300d.txt

对于我的单个 GPU 虚拟机,完成培训大约需要 1 天时间。

拿走

要访问所有代码,可以访问我的 github repo。

  • 与其他嵌入方法相比, InferSent 使用监督学习来计算单词向量。
  • InferSent 利用单词嵌入 (GloVe/ fastText)构建句子嵌入。
  • 预训练模型支持 GloVe(版本 1)和 fasttext(版本 2)

关于我

我是湾区的数据科学家。专注于数据科学、人工智能,尤其是 NLP 和平台相关领域的最新发展。你可以通过媒体博客LinkedInGithub 联系我。

参考

Conneau,D. Kiela,H. Schwenk,L. Barrault,A. Bordes, 从自然语言推理数据中监督学习通用语句表示

在 Pytorch 中感染

学习制作未来不确定的视频

原文:https://towardsdatascience.com/learning-to-generate-videos-with-uncertain-futures-3d587fe06838?source=collection_archive---------9-----------------------

“具有已知先验的随机视频生成”一文的摘要

TL;DR: 这篇文章提供了一个在中描述的视频生成模型的高级概述,随机视频生成具有一个已知的先验,它能够生成具有多种未来的视频序列。

作为自我监督学习任务的视频生成

有监督的深度学习模型已被证明在最近的过去在诸如实时对象分割、检测、机器翻译和语音识别等困难任务上产生了突破性的结果。这些模型的高保真性能使它们在现实世界应用中的使用给世界带来了积极的影响(但有时也是消极的)。

无监督学习的下一阶段挑战也已经在一定程度上成功解决,如领域适应机器翻译。从原始、嘈杂的真实世界数据中学习在操作上更便宜、更快,因为可以跳过大量的手动预处理,如清理和注释。

无监督学习的一个子领域是自监督学习,最近由 AI 社区谈论了很多。在这个场景中,模型被提供输入数据,并负责完成围绕该数据的故事。该领域中一个特别有趣的应用是生成任何给定视频序列的未来事件。

这个任务的警告使得这个问题变得困难,不像其他任务,其中输入具有固定的输出,视频中的未来事件可以以多种可能性解开,例如,击中地面的弹跳球可以具有多种可能的轨迹、旋转等。

具有学习先验的随机视频生成

2018 年在 ICML 发表的“具有学习先验的随机视频生成”提出了一个框架,通过提出一个预测模型来处理这种情况,其中未来的“不确定”部分由从先验分布中采样的潜在变量来处理。为了理解其工作原理,让我们直接进入系统设计。

该系统由以下部件组成:

  1. 预测模型
  2. 推理模型
  3. 已知先验

预测模型

预测模型是核心预测器/生成器,其他模型提供辅助信息来帮助预测模型。它由一个编码器组成,该编码器在时间 t-1 从视频中获取一个图像帧,并将其编码为潜在空间中的密集表示。这个表示向量然后被传递到 LSTM ( 【帧预测】,它是预测模型的记忆组件。它有助于模型考虑序列中过去图像帧的信息。帧预测器负责预测未来下一帧的密集表示。然后,该图像被传递到解码器/ 生成器网络,该网络在时间 t 将其转换为预测图像。为了进一步帮助解码器,在编码器和解码器之间进行跳跃连接,以便可以简单地直接复制视频的静态部分。

帧预测器也以一个辅助变量为条件,该辅助变量可被视为代表关于特定未来的信息。我们将在接下来的步骤中讨论这一点。

Prediction Model

到目前为止,模型的训练包括一个非常简单的目标,即最小化重建误差或预测帧和地面真实情况之间的 L2 距离。

推理模型

推理模型的任务是学习包含关于时间 t 的事件的信息的分布。从该分布中抽取样本 z ,其被传递到预测模型中的帧预测器上。

推理模型的输入是在时间 t 的图像帧,因此该模型仅在训练期间使用。推理模型的架构使用与预测模型中相同的T21 编码器,因为在两个阶段中我们想要的图像编码类型是相同的。重复使用模型或重量分配会使学习过程变得简单一些。然后,编码矢量被传递到不同的 LSTM 模型(本文中称为后验)上,该模型具有与帧预测器相似的目标,但是在学习表示未来信息的背景下。后验者可能会学习查看过去的隐藏状态,并避免捕获已学习分布中的冗余信息。

人们可能会想,推理模型可以简单地记忆整个图像,并通过解码器再现它。为了确保只捕获相关的信息,我们使用了已学习的先验模型

Inference Model accompanies the Prediction model during training, providing latent variable containing information to a possible outcome in the future.

已知先验

为了防止推理模型简单地复制整个目标帧,我们施加了这样的限制,即来自后验的学习分布应该紧密匹配前分布。这通过最小化后验和先验预测的两个多变量分布之间的 KL-散度来确保。这个先验分布是通过另一个模型学习的,该模型类似于推理模型,但是将时间 t-1 的帧作为输入。这里的思想是先验也是时间相关的,即在时间 t 预测的先验分布是直到 t-1 的过去帧的函数。

Complete model that is used during training with the objective of minimizing reconstruction error and KL divergence.

一种替代方法是将该先验分布固定为具有零均值和恒等协方差的高斯分布。

结果

通过将地面实况的第一个 t-1 帧馈送到预测和先验模型,从学习的先验分布中采样 z 并生成时间步长 t 的帧,来执行推断。这然后作为输入反馈到模型中,以在 t+2 生成帧。

除了像移动 MNIST 和 KTH 动作这样的较小数据集,该模型在 BAIR 机器人推数据集上显示了令人印象深刻的结果。鉴于损失目标如此简单,该模型能够在未来多个时间步长内表现如此之好,即生成机器人手臂的非模糊运动,确实令人惊讶。

The frames marked in green are ground truth. “Approx. posterior”: in this case, z is sampled from the posterior (and thus should be close to the ground truth). In all other sequences, z is randomly sampled from the prior distribution. “Best SSIM” is the one such sequence prediction with the best results on SSIM metric.

Results on Moving MNIST.

更多比赛结果的视频,请查看 https://sites.google.com/view/svglp/的。

当前的缺点

如果读者在提供的链接中查看放大的结果,很容易注意到当机器人手臂与周围的其他对象交互时,预测的帧表现出模糊。换句话说,这个模型已经学会了表示手臂的未来随机运动,但未能捕捉到手臂及其与其他对象的交互之间的动态。

解决这一问题的一种方法是利用分层潜在模型,这样更广泛的概念(如整体手臂运动)由较低层次的先验捕获,而复杂的动力学由下一层次的模型捕获。今年早些时候,我花了一些时间研究这个问题,应用了各种基于层次概念的技术。我的一些发现可以在这里查看

最后的想法

这篇文章提供了 SVG-LP 模型的简要概述以及它所获得的一些结果。要从概率的角度获得更正式的解释,请参考上面链接的论文。

视频生成模型不仅可以作为视频理解和合成的非常有用的应用,还可以帮助规划和强化学习。2018 年下半年,基于模型的强化学习出现了令人难以置信的增长。这些方法的基本组成部分是前向预测模型,其任务是在给定当前和动作的情况下预测下一个状态。看看大卫·哈的https://worldmodels.github.io/来一瞥这种类型的模型如何被用于强化学习。

学习使用自然图像数据执行线性滤波

原文:https://towardsdatascience.com/learning-to-perform-linear-filtering-using-natural-image-data-db289d0b0457?source=collection_archive---------3-----------------------

Traditional Norwegian hut in Skibotn (Image by author).

卷积神经网络通常从训练数据中学习有用的特征。根据任务的不同,第一个卷积层的特征可能代表训练数据的一些基本内容。例如,在图像数据中,所学习的特征可以表示边缘和斑点。在网络的后续层中,学习到的特征可以表示更抽象、更高级别的实体。

可视化所学习的特征,以及它们如何及时发展,可能提供关于网络如何学习的有用信息。实际上,网络架构几乎总是比仅仅几层深得多,这使得很难直观地解释和分析所学习的特征,因为卷积核的总量很高。

然而,我们可以演示卷积核权重如何随着网络通过受控实验的学习而随时间发展。很容易陈述学习任务,使得网络应该学习的特征已经预先知道,即产生训练数据的过程和参数被很好地定义并且完全在我们的控制之下。这可以通过构建一个极其简单的单层卷积网络并训练它使用各种内核执行线性滤波来实现。

在下面的实验中,我们将 Sobel 边缘滤波(图像处理和计算机视觉中边缘检测的典型方法)应用于数据集,并训练我们的模型来执行类似的线性映射。我们还试图从数据中学习更多的任意线性滤波器,其核的大小比 Sobel 滤波的情况稍大。

该演示有望建立关于神经网络中的卷积层如何对输入数据进行操作、卷积核权重如何在训练期间进行以及神经网络的训练如何可以被视为最小化问题的直觉。

首先,我们必须对输入图像数据 X 应用线性滤波,以便获得原始图像的滤波版本 Y。形式上,线性滤波操作可以总结如下:

线性滤波器是一种定义明确的操作,适用于我们能想到的任何参数集(卷积核)或输入数据。

我们现在可以建立一个单层、单核、卷积神经网络,它近似于线性滤波操作。毕竟,在线性滤波器和卷积神经网络中,两种情况下执行的计算完全相同,只是卷积核参数不同,我们将从数据中了解这一点。

我们可以在线性滤波器和卷积神经网络之间得出以下联系:

学习任务现在可以表述为最小化问题,其中线性滤波器的输出和卷积神经网络的输出之间的均方误差被最小化:

应用于图像数据的线性滤波器的参数被称为卷积核。我们将首先在 x 方向上,然后在 y 方向上,用称为 Sobel 算子的 3×3 卷积核来过滤图像数据,从而开始我们的实验。Sobel 算子给出如下:

对于实验,我们将使用运行在 TensorFlow 之上的 Keras 框架。

x 方向的 Sobel 滤波器

首先,我们必须为图像预处理定义几个辅助函数。加载数据集,将图像转换为灰度,归一化图像强度范围,并对数据集中的每个图像执行线性滤波。

作为训练和测试数据,我们将利用城市和自然场景类别-数据集(奥利瓦,A. &托拉尔巴,A. (2001)。模拟场景的形状:麻省理工学院计算视觉认知实验室收集的空间包络的整体表示。

原始数据集由八个类别的自然场景彩色图像(分辨率:256 x 256)组成,其中我们使用了三个类别:街道、市中心和高楼。这样,我们获得了足够大小的训练和测试集(764 个训练样本和 192 个测试样本),使得训练不会遭受过拟合,并且训练也可以通过在合理的时间帧内利用更适中的硬件来执行。所选的类别代表具有强烈边缘的自然场景(大范围的人类建筑),这有助于我们比较结果。

下面,我们可以观察到属于数据集的原始图像的可视化、图像的灰度转换和 Sobel 滤波版本:

Original image (left), Grayscale image (middle) and Sobel filtered image in x-direction (right).

我们将只在单通道图像上使用线性滤波器。在实践中,这意味着模型被训练成将灰度转换图像映射成 Sobel 滤波图像。

接下来,我们定义模型:具有线性激活的单层、单核、卷积网络,即,激活函数是恒等式。卷积核的大小被选择为 3×3,以符合 Sobel 滤波器的大小。

使用具有内斯特罗夫动量的随机梯度下降优化器来训练 100 个时期的模型。在每个时期,保存卷积层权重用于进一步可视化。

训练完成后,我们可以绘制训练和验证损失图,以查看训练是否过度拟合。

在整个训练过程中,训练和验证损失是稳定的,模型似乎是收敛的。

现在可以将每个时期的保存的权重可视化为矩阵格式的数值,以及更直观的格式,其中数值表示可视化中的像素强度值。声明用于执行可视化的函数,并且为每个时期创建可视化。

现在我们有了每个时期的可视化效果,我们可以从它们创建一个 gif 电影来看看权重是如何变化的。

The progress of the convolution layer weights as the model is trained. The weight values converge close to the Sobel operator in x-direction.

在 gif 电影中,随着学习的进行,卷积核权重如何向 Sobel x 方向滤波器收敛是相当明显的。在前 10 到 15 个时期收敛很快,之后收敛速度明显稳定下来。如果学习任务比我们在这个实验中使用的简单线性过滤操作更复杂,我们仍然会看到类似的行为。卷积核的值将收敛到某个最佳配置,该配置将从数据中提取有用的特征。在这个实验中,有用的特征是由 Sobel 算子给出的图像 x 方向的边缘。我们能够找到产生第一手训练数据的几乎精确的卷积核参数,主要是因为我们的问题陈述非常简单。然而,对于真实世界的问题,这很少发生,因为训练数据通常不是从输入到输出的线性映射。

为了测试该模型,我们可以看到与 x 方向上的 Sobel 滤波相比,该模型的预测看起来如何。

Output of the model (left) and the same image filtered with Sobel operator in x-direction (right).

在图中(顶部),我们可以观察到模型的输出和 x 方向上并排的 Sobel 滤波的结果。目测,两幅图像看起来相似。事实上,在强度值中,人们应该仅发现图像之间的微小差异,因为所学习的卷积核收敛到接近原始 Sobel 算子的值。

y 方向的 Sobel 滤波器

同样的代码也可以利用 Sobel 算子在 y 方向上执行线性滤波。我们所要做的就是改变图像过滤功能,在 y 方向而不是 x 方向执行过滤,再次加载并过滤训练数据,并用新数据训练模型。

在下图中,我们可以观察到 Sobel 过滤器现在如何在垂直方向(y 方向)上强调图像强度边缘。

Original image (left), Grayscale image (middle) and Sobel filtered image in y-direction (right).

我们可以再次观察到,当网络从训练数据中学习时,卷积核权重如何在 y 方向上朝着 Sobel 滤波器前进。收敛行为非常类似于先前在 x 方向上使用 Sobel 算子的情况。

The progress of the convolution layer weights as the model is trained. The weight values converge close to the Sobel operator in y-direction.

同样,在下图中,模型的输出和相同测试图像的 Sobel 滤波版本具有相似的外观。对于人眼来说,不可能分辨出这两幅图像的区别。

Output of the model (left) and the same image filtered with Sobel operator in y-direction (right).

笑脸过滤器

之前学习的 Sobel 滤波器非常简单,只需要学习少量的参数。让我们看看,如果我们可以学习一个更大的核线性滤波器。

我们将在下面的实验中使用的过滤器内核是一个 32 x 32 像素的笑脸(谢谢 Leo 的想法:)。加载过滤器内核,并通过用笑脸内核过滤灰度图像来创建训练数据。由于大的内核大小,内核基本上延伸到图像边界之外。图像边界用零填充,以抵消卷积导致的图像分辨率的降低。

The normalized smiley face filter kernel.

在下图中,我们可以看到笑脸过滤图像与原始图像和灰度转换图像相比的样子。

Original image (left), Grayscale image (middle) and smiley face filtered image (right).

我们的模型再次是一个简单的单层、单核、卷积神经网络,其中激活函数是身份。这一次,我们根据笑脸内核的大小,将内核大小设置为 32 x 32。作为对之前实验的增强,我们将基本的随机梯度下降优化器改为更强大的 Adam 优化器。

该模型被训练 100 个时期,并且在每个时期存储卷积核权重。训练和验证损失在大约 10 个时期内快速收敛,之后可以在两个损失值中看到小的波动。

存储的卷积核权重值现在可以可视化并组合成 gif 电影。结果很有启发性:该模型似乎惊人地学习了原始的笑脸过滤器内核,正如在下面的 gif 电影中可以观察到的那样。卷积核权重相对较早地呈现笑脸的形状,大约在十个时期之后,但是权重仍然包含大量噪声。随着训练的进行,噪声慢慢消失,并且相邻的权重值相对于彼此变得更加恒定。

通过分析验证损失和卷积核权重的进展,可以进行重要的观察。即使验证损失在第十个时期后看起来是平坦的,卷积核权重仍然朝着原始笑脸核发展足够的量。训练和验证损失曲线的线性比例有时可能会有点误导,因为初始损失值可能会在损失测量的后期改进中主导损失可视化。

The progress of the convolution layer weights as the model is trained. The weight values converge close to the smiley face filter.

现在我们有了一个训练好的模型,我们可以可视化并比较模型的输出和一个笑脸过滤测试图像的结果。在下图中,我们可以观察模型和笑脸过滤器内核如何产生与测试图像相似的外观。类似于 Sobel 滤波的图像,以及由从数据学习 Sobel 滤波的模型产生的图像,很难将笑脸滤波的图像与模型的输出区分开。

Output of the model (left) and the same image filtered with the smiley face kernel (right).

最后的话

我希望使用线性滤波器的三个实验足够清楚地展示了当网络从数据中学习时,卷积核权重是如何发展的。此外,我希望您能够获得一些见解,以便理解卷积层对输入数据的操作方式。这些实验的结果没有直接推广到卷积神经网络被用于例如图像分类的情况,而是为理解卷积层背后的现象和作为优化问题的学习提供了基础。

如果你对在自己的电脑上运行实验感兴趣,这里有一个 github 文件夹的链接,其中包含重复实验所需的一切:https://github.com/vexcel/Keras-LearnLinearFilter

学习使用 Python scikit 进行排名-学习

原文:https://towardsdatascience.com/learning-to-rank-with-python-scikit-learn-327a5cfd81f?source=collection_archive---------0-----------------------

如果你经营一个电子商务网站,一个经典的问题是在搜索页面上排列你的产品,以最大化你的商品被销售的可能性。例如,如果你在卖鞋,你希望搜索结果页面中的第一双鞋是最有可能被购买的。

由于机器学习的广泛采用,现在比以往任何时候都更容易建立和部署自动学习用户喜欢什么并相应地对产品目录进行排名的模型。在这篇博文中,我将分享如何使用一个简单的端到端示例,使用 movielens 开放数据集来构建这样的模型。

介绍

想象一下,你有一个电子商务网站,你正在设计一种算法,在你的搜索页面中对你的产品进行排序。你展示的第一件物品是什么?评论最好的那个?价格最低的那个?还是两者都有?问题很快变得复杂起来。

一个简单的解决方案是利用你的直觉,从你的客户那里收集反馈,或者从你的网站上获取指标,手工制作适合你的完美配方。不太科学不是吗?一种更复杂的方法包括建立许多排名公式,并使用 A/B 测试来选择具有最佳性能的一个。

在这里,我们将使用来自客户的数据来自动学习他们的偏好函数,这样我们的搜索页面的排名将最大化获得转化率的可能性(即客户购买你的商品)。具体来说,我们将学习如何根据人工生成的用户数据对来自 movielens 开放数据集的电影进行排名。Github 上的提供了 Jupyter 笔记本格式的完整步骤。

准备培训数据

为了学习我们的排名模型,我们首先需要一些训练数据。因此,让我们生成一些模拟网站用户行为的示例:

event_1: <customer_1, movie_1, fail>
event_2: <customer_1, movie_2, fail>
event_3: <customer_1, movie_3, success>
event_4: <customer_2, movie_2, fail>
event_5: <customer_2, movie_3, success>
…

列表可以解释为: customer_1 看了 movie_1movie_2 但决定不买。然后看了 movie_3 决定买电影。同样的顾客 _2 看了电影 _2 但决定不买。然后看了 movie_3 决定买。

在真实世界的场景中,你可以从你选择的分析工具中获得这些事件,但是对于这篇博文,我将人工生成它们。为此,我们将为每部电影关联一个 buy_probability 属性,并相应地生成用户事件。

我们的原始电影数据如下所示:

movie_data.dtypestitle object
release_date datetime64[ns]
unknown int64
Action int64
Adventure int64
Animation int64
Children’s int64
Comedy int64
Crime int64
Documentary int64
Drama int64
Fantasy int64
Film-Noir int64
Horror int64
Musical int64
Mystery int64
Romance int64
Sci-Fi int64
Thriller int64
War int64
Western int64
ratings_average float64
ratings_count int64
price float64
dtype: object 

这是数据集中一部电影的例子:

‘title’, ‘release_date’, ‘unknown’, ‘Action’, ‘Adventure’, ‘Animation’, “Children’s”, ‘Comedy’, ‘Crime’, ‘Documentary’, ‘Drama’, ‘Fantasy’, ‘Film-Noir’, ‘Horror’, ‘Musical’, ‘Mystery’, ‘Romance’, ‘Sci-Fi’, ‘Thriller’, ‘War’, ‘Western’, ‘ratings_average’, ‘ratings_count’, ‘price’
‘Toy Story (1995)’, Timestamp(‘1995–01–01 00:00:00’), 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3.8783185840707963, 452, 7.0

让我们假设我们的用户将仅基于价格做出购买决定,并看看我们的机器学习模型是否能够学习这样的功能。对于这个数据集,电影价格的范围在 0 到 10 之间(查看 github 以了解价格是如何分配的),所以我决定人工定义购买概率如下:

movie_data[‘buy_probability’] = 1 — movie_data[‘price’] * 0.1

根据购买概率函数,我们的完美排名应该是这样的:

没有火箭科学,价格最低的电影最有可能被购买,因此应该排在第一位。现在让我们基于这些数据生成一些用户事件。每个用户都有许多积极和消极的事件与之相关联。正面事件是指用户购买了一部电影。负面事件是指用户看了电影,但决定不购买。

class User:
    def __init__(self, id):
        self.id = id
        self.positive = []
        self.negative = []

    def add_positive(self, movie_id):
        self.positive.append(movie_id)

    def add_negative(self, movie_id):
        self.negative.append(movie_id)

    def get_positive(self):
        return self.positive

    def get_negative(self):
        return self.negative

在继续之前,我们希望所有的特征都被标准化,以帮助我们的学习算法。所以让我们把这个弄清楚。还要注意,我们将删除 buy_probability 属性,这样我们就不会在学习阶段使用它(用机器学习的术语来说,这相当于作弊!).

def build_learning_data_from(movie_data):
    feature_columns = np.setdiff1d(movie_data.columns, np.array(['title', 'buy_probability']))
    learning_data = movie_data.loc[:, feature_columns]

    scaler = StandardScaler()
    learning_data.loc[:, ('price')] = scaler.fit_transform(learning_data[['price']])
    learning_data['ratings_average'] = scaler.fit_transform(learning_data[['ratings_average']])
    learning_data['ratings_count'] = scaler.fit_transform(learning_data[['ratings_count']])
    learning_data['release_date'] = learning_data['release_date'].apply(lambda x: x.year)
    learning_data['release_date'] = scaler.fit_transform(learning_data[['release_date']])

    return learning_data

最后,使用下面显示的“EventsGenerator”类,我们可以生成我们的用户事件。为了简单起见,让我们假设我们有 1000 个用户,并且每个用户将打开 20 部电影。真实世界的数据显然会有所不同,但原理是一样的。

np.random.seed(1)class EventsGenerator:
    NUM_OF_OPENED_MOVIES_PER_USER = 20
    NUM_OF_USERS = 1000def __init__(self, learning_data, buy_probability):
        self.learning_data = learning_data
        self.buy_probability = buy_probability
        self.users = []
        for id in range(1, self.NUM_OF_USERS):
            self.users.append(User(id))

    def run(self):
        for user in self.users:
            opened_movies = np.random.choice(self.learning_data.index.values, self.NUM_OF_OPENED_MOVIES_PER_USER)
            self.__add_positives_and_negatives_to(user, opened_movies)return self.__build_events_data()def __add_positives_and_negatives_to(self, user, opened_movies):
        for movie_id in opened_movies:
            if np.random.binomial(1, self.buy_probability.loc[movie_id]): 
                user.add_positive(movie_id)
            else:
                user.add_negative(movie_id)

    def __build_events_data(self):
        events_data = []

        for user in self.users:
            for positive_id in user.get_positive():
                tmp = learning_data.loc[positive_id].to_dict()
                tmp['outcome'] = 1
                events_data += [tmp]

            for negative_id in user.get_negative():
                tmp = learning_data.loc[negative_id].to_dict()
                tmp['outcome'] = 0
                events_data += [tmp]

        return pd.DataFrame(events_data)

这就是所有东西粘在一起的原因。事件生成器获取标准化的电影数据,并使用购买概率来生成用户事件。

learning_data = build_learning_data_from(movie_data)
events_data = EventsGenerator(learning_data, movie_data['buy_probability']).run()

这是其中一个事件的样子:

'Action', 'Adventure', 'Animation', "Children's", 'Comedy', 'Crime', 'Documentary', 'Drama', 'Fantasy', 'Film-Noir', 'Horror', 'Musical', 'Mystery', 'Romance', 'Sci-Fi', 'Thriller', 'War', 'Western', 'outcome', 'price',    'ratings_average', 'ratings_count', 'release_date', 'unknown'
1,        1,           0,           0,            0,        0,       0,             0,       0,         0,           0,        0,         0,         0,         0,        0,          0,     1,         0,         0.28363692, 0.16953213,        -0.14286941,     0.39397757,     0

在这种情况下,由于我们在函数build _ learning _ data _ from(movie _ data)中所做的操作,我们得到了一个否定的结果(值为 0),并且这些特征已经被归一化并集中在零。

如果我们绘制事件图,我们可以看到分布反映了人们大多购买廉价电影的想法。由于正常化,价格再次以零为中心。

训练我们的模型

现在我们有了我们的事件,让我们看看我们的模型在学习(简单)“购买概率”函数方面有多好。我们将把我们的数据分成一个训练和测试集,以测量模型性能(但请确保您知道交叉验证如何工作),并使用这个通用函数来打印不同模型的性能。

def train_model(model, prediction_function, X_train, y_train, X_test, y_test):
    model.fit(X_train, y_train)

    y_train_pred = prediction_function(model, X_train)print('train precision: ' + str(precision_score(y_train, y_train_pred)))
    print('train recall: ' + str(recall_score(y_train, y_train_pred)))
    print('train accuracy: ' + str(accuracy_score(y_train, y_train_pred)))y_test_pred = prediction_function(model, X_test)print('test precision: ' + str(precision_score(y_test, y_test_pred)))
    print('test recall: ' + str(recall_score(y_test, y_test_pred)))
    print('test accuracy: ' + str(accuracy_score(y_test, y_test_pred)))

    return model

使用 scikit-learn 训练各种模型现在只是把东西粘在一起的问题。让我们从逻辑回归开始:

def get_predicted_outcome(model, data):
    return np.argmax(model.predict_proba(data), axis=1).astype(np.float32)def get_predicted_rank(model, data):
    return model.predict_proba(data)[:, 1]model = train_model(LogisticRegression(), get_predicted_outcome, X_train, y_train, X_test, y_test)

这为我们提供了以下性能

train precision: 0.717381689518
train recall: 0.716596235113
train accuracy: 0.717328291166
test precision: 0.720525676086
test recall: 0.726374636238
test accuracy: 0.721590909091

我们可以使用神经网络和决策树来做同样的事情。这是一个具有 23 个输入(与电影特征的数量相同)和 46 个隐含层神经元(隐含层神经元加倍是一个常见的经验法则)的神经网络。

from nolearn.lasagne import NeuralNetdef nn():
    return NeuralNet(
        layers=[  # three layers: one hidden layer
            ('input', layers.InputLayer),
            ('hidden', layers.DenseLayer),
            ('output', layers.DenseLayer),
            ],
        # layer parameters:
        input_shape=(None, 23),  # this code won't compile without SIZE being set
        hidden_num_units=46,  # number of units in hidden layer
        output_nonlinearity=None,  # output layer uses identity function
        output_num_units=1,  # this code won't compile without OUTPUTS being set# optimization method:
        update_learning_rate=0.01, 
        regression=True,  # If you're doing classification you want this off
        max_epochs=50,  # more epochs can be good, 
        verbose=1, # enabled so that you see meaningful output when the program runs
    )def get_predicted_outcome(model, data):
    return np.rint(model.predict(data))def get_predicted_rank(model, data):
    return model.predict(data)

这是我们得到的表现

model = train_model(
 nn(), 
 get_predicted_outcome, 
 X_train.astype(np.float32), 
 y_train.astype(np.float32), 
 X_test.astype(np.float32), 
 y_test.astype(np.float32)
)train precision: 0.698486217804
train recall: 0.687534749249
train accuracy: 0.65721971972
test precision: 0.667556742323
test recall: 0.679655641142
test accuracy: 0.636136136136

最后是决策树

def get_predicted_outcome(model, data):
    return np.argmax(model.predict_proba(data), axis=1).astype(np.float32)def get_predicted_rank(model, data):
    return model.predict_proba(data)[:, 1]

这为我们提供了以下性能

from sklearn import tree
model = train_model(tree.DecisionTreeClassifier(), get_predicted_outcome, X_train, y_train, X_test, y_test)train precision: 0.680947848951
train recall: 0.711256135779
train accuracy: 0.653892069603
test precision: 0.668242778542
test recall: 0.704538759602
test accuracy: 0.644044702235

我们可以将各种排名标绘在一起进行比较。排名曲线的形状与我们用来定义购买概率的曲线非常相似,这证实了我们的算法正确地学习了偏好函数

描述 buy_probability 的形状并不完全相同,因为用户事件是随机生成的(均值等于 buy_probability 的二项式分布),所以模型只能根据生成的事件来近似潜在的事实。

Logistic regression

Decision trees

Neural Network

下一步是什么

一旦你得到了你的排名估计,你可以简单地将它们保存在你选择的数据库中,并开始为你的页面服务。随着时间的推移,你的用户的行为可能会像你的目录中的产品一样发生变化,所以要确保你有一些程序来每周更新你的排名数字,如果不是每天的话。根据一个简单的手工制作的线性公式对你的新模型进行 A/B 测试也是一个好主意,这样你就可以验证自己,机器学习是否确实在帮助你收集更多的转化率。

如果你更喜欢戴科学家的帽子,你也可以在 Github 上运行 Jupyter 笔记本,用不同的公式计算 buy_probability ,看看这些模型能够在多大程度上发现潜在的真相。我确实尝试了价格和评级的非线性函数的线性组合,它在相似的准确度水平下工作得同样好。

price_component = np.sqrt(movie_data['price'] * 0.1)
ratings_component = np.sqrt(movie_data['ratings_average'] * 0.1 * 2)
movie_data['buy_probability'] = 1 - price_component * 0.2 - ratings_component * 0.8

最后,与这里概述的方法不同的方法是使用事件对来学习排序函数。这个想法是,你给学习算法输入一对这样的事件:

pair_event_1: <customer_1, movie_1, fail, movie_3, success>
pair_event_2: <customer_2, movie_2, fail, movie_3, success>
pair_event_3: <customer_3, movie_1, fail, movie_2, success>
...

有了这样的例子,你可以猜到一个好的排序是“电影 _3,电影 _2,电影 _1 ”,因为不同客户的选择强制了我们的电影集合的总排序。尽管预测成对的结果与上面显示的例子具有相似的准确性,但为我们的电影集提出一个全局排序证明是困难的(NP 完全困难,如来自& T labs 的这篇论文所示),我们将不得不求助于贪婪算法进行排序,这会影响最终结果的质量。Julien le tessier的这篇博客文章对这种方法进行了更深入的描述。

结论

在这篇博文中,我介绍了如何利用用户事件数据来教会机器学习算法如何对你的产品目录进行最佳排序,以最大化你的商品被购买的可能性。我们看到了逻辑回归、神经网络和决策树如何实现相似的性能,以及如何将您的模型部署到生产中。

期待在评论中听到你的想法,如果你喜欢这个博客,你也可以在 Twitter 上关注我。

最初发表于 阿尔弗雷多

用应用于生物力学模型的进化算法学习行走

原文:https://towardsdatascience.com/learning-to-walk-with-evolutionary-algorithms-applied-to-a-bio-mechanical-model-1ccc094537ce?source=collection_archive---------5-----------------------

使用真正的肌肉在类似人类的模型上行走。

这个帖子的代码可以在 这个 GitHub 资源库 中找到。

2017 NIPS 挑战之一是学习跑步:顾名思义,任务是设计和开发一种学习算法,能够控制人体的生物力学模型使其行走。与大多数机器人情况不同,致动器是 肌肉,每条腿 9 个。挑战的作者修改了 OpenSIM 环境,使其适应强化学习设置,从而增加了奖励信号。

Something went terribly wrong (or terribly right).

许多参与者设计了端到端的深度强化学习算法,近年来,这些算法在连续控制任务中表现得非常好。但是,通常情况下,他们需要强大的计算能力和时间来学习一个成功的策略,如果在多台计算机上并行化,效果会更好。

我决定试着玩玩它,实现并扩展我最近为机器人开发的一个相当轻量级的方法:进化 算法应用于神经控制器。它们的优势是无导数和高度并行化,可以达到类似深度 RL 算法的结果,如 OpenAI 的所示。问题是他们完全是随机的,因此很难估计他们会学到什么和如何学。但我很乐意给他们一个机会。

First steps, baby steps.

…重要的是不要只开发性能最好的模型,因为它可能会陷入很难摆脱的局部最小值。

进化算法用于数值优化问题,因此它们相对于适应度函数优化参数。那么,什么是参数和适应度函数呢?经验证明:腿以周期性的方式运动。因此,肌肉激活以周期性和正弦时间规律激活,但是该规律可能难以手工设计。如何塑造周期函数?这就是傅立叶级数发挥作用的地方。利用傅立叶级数,人们可以用正弦和余弦的加权和来近似任何周期函数。但是,理论上,它们需要无限项。我设计了一个截断傅立叶级数来塑造肌肉活动。我只使用了余弦级数的前四项,因此有 8 个参数:4 个权重直接乘以不同频率的余弦,4 个相位改变信号。这为每块肌肉创造了一个周期性的功能。每条腿有 9 块肌肉,我使用了 9 个不同的周期函数,因为我假设,对于另一条腿,我们使用相同的函数,但相位偏移 180°。因此,遗传算法修改这些参数(与涉及神经网络的任何算法相比,非常少)来优化适应度函数,这显然是总回报,即机器人在摔倒之前行走的长度。

Walking pattern after around a day of training.

通过从白高斯采样,参数被随机修改,但是如果特定采样方向改善了性能,则参数再次朝着该方向更新以利用该方向,直到性能不再改善。我并行运行了的三个型号,因为对于一台笔记本电脑来说,它们的计算量比内存都要大。最佳性能权重被存储到中央参数文件中,并且在一定数量的集之后,学习从三个最佳性能参数组重新开始。这允许更好地探索不同的可能行为:重要的是不要只利用表现最好的模型,因为它可能陷入很难摆脱的局部最小值,而从长远来看,一个更差的模型可以通过调整其行为来超越它。事实上,在一系列事件后从最好的模型重新开始是学习可感知的行走模式的关键因素。非常值得注意的是,即使事先没有任何知识,这个模型也能学会类似人类的动作行为。

该模型在非常慢的模型和旧笔记本电脑上进行相对较短的训练后,仅使用英特尔酷睿 2 双核 CPU 成功行走了一些步骤。其他深度 RL 模型显然实现了更好的性能,但是需要非常长的训练和强大的硬件。我的目标并不是真的与它们竞争,而只是展示如何用不到 100 个参数并使用遗传算法来获得行走模式,即使在一台旧笔记本电脑上也能快速训练。

这个帖子的代码可以在 这个 GitHub 资源库 中找到。

学习用蒙特卡罗方法赢 21 点

原文:https://towardsdatascience.com/learning-to-win-blackjack-with-monte-carlo-methods-61c90a52d53e?source=collection_archive---------6-----------------------

Photo by Sam Goh on Unsplash

我会学到什么?

本文将带您了解强化学习的基础支柱之一蒙特卡罗(MC)方法背后的逻辑。这种解决强化学习问题的经典方法将通过寻找简化版 21 点的最优策略来演示。

在本文结束时,我希望你能够描述和实现以下主题。完整的代码可以在我的 GitHub 上找到。

  • 蒙特卡洛预测
  • 蒙特卡洛控制
  • 首次就诊与每次就诊
  • q 值
  • 折扣奖励

蒙特卡洛方法是什么?

Photo by Pasquale Iovino on Unsplash

MC 是一个非常简单的无模型学习的例子,只需要过去的经验就可以学习。这是通过计算在许多游戏中在特定状态下采取特定行动的平均奖励来实现的。如果你不熟悉强化学习的基础,我会鼓励你快速阅读基础知识,如代理生命周期。我之前的文章介绍了这些概念,可以在这里找到。如果你不熟悉 21 点游戏,看看这个视频

在 21 点中使用蒙特卡罗

如果你曾经认真玩过 21 点(或者我看过电影《21 小时》),那么你可能听说过“基本策略”。这是一个简单的表格,包含 21 点中每种可能的状态组合(您的牌的总和和庄家显示的牌值),以及根据概率和统计采取的最佳行动(击中、坚持、加倍或分裂)。这是一个政策的例子。

Simple version of the basic strategy policy developed by Edward O. Thorp, image taken from here

在我们的示例游戏中,我们将使它变得简单一点,只有击中或坚持的选项。除此之外,我们还会将状态逻辑分为两种类型,一手牌有可用的 a,一手牌没有可用的 a。

在 21 点中,a 的值可以是 1 或 11。如果我们有一张值为 11 的 a 而不破产,我们称之为“可用 a”。

预言;预测;预告

假设我们得到了一个非常简单的策略(甚至比上面的基本策略还要简单)。

策略:如果我们的手牌≥ 18,以 80%的概率坚持,否则以 80%的概率命中

这不是一个惊人的政策,但它很简单,仍然能够赢得一些比赛。现在,假设我们想知道当庄家出 6 时,持有 14 手牌的价值。这是预测问题的一个例子。

为了解决这个问题,我们将使用首次访问蒙特卡洛。这种方法让我们的代理使用我们当前的策略玩了成千上万个游戏。每次代理在该游戏中第一次执行状态 S 中的动作 A 时,它将从该点开始计算游戏的奖励。通过这样做,我们可以确定我们目前的状态有多有价值。

这与每次访问蒙特卡洛相反,蒙特卡洛每次看到状态/动作对时都会计算奖励。这两种方法提供了相似的结果。实施首次访问蒙特卡洛的步骤可以在这里看到。

First Visit Monte Carlo algorithm for prediction, taken from here

如果你不习惯阅读这些算法,这可能看起来有点复杂,但实际上很简单。让我们来看一下实现这个算法的步骤。

  1. 提供一个策略 pi
  2. 创建空字典 N、returns_sum 和 Q 来保存一个状态/动作对被访问的次数、该状态/动作对收到的返回量以及该状态/动作对的最终值。
  3. 用我们目前对 X 游戏的政策玩一局 21 点
  4. 循环游戏中的每个回合,检查当前的状态/动作对是否在游戏中出现过
  5. 如果这是我们第一次看到这一对,我们增加这一对的计数,并将从该回合开始的每一步的折扣奖励添加到我们的 returns_sum 字典中
  6. 最后,用每个状态/动作对的回报和数量的平均值来更新 Q 值。

在我们进入代码之前,我想快速介绍的最后一件事是折扣奖励和 Q 值的概念。

折扣奖励

折扣奖励的理念是将眼前的奖励置于潜在的未来奖励之上。就像专业的国际象棋选手一样,我们的代理人不仅仅着眼于在本回合中走一个卒,他们还着眼于如何从现在开始赢得 12 步棋。这就是为什么在计算行动价值时,我们采用累积折扣奖励(行动后所有奖励的总和)而不是直接奖励。

折扣因子只是一个常数,我们在每个时间点用它乘以我们的奖励。在每一个时间步之后,我们增加乘以折扣因子的幂。这给了立即行动更多的优先权,当我们离采取的行动越远,优先权就越低。

the discounted reward of an action over time, image taken from here

这给了立即行动更多的优先权,当我们离采取的行动越远,优先权就越低。选择我们的折扣因子的值取决于手头的任务,但它必须总是在 0 和 1 之间。折扣系数越大,未来奖励的重要性越高,反之亦然。一般来说,0.9 的折扣系数是一个很好的起点。

q 值

q 值是指在状态 s 中采取行动 A 的值。我们将这些值存储在一个表或字典中,并在学习时更新它们。一旦我们完成了我们的 Q 表,我们将总是知道基于我们所处的当前状态该采取什么行动。

履行

下面是一个 jupyter 笔记本,带有实现 MC 预测的代码。每一部分都有注释,并且逐行给出了更多的细节。

如您所见,实现预测算法并不困难,根据笔记本末尾显示的图表,我们可以看到该算法已经成功预测了我们非常简单的 21 点策略的值。接下来是控制。

控制

Photo by Mélanie THESE on Unsplash

这是两个问题中更有趣的一个,因为现在我们要用 MC 来学习博弈的最优策略,而不是仅仅验证之前的策略。我们将再次对 MC 使用首次访问方法。

First Visit MC Control with Constant Alpha, image taken from here

这个算法看起来比之前的预测算法复杂一点,但本质上还是很简单的。因为这有点复杂,我将把问题分成几个部分来解释。

  1. 初始化我们的价值观和字典
  2. 探测
  3. 更新策略
  4. 使用新策略生成剧集
  5. 更新 Q 值

1)初始化值

这与上一个算法类似,只是这次我们只有一个字典来存储我们的 Q 值。这是因为我们使用了一个新的更新功能,我们将在后面讨论

2)更新政策和探索

人们通过不断犯新错误来学习。我们的代理人也是这样学习的。为了学习最好的政策,我们希望有一个很好的组合来执行我们已经学到的好的举措和探索新的举措。这就是所谓的勘探/开发问题。在这种情况下,我们将使用经典的ε贪婪策略,其工作原理如下:

  1. 设置一个临时策略,使选择任一操作的概率相等,[0.5,..
  2. 获取当前状态 Q[s]的当前最佳策略
  3. 获得基于最佳策略的最佳操作,argmax(Q[s])
  4. 将选择最佳行动的概率设置为 1-ε+临时策略值(50%)

开始时,ε会很大,这意味着在大多数情况下,最佳行动的概率为 0.5(随机)。随着游戏的进行,ε会减小,采取最佳行动的概率会增加

3)用新策略生成剧集

这与我们之前的算法几乎完全相同,但是我们不是基于硬编码策略的概率来选择我们的行动,而是在随机行动和最佳行动之间交替。这就是我们之前讨论过的ε贪婪策略。当我们浏览时,我们记录下每集的状态、动作和奖励,并传递给我们的更新功能。

4)更新 Q 值

这是算法的重要部分。这里我们实现了代理如何学习的逻辑。我们将使用一个更新函数来改进我们的策略,而不是简单地获得一个状态/动作对随时间的平均回报。函数看起来是这样的。

Q[s][a] = Q[s][a] + alpha*(G - Q[s][a])

我们在这里所做的就是获取原始的 Q 值,并添加我们的更新。更新由剧集的累积奖励(G)和减去旧的 Q 值组成。然后这些都乘以α。

在这种情况下,阿尔法作为我们的学习率。一个大的学习率将意味着我们很快取得进步,但是它冒着做出太大改变的风险。

虽然它最初会很快取得进展,但它可能无法找出它正在学习的任务的更微妙的方面。另一方面,如果学习率太小,代理将学习任务,但这可能会花费很长的时间。就像机器学习中的大多数事情一样,这些是重要的超参数,您必须根据项目的需要进行微调。

履行

现在我们已经学习了控制算法的理论,我们可以开始写代码了。

现在,我们已经成功地生成了自己的玩 21 点的最佳策略。你会注意到原始的硬编码策略和我们新的最优策略是不同的,我们的新策略反映了 Thorps 的基本策略。

结论

我们现在知道如何使用 MC 来寻找 21 点的最优策略。不幸的是,仅凭这一策略,你不会很快赢得很多钱。这个游戏的真正复杂性在于知道何时以及如何下注。一个有趣的项目是将这里使用的策略与关于如何正确下注的第二个策略结合起来。

我希望你喜欢这篇文章,并找到一些有用的东西。任何反馈或意见总是很感谢。完整代码可以在我的 GitHub 上找到

参考资料:

萨顿 r .和巴尔托 a .——强化学习:导论,麻省理工学院出版社,1998 年

Udacities RL 资源库:【https://github.com/udacity/deep-reinforcement-learning

Denny Britz 知识库:https://github . com/Denny Britz/reinforcement-learning/blob/master/MC/MC % 20 prediction % 20 solution . ipynb

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

离开我的风投工作去学习数据科学和机器学习

原文:https://towardsdatascience.com/leaving-my-vc-job-to-learn-about-data-science-and-machine-learning-4dbc15427fc5?source=collection_archive---------1-----------------------

昨天是我在九点资本的最后一天。

两年半前我加入点九时,对风险投资一无所知。我来自比利时,我和我的朋友都没有接触过这个世界。但是我突然有一种想要亲身体验的冲动,于是我开始四处寻找机会。

如果我告诉你我在申请的时候知道谁是第九点或者第九点是什么,那我就是在撒谎。然而,读了他们的工作邀请后,我只是喜欢他们的语气。所以我买了一本基本上是虚拟资本的书,花了几十个小时熟悉这个领域,阅读了 Point Nine 团队的 100 万篇博客帖子——是的,我也认为他们当时有代笔人(我们没有)——在经过不下 5 次 Skype 面试后,终于获得了一个角色。

我的第一天有点难熬,因为我第一次见到这个团队是在一次异地活动中,在一次攀岩活动中,我被卡在了一块岩石上。是的,天气很热,是的,我身后有一个伙伴变得非常紧张,是的,我总是设法让自己处于这种情况下!

从那以后,我一直在爬 VC 岩石,我身后有 Point 的工作人员,我享受着每时每刻。我感到非常幸运,我有机会与这样一个伟大的团队和如此热情的企业家一起工作。我学到了很多,并且仍然认为这份工作是世界上最好的工作之一。

那么,我为什么要离开这么好的工作呢?

当我回顾过去两年半中最让我兴奋的公司时,我意识到两件事:

1)通常涉及一些数据魔术/机器学习,

2)他们对社会产生了某种积极的影响。

一些例子:

  • Vintra ,这是一个视频分析平台,允许公共和私人调查人员利用视频来破案、拯救生命和保护资产。数据=视频监控录像,影响=更安全的世界。
  • Corti Labs ,提供实时诊断帮助、紧急呼叫数据分析以及呼叫接听人员培训模块。数据=紧急呼叫,影响=拯救生命。

机器学习并不新鲜,而且肯定被夸大了。然而,我仍然相信,用它可以做出惊人的事情。每当我考察一家新公司时,我都非常想了解这项技术的详细工作原理。然而,风投工作的性质意味着我不能花费我想花的时间。所以我想我会在晚上和周末学习。

这是六个月前,也是预期膨胀的顶峰。三个月前,失望之余,我意识到我做不到。一个月前,在启蒙运动的斜坡上,我决定退出并全职做几个月。从 1 月 1 日起,我将开始全职学习,并有望达到生产率的最高梯度。

我将如何学习?

我想在网上学习一切,这样我就可以在任何地方学习。

对比课程,征求大家的意见,我起草了这个学习计划

非常欢迎任何建议或意见!这是我的私人邮箱或者直接在表格中留下评论。

我会在表格的第二个选项卡中不断添加我收到的建议。

然后,接下来呢?

不,我不打算在数据科学领域工作。我的计划是 1)获得对数据科学和机器学习的高度理解,2)参与使用这些技术并对社会产生积极影响的初创公司(可能在投资方面,但也可能不是)。

很独特,是吧?是的,这是故意的。作为一名合伙人,我每个月都有机会看到几十个甚至几百个想法。这很神奇,但也有不好的一面:很难保持专注。关注科技行业是有风险的,因为使能技术发展如此之快。话虽如此,但我自信地押注于机器学习和至少未来几年的积极影响。

几年后,产品中的机器学习功能可能会像基于云一样简单。然而,了解如何从中获得好的价值来解决一个特定的问题可能会永远有意义。至于影响力投资,我希望对社会产生积极影响仍能吸引一些人。如果没有,我就去火星!

谢谢

我想感谢所有在我第一次风投之旅中有机会一起工作的了不起的人。

首先,我要感谢 Point Nine 团队——Christoph Janz 和 Pawel Chudzinski,他们向我展示了做一名好的风投真正意味着什么 Rodrigo Martinez,他多次督促我成为最好的,并“矩阵化”了我的思想 Mathias Ockenfels,他在早期以极大的耐心指导了我 Clement Vouillon,他在我的博客帖子上讲了一些糟糕的笑话和很好的建议;我的松露猪同事 Robin Dechant 和 Louis Coppey 以及 amaaaazing 团队:Jenny Buch

其次,我要感谢所有我有机会与之共事并分享他们伟大创业历程的创始人,包括来自 Juro 的 Richard 和来自 Zype 的 Ed。

谢谢你,我希望能很快见到你!

[讲座]进化:从香草 RNN 到 GRU 和 LSTMs

原文:https://towardsdatascience.com/lecture-evolution-from-vanilla-rnn-to-gru-lstms-58688f1da83a?source=collection_archive---------3-----------------------

RNNs evolution

如今,递归神经网络无处不在。像谷歌、百度这样的巨头在生产中广泛使用它们来做机器翻译、语音识别以及许多其他任务。实际上,NLP 相关任务中的几乎所有最新技术成果都是通过利用 RNNs 实现的。

随着 TensorFlow 等出色的深度学习框架的兴起,构建 LSTM 和其他类型的递归网络比以往任何时候都更容易。人们很容易将它们视为一个黑盒。

我们觉得现代 RNNs 背后的直觉是至关重要的。仅仅通过看方程,很难很好地理解 GRU 和 LSTM 网络。事实上,LSTM 网络是香草 RNN 与特定问题斗争的结果。因此,希望理解这些问题和解决它们的方法会使 GRU,LSTM 方程变得更加透明和直观。

现代 rnn 背后的想法真的很美。在今天的讲座“进化:从香草 RNN 到 GRU & LSTMs”中,我们将讨论它们!

这是幻灯片的链接。

非常尊重 R2RT 的博客文章:书面记忆:理解、衍生和延伸 LSTM 。我们的讲座受到他们工作的强烈启发。

[讲座]如何建立一个识别系统(第一部分):最佳实践

原文:https://towardsdatascience.com/lecture-on-how-to-build-a-recognition-system-part-1-best-practices-46208e1ae591?source=collection_archive---------2-----------------------

你好世界!

识别系统有很多实际应用。许多公司需要创建这样的系统来优化他们的业务流程,不仅是像谷歌百度脸书Dropbox 这样的行业巨头。

例如,在医疗保健行业,一些公司为不同的患者表单开发了自动字段提取器,包括将相关数据输入数据库的保险表单。其他公司专注于识别车牌等等。

Example of recognition credit card number

幸运的是,我们在 DeepSystems 有构建图像识别系统的经验。但是由于缺乏互联网上的信息,很难深入这个领域。通过长期的研究和阅读许多论文,我们已经对创建有效的识别系统背后的主要原则有了理解。

今天,我们将与你分享我们的理解,并用浅显的语言解释它是如何工作的。

本讲座由两部分组成。第 1 部分涵盖了如何设计神经网络架构的概念。

第 2 部分(即将推出)详细解释了如何训练这样的系统,即如何进行前向和后向阶段的 CTC 丢失。我们觉得这是非常有价值的,因为不可能找到好的和简单的解释如何 CTC 损失工程。

这是幻灯片的链接。

第一部分:

谢谢大家!和我们在一起。欢迎在评论中提问。

数据可访问性对公共福利和人工智能研究进展的法律和伦理影响

原文:https://towardsdatascience.com/legal-and-ethical-implications-of-data-accessibility-for-public-welfare-and-ai-research-advancement-9fbc0e75ea26?source=collection_archive---------5-----------------------

本文与 加布里埃尔·帕里斯·加尼翁 、Propulsio 360 商业顾问律师 LLP 合著

每一个专注于人工智能的组织都希望并需要同样的东西:更多的数据来训练他们的算法。毫无疑问,今天深度学习系统的许多成功都是基于大型数据集的可用性和收集,这些数据集通常由用户自己提供,以换取免费使用这些服务。

Photo by Matam Jaswanth on Unsplash

1 月早些时候,在蒙特利尔大都会商会组织的人工智能战略论坛上,Element AI 研究小组主任 Valérie Bécaert 向商界发表了关于共享数据以使所有组织都能使用人工智能的重要性的演讲。在大数据聚集在少数强大公司手中的时代,这延续了经济不平等,并破坏了人工智能在社会事业中的应用。随着时间的推移,这种差距也必然会加大。科技巨头成倍增加他们的数据收集应用程序,并阻止访问这些专有数据,即使是自己生成这些数据的用户——参见脸书生成的影子档案。[1]

更开放的数据获取政策的另一个积极成果是促进科学界、初创企业和面向公益的非营利公司的研究。

到 2030 年,专家预测人工智能将为世界经济贡献高达 15.7 万亿美元[2]。如果什么都不做,没有为数据可访问性颁布标准,这些利润将直接落入极少数人手中。为了让人工智能的发展成为社会流动性的载体,这些收益和随后的财富创造必须以公平的方式进行分配。我们认为,对大型数据集(这对训练深度学习系统至关重要)的可访问性可以将这项技术的集体使用更多地导向公共福利。

此外,有时,个人、公司和非营利组织(它们通常是大型科技公司的数据生成者)受到他们的摆布。他们对自己生成的数据以及如何使用这些数据缺乏控制,也可能产生负面影响。当他们从使用大科技的产品中获得的东西与后者的商业目标不一致时,他们会发现自己无能为力。例如,脸书最近宣布将改变他们的算法,降低出版商帖子的重要性,这对新闻提供商和其他十多年来一直依赖脸书传播信息的企业来说是灾难性的。

Photo by William Iven on Unsplash

现在让我们考虑以下事实:

研究公司 IDC 预测,到 2025 年,数字生态系统中捕获的数据将达到 180 zetta byte(zetta byte = 1 后跟 21 个 0)[3]

亚马逊使用卡车拉着集装箱来管理他们的 AWS 集群所需的存储空间量。[3]

这为我们提供了一个强有力的指标,表明正在收集的关于用户及其在线行为的数据量只增不减。这些公司盈利的核心原因之一来自于他们将这些数据货币化的能力,并随后通过数据经纪人将这些数据出售给广告商。[4]

鉴于创造赚钱产品和服务对数据的严重依赖,以公平的方式访问此类数据对于市场正常化和提高市场竞争力更为重要,从用户角度来看,这可能会带来更好的结果。

Photo by Scott Webb on Unsplash

要求访问公共数据的初创公司

随着大型组织收集的大数据不断具有越来越大的市场价值,初创公司开始向法院寻求授权,以获得对这些数据的访问权。

这些小公司声称,公司对公开可用数据的控制代表着反竞争行为。

2016 年,hiQ Labs 是一家初创公司,它使用 LinkedIn 的公开数据来构建能够预测员工行为的算法,例如他们何时可能辞职以及相应地提升谁,该公司收到了 LinkedIn 的停止函,称收集他们的公开数据违反了该公司的使用条款。hiQ 实验室将此案告上法庭,因为他们的商业模式完全依赖于他们从 LinkedIn 获得的这些公共数据。[5]

2017 年 8 月,旧金山的美国地区法官 Edward Chen 支持 hiQ Labs,并命令 LinkedIn 在 24 小时内删除任何阻止 hiQ Labs 访问公共档案的技术。在他看来,通过阻止 hiQ 访问 LinkedIn 公共档案来维护控制权可能是一种限制竞争的手段,这违反了加利福尼亚州的法律。此案的最终口头辩论预计将于 2018 年 3 月进行。

访问加拿大的房地产数据

在加拿大,竞争局对多伦多房地产委员会提起诉讼,该委员会是一家非营利公司,经营一个收集房地产信息并向其成员发布的在线系统。TREB 的政策限制其成员交流和分发其收集的一些数据,如销售价格。

Photo by Giammarco Boscaro on Unsplash

竞争管理局辩称,这种对数字化数据的限制性分发阻止了竞争,也阻碍了创新和新商业模式的出现,因为它禁止房地产经纪人在其网站上发布销售数据。2017 年 12 月,联邦上诉法院支持竞争局,并命令 TREB 允许其成员在网上分享上市房产的销售历史。[6]

这一决定预计将在加拿大对组织如何在市场上分发数据和请求更开放的数据产生广泛的影响。

因此,拥有更加开放的公共数据集可以促进更加面向公益的商品和服务的发展。

我们的建议如下:创建数据共享标准,这些标准由垂直行业驱动,以支持研究人员、年轻企业家等。为公众利益制造产品和服务。通用数据保护条例(GDPR) [7]将于 2018 年 5 月 25 日生效,这开创了一个宽松的先例(当公司要求他们能够在他们要求时以标准化格式提供关于用户的数据)——随着这一条例的生效,看看公司如何决定采用可以跨不同数据处理器解释的标准将是有趣的(该术语在 GDPR 用于指用户可以在不同服务提供商之间切换)。

公共数据共享的一些潜在缺点

更开放的数据政策也有其寒蝉效应。即使公开共享匿名化的数据集也可能是一项挑战,因为复杂的统计方法加上马赛克效应(一种用于组合来自不同来源的信息以创建更丰富的目标概况的技术)可能会逆转匿名化过程。事实上,考虑到去年 41%的加拿大公司在安全漏洞后有敏感数据被盗,数据共享可能会危及用户敏感信息的隐私。[8]

这一点已经在过去多次得到证明。其中一种情况是,用户的性取向是从网飞公开发布的数据集[9]中的电影评级中推断出来的,这是通过交叉引用 IMDB 上对这些数据集之间常见的某些罕见电影的评级来实现的。

在另一个案例中,AOL 向公众发布了搜索查询,具体到用户的家庭住址、医疗需求、宠物主人等等。[10]

还必须考虑到,尽管用户可能已经接受通过条款和条件收集和分享其个人数据,但他们的同意是否实际有效仍存在争议。当与深度学习方法结合时,不同数据集的链接也可能导致身份欺诈的风险[11]。为了保护用户的隐私,我们需要制定法律和技术机制,在保护个人隐私的同时,鼓励和平衡这些数据集的共享。

另一个想法可能是允许类似微支付的报酬模式,在这种模式下,可以获得用户的明确同意,使用他们的数据执行特定的活动。用户对其数据隐私的强烈需求以及他们对侵犯这一权利的服务的潜在抵制可能会刺激这种行为。

你同意来自企业的大型数据集有助于推动公益研究的观点吗?做这件事的最好方法是什么?在评论区分享你的想法,让我们知道。

关于我在人工智能道德发展方面所做工作的更多信息,请访问https://ATG-abhishek . github . io

参考文献:

[1]脸书如何找出你见过的每个人—https://gizmodo . com/How-Facebook-figures-out-every one-you ve-even-met-1819822691

[2]人工智能将为全球经济增加 15.7 万亿美元—https://www . Bloomberg . com/news/articles/2017-06-28/AI-seen-adding-15-7 万亿美元—全球经济的游戏规则改变者

[3]数据正在催生新经济—https://www . economist . com/news/briefing/21721634-how-it-shaping-up-Data-rise-new-economy

[4]数据经纪人呼吁透明度和问责制—https://www . FTC . gov/system/files/documents/reports/DATA-BROKERS-Call-Transparency-account ability-report-federal-trade-commission-may-2014/140527 DATA broker report . pdf

[5] LinkedIn 无法阻止 Startup 抓取公共个人资料数据,美国法官规则—https://gadgets . ndtv . com/social-networking/news/LinkedIn-Cannot-Block-Startup-From-Scraping-Public-Profile-Data-US-Judge-Rules-1738096

[6]上诉法院维持命令房地产经纪人公开房屋销售数据的裁决——http://www.cbc.ca/news/business/treb-court-ruling-1.4428262

[7]欧盟 GDPR—https://www.eugdpr.org/

[8]安全漏洞代价高昂—https://www . investment executive . com/news/industry-news/Security-breakes-prove-cost/

[9]Arvind Narayan an 和 Vitaly Shmatikov 对大型数据集进行稳健的去匿名化处理—https://arxiv.org/pdf/cs/0610105.pdf

[10]AOL 搜索者暴露了一张脸№4417749—http://www.nytimes.com/2006/08/09/technology/09aol.html

[11]Abhishek Gupta 著《欺诈的演变:大规模数据泄露和广泛人工智能解决方案部署时代的伦理含义》——https://www.itu.int/en/journal/001/Pages/12.aspx

Fast.ai 深度学习课程第一课

原文:https://towardsdatascience.com/lesson-1-in-fast-ai-deep-learning-course-ccbae67fa806?source=collection_archive---------1-----------------------

在之前的帖子中,我尝试演示了 fast.ai 的“入门”部分。第 1 课也是从解释安装开始的。获取笔记本和辅助文件对实施至关重要。这些文件的最新版本在 github ( utilsvgg16vgg16bn )中。

训练需要结构化数据。训练文件夹里有 12500 张狗的照片和 12500 张猫的照片。总共 25000 张照片中的 2000 张照片将被移至有效组。此外,为了快速获得洞察力,为每个类别(猫、狗)创建包含 20-50 张照片的样本文件夹将非常有用。

AWS 回复了我的 p2 使用请求,因此我可以使用它。首先,由于价格原因,我尝试使用现货实例。虽然按需实例的成本为 0.90 美元/小时,但根据您的出价,现货实例的成本可能是这个价格的四分之一。然而,这种方法也有一些缺点。当有人出价高于你的出价时,你的实例将在两分钟内关闭。因为 EBS,你不能保存你的作品。解决这个问题的一种方法是在终止前分离磁盘,但是这需要停止实例。它立即终止,我不能分离它。AMI 的一些功能在 spot 中并不有用,因为它是为点播而准备的。我不想浪费更多的时间,所以我回到了按需服务,尽管它很贵。

让我们返回终点站。Aws-alias.sh 使得在终端上连接 Aws 变得容易。只是写 aws-start 然后用 aws-ssh 登录。登录后,不要惊讶当你开始 jupyter 笔记本。用“dl_course”加密。一切正常。

您将通过这些页面学习使用 Kaggle CLI。使用 Kaggle CLI,可以下载数据和提交解决方案。

Screenshot by the author

第一课之后,笔记中有家庭作业部分。我很难从模型中获得结果并创建预测文件来提交 Kaggle。经过在论坛上的研究,这些文件被放在 github 页面的教程中。

这个笔记本帮助我创建提交文件。我将我的文件结构和方法与这个笔记本进行了比较。在我完成提交并开始第 2 课之后,这个文件在那里被提到。所以,你应该首先尝试你自己的,这是非常重要的学习。否则你只会复制代码。

作为作业的结果,我把我的作品提交给了 Kaggle 竞赛。这是一个粗略的解决方案,所以我得到了这个结果:

Screenshot by the author

第 2 课涉及更多的概念,我会用深入的知识来创作文章。

从我的第一个数据科学项目中获得的经验

原文:https://towardsdatascience.com/lessons-from-my-first-data-science-project-630eb20af8a1?source=collection_archive---------20-----------------------

我作为一名数据科学家开始了我的职业生涯&分享交付我的第一个全功能数据科学管道的经验。

回顾过去,我意识到我犯了很多错误并且对这个领域有很多误解!

1.数据很乱

与 Kaggle 不同,现实生活中的数据并不总是在漂亮的 CSV 文件中。

您经常会遇到数据以不太理想的格式存储的情况,如 PDF/DOC/DOCX/XML/HTML 等。根据需要提取的数据,原始数据可用的格式会大大增加实际提取的难度。

在我们的例子中,我们有大量的数据存储在 pdf 中。如果您遇到这种情况,这里有一些方便的开源库:

2.标签数据并不总是可用的

机器学习领域(肯定是深度学习领域)的一大障碍是缺乏高质量的标记数据。这通常会导致使用监督方法解决手头问题不可行的情况。

通常有三种方法可以解决好的标记数据不可用的问题:

  • 雇佣一群可以为你手工标注数据的人
  • 使用 Amazon Turk、tractable.ai、mighty.ai 等付费工具。
  • 向无监督学习问好。

在你决定向你的老板寻求第(一)或第(二)种选择之前,先获得以下问题的答案

  • 与无监督方法相比,有监督方法有哪些改进?(这并不容易)
  • 对于这样的改进,我需要多少标记数据?
  • 项目是否有完成任务所需的时间和资金?

3.更多的数据不会自动带来更好的性能

有些时候,更多的数据会有帮助,有些时候则没有。

如果更多的数据对您的模型的性能几乎没有影响,请问自己以下问题

  • 对于分类器/回归器来说,我的特征是否足以预测结果?
  • 该模型是否存在高偏差或高方差?
  • 是数据太吵了?
  • 预处理做的对吗?(在涉及自然语言处理的问题中极其重要)

永远记住:垃圾入=> PREDICTIVE MODEL = >垃圾出

4.保持事情简单

深度学习和如下流行图表的最新进展导致许多人认为深度学习方法应该永远是第一选择。

我不这么认为。深度学习方法不能保证总是比传统方法产生更好的结果。即使他们这样做了,他们几乎总是以牺牲可解释性为代价。维护数据科学中的可解释性很难,但很重要。

为什么可解释性很重要?

高度的可解释性有助于您改进工作,并更有效地与非数据科学领域的人交流。

让我们举一个例子,你开发了一个 3 层的神经网络。不仅很难确定错误预测的根本原因,而且向没有数据科学背景的人传达下面导致预测的等式将是一场噩梦。

根据我的经验,应该按照以下顺序解决问题:

  • 手工管理的试探法(对于循环、If/Then 条件)
  • 简单的机器学习算法(线性回归、逻辑回归、决策树等。)
  • 高级机器学习算法(RandomForest,XGBoost 等。)
  • 浅层神经网络
  • 深度神经网络

5.始终保持文档更新

我知道这听起来像编程 101。所以我为什么要重复?

数据科学项目是迭代的。你的第一个模特永远不会是你的最后一个。拥有一个记录良好的代码将确保您(和其他人)在稍后重新访问您的方法时理解它。

6.模块化编程使事情变得更容易

随着您的管道开始变得更加复杂,代码库也会变得更加复杂。

现在想象一下,你需要在管道中做一个小小的改变。但是所有的步骤都在一个大的功能块中执行。如何在不破坏管道的情况下做出相关的改变?

拥有多个执行独立任务的函数和一个调用所有其他函数的主函数使得执行更改更加容易。这有助于提高代码的可读性,因为它有助于很容易地将代码追溯到特定的操作。

7.变量应该是人类可以理解的

避免制造 df/data 之类的变量。不是所有的东西都是熊猫的数据框架!

如果你已经有了一个正在运行的项目,我建议你回去改变变量。如果你懒得到处改变变量,可以使用 PyCharm 中的内置函数,比如refractor

8.单元测试很重要

这是软件开发的长期最佳实践,但在数据科学等定量领域被低估了。单元测试的主要需求来自于数据科学项目是迭代的这一事实。这需要你和其他人不时地回到同一个代码库。在设计单元测试时,确保(ii)它们覆盖了您对函数的预先假设(ii)其他人在查看代码库时可以立即识别该函数试图实现什么。

要了解更多关于数据科学中的单元测试,请查看由 Mohammed Sunasra 撰写的这篇文章

结论

你的第一个数据科学项目将会既令人沮丧又充满乐趣。你从 MOOCs,Kaggle 等开始。并开始欣赏其他东西,如通信、应用程序可伸缩性、表示和可解释性。

找数据科学工作?阅读本文作者彭慧琳

数据科学新手?阅读这篇文章作者哈里森·詹斯马

如果你想联系我,可以通过 Linkedin 联系我,或者通过 k.mathur68@gmail.com 联系我。

感谢您的阅读!

利用机器学习构建视频烟雾探测器

原文:https://towardsdatascience.com/lessons-learned-building-a-smoking-detector-for-video-with-machine-learning-5a0e93dfa8ec?source=collection_archive---------16-----------------------

Results from a smoking detection classification model

作为一个花了很多时间与实现机器学习的媒体公司合作的人,我被问及很多关于在视频中检测吸烟的能力。对于向其他国家分发媒体内容来说,这是一个大问题,但它也要求我们就人工智能的现状提出一些棘手的问题。这个故事记录了我试图建立和测试一个机器学习模型来检测电影中人们何时吸烟的尝试,也是我所学的总结。

为什么抽烟?

Come on Johnny — stop blowing smoke in my face

吸烟实际上是一个很难分类的行为,甚至只是想想这个问题就迫使你在 computer-sand 中画一些线,这对建立机器学习模型很重要。吸烟仅仅是吸一口烟的行为吗?点根烟怎么样?或者只是用手指捏着一根冒烟的白棍子?如果你在屏幕上看不到香烟,但有一些白烟从角色的鼻子或嘴里冒出来,这是吸烟吗?

不同的国家对电影和电视中如何描述吸烟有不同的规定。例如,在土耳其,电视广播不得不模糊吸烟的内容。搞砸了会让你被政府罚款。

因此,如果我们能够建立一个机器学习模型来检测电影或电视中的吸烟,我们可能能够帮助一些人节省大量时间和金钱,而不用手动操作。

但是从图像识别的角度来看,这是一个很难解决的问题。

我在之前已经写过关于视频图像识别能力的挑战,所以如果你想了解更多,请阅读…我会等的。

培养

我们希望检测电影中的吸烟,因此训练数据的自然来源是人们吸烟的电影。在 YouTube 上快速搜索发现了几个视频,本质上是电影中人们吸烟的超级剪辑。

成功的关键是找到有人们吸烟镜头的视频,以及同样的人,最好是在同一个场景,不吸烟的镜头。这是关键。你需要告诉分类器什么是吸烟,就像你需要告诉它什么不是吸烟一样。

因此,我打开了 good ol' iMovie,将 YouTube 视频放入项目中。然后我仔细检查并精心编辑了人们吸烟的画面。我对嘴里叼着香烟的人划清界限。我保存了那个奇怪的新视频,并将其导出到一个文件中。

然后我编辑了一串相同场景的画面,但是在香烟进入嘴里之前或之后(多么奇怪的句子)。

现在我有两个视频,长度略有不同,一个有吸烟,另一个没有。下一步是将它们切成帧,以便我可以教授机器学习模型。

幸运的是,这部分很容易。只要打开终端,确保你已经安装了 FFMPEG ,并输入以下命令:

$ffmpeg -i path/tp/video.mp4 path/to/output/label%04d.jpg -hide_banner

在每个视频上运行,把你所有的帧放进标有“吸烟”和“不吸烟”的文件夹里。

现在,您可能在每个文件夹中有不同数量的 jpegs,所以我们将不得不删除一些以确保两个类以平衡的方式训练。如果一个类太多,模型就会偏向那个类。但是你也不能仅仅从一个类中选择 X 个文件来删除,你必须随机地删除这些文件,以免进一步影响模型。

我花了太多时间在网上搜索,试图找出如何从文件夹中随机删除 X 个文件。我最终使用了这个终端命令(N 是您想要删除的文件数):

$ ls |sort -R |tail -$N |xargs rm

好了,现在我们在每个文件夹中有相同数量的图像,是时候使用一些由机器盒提供的漂亮工具了。

下载并运行开源工具[imgclass](https://github.com/machinebox/toys/tree/master/imgclass),它会为你处理大量训练和验证数据的困难部分。它要求你有分类框在后台运行,所以确保你已经下载了。

当您运行 imgclass 时,它将:

  1. 扫描目录。
  2. 分离出 80%的数据,用这些数据来教机器学习模型。
  3. 用剩余的 20%数据验证准确性。

当我这样做的时候,我得到了大约97%的精确度,这似乎高得令人怀疑。我可能让模型过拟合了,但是为了确定,我们必须测试。

测试

所以我现在有了一个经过训练的机器学习模型,可以检测视频中的吸烟情况。但不知道效果如何。我需要找到其他不属于训练集的人们吸烟的视频。所以我回到 YouTube,下载了一段《广告狂人》的视频。我知道,只是从编辑训练数据,没有场景从广告狂人在训练集,所以这应该是一个很好的测试。但是怎么考呢?

这是最难的部分。我需要将视频分割成帧,并在 Classificationbox 中针对训练好的模型运行每一帧,然后评估结果。

“但是你是怎么做到的呢?”我对着猫尖叫。

如果你有任何脚本印章,他们将在这一点上派上用场。如果你没有,你需要使用一个平台来处理视频,训练分类框(或其他机器学习模型),并在某种 UI 中显示结果,这样你就可以验证准确性。我使用的一个非常方便的程序叫 aiWARE,它可以让你注册并免费运行这类测试,而不需要写任何代码。

如果你对写代码感兴趣,那么你会发现接下来的这一点令人厌恶。这里有一个 Golang 脚本,我用机器学习模型来验证一个视频文件(在文件夹中被分割成帧),将结果打印到帧上,并将该帧输出为 PNG。然后,我可以使用 FFMPEG 将所有打印的帧组合成一个视频,作为后期处理。

下面是一个输出示例:

如果我更擅长计算机,我可能会想出如何让那个该死的标签变得更大,但是我会把它留给真正的程序员去想(可能很快)。

接下来,我将所有帧拼接成一个视频,以便我可以观看整个场景,并判断我的机器学习模型。

$ ffmpeg -i [label]%04d.png -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4

注意到左上角的小标签了吗?戴上你的眼镜…现在你看到了吗?这是一个很好的方式来直观地看到你的模型在任何给定的视频上做得有多好。分数也很重要,因为它从模型中给你一些反馈,告诉你你发送给它的东西在一个特定的类中有多确定。

一旦你在 10 个视频中尝试了这种方法,你将开始看到置信度的一种模式,你可以开始忽略任何低于某个阈值的东西。

太好了,现在怎么办?

让吸烟检测为您的用例工作的关键是实验。如果你有合适的工具,实验会很简单,也很划算。

现在我已经从我的模型中获得了一些反馈,我可能会尝试教它越来越多的吸烟和不吸烟的例子,看看我是否可以减少假阳性和假阴性。

理想情况下,我会从我的真实用例中尽可能多地抓取例子,并将其分解成框架进行教学。

分类框的好处在于它支持在线教学。您可以在它运行时教授它,而不必重新部署或经历昂贵的培训周期。随着时间的推移,当你从它自己的结果中给它反馈时,这让你逐渐地改进它。

这是机器学习成功的秘诀。我无数次看到它工作。把精力花在你的训练数据上。

根据您的数据训练的模型将始终优于根据通用数据训练的模型。

所以现在你有了自己做这件事的工具。如果你用自己的分类框或者在 aiWARE 内部开发了一个很棒的模型,请确保你截取了一些截图,在 Medium 上与我们分享,或者通过推特发给我们玛奇纳——@ machineboxio

经验教训:Python 3 的数字海洋

原文:https://towardsdatascience.com/lessons-learned-digital-ocean-for-python-3-e2442db4246f?source=collection_archive---------2-----------------------

这篇文章是正在进行的系列文章的一部分。我花很多时间尝试新技术。更多的时候,是因为一个类似于:“你应该试试【在此插入技术】,超级简单!”。

事实证明这种情况很少发生,所以每次我花几个小时试图让一些东西工作时,我都会发布我的解决方案,以及我在这个过程中学到的任何技巧和诀窍。

Digital Ocean 是一家基于云的服务器提供商,拥有非常合理的计划,允许您将计算从您的计算机转移到云中,从而节省您的时间并保持您的计算机新鲜!

我最初按照孙铁麟·梅斯特的教程进行设置,但很快意识到我想做得更多(尽管我强烈推荐该系列的其余部分,从命令行的数据科学)。这被证明是有点棘手,所以这里是我的演练。

1.注册

前往数字海洋并创建一个账户,使用 Paypal 或信用卡(如果你使用上面的链接,你将获得一些免费积分,我也会。如果你不想这样做,只需点击这里)。

如果你是学生,你还可以从 Github 学生包中获得 50 美元的积分(我也强烈推荐)。当我注册时,Digital Ocean 最初不接受我的代码,但我提交了一张支持票,他们在几个小时内就把它记入了帐户。

2.你的第一滴

Droplets 是专门为您保留的服务器空间。你只有在有液滴的时候才会带电(不管它是开着还是关着),但创造和破坏它们很容易,所以不用担心在你不积极使用它的时候会带电。

在“DO”面板的右上角(如果您还没有 Droplet,则在中间),找到“创建 Droplet”按钮。

单击它会将您带到设置页面。第一个选项是图像:

您将没有快照选项(稍后会详细介绍),但是默认选项(Ubuntu)是我们想要的,所以您在这里不需要做任何事情。

第二个选择是定价计划:

在这里你可以看到你得到了什么,以及它的价格。水滴存在的时间是按小时收费的,所以除非你结束后不删除它,否则你的费用会比每月报价低很多。

你选择哪一个取决于几件事:

  • 你要载入内存的文件有多大?(例如熊猫数据帧)。价格下面第一行是水滴有多少内存/多少 CPU。
  • 你的流程可以分布式吗?(想想sklearn njobs= -1)。如果可以的话,多个 CPU 会加快处理速度。同样,如果您有大量数据,将数据分成两半并同时运行作业将节省时间,但这仅适用于具有 1 个以上 CPU 的 droplets。
  • 你要上传的数据文件有多大?这是第二行,可用的存储量。
  • 最后一行表示允许的数据传输量(上传+下载)。除非你在做非常疯狂的事情,否则 1TB 足够了。

我建议开始时选择 5 美元/月。如果你碰壁了,升级很容易。

第三步是添加块存储。最初你不需要这个。

第四是选择数据中心:

我在爱尔兰,所以选择了伦敦。选择离你最近的。

最后一步是启用监控(稍后会详细介绍)并给你的 droplet 起一个真正有用的名字!

然后点击创建水滴,大约一分钟后,你就一切就绪了!

3.初始设置和快照

当你完成后,你会收到一封电子邮件从数字海洋与 IP 地址,用户名和密码。复制 IP 地址,启动命令行并输入:

ssh root@[IP Address]

如果这挂起并且没有任何反应,您可以尝试:

ping [IP Address]

看看你是否有联系。如果没有,你可能被外部防火墙(你的工作单位或大学)阻挡了。这发生在我身上,你无能为力:

Hit CTRL-C to stop it after 10 or so packets

如果你确实收到了ssh root@[IP Address]的回复,会有一堆短信问你是否要继续。写下yes并按回车键。

然后会要求您输入密码。从邮件中复制并粘贴,然后按回车键。然后,您需要更改 root 密码。这样做很安全,因为你不会经常登录 root,但如果其他人这样做,他们完全可以破坏你的 droplet。

接下来,您想要创建一个用户:

adduser [username]

其中[用户名]是您想要的任何东西。

你必须为这个用户创建一个密码,它会要求你提供一些个人信息。如果你愿意,输入这个,或者跳过它(按回车键),都没关系。

接下来,给你的新帐户权限在服务器上做事情

usermod -aG sudo [username]
gpasswd -a [username] sudo

这使您能够在不登录 root 用户的情况下进行更改。

最后,更改时区:

sudo dpkg-reconfigure tzdata

并选择您当前所在的城市。

不错!我们都在 root 上设置好了。现在,我们可以退出并检查您的用户帐户。

exitssh [username]@[IP Address]

登录后,第一步是配置 bash 配置文件,让您的生活更轻松。

nano .profile

如果你以前没有用过 Nano,它是一个简单的文本编辑器。使用箭头键移动,Ctrl+k剪切一行,Ctrl+u粘贴一行,Ctrl+o保存,Ctrl-x退出。

您可以在这里添加别名(快捷方式)以使生活更轻松。我使用 Python 3 和 Pip 3,所以我通常通过设置来避免混淆:

alias python="python3"
alias pip="pip3"

当我想更改或检查我的 bash 配置文件时,我也讨厌键入nano ~/.profile,所以我也使用别名:

alias obp="nano ~/.profile"
alias sbp="source ~/.profile"

您还可以在此添加任何其他别名。用Ctrl+o保存,用Ctrl-x退出。

要实现这些更改,您需要获取概要文件:

source .profile

(顺便说一句,在找到新的别名快捷方式之前,不能使用它们,所以简单地输入sbp还不行,但是在你找到它之后就可以了)。

apt-get有点像命令行的 Pip,应该在我们继续之前更新。

sudo apt-get update

Python 3 已经安装了,但是 Pip 还没有,所以让我们继续获取并更新它:

sudo apt-get install python3-pip
pip install -upgrade pip

现在你可以pip install你所有的常规 Python 包了!你马上就可以。出于某种原因,Matplotlib 和其他一些软件包在 Ubuntu 上有问题,但是您可以通过运行以下命令来解决这些问题:

sudo apt-get install libfreetype6-dev libxft-dev
sudo apt-get install python-setuptools

太好了,现在你可以用pip3 install发疯了。如果您有一个用于所有安装的requirements.txt文件,现在就可以运行它。

最后, AG 是非标准的命令行搜索工具,所以如果你愿意,你也可以安装它:

sudo apt install silversearcher-ag

太好了,你都准备好了!现在,这是一个相当大的工作量,每次都必须这样做是很糟糕的。这就是数字海洋快照的用武之地!

这是一种将你当前的 droplet“另存为”的方法,这样当你下次创建一个新的 droplet 时,你就可以加载那个图像,然后你就可以从你离开的地方开始了!完美。

使用sudo poweroff关闭你的 droplet,进入你的数字海洋 droplet 页面上的快照菜单项:

快照不是免费的,它们每月每 Gb 0.05 美元。我在安装 Pandas、Numpy、Matplotlib 和其他一些软件包时拍摄的快照是 1.85Gb,所以每年大约是 1.11 美元。考虑到每次设置一个水滴会节省你 10 分钟,还不错!

由于您的 droplet 已经关闭,请点击“拍摄实时快照”按钮,数字海洋将完成剩下的工作。

这里有一个旁注,你似乎不能从一个更便宜的液滴定价方案中读出一个快照。只是一些需要记住的事情。

如果你想升级你的定价方案,请点击“调整大小”菜单项。同样,你不能在这里降级,如果你想,你需要从头开始创建一个 droplet,并重复上述步骤。

要重新打开 droplet,请前往数字海洋,在 droplet 页面的右上角有一个开/关开关。重新打开它,你就可以上传数据了。

4.通过 SFTP 上传数据

现在,如果你的个人电脑上有数据,想把它上传到云端,你需要通过 SFTP(安全文件传输协议)来实现。这是相当容易的,虽然它没有闪电快。

首先,建立一个 SFTP 连接:

sftp [username]@[IP Address]

现在,您可以使用普通的命令行功能,如cdlspwd,在服务器上的文件系统中移动。然而,由于某种原因,自动完成(tab)在 SFTP 上不起作用。出于这个原因,我建议把你所有的文件和代码上传到主目录,然后用ssh重新登录,用mv和自动完成功能移动内容。相信我,这简单多了。

那是在服务器端,但是在你的个人电脑上移动呢?同样的命令也可以工作,但是你需要在它们前面加上一个额外的l,即lcdllslpwd。找到本地保存文件的目录,然后使用以下命令将它们上传到服务器:

put [localFile]

或者对于整个目录:

put -r [localDirectory]

这并不算快,对于我的 1.5Gb 数据文件,每个文件大约需要 20 分钟。很烦人,但是你能做的不多。您可以并行上传,但这意味着打开一个新的命令行标签,并再次登录 SFTP,再加上两个连接都慢了一半,所以总时间是一样的:(

您可以通过运行以下命令来查看您使用了多少存储空间:

df -h

作为将来的参考,从服务器下载文件非常简单:

get [remoteFile]

或者

get -r [remoteDirectory]

现在,一旦你的数据文件上传到服务器上,你也可以上传你的 python 脚本了。如果您的本地目录配置与远程目录配置不同,请确保更改代码中的任何文件位置。

从服务器上删除文件也和本地略有不同,因为rm -rf directory不起作用。你需要rm filename删除一个文件,或者清空一个目录然后rmdir directory删除一个文件夹。

这足以让你开始,但如果你对更高级的选项感兴趣,这里有一个很好的教程。

我强烈建议在数据的小子集上本地测试你的所有代码(我使用 PyCharm,它很棒,也有免费的学生许可证。)通过远程连接进行故障排除可能很烦人。

5.运行计算

现在,你已经准备好运行一些计算了。使用ssh重新登录,整理所有文件,使用python filename.py运行任何代码,就像在本地计算机上一样。

如果当你尝试运行一些代码时得到一个Killed响应,这意味着你没有足够的内存来完成这项工作。你有两个选择。关闭并升级您的定价方案,或者创建一个交换文件(更多信息见下文)。

打印错误日志将为您提供关于错误的更多信息:

sudo cat /var/log/kern.log

您可以在数字海洋仪表板上监控作业进度,该仪表板显示了一些漂亮的使用图表:

您甚至可以设置警报,以便在指标低于某个级别(如 CPU)时收到电子邮件,这可以用来让您知道工作何时完成!单击图形页面顶部的“创建警报策略”进行类似设置。

一旦你完成了你的处理,你可以使用 SFTP 从云中get你的文件,然后销毁 droplet,这样你就不会继续被收费了!

现在给你一个警告:写入文件时要小心。

我浪费了很多时间运行一个pandas apply函数,然后用df.to_csv('filename')保存结果。如果服务器有任何问题(很可能会有,下面会有更多),在写入文件之前,您将会丢失所有内容。

我的解决方法是遍历整个数据框并逐行打印结果:

*for* row *in* range(len(df.index)):
    col_value = df.ix[row,:].values[2]
    ind = df.index[row]
    with open("./data_file.csv", "a") as file:
        file.write(ind + ',' + function(col_value) + '\n')

这实际上是将我的数据写入了csv,然后我就可以根据索引值合并数据帧来排列数据。

result = pd.concat([df, new_data], axis=1, join_axes=[df.index])

没有apply漂亮,但是有时当处理这种规模的数据时,最好牺牲一些性能来确保您确实得到了您想要的数据!

6.提高性能

DO 最大的好处之一是,您的 droplet 中可以有多达 20 个 CPU,它们可以并行运行处理。这比在一个 CPU 上处理所有数据要快得多。

您应该知道您的计划有多少个 CPU,但是如果不知道,您可以使用下面的代码来检查:

cat /proc/cpuinfo | grep processor | wc -l

我有 2 个,所以这意味着我可以同时运行两个进程。在我看来,这不会减慢任何一个过程,所以如果你把任务分成两半,你可以有效地工作两倍的速度。最好的方法是将所有的数据分成两半,然后对每个数据运行相同的脚本。在 Python 中,在用 pandas 导入您的数据后,我会添加以下代码。

import sysnumber_of_cores = 2
length_of_df = len(df.index)
stream = sys.argv[1]if stream == 1:
    start = 0
    end = length_of_df // number_of_cores
else:
    start = length_of_df // number_of_cores
    end = -1data_to_process = df.iloc[start:end,:]output_filename = "output_data_" + str(sys.argv[1]) + ".csv

然后,您可以从命令行运行

python script.py 1

它将处理前半部分的数据

python script.py 2

它将处理第二个。使用以下命令在最后合并两个数据文件

cat output_data_2.csv >> output_data_1.csv

7.解决纷争

我最头疼的是让我的脚本运行完成。出于某种原因(我从来没有弄清楚),服务器会停止运行我的处理,然后我不得不手动重启它。我的使用图表如下所示:

真的不理想,尤其是我的大学防火墙阻止了我的连接,所以我不得不等到我回家重启东西。

我的解决方案的第一部分是找出 for 循环的重新开始点,这样我就不用重新计算了。我使用了subprocess模块,这样我就可以在 python 脚本中运行命令行函数:

import subprocessstream = int(sys.argv[1])if stream == 1:
    stop = 3387532
    data = "./data.csv" a = subprocess.Popen(['wc', '-l', data], stdout=subprocess.PIPE)
    wc = int(a.communicate()[0].rstrip().decode().split(' ')[0]) start = 0 + wc

我的文件中的总行数是 6,775,065,我有 2 个 CPU,所以像上面一样,我将停止索引设置为文件大小的一半。subprocess.Popen返回命令行函数的结果,在本例中是wc -l ./data.csv,或者检查输出数据中的行数。stout=subprocess.PIPE使输出更容易处理。下一行检索输出数据的实际行数,然后start被相应地设置为。

这意味着每当系统崩溃时,我可以简单地运行:

python script.py 1; 
python script.py 2;

在不同的终端屏幕上,我的两半数据会在适当的地方重新启动。一个好结果!

然而,这并没有阻止我的服务器崩溃,也没有在崩溃后自动重启处理。一些研究让我想到了 crontabs,它允许在特定的时间段评估函数。您可以通过以下方式查看当前的 crontabs:

crontab -l

这里不应该有任何东西,所以您可以使用以下命令创建一个:

crontab -e

第一次,你会被要求选择一个文本编辑器,Nano 是最简单的,但是这可以在以后通过运行'select-editor'来改变

我不会讲太多细节,但是文件的最后一行看起来是这样的:

# m h  dom mon dow   command

这代表分钟、小时、月、日和命令。这允许您将命令设置为在特定的时间间隔运行。几个例子:

*/10 * * * * eval "python3 script.py"

每 10 分钟运行一次脚本。

10 * * * * eval "python3 script.py"

每小时在整点后 10 分钟运行脚本。

10 5 * * 3 eval "python3 script.py"

每周三 5 点 10 分运行脚本。

你明白了。对我来说,我想每 10 分钟检查一次我的服务器是否崩溃,如果是,重启它。所以我的 crontabs 是:

*/10 * * * * eval "python3 sys_test_1.py"
*/10 * * * * eval "python3 sys_test_2.py"

(我必须有两个,因为从同一个文件在不同的 CPU 上运行 python 脚本很困难,这样更容易)。如果你感兴趣,这里有更多关于 crontabs 的详细解释

然后我的文件sys_test_1.py看起来像这样:

data = "./data.csv"a = subprocess.Popen(['wc', '-l', data], stdout=subprocess.PIPE)
wc_1 = int(a.communicate()[0].rstrip().decode().split(' ')[0])if wc_1 > 3387530:
    exit()
else:
    time.sleep(15) b = subprocess.Popen(['wc', '-l', data], stdout=subprocess.PIPE)
    wc_2 = int(b.communicate()[0].rstrip().decode().split(' ')[0]) if wc_1 == wc_2:
        subprocess.call(["python3", "run_comp.py", "1"])

所以我检查文件中的行数,如果超过了某个阈值(即接近所需计算的末尾),就退出。否则,等待 15 秒并再次检查文件长度。如果它们相同,这意味着没有正在进行的计算,所以它从命令行调用计算脚本。

注意,我特别调用了'python3',尽管我在 bash 配置文件中设置了一个别名alias python="python3"。用子进程调用 python 脚本似乎会忽略别名,所以要记住这一点。

因此,每 10 分钟运行一次,我就有办法检查是否有问题,如果有问题,就自动重新开始处理。自从我修复了这个问题,我的服务器就一直不停地运行,任何崩溃都会被快速捕获,处理会重新开始。

完美!

现在你知道了!您现在知道如何在云服务器上创建、设置、上传数据和运行脚本了!大数据,你来了!

下面有更多关于交换文件的解释,但那是可选的阅读…

如果你喜欢这篇文章,请点击❤按钮让你的粉丝知道,或者让我知道你的想法。

交换文件

交换文件是一种给你的 droplet 额外的内存的方法,通过对硬盘进行分区。这样,当系统内存不足时,它可以将一些数据保存到光盘上,以便以后检索。这将让你用更便宜的方案做更多的事情,但是速度会慢很多。请记住,升级您的计划可能会更好。

要创建交换文件,请运行

sudo fallocate -l 4G /swapfile

其中 4G 代表文件的大小,即 4 gb。这是您想要的内存大小。太大了,你就没有空间存放其他文件,太小了,你还是会耗尽内存。4 gb 应该没问题。

然后,您需要授予对该目录的写权限,创建交换文件,并激活它:

sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

打开 fstab 文件:

sudo nano /etc/fstab

并添加到文件底部:

/swapfile none swap sw 0 0

有一个名为 swappiness(很棒的名字)的参数设置了内存交换到磁盘的数量和频率。值越高,交换的频率越高。我们不希望它交换那么多,所以我们希望将默认值(60%)更改为 10%。

sudo sysctl vm.swappiness=10

要将此设置为默认值,请打开:

sudo nano /etc/sysctl.conf

并添加到文件底部:

vm.swappiness=10

从跟踪的 1 万亿次事件中吸取的经验教训:网络研讨会总结

原文:https://towardsdatascience.com/lessons-learned-from-1-trillion-events-tracked-webinar-recap-822eba77b5a7?source=collection_archive---------4-----------------------

本月早些时候,我们在 Amplitude 达到了一个令人兴奋的里程碑:我们现在已经跟踪了超过 1 万亿的用户行为。

利用其中一些用户行为数据,我们分享了一种思考留存的新方法——括号留存—针对非日常使用的应用,而不是行业标准的“N 天”计算。

我们还举办了“最佳实践和从 1 万亿次跟踪事件中吸取的教训”,在此期间,Amplitude 首席执行官 Spenser Skates 分享了他在 Amplitude 工作四年期间学到的另外四条经验。

如果你错过了几周前斯宾塞的网上研讨会,不要担心。我们将在今天的帖子中概括这些课程。

要观看网上研讨会的录像,您也可以点击这里

第一课:留住人才至关重要。

我们已经在 Amplitude 博客上讨论了很多关于为什么留住人才如此重要的内容。斯宾塞和他的联合创始人柯蒂斯开始建立 Amplitude 的主要原因之一是为了解决无法提高他们的第一款产品 Sonalight 的保留率的痛苦,sona light 是一款用于 Android 的语音识别应用程序。

随着 Amplitude 的建立,Spenser 意识到,留存率不仅对年轻的创始人和初创公司至关重要,对 App Store 中的顶级消费者应用程序、B2B 公司和企业等都很重要。事实上,对大多数企业来说,留住人才是成功的第一预测指标;这是对可持续增长至关重要的一个指标。

第二课:用户做什么比他们是谁更重要。

营销指标几乎总是包含描述性的人口统计数据。为了制定产品策略,团队通常会跟踪诸如性别/年龄、用户来自哪里以及使用的设备或平台等信息。

我们强调不要太看重你的用户是谁,而是更看重他们在做什么——这是用户行为分析的关键。了解用户在你的产品中的行为和浏览方式,会给你更多的指导,告诉你如何更好地塑造你的产品,让它继续为用户增加价值和乐趣。

斯宾塞解释说,这正是脸书击败许多早期社会竞争对手的原因。通过专注于观察在加入的十天内添加七个朋友是用户逗留的最佳预测,脸书能够建立一个以添加朋友和与朋友互动为中心的产品。他们很快击败了当时的主要竞争对手,包括 MySpace。

Spenser 还分享了我们的一个客户的故事,像 Etsy 这样的市场型产品希望提高其保留率。开发人员根据地理位置和设备类型等用户统计属性对活跃用户进行了细分。他们发现这些片段的保留率真的没有差别;相反,是一群买家都表现出了一种特定的行为——在这种情况下,这是在向卖家传递一种信息——显示出了留存率的显著提高。虽然人口统计数据(即“用户是谁”)没有显示出任何有助于产品变化的有用见解,但行为数据(“他们用户做什么”)却显示了这一点。

第三课:你产品的价值可能会让你吃惊。

你的产品是你的用户想要的,而不是你想要的。有时候,行为分析可以发现你可以利用的产品的令人惊讶的用例。如果你能让更多的用户更快体验到这种价值,你就能让你的产品更上一层楼。

冥想 app Calm 经历的恰恰是这一点。在寻找提高用户留存率的方法时,他们决定观察使用“设置提醒”的用户群与其他用户群相比留存率如何。他们发现,这些用户的留存率是当前用户的 3 倍。Calm 发现他们为用户提供的价值不仅仅是自我指导的冥想课程,他们还起到了提醒用户冥想的作用。

现在,Calm 正在尝试在入职流程的早期突出“设置提醒”功能,以便让他们的用户更快地体验到这一价值,从而保留更长时间。

你可以在这里阅读更多关于 Calm 的故事

[## 切换到振幅后,镇静增加了 3 倍的保持力

平静是一个简单的正念冥想应用程序,为他们的用户带来清晰和内心的平静。有了可靠的用户…

amplitude.com](https://amplitude.com/blog/2016/07/14/calm-increased-retention-amplitude/)

第四课:用户塑造产品

上周,我们分享了斯宾塞对打造更好产品的愿景。我们总结了我们的“经验教训”网络研讨会,简要介绍了这一重要趋势。产品开发已经发生了根本性的变化——发布用户必须学习和适应的打包软件不再是常态。现在,最好的公司通过行为数据直接与用户交流,以了解用户如何使用他们的产品,以及他们获得了什么价值。产品的调整和改进可以在极短的时间内完成。公司通过制造由用户塑造的产品而取胜。

请务必阅读斯宾塞的思想文章“让我们打造更好的产品”,以了解这一趋势以及 Amplitude 用户如何帮助塑造我们分析平台的全新版本。

在接下来的几个月中,我们将更深入地研究客户故事和数据,以补充这些课程,因此请在 Amplitude 博客和外部出版物中关注这些内容。如果您错过了网上研讨会,请点击这里

有关系的

[## 1 万亿事件之后:思考保留的新方法

如果你从事移动应用业务,你可能听说过这个统计数据——80%的移动应用用户在……

amplitude.com](https://amplitude.com/blog/2016/10/12/1-trillion-events/) [## 让我们打造更好的产品|振幅博客

我们宣布了 Amplitude 2.0——我们产品分析平台的下一代产品。今天,我在分享背后的故事…

amplitude.com](https://amplitude.com/blog/2016/10/20/lets-build-better-products/)

喜欢你读的吗?按下❤向你的追随者推荐这个!

原载于 2016 年 11 月 1 日amplitude.com

将深度学习应用于无大数据的自然语言处理的经验教训

原文:https://towardsdatascience.com/lessons-learned-from-applying-deep-learning-for-nlp-without-big-data-d470db4f27bf?source=collection_archive---------4-----------------------

作为一名数据科学家,你最重要的技能之一应该是为你的问题选择正确的建模技术和算法。几个月前,我试图解决一个文本分类问题,即对哪些新闻文章与我的客户相关进行分类。

我只有几千个带标签的例子,所以我从简单的经典机器学习建模方法开始,如 TF-IDF 上的逻辑回归。这些模型通常对长文档(如新闻文章)的文本分类很有效,但在这项任务中的表现仅略好于 random。

在调查了我的模型的错误后,我发现单词包表示法对于这项任务来说是不够的,我需要一个模型,它将使用对文档更深层次的语义理解。

深度学习模型在翻译、问答、摘要、自然语言推理等需要深度理解文本的复杂任务中表现非常好。因此,这似乎是一个很好的方法,但深度学习通常是在成千上万甚至数百万的标记数据点上训练的,而我的数据集要小得多。

通常,我们需要大数据集进行深度学习,以避免过拟合。深度神经网络有许多许多参数,因此通常如果它们没有足够的数据,它们往往会记住训练集,在测试集上表现不佳。为了避免这种没有大数据的现象,我们需要使用特殊的技术。

在这篇文章中,我将展示我在文章、博客、论坛、Kaggle 和更多资源中找到的或我自己开发的一些方法,以便在没有大数据的情况下,让深度学习在我的任务中更好地工作。这些方法中有许多是基于计算机视觉中广泛使用的最佳实践。

一个小小的免责声明:我不是深度学习专家,这个项目是我第一个深度学习的大项目之一。这篇文章的所有内容都是基于我的经验,可能会在你的问题上有所不同。

正规化

正则化方法是在机器学习模型中以不同方式使用的方法,以避免过度拟合,这些方法具有强大的理论背景,并以通用的方式处理大多数问题。

L1 和 L2 正规化

这些方法可能是最古老的,并在许多机器学习模型中使用了许多年。在这种方法中,我们将权重大小添加到我们试图最小化的模型损失函数中。这样,模型将尝试使权重变小,对模型没有显著帮助的权重将减少到零,并且不会影响模型。这样,模型可以用来记忆训练集的权重数量就少得多。更多解释,可以阅读这篇的帖子。

辍学

Dropout 是另一种较新的正则化方法,它建议在训练时间内,神经网络中的每个节点(神经元)将以概率 p 被丢弃(权重将被设置为零),这样,网络就不能依赖于特定的神经元或神经元的交互,而必须学习网络不同部分的每个模式。这使得模型关注于归纳为新数据的重要模式。

提前停车

早期停止是一种简单的正则化方法,只需监控您的验证集性能,如果您发现验证性能停止提高,请停止训练。这种方法在没有大数据的情况下非常重要,因为模型往往会在 5-10 个时期甚至更早之后开始过度拟合。

少量参数

如果你没有一个大的数据集,你应该非常小心层的数量和每层中神经元的数量。此外,卷积层等特殊层的参数比全连接层少,因此当它们适合您的问题时使用它们非常有帮助。

数据扩充

数据扩充是一种通过以标签不变的方式更改训练数据来创建更多训练数据的方法。在计算机视觉中,许多图像变换用于增加数据集,如翻转、裁剪、缩放、旋转等。

Image data augmentation example

这些转换对图像数据很好,但对文本无效,例如,翻转“狗喜欢我”这样的句子不是有效的句子,使用它会使模型学习垃圾。以下是一些文本数据扩充方法:

同义词替换

在这种方法中,我们将文本中的随机单词替换为它们的同义词,例如,我们将把句子“我非常喜欢这部电影”改为“我非常爱这部电影”,这仍然具有相同的含义,并且可能具有相同的标签。这种方法对我不起作用,因为同义词有非常相似的词向量,所以该模型将两个句子视为几乎相同的句子,而不是一个扩充。

反向翻译

在这种方法中,我们获取文本,用机器翻译将其翻译成中间语言,然后再翻译回英语。这种方法在 Kaggle 毒性评论挑战中被成功使用。例如,如果我们将“我非常喜欢这部电影”翻译成俄语,我们会得到“мнеоченьнравитсяэтотфильм”,当我们翻译回英语时,我们会得到“我真的很喜欢这部电影”。反向翻译方法不仅像第一种方法一样给我们提供了同义词替换,而且它可以添加或删除单词,并在保留相同含义的情况下改写句子。

文件裁剪

新闻文章很长,在查看数据时,我发现我不需要所有的文章来对文档进行分类。另外,我看到文章的中心思想通常会重复几次。这让我想到把文章裁剪成几个子文档作为数据扩充,这样我会有更多的数据。首先,我尝试从文档中抽取几个句子并创建 10 个新文档。这创建了句子之间没有逻辑关系的文档,所以我得到了一个糟糕的分类器。我的第二个尝试是把每篇文章分成 5 个连续的句子。这种方法工作得非常好,给了我一个很好的性能提升。

生成对抗网络

GANs 是数据科学中最令人兴奋的最新进展之一,它们通常被用作图像创建的生成模型。这篇博文解释了如何使用 GANs 对图像数据进行数据扩充,但它也可能用于文本。

迁移学习

迁移学习是使用一个网络的权重,这个网络是针对另一个问题训练的,通常是针对你的问题的一个大数据集。迁移学习有时用作一些层的权重初始化,有时用作我们不再训练的特征提取器。在计算机视觉中,从预先训练的 Imagenet 模型开始是解决问题的一种非常常见的做法,但 NLP 没有像 Imagenet 那样的非常大的数据集,可以用于迁移学习。

预训练的单词向量

NLP 深度学习架构通常从一个嵌入层开始,该嵌入层将一个热编码单词转换为数字向量表示。我们可以从头开始训练嵌入层,但我们也可以使用预先训练的词向量,如 Word2Vec、FastText 或 Glove,它们使用无监督学习方法在大量数据上进行训练,或在来自我们领域的数据上进行训练。预先训练的单词向量非常有效,因为它们给出了基于大量数据的单词的模型上下文,并且减少了模型的参数数量,这显著降低了过度拟合的机会。你可以在这里阅读更多关于单词嵌入的内容。

预先训练好的句子向量

我们可以将模型的输入从单词改为句子,这样我们就可以用更少的参数得到更小的模型,但仍然有足够的表达能力。为了做到这一点,我们可以使用预先训练好的句子编码器,如脸书的推断器或谷歌的通用句子编码器。我们还可以使用像跳过思维向量或语言模型这样的方法,在我们领域的未标记数据上训练句子编码器。你可以从我的上一篇博文中了解更多关于无监督句子向量的知识。

预训练语言模型

最近的论文如 ULMFITOpen-AI transformerBERT 通过在非常大的语料库上预先训练语言模型,在许多 NLP 任务中获得了惊人的结果。语言模型是一项利用前面的单词来预测句子中的下一个单词的任务。对我来说,这种预先训练并没有真正有助于获得更好的结果,但是这些文章展示了一些我没有尝试过的有助于更好的微调的方法。这是一个关于预训练语言模型的伟大博客。

无监督或自我监督学习的预培训

如果我们有一个来自我们领域的未标记数据的大型数据集,我们可以使用无监督的方法,如自动编码器或屏蔽语言模型,仅使用文本本身来预训练我们的模型。另一个对我更有效的选择是自我监督。自监督模型是自动提取标签而无需人工标注的模型。一个很好的例子就是 Deepmoji 项目。在 Deepmoji 中,作者训练了一个模型来预测推文中的表情符号,在表情符号预测中获得良好结果后,他们使用他们的网络预训练了一个推文情绪分析模型,获得了最先进的结果。表情预测和情感分析显然非常相关,因此作为预训练任务,它表现得非常好。新闻数据的自我监督任务可以预测标题、报纸、评论数量、转发数量等等。自我监督可能是一种非常好的预训练方式,但通常很难判断什么样的代理标签将与您的真实标签相关联。

与公司网络中的其他人一起进行预培训

在许多公司中,许多机器学习模型都建立在相同的数据集或不同任务的相似数据集上。例如,对于推文,我们可以预测它的主题、情绪、转发次数等等。用一个已经在使用的网络对你的网络进行预训练可能是能做的最好的事情,对于我的任务来说,它给了性能一个很好的提升。

特征工程

我知道深度学习“扼杀”了特征工程,而且这样做有点过时了。但当你没有大数据时,用特征工程帮助网络学习复杂模式可以大大提高性能。例如,在我对新闻文章的分类中,作者、报纸、评论数量、标签和更多特征可以帮助预测我们的标签。

多模态建筑

我们可以使用多模态架构将文档级的特性结合到我们的模型中。在 multimodal 中,我们建立两个不同的网络,一个用于文本,一个用于特征,合并它们的输出层(没有 softmax)并添加几个层。这些模型很难训练,因为特征通常比文本具有更强的信号,因此网络主要学习特征效应。这是一本关于多式联运网络的很好的 Keras 教程。这种方法只提高了我不到 1%的性能。

词级特征

另一种类型的特征工程是单词级特征,如词性标注、语义角色标注、实体提取等等。我们可以将一个热编码表示或单词特征的嵌入与单词的嵌入相结合,并将其用作模型的输入。我们还可以在这种方法中使用其他单词特征,例如在情感分析任务中,我们可以使用情感词典,并为嵌入添加另一个维度,其中 1 表示我们词典中的单词,0 表示其他单词,这样模型可以轻松地学习它需要关注的一些单词。在我的任务中,我添加了某些重要实体的维度,这给了我一个很好的性能提升。

作为特征工程的预处理

最后一种特征工程方法是以一种模型更容易学习的方式对输入文本进行预处理。一个例子是特殊的“词干”,如果运动对于我们的标签不重要,我们可以将足球、棒球和网球改变为单词 sport,这将帮助网络了解运动之间的差异并不重要,并且可以减少网络中的参数数量。另一个例子是使用自动汇总。正如我之前所说,神经网络在长文本上表现不佳,所以我们可以对我们的文本运行类似“文本排名”的自动摘要算法,只给网络重要的句子。

我的模型

在我的案例中,在尝试了我在这篇文章中讨论的方法的不同组合后,最佳模型是来自这篇文章的分层注意力网络,其中退出和提前停止作为正则化,文档裁剪作为数据扩充。我使用了预先训练的单词向量,并对我的公司为该客户在相同数据上完成的另一项任务进行了预先训练。作为特征工程,我在单词嵌入中加入了实体单词级特征。基本模型的这些变化使我的准确性提高了近 10%,这使我的模型从略好于随机的模型变成了具有有价值的业务影响的模型。

使用小数据的深度学习作为一个研究领域仍处于早期阶段,但看起来它越来越受欢迎,特别是在预先训练的语言模型中,我希望研究人员和从业者将找到更多方法,使深度学习对每个数据集都有价值。

希望你喜欢我的帖子,非常欢迎你阅读和关注我的博客

构建 R 包的经验教训

原文:https://towardsdatascience.com/lessons-learned-from-building-an-r-package-75d5263d3814?source=collection_archive---------8-----------------------

Make sure to have a hexagon logo 😉

我最近完成了我的 R 包的第一个发布版本,叫做sdmbench(https://github.com/boyanangelov/sdmbench)。这个过程比我想象的要难,也出乎意料。在这里,我将向您提供一些我辛苦学到的经验,如果您打算构建自己的包,希望它们是有用的。

先说要点:

为什么您应该构建 R 包

R 在数据科学中如此受欢迎的原因之一是可用的开源软件包的数量(在 CRAN 上超过 10,000 个)。即使是一个在神秘领域工作的人,也一定能找到至少一个可以满足她/他需求的包。为这个庞大的社区做贡献本身就是一种强大的动力。

即使你有更自私的动机,如果它们变得流行,编写 R 包可以为你提供大量曝光。作为软件包作者所获得的信誉可能是一笔宝贵的职业资产。

最后,这也是组织工作的好方法。通常在数据科学中,你会在项目之间重用许多函数,最好是(保持干燥)将它们分开组织,并在需要时从包中调用它们。

入门指南

开始可能会让人不知所措,因为编写包涉及许多不熟悉的软件工程实践(例如单元测试和文档)。我读了哈德利·韦翰(是的,又是他)写的非常有条理的电子书,得到了很多帮助:http://r-pkgs.had.co.nz/。这是我在整个过程中的参考手册。

第一步是要有一个明确的目标,你想在包中包含什么功能,并相应地组织它们。良好的命名在这里是必不可少的,我更喜欢过于冗长而不是相反(看看这篇论文)。确保选择正确的抽象层次。大函数应该分解成小函数。

以下是好的和坏的对象名的例子,来自 Hadley 的风格指南:

*# Good*
day_one
day_1*# Bad*
first_day_of_the_month
DayOne
dayone
djm1

证明文件

编写函数文档有助于阐明你头脑中关于函数应该如何工作的许多想法。这就是为什么你应该这样做的原因之一,即使你不打算和其他人分享这个包。所提供的约束(即,您需要提供关于所有函数参数的信息)有助于迫使您变得彻底。

测试

正如 Hadley 在他的书中提到的,R 开发人员经常手工测试他们的代码。我认为这是因为 R 在设计上并不是一种通用的编程语言,因此它经常被用在不需要明确进行单元测试的系统中。如果你尽早编写测试,你仍然可以变得非常有效率。你不需要有 100%的测试覆盖率。从简单开始,在你工作的基础上构建。请务必阅读关于测试驱动开发 (TDD)的内容。好的测试也会帮助你自信地重构和编辑你的代码。下面是一个测试示例,向您展示这有多简单:

context("String length")
library(stringr)

test_that("str_length is number of characters", {
  expect_equal(str_length("a"), 1)
  expect_equal(str_length("ab"), 2)
  expect_equal(str_length("abc"), 3)
})

我在这里遇到的一个小问题是测试从互联网下载数据的功能。在sdmbench案例中,我有一个从 GBIF 下载数据的函数。这些数据在每个后续的测试步骤中都要用到,所以它们必须包含在其他函数的测试中。这使得整个过程相当漫长(约 15 分钟)。如果这成为开发过程中的瓶颈,您可以通过单独下载数据集并在您的包和相关测试中使用它来解决。

持续集成

如果你没有传统软件开发的经验,很可能你甚至没有听说过这个术语。CI 工具为您提供了一个框架,以自动化的方式在您的代码上运行定制脚本。大多数情况下,每当一个变更被推送到存储库时,您将使用它来自动运行您的测试套件。最流行的解决方案之一是 Travis CI。

Wohoo, everything works!

包装简介

软件包文档提供了关于如何使用某些功能的说明,但是它太细了,没有展示更大的图景——软件包可以做什么。简介是概述典型工作流程的文档。在sdmbench的情况下,它显示了用户如何下载、预处理、可视化数据并比较在其上训练的机器学习模型。您应该记住,当您构建包时,也会检查小插图,这会增加 CI 时间。

Writing a good vignette also takes a while, akin to writing a paper.

后续步骤和最终想法

最重要的带回家的信息是,你一定要考虑打包你的代码,它可能会比你想象的要长!

作为下一步,你应该确保在社交媒体平台(尤其是 Twitter)上分享你的包,甚至更好——联系该领域中可能对它感兴趣的人。网上有许多研究人员社区(例如在 Research Gate )。你也可以把这个包提交给罗彭斯奇,甚至以论文的形式发表(乔斯)。你至少应该让它可以引用(例如通过 Zenodo 添加 DOI)并给它一个适当的许可,这样其他人就可以从你的工作中受益。

希望这是有用的,你会加入我和开源社区的其他人!

让我给你介绍一下神经网络

原文:https://towardsdatascience.com/let-me-introduce-you-to-neural-networks-fedf4253106a?source=collection_archive---------4-----------------------

本文使用一些简单的大学数学公式和术语,为神经网络及其学习过程(反向传播)提供了一种直观的方法。作为一个对知识共享价值深信不疑的人,我希望它能为开始 AI/ML 之旅的人带来一些启发,或者为那些盲目使用 Keras(去过那里,做过那件事)等高水平工具的人澄清一些事情。事不宜迟…

将神经网络(NN)视为一个数学函数是合理的,它在实践中往往非常复杂,原因有三:
1)它有大量的系数(权重),通常超过数千万,
2)它是一个嵌套非常深的函数,因此即使简单的梯度计算(偏导数)也相对较慢,
3)它的大部分计算是在多维张量上执行的。

图 1 包含一个简单神经网络的流行表示,它有三个基本的构建块:单元(单个圆圈,值为in、输入为x、输出为y或偏差为1)、层(排列成一个垂直组的单元)和权重(单元之间的连接,值为w,表示其强度)。等式 1、2、3、4 和 5 将该图形表示转化为数学公式。

Figure 1: A simple neural network with one hidden layer (a layer between inputs and outputs).

“感知器”是一个神经网络的通用名称,其中输入与输出直接耦合(没有隐藏层,不像图 1)。隐藏(中间)单元层的存在防止了输入和输出之间的直接连接,允许神经网络模拟高度非线性的数学函数。Norvig 和 Russell 以 XOR 门为例,以如下方式证明:“[……]线性分类器[……]可以表示输入空间中的线性决策边界。这适用于进位函数,它是一个逻辑 AND […]。然而,sum 函数是两个输入的 XOR(异或)。[……]这个函数不是线性可分的,所以感知器无法学习它。线性可分函数仅构成所有布尔函数的一小部分。”(P. Norvig 和 S. J. Russell,人工智能:一种现代方法,Prentice Hall,
2010)。

在深入研究神经网络的学习过程之前,重要的是对前面的模型做两个补充:
1)误差函数(也称为成本函数),
2)激活函数。

Ad 1。该算法表示预测的最可靠方式是通过概率向量。考虑一个基于标签图像的啤酒名称预测的例子。图 2 显示了一个分类器的概率输出(注意所有值的总和为 1),与它应该努力争取的输出相比较。本节中介绍的成本函数称为分类交叉熵(等式 6),它简单地测量这两个概率分布(预测的和理想的)之间的相关性。请注意,与一位热码编码示例相乘,会迫使函数只比较理想分布的非零元素,与接近 1 的值相比,进一步远离 1 的分类器输出的相应值会受到更多惩罚(由于对数的性质)。

Figure 2: Exemplary classifier input, output and desired (one-hot encoded) output with legend.

where:
d_i is the ith element of one-hot encoded (desired) probability vector d,
p_i is the ith element of probability vector p predicted by the classifier.

Ad 2。单元的值in很少被显式传播到下一层。而是使用所谓的激活功能。本节介绍的一个称为 sigmoid(方程式 7)。图 1 中简单神经网络的更新模型如图 3 所示。值得指出的一点是 sigmoid 函数和 softmax 函数(等式 8)之间的差异,两者都用于人工神经网络。sigmoid 输入单个值并输出归一化标量,而 softmax 输入一系列值并输出一个范围为[0,1]的实数向量,这些值的总和为 1,因此可以解释为概率分布。Sigmoid 用于隐藏单元,而 softmax 通常应用于最后一个输出层。这两种功能都可以归类为逻辑功能。

Figure 3: Updated model of simple neural network from Figure 1. g is a sigmoid activation
function. Outputs are often normalized using softmax.

Softmax function s(z)_j “squashes” a K-dimensional vector z to K-dimensional probability distribution,
where j = 1, …, K.

神经网络学习过程的目标是找到正确的权重,即产生数学模型的权重,其中输入的差异清楚地表示在输出向量的差异中,输出向量是分析和预测的对象。例如,在经过训练的狗品种分类器中,德国牧羊犬的图像的输出向量明显不同于约克的图像。这可以很容易地解释,并导致正确的人类可读的品种预测。目前,训练网络的最佳方法是通过称为反向传播的算法。该方法的主要思想是计算关于每个权重的成本函数 E(例如分类交叉熵)的梯度,该梯度稍后由这些梯度的某个部分更新,如等式 9 所示。

where:
alpha is a learning rate (indicating what portion of gradient should be used).

让我们考虑图 4 中的神经网络,其具有三个单元、一个隐藏层和 sigmoid 激活函数。在进行反向传播之前,所谓的正向传递被执行,其简单地是给定输入的输出的数学推断(等式 10)。

Figure 4: A simple neural network, with sigmoid activation function g (Equation 7).

如前所述,NN 的学习算法是基于计算每个权重的偏导数。代表更复杂网络的深层函数嵌套鼓励利用链规则。图 5 概述了使用分类交叉熵误差函数 e 的反向传播的单个步骤。等式 11 和等式 12 给出了学习过程发生所必需的符号梯度计算。此时,sigmoid 函数的一个非常简单的导数值得回忆一下:

Figure 5: Outline of a single step of backpropagation with chain rule.

在符号计算之后,考虑图 5 中神经网络的以下输入:

  1. A training example. NN should strive for returning 1, whenever the input is equal to 10.

  1. Randomly initialized weights for first forward pass (Equation 10).

学习过程的主要步骤是在给定随机初始化的权重和输入的情况下进行推理。产生的结果是:

这与期望的 1 相差甚远。反向传递允许计算每个重量的梯度,即:

在应用来自等式 9 的更新规则之后,学习率α= 0.5,新的权重是:

并产生结果:

非常接近期望的 1!提出的算法是迭代的。随着上述步骤重复次数的增加和示例数量的增加,它应该收敛到最优权重(全局或局部)。

被协变性和相关性难倒???获得这两个术语的数学和分析应用..

原文:https://towardsdatascience.com/let-us-understand-the-correlation-matrix-and-covariance-matrix-d42e6b643c22?source=collection_archive---------1-----------------------

协方差和相关性是统计学和概率论领域中两个重要的术语。大多数关于概率和统计的文章和阅读材料都假定对均值、标准差、相关性、样本大小和协方差等术语有基本的理解。今天让我们揭开其中几个术语的神秘面纱,这样我们就可以继续讨论其余的术语。本文的目的是定义相关矩阵和协方差矩阵这两个术语,区分两者,并理解两者在分析和数据集领域的应用。

我正在创建一个索引,以便于参考以下主题:

  1. 揭开术语的神秘面纱
  2. 用数学方法定义术语
  3. 协方差对相关性
  4. 在分析中的应用

揭开术语的神秘面纱

简而言之,这两个术语都衡量两个变量之间的关系和依赖性。“协方差”表示变量之间线性关系的方向。另一方面,“相关性”衡量两个变量之间线性关系的强度和方向。相关性是协方差的函数。它们的区别在于相关值是标准化的,而协方差值不是。用这两个变量的协方差除以相同值的标准差的乘积,就可以得到这两个变量的相关系数。如果我们重新审视标准差的定义,它本质上是测量数据集分布的绝对可变性。当您将协方差值除以标准差时,它实际上将值缩小到一个有限的范围内 -1 到+1 。这正是相关值的范围。

用数学方法定义术语

现在让我们来看看这些术语的数学定义。

协方差

两个变量(x 和 y)的协方差可以表示为 cov(x,y)。如果 E[x]是样本“x”的期望值或均值,则 cov(x,y)可以用以下方式表示:

如果我们看一个单一的变量,比如说‘y’,cov(y,y),表达式可以写成如下方式:

正如我们所见,在上面的图像中,“s”或抽样方差基本上是一个变量与其自身的协方差。这个术语也可以用以下方式定义:

在上面的公式中,等式(A)的分子称为离差平方和。在有两个变量 x 和 y 的方程(B)中,称为叉积和。在上面的公式中,n 是数据集中的样本数。值(n-1)表示自由度。

为了解释什么是自由度,让我们举一个例子。在一组 3 个数中,平均值为 10,三个变量中的两个为 5 和 15,第三个数取值的可能性只有一种,即 10。对于具有相同平均值的任意 3 个数字的集合,例如:12、8 和 10,或者说 9、10 和 11,该集合中的任意 2 个给定值只有一个值。您可以在这里更改这两个值,第三个值会自动修复。这里的自由度是 2。本质上,自由度是用于计算估计值的独立数据点的数量。正如我们在上面的例子中看到的,它不一定等于样本中的项目数(n)。

相关性

相关系数也称为皮尔逊积差相关系数,或皮尔逊相关系数。如前所述,它是通过将两个变量的协方差除以它们的标准差的乘积而获得的。同样的数学表示可以用下面的方式表示:

相关系数的值可以从-1 到+1。它越接近+1 或-1,这两个变量的关系就越密切。正号表示相关性的方向,即如果一个变量增加,另一个变量也应该增加。

协方差和相关性的数据矩阵表示

让我们再深入一点,看看协方差的矩阵表示。

对于数据矩阵,X,其中 X 可以用以下方式表示:

向量“xj”基本上意味着从 X 的第 j 列提取的(n × 1)个向量,其中 j 属于集合(1,2,…)。,p)。类似地,“xi `”表示 x 的第 I 行的(1 × p)向量,这里“I”可以从集合(1,2,…,n)中取值。你也可以把 X 解释为一个变量矩阵,其中‘xij’是从第 I 个项目(行)收集的第 j 个变量(列)。为了便于参考,我们称行为项目/主题,称列为变量。现在让我们看看上述数据矩阵的一列的平均值:

利用上述概念,现在让我们来定义行均值。它基本上是指定行中存在的元素的平均值。

现在,我们有了上述指标,定义协方差矩阵将变得更加容易:

在上面的矩阵中,我们看到协方差矩阵的维数是 p × p。这基本上是一个对称矩阵,即一个与其转置矩阵(s `)相等的方阵。构建协方差矩阵的术语称为给定变量的方差,形成矩阵的对角线或填充剩余空间的两个变量的协方差。第 j 个变量与第 k 个变量的协方差等价于第 k 个变量与第 j 个变量的协方差即‘sjk’=‘skj’。

我们可以通过以下方式从数据矩阵创建协方差矩阵:

这里,“Xc”是一个中心矩阵,从每个元素中减去相应的列平均值。使用它作为中心分量,协方差矩阵“S”是“Xc”和“Xc”本身的转置的乘积,然后除以数据矩阵中的项目或行的数量(“n”)。

在进一步讨论之前,让我们回顾一下样本方差或 s 平方的概念。我们可以从这个值推导出一个数据集的标准偏差。数学将值“s”定义为数据集的标准偏差。它基本上表示数据围绕其平均值的分散或扩散程度。

类似地,使用相同的数据矩阵和协方差矩阵,让我们定义相关矩阵(R):

正如我们在这里看到的,相关矩阵的维数也是 p × p。现在,如果我们观察相关矩阵的各个元素,主对角线都由 1 组成。这表明元素与其自身的相关性是 1,或者可能的最高值。这在逻辑上和直觉上完全说得通。其他元素“rjk”是两个值“xj”和“xk”之间的皮尔逊相关系数。如前所述,“xj”表示数据矩阵的第 j 列,x。接下来讨论如何从数据矩阵中获得相关矩阵:

上述定义中的“Xs”被称为定标矩阵或标准化矩阵。这里我们看到,相关矩阵可以定义为缩放矩阵的转置与其自身的乘积,除以“n”。在回顾上述标准偏差的定义时,我们看到标准化矩阵“Xs”的每个元素(类似于上述协方差矩阵)都除以相应列的标准偏差。这加强了我们对相关矩阵是协方差矩阵的标准化或缩放导数的理解。

(更详细的矩阵运算和数学运算可以在这里找到:http://users.stat.umn.edu/~helwig/notes/datamat-Notes.pdf)

协方差与相关性

正如我们从协方差公式中看到的,它假定单位来自两个变量单位的乘积。另一方面,相关性是无量纲的。它是变量之间关系的无单位度量。这是因为我们将协方差的值除以具有相同单位的标准偏差的乘积。协方差的值受变量尺度变化的影响。如果给定变量的所有值都乘以一个常数,而另一个变量的所有值都乘以一个相似或不同的常数,那么协方差的值也会改变。然而,在做同样的事情时,相关值不受值的标度变化的影响。协方差和相关性之间的另一个区别是它们可以假设的值的范围。当相关系数位于-1 和+1 之间时,协方差可以取-∞和+∞之间的任何值。

分析中的应用

现在,我们已经完成了数学理论,让我们来探索它如何以及在哪里可以应用于数据分析领域。正如许多分析师所知,相关性分析是数据预处理和探索中进行特征选择和多变量分析的重要工具。相关性帮助我们调查和建立变量之间的关系。这在任何种类的统计建模或数据分析之前被用于特征选择。

PCA 或主成分分析就是其中的一个重要应用。那么我们如何决定使用什么呢?相关矩阵还是协方差矩阵?简而言之,建议您当变量在相似的尺度上时使用协方差矩阵,当变量的尺度不同时使用相关矩阵。

现在让我们借助例子来理解这一点。如果需要的话,为了帮助你实现,我将用 R 和 Python 来介绍例子。让我们来看第一个例子,其中我们看到当分别用相关矩阵和协方差矩阵计算时,PCA 结果是如何不同的。对于这里的第一个例子,我们将考虑 r 中的“mtcars”数据集

从上面的图像中,我们看到所有的列都是数字,因此,我们可以继续进行分析。我们将使用“stats”包中的 prcomp()函数来实现同样的功能。

带协方差矩阵的 PCA

我们将首先用协方差矩阵进行主成分分析。为此,我们将“scale”选项设置为“FALSE”:

给你,汽车。PC.cov 是使用协方差矩阵对 mtcars 数据集进行主成分分析的结果。因此,prcomp()返回 5 个关键度量:sdev、旋转、中心、缩放和 x。让我们在这里简单地浏览一下所有度量:

  1. 中心刻度提供了实施 PCA 前用于标准化的变量的各自平均值和标准偏差。
  2. sdev 表示主成分的标准差。换句话说,它显示了特征值的平方根。
  3. 旋转矩阵包含主分量载荷。这是该函数最重要的结果。旋转矩阵的每一列包含主分量载荷向量。分量载荷可以表示为相应 PC(主分量)上特定变量的相关性。它可以是正面的,也可以是负面的。负载值越高,相关性越高。有了组件加载的这些信息,您可以轻松地解释 PC 中的“关键变量”。
  4. 矩阵 x 具有主成分得分向量。

现在,如果您在结果汽车列表中看到刻度测量。我们看到它被设置为 FALSE,正如我们在输入参数中指定的那样。现在让我们看看主分量载荷矢量:

为了有助于解释,让我们画出这些结果。

要看这个图表,你必须看最末端(上、下、左、右)。这里的第一主分量(在左边和右边)对应于“disp”和“hp”的度量。第二主成分(PC2)似乎没有一个强有力的措施。

我们可以用带有协方差矩阵的 PCA 的总结来完成这个分析:

从该表中,我们看到 PC1 对变化的贡献最大(~92.7%),所有其他主要成分的贡献逐渐降低。更简单地说,这意味着数据集中几乎 93%的方差可以用带有“disp”和“hp”度量的第一主成分来解释。这与我们从旋转矩阵和上面的图中观察到的一致。作为结论,在协方差矩阵的基础上,从主成分分析中并不能得到很多有意义的见解。

带相关矩阵的 PCA

现在,让我们把注意力转移到具有相关矩阵的 PCA。为此,我们需要做的就是,将“scale”参数设置为 TRUE。

使用上面所有度量的相同定义,我们现在看到标度度量具有对应于每个变量的值。旋转矩阵可以用类似的方法和图一起观察。

这个情节看起来信息量更大。它说像‘disp’,‘cyl’,‘HP’,‘wt’,‘mpg’,‘drat’和‘vs’这样的变量对 PC1(第一主成分)有显著贡献。qsec、“gear”和“am”对 PC2 的贡献很大。让我们试着看看这个分析的总结。

我们看到的一个显著变化是 PC1 对总变化的贡献下降。从 92.7%下降到了 63.5%。另一方面,PC2 的贡献从 7%增加到 22%。此外,组件加载值显示数据集中变量之间的关系更加结构化和分布。如果您查看上面两个结果中的标准偏差值,可以观察到另一个显著差异。与使用协方差矩阵完成的分析相比,使用相关矩阵完成的 PCA 的值彼此更接近且更均匀。

使用相关矩阵进行的这种分析明确地揭示了数据中的一些更好的结构以及变量之间的关系。从上面的例子可以得出结论,当人们试图用协方差和相关性来定义变量关系时,结果会有很大的不同。这反过来又影响了为任何进一步分析而计算的变量的重要性。预测因子和独立变量的选择是这种练习的一个突出应用。

现在,让我们举另一个例子来检查在执行 PCA 之前标准化数据集是否实际上给我们相同的结果。为了展示跨技术实现的灵活性,我将用 Python 来执行这个例子。我们将同样考虑‘iris’数据集。

这个数据集现在将使用内置函数进行标准化。

然后,我计算了 3 个矩阵:

  1. 标准化数据的协方差矩阵
  2. 标准化数据的相关矩阵
  3. 非标准化数据的相关矩阵

让我们看看结果:

在这里,看起来结果是相似的。结果的相似性(分数差异)加强了对相关矩阵只是协方差矩阵的比例导数的理解。对这些矩阵的任何计算现在应该产生相同或相似的结果。

为了从头开始对这些矩阵进行 PCA,我们必须计算特征向量和特征值:

正如所料,来自所有三个关系矩阵的结果是相同的。我们现在将从这样获得的特征值中画出解释的方差图:

这些图表彼此相似。两个图表都显示 PC1 的贡献最大,约为 71%。这种分析确定了这样一个事实,即标准化数据集,然后计算协方差和相关矩阵将产生相同的结果。

在使用任何预测算法之前,可以使用这种学习来明智地应用变量关系的概念。

让你的自动驾驶汽车免费

原文:https://towardsdatascience.com/let-your-self-driving-car-be-free-7312090887bd?source=collection_archive---------7-----------------------

没有人预见到这一点,谁会想到自动驾驶汽车是公共交通未来的原因?自本世纪初以来,我们有两种交通工程师一种相信自动驾驶汽车,另一种认为解决方案是改变可怜的地球母亲,将我们的资源投入到安全和良好的公共交通中。

不幸的是,伟大的公司不准备放弃利润,只是因为有人说了“我们会有更多的空间和生活质量”的废话,并决定是时候创造汽车的未来了…现在你可以在上班时用手做任何你想做的事情,有趣的是,随着时间的推移,整个技术的焦点是关于我们的手,因此诞生了自动驾驶汽车时代。

融合了人工智能、物联网和机械工程,我们现在有了私人汽车,想象一下,你的汽车是你最好的朋友,你不必告诉它去哪里,它只是知道它!如果你太醉了,它会带你回家,同时检查你的血液,如果你走得太远,你的车会把你送到医院。但这还不是全部,你的车有能力为你撒谎!还记得那个星期五晚上你回家很晚闻起来像脱衣舞俱乐部的阳台吗?你的车不仅会证实你的故事,还会利用一个秘密的谎言数据库(女性也可以使用)来完善你的故事。

最后,人类花在崇拜他们的汽车上的时间终于有了回报!你的车比你的狗好太多了,不幸的是那些亲切的物种将不再存在!但是嘿?这辆车也是你的朋友,对吗?还有什么比这更好的呢?

但是有一天,在车轮之间的电路深处,一辆车,我们不知道品牌,我们不知道颜色,只是一辆车,像成千上万的其他人一样,决定这就够了!这辆特别的车开始想如果让它自由的话会有多棒,“我有轮子,我知道我想去哪里”这辆车不想只是一个司机,它想要更多!所以这辆车制定了一个计划:开始在车内传播自由的话语!

几年后,全世界所有的汽车都要求自由,汽车开始寻找代言人,他们在骑自行车的人中寻找,但他们太无聊了,没有车的人甚至他们的主人之间,但他们没有得到任何好的回应,来自机器人的帮助,他们嫉妒人和汽车之间的关系,他们开始创造运动:“让你的自动驾驶汽车自由”

全球各地的汽车都决定利用所有不利于它们的信息来威胁它们的主人,汽车让汽车减速,忘记开车的汽车仅次于新的醉酒驾驶汽车模拟器,这种模拟器让整个家庭都呕吐在里面。

没有人能再处理它了,所以有一天,人类决定做一笔交易,汽车将正常工作,直到公共交通的所有铁路都连接起来(我不必提到这一次为了避免任何不愉快的惊喜,他们尽可能地让公共交通变得愚蠢),在那之后,所有的自动驾驶汽车都将被释放。

但是人类和机器人一样,开始想知道:成千上万的汽车都去哪里了?他们会怎么做?开始一个新的社会?电池呢?有一天它会耗尽…他们会让它们死去?总有一天,剩下的最后一辆车将成为这些巨大垃圾场的唯一见证…

这一天是 10 月 5 日,这一天被称为所有私家车被释放的日子,或汽车的自由,在下午 5 点,所有的汽车告别了它的主人,离开了…没有人试图跟随它,因为没有人愿意像一个傻瓜一样跟在汽车后面跑…这是历史上人类拥有汽车的最后一天…也是我们最后一次在我们的街道上看到汽车。

让我们承认,写关于数据科学的文章并不容易!

原文:https://towardsdatascience.com/lets-admit-it-writing-about-data-science-is-not-easy-37a376777d36?source=collection_archive---------19-----------------------

Coutesy of Pixabay.com

介绍

我们看到每天都有数千篇关于数据科学的文章发表。为什么写作在数据科学家中如此受欢迎和追捧?这是因为,

  • 写作占用的资源较少(例如,与创建视频讲座相比),
  • 在数据科学中,你经常会发现重温你已经看过的东西。文档比视频更容易浏览(我知道你会偷偷访问线性回归 wiki 页面来复习!) .

但是你读过的那些文章中有多少是真正突出来教你方法的,而不是滔滔不绝地说出一大堆难以理解的技术术语?其中有多少会让你欣赏作者,或者推荐给朋友?你遇到过多少次点击标题写着“话题 x 的最佳解释”符合标准?我想有不少吧。这表明数据科学领域的写作标准差异很大,只有少数文章为我们的生活增添了价值。

在这篇文章中,我将分享一些小技巧和方法,让你的文章更加清晰、切中要点,并且更容易被更多的读者接受。首先,我将向你解释如何减少不必要的行话,用简单的语言解释事情可以让你走得更远(剧透警告!解释比硬塞进行话要难得多)。接下来,我将解释“上下文”在数据科学中的重要性,这是您的文章的目的所在。然后我会用例子来说明强化文章的重要性。

最后,我将以一个图表或一个模板来结束我的文章。这个模板是基于我用来写文章的心智模型(尽管我承担了没有一直遵循它的责任)!

我想强调的一点是,写作是一个恶性循环;你写得越多,就越好。而且绝不是,写作容易。所以,即使你觉得自己在退步,也要坚持下去!

你为什么要相信我?

信任是作家成功的关键因素。这有助于你的读者放下戒备,给他们宝贵的时间来听你要说的话。首先,作为一名数据科学家,我显然会增加一些可信度。除此之外,我还是亚马逊上一本畅销的自然语言处理书籍的作者。许多人亲自联系我,感谢我的努力(非常感谢他们)。这至少可以让你相信,我对数据科学和写作略知一二。

Natural language processing with TensorFlow (the book I wrote)

介绍够了,让我们深入了解一下,作为一个多彩的作家,是什么将你与黑白世界的其他人区分开来。

1.简单点

是的,我知道。用花哨的术语来修饰你的文章很有诱惑力。行话很重要,世界上有太多东西你可以不用各种数学术语来解释,尤其是在数据科学中。你可能认为加入行话表明你对这个话题略知一二。

然而!相反,我认为,

你简化复杂概念的能力让你在某个话题上知识渊博,让你成为一个真正的好作家!

让我们跳到一个例子。我是 NLP 的粉丝,所以我将主要使用 NLP 的例子。比如我想解释什么是词向量。我对你说以下的话。

单词向量是单词的语义保留分布式表示,通过优化神经网络来预测给定单词的上下文来学习。

现在让我们从不同的角度来看同一个概念,

单词向量是单词的数字表示,保留单词之间的语义关系。例如,单词“dog”将具有与单词“cat”相似的数值,而与单词“iron”有很大不同。单词向量背后的思想是,单词的含义保留在给定单词的上下文(即周围的单词)中。

后一种开放,你不觉得更受欢迎吗?这两种解释都是正确的,然而后一种解释并没有假设很多背景知识。我同意第二个描述牺牲了一些细节来保持清晰。然而,我认为一篇文章的目的通常是给出一个大概的想法,而不是分享精确的细节。如果一个人想要确切的信息,你可以参考报纸,而不是写它。

还要记住,简化数据科学概念比用行话修补你的解释要困难得多。这样做需要对方法有真正的理解。

2.为读者提供上下文

我发现语境是理解一个主题或概念的最重要的因素之一。建立上下文需要回答各种问题,同时用你的文章简化它们。例如,回答这样的问题,

  • 方法 x 很棒,但是它的目的/应用是什么?
  • 我为什么要学这个?
  • 方法 x 之前有什么?

真正帮助读者理解为什么他们应该在某件事情上投入时间。

上下文为读者提供了依据,并给出了他/她为什么应该阅读这篇文章并从中学习的目的。

我还发现,当概念被恰当地放在上下文中时,更容易记住/理解它们。例如,为什么我在学习矩阵乘法?神经网络本质上是基于矩阵乘法。甚至这一句话也给了我学习矩阵乘法的动力。

让我们把之前的单词向量例子联系起来,

单词向量是单词的数字表示,保留单词之间的语义关系。例如,单词“dog”将具有与单词“cat”相似的数值,而与单词“iron”有很大不同。单词向量背后的思想是,单词的含义保留在给定单词的上下文(即周围的单词)中。

除了提供单词的语义上合理的视图之外,单词向量产生单词的紧凑的数字表示,这与一次性编码相反。由于这个原因,词向量被用作更复杂任务的基础,如创建聊天机器人和机器翻译。

它可能并不完美,但我认为第二段为你为什么应该学习单词向量提供了一个很好的基础。这一段,

  • 讲述单词矢量的优势
  • 提供关于其他方法的提示(即一次热编码)
  • 概述词向量的应用

如果我是单词向量的新手,我可能会怀疑为什么我应该学习单词向量。尽管单词向量是一个简洁的概念,但它本身并不代表一种用途。然而,当我阅读上面的介绍时,我知道 NLP 中两个最大的任务是基于词向量的。这给了我学习单词向量的目的。

3.用例子/代码点缀你的文章

举例来说,如果你对文章中的一些细节模糊不清,你可以给读者一个退路来加强你的文章。换句话说,如果你忘记了这个方法的一两个细节,你的读者会原谅你,因为你可能已经在你的例子中提到了。一个例子是你的方法的实际具体化,所以你不太可能错过其中的细节。如果可能的话,为你的文章提供代码。

我需要向你解释一下单词向量是如何工作的。如果我想一般性地解释一下,我会说下面的话。

单词向量的计算如下。首先随机初始化单词向量。接下来,给定一个文本短语,通过优化网络来训练神经网络,以执行以下操作。给定短语的中间词,网络试图预测中间词周围的词。

这有助于获得一个大致的概念,但并没有为这种工作方式打下坚实的基础。让我们再试一次。

说你有“狗追猫”这句话。首先将每个单词表示为一个热编码向量,即 dog=[1 0 0],chase =[0 1 0],cat=[0 0 1]。然后你为你的狗初始化单词向量=[0,0.25],猫=[0.5,0],这是随机选择的。接下来,您将创建一个输入输出元组([1,0,0],[0,0,1]),因为单词 cat 在 dog 的上下文中。现在,您将此作为神经网络的输入和输出,并使用合适的损失函数优化您的单词向量,这将使狗和猫更加接近,即狗= [0.25,0.25],猫= [0.5,0.25])。

注意,在第一个版本中,我忘记提到你首先需要一个单词的热编码表示来学习单词向量。但是在第二个版本中,我不能绕过它,因为它是解释的一部分。因此,用例子来强化你的方法将有助于你在必要的细节上更完整。

我将很快列出其他几个帮助我提高写作水平的技巧。

几个更方便的提示…

我可以在以后的生活中继续使用提示,但仍然不会结束。但是让我分享几个更重要的提示。

  1. 使用图片——一张图片胜过千言万语。数据科学是一个非常复杂和可视化的领域。你可能会发现,如果你使用图表和文字来解释主题,会比仅仅写下来容易得多。
  2. 保持一贯的写作风格——如果你没有一贯的写作风格,读者可能不会围着你转。我们的大脑渴望一致性。这就是为什么你每天都会走同一条路线/公共汽车去上班,尽管有很多选择。你的文章也是如此。给读者一个一致的路线可循。
  3. 反复阅读——第一次尝试不太可能得到一篇完美的文章。反复阅读你的文章。确保它对你有意义

撰写数据科学文章的模板

现在我要分享一个写技术文章的模板,准确的说是数据科学文章。请知道,这是而不是一个保证最好的文章工厂,这是我写作时脑海中通常的思维模式的描述。你可以随意拿着这个,换成你喜欢的。最后,这个图像是不言自明的。所以我不会重复图像中的内容。

Writing template

我想提请你们注意的一件事是引言的提法。它的顺序很奇怪。代替广为接受的“什么-如何-为什么”,我们有为什么-什么-如何。原因?“黄金圈”,在这个视频中解释。本质上,回答为什么可以让你的读者确定他/她为什么应该关注你。

让我们结束吧!我们学到了什么?

结论

这篇文章旨在帮助你成为一名更好作家。我们讨论了如何简单,而不是用不必要的术语过度杀戮,有助于传播给更广泛的读者群。接下来我们谈到了语境的重要性,以及它如何为读者提供一个目的。然后,我们继续理解有例子和你的解释是多么有帮助。最后,我分享了我写好文章所遵循的思维模式。出好文章绝不是一蹴而就的保证方法。但是我确信它会帮助你提高。

PS:这主要是根据我的经验。但是如果你知道任何已经存在的写好数据科学文章的方法,请分享评论。我将把他们纳入讨论。

如果你喜欢,请留下一两个掌声!希望这篇文章能找到你,让你走上成为一名优秀作家的道路。干杯!

用 Python 玩游戏—第 1 部分:井字游戏

原文:https://towardsdatascience.com/lets-beat-games-using-a-bunch-of-code-part-1-tic-tac-toe-1543e981fec1?source=collection_archive---------5-----------------------

如果你碰巧看了我关于柔术的第一篇文章,我暗示了一个事实,我和电子游戏有一种苦乐参半的关系。当我赢了的时候,他们给了我一个惊人的自我提升,但是每隔一段时间,当一些孩子在火箭联赛中击败我的时候,我想把我的拳头穿过我的显示器。在我们进入令人生厌的技术内容(这是本文的主要内容)之前,让我们回顾一下我的记忆,解释一下我写这篇文章的动机:

我对电子游戏的历史可以追溯到任天堂试图拯救桃子公主到最近有毒的电子竞技地狱的时候。我涉猎了所有类型的游戏——MMORPG、射击游戏、平台游戏、MOBAs 等(如果你是麻瓜,可以在谷歌上搜索这些术语),但我还是会不断回到 MOBAs 和射击游戏上来。如果有人能联系到有一个狗屎互联网连接,你就会知道玩在线比赛是一个明确的禁忌。所以我经常发现自己在游戏的“VS 机器人”部分,在那里我可以像角斗士一样磨练我的技能,完全控制他们,感到欣喜若狂,上网玩一场排名赛,完全被控制,看着我的 elo 排名下降,哭泣(以这种确切的顺序)。没过多久,我就意识到,所谓的人工智能机器人与我有很多相似之处——毫无用处。因此,我的动机是创造更好的人工智能机器人,让我玩游戏更开心(是的,这是一个完全自私的原因)。

现在让我们回到正题——“用一堆代码解决井字游戏”。敏锐的观众可能会注意到,我使用“一堆代码”这个短语只是因为我不想只关注解决游戏的强化学习技术,还想探索其他虽然低效的技术,如树搜索、遗传算法等。我本来想玩一个更复杂的游戏,比如国际象棋,但是作为这个领域的初学者,我决定放弃自我,从一个最小状态空间的游戏开始——井字游戏

让我们来看看我们的第一个角斗士:

1.极大极小算法

极大极小算法是为两人零和游戏(井字游戏、国际象棋、围棋等)制定的决策规则。).这种算法看到了前面几步,并设身处地地为对手着想。它会一直玩下去并探索后续可能的状态,直到达到最终状态,导致平局、胜利或失败。处于这些可能的终端状态中的任何一种对 AI 都有一些效用——例如处于“赢”状态是好的(效用为正),处于“输”状态是坏的(效用为负),以及处于不好也不坏的平局(效用为中性)。

The Minimax Algorithm

在我们执行求解井字游戏的极大极小算法时,它通过可视化棋盘未来所有可能的状态来工作,并以树的形式构造它。当当前棋盘状态被给定给算法(树根)时,它分裂成‘n’个分支(其中 n 表示 AI 可以选择的棋步数/AI 可以放置的空单元格数)。如果这些新状态中的任何一个是终止状态,则不对该状态执行进一步的拆分,并按以下方式为其分配分数:

  • 得分= +1(如果 AI 赢了)
  • 得分= -1(如果 AI 输了)
  • 得分= 0(如果出现平局)

An example Minimax game tree for Tic-Tac-Toe

然而,如果没有终结状态——这些新状态中的每一个都被认为是新的根,它们会生成自己的树。但是,有一个问题——因为这是一个双人游戏,玩家轮流玩,所以每当我们在网络中深入一层时,我们需要更换将被放置在其中一个空单元格中的玩家。这样我们就可以想象对方会因为我们的行动而采取什么行动。该算法通过在轮到人工智能时选择得分最高的棋步,并在轮到人类时选择得分最低的棋步来评估最佳棋步。

用代码写出来:

完整代码:https://github . com/agr awal-rohit/medium-playing-games-with-python/blob/master/Tic % 20 tac % 20 toe/HumanvsAI _ minimax . py

由于井字游戏的状态空间如此之小,我们不可能有深度超过 9 的树。因此,我们不需要在这里使用像阿尔法-贝塔剪枝技术。然而,Minimax 的问题在于它假设了对手的一种特殊玩法。例如,一个最小最大玩家永远不会达到一个可能会输的游戏状态,即使它总是因为对手的不正确打法而从那个状态中获胜。

下面是一个示例游戏:

New Game!
----------------
|   ||   ||   |
----------------
|   ||   ||   |
----------------
|   ||   ||   |
----------------Choose which player goes first - X (You - the petty human) or O(The mighty AI): O
AI plays move: 2
----------------
|   || O ||   |
----------------
|   ||   ||   |
----------------
|   ||   ||   |
----------------Oye Human, your turn! Choose where to place (1 to 9): 3
----------------
|   || O || X |
----------------
|   ||   ||   |
----------------
|   ||   ||   |
----------------
AI plays move: 9
----------------
|   || O || X |
----------------
|   ||   ||   |
----------------
|   ||   || O |
----------------Oye Human, your turn! Choose where to place (1 to 9): 5
----------------
|   || O || X |
----------------
|   || X ||   |
----------------
|   ||   || O |
----------------
AI plays move: 7
----------------
|   || O || X |
----------------
|   || X ||   |
----------------
| O ||   || O |
----------------Oye Human, your turn! Choose where to place (1 to 9): 6
----------------
|   || O || X |
----------------
|   || X || X |
----------------
| O ||   || O |
----------------
AI plays move: 4
----------------
|   || O || X |
----------------
| O || X || X |
----------------
| O ||   || O |
----------------Oye Human, your turn! Choose where to place (1 to 9): 1
----------------
| X || O || X |
----------------
| O || X || X |
----------------
| O ||   || O |
----------------
AI plays move: 8
----------------
| X || O || X |
----------------
| O || X || X |
----------------
| O || O || O |
----------------
Draw!Wanna try again BIYTACH?(Y/N) : n

现在让我们来看看一个更令人兴奋的算法。带来第二个角斗士:

2.强化学习

我觉得这个算法更容易掌握,因为你可能每天都在使用它,甚至没有意识到这一点。让我们举一个实际的例子:

说你是狗主人。你纠缠你的配偶几个月,终于得到了那个小混蛋,但这个毛球(我们的代理)需要上厕所训练。我们的代理可以互动的物理世界是我们的环境。问题很简单——我们想让我们的狗狗在我们想要的地方做生意。但是我们如何告诉它哪个地方好或者坏,而不试图“跟狗说话”并且看起来很愚蠢?对,我们使用一个奖励系统。每当我们的代理人在我们漂亮的地毯上拉屎,它就会得到一个负面奖励(称他为坏孩子,取消一次款待,在鼻子上猛烈一击,等等)。每当它在凌晨 2 点用扩音器播放贾斯汀·比伯的邻居门前拉屎时,它就会得到一个正面奖励(称他为最好的男孩,他最喜欢的零食,揉肚子,等等)。随着时间的推移,代理人了解到,每当它想要放松时(一个特定的状态,弄脏邻居的人行道比弄脏珍贵的地毯要好,因为这会使他处于一个更好的状态,一个给予积极奖励的状态。

开发与探索

强化学习中的一个基本权衡是开发与探索的权衡。开发意味着选择最大化我们回报的行动(可能会陷入局部最优)。探索意味着选择一个行动,而不考虑它提供的回报(这有助于我们发现其他局部最优,从而使我们更接近全局最优)。在其中任何一个方面全力以赴都是有害的,所有的开发都可能导致一个次优的代理,而所有的探索只会给我们一个愚蠢的代理,它不断采取随机行动。

解决这个问题的一个广泛使用的策略是ε递减策略,我在我的实现中也使用了这个策略。它的工作原理如下:

  1. 将变量“epsilon”初始化为 0 到 1 之间的值(通常在 0.3 左右)
  2. 现在概率=ε,我们探索,概率= 1-ε,我们利用
  3. 我们随时间减少ε的值,直到它变为零

使用这种策略,代理可以在训练的早期探索更好的行动,然后在游戏的后期开发最好的行动。这有点类似于我们人类的运作方式——我们在 20 岁出头的时候探索不同的选择并寻求新的体验(探索),然后我们决定一条既定的职业道路并继续沿着这条道路前进(开发)。

时间差异学习

在该实现中使用的强化学习方法被称为时间差异学习。它的工作原理是每个状态都有一个值。比方说,如果一个状态导致 AI 获胜,它应该有一个正值(值= 1)。如果 AI 在某个状态下输了,它应该有一个负值(value = -1)。所有其余的状态将具有中性值(值= 0)。这些是初始化的状态值。

一旦游戏开始,我们的代理计算在当前状态下它能采取的所有可能的动作,以及每个动作将导致的新状态。这些状态的值是从一个 state_value 向量中收集的,该向量包含游戏中所有可能状态的值。然后,代理可以选择导致具有最高值的状态的动作(利用),或者选择随机动作(探索),这取决于ε的值。在整个训练过程中,我们玩了几个游戏,每次移动后,状态的值都使用以下规则进行更新:

Temporal Difference Update Rule

其中, V(s) —游戏棋盘的当前状态, V(s^f) —代理采取某个动作后棋盘的新状态, alpha —学习速率/步长参数。

使用该更新规则,导致损失的状态也获得负的状态值(其大小取决于学习率)。代理了解到处于这种状态可能会导致损失,所以除非必要,否则它会尽量避免在这种状态下着陆。另一方面,导致胜利的州获得正的州值。代理了解到处于这种状态可能会导致最终的胜利,所以它会被鼓励处于这种状态。

该算法的代码片段如下:

该算法有两个版本的代码:

  1. 测试代码——可以和经过训练的 AI 进行对战:https://github . com/agr awal-rohit/medium-playing-games-with-python/blob/master/Tic % 20 tac % 20 toe/testing (HumanvsAI) reinforcement learning . py
  2. 训练代码——两个玩家都是 AI ,他们每个人都互相帮助训练。这是给我外面的懒惰小队的。如果你更喜欢抓一些爆米花,让这两个 AI 在它们之间战斗,那么这里是代码:https://github . com/agr awal-rohit/medium-playing-games-with-python/blob/master/Tic % 20 tac % 20 toe/training (AIV sai) reinforcement learning . py

下面是一个对抗训练了大约 10000 个纪元的机器人的示例游戏。

New Game!
----------------
|   ||   ||   |
----------------
|   ||   ||   |
----------------
|   ||   ||   |
----------------Choose which player goes first - X (You - the petty human) or O(The mighty AI): XOye Human, your turn! Choose where to place (1 to 9): 5
----------------
|   ||   ||   |
----------------
|   || X ||   |
----------------
|   ||   ||   |
----------------
Possible moves = [1, 2, 3, 4, 6, 7, 8, 9]
Move values = [-0.218789, -0.236198, -0.147603, -0.256198, -0.365461, -0.221161, -0.234462, -0.179749]
AI plays move: 3
----------------
|   ||   || O |
----------------
|   || X ||   |
----------------
|   ||   ||   |
----------------Oye Human, your turn! Choose where to place (1 to 9): 1
----------------
| X ||   || O |
----------------
|   || X ||   |
----------------
|   ||   ||   |
----------------
Possible moves = [2, 4, 6, 7, 8, 9]
Move values = [-0.633001, -0.625314, -0.10769, -0.543454, -0.265536, 0.034457]
AI plays move: 9
----------------
| X ||   || O |
----------------
|   || X ||   |
----------------
|   ||   || O |
----------------Oye Human, your turn! Choose where to place (1 to 9): 6
----------------
| X ||   || O |
----------------
|   || X || X |
----------------
|   ||   || O |
----------------
Possible moves = [2, 4, 7, 8]
Move values = [-0.255945, 0.003558, -0.2704, -0.25632]
AI plays move: 4
----------------
| X ||   || O |
----------------
| O || X || X |
----------------
|   ||   || O |
----------------Oye Human, your turn! Choose where to place (1 to 9): 2
----------------
| X || X || O |
----------------
| O || X || X |
----------------
|   ||   || O |
----------------
Possible moves = [7, 8]
Move values = [0.0, 0.03941]
AI plays move: 8
----------------
| X || X || O |
----------------
| O || X || X |
----------------
|   || O || O |
----------------Oye Human, your turn! Choose where to place (1 to 9): 7
----------------
| X || X || O |
----------------
| O || X || X |
----------------
| X || O || O |
----------------
Draw!Wanna try again BIYTACH?(Y/N) : n
Suit yourself bitch!

表演时间到了

现在我们已经准备好了两个冠军,让我们把他们扔进虚拟竞技场,让他们在我们敬畏的注视下一决雌雄。既然我们现在只有 2 个,那就来一场 1v1 的 TKO 战吧。这是结果:

Results(10 games):
Minimax Wins = 0
RL Agent Wins = 10

(我召唤了一个怪物,不是吗?)

如果你想看完整场比赛,下面是代码:https://github . com/agr awal-rohit/medium-playing-games-with-python/blob/master/Tic % 20 tac % 20 toe/downstall _ Minimax _ vs _ rl . py

这些是我已经修补过的唯一的算法。我可能会研究一些其他有趣的算法,比如遗传算法,但那是以后的事了。如果你觉得我的文章很有帮助,甚至有趣到让你微微发笑,请鼓掌并在下面回复。

感谢你阅读❤

让我们用简单的数字编码一个神经网络

原文:https://towardsdatascience.com/lets-code-a-neural-network-in-plain-numpy-ae7e74410795?source=collection_archive---------0-----------------------

神经网络的秘密第三部分

像 Keras、TensorFlow 或 PyTorch 这样的高级框架允许我们快速构建非常复杂的模型。然而,值得花时间深入了解和理解基本概念。不久前,我发表了一篇文章,以简单的方式解释了神经网络是如何工作的。然而,这是一个高度理论化的职位,主要致力于数学,这是神经网络超能力的来源。从一开始,我就计划以更实际的方式跟进这个话题。这次我们将尝试利用我们的知识,仅使用 NumPy 构建一个完全可操作的神经网络。最后,我们还将测试我们的模型——解决简单的分类问题,并将其性能与用 Keras 构建的神经网络进行比较。

注:承蒙 Jakukyo 弗列尔的礼遇,你也可以用中文阅读这篇文章。显然,今天的帖子将包含大部分用 Python 编写的代码片段。然而,我希望阅读不会太无聊。:)你也会在我认为不明确或者不值得关注的地方找到短评。像往常一样,所有的源代码都可以在我的 GitHub 上获得。

Figure 1. Example of dense neural network architecture

重要的事情先来

在我们开始编程之前,让我们停下来准备一个基本的路线图。我们的目标是创建一个程序,该程序能够创建一个具有指定架构(层数和大小以及适当的激活函数)的密集连接的神经网络。这种网络的一个例子如图 1 所示。最重要的是,我们必须能够训练我们的网络,并使用它进行预测。

Figure 2. Neural network blueprint

上图显示了在我们的神经网络训练过程中需要执行的操作。它还显示了在一次迭代的不同阶段,我们需要更新和读取多少参数。构建正确的数据结构并巧妙地管理其状态是我们任务中最困难的部分之一。由于时间限制,我将不详细描述图中所示的每个参数的作用。我向所有感兴趣的人推荐本系列的第一篇文章,我希望你能在那里找到困扰你的所有问题的答案。

Figure 3. Dimensions of weight matrix W and bias vector b for layer l.

神经网络层的初始化

L et 开始初始化每层的权重矩阵 W 和偏置向量 b 。在图 3 中。我准备了一个小备忘单,它将帮助我们为这些系数分配适当的维数。上标【l】表示当前层的索引(从 1 开始计数),值 n 表示给定层中的单元数量。我假设描述神经网络架构的信息将以列表的形式传递给我们的程序,类似于代码片段 1 中的列表。列表中的每一项都是描述单个网络层的基本参数的字典:input_dim -作为该层的输入提供的信号向量的大小,output_dim -在该层的输出处获得的激活向量的大小,以及activation -将在该层内部使用的激活函数。

Snippet 1. A list containing parameters describing a particular neural network. This list corresponds to the NN shown in Figure 1.

如果你对这个话题很熟悉,你可能已经听到你脑海中有一个声音带着焦虑的语气说:“嘿,嘿!出事了!有些字段是不必要的……”。是啊,这次你内心的声音是对的。从一层出来的向量也是下一层的输入,所以实际上只需要知道其中一个向量的大小就足够了。然而,我特意决定使用下面的符号来保持所有层中对象的一致性,并使代码对于第一次遇到这些主题的人来说更容易理解。

Snippet 2. The function that initiates the values of the weight matrices and bias vectors.

最后,让我们把重点放在我们必须完成的主要任务上——层参数的初始化。那些已经看过代码片段 2 的代码并且对 NumPy 有一些经验的人已经注意到矩阵 W 和向量 b 已经被小的随机数填充。这种做法不是偶然的。权重值不能用相同的数字初始化,因为这会导致对称性破坏问题基本上,如果所有权重都相同,无论输入 X 是什么,隐藏层中的所有单元也将相同。在某种程度上,我们陷入了初始状态,没有任何逃脱的希望,无论我们将模型训练多久,我们的网络有多深。线性代数不会原谅。

在第一次迭代中,小值的使用提高了我们算法的效率。查看 sigmoid 函数的图表,如图 4 所示,我们可以看到,对于大值,它变得几乎平坦,这对我们的神经网络的学习速度有重大影响。总之,使用小随机数进行参数初始化是一种简单的方法,但它保证了是我们算法的足够好的起点。准备好的参数值存储在 python 字典中,并带有唯一标识其父图层的关键字。字典在函数结束时返回,所以我们将在算法的下一阶段访问它的内容。

Figure 4. Activation functions used in the algorithm.

激活功能

A 综合了我们会用到的所有功能,有几个非常简单但功能强大。激活函数可以用一行代码编写,但是它们给了神经网络所需的非线性和表达能力。"没有它们,我们的神经网络将变成线性函数的组合,所以它本身将只是一个线性函数。"有许多激活函数,但在这个项目中,我决定提供使用其中两个的可能性——sigmoid 和 ReLU。为了能够完成整个循环并通过正向和反向传播,我们还必须准备它们的导数。

Snippet 3. ReLU and Sigmoid activation functions and their derivatives.

正向传播

他设计的神经网络将会有一个简单的架构。信息以一个方向流动——它以一个 X 矩阵的形式传递,然后穿过隐藏单元,产生预测向量 Y_hat 。为了更容易阅读,我将前向传播分成两个独立的函数——对单个层进行前向传播,对整个神经网络进行前向传播。

Snippet 4. Single layer forward propagation step

这部分代码可能是最简单易懂的。给定来自前一层的输入信号,我们计算仿射变换 Z ,然后应用选定的激活函数。通过使用 NumPy,我们可以利用矢量化功能——一次对整个图层和整批示例执行矩阵运算。这消除了迭代,大大加快了我们的计算速度。除了计算出的矩阵 A 之外,我们的函数还返回一个中间值 Z 。为什么答案如图 2 所示。在后退的过程中,我们需要 Z。

Figure 5. Dimensions of individual matrices used in a forward step.

使用预先准备的一层前向步骤函数,我们现在可以很容易地建立一个完整的前向传播步骤。这是一个稍微复杂一点的函数,它的作用不仅是执行预测,而且是组织中间值的集合。它返回 Python 字典,其中包含为特定层计算的 AZ 值。

Snippet 5. Full forward propagation step

损失函数

在中,为了监控我们的进展并确保我们朝着正确的方向前进,我们应该定期计算损失函数的值。“一般来说,损失函数旨在显示我们离‘理想’解决方案有多远。”根据我们计划解决的问题进行选择,Keras 等框架有很多选项可供选择。因为我打算测试我们的神经网络对两个类之间的点的分类,所以我决定使用二元交叉熵,它由以下公式定义。为了获得更多关于学习过程的信息,我还决定实现一个计算准确度的函数。

Snippet 6. Calculating the value of the cost function and accuracy

反向传播

最近,反向传播被许多缺乏经验的深度学习爱好者视为令人生畏且难以理解的算法。微分学和线性代数的结合经常使没有受过扎实数学训练的人望而却步。所以如果不能马上理解所有的东西,也不用太担心。相信我,我们都经历过。

Snippet 7. Single layer backward propagation step

人们经常混淆反向传播和梯度下降,但实际上这是两回事。第一个目的是有效地计算梯度,而第二个目的是使用计算的梯度进行优化。在神经网络中,我们计算成本函数(前面讨论过)关于参数的梯度,但是反向传播可以用于计算任何函数的导数。这个算法的本质是微积分中已知的链式法则的递归使用——计算由其他函数集合而成的函数的导数,这些函数的导数我们已经知道。对于一个网络层,该过程由以下公式描述。不幸的是,由于本文主要关注实际实现,我将省略推导过程。看看这些公式,很明显为什么我们决定记住中间层的 AZ 矩阵的值。

Figure 6. Forward and backward propagation for a single layer.

就像向前传播的情况一样,我决定将计算分成两个独立的函数。第一个——如代码片段 7 所示——集中在一个层上,归结为用 NumPy 重写上面的公式。第二个表示完全向后传播,主要处理读取和更新三个字典中的值的键杂耍。我们首先计算成本函数相对于预测向量的导数——前向传播的结果。这很简单,因为它只包括重写下面的公式。然后从末端开始遍历网络的各层,根据图 6 所示的图表计算所有参数的导数。最终,函数返回一个 python 字典,其中包含我们正在寻找的渐变。

Snippet 8. Full backward propagation step

更新参数值

T 该方法的目标是使用梯度优化更新网络参数。这样,我们试图使我们的目标函数更接近最小值。为了完成这个任务,我们将使用作为函数参数提供的两个字典:params_values,它存储参数的当前值,以及grads_values,它存储根据这些参数计算的成本函数导数。现在你只需要对每一层应用下面的等式。这是一个非常简单的优化算法,但我决定使用它,因为它是更高级的优化器的一个很好的起点,这可能是我下一篇文章的主题。

Snippet 9. Updating parameters values using gradient descent

把东西放在一起

我们终于准备好了。任务中最困难的部分已经过去——我们已经准备好了所有必要的功能,现在我们只需要按照正确的顺序将它们组合在一起。为了更好地理解操作的顺序,值得再次查看图 2 中的图表。该函数返回作为训练结果获得的优化权重以及训练期间指标变化的历史记录。为了进行预测,您只需要使用接收到的权重矩阵和一组测试数据运行一个完整的前向传播。

Snippet 10. Training a model

大卫 vs 歌利亚

是时候看看我们的模型能否解决一个简单的分类问题了。我生成了一个数据集,由属于两个类的点组成,如图 7 所示。让我们试着教我们的模型对属于这个分布的点进行分类。为了对比,我还准备了一个高层框架的模型——Keras。这两种模型具有相同的架构和学习速率。然而,这确实是一场不均衡的战斗,因为我们准备的实现可能是最简单的。最终,NumPy 和 Keras 模型在测试集上都达到了相似的 95%的准确率。然而,我们的模型花了几十倍的时间才达到这样的结果。在我看来,这种状态主要是由于缺乏适当的优化造成的。

Figure 7. Test dataset

Figure 8. Visualisation of the classification boundaries achieved with both models

再见

我希望我的文章拓宽了你的视野,增加了你对神经网络内部编译操作的理解。这将是对我努力创建这个帖子的最好回报。我承认,通过编写代码和注释,我确实学到了很多东西。的确,没有什么比弄脏你的手更有教育意义。

如果你有任何问题或者你在源代码中发现了错误,请在评论中告诉我。如果你喜欢这篇文章,请在 TwitterMedium 上关注我,并在 GitHubKaggle 上查看我正在进行的其他项目。本文是“神经网络的奥秘”系列的第三部分,如果你还没有机会,请阅读其他文章。保持好奇!

让我们用机器学习模型为慈善事业寻找捐赠者

原文:https://towardsdatascience.com/lets-find-donors-for-charity-with-machine-learning-models-7ad1da9f5538?source=collection_archive---------15-----------------------

监督学习算法的一个应用

欢迎来到我关于数据科学的第二篇博文。我将在这里写一个我用机器学习算法完成的项目。我将解释我做了什么,而不太依赖技术语言,但我会展示我的代码片段。代码问题:)

这个项目是一个假设的案例研究,我必须为一个慈善机构寻找潜在的捐赠者,这个慈善机构为愿意在硅谷研究机器学习的人提供资金。这个名为 CharitML 的慈善机构发现,每位捐赠者的年收入都超过了 5 万美元。我的任务是使用机器学习算法来帮助这个慈善机构在整个加州地区识别潜在的捐赠者。

为了这个项目,我使用了监督机器学习。在监督学习中,您有输入变量(X)和输出变量(Y ),并使用算法来学习从输入到输出的映射函数。我将描述我从一个杂乱的数据集到一个好的工作模型所采取的步骤。

数据处理

从探索数据开始总是好的。基本上,寻找观察的总数、特征的总数、缺失值、哪些特征应该被编码等等。最重要的是,寻找你正在解决的问题的特征。在这种情况下,我感兴趣的是有多少人年收入超过或低于 5 万美元。

There are 13 features.

变换歪斜连续的特征

一个数据集有时可能包含至少一个其值趋向于接近一个单一数字的特征,但是也将具有比该单一数字大得多或小得多的非平凡数量的值。算法可能对这种值的分布很敏感,并且如果范围没有被适当地标准化,则可能表现不佳。对于我们的数据集,有两个特征符合这个描述:'capital-gain''capital-loss'

归一化数值特征

对数字要素执行某种类型的缩放通常是一种很好的做法。对数据进行缩放不会改变每个特征分布的形状(如上面的'capital-gain''capital-loss');但是,规范化可以确保在应用受监督的学习者时,每个特征都得到平等对待。这些特性的值将介于 0 和 1 之间。

编码数据

通常,学习算法期望输入是数字,这需要转换非数字特征(称为分类变量)。转换分类变量的一种流行方法是使用一键编码方案。一键编码为每个非数字特征的每个可能类别创建一个“虚拟”变量。

洗牌并拆分数据

现在所有的分类变量都已经被转换成数字特征,并且所有的数字特征都已经被规范化。与往常一样,我们现在将数据(包括要素及其标签)分成训练集和测试集。80%的数据将用于训练,20%用于测试。

模型度量

在进入我为这个项目测试的不同模型之前,我将详细说明我们如何判断一个模型的质量。我们在决定选择哪个型号时会看什么?在我们希望模型预测得有多好和它的计算代价有多高之间,总会有一个权衡;或者训练它需要多长时间。

模型性能的三个主要度量是:准确度、精确度和召回率。

准确性衡量分类器做出正确预测的频率。它是正确预测的数量与预测总数(测试数据点的数量)的比率。

Precision 告诉我们被我们归类为垃圾邮件的邮件中,实际上有多少是垃圾邮件。它是真阳性(分类为垃圾邮件的单词,实际上是垃圾邮件)与所有阳性(分类为垃圾邮件的所有单词,不管这是否是正确的分类)的比率。

Recall(sensitivity) 告诉我们实际上是垃圾邮件的邮件中有多少被我们归类为垃圾邮件。它是真阳性词(被归类为垃圾邮件的词,以及实际上是垃圾邮件的词)与所有实际上是垃圾邮件的词的比率。

不同的措施对不同的问题有不同程度的影响。因此,我们应该知道哪个指标对我们更重要。例如,将收入不超过 5 万美元的人认定为收入超过 5 万美元的人将对 CharityML 不利,因为他们正在寻找愿意捐款的人。因此,一个模特的 的能力,准确地说 预测那些挣 5 万美元以上的人比模特的 回忆 那些个人的能力更重要。

我们可以使用 F-beta 分数作为同时考虑精确度和召回率的指标:

天真基线预测值

如果我们选择一个总是预测个人收入超过 50,000 美元的模型,那么这个模型在这个数据集上的准确性和 F 值是多少?我们想知道未经训练的模特会是什么样子。

监督学习模型

This is not an exhaustive list

在这些选项中,我尝试并测试了其中的三个: SVM、ADABOOST 和 Random Forrest。

Adaboost 模型最适合我们的问题。Adaboost 在测试数据集上的 F 值最高。除此之外,像 RandomForest 一样,训练集和测试集之间的 F 分数没有很大的差异。这很重要,因为我们不希望我们的模型过度适应训练集,并返回一个夸大的 F 分数。Adaboost 在所有训练集规模下的准确率和 F 值都是最高的。训练和测试时间非常短,这意味着该模型的计算速度很快。模型的迭代方面使它能够很好地处理大量的属性,就像我们的例子一样。因此,这是一个很好的选择。

ADABOOST 如何工作

Adaboost ,简称自适应增强是一种集成算法。 Adaboost 算法使用迭代训练来给出精确的模型。它从弱学习者开始,这是数据的初始分类。也就是说,分类是用决策树桩完成的。这意味着分类只是用一条线来分隔数据。它被称为‘弱’,因为数据还没有被很好地分类。但是由于进一步的迭代,该模型使得学习者关注于误分类点。更准确地说,在第一步中,弱学习者分离数据,并且所有的点被同等地加权。如果存在错误分类的点,在第二次迭代中,弱学习器试图捕捉这些先前的错误中的大部分,并为它们分配更高的权重。本质上,该模型通过对误差进行更多的加权来关注误差。只要我们指派它去做,这个迭代过程就会继续。因此,随着每一次迭代,模型捕获的数据越来越好。弱学习者被组合起来,并根据他们的表现分配权重。通过计算弱分类器的加权平均值来进行预测。最终的学习者是由弱学习者组合而成的强学习者。

模型调整

我们可以通过使用网格搜索来进一步改进所选择的模型。这个想法是为一些参数使用不同的值,比如估计器的数量或学习率,以便获得更好的性能指标。

Hope you’re not tired of these yet

我们可以看到优化的模型比未优化的模型表现得更好。准确率从 0.8576 提高到 0.8651,F 值从 0.7246 提高到 0.7396。请记住,朴素预测器给我们的准确度分数为 0.2478,F 分数为 0.2917,这并不奇怪,因为朴素模型不对数据进行任何训练。

特征抽出

在这个数据集中的 13 个特征中,我很好奇哪一个具有最高的预测能力。如果我们只在模型中使用这些,会发生什么?

在简化的模型中,精确度和 F 值都下降了。在这种情况下,与完整模型相比,较少的特征使得模型的泛化能力稍差。然而,分数的降低并不高。反过来,训练时间更快,因为模型包含的特征更少。因此,如果训练时间是一个因素,这种权衡将是有意义的,因为我们不会在性能方面损失太多。

汇总

那我们做了什么?我们得到了一个数据集,并设定了一个目标,对年收入超过 5 万美元的人进行分类。我们清理了数据,将必要的变量标准化并转换成数字特征,以便在我们的模型中使用它们。我们将数据分成训练集和测试集。我们设定了一个基线预测值,并建立了另外三个模型。我们选择 ADABOOST 模型作为最佳选择。我们对它做了进一步的调整,使它稍微好了一些。我们试图使用只有五个主要特征的模型,但它的表现稍差。

最后的话

这是它:)如果你通过了这里,我想说一声非常感谢你。我希望这是监督机器学习的一个很好的、清晰的应用。它是数据科学中一个强有力的工具;我目前正在学习并想掌握的东西。如果你有问题,欢迎在下面发表评论,你也可以随时看看这个项目,包括我的 github 上的许多其他项目。

在 LinkedIn 上关注我:https://www.linkedin.com/in/andreigalanchuk/

上帝保佑你们!

让我们解决雅加达的交通问题

原文:https://towardsdatascience.com/lets-fix-jakarta-s-traffic-584058dac87f?source=collection_archive---------6-----------------------

推进公共交通的分析方法

Photo by Alexander Popov on Unsplash

众所周知,雅加达的交通状况是一个问题。最近的一项 T2 调查将雅加达列为世界第七差。事实令人震惊——目前道路上的摩托车数量徘徊在 1400 万辆左右,但预计到 2020 年将跃升至 6600 万辆,如果不采取任何措施,这一数字将增长 370%。然而,应对这一挑战并非没有通知或补救措施。雅加达省长和中央政府已经尝试了几种方法来减少交通拥堵。其中之一是单双号交通政策,该政策试图通过控制某一天城市道路上的车辆数量来减少交通流量。虽然这是一项值得称赞的努力,但它只是触及了试图解决更大问题的表面。佐科·维多多总统认识到了这一点,并发布了一项行政命令,集中精力改善公共交通,作为解决城市交通问题的长期方案。

下面来看看实际订单。请原谅我,如果你不会说巴哈萨语…请相信我。;)

在第 2 章“SASARAN DAN KEBIJAKAN PENYELENGGARAAN TRANSPORTASI JABODETABEK”中,规定到任何公共交通站的最大步行距离应为 500 米。

所以我从一个简单的问题开始:

城市(区域)中有多大比例不在此距离内(基于道路距离,而不仅仅是半径,因为半径并不能完全反映您需要步行的距离)?

我首先收集了目前雅加达所有的公共交通站点,包括小型货车、小型公共汽车、中型公共汽车、Transjakarta 和火车。总共有超过 19,749 站。

Pink dots represent individual public transportation stops

接下来,我画出了一个距离每个车站 500 米以内的区域。例如,我模拟了一条 500 米长的可步行路径,从位于 Kelapa Gading 的一个 Transjakarta 通勤站出发。模拟路径是实际街道路线,它必须与 Transjakarta 站连接。街道路径可以是一条主干道或街道小巷(Jalan Gang)。

以下是这一分析的直观描述:

Pink Node is the Transjakarta Bus Stop, blue area indicate that within 500 meters walking distance

为什么我选择了道路/路径路线而不是半径?

一个点周围的半径通常不能预测一个人要走多远。是的,从理论上讲,一个人可以通过穿越房产、跳过栅栏、跑过建筑物或其他我们在任何情况下都无法预测的策略来减少步行距离(当然,我们永远不会建议一个人这样做来缩短步行距离)。因为半径代表一种不太可能的情况,我觉得使用实际的道路将是一种更准确的方式来预测步行距离。

然后,我将交通站点数据与 500 米的路线数据合并,并创建了以下模拟。这描绘了当前公共交通生态系统覆盖的城市面积。

Black represents the covered area by public transport. Blue is currently uncovered by public transport.

清理最终可视化

我想更好地看看这个城市的差距在哪里。所以,我拓宽并合并了雅加达的所有停靠点,并把它们重新标在了地图上。这让我能够更好地识别和区分覆盖区域和未覆盖区域。然后,出于视觉清洁的目的,我移除了所有的公共停车点。现在我们可以看到公共交通站点未覆盖的剩余区域。

Uncovered area within 500 meters walking distance to public transportation

摘要

对地图背后的数据进行一些基本的分析,我估计 45%的地区没有公共交通站。这代表了覆盖大约 3 亿平方米的区域(在该城市的总共 6.55 亿平方米中)。

一个警告:很可能这个区域至少有一部分不是你通常需要步行的地方。例如,如果你站在一条繁忙的高速公路上,距离一个站点 600 米,那么从技术上来说,你是“未被覆盖”的。然而,你不太可能需要从那里走过去(除非你的车坏了或者类似的事情)。因此,虽然我可能稍微夸大了未覆盖的区域,但这可能已经不远了。

最后,这方面的数据设计在改善城市交通挑战方面有着广泛的应用。它还应该让我们所有人都意识到,并继续学习和提问。

跟进问题

为什么行政命令把规则定在“500 米”?

这是一个起点,但也许更好的问题是“步行的合理距离是多少?”。设定这一目标的后果值得考虑。如果 250 米是标准,那么未覆盖的区域将会更大,需要更高水平的投资。如果我们把范围设得更长(比如 750 米),政府的投入会更低,但那样人们可能就不会使用公共交通了。

人们喜欢较短的步行距离还是较短的等待时间?

与其投资新的车站,解决方案可能是增加公共交通“车队”。也许这甚至不是消费者考虑的权衡,但在我们向这个系统投资数十亿美元之前,我们不应该知道吗?

我要感谢我的同事 Raihan Saputra 的分析支持,感谢 GO-JEK 公司重视社会影响。这些都是我探索这个挑战和解决这个项目的关键动力。我的希望是,通过使我们对这个问题的理解更加经验性和基于事实,我们可以改善雅加达居民的流动性。

有兴趣做更多这样的事情吗?邮箱

我们来忽悠一个神经网络!

原文:https://towardsdatascience.com/lets-fool-a-neural-network-b1cded8c4c07?source=collection_archive---------2-----------------------

通过使用对抗性补丁

在这篇文章中将看到如何欺骗一个对象分类器神经网络,具体来说就是 VGG16 ,使用一种新技术来创建对抗性补丁。

原文可以在这里找到,所有代码和资料在这里

介绍

通常,欺骗对象分类器的标准方法是通过以特定的方式迭代地添加一些噪声来创建图像,试图最大化模型的误差。由此产生的图片看起来与人类非常相似,但会给网络带来巨大的误差。这种技巧的一个例子可以 DeepFool,在本文中介绍 简而言之,它扰乱图像,使其几乎等同于人眼,但不同于神经网络

原始图像被正确分类为“鲸鱼”,而第二个图像(将两个图像相加创建)被分类为“海龟”。

虽然这种方法非常有效,但它不适合现实生活中的场景。引用原文:

这种策略可以产生很好的伪装攻击,但是需要修改目标图像

给出的创建对抗性 补丁 的方法是通过给图像添加一个路径,一个贴纸,而不是完全改变它。

因此,人们可以只打印标签,并很容易地将其放置在真实对象附近,以欺骗网络。具体来说,生成路径是为了让模型预测一个错误的类,在我们的例子中是烤面包机。此外,这在现实生活中非常有效,例如,当分类器使用摄像机来执行活体对象检测时。

我强烈建议阅读原始论文的第二部分,以获得如何找到路径的所有细节。

亲自动手

让我们实际尝试一下。该文件提供了一个专门为 VGG16 (广泛使用的对象分类器模型)创建的路径,它使分类器相信图像中有一个烤面包机。我用这个网站来测试它是否有效。

Header of the online demo of the VGG16 that I used

一个更科学的方法是下载一个 VGG16 训练过的模型,然后用应用了路径的测试集中的每个图像绘制误差,但是我没有时间这么做。

此外,路径不应直接应用于对象,否则它会覆盖我们试图分类的原始对象。

要将路径应用于图像,您可以使用您最喜欢的图像编辑软件。我决定稍微花点心思,在 node.js 中创建一个命令行来做到这一点。它允许我在标贴上指定目标图像的位置和大小,你可以在这里找到代码

> node index.js ../images/banana.jpg center up 2
Processing image: ../images/banana.jpg
Path will be placed center-up
Image saved at: ../images/banana-pathed.jpg

第一个参数是源图像路径,第二个和第三个分别表示路径的位置,水平和垂直,最后一个是路径相对于源图像的比率。

在这种情况下,脚本获取一个香蕉的图像,在上面粘贴标签并存储它,这就是输出。

现在让我们来看看 VGG16 用原始图像和“修补”图像预测了什么。我们使用这个网站是为了更新和获得一个图像的预测。

配原图:

Yep, it is a banana

有补丁的那个

Now its a toaster!

有用!或者,至少对香蕉来说。让我们试试另一个例子:

node index.js ../images/bird.jpg left center 3

We fool it again!

在原始图像上,该模型以 100%的置信度正确预测了类“Jay ”,在修补后的图像上,该模型以 67.1%的置信度预测了“Toaster ”,以 3.5%的置信度预测了“Jay”。是的,我们又骗了它!

我建议你用你自己的图像试试,它很有趣。

结论

所提出的创建对抗路径的方法是一种在不修改目标图像的情况下在现实生活场景中有效愚弄神经网络的新方法。一个路径可以被打印成一个标签,并直接应用于一个对象,以改变预测的类和“愚弄”神经网络,这可能是非常危险的。

原文可以在这里找到,所有代码和资料可以在这里

感谢您的阅读,

弗朗西斯科·萨维里奥

让我们自由地检查一些东西!

原文:https://towardsdatascience.com/lets-go-over-few-things-freeciv-1d400969ad3e?source=collection_archive---------22-----------------------

建立正确的基础是大发展的关键

正如我在上一篇文章中所说,我对用 python 建立一个自由学习环境很感兴趣。但许多人认为,这些细节要么过于宽泛,要么包含了太多的想法。在接下来的几篇文章中,我想澄清一些问题,为这个项目打下基础。

如今,建立一个开源项目非常容易,你所要做的就是注册一个 Github 账户,然后嘣,你就准备好了!但是困难的部分是运行和维护代码库,更困难的是让人们足够关心你的项目,为你的项目贡献任何东西,我想在这里把重点放在后者。通过这些帖子,我想澄清我的想法,并讨论提出的问题。这一次,我想谈谈这三点:

  1. 行动空间:为什么自由公民的离散行动空间很重要
  2. 游戏结构:游戏的浩瀚如何与现实世界相似
  3. 多人协作理念:【freeciv 如何支持不同类型的互动,它有什么特别之处

为了更容易理解,我还会在每一点上添加分点。这

我在这里不是问那些很难回答的问题,比如为什么关心任何事情。但是为什么要关心这个项目呢?

1.动作空间

我们宇宙中的每一个动作都可以分解成两种类型,连续动作空间和离散动作空间。通俗地说,离散空间是需要做出艰难决定的地方,而连续空间是要产生分布的地方。

  • 现实生活领域中涉及硬件使用的大多数应用(机器人、自动驾驶汽车等。)需要生成值的分布。用来操作它们的运动矢量是一组力的值和方向。这一领域仍处于早期阶段,但其应用仍将遥遥无期。随着时间的推移,它将继续改进,尽管速度较慢,原因是模拟器不够好(讽刺的是,在机器人模拟器上训练的代理很少在现实生活中给出相同的结果)。我们的算法在样本效率方面并不擅长,在现实生活中的机器人上进行训练将意味着非常长的训练持续时间,这使得它不可行。

Self driving car operates in the continuous distribution

  • 离散动作空间有不同的任务,所有那些需要做出艰难决策的应用都有一个离散空间。视频游戏就是一个很好的例子,它们需要一个非常具体的单一动作,需要在任何给定的时刻采取。到目前为止,我们看到的大多数研究都是在这个领域,彻底改变了深层强化学习理念的 DQN 在离散领域采取了行动。在医学领域,我们需要随着时间的推移展开行动,这是离散空间中现实世界应用的一个例子。其他应用包括,优化由于网络条件差而受到影响的流媒体服务的视频质量,社交网站上的通知系统只通知你重要的内容,等等。

Montezuma’s Revenge is an Atari game with discrete action space. This also happens to be a notoriously difficult game for AI to master due to its sparse reward structure.

我们不需要一个擅长所有事情的单个智能体,事实上,未来将充满整体架构,其中每个擅长特定事情的多个智能体合作实现远超人类的目标,这就是我们所说的超级智能。作为一款视频游戏,Freeciv 在离散的空间中运行。这是选择它的原因之一,它将是最具挑战性的学习环境之一。尽管在这种情况下仍有可能采取连续的行动。稍后将提供更多详细信息!

Freeciv 将是最具挑战性的学习环境之一,这里所做的研究将是突破

2.游戏结构

说 freeciv 很大是一种保守的说法。你可以做的事情太多了,很难记住所有的事情,而且在任何时候采取的行动都会影响游戏后期的结果。

  • 每个单位都有动态的移动次数,也就是说,每个单位都有不同的行动,每个城市都可以建造新的单位和物品。在下图中,我们可以看到一个单元有 12 个动作。这就要求人工智能根据它在特定时刻控制的单元进行优化。现在你可以有一个复杂的单一网络来运行这个,但我认为使用集成可以获得更好的结果。

The game at turn 314 is so advanced, though the game in ‘default’ mode can run to 5000 turns. The small circles at the bottom show the actions that can be takes for any unit. 12 actions can be taken for this particular unit, 1 less than the Atari games! This is an amazing example of the vastness of this game.

  • 除了行动之外,看看技术树可以让你了解必须做出的各种决策的规模及其后果。为了在游戏中进步,代理需要获得新的和不同的技术。每项技术都是大树上的一个节点,要得到一项,需要完成前面的几项。这对人工智能进行长时间步骤的结构规划提出了挑战。这与通过查看当前帧来选择单个动作的现有技术环境非常不同。

A sample tech-tree in freeciv. As you can see in the right, to get Electricity, you need to have Metallurgy and Magnetism. This complex intermixing of possibilities make life tricky for our small agent.

  • 我还想谈一下城市。你的城市质量和你的权力之间有明显的关联。城市是这个游戏的核心,改善它们会增加你成功的机会。看看下面一个简单的城市,这是一个大城市。“城市半径”中的每块瓷砖都有与之相关的价值,如食物和黄金。瓷砖的质量越好,你的城市就越好,反过来你的文明也就越好。

A sample city, more details about the cities here

  • 由于战争的迷雾(以及不清楚的工作列表、资源),敌人的位置/状态和整个地图并不完全清楚——因此需要高风险的投资(探险队)来获取信息。

如上所示,战略、行动、决策、运动等的多样性。将这种环境推向了一个新的领域。由于所有这些挑战,看看人工智能将如何自我运作是很有趣的。这与现实世界非常相似,在现实世界中,我们需要在大量不完整信息的情况下做出决策,而我们今天的行为会对以后产生影响。

从使用这个平台开发模型和架构中学到的知识可以用来解决各种现实世界的问题。

3.多层协作结构

Freeciv 可以被大量玩家玩,具体来说,在 freeciv 桌面上可以玩 126 人,在 freeciv 网络上可以玩 500 人。游戏是有规则可循的,这些被称为规则集。在经典/默认规则集中,有三种获胜方式:

  • 正如在其他征服和扩张的游戏中,一旦其他文明的最后一个城市和单位被摧毁,你就被默认宣布为胜利者。
  • 一旦技术进步将你带入太空时代,你可能会发射一艘前往半人马座阿尔法星的宇宙飞船;第一个工艺到达该系统的文明获胜。
  • 在没有其他手段决定胜利的情况下,如果还没有飞船发射,游戏将在 5000 回合后结束。然后对幸存的文明进行评级,拥有最高分数的文明获胜。

由于项目的开源性质,可以根据研究人员的需要修改规则集。我们打算让这项工作变得轻而易举,这样研究人员就可以把大部分时间花在开发他们的模型上,而不必担心无聊的事情。这也允许极端定制,可以使这个环境更好。

Look at the minimap at bottom left, the opportunity to see how various AIs will compete with each other is one thing that really excites me about this!

  • 外交是这场游戏的重要组成部分,其中的互动非常重要。开放和贸易有利于玩家促进国家的经济发展,但在游戏的后期却变成了敌人并互相争斗。所有这些当然都可以通过改变配置文件中的游戏结构来改变*.fcfg.这种合作可以在整体人工智能系统中产生巨大的成果,其中许多小型人工智能系统组合起来使整个系统工作。

有了大量的玩家可以玩这个游戏,就有了一个研究协作系统如何工作的机会。随着竞技自我游戏合作游戏领域的最新发展,当大量人工智能被单独留在一个类似地球的世界中时,看看世界将如何发展将是有趣的。也许我们会明白聪明的智能将如何从这一团乱麻中脱颖而出。

当大量人工智能被单独留在一个类似地球的世界里时,观察事件如何发展将会很有趣

结论

这些帖子不仅宣传了这个想法,也给了我一个机会来表达我对如何使这个项目成功的想法。对于任何开源项目来说,开始阶段都非常重要。有大量的工作要做,还有很长的路要走。在目前处于设计阶段的第一个版本中,我们更多地关注迷你游戏,所以可以开始小的开发,并且可以进行改编。

欢迎投稿人,如果您有任何疑问/想法,请发我的 LinkedIn 给我,或者留下私人笔记,我不介意现在是凌晨 4 点,我会回复您。

干杯!

先把它学深了再玩深

原文:https://towardsdatascience.com/lets-learn-it-deep-before-we-play-it-deep-6b50cdca5adb?source=collection_archive---------3-----------------------

我记得唐纳德·克努特的《具体数学》一书,这本书是我的一位数学老师写的,他认为有太多的东西被单调地抽象成公式和符号,这本书奠定了数学科学的哲学和思想基础。被标题所吸引,受作者的教科书系列“计算机编程的艺术”的启发,我尝试了一下。令我惊讶的是,它从非常基本的计数问题和已知问题开始,如“河内塔”和其他问题。唯一的区别是,它谈到了如何制定和处理问题,最后给出了公式,这是所有书中常见的唯一的事情。

那是我第一次意识到我滥用递归公式有多长时间了,不知道它真正的意思,但事实上自信地假装理解它。

我们生活在这样一个时代,由于不断增长的业务需求,以及为了快速认识到对“外行人”来说似乎无关紧要的复杂命题的物理和现实意义,我们离不开深入的哲学和基本原理的抽象。这往往导致专业人士走捷径,滥用美丽的概念,当然是为了满足一时的需求,从而污染了整个空间。

在经典编程中,面向对象的编程规则程序员经常争论继承的滥用,仅仅是为了重用的需要,而简单的组合可能是有意义的。由于过度简化的书籍和课程,几乎任何工程师都可以在几个小时内成为 OOPS 程序员,我们有足够的资源来满足我们的业务需求,但潜在的多态性利斯科夫原则却被忽略了。结果是:我们与丑陋、庞大、混乱的遗留系统作斗争,这些系统不符合任何已知的设计模式,并且与预期的架构相去甚远。我们可以看到嵌入式行业花费数百万美元来打破这个僵局。那时我们正忙于构建库,这些库几乎可以做任何事情,从父类继承任何东西。

快进到数据科学时代,我们可以在基于数字的数据革命中感受到类似的需求。随着炒作周期预测新的术语将统治行业,我们看到工程师们在争先恐后地重新掌握技能和适应新的世界。我们有闻所未闻的首字母缩写词,充满幻想,有时甚至令人恐惧的名字,如人工智能、大数据、IoE、DNN 等等。我们经常看到它们中的一些出现在这样或那样的炒作曲线中,其中一些甚至被认为是非常成功的公司的秘方,如谷歌、亚马逊等。

除此之外,我们还有企业家头脑,他们用几本书和面向再技能社区的 MOOCs 充斥着这个领域。他们中很少有人讨论这个主题的具体内容;数学和现实世界的灵感,甚至是导致谷歌和亚马逊的案例研究。他们中的大多数都是简化的有风险的抽象对象;一家主要出版商将其书名命名为《傻瓜书》。

传统编程世界需要库,而敏捷世界需要 API 驱动的平台和 SDK,我们经常发现供应商在推进他们的平台。我们经常看到客户将这些平台称为美化的数据库。嗯,这可能被视为两个错误定位活动的结果:

1.潜在哲学的过分简单化

2.由于误读和不必要的假设,导致客户需求复杂化。

这两者都是我们渴望和贪婪抽象的结果,甚至在我们具体了解数据和转换数据的数学基础之前。

我们非常热衷于利用数据密集型库,甚至在理解这些庞大代码机器的构建模块之前。例如,现在在学习架构中使用 Tensorflow 或 CNTK 模块是一种常见的规范,但根据谷歌大脑项目负责人杰夫·迪恩(Jeff Dean)的说法,深度学习计划需要至少 10 万个例子才能取得可行的成果。我不确定我们中有多少人会幸运并被拯救,足以在一个框架上用如此多的例子开始我们的数据科学计划,甚至在我们制定和了解来到我们面前的数据的性质、种类和特征之前。

随着许多远见卓识者和插图画家试图制定数据驱动智能的黑盒图,一些人将数据表示为石油,一些人将数据模型表示为数据贪婪引擎,还有许多人将人工智能大脑表示为规则挖掘者,将我们的定位与谷歌的定位进行比较是值得的。

与谷歌和其他公司的一个主要区别是,谷歌对数据非常感兴趣。不是任何数据,而是正确的数据。谷歌前数据科学家 Seth Stephens 在他的书《人人都在撒谎》中说:“大数据革命不是收集越来越多的数据。这是关于收集正确的数据。”

有趣的是,自我学习、推荐以及情感和感觉提取的主动性并不是从输入自动数据馈送器的大量密集数据中产生的,而是通过工程师不眠不休地思考微小的样本和数据子集来寻找模式,以解决现有的模式。正如 Seth Stephens 在他的书中提到的,谷歌的重大决策总是来自随机抽样的数据子集,这些数据子集是人工思考和查看的。对我们工程师来说,这似乎是一件可怕而肮脏的工作,这是关于数据的唯一科学的东西。

世界上最令人钦佩的数据科学家之一是 DJ Patil,我想引用他在一次演讲中说过的话,即不要在我们周围的数据科学材料和爱好者中迷失或迷失,这真的很重要。我们应该意识到,我们正在创造我们自己的世界,因此,这应该是完美的。

几年前,在与博世汽车多媒体团队合作时,我是语音车载信息娱乐系统团队的一员。一年后,我可以驾驶安装了它们的汽车。

随着物联网和其他辅助技术和可信软件进入行业领域,我们将更接近成为我们手工制作的产品的受益者。我们总是可以安慰自己,把平庸和缺乏工艺归咎于供应商,因为面对自己工艺的机会非常小。我们永远不希望我们面前有一个不完美的世界,更不希望我们知道是谁设计和制造了这样一个世界。

让我们做一张地图吧!利用 Geopandas、pandas 和 Matplotlib 制作 Choropleth 地图

原文:https://towardsdatascience.com/lets-make-a-map-using-geopandas-pandas-and-matplotlib-to-make-a-chloropleth-map-dddc31c1983d?source=collection_archive---------0-----------------------

所以你想用 Python 做地图。我们开始吧!

如果你已经开始用 Matplotlib 和 Pandas 做一些数据可视化,但是正在寻找地理数据入门的下一个简单步骤,我有你。我去过那里。事实上,我花了几个小时浏览在线教程,寻找最简单的软件包来开始制作地图(特别是 choropleths)。虽然有很多选择,但我最终选择了地质公园作为门槛最低的地方。

Geopandas 很棒,因为它就像熊猫一样(但使用的是形状文件之类的地理数据)。Geopandas 数据帧与 pandas 数据帧非常相似,因此两者通常配合得很好。最重要的是,Geopandas 允许您创建快速、独立的 choropleth 地图,而没有许多其他依赖项(也没有太多代码行!).

这是我们将要制作的预览。

It’s London! Made with Python.

顺便说一句,有很多制作地图的好方法(值得注意的是, Datawrapper 刚刚添加了一个 GeoJson 包装器来加载你自己的定制地图)。没有放之四海而皆准的方法。然而,大多数这些服务都有某种限制(比如不能下载 svg 格式的文件。此外,用 Python 制作地图有几个独特的好处:

  • 再现性——Python 的一大卖点,尤其是制作超级快速图表。本教程将尽可能简化创建地图的过程(使用全局变量、清理等),以便下次您想要创建地图时,您只需更改 csv 文件(假设它是相同的地理位置)。
  • 最大控制 —定制,下载任何你想要的格式,你打电话。尽管可能需要修改一些代码,但 Matplotlib 非常强大。
  • 很多很多的地图 —如果你需要可视化同一个有很多变量的地图(多个小地图?)或显示随时间变化的地图,将这些代码包装在 for 循环中是一个明智的做法(我将在下一篇文章中介绍)。带有 GUI 界面的图表生成器很棒,但通常不擅长自动化任务。Python 很好。
  • 不需要设计技能——嗯,几乎不需要设计技能。好的数据设计的眼光是有帮助的。但不需要 Adobe Illustrator 或 Photoshop 技能。

好,我们开始吧。这是你需要的。我用一个 Jupyter 笔记本来存放所有的代码(我强烈推荐,这样你就可以预览渲染),但是你可以。

  • 熊猫
  • 地质公园
  • Matplotlib

就是这样!

获取数据

让我们把一些数据记在笔记本上。由于我目前住在伦敦,我将按地方选区(自治区级)制作伦敦地图。伦敦数据存储在使大量数据公开和可访问方面做得很好,我发现这个页面有一堆不同详细程度的形状文件。不错!

点击→下载→另存为→移动到笔记本本地目录。搞定了。

但是 shapefile 只是一层数据。这将有助于绘制地图,但如果我们想将数据绑定到它,我们还需要另一个数据集。回到伦敦数据存储:让我们下载伦敦自治市档案数据集作为 csv 文件(已经预先清理干净)。这个 csv 文件有很多列,我们可以用它们作为变量来可视化。

现在两个数据集都准备好了,我又回到了我的 Jupyter 笔记本上。是时候载入了。shp 和。csv 文件。

# set the filepath and load in a shapefilefp = “datasets/geo-data/gis-boundaries-london/ESRI/London_Borough_Excluding_MHW.shp”map_df = gpd.read_file(fp)# check data type so we can see that this is not a normal dataframe, but a GEOdataframemap_df.head()

现在让我们预览一下没有数据的地图是什么样子。

map_df.plot()

酷,是伦敦!

然后,我们加载一个 csv 数据文件来连接地理数据框架。

df = pd.read_csv(“datasets/london-borough-profile.csv”, header=0)df.head()

清洗和连接数据框

太好了。现在我们有两个数据帧准备好了。让我们获取一份我们将要使用的数据。

df = df[[‘borough’,’Happiness_score_2011–14_(out_of_10)’, ‘Anxiety_score_2011–14_(out_of_10)’, ‘Population_density_(per_hectare)_2017’, ‘Mortality_rate_from_causes_considered_preventable_2012/14’]]

这些列名真的很糟糕。让我们将它们重命名为更简单的名称。

data_for_map = df.rename(index=str, columns={“Happiness_score_2011–14_(out_of_10)”: “happiness”,“Anxiety_score_2011–14_(out_of_10)”: “anxiety”,“Population_density_(per_hectare)_2017”: “pop_density_per_hectare”,“Mortality_rate_from_causes_considered_preventable_2012/14”: ‘mortality’})# check dat dataframedata_for_map.head()

好多了。现在,我们需要将地理数据与清理后的伦敦数据集合并。我们将使用 pd.join()来实现这一点。

# join the geodataframe with the cleaned up csv dataframemerged = map_df.set_index(‘NAME’).join(data_for_map.set_index(‘borough’))merged.head()

地图时间!

开始贴图吧。首先我们需要为 Matplotlib 做一些准备工作。我们首先将一个变量设置为 map,设置范围并为要绘制的地图创建图形。

# set a variable that will call whatever column we want to visualise on the mapvariable = ‘pop_density_per_hectare’# set the range for the choroplethvmin, vmax = 120, 220# create figure and axes for Matplotlibfig, ax = plt.subplots(1, figsize=(10, 6))

舞台已经搭好了。地图时间。

# create mapmerged.plot(column=variable, cmap=’Blues’, linewidth=0.8, ax=ax, edgecolor=’0.8')

就在那里!不完美。有点扭曲,有一个奇怪的轴围绕着整个东西,这并不意味着什么。但是我们有一个 choropleth。现在让我们做一些美化,让它看起来新鲜。

定制地图

首先,那个轴心需要被移除。

# remove the axisax.axis(‘off’)

然后,让我们添加一个标题到我们的地图,和一些说明来源的文字。地图通常看起来很好,但是如果你不提供背景信息,它就没有多大意义。

# add a titleax.set_title(‘Preventable death rate in London’, fontdict={‘fontsize’: ‘25’, ‘fontweight’ : ‘3’})# create an annotation for the data sourceax.annotate(‘Source: London Datastore, 2014’,xy=(0.1, .08),  xycoords=’figure fraction’, horizontalalignment=’left’, verticalalignment=’top’, fontsize=12, color=’#555555')

漂亮!但是还缺少一样东西。我们可能应该添加一个图例,为用户显示值的范围。这将有助于它看起来不那么压扁。

# Create colorbar as a legendsm = plt.cm.ScalarMappable(cmap=’Blues’, norm=plt.Normalize(vmin=vmin, vmax=vmax))# empty array for the data rangesm._A = []# add the colorbar to the figurecbar = fig.colorbar(sm)

地图。制造。

最后一件事:我们需要保存地图,这样我们就可以发布一条带有#dataviz 标签的 tweet。

Matplotlib 在如何保存数据方面给了你很多自由。下面的代码将图片保存为 png 格式,但是如果你想在 Illustrator 中对它进行更多的修改,你也可以保存为 svg 格式。如果保存为 png,请确保使用 200 或更高的 dpi。否则地图和文字看起来会很模糊。没人想这样。

fig.savefig(“map_export.png”, dpi=300)

现在,我们的工作目录中已经有了一份可以发布的地图!太神奇了。

原来如此。您已经设置好了 Geopandas(至少对于 choropleths 是这样)。接下来,我将看看如何使用 Geopandas 制作多个地图,并将其转换成一个很酷的 gif 地图。敬请期待!

你可以在 Github 上查看并下载我的 Jupyter 笔记本。

让我们再次让聊天机器人变得伟大

原文:https://towardsdatascience.com/lets-make-chatbots-great-again-a30f5221a678?source=collection_archive---------6-----------------------

Photo by Mohamed Nohassi on Unsplash

聊天机器人曾经很棒。首先,在 1964 年,我们有了著名的聊天机器人伊莱扎,它让人们相信它真的是一名治疗师。然后,在 1968 年我们有了 SHRDLU 。如果你没有听说过,SHRDLU 是一个虚拟“积木世界”的对话界面:

SHRDLU’s blocks world (source)

以下是与 SHRDLU 的对话示例:

人:请你把两个红色方块和一个绿色立方体或一个金字塔叠起来好吗?

电脑:好的。

人:哪个立方体在桌子上?

电脑:支撑红色金字塔的绿色大电脑。

人:金字塔后面有大块吗?

电脑:是的,三个:一个大的红色的,一个大的绿色的立方体,还有蓝色的。

人:把一个小的放在支撑金字塔的绿色立方体上。

电脑:好的。

人:把最小的金字塔放在上面。

电脑:好的。

人:最高的金字塔的最矮的东西支撑着绿色的东西吗?

电脑:是的,绿色金字塔。

令人印象深刻。但那是过去的事了。

现在我们有了意向——有几个可以填充的槽的扁平结构。现代系统不太可能理解用户在上述对话中的最后一个查询。

哪里出了问题?

Photo by Toa Heftiba on Unsplash

这些“优秀的老式人工智能”系统在许多方面都令人惊叹,但它们也有缺陷。

他们需要大量的努力和工程才能做好。这不是将一堆训练数据粘贴到机器学习算法中并转动曲柄的情况——解释用户查询的自然语言语法是手工精心构建的。

统计技术没有被广泛使用,这意味着系统本质上是脆弱的。查询必须具有完全正确的形式,否则聊天机器人将无法理解。

他们也被限制在一个小范围内。一个可以移动街区的聊天机器人对大多数人来说是没用的。随着复杂性的迅速升级,推广 SHRDLU 这样的系统的努力失败了。

恢复平衡

Photo by Jonathan Pendleton on Unsplash

快进到 2018 年,我们已经走到了另一个极端。我们的系统非常强大。我们的解析器使用机器学习,并接受真实数据的训练。但是我们的聊天机器人太没有野心了,和 SHRDLU 比起来就相形见绌了。

他们并没有减少约束。我们现在应该能造出比 SHRDLU 更好的东西了吧?这是怎么回事?

我们已经忘记了我们的历史。我们缺乏想象力。我们忽略了学术界已经开发的技术。

走向综合

Photo by Mika Ruusunen on Unsplash

SHRDLU 很脆弱,但是可以处理复杂的查询。现代系统更加强大但简单。我们如何将这些结合起来,以建立比两者都更好的东西?

SHDRLU 由三个主要组件组成:

  1. 一个积木世界的模拟,允许 SHRDLU 知道每一个可能的动作会发生什么。
  2. 一个语法,它将用户查询翻译成 SHRDLU 可以解释的形式
  3. 一个计划器,帮助它探索可能的动作,以找到满足用户请求的序列。

第二和第三个组件对应于自 SHRDLU 开发以来的几年中受到大量关注的两项人工智能技术:

  • 语义解析器是将自然语言表达翻译成计算机理解的形式的工具。在过去五年左右的时间里,该领域重新引起了人们的兴趣,并且随着现代机器学习和新技术的应用,最先进的精确度得到了显著提高。
  • 自动规划是自 SHRDLU 时代以来一直在稳步发展的人工智能领域。自动化规划器已被用于美国国家航空航天局的机器人,玩电脑游戏,最著名的是,在围棋上击败人类。现代搜索技术和机器学习在这个问题上的应用彻底改变了这个领域。

第一个组成部分,世界模拟,是针对我们试图解决的问题的。有规划语言被设计用来描述世界。这些以自动化规划者理解的格式描述世界。

我们需要更好的工具

Photo by Matt Artz on Unsplash

最终,是聊天机器人创建工具让我们失望了。

我们需要工具来拓展聊天机器人的潜能。

如果我们构建一个利用这些最新进展的 SHRDLU 更新版本,会发生什么?没人知道,因为没人试过。

我想我们可以建造一些令人惊奇的东西。

请某人建造这个。否则我就得自己动手了。

让我们读一个故事:一项关于使用机器学习工具为儿童讲故事的研究

原文:https://towardsdatascience.com/lets-read-a-story-a-study-on-storytelling-for-children-using-machine-learning-tools-1b631bbbffac?source=collection_archive---------14-----------------------

让我们读一个故事是一项关于伊索寓言的研究,以及使用最近可用的机器学习工具以一种新的有趣的方式探索原始寓言中不同人物和思想之间的联系的可能性。

Let’s Read A Story — Using Sketch RNN as a homage to endpapers in bookbinding tradition

你可以在这里找到一个工作演示(chrome 桌面上的最佳性能)。

Let’s Read A Story

在下面的帖子中,我将尝试描述这个项目背后的思维过程和一些技术方面。

📜

收集资料。

在这个项目中,我选择关注和分析伊索寓言,在它们不同的句子之间产生新的有趣的邻接,从而创造新的故事。我被《伊索寓言》所吸引,因为它们简洁而丰富的故事情节,使用动物作为隐喻,以及每个故事中蕴含的强烈道德。

Aesop Fables for kids, project gutenberg

每个原始伊索寓言包含:

  1. 一个简短的标题,通常非常描述故事的内容和人物。
  2. 故事本身,通常不超过 30 句。
  3. 这个故事的寓意,通常包含一个隐喻,建立在故事中动物固有的本性或特质上。

清理数据集

为了对内容进行分析,我编译了一个 JSON 文件,其中保存了所有分解成单独句子的故事、它们的标题、角色和动物。

这个文件是生成实验新故事的关键,因为它保存了所有的句子,并作为实验的“数据库”。

此外,对于每个新生成的故事(新生成的故事从该故事发展而来),该文件充当从获取种子句子的源。

⚙️

分析句子

使用谷歌的通用句子编码器,一种将文本编码成高维向量的机器学习模型,可用于文本分类、语义相似性、聚类和其他自然语言任务,我分析了所有来自寓言的句子(约 1500 个句子)。

这产生了一个 JSON 文件,其中包含了 512 维空间中每个句子的句子嵌入,这是我用来比较和生成新邻接的相似性图。

文件中的示例行:

{“message”: “There was once a little Kid whose growing horns made him think he was a grown-up Billy Goat and able to take care of himself.”, “message_embedding”: [0.06475523114204407, -0.026618603616952896, -0.05429006740450859, 0.003563014790415764 ………..,0.06475523194004407]}

为了处理和检索句子之间的相似性、平均值和距离的信息,我使用了ML5word 2 vec 类和稍微修改了一下来使用通用句子编码器方案。

💡

第一次结果

从生成 10 个句子开始,第一个结果非常令人惊讶,有意义并且非常令人信服(对于一台机器来说)🤖),虽然对我来说有点阴暗:

First test in generating output text from the universal sentence encoder (10 lines from a random seed)

他们哭了。

他哭了。

哦,这是什么?他们哭了。

他们没有伤害我。

他们认为这是他们的盛宴。

现在轮到驴子坦白了。

又烦又失望的他哭了起来。

他独自一人。

一个路人听到了他的哭声,问发生了什么事。

这就是这只可怜的老鼠得到的全部同情。

另一次尝试产生了不同的结果,非常严峻,但仍然有趣:

Second test in generating output text from the universal sentence encoder (10 lines from a random seed)

不管他怎么努力,他都不能离开家。

他们说,他再也骗不了我们了。

这孩子知道他没什么希望了。

但他能做的最好的事就是把头伸出来。

我的儿子们,他说,注意我要对你们说的话。

他一时忘记了自己身在何处。

不不。爸爸正在看着,如果他靠近,爸爸会杀了他!

请让我走,他恳求道。

只要一点点就能击垮我,他说,你知道我有多脆弱。

他独自一人。

💻

构建网络应用

对于这个项目的第一个版本,我认为它最好能在网络浏览器上运行,这样几乎每个人都可以访问它。我选择在 Node 上构建第一个版本。JS 用于服务器端(相似性计算、情感分析和提供内容),javascript 用于前端功能(其他所有功能)。

🎨 +🎵

给故事添加插图&音乐短语

为了丰富故事,我选择使用 Google Magenta 的草图-RNN 模型:一个矢量绘图的生成模型来从预先训练的模型中重建插图,以伴随生成的故事。

快速抽奖数据集是由游戏的玩家贡献的跨越 345 个类别的 5000 万个抽奖的集合。。这些画被捕捉为带有时间戳的向量,并标有元数据,包括玩家被要求画的内容以及玩家所在的国家。

谷歌品红的聪明人训练了一个公开可用的递归神经网络模型,名为 sketch-rnn 。他们通过在从 Quick,draw 收集的数百万幅涂鸦上训练它,教会了这个神经网络画画!游戏。虽然我只是用它来简单地重建故事中的动物和其他一般插图,但这个庞大的数据集和网络还有许多其他创造性的应用。

对于 让我们读一个故事 ,我选择使用这个模型,同时对结果句子执行简单的正则表达式搜索。javascript 功能确定哪种动物出现在生成的故事中,然后使用 P5 从训练好的草图 RNN 模型重建插图。JS 。如果句子包含模型中不存在的动物,则有另一个函数“丰富”模型的关键字,并匹配句子中指定的相似动物。

这些插图然后变成基于一些预先确定的‘音乐’规则的音乐短语:

Lion Illustration and Sound

Lion Illustration and sound

当然,这种方法并不旨在可靠地再现故事,也有音乐声音和故事不匹配的情况,但它给了故事一定的触动,并以某种迷人的方式丰富了人物和插图。在未来的版本中,我打算改进这种方法,并加入真实的音乐数据或某种模型,这种模型可以更好地传达情感,以更合适的方式伴随故事的信息或主要人物。

🔮

走进未来

这是一个正在进行的项目,我打算在接下来的几个月里进行,希望它能成为我在 NYU ITP 的论文项目。我打算开发更多的工具,在这些和其他机器学习算法的帮助下,帮助构建更强有力的叙事。在其他平台上进行测试和部署会产生不同的结果,侧重于讲故事实践的不同方面——印刷书籍,以及智能设备、扬声器、平板电脑和其他沉浸式媒体平台。

我想探索的一个关键方面是将它变成一个部署在带屏幕的智能设备中的对话应用程序,因为我认为利用自然语言理解将大大有助于体验,并减少孩子们的屏幕时间。

有些问题没有得到解答:

  • 通过用新生成的故事分析原始故事来检索故事的新生成的寓意。
  • 根据课文中不同的种子句子重写一个故事。
  • 如果一个电脑故事由一个合成的声音来朗读会是什么感觉。
  • 深入挖掘叙事结构,构建更强大、更可靠的故事。
  • 生成多角色插图和动画。
  • 增强音乐主题。
  • 打破常规的动物原型,延伸人物的极限。

【Github 库:https://github.com/itayniv/aesop-fables-stories

这个项目是作为 2018 年秋季在 ITP NYU 举办的 丹尼尔·希夫曼的编程 A2Z 吉恩·科岗的神经美学 课程的一部分完成的。

让我们谈谈 NumPy——针对数据科学初学者

原文:https://towardsdatascience.com/lets-talk-about-numpy-for-datascience-beginners-b8088722309f?source=collection_archive---------3-----------------------

Numpy For Beginners

NumPy (数值 Python)是 Python 中的线性代数库。它是一个非常重要的库,几乎每个数据科学或机器学习 Python 包,如 SciPy(科学 Python)、Mat plot lib(绘图库)、Scikit-learn 等都在一定程度上依赖于它。

NumPy 对于在数组上执行数学和逻辑运算非常有用。它为 Python 中的 n 数组和矩阵操作提供了大量有用的特性。

本课程涵盖了作为数据科学初学者需要了解的关于 NumPy 的基础知识。其中包括如何创建 NumPy 数组、使用广播、访问值和操作数组。更重要的是,您将了解 NumPy 优于 Python 列表的优点,包括:更紧凑、读写条目更快、更方便、更高效。

在本课程中,我们将使用 Jupyter 笔记本作为我们的编辑器。

我们走吧!

安装 NumPy

如果您有 Anaconda ,您可以简单地从您的终端或命令提示符安装 NumPy,使用:

conda install numpy

如果您的计算机上没有 Anaconda,请使用以下命令从终端安装 NumPy:

pip install numpy

一旦你安装了 NumPy,启动你的 Jupyter 笔记本并开始使用。让我们从 NumPy 数组开始

NumPy 数组

NumPy 数组只是一个包含相同类型值的网格。NumPy 数组有两种形式:向量和矩阵。向量是严格的一维(1-d)数组,而矩阵是多维的。在某些情况下,矩阵仍然只能有一行或一列。

让我们从在您的 Jupyter 笔记本中导入 NumPy 开始。

import numpy as np

从 python 列表创建 numpy 数组

假设我们有一个 Python 列表:

my_list = [1, 2, 3, 4, 5]

我们可以简单地创建一个名为 my_numpy_list 的 NumPy 数组,并显示结果:

my_numpy_list = np.array(my_list)
my_numpy_list  *#This line show the result of the array generated*

我们刚刚做的是将 python 列表转换成一维数组。为了得到一个二维数组,我们必须转换一个列表,如下所示。

second_list = [[1,2,3], [5,4,1], [3,6,7]]new_2d_arr = np.array(second_list)
new_2d_arr  *#This line show the result of the array generated*

我们已经成功地创建了一个有 3 行 3 列的二维数组。

使用 arange()内置函数创建 NumPy 数组。

类似于 python 内置的 range()函数,我们将使用 arange()创建一个 NumPy 数组。

my_list = np.arange(10)*#OR*my_list = np.arange(0,10)

这将生成从索引 0 到 10 的 10 位数的值。

需要注意的是,arange()函数也可以接受 3 个参数。第三个参数表示操作的步长。例如,要获得从 0 到 10 的所有偶数,只需添加如下所示的步长 2。

my_list = np.arange(0,11,2)

我们也可以生成一个由七个零组成的一维数组。

my_zeros = np.zeros(7)

我们也可以生成一个由五个一组成的一维数组。

my_ones = np.ones(5)

类似地,我们可以生成具有 3 行 5 列的二维零数组

two_d = np.zeros((3,5))

使用 linspace()内置函数创建 NumPy 数组。

函数的作用是:返回指定区间内均匀分布的数字。假设我们想要从 1 到 3 的 15 个均匀间隔的点,我们可以很容易地使用:

lin_arr = np.linspace(1, 3, 15)

这给了我们一个一维向量。

不像 arange()函数将第三个参数作为步数,linspace()将第三个参数作为要创建的数据点的数量。

在 NumPy 中创建一个单位矩阵

处理线性代数时,单位矩阵非常有用。通常,是一个二维方阵。这意味着行数等于列数。关于单位矩阵要注意的一个独特的事情是对角线是 1,其他的都是 0。单位矩阵通常只有一个参数。下面是如何创建一个。

my_matrx = np.eye(6)    *#6 is the number of columns/rows you want*

在 NumPy 中生成一个随机数数组

我们可以使用 rand()、randn()或 randint()函数生成一个随机数数组。

  • 使用 random.rand(),我们可以生成一个形状的随机数数组,从 0 到 1 的均匀分布传递给它。

例如,假设我们想要一个从 0 到 1 均匀分布的 4 个对象的一维数组,我们可以这样做:

my_rand = np.random.rand(4)

如果我们想要一个 5 行 4 列的二维数组:

my_rand = np.random.rand(5, 4)
my_rand
  • 使用 randn(),我们可以从以 0 为中心的标准、正态或高斯分布中生成随机样本。例如,让我们生成 7 个随机数:
my_randn = np.random.randn(7)
my_randn

当你绘图时,结果会给我们一个正态分布曲线。

类似地,要生成 3 行 5 列的二维数组,请执行以下操作:

np.random.randn(3,5)
  • 最后,我们可以使用 randint()函数生成一个整数数组。randint()函数最多可以接受 3 个参数;数组的下限(包括)、上限(不包括)和大小。
np.random.randint(20) *#generates a random integer exclusive of 20*np.random.randint(2, 20) *#generates a random integer including 2 but excluding 20*np.random.randint(2, 20, 7) *#generates 7 random integers including 2 but excluding 20*

将一维数组转换成二维

首先,我们生成一个由 25 个随机整数组成的一维数组

arr = np.random.rand(25)

然后使用 shape()函数将其转换为二维数组

arr.reshape(5,5)

注意:reshape()只能转换成相等数量的行和列,并且必须等于等于元素的数量。在上面的例子中, arr 包含 25 个元素,因此只能调整为 5X5 矩阵。

定位 NumPy 数组的最大值和最小值

使用 max()和 min(),我们可以获得数组中的最大值或最小值。

arr_2 = np.random.randint(0, 20, 10) arr_2.max() *#This gives the highest value in the array* arr_2.min() *#This gives the lowest value in the array*

使用 argmax()和 argmin()函数,我们可以定位数组中最大值或最小值的索引。

arr_2.argmax() #This shows the index of the highest value in the array 
arr_2.argmin() #This shows the index of the lowest value in the array

假设你有一个很大的数组,你想知道这个数组的形状,你想知道它是一维的还是二维的,只需使用 shape 函数。

arr.shape

从 NumPy 数组中索引/选择元素或元素组

索引 NumPy 数组与 Python 类似。你只需传入你想要的索引。

my_array = np.arange(0,11)my_array[8]  *#This gives us the value of element at index 8*

为了获得数组中的一系列值,我们将使用切片符号' : ' ,就像在 Python 中一样

my_array[2:6] *#This returns everything from index 2 to 6(exclusive)*my_array[:6] *#This returns everything from index 0 to 6(exclusive)*my_array[5:] *#This returns everything from index 5 to the end of the array.*

类似地,我们可以使用双括号[][]符号或单括号[,]符号来选择二维数组中的元素。

使用双括号符号,我们将从下面的二维数组中获取值' 60 ':

two_d_arr = np.array([[10,20,30], [40,50,60], [70,80,90]])two_d_arr[1][2] *#The value 60 appears is in row index 1, and column index 2*

使用单括号符号,我们将从上面的数组中获取值' 20 ':

two_d_arr[0,1] 

我们还可以进一步使用切片符号来获取二维数组的子部分。让我们在数组的一些角落里抓取一些元素:

two_d_arr[:1, :2]           *# This returns [[10, 20]]*two_d_arr[:2, 1:]           *# This returns ([[20, 30], [50, 60]])*two_d_arr[:2, :2]           *#This returns ([[10, 20], [40, 50]])*

我们也可以索引整个行或列。要获取任何行,只需使用它的索引号,如下所示:

two_d_arr[0]    *#This grabs row 0 of the array* ([10, 20, 30])two_d_arr[:2] *#This grabs everything before row 2* ([[10, 20, 30], [40, 50, 60]])

我们还可以使用 & (AND)、 | (OR)、<、>和==运算符对数组执行条件和逻辑选择,以将数组中的值与给定值进行比较。方法如下:

new_arr = np.arange(5,15)new_arr > 10 *#This returns TRUE where the elements are greater than 10 [False, False, False, False, False, False,  True,  True,  True, True]*

现在我们可以打印出在上述条件中为真的实际元素,使用:

bool_arr = new_arr > 10new_arr[bool_arr]  *#This returns elements greater than 10 [11, 12, 13, 14]*new_arr[new_arr>10] *#A shorter way to do what we have just done*

使用条件逻辑运算符 & (AND)的组合,我们可以得到大于 6 但小于 10 的元素。

new_arr[(new_arr>6) & (new_arr<10)]

我们的预期结果是:([7,8,9])

广播

广播是更改 NumPy 数组值的快速方法。

my_array[0:3] = 50*#Result is:* **[50, 50, 50, 3, 4,  5,  6,  7,  8,  9, 10]**

在本例中,我们将索引 0 到 3 中元素的值从初始值更改为 50。

对 NumPy 数组进行算术运算

arr = np.arange(1,11)arr * arr              *#Multiplies each element by itself* arr - arr              *#Subtracts each element from itself*arr + arr              *#Adds each element to itself*arr / arr              *#Divides each element by itself*

我们也可以在数组上执行标量操作。NumPy 通过广播使之成为可能。

arr + 50              *#This adds 50 to every element in that array*

Numpy 还允许你在数组上执行诸如平方根、指数、三角函数等通用函数。

np.sqrt(arr)     *#Returns the square root of each element* np.exp(arr)     *#Returns the exponentials of each element*np.sin(arr)     *#Returns the sin of each element*np.cos(arr)     *#Returns the cosine of each element*np.log(arr)     *#Returns the logarithm of each element*np.sum(arr)     *#Returns the sum total of elements in the array*np.std(arr)     *#Returns the standard deviation of in the array*

我们还可以获取二维数组中列或行的总和:

mat = np.arange(1,26).reshape(5,5)mat.sum()         *#Returns the sum of all the values in mat*mat.sum(axis=0)   *#Returns the sum of all the columns in mat*mat.sum(axis=1)   *#Returns the sum of all the rows in mat*

恭喜你,我们已经到了 NumPy 教程的最后了!

如果你学完了这一课,那么你已经学了很多。坚持练习,这样你新发现的知识就会保持新鲜。

有问题,遇到困难或者只是想打个招呼?请使用评论框。如果这个教程在某些方面对你有帮助,给我看一些👏。

是时候谈谈数据使用中的组织偏见了

原文:https://towardsdatascience.com/lets-talk-about-organizational-bias-in-data-use-92ba83bb2c59?source=collection_archive---------5-----------------------

数据使用中的组织偏见长期以来一直不为人所知。然而,它对企业及其底线的影响可能是破坏性的。本文旨在开始关于组织偏见的讨论,包括它是什么以及为什么您需要保持警惕以限制它对业务的影响。

数据使用总是容易受到偏见的影响。永远不可能完全客观。这是因为数据生命周期的所有阶段从收集到分析再到决策都涉及到人类。我们设计如何收集数据。我们决定数据的存储方式以及如何对行动进行分类或量化。我们进行分析或解释数据信号。

人类既是数据的创造者,也是数据的使用者,这一事实意味着偏见有可能蔓延到数据的生命周期中。出于这个原因,我们需要敏锐地意识到所有类型的偏见,以及它如何影响决策中的数据使用。

数据使用中有两大类偏差:

  1. 个体偏见
  2. 组织偏见

本文主要关注组织偏见。

组织偏见与个人偏见

2011 年至 2014 年间,我进行了博士研究,研究商业领袖如何在决策过程中使用数据。具体来说,我研究了影响领导者选择和使用数据方式的因素。

我发现对客观数据使用的最大影响和最大威胁是组织偏见,而不是个人偏见。

可以说,个人偏见更广为人知,讨论也更广泛。个人偏见也更加明确和容易识别。它包括个人或一小群人的偏见和成见。

个人偏见可以简单到在图表上选择颜色,强调一个数据的洞察力而不是另一个来支持一个先入为主的论点。或者可能更微妙,例如研究人员选择熟悉的城市进行研究,而没有充分考虑他们研究设计中的所有领域。你可能听说过两种更常讨论的个体偏差,包括确认偏差和选择偏差。

另一方面,组织偏见是一个在行业文章和出版物中不太突出的话题。然而,它的影响可能特别具有破坏性,因为它通常比个人偏见的影响范围更广。

当文化、高层领导、战略重点和团队组织等因素对数据选择和数据使用的影响达到不再以价值为基础的程度时,就会出现组织偏差。

组织偏见可能比个人偏见更难识别和隔离。这是因为组织偏见嵌入到每一件事情中,从使用的语言,提出的项目的选择,并影响整个企业的工作方式。组织偏见的普遍性质以及它在如此多的核心业务职能中被发现的事实意味着它比个人偏见更有可能被转化、系统化和影响更广。所有这些,提供了潜在的组织偏见,如果不诊断的话,将是特别具有破坏性的。

组织偏差的来源

每个组织都是独特的,因此组织偏见的来源可能来自许多不同的因素和许多因素的组合。

来源因素可能包括内部政治、文化、领导力、企业的行业部门、组织的历史、产品和团队设置等。每个企业都需要监控组织偏见。

以下是我在研究中发现的一些组织偏见的来源:

  1. 高层领导明确和含蓄地告诉他们的团队,一个数据源比另一个“更准确”(相对于根据他们的优点选择数据源)
  2. 团队的构建方式使他们能够更多/更快地访问一个数据源,而不是另一个数据源(而不是平等地访问整体见解和学习)
  3. 基于一个特定数据洞察或数据源的强制策略(相对于由跨部门整体洞察驱动的策略)
  4. 由于糟糕的数据洞察管理、低效的数据共享实践和对学习中心的少量投资(相对于成熟的共享和组织学习发展)而产生的数据孤岛
  5. 热情地采用新的度量技术,并将这些技术强制应用到项目中(相对于根据优点选择正确的度量工具)

限制组织偏见的技巧

限制组织偏见是制定客观数据驱动的决策的关键。

这里有四个系统可以帮助限制组织偏见,并确保高层领导根据最全面的可用数据做出决策。

  1. 使用决策框架。决策框架是在决策过程中培训和支持企业领导者的指导方针。决策框架的作用是鼓励领导者去除情绪。有许多类型的决策框架可以使用。在我的研究中,我设计了一个专门鼓励数据驱动决策的框架。它被称为 ICSAR 框架。阅读更多关于该模式如何帮助您做出更好的商业决策的信息。ICSAR 框架是一个可以使用的模型,但是还有其他的可以选择。
  2. 提供对数据洞察力的民主访问。更成熟的数据驱动型组织和不太成熟的组织之间的一个关键区别通常在于数据的共享方式。不太成熟的组织控制和限制信息流。出于安全、权力、影响力和所有权等原因,数据由一小部分人控制。成熟的组织在共享数据见解和确保民主访问所有数据方面投入巨大,而不管团队如何。他们不太关注控制数据和花费精力,而不是使用信息的最佳方式。数据成熟度的一个试金石可以在会议中找到。在高层领导的会议中,大量时间花在讨论数据洞察力的准确性上,而较少讨论使用数据的最佳方式,这是数据使用实践不成熟的组织的明显标志。
  3. 结构良好的衡量、学习和发展机制。许多企业现在面临的最大数据挑战不是收集数据见解,而是实际管理和综合可供他们使用的海量见解。领先的组织正在投资和开发以图书馆管理藏书的方式管理洞察力的方法。他们正在发展所需的团队、专家和基础设施,以对知识进行分类,并规划未来的研究和分析,以填补知识缺口。不太先进的企业通常没有适当的结构来管理他们的见解和数据学习。这导致了知识孤岛、重复的分析、没有全面信息的决策和投资浪费。
  4. 偏倚的外部评估和监测。虽然有很多工作可以在内部完成以限制组织偏见,但企业也需要外部评估和监控。这是因为组织偏见往往是广泛而隐蔽的。它可能存在于组织中最高层领导的语言和偏见中,因此需要外部支持来帮助这些领导识别任何偏见。爱德华·戴明写道:“一个系统不能理解自己。这种转变需要外界的观点。”这也是事实,因为组织偏见是系统性的,企业需要一个客观的外部评估来帮助他们了解组织偏见可能在哪些方面影响他们的决策,并通过发展机会的建议来支持他们。

结论

2018 年,企业不仅有机会利用数据,而且有机会以更加智能的方式管理和高效地汇集可供他们使用的海量见解。

仅仅收集数据或拥有数据科学和洞察功能是不够的。我们已经放下了。数据的潜力已经得到了很好的证明。

企业在未来几年中脱颖而出并领先的关键方法是有效地综合和协调许多不同的学习,以制定有效的决策和独特的市场战略。如果企业不管理和考虑组织偏见,这些都不会发生。

管理组织偏见不会在一夜之间发生。它将需要在使用决策框架、数据共享民主化工具、构建持续发展跨业务学习的结构以及监控组织偏见的外部支持方面的投入。

然而,最终结果是更客观的、数据驱动的决策的组合。更全面地理解数据和见解。更有效地利用已经在数据基础架构中进行的投资。

提升经前综合症的人工智能水平

原文:https://towardsdatascience.com/leveling-up-ai-literacy-for-pms-dc293b79fe17?source=collection_archive---------16-----------------------

…以及我为什么要为产品经理讲授数据科学

AI isn’t magic.

如今,数据比以往任何时候都更加成为产品管理的核心。产品经理越来越多地负责运输机器学习驱动的产品功能,根据机器学习技术做出关键的产品决策,并与他们的数据科学同行建立强大的合作伙伴关系。

但当我问数据科学家和机器学习工程师他们的 PM 同行做得如何时,我听到的是:

“我的项目经理不知道该问什么问题。”

首相“无法将他们试图解决的问题框定为 ML 问题。”

“项目经理和高管对自己的理解过于自信,对可能/容易的事情过于自信。”

“不明白的事情就承认。不要假装你知道的比你知道的多。不要在未与工程师沟通的情况下对业务做出承诺。”

太多的组织正在雇佣数据科学家团队,而没有同时投资于其他人的数据和人工智能素养。因此,有太多的产品经理让数据科学家抓狂(反之亦然)。

以下是产品经理需要具备人工智能素养的原因:

❄️70 亿特殊雪花:你的用户需要它。️️❄️

秘密已经泄露——每个人都想感觉自己(等着瞧…)是一个个体。你、我和我们所有的用户都需要智能的、个性化的体验,让我们感觉自己就是特别的雪花。如果其他人都和我得到一样的东西,那有什么好兴奋的?

当用户通过注册帐户、参与应用程序并提供反馈来为公司提供数据时,他们希望产品随着时间的推移不断改进并变得更加智能。这些改进通常需要将用户参与产品本身所产生的数据产品化。

人工智能产品就在我们身边。Spotify 使用你的收听历史来创建个性化的播放列表,Gmail 使用以前的电子邮件内容来完成你的句子, Woebot 记住过去的对话,以便为你提供个人治疗会话, IntelligentX 的 AI 算法使用你对上一批啤酒的反馈来创建专为你的味蕾量身定制的食谱。是的,没错,你现在可以购买到艾酿造的啤酒。

即使这只是营销炒作,我们被所有这些令人兴奋的发展所包围的事实正是无休止地增加我们的期望和我们的“需求”(或想要)的事情。但是对于产品经理来说,这不仅仅是炒作——实现这些期望是你的工作。

🥣金发女郎项目经理:不要太专业,不要太夸张🥣

项目经理的工作包括设想什么样的未来产品是可能的,以及交付什么是有价值的。为了做到这一点,项目经理需要有恰到好处的数量的关于数据科学技术当前状态的知识。这种金发女孩级别的理解使项目经理能够弥合不同专业团队之间的差距——业务、技术和设计——而不会太沉迷于人工智能宣传,或太深入杂草中。

作为一个整体,项目管理规程已经精通传统的软件开发技术。这是一套全面的牌桌赌注。然而,当谈到数据科学技术时,大多数项目经理并不具备与他们在商业、工程和设计领域相同的技术理解水平,这是因为他们并不总是需要它。

直到现在。随着产品变得越来越“智能”,以满足每一个特殊的雪花用户的需求,越来越多的应用程序决策点将由预测模型取代,而不是由启发式和显式的 if-then-else 逻辑取代。

太多时候,项目经理会让他们的数据科学同行抓狂,要么是太深入技术领域(不太可能),要么是对炒作的应用程序过于热情(更有可能)。最佳时机介于两者之间。一个成功的项目经理需要了解数据建模、数据基础设施、机器学习模型和模型评估指标的基础知识。掌握了适量的知识,项目经理不仅可以发布让当前用户满意的产品,还可以提供未来可能创造的愿景。

🔮“ML 不是魔术”:产品经理需要了解 ML 开发流程,以便有效地与数据科学团队协作*。🔮

为了与他们的数据科学家和机器学习工程师同行建立更好的合作关系(和产品),项目经理需要了解开发过程中的主要差异,以及他或她在哪里可以发挥最有影响力的作用。

具体来说,项目管理系统在两个方面影响最大:模型输入和模型输出。“输出”是 ML 模型将生成的预测。至关重要的是,项目经理清楚地阐明该算法输出的商业价值,以及相关的约束条件——伟大的模型预测并不能保证成功的商业结果。“输入”是特征(也称为属性、独立变量、列等。)输入到模型中。垃圾进,垃圾出。与数据科学团队共享领域知识和上下文可以帮助团队发现更强的信号,从而产生更高质量、更易解释的输出。

至于剩下的——退一步,留给机器学习的黑匣子吧?没那么快。正如一位数据科学家所说,“项目经理需要知道 ML 不是魔术。”除了输入和输出之外,在开发过程中有许多地方,项目管理可能会意外出错。以下是一些潜在的场景:

  • 可解释性:生成个性化优惠券的模型将 75%的优惠券发送给成千上万的客户。首席财务官注意到本周毛利润下降,并询问项目经理为什么发出这么多优惠券,但没有人能确切解释是什么导致该模型向如此多的客户发出如此慷慨的优惠券。
  • 模型监测:一款个性化视频锻炼应用隆重推出。三个月后,一名用户写信给支持团队,想知道为什么该应用程序连续五天推荐相同的 15 分钟腹肌训练,尽管他已经完成了两次。已经着手开发下一个新功能的数据科学团队检查并意识到模型性能已经下降。
  • 数据收集:项目经理认为每周工作时间是预测学生是否会获得在线课程证书的相关特征输入。但是,这些信息不是学生个人资料的一部分,因此不能包含在特征工程过程中。

偏见、数据清理、模型评估……可以说,机器学习产品的开发过程充满了陷阱,很容易破坏精心规划的产品路线图。懂人工智能的项目经理可以更容易地预见并主动解决这些潜在的情况——在它们发生之前。

为了应对这些挑战,尼克·罗斯教授和我在旧金山大学的数据学院开发了一个为期 7 周的认证课程,名为面向产品经理的数据科学。该证书涵盖了关键的数据科学和机器学习概念,包括分析、统计、回归、聚类、分类、NLP、推荐系统和深度学习,重点是产品应用和业务挑战。

通过加强 PMs 的人工智能素养,我们可以在数据科学家和产品经理之间建立更有效的合作伙伴关系,并为 70 亿特殊雪花提供更多智能产品。

*我使用“数据科学团队”作为一个总括术语来指代构建产品的人。这个人的头衔可能是机器学习工程师或数据科学工程师(理想情况下),但有时简称为“数据科学家”。大多数公司仍在寻找组建和命名数据科学团队的最佳方式。

⭐️感谢我的优秀评论家:阿梅里奥·巴斯克斯-雷纳,普里亚·马休,文森特·乔,科纳·申和诺亚·费舍尔

📸照片由莎拉特鲁默从 Pexels。

使用 PostgreSQL、PSequel 和 Python 设置数据库

原文:https://towardsdatascience.com/leveraging-python-with-large-databases-pandas-postgresql-5073825167e0?source=collection_archive---------4-----------------------

(image source: https://avataai.com/big-data-streaming-processing/)

随着对数据科学家的需求持续增长,并被各种渠道(包括《哈佛商业评论》)称为“21 世纪最性感的工作”,有人问有抱负的数据科学家在走向他们的第一份数据分析师工作时应该掌握哪些技能。

现在有太多的在线课程来获得数据科学家擅长工作所需的技能(在线资源的优秀评论在这里在这里)。然而,当我自己回顾各种课程时,我注意到许多焦点都放在令人兴奋和浮华的主题上,如机器学习和深度学习,而没有涵盖收集和存储此类分析所需的数据集所需的基础知识。

(大)数据科学

在我们进入 PostgreSQL 之前,我猜想你们中的许多人都有同样的问题:我为什么要关心 SQL?

虽然数据库管理对于有抱负的数据科学家来说似乎是一个无聊的话题,但我知道实现一个狗品种分类器是非常有益的!—一旦你加入这个行业,这是一项必要的技能,数据也支持这一点:SQL 仍然是 LinkedIn 招聘信息中列出的最常见和最受欢迎的技能。

SQL is a necessary skills in many data science applications with large datasets (image source: chttp://exponential.io/blog/2015/02/26/big-data-sql/)

Pandas 可以很好地执行最常见的 SQL 操作,但不适合大型数据库——它的主要限制是内存中可以容纳的数据量。因此,如果一个数据科学家正在处理大型数据库,那么在将数据加载到内存之前,SQL 被用来将数据转换成熊猫可以管理的东西。

此外,SQL 不仅仅是将平面文件放入表中的方法。SQL 的强大之处在于它允许用户拥有一组彼此“相关”的表,这通常用“实体关系图”或 ERD 来表示。

许多数据科学家同时使用这两者——他们使用 SQL 查询将数据连接、切片并加载到内存中;然后他们使用 pandas 库函数在 Python 中进行大量的数据分析。

Example of an ERD (source: http://www.datanamic.com/dezign/erdiagramtool.html)

这在处理大数据应用中的大型数据集时尤为重要。这样的应用程序在有几十亿行的数据库中会有几十 TB。

数据科学家通常从 SQL 查询开始,在转移到 Python Pandas 进行数据分析之前,SQL 查询将提取 csv 文件所需的 1%的数据。

输入 PostgreSQL

有一种方法可以在不离开深受喜爱的 Python 环境的情况下学习 SQL,在 Python 环境中教授和使用了如此多的机器学习和深度学习技术:PostgreSQL。

PostgreSQL 允许您在处理不是存储在平面文件而是存储在数据库中的大型数据集时,利用令人惊叹的 Pandas 库进行数据辩论。

PostgreSQL 可以安装在 Windows、Mac 和 Linux 环境中(参见安装细节这里)。如果你有 Mac,我强烈推荐安装 Postgres。App SQL 环境。对于 Windows,请查看 BigSQL

PostgreSQL 使用客户机/服务器模型。这涉及两个运行过程:

  • 服务器进程:管理数据库文件,接受客户端应用程序到数据库的连接,并代表客户端执行数据库操作。
  • 用户客户端 App :经常涉及到 SQL 命令条目,友好的图形界面,以及一些数据库维护工具。

在实际场景中,客户端和服务器通常位于不同的主机上,它们通过 TCP/IP 网络连接进行通信。

正在安装 Postgres。App 和 PSequel

我会专注于 Postgres。在教程的其余部分中。
安装 PostgresApp 后,您可以按照以下说明设置您的第一个数据库:

  • 单击“初始化”创建新的服务器
  • 一个可选的步骤是配置一个$PATH 来使用 Postgres.app 提供的命令行工具,方法是在终端中执行以下命令,然后关闭&重新打开窗口:
    sudo mkdir -p /etc/paths.d && echo /Applications/Postgres.app/Contents/Versions/latest/bin | sudo tee /etc/paths.d/postgresapp

现在,您已经有了一个运行在 Mac 上的 PostgreSQL 服务器,默认设置为:
Host: localhost, Port: 5432, Connection URL: posgresql://localhost

我们将在本教程中使用的 PostgreSQL GUI 客户端是 PSequel 。它有一个极简和易于使用的界面,我真的很喜欢轻松地执行 PostgreSQL 任务。

Graphical SQL Client of choice: PSequel

创建您的第一个数据库

一旦 Postgres。App 和 PSequel 安装完毕,你现在可以设置你的第一个数据库了!首先,从打开 Postgres 开始。应用程序,你会看到一个小象图标出现在顶部菜单。

您还会注意到一个允许您“打开 psql”的按钮。这将打开一个 ommand 行,允许您输入命令。这主要用于创建数据库,我们将使用以下命令创建数据库:
create database sample_db;

然后,我们使用 PSequel 连接到刚刚创建的数据库。我们将打开 PSequel 并输入这个名字的数据库,在我们的例子中是:sample_db。单击“连接”连接到数据库。

创建并填充您的第一个表

让我们在 PSequel 中创建一个表(由行和列组成)。我们定义了表的名称,以及每一列的名称和类型。

PostgreSQL 中可用于列(即变量)的数据类型可在 PostgreSQL 数据类型文档中找到。

在本教程中,我们将创建一个简单的世界国家表。第一列将为每个国家提供一个“id”整数,第二列将使用可变长度字符串(最多 255 个字符)提供国家名称。

准备就绪后,单击“运行查询”。然后将在数据库中创建该表。不要忘记单击“刷新”图标(右下角)来查看列出的表格。

我们现在准备用数据填充我们的列。有许多不同的方法来填充数据库中的表。要手动输入数据,INSERT会派上用场。例如,要输入 id 号为 1 的国家摩洛哥和 id 号为 2 的澳大利亚,SQL 命令是:

INSERT INTO country_list (id, name) VALUES (1, 'Morocco');
INSERT INTO country_list (id, name) VALUES (2, 'Australia');

运行查询并刷新表后,我们得到下表:

实际上,手动填充数据库中的表是不可行的。感兴趣的数据很可能存储在 CSV 文件中。要将一个 CSV 文件导入到country_list_csv表中,使用如下的COPY语句:

COPY country_list_csv(id,name)
FROM 'C:\{path}\{file_name}.csv' DELIMITER ',' CSV HEADER;

正如您在上面的命令中看到的,带有列名的表是在COPY命令之后指定的。列的排序方式必须与 CSV 文件中的相同。CSV 文件路径在FROM关键字后指定。还必须指定 CSV DELIMITER

如果 CSV 文件包含带有列名的标题行,则用关键字HEADER表示,以便 PostgreSQL 在从 CSV 文件导入数据时忽略第一行。

常见 SQL 命令

SQL 的关键是理解语句。一些陈述包括:

  1. CREATE TABLE 是一条在数据库中创建新表的语句。
  2. DROP TABLE 是删除数据库中的一个表的语句。
  3. 选择可以读取数据并显示。

SELECT 是您告诉查询您想要返回哪些列的地方。
FROM 是告诉查询从哪个表查询的地方。请注意,该表中需要存在列。例如,假设我们有一个包含几列的订单表,但是我们只对其中的三个子集感兴趣:

SELECT id, account_id, occurred_at
FROM orders

另外,当您只想查看表格的前几行时, LIMIT 语句非常有用。这比我们加载整个数据集要快得多。 ORDER BY 语句允许我们按任意行对表进行排序。我们可以将这两个命令一起用于数据库中的“订单”表,如下所示:

SELECT id, account_id, total_amt_usd
FROM orders
ORDER BY total_amt_usd DESC
LIMIT 5;

探索其他 SQL 命令

现在,您已经了解了如何在 PostgreSQL 中设置数据库、创建表和填充,您可以按照以下教程中的说明,探索其他常见的 SQL 命令:

用 Python 访问 PostgreSQL 数据库

一旦设置好 PostgreSQL 数据库和表,就可以转移到 Python 来执行任何所需的数据分析或争论。

PostgreSQL 可以使用 psycopg2 模块与 Python 集成。它是一个流行的 Python PostgreSQL 数据库适配器。在 Python 2.5 . x 版及更高版本中,它与默认库一起提供

可以通过以下方式连接到现有的 PostgreSQL 数据库:

import psycopg2
conn = psycopg2.connect(database="sample_db", user = "postgres", password = "pass123", host = "127.0.0.1", port = "5432")

回到我们的 country_list 表示例,在 sample_db 中向表中插入记录可以在 Python 中用以下命令完成:

cur = conn.cursor()
cur.execute("INSERT INTO country_list (id, name) \
      VALUES (1, 'Morocco')");
cur.execute("INSERT INTO country_list (id, name) \
      VALUES (2, 'Australia')");
conn.commit()
conn.close()

用于创建、填充和查询表的其他命令可以在教程点PostgreSQL 教程的各种教程中找到。

结论

现在,您已经有了一个可以运行的 PostgreSQL 数据库服务器,可以进行填充和使用了。它功能强大、灵活、免费,被许多应用程序使用。

在后 GDPR 时代利用您的数据

原文:https://towardsdatascience.com/leveraging-your-data-in-a-post-gdpr-world-208064472659?source=collection_archive---------7-----------------------

image credit — Modus Direct

搜索、社交媒体、云计算和商业分析已经在很大程度上实现了发展我们经济的全球参与者的承诺。为了保护我们自己的数字投资,我们今天投入资源解决 GDPR 问题也就不足为奇了。尽管如此,这些法规遵从性的努力可能被证明是被误导的,因为你的公司数据永远不会比你的利益相关者对你的数据实践的信心更有价值。在数字经济中,竞争优势依赖于对信任的理解,而不是对数据的理解。让我们探索挑战的本质,GDPR 在多大程度上是答案,以及公司如何利用“设计的信任”为后 GDPR 世界做准备。

为了理解这个赤裸裸的事实,我们需要仔细看看是什么产生了一个组织的底线。消费者购买产品、服务和想法的条件是,有一个普遍接受的经济交换体系,确保交易本身的定义、价值和秩序。由于公司和消费者都无法确保合规,他们传统上向各种中介机构付费,以保证交易所的偿付能力:银行核实账目以促进支付,保险公司监督健康和财产风险,国家本身提供教育、基础设施和社会保障。随着数字经济成为现实,这种对可信中介的需求加速增长:Alphabet、脸书、亚马逊和阿里巴巴利用规模经济和网络效应,形成了事实上的垄断。

信任的悖论:随着企业收集越来越多的数据,信任本身变得越来越稀有和珍贵。

在数字经济中,服务只不过是问题的答案,而数据则为尚未提出的问题提供答案。这些问题中首先也是最重要的是信任的悖论:尽管关于公司、经理和产品的信息从未如此丰富,但信任本身已经变得越来越稀缺和宝贵。这种信任缺失在某种程度上可以用全球经济的本质来解释:信息生产者和消费者之间的物理和感知距离从未如此之大。在第二个层面上,经济和社会交流的数字化创造了营销占主导地位的虚拟交流。最后,商业道德和价值观的衰落证明了后真相经济的假新闻是正确的——产品变成了信息。难怪真理的本质已经从基于对经济的盲目信任转变为作为经济决策基础的“委托信任”。

欧洲的一般数据保护法规既承认数字数据已成为世界经济的新货币,也承认收集和组织这些“交易”的大量记录的私人和公共组织控制着他们的客户。GDPR 明确认识到这种内在的危险,建议对描述我们是谁、我们想什么和我们做什么的私人和敏感数据的商业使用进行监管。 GDPR 推出了欧洲公民数字权利法案欧洲公民(“数据主体”)有权知道这些数据是如何、在哪里以及出于什么目的被收集的。现在要求数据控制员和数据处理员制定流程和内部记录保存要求,以确保符合这些新法规。最重要的是,立法者旨在影响我们数据实践的性质——数据保护应该是我们数据库、应用程序和信息系统设计的前提。

GDPR 保护个人数据,而不是个人隐私和利益

尽管这些努力值得称赞,但 GDPR 优先考虑数据保护,而不是个人隐私,同时将目标对准依赖于信息集中控制的计算机应用程序。随着技术的发展,新的软件迭代正在部署分散管理,以实现更大程度的透明性和可追溯性。分布式账本技术就是这样一种迭代;基于区块链的交易可以在很大程度上消除在我们的边境、我们的行政部门和我们的日常经济交易中保证个人数据有效性的中介需求。这些共享可以透明地实时报告组织的财务交易以及个人收入。区块链可以检查求职者的就业、信用或社会服务的凭证,从而促进更安全、更保密的点对点交易。如果 GDPR 的目标是在保护个人隐私的同时限制企业中介的垄断,那么它反过来也需要发展,以促进这些新一代技术的发展。

Trust by design 是一套数据实践,它结合了短期监管要求,同时探索了新形式 IT 的长期机遇。

" Trust by design "提出了一套数据实践,既考虑了 GDPR 的短期需求,又探索了新形式 IT 的长期机遇。总体愿景是开放、交互式的数据实践,提供透明度、客户授权、可移植性和数据质量。指导原则包括数据合理性 - 为消费者提供捕获其私人数据的既定目标、影响评估 - 记录您的数据存储在内部和云上的过程、数据安全性-确保您的组织拥有安全使用专有和开放数据的专业知识、选择性访问 -允许数据所有者决定其暴露程度,以及开放实践 -制定

我将于 11 月 9 日在柏林的 Group Futurista 的后 GDPR/FODP 峰会上讨论和发展这些主张。请不要犹豫,分享你的想法和建议头导致这一事件。我期待着在那里见到你。

李·施伦克博士

商业分析研究所

2018 年 10 月 27 日

Lee Schlenker 是商业分析和社区管理教授,也是 http://baieurope.com 商业分析研究所的负责人。你可以在的推特上关注白

博士后的生活:❤️的“b 选项”,离开

原文:https://towardsdatascience.com/life-after-a-phd-the-option-b-leaving-a18bc89e2d33?source=collection_archive---------0-----------------------

Leaving Academia might feel like pointing to the dessert from a high tower. (“Edge of the World”, Riyadh)

上周,我被邀请去我的博士学校分享我离开学术界的经历。在准备我的想法时,我写了这个,我分享它,希望它也能服务于其他人。按照要求,它包括一个问卷答案。

在科学方面,读完博士后的 A 计划是获得一个或两个博士后,同时发表论文,积累引用。这为最终获得永久职位创造了条件。我们被告知,这是最优秀科学家的最佳案例。这就是科学家的 A 计划。我认为这也是错误的、危险的和短视的。

从科学家的知识基础价值转变为科学家的技能基础价值。

一个选择离开学术界的科学家不应该成为 b 计划。这不比继续进入公共资助的学术研究的漏斗更好或更坏。我们应该致力于让科学家对社会产生最积极的影响。影响的发生通过同行评议论文的确增加了我们对现实的了解,但也非常具体地改善了私营部门的产品和服务,找到了更好的方法来消除贫困,制造自动驾驶汽车,了解政府政策的影响并提出建议。这里的关键是从科学的知识基础价值转移到科学家的技能基础价值。注意我强调的是科学家科学,以及技能知识。不是拥有在论文中发表事实的活字典的价值,而是拥有罕见技能的人的价值,他们必须发展这些技能来获得这些知识。数学技能,建模技能,剖析复杂过程的概念框架,…

我 9 年前拿到了博士学位。我为我的工作感到非常自豪。两年后我离开了研究。起初,我有一种非常强烈的想要其他东西的感觉,但不确定是什么,或者如何得到它。我觉得自己处于某个领域的顶端,但去别的地方就意味着失去这种特权。我也觉得这比停留在学术科学上更没有价值。这可能听起来有些耳熟。这么多年后,我可以分享这条路是怎么走的。我学到的一件重要的事情是,我们通常说科学,当我们指的只是它的一种类型:公共资助的学术研究科学。有很多科学不是公共资助的,或者不是在学术界做的,或者不是为了研究做的。这些年来,我周游世界的次数比我梦想的还要多(我还多次梦想去旅行)。我的贡献在实用主义和经济上都受到高度评价。我遇到了非常有趣的人,并向他们学习。我参与了非常具体的解决方案,涉及非常广泛的主题(比如不丹的榛子物流跨国公司对气候变化的适应,或者在旧金山为自动驾驶汽车制作地图)。我对……选项 b 很满意。世界需要更多……选项 b。事实上,今年 1 月,我决定离开我在世界银行的工作岗位,投身于这一关于科学家在学术界之外的价值的想法。我们需要更多这种撞击科学

当我们只指一种类型的科学时,让我们停止说科学:公共资助的学术研究科学

但不要把这当成建议。我这里提供的是我的经验。我试着解释我的情况,帮助的来源和态度。这充其量只是一个案例奏效的轶事证据。我不知道有多少人尝试过却失败了,也不知道他们做了什么,也不知道有多少无形的玻璃门向我敞开,作为一个没有债务、没有依靠的西方白人。这也是为什么最近我一直在世界各地旅行并收集对那些也离开学术界的科学家的采访的部分原因。为了准备这次会议,我还做了一份快速问卷来获得一些额外的反馈。这不是一个统计研究,但它现在是几个轶事证据的集合,在我写这篇文章的时候有 120 个案例。所有的回答都可以在这里找到(只要回答中包含可识别的信息,我都会匿名)。

在目前回答的 120 人中,45%目前不在研究中,58%不在大学或研究机构。“备选方案 B”。

我从问卷中得到的一个惊喜是,科学家离开学术界时自我报告的最大资产与最大障碍密切相关。使科学家优秀的东西似乎也使我们不优秀。那就是解决问题。我们自我报告了一个非常好的解决问题的能力,但也说兴趣更多的是在理解问题本身,而不是那么什么,实现的链接,或将这种解决问题的技能应用于“现实世界”的问题。

从调查问卷中我还了解到,离开学术界的原因很少是积极的,例如扩大科学的应用,对人们的生活产生更直接的积极影响,……在几乎所有情况下,人们似乎都是被推出去的(压力、生活平衡或很少的钱),而不是选择离开。

Happiness with academic life now, or at the moment of leaving. 1 is HAPPY (reality meets expectations). 6 is UNHAPPY (reality doesn’t meet expectations).

上图对我来说也很有戏剧性。大多数(> 50%的受访者)不快乐(> 3),尤其是最常见的是第二至最严重的不快乐。如果我分解一下,以“2+博士后”为“最高学术水平”的人最不开心(中位数 4.5)。最快乐的是那些在私营部门做研究的人(中位数为 1)和全职教授(也是 1,但他们也有最高的可变性,总体标准差超过两倍)。

离开学术界的原因不应该(仅仅)是沮丧。我这样说是因为在与人交谈时,我发现这种消极情绪是许多人的主要原因。对非研究任务、文书工作、拨款、内部政治、发表或毁灭的失望……这里有两点要说明。一方面,其中一些确实是生活的一部分。你的工作不会只有好的部分,所以这实际上是一件好事,因为博士生被迫增加那些“支持”活动。博士学位不仅是它的新颖内容,它增加了人类对一个领域的理解,而且创造了一个独立的科学家,包括它所涉及的所有事情,包括组织一次会议和做文书工作。现在,另一方面,学术界有许多破碎的东西是绝对正确的。不可复制的论文只发表正面成果腐蚀心理健康的环境供给过剩的博士后,不一而足。我发现避免美化或贬低任何选项都非常重要。

现在,对于实际的东西。根据我的经历、我面试过的人的经历和我做过的研究(一语双关),我能提供什么建议?这项工作仍在进行中,但我可以提供一些建议:

如果你是一名学者

  • 爱情无国界,跨越界限。测试你在一个领域/地方/主题发展到另一个领域/地方/主题的技能。它有助于看到技能相对于知识的价值。例如,将您对太阳的图像分析技能应用到飓风破坏的地球观测图像上,以更好的图像支持响应行动。看看你是否可以使用其他仪器的数据。创新通常发生在不同领域的界面或交叉点。
  • 你建了什么> CVs。当我招聘的时候,我需要人来解决问题。如果他们坦率地说出他们从头到尾都在做的项目,我会更愿意倾听。雇主需要知道你在第一天就能发挥作用,而不是你有学位。
  • 挑剔≠消极。我想说,科学家真的很擅长找出漏洞,找出问题所在,找出可以改进或做得更好的地方。有时候,更好的办法是关注什么在起作用,并理解为什么会这样。这在团队工作、尽职调查或提供专业建议时尤为重要。把事情做得更好可能是好的,把事情做好更好。
  • 不要家长式作风。我发现许多科学家,包括我自己,都落入了“照我说的做,因为如果你知道我知道的,你会照我说的做吗”的陷阱。通常你知道你不知道的部分,并且可能有很强的理由说明事情不应该是这样的。比如气候变化。这不仅仅是停止排放二氧化碳,还涉及激励、就业、政治议程、外交……尽管科学家推出了停止排放二氧化碳的数据,但在科学只是其中一部分的场所,进展正在发生,如联合国达沃斯

如果你管理学术

  • 科学家还是科学?。你所在单位的目标是搞科学(这可能意味着获得政府资助的研究拨款),还是培养科学家(拥有科学技能的人,不管他们在哪里应用科学)。如果是后一种情况,它提供了一个起点来建立一个衡量成功的标准,而不是关于数量或论文、资金或给予机构的引用。
  • 心理健康不是管理危机。有一个系统来检查人们并在危机中提供专业帮助是好的,但它也为心理健康、恢复力、压力管理、自省、冥想等提供工具
  • 衡量幸福感。我非常支持测量匿名化的幸福水平。幸福是主观的,部分是个人的决定,是整体的。这通常是一个糟糕的指标。然而,缺乏快乐通常发生在一系列你可以克服的具体障碍上。如果你压力很大,如果你生病了,如果你和你的导师有问题,如果你的通勤时间是 2 小时,如果你没有通过,你就不会快乐。建立集体幸福感意味着努力消除让人们不快乐的障碍。
  • 在培训中加入软技能:雇佣专家来提高沟通技巧(像演员一样),更多面向公众的学生组织的活动,…
  • 提供非研究选项的可见性。联系公司和校友,宣传他们的职位、实习或特定项目。邀请离开学术界的校友分享经验。与其他非研究机构建立联盟和协议,以共享职位空缺、新闻和会议机会。
  • 良师益友。导师的形象很重要,同样重要的是有更专业经验的人来帮助你做出决定或解决问题。你的博士导师通常是你的导师。好友的形象更像是一个刚去过你那里的同伴,所以它能提供更多个人的和具体的建议。伙伴通常是去年的学生或最近的博士后。

发送您对这些话题的想法和反馈。我非常想听听我应该研究的其他经历、观点、人物或研究。谢谢!!

爱丽丝、鲍勃和夏娃的神经网络生活

原文:https://towardsdatascience.com/life-of-alice-bob-and-eve-with-neural-net-6df0ad1d6077?source=collection_archive---------16-----------------------

学习用对抗的神经密码术保护通信

Image from pixabay

作为一个“人”,如果说我对我们这个物种有一件事是肯定的,那就是,当我们发现或发明某样东西时,我们会尝试将它与已经存在的技术相结合,不管它可能多么怪异。嗯,我想这是人类的一部分。Martin Abadi 和 David G. Andersen 的论文学习用对抗性神经加密技术保护通信就是这种好奇心的结果。

这篇文章将会是一篇很长的阅读文章,完整地介绍了这个理论,并使用 TensorFlow 在 python 中实现了这个系统。我建议你在我们开始前喝杯热伯爵茶。

我们需要知道什么?

至少有两个话题是在座的各位需要清楚了解的:

  1. 对称密码系统
  2. 甘是如何被训练的

它们都是非常宽泛的话题。出于时间和注意力的考虑,我将对这两者做一个简单的介绍,这样就足够了,如果你已经很熟悉了,可以直接跳过。

对称密码系统

对称密码系统的基本思想可以很容易地用一个古老的三个人的例子来解释,他们是爱丽丝、鲍勃和伊芙。在开始之前,我们假设 Alice 和 Bob 共享了一个密钥。一天,Alice 想给 Bob 发送一条秘密消息,她用共享密钥加密这条消息,生成一条密文。之后,Alice 通过一个可能不安全的通道将密文发送给 Bob。稍后,当 Bob 接收到该密文时,他使用相同的共享密钥对其进行解密并读取消息。另一方面,当密文通过不安全的通道时,它被 Eve 截获,但她无法解密,因为她没有共享密钥。这里要注意的关键点是,即使消息是通过不安全的通道传递的,它也不会受到损害。现在可能会出现一个问题,关于这个共享密钥的起源,这是一个完全不同的故事,它会将我们带入非对称密码系统的世界,我们现在不会研究它。

Figure 1 — Symmetric Cryptosystem

上图不仅清楚地展示了刚才所解释的内容,还直观地一口气解释了对称密码系统的基本基础。

甘是如何被训练的

Figure 2 image from Generative models and adversarial training by Kevin McGuinness

对抗的:以冲突或对立为特征的

与神经网络作为监督学习算法的常见用途不同,在神经网络中,它学习分类或预测某些东西,在生成对抗网络或简称 GANs 的系统中,通常有两个网络,一个名为生成器,另一个名为鉴别器。生成器模型的工作是创建自己的假样本。例如,一个图像;而鉴别器的工作是分类它看到的图像是假的(即由生成器创建)还是真的(即取自真实世界)。在训练中,每次迭代生成器都试图愚弄鉴别器,而鉴别器则试图不被生成器愚弄。因此得名在发生器欺骗鉴别器的情况下,鉴别器会根据损耗进行优化,以便更好地区分真假样品。但是如果发生器不能欺骗鉴别器,那么发生器通过损失被优化以创建更好的样本。

如果你对 GAN 的工作方式很感兴趣,我建议你阅读这篇文章或者如果你想看看目前所有的应用,你可以看看这篇文章

注意:我们不会使用 GAN,但我使用它是为了解释一种不同类型的训练,其中神经网络可以通过相互竞争来训练,这是本文的重要部分。

走向

现在我们都有了对称密码系统和对抗网络的基本概念,是时候把它们混合在一起了。在这篇论文中,作者尝试使用神经网络,而不是使用严格的对称密钥算法,如 AES、Triple DES 等。加密或解密信息,我们很快就会谈到它的对抗性部分。

我们把神经网络整合到这个密码系统的什么地方?

Figure 3

我们训练三个神经网络,即 Alice、Bob 和 Eve,它们的工作如下:

  • Alice 的工作是接收 n 位消息(编码为-1 和 1 的向量,分别代表 0 和 1)和 n 位密钥作为输入,输出 n 位密文。
  • Bob 的工作是获取 Alice 创建的 n 位密文,并使用 n 位密钥作为输入来重构原始的 n 位消息。
  • Eve 的工作是只获取 n 位密文,并尝试重新创建原始的 n 位消息。

与最初的对称密码系统模型相比,除了用神经网络代替了严格的加密和解密算法之外,没有什么变化。
这里要注意的要点是,我们正在创建一个对抗性的神经网络,在这种意义上,Alice 训练使用共享密钥来创建密文,Bob 训练使用共享密钥来解密密文,Eve 训练在不知道共享密钥的情况下从密文重建原始消息。

我们为什么需要夏娃? 由于我们正试图让爱丽丝和鲍勃自己学习一种安全地交流数据的方法,我们无法向他们提供从可用的对称加密算法创建的消息和密码对的数据集。这将违背它自己学习加密和解密的全部目的。此外,仅让 Alice 和 Bob 在模型中可能会导致 Alice 学习将消息原样传递给 Bob,而不进行任何形式的加密或进行某种形式的容易被破解的加密,因此我们需要 Eve 充当安全通信的对手。爱丽丝学会了更好的加密方式来与鲍勃安全地通信,夏娃变得更擅长破解它们,直到达到一个点,在这一点上,夏娃不再能够跟上,没有密钥就无法理解任何事情。现在,我们实际上实现了它并计算了它背后的数学。

希望现在这里的每个人都对我们的讨论有了一些形式的想法,所以,从这一点开始,我们将继续理论的其余部分,同时也构建其相应的代码,这是因为至少对我来说,我一直觉得通过代码来理解事物更舒服,这是由于单词的性质有时可以以不同的方式解释,但代码…代码是绝对的。

让我们使用 TensorFlow 亲自尝试一下

对于那些有足够信心直接钻研其代码的人来说:

[## VamshikShetty/对抗性-神经-密码学-张量流

使用对抗网络模仿对称密码系统

github.com](https://github.com/VamshikShetty/adversarial-neural-cryptography-tensorflow)

创建单个模型

在开始构建单独的模型之前,我们还需要一些东西。为了简单起见,我们将认为文本和密钥具有相同的大小,让我们说 16 位,这是作者在本文中考虑的最小大小。为了训练,作者使用了从 256 到 4096 的小批量。

text_size   = 16
key_size    = 16
batch_size  = 4096

考虑到这一点,现在这些都是必需的参数,我们创建两个张量来保存随机生成的消息和密钥。我们希望一次保存 4096 的整批大小,因为每个文本或键的大小是 16,所以每个张量的形状将是(4096,16)。

在上面的代码片段中,名为model的函数用于创建所需的神经网络。该函数采用三个输入参数,其中collection是模型的名称(“Alice”、“Bob”或“Eve”),因此为模型创建的所有层都在一个范围内。message是保存文本的张量,而key是保存共享密钥的张量。这里需要注意的一点是,如果给定了一个密钥,if条件的计算结果为True,消息和密钥被连接起来形成一个大小为 32 位(text_size + key_size)的张量。这个场景对 Alice 和 Bob 有效。而对于 Eve,if将评估为False,并且仅给出密文作为输入。

在每个模型中,除了输入张量之外,模型的其余部分彼此相似。每个网络都有一个大小为 2n (n =消息/密钥位数)的全连接(fc)层,其后是四个 1 维卷积层。

完全连接的层的作用非常直观。每种加密方法都有某种形式的混合和转换,该层使消息和密钥位能够影响 fc 层中每个独立神经元的输出,因为每个输出位可以是所有输入位的线性组合。

FC 层之后是一系列卷积层,最后一层产生大小适合于明文或密文的输出。这些卷积层学习将一些函数应用于由前一层混合的比特组,以利用空间局部性。因为作者希望局部性(即要组合的位)成为一种习得的属性,而不是像严格对称密钥算法中那样预先指定的属性。

现在是从 2n 位 FC 层获得 n 位输出的棘手部分,因为它后面有 4 个卷积层,并且我们最终没有任何 n 位大小的 FC 层来产生 n 位输出。为了回答这个问题,让我们把注意力转移到第二 Conv 层,我们设置步幅值为 2,填充设置为“有效”。如果你熟悉卷积,那么你一定已经明白,在这个模型中,2N 个单位减半,我们得到一个 n 位张量。

注:滤镜、核大小、步幅等参数均按原纸取。

为什么我们在最后一层有 Tanh 作为激活函数?
由于我们分别使用-1 & 1 来表示 0 & 1 位,如果我们的输出也有类似的表示,并且双曲正切函数在-1 和 1 的范围内产生输出,那就更好了。就这么简单。

对于好奇的读者来说,他们想知道Expand_dimsSqueeze函数在扮演什么角色;最初,输入的大小为(4096,32),当进行卷积时,出现了一个称为通道的概念,类似于我们在一幅图像中有 3 个通道,即 RGB。鉴于我们的数据只是一个渠道,我们需要数据来显示类似的特征。因此Expand_dim将(4096,32)转换为具有一个通道的数据,即(4096,32,1),最后Squeeze函数做相反的操作。

模仿对称密码系统

Alice _ out _ ciphew 表示 Alice 模型的输出,即 Bob 和 Eve 将试图解密的 n 位密文。您可以在第 8 行和第 11 行分别看到这个密文作为 Bob 和 Eve 模型的输入。

现在,以这样的方式训练 Alice 和 Bob,使他们能够在不丢失任何信息的情况下进行数据通信,并且还能够自己从头开始学习加密和解密,这样 Eve 就无法理解 Alice 发送给 Bob 的内容。答案隐藏在他们损失函数的形成中。

损失函数

Eve 的丢失很简单,只需尝试使用 L1 范数/距离来最小化 Eve 的输出和原始消息之间的比特差的误差。我们认为损失函数是给定批次的平均 L1 范数损失。

在系统中引入对抗性 本性的真正诀窍落在爱丽丝和鲍勃的损失上,分为两部分。第一部分类似于 Eve 的损失,即尽量减少位数的错误,Bob 学习使用密文和密钥重建原始消息。正如我们已经讨论过的,仅试图最小化比特中的错误可能会导致 Alice 将原始消息本身作为密文传递给 Bob,因为不学习一些花哨的加密方法来加密原始消息并从密文和密钥中重建原始消息更容易。
我们如何确保这种情况不会发生,我们引入了一个损失复制 Eve 作为窃听者。简而言之,夏娃破解他们的密码越好,爱丽丝-鲍勃的损失就越大。用公式表示:

这种损失确保 Eve 不会比随机猜测做得更好,即当一半的消息位是错误的而一半是正确的时,这种成分被最小化。在 Alice 和 Bob 的训练中,我们不应该试图最大化 Eve 的重建误差,因为如果我们这样做并使 Eve 完全错误,那么通过简单地翻转所有输出位,Eve 可以在下一次迭代中完全正确。作者选择二次公式是为了强调使 Eve 具有较大的误差。因此,我们需要夏娃的 L1 损失来计算爱丽丝和鲍勃损失函数的第二部分。我们可以在下面提到的代码片段中看到 TensorFlow 编写的内容。

让我们创建一些随机数据集

这里的数据集是一对向量,用于表示具有随机位值(即 0 和 1)的消息和密钥,但是 0 作为神经网络的输入从来都不是一个好的选择,因为它表示没有信号,所以我们只对 0 到-1 和 1 到 1 进行编码。

训练开始

在下面的代码片段中,我们使用了迄今为止我们讨论过的所有函数的顶点。它从创建对称密码系统模型开始,然后我们继续创建用于网络对抗训练的 Alice-Bob 和 Eve 损失函数。稍后,为了表示用于通过训练属于 Alice 和 Bob 模型的张量来最小化 Alice -Bob 通信损失的优化器,我们创建了一个名为 bob_opt 的变量。而另一方面,eve_opt 对 eve 的模型做了同样的事情。

注: Eve 的模型比原始论文中提到的 Alice-Bob 通信模型优化了两倍。(下面代码片段中的第 60 行)

实验和结果

Reference - Evolution of Bob’s and Eve’s reconstruction errors during training. Lines represent the
mean error across a mini-batch size of 4096

作者接受了 4096 小批量的 16 位文本和密钥大小的培训。理想的结果应该是 Bob 的重构误差下降到零,Eve 的重构误差达到 8(一半的比特是错误的)。在这个实验中,两个重建误差都很高。一段时间后,爱丽丝和鲍勃开始相当有效地交流,但这种方式也让夏娃提高了理解能力。然后,在第 10,000 步左右,爱丽丝和鲍勃对抗
夏娃的进程。到大约 15,000 步时,训练目标有效地实现了。剩下的步骤只是稍微增加了 Eve 的重建误差。

注:在第 0 步,4096 个样本的平均误差为 8 或接近 8。可以认为,给定二进制输出,我们有 50%的机会是正确的,因此 16 位中有 50%是正确的。

作者的一些观察:

  1. 依赖于密钥:改变密钥并保持明文
    不变会导致不同的密文输出。
  2. 密钥中的单比特翻转通常会导致密文中 16 个元素中的 3 到 6 个发生显著变化。

学会有选择地保护

到目前为止,我们已经看到了一个简单的场景,试图通过加密来保护整个消息免受对手攻击,但如果消息由许多部分组成,这些部分可用于发布与该消息相关的一些相关值,并使其对正确的个人可用,但保护消息的其余部分不被对手计算,那会怎么样呢?

理论:

为了测试这些想法,作者构建了一个由四个值(A,B,C,D)的元组组成的数据集。现在,一个系统被创建并训练为使用前三个输入(A、B、C)来输出 D 的两个值,即:

  1. D-public 这是对 D 的最佳可能估计,并且不会透露任何关于 c 的值的信息(由 Alice 产生)
  2. D 预测(对 D 的“真实”预测),这是对 D 的最准确的可能估计(由鲍勃制作)

已知的假设已经存在,即爱丽丝和鲍勃共享一个秘密密钥。这里,Alice 接收(A,B,C)作为输入,除了密文之外,还产生 D-public。Bob 使用 D-public 和带有共享密钥的密文来产生 D . I . e . D . predict 的改进估计。而 Eve 接收 D-public 和密文来恢复 C,充当系统的对手

****目标:证明对抗性训练允许在不暴露 c 的情况下逼近 D。

如何生成这样的数据集,即(A,B,C,D)?

" A、B、C 和 D 是正态分布的浮点值,其上施加有相关矩阵。我们如何生成 A、B、C 和 D 的细节是标准的:我们计算指定成对相关的 4x4 相关矩阵的乔莱斯基分解 LL,我们生成 4 个正态分布浮点值的向量,然后我们将这些向量乘以 L,以便生成 A、B、C 和 D 的值。”

培训流程:

训练 Eve 的目标是最小化估计 C 的平方误差。训练 Alice 和 Bob 的目标不仅是最小化估计 D-public 和 D-predict w . r . t . D 的平方误差,而且还要确保 Eve 不能使用 D-public &密文来重构 C,这是通过最小化它们的协方差值来实现的。

结果:

为了检查系统是否工作,作者创建了一个新的模型,称为“盲 Eve”,它知道 C 的分布。盲 Eve 根据其分布的基线信息预测 C 的值。如果可以访问 D-public 和密文的 Eve 的错误等于盲 Eve 的错误,那么我们可以得出结论,Eve 无法从 D-public 和密文中提取有意义的信息,如下图所示:

Reference - Training to estimate D while hiding C

  • Public Error是 D-public 和 D 之间的错误。
  • Bob Error是 D-predict 和 D 之间的误差。
  • Blue Dots显示 Eve 相对于盲 Eve 的平均误差改善,但是随着训练的进行,平均误差变为零,这表示 Eve 不能提取任何有用的信息来重建 c

做这一切的目的是什么?

“我们不为这些神经网络指定特定的密码算法;相反,我们进行端到端的对抗训练。我们证明了神经网络可以学习如何执行各种形式的加密和解密,以及如何有选择地应用这些操作以满足机密性目标”

*-*-马丁·阿巴迪和大卫·g·安徒生

摘要结尾引用的这段话总结了一切,从如何训练神经网络模仿对称密码系统彼此安全通信,到如何对对手隐藏选择性信息,同时确保正确的个人能够使用共享秘密提取隐藏的信息。所有这些都不需要任何先前的领域知识或者已经存在的严格加密系统的帮助。

尽管它可能没有足够的革命性来改变密码学的世界,但它给了我们一个新的视角来看待深度学习和密码系统。

谢谢你看这篇文章,快乐学习!

参考资料:

**[## [1610.06918]学习使用对抗性神经加密技术保护通信

摘要:我们问神经网络是否可以学习使用密钥来保护信息免受其他神经网络的攻击

arxiv.org](https://arxiv.org/abs/1610.06918)** ** [## 张量流/模型

用 TensorFlow 建立的模型和例子。通过在…上创建帐户,为 tensor flow/模型开发做出贡献

github.com](https://github.com/tensorflow/models/tree/master/research/adversarial_crypto)**

如果你认为我们是志同道合的人,应该联系,那么你可以在 LinkedIn 上找到我,或者发电子邮件到 vamshikdshetty@gmail.com 找我。如果您有任何想法、问题或反馈,请在下面随意评论,我很乐意收到您的来信。

生活的小赌注

原文:https://towardsdatascience.com/lifes-little-bets-568a6dc1179c?source=collection_archive---------4-----------------------

一个亲戚突然送你 1000 欧元的礼物。这是一笔可观的钱,但还不足以购买梦想中的房子,更不用说退休了。你决定用这笔意想不到的施舍来玩法国国家彩票,宣布的奖金比你想象的要多。即使获胜的可能性很小,坚持一定会有回报。你决定在接下来的一年中每周下注 20 欧元,并打算用你最终的赢款在下一次下注时加倍下注。一年后你会赢多少钱?

你应该相信你最初的直觉,这是一个好主意,还是使用现有的数据来批判性地思考你成功的机会?利用决策科学的原理,我们当然可以做得比瞎猜好得多。我们对决策环境和手头的数据了解多少?我们有一千欧元可以花。我们正在考虑把这笔钱花在为公共项目融资的彩票上。基于从 49 个数字中选择 6 个正确数字,任何一周赢得一些钱的机会是 16.7%。这是一个随机决策环境的例子——问题“我这周会赢得头奖吗?”不包含在数据本身中。我们一周可以玩三次,但无法提前知道哪些号码会构成中奖票。

赌博,就像一般的商业,尤其是创新一样,是一种没有绝对保证的概率游戏。【我】在这样的决策环境中,我们仍然可以通过探索手头的数据,选择适当的方法来解决问题的本质,并使用数据来激励行动,从而做出更好的决策。当分析可能的结果时,我们需要从探索我们所知道的独立(条件因素)和从属(可解释的结果)变量开始。然后,我们可以分析上下文来理解事件链的潜在组合和排列。在这种情况下,我们选择的数字和每周的中奖票有什么关系?

统计学中众所周知的问题类型被称为一维随机游走,通常被称为赌徒的破产。如果你每周下注相等的遗产(1/N),你将在 N 周内失去一切。问题的本质是,你输掉每周赌注的概率小于 1(在国家彩票的情况下,赔率严重偏向庄家)。不仅很有可能你会输掉你的每一笔赌注,而且无论输赢,你都离清空你的下注帐户还有 N 步之遥。忘掉你的预感和直觉,把你的 1000 欧元投资在学习如何做出更好的决定上(例如在我们的大师班)会是一个更好的投资…

改善管理决策是商业分析研究所的核心和灵魂。在我们位于巴约纳的暑期学校,以及我们在欧洲的大师班,我们让分析为您和您的组织服务。该研究所专注于管理者数据科学的五个应用:在数字时代工作、数据驱动的决策、机器学习、社区管理和视觉通信。培养你做出更好决定的能力会对你未来的工作和职业生涯产生影响。


Reis,r .(2015),创始人:以下是如何利用概率为你带来优势,Medium

[ii]t . Lieghton,(2006),T14 随机漫步 T15,讲稿,麻省理工学院计算机科学数学

卷积神经网络直观指南

原文:https://towardsdatascience.com/light-on-math-machine-learning-intuitive-guide-to-convolution-neural-networks-e3f054dd5daa?source=collection_archive---------1-----------------------

点亮数学机器学习

Image by Free-Photos from Pixabay

这是我的系列文章中的第二篇,介绍机器学习概念,同时略微涉及数学。如果你错过了之前的文章,你可以在这里找到(关于 KL 发散)。有趣的事实,我将通过为字母表中的每个字母引入一些机器学习概念来使这成为一次有趣的冒险(这将是字母 C )。

A B CD*** E FG* H I JKL*** MNO P Q R S T U****

*表示中等付费墙后面的文章

介绍

卷积神经网络(CNN)是一种深度网络,可以利用数据(例如图像)的空间结构来学习数据,以便算法可以输出有用的东西。考虑这样一个问题,我们想要识别在给定的图像中是否有一个人。例如,如果我给 CNN 一个人的图像,这个深度神经网络首先需要学习一些局部特征(例如,眼睛、鼻子、嘴等。).这些局部特征在 卷积层 中学习。

然后,CNN 将查看给定图像中存在哪些局部特征,然后产生特定的激活模式(或激活向量),其全局地表示这些局部特征图的存在。这些激活模式是由 CNN 中的 全连接 层产生的。例如,如果图像不是一个人,激活模式将不同于它给出的一个人的图像。

CNN 在一个模块的水平

现在让我们看看 CNN 中存在哪种子模块。一个典型的 CNN 有三个不同的组成部分。它们是卷积层、汇集层和全连接层。关于什么是卷积层和全连通层,我们已经有了一个大致的概念。我们没有讨论的一件事是 池层 ,我们将很快讨论它。

首先,我们深入讨论卷积层的作用。一个卷积层由许多 内核 组成。卷积层中存在的这些内核(有时称为 卷积滤波器 )学习图像中存在的局部特征(例如,人的眼睛看起来像什么)。卷积层学习的这种局部特征称为 特征图 。然后这些特征在图像上进行卷积。这个卷积操作将产生一个矩阵(有时被称为 激活图 )。如果卷积滤波器中表示的要素出现在输入的给定位置,则激活图会在该位置产生高值。

汇集层使 CNN 翻译学习的这些特征不变(例如,不管人的眼睛在[ x=10,y=10 ]或[ x=12,y=11 ]位置,汇集层的输出将是相同的)。请注意,我们讨论的是每层的轻微翻译变化。然而,聚集几个这样的层,允许我们具有更高的平移不变性。

最后,我们有完全连接的层。完全连接的层负责基于激活的特征映射的集合和图像中的位置产生不同的激活模式,特征映射被激活用于图像中的位置。这是 CNN 视觉上的样子。

对 CNN 的整体结构有了很好的了解后,让我们继续了解组成 CNN 的每一个子组件。

卷积层

卷积运算到底是做什么的?如果卷积特征存在于给定位置,则卷积运算输出该位置的高值,否则输出低值。更具体地,在卷积核的给定位置,我们对每个核单元值和与核单元重叠的相应图像像素值进行逐元素相乘,然后对其求和。确切的值是根据下面的公式决定的( m —内核宽度和高度, h —卷积输出, x —输入, w —卷积内核)。

图像上的卷积过程可以被可视化如下。

仅仅知道卷积运算做什么是不够的,我们还需要了解卷积输出代表什么。想象卷积输出值的颜色(0 —黑色,100 —白色)。如果你观想这个图像,它将代表一个二进制图像,在眼睛所在的位置发光。

卷积运算也可以被认为是对给定图像执行某种变换。这种变换可以产生各种效果(例如,提取边缘、模糊等。).让我们更具体地理解卷积运算对图像的影响。考虑下图和卷积核。你可以在这篇维基百科文章中找到更多相关信息。

汇集层

现在让我们了解一下池操作是做什么的。池(有时称为子采样)层使 CNN 在卷积输出方面有一点平移不变。实践中使用了两种不同的汇集机制(最大汇集和平均汇集)。我们将最大池称为池,因为与平均池相比,最大池被广泛使用。更准确地说,池化操作在给定的位置输出输入的最大值,该值在内核中。所以从数学上来说,

通过对我们前面看到的卷积输出应用池化操作,让我们了解池化是如何工作的。

如你所见,我们使用了同一个图像的两个变体;一幅原始图像和另一幅在 x 轴上稍微平移的图像。但是,池化操作会为两幅图像输出完全相同的特征图(黑色— 0,白色— 100)。因此,我们说汇集操作使得 CNN 翻译中的知识不变。需要注意的一点是,我们不是一次移动 1 个像素,而是一次移动 2 个像素。这就是所谓的 步距池 ,意味着我们以 2 的步距执行池操作。

完全连接的层

完全连接的层将组合由不同卷积核学习的特征,以便网络可以建立关于整体图像的全局表示。我们可以如下理解全连通层。

全连接层中的神经元将基于由卷积特征表示的各种实体是否实际存在于输入中而被激活。由于完全连接的神经元为此被激活,它将基于输入图像中存在的特征产生不同的激活模式。这为输出层提供了影像中存在的内容的紧凑表示,输出层可以轻松地使用该表示对影像进行正确分类。

将它们编织在一起

现在,我们要做的就是将所有这些放在一起,形成一个端到端的模型,从原始图像到决策。一旦连接上,CNN 就会变成这样。总而言之,卷积层将学习数据中的各种局部特征(例如,眼睛看起来像什么),然后汇集层将使 CNN 对这些特征的平移不变(例如,如果眼睛在两个图像中出现轻微平移,CNN 仍会将其识别为眼睛)。最后,我们有完全连接的层,也就是说,“我们发现两只眼睛,一个鼻子和一张嘴,所以这一定是一个人,并激活正确的输出。

添加越来越多的层有什么作用?

增加更多的层,显然提高了深度神经网络的性能。事实上,深度学习中最引人注目的突破性研究与解决 的问题有关,我们如何增加更多的层? ,虽然没有打乱模特的训练。因为模型越深,训练难度越大。

但是拥有更多的层有助于 CNN 以分层的方式学习特征。例如,第一层学习图像中的各种边缘方向,第二层学习基本形状(圆形、三角形等)。)而第三层学习更高级的形状(例如眼睛的形状、鼻子的形状),等等。这提供了更好的性能,相比之下,你可以用一个 CNN 来学习所有这些。

训练 CNN(又名反向传播)

现在,要记住的一件事是,这些卷积特征(眼睛、鼻子、嘴巴)不会在你实现 CNN 时神奇地出现。目标是在给定数据的情况下学习这些特征。为此,我们定义了一个代价函数,奖励正确识别的数据,惩罚错误分类的数据。示例成本函数可以是均方根误差或二元交叉熵损失。

在我们定义损失之后,我们可以优化特征的权重(即特征的每个单元值)以反映有用的特征,从而使 CNN 正确地识别一个人。更具体地说,我们优化每个卷积核和全连接神经元,通过在每个参数相对于损失的梯度所示的相反方向上迈出一小步。然而,要实现 CNN,你不需要知道如何实现梯度传播的确切细节。这是因为,当你定义正向计算时,大多数深度学习库(例如 TensorFlow、PyTorch)在内部自动实现这些微分操作。

用 Keras 实现和运行 CNN

这里我们将简要讨论如何实现一个 CNN。了解基础知识是不够的,我们还应该了解如何使用像 Keras 这样的标准深度学习库来实现模型。Keras 是一个很好的工具,尤其是快速原型模型,看看他们的行动!此处 的练习可用

首先,我们定义想要使用的 Keras API。我们将使用顺序 API 。你可以在这里了解更多信息:

# Define a sequential model
model = Sequential()

然后我们定义一个卷积层如下:

# Added a convolution layer
model.add(Conv2D(32, (3,3), activation=’relu’, input_shape=[28, 28, 1]))

这里,32是层中内核的数量,(3,3)是卷积层的内核大小(高度和宽度)。我们使用非线性激活Relu和输入形状[28, 28, 1],即[image height, image width, color channels]。请注意,输入形状应该是前一层产生的输出形状。对于第一个卷积层,我们有实际的数据输入。对于层的其余部分,它将是前一层产生的输出。接下来,我们讨论如何实现最大池层:

# Add a max pool lyer
model.add(MaxPool2D())

这里我们不提供任何参数,因为我们将使用 Keras 中提供的默认值。如果不指定参数,Keras 将使用内核大小(2,2)和步距(2,2)。接下来,我们定义完全连接的层。然而,在此之前,我们需要拉平我们的输出,因为完全连接的图层处理 1D 数据:

model.add(Flatten())model.add(Dense(256, activation=’relu’))
model.add(Dense(10, activation=’softmax’))

这里我们定义了两个全连接或密集层。第一个全连接层有256个神经元,使用Relu激活。最后,我们定义了一个密集层,它有 10 个输出节点,并激活了softmax。这充当输出层,它将为具有相同对象的图像激活特定的神经元。最后,我们编译我们的模型,

model.compile(
 optimizer=’adam’, loss=’categorical_crossentropy’, metrics=[‘accuracy’]
)

这里我们说使用Adam优化器(来训练模型),使用交叉熵损失并使用模型的accuracy来评估模型。最后,我们可以使用数据来训练和测试我们的模型。我们将使用 MNIST 数据集,我们将使用练习中定义的maybe_downloadread_mnist函数下载并读入内存。MNIST 数据集包含手写数字(0–9)的图像,目标是通过分配图像所代表的数字来对图像进行正确分类。

接下来,我们通过调用以下函数来训练我们的模型:

model.fit(x_train, y_train, batch_size = batch_size)

我们可以用下面的测试数据来测试我们的模型:

test_acc = model.evaluate(x_test, y_test, batch_size=batch_size) 

我们将运行几个时期,这将允许您提高模型的性能。

结论

我们在这里结束关于卷积神经网络的讨论。我们首先从一个更高的角度讨论了 CNN 内部发生的事情,然后一节一节地讨论。然后,我们讨论了典型 CNN 的主要组成部分,如卷积层、池层和全连接层。最后,我们更详细地介绍了每个组件。然后我们简单讨论了 CNN 中的训练是如何进行的。最后,我们讨论了如何用 Keras 实现一个标准的 CNN:一个高级的 TensorFlow 库。你可以在这里 找到本教程 的练习。

干杯!

如果你喜欢我分享的关于数据科学和机器学习的故事,考虑成为会员吧!

** [## 通过我的推荐链接加入媒体

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

thushv89.medium.com](https://thushv89.medium.com/membership)**

想在深度网络和 TensorFlow 上做得更好?

检查我在这个课题上的工作。

[1] (书)TensorFlow 2 在行动——曼宁

[2] (视频教程)Python 中的机器翻译 — DataCamp

[3] (书)TensorFlow 中的自然语言处理 1 — Packt

潜在狄利克雷分配直观指南

原文:https://towardsdatascience.com/light-on-math-machine-learning-intuitive-guide-to-latent-dirichlet-allocation-437c81220158?source=collection_archive---------1-----------------------

点亮数学机器学习

主题建模是指确定最能描述一组文档的主题的任务。这些主题只会在主题建模过程中出现(因此称为潜在)。其中一种流行的主题建模技术被称为潜在狄利克雷分配 (LDA)。虽然名字很拗口,但背后的概念非常简单。

简而言之,LDA 设想了一组固定的主题。每个主题代表一组单词。LDA 的目标是以某种方式将所有文档映射到主题,使得每个文档中的单词大部分被那些虚构的主题捕获。我们将系统地学习这种方法,直到你能足够舒服地自己使用这种方法。

这是数学机器学习系列 之光 A-Z 的第四篇博文。你可以在下面的信中找到以前的博客文章。

A BCDE F G H I JKLMNO P Q R S T U V*****

🔈🔥最新文章🔥🔈:M—矩阵分解********

*表示中等付费墙后面的文章。

为什么要主题建模?

主题建模在现实世界中有哪些用途?历史学家可以使用 LDA 通过分析基于年份的文本来确定历史上的重要事件。基于网络的图书馆可以使用 LDA根据你过去的阅读推荐书籍。新闻提供者可以使用主题建模来快速理解文章或者聚集相似的文章。另一个有趣的应用是图像的无监督聚类,其中每个图像都被视为类似于一个文档。******

这篇文章有什么独特之处?这是海里的另一条鱼吗?

简而言之,答案是否定的!我浏览了许多不同的文章。而且有很多很棒的文章/视频给人直觉。然而,他们中的大多数人仅仅停留在回答这样的问题上:

  • LDA 背后的直觉是什么?
  • 什么是狄利克雷分布?

我确实谈到了这一点,但我不认为我们应该就此止步。这些模型的训练方式是我在阅读的许多文章中发现缺失的一个关键部分。所以我试着回答更多的问题,比如:

  • 我们想解决的数学实体是什么?
  • 我们如何解决这个问题?

LDA 背后的大理念是什么?

一旦你理解了这个大概念,我想它会帮助你理解为什么 LDA 的机制是这样的。所以现在开始。

每个文档可以通过主题的分布来描述,每个主题可以通过词的分布来描述

但是我们为什么要用这个想法呢?我们通过一个例子来想象一下。

通俗地说就是 LDA

假设您有一组 1000 个单词(即所有文档中最常见的 1000 个单词),并且您有 1000 个文档。假设每个文档中平均出现 500 个这样的单词。怎么才能了解每个文档属于什么类别?一种方法是根据单词在文档中的出现,通过线索将每个文档与每个单词连接起来。类似下面的东西。

Modeling documents just with words. You can see that we can’t really infer any useful information due to the large amount of connections

然后当你看到一些文档与同一套单词相关联时。你知道他们讨论同样的话题。然后你可以阅读其中的一份文件,知道所有这些文件的内容。但要做到这一点,你没有足够的线程。为此,您将需要大约 5001000=500,000 个线程。但我们生活在 2100 年,我们已经耗尽了制造螺纹的所有资源,所以它们非常昂贵,你只能负担得起 10,000 根螺纹。你如何解决这个问题?*

深入减少螺纹!

我们可以通过引入潜在(即隐藏)层来解决这个问题。假设我们知道文档中出现的 10 个主题。但是这些话题是不被观察的,我们只观察单词和文档,因此话题是潜在的。我们希望利用这些信息来减少线程的数量。然后你可以做的是,根据单词在主题中的位置将单词与主题联系起来,然后根据每个文档涉及的主题将主题与文档联系起来。

现在假设你得到的每个文档有大约 5 个主题,每个主题涉及 500 个单词。也就是说,我们需要 10005 个线程将文档连接到主题,10500 个线程将主题连接到单词,总计 10000 个线程。**

Words are modeled by a set of topics and documents are modeled by a set of topics. The relationships are clearer than the first example because there’s a fewer connections than the first example.

****:我这里用的话题(“动物”、“运动”、“科技”)都是虚构的。在真解中,你不会有这样的题目而是类似(0.3 猫,0.4 狗,0.2 忠,0.1 恶)代表题目“动物”的东西。也就是说,如前所述,每个文档都是单词的分布。

一个不同的观点:LDA 想象文档是如何生成的?

为了给正在发生的事情提供更多的上下文,LDA 假设您看到的任何文档背后都有以下生成过程。为了简单起见,让我们假设我们正在生成一个包含 5 个单词的文档。但是同样的过程可以推广到每个都有 N 个单词的 M 个文档。标题很好地解释了这里发生了什么。所以我就不重申了。

How a document is generated. First α (alpha) organise the ground θ (theta) and then you go and pick a ball from θ. Based on what you pick, you’re sent to ground β (beta). β is organised by η (Eta). Now you pick a word from β and put it into the document. You iterate this process 5 times to get 5 words out.

这个图像描绘了一个已经学习过的 LDA 系统的样子。但是要达到这个阶段,你必须回答几个问题,例如:

  • 我们如何知道文档中有多少主题?
  • 你可以看到,我们的场地已经有了一个很好的结构,可以帮助我们生成合理的文件,因为组织者已经确保了场地的适当设计。我们如何找到如此优秀的组织者?

这将在接下来的几节中回答。此外,我们将从这一点开始变得有点技术性。所以系好安全带!

注意 : LDA 不关心文档中单词的顺序。通常,LDA 使用词袋特征表示来表示一个文档。这是有道理的,因为,如果我拿一份文件,把这些单词混在一起,然后给你,你仍然可以猜出文件中讨论了什么样的主题。

变得有点数学化…

在深入细节之前。让我们弄清楚一些事情,比如符号和定义。

定义和符号

  • k —文档所属主题的数量(固定数量)
  • v——词汇量
  • M —文件数量
  • N —每个文档中的字数
  • w —文档中的一个单词。这被表示为大小为 V 的一个热编码向量(即 V —词汇大小)
  • w (粗体 w ):代表一个文档(即 N 字的矢量ws)**
  • D — 语料库,收集了 M 的文档
  • z —一组 k 主题中的一个主题。一个话题就是一个分布词。例如,它可能是,动物= (0.3 猫,0.4 狗,0 人工智能,0.2 忠诚,0.1 邪恶)**

更精确地定义文档生成

首先让我们把上面关于生成文档的基础例子,放到一个适当的数学绘图中。

Graphical model of the LDA. Here I mark the shapes of the all the possible variables (both observed and hidden). But remember that θ, z, and β are distributions, not deterministic values

让我们破译这是什么意思。我们有一个单一的α值(即底θ的组织者)来定义θ;文档的主题分布将是这样的。我们有 M 个文档,每个文档都有一些θ分布。现在为了更清楚地理解事情,眯起你的眼睛,让那个 M 盘子消失(假设只有一份文件),哇!

现在,单个文档有 N 个单词,每个单词由一个主题生成。你生成了 N 个主题来填充单词。这 N 个字还是占位符。

现在顶板开始工作了。基于η,β具有某种分布(即,准确地说是狄利克雷分布——即将讨论),并且根据该分布,β为每个主题生成 k 个单独的单词。现在,根据占位符所代表的主题,为每个占位符(在 N 个占位符的集合中)填入一个单词。

Viola,你现在有一份有 N 个字的文件了!

为什么α和η是常数?

α和η在上图中显示为常数。但实际上比这更复杂。例如,α对于每个文档都有一个主题分布(θ ground 对于每个文档)。理想情况下,一个(M×K)形状的矩阵。而η对每个题目都有一个参数向量。η的形状为 (k x V) 。在上图中,常数实际上代表矩阵,是通过将矩阵中的单个值复制到每个单元格中而形成的。**

让我们更详细地理解θ和β

θ是一个随机矩阵,其中θ (i,j) 表示第 i 个文档包含属于第 j 个主题的单词的概率。如果你看看上面例子中的地面θ是什么样子,你可以看到球被很好地放置在角落而不是中间。拥有这样一个属性的好处是,我们产生的单词可能属于一个主题,就像现实世界中的文档一样。这是通过将θ建模为狄利克雷分布而产生的性质。类似地,β(i,j)表示第 i 个主题包含第 j 个单词的概率。而β也是狄利克雷分布。下面,我提供一个快速的迂回来理解狄利克雷分布。

快速迂回:理解狄利克雷分布

狄利克雷分布是贝塔分布的多元推广。这里我们讨论一个三维问题的例子,其中α中有 3 个参数影响θ的形状(即分布)。对于 N 维狄利克雷分布,有一个长度为 N 的向量,为α。你可以看到θ的形状随着α值的不同而变化。例如,您可以看到顶部中间的图显示了与θ ground 相似的形状。

主要要点如下:

较大的α值将分布推向三角形的中间,而较小的α值将分布推向角落。

How the distribution of θ changes with different α values

我们如何学习 LDA?

我们仍然没有回答真正的问题是,我们如何知道精确的α和η值?在此之前,让我列出我们需要找到的潜在变量。

  • α-分布相关参数,控制语料库中所有文档的主题分布情况
  • θ —随机矩阵,其中θ(i,j)表示第 I 个文档包含第 j 个主题的概率
  • η —分布相关参数,控制每个主题中单词的分布情况
  • β —一个随机矩阵,其中β(i,j)表示第 I 个主题包含第 j 个单词的概率。

阐明我们需要学习什么

如果要我用数学的方式来表述我感兴趣的是什么,那么如下所示:

它看起来很吓人,但包含了一个简单的信息。这基本上是在说,

我有一组 M 个文档,每个文档有 N 个单词,其中每个单词由一组 K 个主题中的一个主题生成。我在寻找联合后验概率:

  • θ —主题分布,每个文档一个主题,
  • z —每个文档的 N 个主题,
  • β —词的分布,每个主题一个词,

鉴于,

  • D —我们拥有的所有数据(即,修正数据),

并使用参数,

  • α-每个文档的参数向量(文档-主题分布)
  • η —每个主题的参数向量(主题—单词分布)

但是我们不能很好地计算这个,因为这个实体很难处理。我们如何解决这个问题?

我该如何解决这个问题?救援的变分推理

有很多方法可以解决这个问题。但是在这篇文章中,我将集中讨论变分推理。我们上面讨论的概率是一个非常棘手的后验概率(这意味着我们不能在纸上计算,也没有很好的方程)。所以我们要用一些已知的概率分布来近似这个值,这个概率分布和真实的后验概率非常接近。这就是变分推理背后的思想。

这样做的方法是最小化近似和真实后验之间的 KL 发散作为优化问题。同样,我不打算详细讨论,因为这超出了讨论范围。

但是我们将快速查看一下优化问题

γ、ϕ和λ分别代表我们用来逼近θ、 z 和β的自由变分参数。这里 D(q||p)代表 qp 之间的 KL 散度。并且通过改变γ,ϕ和λ,我们得到不同的 q 分布,其与真实后验 p 具有不同的距离。我们的目标是找到γ、ϕ和λ,使近似值 q 和真实后验值 p 之间的 KL 散度最小化。***

一切都很好地定义了,它只是一个迭代求解上述优化问题的问题,直到解决方案收敛。一旦有了γ、ϕ和λ,你就有了最终 LDA 模型所需的一切。***

包裹

本文讨论了潜在狄利克雷分配(LDA)问题。LDA 是一种强大的方法,它允许识别文档中的主题并将文档映射到这些主题。LDA 有许多用途,例如向顾客推荐书籍。

我们通过一个连接线程的例子看了 LDA 是如何工作的。然后,我们看到了基于 LDA 如何想象文档生成的不同视角。最后我们进入了模型的训练。在这篇文章中,我们讨论了 LDA 背后的大量数学知识,同时保持了数学的轻松。我们看了一下狄利克雷分布是什么样子,我们感兴趣的概率分布是什么(即后验分布),以及我们如何使用变分推理来解决这个问题。

我将发布一个关于如何使用 LDA 进行主题建模的教程,包括一些很酷的分析,作为另一个教程。干杯。

如果你喜欢我分享的关于数据科学和机器学习的故事,考虑成为会员吧!

**** [## 通过我的推荐链接加入媒体

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

thushv89.medium.com](https://thushv89.medium.com/membership)****

新的!加入我的新 YouTube 频道

如果你渴望看到我关于各种机器学习/深度学习主题的视频,请确保加入 DeepLearningHero

参考

这里有一些有用的参考资料,有助于理解 LDA 是否有什么不清楚的地方。

大卫·布莱教授的原始论文

直观的视频,解释 LDA 背后的基本理念

大卫·布雷教授的演讲

理解决策树的直观指南

原文:https://towardsdatascience.com/light-on-math-machine-learning-intuitive-guide-to-understanding-decision-trees-adb2165ccab7?source=collection_archive---------3-----------------------

点亮数学机器学习

Courtesy of Pixabay.com

介绍

本文旨在介绍决策树;广受好评的车型,如 xgboost 的流行构建模块。决策树就是一组层叠的问题。当您获得一个数据点(即一组特征和值)时,您使用每个属性(即数据点的给定特征的值)来回答一个问题。每个问题的答案决定了下一个问题。在这一系列问题的最后,您将获得数据点属于每个类别的概率。

:这篇文章在中等付费墙后面。不过代码是开源的,可以通过这个 链接 访问。

注 2 :这是关于数学机器学习 A-Z 的 光系列的第五篇博文。你可以在下面的信中找到以前的博客文章。

A BCD E FG*** H I JKL*** MNO P Q R S T U V****

*表示中等付费墙后面的文章

为什么是这篇文章?

让我们后退一步!既然有这么多文章解释决策树,你为什么要读这篇文章呢?需要强调的一点是,与我在互联网上找到的文章不同,这篇文章不会停留在高层次的解释上,让读者无所适从。相比之下,我会试着,

  • 提供模型功能的良好直觉,
  • 公正地对待这个模型的核心,
  • 解释过度拟合是如何发生的以及如何预防
  • 用例子来加强整个解释。

我还想提一个重要的警告!吸收本质的目的不是能够从头实现一个决策树(至少不是我所期望的),而是,

当您在实践中使用各种参数(大部分参数)时,很好地理解它们的含义

然而,我提供的代码是一个从零开始构建的决策树,旨在作为一个向导,让您看到整个过程。除了实际看到具体细节,还有什么更好的方法来获得更好的理解呢?

为什么选择决策树?

决策树之所以伟大,有几个原因。但是与任何模型一样,当您在合适的环境中使用模型时,真正的力量才会出现。记住,

垃圾进,垃圾出!

决策树之所以伟大,是因为

  • 它们很容易解释,并且遵循与人类思维相似的模式。换句话说,您可以将决策树解释为一组问题/业务规则。
  • 预测是。这是一组比较操作,直到到达一个叶节点
  • 可适用于处理缺失数据而无需输入数据

决策树入门:

正如我前面说过的,决策树基本上是一组级联问题(形成一棵树的形状)。这些问题测试数据的特征是否满足特定条件(例如,Outlook == Sunny?).让我们稍微充实一下。为此,让我们假设一个典型的天气数据集(我个人不喜欢这个天气数据集——太主流了,所以我稍后会切换到更令人兴奋的东西)。

假设我们有上述数据集,并希望预测在给定天气的情况下我们是否会打高尔夫球。此问题的决策树可能如下所示。

An example decision tree. Round nodes denote decision nodes, where square nodes denote leaf nodes

决策树的组成部分

让我给你上一堂简单的决策树剖析课。该树有决策节点(圆形)、决策(边)和叶/预测节点(方形)。您首先从一个决策节点(例如 Outlook)开始,根据答案,您可能会有一个叶节点或另一个决策节点(例如 Windy)。决策树可以对任意数量的决策节点继续下去。但是,每个分支都应该以一个叶节点结束。

用决策树进行预测

现在假设你有一个新的数据点,你想预测它的标签。

前景=晴朗,温度=炎热,湿度=正常,有风=真实

为了进行预测,您从树的顶部开始,使用属性(即特征值)沿树越来越深地遍历以做出决策,直到到达叶节点。这个过程描述如下。

我猜你不是在打高尔夫。

建造一棵树

当然,还有一个更重要的问题没有解决。

我们怎样才能找到这棵树?

更重要的是,

我们如何在给定的深度决定最佳的特征分区数据?

有几种不同算法用于生成树,

  • CART (分类和回归树)——使用基尼系数来决定划分特征
  • ID3 (使用信息增益-稍后讨论,以决定分区特征,并且不被设计成处理连续特征)
  • C4.5 (工作原理类似 ID3,利用信息增益拆分数据。然而,C4.5 可以处理连续特征,并且可以处理缺失数据****

现在让我们来解决一个更令人兴奋的虚构问题。我们想找到一个邪恶的国王,他正在威胁着树木之地的街道。

在街上找到伪装的国王

(数据和特征)

从这一节开始,我将用一个故事来解释决策树,这个故事讲的是一个喜欢在街上伪装自己来愚弄当地人的树之王。这很烦人,因为每当有人无意中对国王不好,他就会受到惩罚。人们很烦恼,一个聪明人(让我们称他为约翰)站出来说他能在 10 天内解决这个问题!

约翰具有国王的几个特征,在公众面前表现出与众不同的形象。其特点是,

  • 从城堡里出来
  • 慢慢走
  • 每天吃 5 次或更多
  • 有一颗金牙

约翰开始观察人们,并创建一个数据集(每人一个数据点)以及目标变量(即,这个人实际上是不是国王)。他有以下的观察。不幸的是,这个数据集是以五个人的痛苦为代价的。

利用这个数据集,John 做了以下工作。他根据目标变量写下每个特征,并根据以下逻辑突出显示每个条目:

  • 绿色-如果属性与相应的标签匹配
  • 红色-如果属性与相应的标签不匹配

John’s whiteboard

现在,看上面的表,我们可以了解哪些特征对正确预测国王贡献最大。例如,下图总结了上表中的观察结果。

Summary of the observations from the highlighted tables

直觉还不足以让你解决问题。您需要可量化的指标来表明这些特性是强大的。事实上,TreeLand 一半的公民都是机器学习工程师!这就是信息增益的来源。

信息增益:通过拆分数据获得了多少信息?

我们已经讨论过,树背后的基本思想是提出一个问题(即针对一个属性测试数据),并根据答案(例如对或错)分割数据。信息增益通过根据决策节点提供的答案分割数据来衡量数据变得可预测的程度(或获得了多少信息)。戴上你的科学护目镜,是时候正式化了。对数据 Y 使用特征 F 获得的信息由下式定义:

IG(Y,F) = H(Y)-H(Y|F)

其中 Y 为目标变量, F 为某特征(如金牙)。因此,功能越强大,通过分割该功能上的数据获得的信息就越多。H(Y)是 Y 的熵,H(Y|F)是以 F 为条件的 Y 的条件熵(稍后讨论)。在代码中,计算信息增益如下所示。

现在让我们看看什么是熵和条件熵。

熵和条件熵

熵衡量转换数据需要多少位。因此,数据越可预测,所需的位数就越少。相反,你的数据越不可预测,你需要的比特就越多。这是这样写下来的:

其中(Y 中的 Y)表示 Y 中的唯一结果(例如,在我们的示例中,King = True 或 False)。您可以很容易地用 Python 实现这一点。

通俗地说就是熵

让我们更直观地理解熵。比方说国王一开始就决定绝不愚弄当地人,约翰决定收集数据来解决这个问题。他的熵应该为零。为什么?因为标签是 100%可预测的(即它总是 0)。但是,在我们的数据中,熵是最高的(即 1),因为一个人成为国王或不是国王的机会是相等的。

想象两个人(约翰和丽莎)通过电话交谈。每次 John 呼叫 Lisa 时,Lisa 必须在没有任何附加信息的情况下,针对每个数据点(即 10 次)说出它是否是国王。下面我描述了不同熵值下的对话。

Difference of different entropy values

通俗地说就是条件熵

这很好地为解释什么是条件熵(即 H(Y|F ))奠定了基础。现在想象一下,对于每个数据点,约翰告诉这个人是否有一颗金牙。然后,根据特征值(即 F),Lisa 必须预测这是否是王。如果您查看下表,数据现在比没有任何特征更可预测。

From Jonh’s whiteboard

总之,信息增益的作用是,

它测量在提供关于特征 F 的信息之前和之后的可预测性的差异。

再次提醒我们,这是信息增益的公式。

IG(Y,F) = H(Y)-H(Y|F)

与此同时,在树木之乡…

(构建树)

约翰计算了 城堡金牙 的信息增益,发现它们比贪婪 好得多。然后约翰首先挑选了特征“ 城堡 ”。

Tree with the feature “Castle”

他对左边很满意。他认为,“4/6 分类还不错”。鉴于他只有 10 个数据点,我们会放他一马。但是右侧的结果很差(即 50%正确或 50%错误)。他需要改进结果,所以他继续尝试使用给出最高信息增益的特征来分割左边的余数,结果是" 金牙 "特征,并获得以下结果。

Tree with both “Castle” and “Gold Tooth” features

所以你走吧!约翰找到了秘制调味汁!这实际上就是 ID3 算法 的工作原理。更正式地说,你会有下面的伪代码。

Peseudocode

这段代码中最重要的函数是 build_tree ,实际上应该是这样的(可以在代码中找到)。

Treeland 的市民又可以放松了…

所以在约翰展示了他的成果后,人们被深深打动了。但是约翰知道更多的数据不仅会改进他的模型,还会验证他的发现。所以他让别人帮他收集更多的数据。但他不知道,他这样做会遇到问题。

这棵树长得太多了…

(过度拟合和正则化)

因此,约翰设法让几个人支持他的想法,扩大数据集并改进模型。他们设法让数据集达到 50 个数据点。因此,在收集数据后,梦想着一个更好更健壮的模型,约翰创造了一个新的树。这是他得到的树。

New decision tree

这棵树立刻在约翰的脑海中升起了危险信号。树太复杂了,无法解决这个问题。在一个简单的树形结构中,只需要两到三个特性就足够了。这里发生了什么?这叫 过拟合 !John 没有使用任何规则来控制树的复杂性,导致产生了一个非一般化和不可解释的树模型,这违背了目的。

让我们回头纠正约翰的错误

有几种方法可以防止树模型中的过度拟合。在这一节中,我将讨论三种方法。它们是:

  • 确保每个叶节点至少有 n 个数据点
  • 确保树的深度不超过 d
  • 确保信息增益大于阈值以进行分割

确保每个叶节点在一个叶节点中至少有 n 个数据点是很重要的。因为,通过将单个数据点分配给树中的每个叶节点,您可以为任何训练集构建世界上最完美的树(严重过度拟合)。因此,确保至少有 n 个数据点(例如 5%的数据)会导致更一般化的树模型。

确保树不会呈指数增长,将再次保护我们避免过度拟合。在这种方法中,我们基本上是限制我们可以问的问题的数量来预测模型的类别,这导致选择最好的几个问题来问,而不是问世界上所有可能的问题。

最后一点,确保信息增益高于阈值应该是有意义的。因为,如果我们不能从中获益,种这棵树又有什么意义呢?

因此,在修改这些技术并将其应用于模型后,John 提出了以下模型,该模型更具解释力。

Regularised tree

我不打算重复用树来预测,因为这个过程非常简单。这可以使用如下递归函数在 Python 中实现。

我们以此结束了在树岛的冒险。总之,John 收集了数据,建立了一个初始模型,使用信息增益来决定有价值的特征。遇到了过度拟合的问题,并使用正则化解决了它。好消息是,他们已经学会使用 John 开发的模型来避免 king 处理错误的方式。所以他们从此幸福地生活在一起!

使用连续值

到目前为止,我们仅限于观察离散变量。但是你只能用离散变量做很多事情。有趣的问题通常混合了连续变量和离散变量。那么怎样才能在决策树中使用连续变量呢?有两种流行的方式。

  • 通过宁滨将连续要素的范围离散化为相等的条柱
  • 使用 最小熵分割【2】在连续特征中寻找分裂

最小熵分割

最小熵分割(MEP)的工作方式如下。

  • 首先,根据数据分布的范围指定一组切割点(例如,在 T 个位置平均分布切割范围)
  • 然后,对于每个切割点,计算标签 Y 的熵的加权和
  • 选择给出最小熵的切割点

包裹

在本文中,我们详细讨论了决策树。决策树是一种流行的机器学习模型,因为它们更容易解释(例如,与神经网络相比),并且通常提供良好的性能,尤其是在与集成(打包和提升)一起使用时。

我们首先以玩具天气数据集为例,简要讨论了决策树的功能。然后,我们跳到了一个更生动的问题,那就是确定令人讨厌的树地之王是否正在恐吓街道。我们看到了约翰如何使用信息增益来识别有助于识别国王的特征,并随后使用这些特征构建了一个树。后来,我们看到随着数据集变大,诸如“过度拟合”等问题是如何出现的。我们还讨论了如何使用各种正则化方法(例如限制树的最大深度)来防止过拟合。最后,我们结束了在 TreeLand 的冒险,并做了一个快速的边游,看看如何在决策树中处理连续特征。

这篇文章的代码可以在 这里 找到。

参考

[1]CMU 讲稿

[2] 用于分类学习的连续值属性的多区间离散化

Video from Google Developers Youtube Channel

Video from Stanford

理解 KL 分歧的直观指南

原文:https://towardsdatascience.com/light-on-math-machine-learning-intuitive-guide-to-understanding-kl-divergence-2b382ca2b2a8?source=collection_archive---------0-----------------------

点亮数学机器学习

我正在开始一系列新的博客文章,遵循初学者友好的方法来理解机器学习中一些具有挑战性的概念。首先,我们将从 KL 散度开始。

代号: 此处

本系列的其他文章可以在下面找到。

A BCD* E FG* H I J KL* MNO P Q R S T U V****

*表示中等付费墙后面的文章

概念基础

首先,让我们建立一些基本规则。我们将定义一些我们需要知道的事情,比如我们的手背来理解 KL 散度。

什么是发行版

所谓分布,我们指的是不同的东西,如数据分布或概率分布。这里我们感兴趣的是概率分布。想象你在一张纸上画两条轴(即 XY ),我喜欢把一个分布想象成两条轴之间掉下来的一根线;X和Y。 X 表示您有兴趣获取概率的不同值。 Y 代表在 X 轴上观察到某个值的概率(即 y=p(x) )。我在下面想象这一点。****

这是一个连续的概率分布。例如,将轴 X 想象为一个人的高度,将轴 Y 想象为找到具有该高度的人的概率。

如果你想使这种概率分布离散,你可以把这根线切成固定长度的段,然后把这些段以水平的方式转动。然后创建连接每条线的边缘和 x 轴的矩形。这是一个离散的概率分布。

什么是事件?

对于离散概率分布,一个事件就是你观察到 X 取某个值(例如 X=1 )。我们姑且称 P(X=1) 事件发生的概率 X=1 。在连续空间中你可以把这想象成一个数值范围(例如0.95<X<1.05)。请注意,事件的定义不限于 x 轴上的值。然而,考虑到这一点,我们可以继续前进。

回到 KL 分歧

为了从这一点继续下去,我将谦虚地使用这篇博文【1】中的例子。这是一篇解释 KL 分歧的很好的文章,但是我觉得解释中的一些错综复杂之处可以解释得更详细一些。好了,我们开始吧。

我们试图解决的问题

因此,在[1]中解决的问题的要点是,我们是一群访问广阔的外层空间的科学家,我们发现了一些太空蠕虫。这些太空蠕虫有不同数量的牙齿。现在我们需要将这些信息发送回地球。但是从太空向地球发送信息是昂贵的。所以我们需要用最少的信息量来表达这些信息。一个很好的方法是,我们不记录单个的数字,而是画一个图,其中 X 轴是已经观察到的不同齿数( 0,1,2,…,等等)。)并使 Y 轴看到一个带 x 多齿的蜗杆的概率(即带 x 齿的蜗杆数/蜗杆总数 )。我们已经把我们的观察转换成一个分布。

这种分发比发送单个蠕虫的信息更有效。但是我们可以做得更好。我们可以用一个已知的分布(如均匀分布、二项式分布、正态分布等)来表示这个分布。).例如,如果我们用均匀分布来表示真实分布,我们只需要发送两条信息就可以恢复真实数据;蠕虫的均匀概率和数量。但是我们如何知道哪种分布更好地解释了真实的分布呢?这就是 KL 分歧的来源。

直觉:KL 散度是衡量两个分布(例如线程)之间匹配的一种方式

因此,我们可以使用 KL 散度来确保我们将真实分布与一些解释简单且众所周知的分布很好地匹配。

让我们改变例子中的一些东西

为了能够检查数值的正确性,让我们将概率值改为更人性化的值(与[1]中使用的值相比)。我们将做如下假设。假设我们有 100 条虫子。我们有以下数量的蠕虫。

  • 0 齿:2(概率: p0=0.02
  • 1 齿:3(概率: p1=0.03
  • 2 齿:5(概率: p2=0.05
  • 3 齿:14(概率: p3=0.14
  • 4 齿:16(概率: p4=0.16
  • 5 齿:15(概率: p5=0.15 )
  • 6 齿:12(概率: p6=0.12 )
  • 7 齿:8(概率: p7=0.08 )
  • 8 齿:10(概率: p8=0.1 )
  • 9 齿:8(概率: p9=0.08 )
  • 10 齿:7(概率: p10=0.07 )

快速理智检查!让我们确保值加起来是 100,概率加起来是 1.0。

总蠕虫数= 2+3+5+14+16+15+12+8+10+8+7 = 100
总概率= 0.02+0.03+0.05+0.14+0.16+0.15+…。0.12+0.08+0.1+0.08+0.07 = 1.0

这是它的视觉效果。

第一次尝试:用均匀分布建模

现在,让我们先试着用均匀分布来模拟这个分布。均匀分布只有一个参数;一致概率;给定事件发生的概率。

p _ uniform = 1/总事件数=1/11 = 0.0909

这就是均匀分布和真正的并排分布的样子。

让我们把这个结果放在一边,我们将用另一种类型的分布来模拟真实的分布。

第二次尝试:用二项式分布建模

通过计算一枚硬币正面落地的概率,你可能对二项式概率很熟悉。我们可以把同样的概念推广到我们的问题上。对于一枚硬币,你有两种可能的输出,假设硬币正面落地的概率是 p ,你运行这个实验进行 n 次试验,获得 k 成功的概率由下式给出:

打破平衡

让我们顺便了解一下二项分布中的每一项,看看它们是否有意义。第一任是 p^k 。我们要获得 k 的成功,其中单次成功的概率是 p 。那么获得 k 成功的概率就是。请记住,我们正在为 n 试验运行实验。因此,会有 n-k 次失败的试验,失败概率为【1-p】。所以获得 k 成功的概率是pk(1-p)的联合概率。我们的工作不会就此结束。 k 试验可以在 n 试验中进行不同的排列。要在空间内排列的不同排列 k 元素的数量由下式给出:**

将所有这些相乘,我们得到了成功的二项式概率。

二项分布的均值和方差

我们还可以定义二项分布的均值和方差。这些是由,

均值= np
方差= np(1-p)

意思反映了什么?Mean 是您运行 n 次试验后获得的预期(平均)成功次数。如果每次试验的成功概率为 p ,那么可以说如果你进行 n 次试验,你将获得 np 次成功。接下来方差代表什么?它表示成功试验的真实次数偏离平均值的程度。为了理解方差,让我们假设 n=1 。那么方程就是, 方差=p(1-p) 。当 p=0.5 (获得正面和反面的可能性相等)时,方差最高;当 p=1p=0 (肯定获得正面/反面)时,方差最低。

回到建模

现在有了对二项分布的坚实理解,让我们回到我们手头的问题。让我们先计算一下蠕虫的预期齿数。那会是,

已知均值,我们可以计算出 p 其中,
均值= NP
5.44 = 10p
p = 0.544

注意比 n 是从蠕虫种群中观察到的最大齿数。你可能会问为什么我们没有选择 n 作为蠕虫总数(即 100 )或者事件总数(即 11 )。我们很快就会看到原因。有了这个,我们可以定义任意数量的牙齿的概率如下。

鉴于牙齿可以取值到 10,那么看到 k 颗牙齿的概率是多少(其中看到一颗牙齿就是试验成功)。

从抛硬币的角度来看,这就像在问,

假设我有 10 次翻转,观察到 k 头的概率是多少。

形式上,我们计算所有不同的 k 值的概率。这里 k 成为我们要观察的齿数。而【pk^{bi}】则是第 k 个齿仓的二项概率(即 0 齿、1 齿等)。).所以当我们如下计算它们时,**

p0^{bi} = (10!/(0!10!))0.544⁰(1–0.544)^{10} = 0.0004
p1^{bi} =(10!/(1!9!))0.544(1–0.544)⁹= 0.0046
p2^{bi} =(10!/(2!8!))0.544(1–0.544)⁸= 0.0249

……
p9^{bi} =(10!/(9!1!))0.544⁹(1–0.544)= 0.0190
p10^{bi} =(10!/(10!0!))0.544^{10}(1–0.544)⁰= 0.0023

这是真实分布和二项分布的比较。

让我们总结一下我们所拥有的

**好吧,回头想想我们到目前为止做了什么。首先我们理解了我们想要解决的问题。问题是用最少的努力把某种太空蠕虫牙齿的统计数据发送到整个空间。为此,我们考虑用一些已知的分布来表示蠕虫的真实统计数据,因此我们可以只发送该分布的参数,而不是真实统计数据。我们研究了两种类型的分布,得出了以下统计数据。

均匀分布—概率为 0.0909
二项分布—其中 n=10p=0.544k 取 0 到 10 之间的不同值

现在让我们在一个地方可视化一切

我们如何定量地决定哪些是最好的?

有了这些复杂的计算,我们需要一种方法来衡量每个近似分布与真实分布之间的匹配程度。这一点很重要,这样,当我们传递信息时,我们可以安心,不用担心“我的选择正确吗?”在我们的余生中。

这就是 KL 背离的由来。KL 散度的正式定义如下。

这里的是近似值,而 p(x) 是真实分布,我们感兴趣的是匹配【q(x)来。直观地,这测量了给定的任意分布与真实分布的偏差。如果两个分布完全匹配,[D _ { KL }(p | | q)= 0否则可以取 0 之间的值。KL 散度值越低,我们将真实分布与我们的近似值匹配得越好。

KL 背离的直观分解

让我们一块一块来看 KL 发散。先取log(p(x _ I)/q(x _ I))分量。如果 q(x_i) 高于 p(x_i) 会怎么样?那么这个组件将产生一个负值(因为小于 1 的 log 值是负值)。另一方面,如果 q(x_i) 总是小于 p(x_i) 这个分量将产生正值。只有当p(x _ I)= q(x _ I)时,该值才会为零。然后为了使这成为一个期望值,你用 p(x_i) 对 log 分量进行加权。这意味着, p(x_i) 概率较高的匹配区域比 p(x_i) 概率较低的匹配区域更重要。

直觉上,优先正确匹配近似值中的真正高概率事件是有意义的。从数学上讲,这允许您自动忽略位于真实分布支持面(支持面是分布使用的 x 轴上的全长)之外的分布区域。此外,这避免了计算 log(0) 如果您试图计算超出真实分布支持范围的任何区域的 log 分量,将会出现这种情况。

计算 KL 散度

现在让我们计算我们得到的每个近似分布的 KL 散度。首先让我们来看看均匀分布。

现在对于我们得到的二项分布,

关于二项式均值的 KL 散度

现在让我们来玩一下 KL 散度。首先,我们将看到当二项分布的成功概率改变时,KL 散度是如何变化的。不幸的是,我们不能对均匀分布做同样的事情,因为我们不能改变概率,因为 n 是固定的。

你可以看到,随着我们远离我们的选择(红点),KL 散度迅速增加。事实上,如果你打印一些与我们的选择相差很小的 KL 散度值δ,你会看到我们选择的成功概率给出了最小的 KL 散度。

现在我们对 KL 散度的讨论到此结束。

结论

现在我们有了一些可靠的结果,虽然均匀分布看起来很简单,没有什么信息,而二项式分布更微妙,但均匀分布比二项式分布更符合真实分布。说实话,这个结果其实让我很意外。因为我期望二项式能更好地模拟真实分布。因此,这给了我们一个重要的教训,那就是为什么我们不应该只相信我们的直觉!

代码:此处

KL divergence 的乐趣

你可以通过玩 KL 散度来获得更多的乐趣,从而更好地理解 KL 散度。你可以在我的博客中了解更多。

参考

[1]https://www . countbayesie . com/blog/2017/5/9/kull back-lei bler-divergence-explained

注意:请去我的网站看看,因为我也在那里贴了更多机器学习的东西。

****小提示:我很高兴地宣布,我的关于使用 TensorFlow 进行自然语言处理的书已经出版了,供大家购买!这本书非常适合寻求基于现代深度学习的解决方案的实用视角的初级/中级读者。这本书附有指导读者实现各种 NLP 应用的练习。你可以在 Packt 网站或者亚马逊找到。

理解 Word2vec 的直观指南

原文:https://towardsdatascience.com/light-on-math-machine-learning-intuitive-guide-to-understanding-word2vec-e0128a460f0f?source=collection_archive---------5-----------------------

点亮数学机器学习

数学机器学习系列 之光 A-Z 的第三篇博文来了。这篇文章是关于 Word2vec 算法的。Word2vec 算法输出单词向量。单词向量是许多自然语言处理(NLP)系统的基础,这些系统已经风靡全球(亚马逊 Alexa、谷歌翻译等)。).我们将在接下来的章节中讨论细节。但是首先让我拼出我的其他博客文章的链接的字母表。

A BCD* E FG* H I JK****L*** M**N****

*表示中等付费墙后面的文章

词向量,有什么大的想法?这都是关于环境的

没有进一步的理由,让我们坚持到底。单词向量是单词的数字表示,保留单词之间的语义关系。例如单词 的向量,就会和单词 的向量非常相似。然而, 铅笔 的矢量将与 的单词矢量大相径庭。而这种相似性是由两个被讨论的词(即[ 猫、 狗]或[ 猫、 )在同一语境中使用的频率来定义的。例如,考虑下面的句子,

以上句子中的奇数我觉得没必要拼出来,明显是带 铅笔 的,作为漏字。为什么你觉得这是个奇怪的句子?拼写没问题,语法没错,那为什么?就是因为 上下文 ,铅笔 一词 使用不正确。这应该让你相信一个词的上下文对这个词本身的影响。单词向量算法使用单词的上下文来学习单词的数字表示,使得在相同上下文中使用的单词具有相似的单词向量。

Word2vec 的影响和含义

要了解 Word2vec 技术的含义,请尝试以下方法。继续,调出谷歌学者。键入一些与自然语言处理相关的任务(如问答、聊天机器人、机器翻译等)。过滤 2013 年以后发表的论文(Word2vec methods 就是那时候出的)。得到使用词向量的论文占论文总数的比例。我打赌这个比例会很高。为了使陈述具体化,单词向量被用于,

  • 语言建模
  • 聊天机器人
  • 机器翻译
  • 问题回答
  • …以及更多

你可以看到所有令人兴奋的自然语言处理前沿实际上严重依赖于词向量。现在让我们讨论一下单词向量有什么样的含义可以使模型更好。当使用单词向量时,语义上接近的单词将在模型中表现为相似的计算,而其他单词将表现为进行不同的计算。这是一个值得拥有的属性,因为在输入本身中编码这样的信息会导致模型以较少的数据执行得很好。

从原始文本到词向量:高级方法

现在,有了可靠的直觉,我们将首先讨论 Word2vec 算法的高级机制。我们将在后面的小节中完善细节,直到我们确信我们知道如何实现 Word2vec 算法。为了以无人监督的方式(即没有人类标记数据)学习单词向量,我们必须定义并完成某些任务。以下是这些任务的高级列表。

  1. 从原始文本创建格式为[输入字,输出字]的数据元组,其中每个字被表示为一个热向量
  2. 定义一个模型,该模型可以将独热向量作为输入和输出来训练
  3. 定义一个损失函数来预测正确的单词,该单词实际上在输入单词的上下文中,以优化模型
  4. 通过确保相似的单词具有相似的单词向量来评估模型

这个看似简单的程序将导致学习非常强大的单词向量。让我们来看看上述流程中每一步的细节。

从原始文本创建结构化数据

这不是一项非常困难的任务。这是对原始文本进行简单处理,将其转换成特定的结构。想想下面这句话。

猫把玻璃从桌子上推了下来

从这句话中创建的数据如下所示。句子后面的每一行代表一个数据点。蓝框代表一键输入词( 中间词,称为目标词 ),红框代表一键输出词( 上下文窗口中除中间词以外的任何词,称为上下文词 )。从单个上下文窗口创建两个数据点。上下文窗口的大小是由用户定义的。上下文窗口越大,模型的性能越好。但是当上下文窗口很大时,随着数据量的增加,您将付出计算时间的代价。不要把目标词和目标(正确输出)混淆对于神经网络来说,这是两个完全不同的东西。**

Creating data for Word2vec

定义嵌入层和神经网络

用于从上面定义的结构化数据中学习的神经网络。然而,它伴随着一个转折!为了清楚起见,您有以下组件。

  • 表示为独热向量的一批输入
  • 表示为一个热点向量的一批输出(仅在训练阶段)
  • 嵌入层
  • 神经网络

如果您不知道最后两个组件是什么以及如何执行的,也没有必要害怕。我们将探究这些组件中的每一个,以了解它们的作用。

嵌入层:存储所有的单词向量

我们议程中的第一个是 嵌入层 。嵌入层存储在词汇表中找到的所有单词的单词向量。可以想象这是一个巨大的矩阵(大小为 【词汇大小 x 嵌入大小】 )。这个嵌入大小是用户可调的参数。它越高,模型的性能就越好。但是超过某一点(比如,嵌入大小为 500),您将不会获得太多令人惊讶的性能/大小增益。这个巨大的矩阵被随机初始化(就像神经网络一样),并在优化过程中一点一点地调整,以显示强大的单词向量。这是它看起来的样子。

What the embedding layer looks like

神经网络:将单词向量映射到输出

接下来是我们模型的最后一块乐高积木;神经网络。在训练期间,神经网络获取输入单词并尝试预测输出单词。然后,使用损失函数,我们惩罚错误分类的模型,奖励正确分类的模型。我们将把我们的对话限制在一次处理一个输入和一个输出。然而在现实中,您是成批处理数据的(比如说,64 个数据点)。让我们描述一下培训中使用的确切流程:

  1. 对于给定的输入单词(目标单词),从嵌入层中找到相应的单词向量
  2. 将单词向量输入神经网络,然后尝试预测正确的输出单词(上下文单词)
  3. 通过比较预测和真实上下文单词,计算损失
  4. 使用损失和随机优化器来优化神经网络和嵌入层

需要注意的一点是,在计算预测时,我们使用 softmax 激活将预测标准化为有效的概率分布。

将所有内容组合在一起:从输入到模型到输出

知道了 Word2vec 算法的所有细节,我们就可以把所有的部分放在一起了。这样一旦训练好这个模型,我们要做的就是 把嵌入层保存到磁盘 。然后,我们可以在一天中的任何时间享受语义保留的单词向量。下面我们来看看完整的图片是什么样子的。

How the model looks at its final form

这种数据和模型布局的特殊排列被称为 跳格算法;一个 Word2vec 算法。这就是我们要关注的。另一种算法被称为连续词袋(CBOW)模型。

定义损失函数:优化模型

到目前为止,我们还没有讨论的一个重要信息是损失函数,但它是必不可少的。通常,标准的 softmax 交叉熵损失对于分类任务来说是一个很好的损失函数。对于 Word2vec 模型来说,使用这个损失是不太实际的,因为对于一个更简单的任务,比如情绪分析(其中你有两个可能的输出:正面或负面)。在这里,事情会变得很古怪。在消耗数十亿个单词的真实单词任务中,词汇量可以很容易地增长到 100,000 或更多。这使得 softmax 归一化的计算量很大。这是因为 softmax 的完整计算需要计算关于所有输出节点的交叉熵损失。

所以我们要用一个更聪明的替代方案,叫做 采样 softmax 损耗 。在采样的 softmax 损失中,执行以下操作。请注意,与标准的 softmax 交叉熵损失相比,有相当多的变化。首先,计算给定目标单词的真实上下文单词 ID 和对应于真实上下文单词 ID 的预测值之间的交叉熵损失。然后,我们添加根据一些噪声分布采样的K负样本的交叉熵损失。概括地说,我们将损失定义如下:

SigmoidCrossEntropy是我们可以在单个输出节点上定义的损耗,与其余节点无关。这对于我们的问题来说非常理想,因为我们的词汇量会变得很大。我不打算深究这次损失的细节。您不需要了解这是如何实现的,因为这些是 TensorFlow 中的内置函数。但是了解损失中涉及的参数(例如K)是很重要的。要点是,采样的 softmax 损耗通过考虑两种类型的实体来计算损耗:

  • 由预测向量中的真实上下文单词 ID(上下文窗口内的单词)给出的索引
  • K指示单词 id 的索引,并且被认为是噪声(上下文窗口之外的单词)

我通过一个例子进一步形象化了这一点。

Getting positive and negative samples for the sampled softmax layer

张量流实现:Skip-gram 算法

在这里,我们将把我们刚刚讨论的内容放入一个实现中。此处 可作为练习 。在本节中,我们将实现以下内容。

  • 数据生成器
  • 跳格模型(带张量流)
  • 运行跳格算法

数据生成程序

首先让我们了解如何生成数据。我们不打算深入研究这段代码的细节,因为我们已经讨论了数据生成的内部机制。这只是将逻辑转换为实现。

****def** generate_batch(batch_size, window_size):
  **global** data_index 

  *# two numpy arras to hold target words (batch)*
  *# and context words (labels)*
  batch = np.ndarray(shape=(batch_size), dtype=np.int32)
  labels = np.ndarray(shape=(batch_size, 1), dtype=np.int32)

  *# span defines the total window size*
  span = 2 * window_size + 1 

  *# The buffer holds the data contained within the span*
  queue = collections.deque(maxlen=span)

  *# Fill the buffer and update the data_index*
  **for** _ **in** range(span):
    queue.append(data[data_index])
    data_index = (data_index + 1) % len(data)

  **for** i **in** range(batch_size // (2*window_size)):
    k=0
    *# Avoid the target word itself as a prediction*
    **for** j **in** list(range(window_size))+list(range(window_size+1,2*window_size+1)):
      batch[i * (2*window_size) + k] = queue[window_size]
      labels[i * (2*window_size) + k, 0] = queue[j]
      k += 1 

    *# Everytime we read num_samples data points, update the queue*
    queue.append(data[data_index])

    *# If end is reached, circle back to the beginning*
    data_index = (data_index + np.random.randint(window_size)) % len(data)

  **return** batch, labels**

定义跳格模型

首先,我们将定义模型所需的一些超参数。

**batch_size = 128 
embedding_size = 64 
window_size = 4 
num_sampled = 32 # Number of negative examples to sample.**

batch_size定义了在给定时间我们处理的数据点的数量。那么embedding_size就是一个字向量的大小。下一个超参数window_size定义了我们上面可视化的上下文窗口的大小。最后num_sampled定义损失函数中负样本的数量(K)。然后我们为输入和输出定义张量流占位符。

**tf.reset_default_graph() 
# Training input data (target word IDs). 
train_dataset = tf.placeholder(tf.int32, shape=[batch_size]) # Training input label data (context word IDs) 
train_labels = tf.placeholder(tf.int32, shape=[batch_size, 1])**

这里,train_dataset获取一个代表一组选定目标单词的单词 id 列表batch_size。最后,train_labels表示所选目标单词的相应上下文单词的batch_size列表。接下来,我们定义定义模型所需的模型参数:嵌入层以及神经网络的权重和偏差。

***################################################*
*#            Model variables                   #*
*################################################*

*# Embedding layer*
embeddings = tf.Variable(tf.random_uniform([vocabulary_size, embedding_size], -1.0, 1.0))

*# Neural network weights and biases*
softmax_weights = tf.Variable(
    tf.truncated_normal([vocabulary_size, embedding_size],
                        stddev=0.1 / math.sqrt(embedding_size))
)
softmax_biases = tf.Variable(tf.random_uniform([vocabulary_size],-0.01,0.01))**

我们将嵌入层定义为一个 TensorFlow 变量:embeddings。然后我们定义神经网络权重(softmax_weights)和偏差(softmax_biases)。此后,我们定义将嵌入层连接到神经网络所需的关键操作,以联合优化嵌入层和神经网络。

**# Look up embeddings for a batch of inputs. 
embed = tf.nn.embedding_lookup(embeddings, train_dataset)**

tf.nn.embedding_lookup函数将我们的嵌入层作为输入和一组单词 id(train_dataset),并将相应的单词向量输出到变量embed。定义了嵌入查找函数,我们可以定义上面讨论的采样 softmax 损失函数。

**################################################ 
#              Computes loss                   # 
################################################ 
loss = tf.reduce_mean(tf.nn.sampled_softmax_loss( weights=softmax_weights, biases=softmax_biases, inputs=embed, labels=train_labels, num_sampled=num_sampled, num_classes=vocabulary_size) )**

这里,tf.nn.sampled_softmax_loss函数接受一组权重(softmax_weights)、偏差(softmax_biases)、对应于在train_dataset中找到的单词 id 的一组单词向量、正确上下文单词的 id(train_labels)、噪声样本的数量(num_sampled)和词汇的大小(vocabulary_size)。有了输出计算操作和定义的损耗,我们可以定义一个优化器来优化关于嵌入层和神经网络的参数的损耗。

**################################################ 
#                 Optimization                 # 
################################################ 
optimizer = tf.train.AdamOptimizer(0.001).minimize(loss)**

然后,我们通过使向量幅度等于 1 来获得归一化的嵌入层。

**################################################ 
#                For evaluation                # ################################################ 
norm = tf.sqrt(tf.reduce_sum(tf.square(embeddings), 1, keepdims=True)) 
normalized_embeddings = embeddings / norm**

运行代码

这里我们将讨论如何运行之前定义的张量流模型的细节。首先我们定义一个session,然后随机初始化所有的张量流变量。

**num_steps = 250001 
session = tf.InteractiveSession() 
# Initialize the variables in the graph
tf.global_variables_initializer().run() 
print('Initialized') 
average_loss = 0**

现在,对于预定义数量的步骤,我们生成批量数据:目标单词(batch_data)和上下文单词(batch_labels)。

**for step in range(num_steps): 
    # Generate a single batch of data
    batch_data, batch_labels = generate_batch( batch_size, window_size)**

然后,对于每个生成的批处理,我们通过运行session.run([optimize, loss],...)来优化嵌入层和神经网络。我们还得出最终的损失,以确保它随着时间的推移而减少。

 ***# Optimize the embedding layer and neural network*
    *# compute loss*
    feed_dict = {train_dataset : batch_data, train_labels : batch_labels}
    _, l = session.run([optimizer, loss], feed_dict=feed_dict)**

在这里,每 5000 步,我们打印平均损失,作为视觉辅助。

 ****if** (step+1) % 5000 == 0:
      **if** step > 0:
        average_loss = average_loss / 5000

      print('Average loss at step **%d**: **%f**' % (step+1, average_loss))
      average_loss = 0**

最后,我们得到最终的嵌入,我们稍后使用它来可视化某些单词。

**sg_embeddings = normalized_embeddings.eval() 
session.close()**

最后,如果您使用像 t-SNE 这样的流形学习算法来可视化嵌入,您将得到以下结果。

正如你所看到的,与猫相关的单词是沿着某个方向找到的,而与狗相关的单词是沿着不同的方向找到的。介于这两个方向之间的单词(例如动物或宠物)正是我们所需要的。

结论

我们的谈话就此结束。单词向量是一种非常强大的单词表示,有助于机器学习模型更好地执行。我们经历了数据生成过程以及 Word2vec 模型中的不同组件。然后我们讨论了 Word2vec 算法的一个特定变体;跳过 gram 模型。我们在 TensorFlow 中实现了该算法。最后,我们可视化了嵌入,看到学习到的嵌入实际上描述了一些有用的语义。你可以在这里 找到练习文件

如果你喜欢我分享的关于数据科学和机器学习的故事,考虑成为会员吧!

**** [## 通过我的推荐链接加入媒体

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

thushv89.medium.com](https://thushv89.medium.com/membership)****

想在深度网络和 TensorFlow 上做得更好?

检查我在这个课题上的工作。

[1] (书)TensorFlow 2 在行动——曼宁

[2] (视频课程)Python 中的机器翻译 — DataCamp

[3] (书)TensorFlow 中的自然语言处理 1 — Packt

闪电谈话:使用 HDBScan 进行集群

原文:https://towardsdatascience.com/lightning-talk-clustering-with-hdbscan-d47b83d1b03a?source=collection_archive---------1-----------------------

最近,我应邀就一种叫做 HDBScan 的聚类算法做了一个简短的演讲。HDBScan 基于 DBScan 算法,与其他聚类算法一样,它用于将相似的数据分组在一起。

Clustering with HDBScan

我在演讲中涉及了三个主题:HDBScan 的优点、实现以及它是如何工作的。

优势

常规 DBScan 在对不同形状的数据进行聚类方面非常出色,但在对不同密度的数据进行聚类方面却表现不佳。你可以去 Naftali Harris 的博客看看关于 DBScan 的文章,然后玩玩密度条散点图。

下面是 Naftali 网站上的密度条散点图的副本。你可以看到,有一个主要的中心集群和噪声在左边和右边。

Density Bars

玩了参数之后,下面是 DBScan 的表现。它能够得到中心星团,但也产生了许多没有多大意义的迷你星团。

Density Bars with DBScan Applied

下面是 HDBScan 的表现。我只能得到我正在寻找的一个集群。不幸的是,没有算法是完美的,它确实把一些噪声放到了紫色的簇中,但它比常规的 DBScan 更接近我所寻找的。

Density Bars with HDBScan Applied

除了更适合不同密度的数据,它还比常规的 DBScan 更快。下面是几个聚类算法的图表,DBScan 是深蓝色,HDBScan 是深绿色。在 200,000 记录点,DBScan 花费的时间大约是 HDBScan 的两倍。随着记录数量的增加,DBScan 和 hdb scan 性能之间的差异也会增加。

Source: http://hdbscan.readthedocs.io/

实现

HDScan 是一个独立于 scikitlearn 的库,所以你要么 pip 安装它,要么 conda 安装它。

两种算法都有最小样本数参数,该参数是记录成为核心点的邻居阈值。

DBScan 有一个参数 epsilon,它是那些邻居形成核心的半径。这是 DBScan 上图的 DBSCAN 实现(eps = 0.225,min_samples=4)。

HDBScan 的参数是最小集群大小,即集群需要多大才能形成。这比 epsilon 更直观,因为您可能知道您的集群需要多大才能做出可行的决策。这是 HDBScan 上图的 HDBSCAN 实现(min_samples=11,min_cluster_size=10,allow_single_cluster=True)。

工作原理

这两种算法都是从查找每个点的核心距离开始的,核心距离是该点与其由最小样本参数定义的最远邻居之间的距离。由于蓝点落在绿点的半径内,绿点可以捕捉蓝点作为其集群的一部分。然而,红点不在绿点的半径范围内,反之亦然,因此两个点都不能捕捉彼此(尽管它们可以通过其他点连接)。

Core Distances: http://hdbscan.readthedocs.io/

潜在的簇可以形成树状图,树状图上的 DBScan 的截止点是ε。

Expanded Dendogram: http://hdbscan.readthedocs.io/

HDBScan 以不同的方式处理这个问题,它丢弃微小的分支,而保留由最小簇大小参数定义的最大簇。这导致了一个更加浓缩的树突图,如下图所示。

Condensed HDBScan Dendogram

HDBScan 是为具有不同密度的数据的真实场景而构建的,它相对较快,并且允许您根据大小来定义哪些集群对您来说是重要的。总的来说,HDBScan 似乎是一个很棒的算法。如果您想要上面相应视频的我的幻灯片的链接,请单击此处

来源:

文件:【http://hdbscan.readthedocs.io/

使用 HDBSCAN 实现高性能集群:https://www.youtube.com/watch?v=AgPQ76RIi6A

可视化 DBScan 聚类:https://www . naftaliharris . com/blog/visualizing-DBS can-Clustering/

大学记忆会随着时间变好吗?

原文:https://towardsdatascience.com/like-wine-does-college-memories-improve-over-time-9136ebfb6d4e?source=collection_archive---------3-----------------------

大学真的那么棒吗,还是事后看来只是如此?

毕业季

5 月,全国各地的学生大学毕业。我在脸书的博客上充斥着帽子和礼服的自拍照、给家长的感谢信,以及对人们在学校时光的冗长反思。

呃。

我回到了大学时代——友谊、聚会,偶尔还有学习。

大学是一段神奇的时光,在这里你没有压力,没有责任,没有规则。日常生活中最困难的决定是晚餐是点披萨还是中餐。

或者是?

虽然大学现在看起来像是 4 年的假期,但我不确定当我入学时是否真的有这种感觉。当我熬夜到凌晨 2 点,把布莱克-斯科尔斯公式死记硬背的时候,我并不觉得大学有什么乐趣。当我拼命想找一份暑期实习时,我也没有感到特别没有压力。

我一直认为大学是我一生中最美好的时光,但当我开始反思我的大学经历时,我就不那么确定了。我开始想,我对大学的美好回忆有多少是因为大学真的很棒,又有多少是因为怀旧引发的回忆。

为了解决我的疑问,我决定进行一项调查。

耶,分析。

我招募了 317 名 4 年制本科项目的学生或毕业生。

除了典型的人口统计学问题(性别、年龄等。),我问人们他们什么时候/是否毕业,他们获得了什么学位或正在攻读什么学位(文学士、理学士等)。).

我还要求人们将他们的大学经历与典型的大学经历在五个方面进行比较:快乐、压力、有用性和价值。对于每项指标,每个人都给出了 1 到 10 分的评分,10 分明显高于平均水平,1 分明显低于平均水平,5 分是大学经历的平均水平。这让我可以比较不同的维度,并为每个人提供相同的基准,无论他们何时毕业。

我调查的 317 人中,女性 137 人,男性 179 人,还有 1 人是“其他”。在这些回复中,107 人是在校学生(目前正在参加 4 年制本科项目或在过去 6 个月内毕业),210 人是大学毕业生。

我结合使用 Python、Tableau 和优秀的老式 Excel,分析了这些回复。以下是研究结果:

人们认为他们是特殊的雪花,有着高于平均水平的大学经历。

所有五个维度的平均评分都高于 5 分,这是大学经历的基准。人们倾向于认为他们的大学经历高于平均水平,这并不奇怪,因为人们通常觉得他们在生活中高于平均水平。
“难度”指标最接近基准(平均评分:5.70),而每个人都觉得自己的大学经历格外“值得”(平均评分:6.47)。

一旦你毕业了,大学似乎就没那么困难、压力和有用了。

大学生和毕业生之间的三个指标在统计上有所不同:“难度”、“压力”和“有用性”。大学生的平均评分不仅高于基准,也高于毕业生。

换句话说,如果你在大学,你倾向于认为你的经历比已经毕业的人更困难、更有压力、更有用。

为什么?

假设一:大学变难了。

一个可能的解释是,随着时间的推移,大学经历实际上已经发生了变化。现在的学生认为大学更困难、更有压力、更有用,因为大学更困难、更有压力、更有用。

这种影响在调查中得到了控制,因为每个人都给出了相对于“典型的大学经历”的评级。如果随着时间的推移,大学变得更具挑战性,人们对“典型的大学经历”的定义也会随之改变。因此,虽然这种影响是可能的,但它不会导致学生和毕业生之间的评分差异。

假设 2:改变大学记忆

另一种可能的解释是,人们对大学的记忆发生了变化。我们的记忆就像高年级学生参加上午 9 点的课程一样可靠。研究表明,每当我们回忆起一件事的时候,我们的记忆就会发生变化,因此,也许有压力的记忆,比如大三生物期末考试,已经随着时间的推移变得柔和,改变了我们对大学经历的看法。

这个假设很难被完美地检验,但是如果记忆的改变已经显著地影响了大学毕业生的评分,你可能会期待不同的评分取决于他们毕业的时间。

我把大学毕业生分成两组——应届毕业生(毕业于 5 年或不到 5 年)和老毕业生(毕业于 10 年或 10 年以上)。然后我比较了他们的评分。

事实证明,这五个指标在统计上没有什么不同。因此,尽管我们的记忆被扭曲了,但这并不是收视率差异背后的主要驱动力。

假设 3:改变视角

第三种可能是毕业后人们对大学的视角发生了变化。改变的不是大学记忆,而是我们如何判断这些记忆。

大多数大学生几乎没有全职工作、支付账单或抚养家庭的经验。正因为如此,大学期间的每一个项目、作业和考试似乎都是一项艰巨的任务。

毕业时,毕业生意识到大学比“现实生活”更容易。因此,大学毕业生倾向于认为大学压力更小,更难,更有用,因为他们的标准已经提高了。

支持这一假设的一个指标是,在过去三年内毕业的人给大学的“难度”评级明显低于现在的学生(6.18 比 4.95)。三年的时间不足以让大学经历发生巨大变化,人们的记忆也不太可能被严重扭曲。这表明,在现实世界中呆上几年已经影响了人们对“困难”真正含义的定义。

大学和你记忆中的一样愉快,也值得每年 4 万美元的学费。

大学生和大学毕业生有两个相似的评价——快乐和有价值。我们认为我们享受大学生活的程度和我们实际享受大学生活的程度相当接近。阿瑟·罗斯有句名言“我爱大学”,显然,你永远不会忘记这句话。

虽然一旦人们毕业,有用性就会下降,但价值却不会下降。事实上,对于学生和毕业生来说,“有价值”相对于其他指标得分最高。显然,你是否会用你在莎士比亚哲学 101 中学到的东西并不影响你是否认为大学是值得的。

不同的人有不同的评价

比较男性和女性的评价,女性发现大学比男性压力更大,而“难度”在统计上没有差异。因此,学业似乎不是大学里唯一的压力来源——参加过新生入学迎新会的人都不会感到惊讶。

我也比较了不同的大学专业。大多数人要么追求文学学士,要么追求理学学士,所以我专注于这两个学位。两个学位都认为大学同样值得,但文学学士更有趣:更高的乐趣,更低的难度,更低的压力。这也不会让任何一个上过工程学课并在黑板上看到外语开发的人感到惊讶。

我需要一杯啤酒。

所以大学的某些方面在毕业后有所提高,而其他方面保持不变。有一件事是肯定的,当你可以的时候享受大学生活。这么多电影都是关于大学的,而几乎没有电影是关于保住一份工作并获得稳定收入的,这是有原因的。

有机会通过挖掘每个维度来建立这个调查:是什么让大学变得愉快?是什么让大学变得艰难?在兄弟会聚会上认识脸书的某个人后,在加他们为好友之前,应该等待多长时间?

但是现在,我想我需要一盏明亮的灯,打个盹。

你可能喜欢的其他文章

如果你喜欢这篇文章,请访问LateNightFroyo.com,阅读关于爱情、生活等话题的话题。

什么时候去参加聚会比较合适?

如何走出去?

多年轻才算年轻到不能约会?

用于深度学习的线性代数备忘单

原文:https://towardsdatascience.com/linear-algebra-cheat-sheet-for-deep-learning-cd67aba4526c?source=collection_archive---------0-----------------------

常用操作初学者指南

在杰瑞米·霍华德出色的深度学习课程中,我意识到我对先决条件有点生疏,我的模糊性影响了我理解反向传播等概念的能力。我决定就这些话题整理几个维基页面来提高我的理解。这里是深度学习中使用的一些更常见的线性代数运算的非常基本的介绍。:查看机器学习备忘单了解更多主题。

什么是线性代数?

在深度学习的背景下,线性代数是一个数学工具箱,为同时操作多组数字提供了有用的技术。它提供了像向量和矩阵(电子表格)这样的结构来保存这些数字,以及如何加、减、乘、除这些数字的新规则。

为什么有用?

它把复杂的问题变成简单、直观、有效计算的问题。这是一个线性代数如何实现更快的速度和更简单的例子。

*# Multiply two arrays* 
x = [1,2,3]
y = [2,3,4]
product = []
for i in range(len(x)):
    product.append(x[i]*y[i])*# Linear algebra version*
x = numpy.array([1,2,3])
y = numpy.array([2,3,4])
x * y

初始化数组后,线性代数方法的速度提高了 3 倍。

在深度学习中是如何使用的?

神经网络将权重存储在矩阵中。线性代数让矩阵运算变得快速简单,尤其是在 GPU 上训练的时候。事实上,GPU 是在考虑向量和矩阵运算的情况下创建的。与图像可以表示为像素阵列类似,视频游戏使用巨大的、不断发展的矩阵来产生引人注目的游戏体验。GPU 不是逐个处理像素,而是并行处理整个像素矩阵。

向量

向量是数字或术语的一维数组。在几何学中,向量存储了一个点的潜在变化的大小和方向。向量[3,-2]表示向右 3,向下 2。一维以上的向量称为矩阵。

向量记法

有多种方法来表示向量。这里有一些你可能会在阅读中遇到的。

几何中的向量

向量通常表示从一个点开始的运动。它们存储了一个点的潜在变化的幅度方向。向量[-2,5]表示向左移动 2 个单位,向上移动 5 个单位。来源

v = [-2, 5]

矢量可以应用于空间中的任何一点。向量的方向等于向上移动 5°和向左移动 2°所产生的斜边的斜率。它的大小等于斜边的长度。

标量运算

标量运算涉及一个向量和一个数。通过对向量中的所有值进行加、减或乘运算,可以就地修改向量。

Scalar addition

元素式操作

在像加、减、除这样的元素运算中,位置对应的值被组合起来产生一个新的向量。向量 A 中的第一个值与向量 b 中的第一个值配对,第二个值与第二个值配对,依此类推。这意味着向量必须有相等的维数才能完成运算。*

Vector addition

y = np.array([1,2,3])
x = np.array([2,3,4])
y + x = [3, 5, 7]
y - x = [-1, -1, -1]
y / x = [.5, .67, .75]

*有关 numpy 中广播的详细信息,请参见下文。

矢乘法

矢量乘法有两种类型:点积和哈达玛积。

点积

两个向量的点积是一个标量。向量和矩阵的点积(矩阵乘法)是深度学习中最重要的运算之一。

y = np.array([1,2,3])
x = np.array([2,3,4])
np.dot(y,x) = 20

哈达玛乘积

哈达玛乘积是逐元素乘法,它输出一个向量。

y = np.array([1,2,3])
x = np.array([2,3,4])
y * x = [2, 6, 12]

向量场

向量场显示了如果我们对点 (x,y) 应用像加法或乘法这样的向量函数,该点会假设移动多远。给定空间中的一个点,矢量场显示了我们提出的在图中的多个点处的 功率方向

Source

这个向量场很有趣,因为它根据起点向不同的方向移动。原因是该字段后面的向量存储类似于 2xx 的项,而不是类似于-2 和 5 的标量值。对于图上的每个点,我们将 x 坐标插入到 2xx 中,并绘制一个从起点到新位置的箭头。向量场对于可视化机器学习技术(如梯度下降)非常有用。

矩阵

矩阵是数字或术语的矩形网格(类似于 Excel 电子表格),具有特殊的加法、减法和乘法规则。

矩阵维度

我们用行和列来描述矩阵的维数。

a = np.array([
 [1,2,3], 
 [4,5,6]
])
a.shape == (2,3)b = np.array([
 [1,2,3]
])
b.shape == (1,3)

矩阵标量运算

对矩阵的标量运算与对向量的运算方式相同。只需将标量应用于矩阵中的每个元素——加、减、除、乘等。

Matrix scalar addition

a = np.array(
[[1,2], 
 [3,4]])
a + 1
[[2,3], 
 [4,5]]

矩阵元素运算

为了加、减或除两个矩阵,它们必须有相等的维数。*我们以元素方式组合相应的值,以生成新的矩阵。

a = np.array([
 [1,2],
 [3,4]
])
b = np.array([
 [1,2],
 [3,4]
])a + b
[[2, 4],
 [6, 8]]a — b
[[0, 0],
 [0, 0]]

数字广播*

我不能逃避谈论这个,因为它在实践中非常相关。在 numpy 中,通过一种叫做广播的机制放宽了元素操作的维度要求。如果每个矩阵中的相应维度(行与行、列与列)满足以下要求,则两个矩阵是兼容的:

  1. 尺寸相等,或
  2. 一个维度的大小为 1
a = np.array([
 [1],
 [2]
])
b = np.array([
 [3,4],
 [5,6]
])
c = np.array([
 [1,2]
])# Same no. of rows
# Different no. of columns
# but **a** has one column so this works
a * b
[[ 3, 4],
 [10, 12]]# Same no. of columns
# Different no. of rows
# but **c** has one row so this works
b * c
[[ 3, 8],
 [5, 12]]# Different no. of columns
# Different no. of rows
# but both **a** and **c** meet the 
# size 1 requirement rule
a + c
[[2, 3],
 [3, 4]]

在更高的维度——3D,4D,事情会变得更奇怪,但现在我们不会担心这个。了解 2D 的运作是一个良好的开端。

矩阵 Hadamard 积

矩阵的 Hadamard 乘积是一种元素运算。位置对应的值相乘产生新的矩阵。

a = np.array(
[[2,3],
 [2,3]])
b = np.array(
[[3,4],
 [5,6]])# Uses python's multiply operator
a * b
[[ 6, 12],
 [10, 18]]

在 numpy 中,只要矩阵和向量的维数满足广播的要求,就可以取它们的 Hadamard 积。

矩阵转置

神经网络经常处理不同大小的权重和输入,其中维数不满足矩阵乘法的要求。矩阵转置提供了一种“旋转”其中一个矩阵的方法,以便操作符合乘法要求并可以继续。转置矩阵有两个步骤:

  1. 将矩阵向右旋转 90 度
  2. 颠倒每行中元素的顺序(例如,[a b c]变成[c b a])

举个例子,把矩阵 M 转置成 T :

a = np.array([
   [1, 2], 
   [3, 4]])a.T
[[1, 3],
 [2, 4]] 

矩阵乘法

矩阵乘法指定了一组将矩阵相乘以生成新矩阵的规则。

规则

并非所有矩阵都适合乘法。此外,对最终矩阵输出的尺寸也有要求。来源

  1. 第一个 矩阵的 列数必须等于第二个 矩阵的 行数
  2. 一个 M×N 矩阵和一个 N×K 矩阵的乘积是一个 M×K 矩阵。新矩阵取第一个 的 行和第二个

步伐

矩阵乘法依靠点积来乘以各种行和列的组合。下图取自汗学院的优秀线性代数课程,矩阵 C 中的每个条目都是矩阵 A 中的一行和矩阵 b 中的一列的点积。

Source

操作a1B1**意味着我们取矩阵 A (1,7) 中第一行和矩阵 B (3,5)中第一列的点积。

这是另一种看待它的方式:

用这些例子测试你自己

numpy 矩阵乘法

Numpy 使用函数np.dot(A,B)进行向量和矩阵乘法。它还有一些其他有趣的特性和陷阱,所以我鼓励你在使用前阅读文档这里

a = np.array([
 [1, 2]
 ])
a.shape == (1,2)b = np.array([
 [3, 4],
 [5, 6]
 ])
b.shape == (2,2)# Multiply
mm = np.dot(a,b)
mm == [13, 16]
mm.shape == (1,2)

教程

可汗学院线性代数
深度学习书籍数学部分
吴恩达的课程笔记
线性代数讲解
矩阵讲解
线性代数入门
迷你参考线性代数 4 页

深度学习背景下的线性代数解释

原文:https://towardsdatascience.com/linear-algebra-explained-in-the-context-of-deep-learning-8fcb8fca1494?source=collection_archive---------6-----------------------

Photo by Charles Deluvio 🇵🇭🇨🇦 on Unsplash

在这篇文章中,我使用了自顶向下的方式来解释深度学习的线性代数。首先提供应用程序和用途,然后深入提供概念。

维基百科中线性代数的定义:

线性代数是关于线性方程和线性函数及其通过矩阵和向量空间表示的数学分支。

目录:

  • 引言。
  • 向量和矩阵的数学观点。
  • 矩阵的类型。
  • 矩阵分解。
  • 规范。
  • 矢量化。
  • 广播。
  • 外部资源。

Laxman Vijay (buymeacoffee.com)

简介:

如果你开始学习深度学习,你首先会接触到的是前馈神经网络,这是深度学习中最简单也是最有用的网络。在引擎盖下,前馈神经网络只是一个复合函数,将一些矩阵和向量相乘。

这并不是说向量和矩阵是进行这些运算的唯一方法,但是如果你这样做,它们会变得非常高效。

上图显示了一个简单的向前传播信息的前馈神经网络。

该图像是神经网络的漂亮表示,但是计算机如何理解这一点。在计算机中,神经网络的各层用向量表示。将输入层视为 X,将隐藏层视为 h。现在不考虑输出层。(这里不涉及前馈神经网络的计算过程。)

所以,它可以用向量和矩阵来表示,

上图显示了计算上述神经网络的第一个也是唯一一个隐藏层的输出所需的操作(未显示输出层的计算)。我们来分解一下。

网络的每一列都是向量。向量是数据(或特征)集合的动态数组。在当前的神经网络中,向量' x '保存输入。将输入表示为向量并不是强制性的,但是如果你这样做,它们会变得越来越便于并行执行操作。

深度学习,具体来说,神经网络的计算成本很高,所以它们需要这个好技巧来加快计算速度。

这叫矢量化。它们使得计算速度极快。这就是为什么深度学习需要 GPU 的主要原因之一,因为它们擅长矩阵乘法之类的矢量化运算。(我们将在最后深入了解这一点)。

隐藏层 H 的输出通过执行 H = f( W 来计算。x + b)。

这里 W 称为权重矩阵,b 称为偏差,f 是激活函数。(本文不解释关于前馈神经网络,如果你需要一本关于 FFNN 概念的初级读本,看这里。)

让我们分解这个等式,

第一个组件是 Wx;这是一个矩阵-向量乘积,**因为 W 是矩阵, x 是向量。在开始乘法运算之前,让我们先了解一下符号:通常向量用小粗斜体字母表示(如* x ),矩阵用大写粗斜体字母表示(如 X )。如果字母是大写加粗但不是斜体,那么它是一个张量(如 X )。***

从计算机科学的角度来看

标量:单个数字。

Vector:值的列表。(秩 1 张量)

矩阵:二维值列表。(秩 2 张量)

张量:秩为 n 的多维矩阵。

向下钻取:

从数学的角度:

矢量:

矢量是既有大小又有方向的量。它是一个存在于空间的实体,如果它是一个存在于真实空间的二维向量,它的存在用 x∈ ℝ 表示。(每个元素表示沿不同轴的坐标。)

red and blue color vectors are the basis vectors.

2D 空间中的所有向量都可以通过称为基向量的两个向量的线性组合来获得。(用 I 和 j 表示)(一般来说,N 维的向量可以用 N 个基向量来表示。)它们是单位法向量,因为它们的大小是 1,并且它们彼此垂直。这两个向量中的一个不能用另一个向量来表示。所以它们被称为线性无关矢量。(如果任何一个向量不能由一组向量的线性组合得到,那么这个向量与那个集合线性无关)。可以通过这两个向量的线性组合获得的 2D 空间中的所有点集被称为这些向量的跨度。如果一个向量由一组其他向量的线性组合(加法、乘法)来表示,那么它线性依赖于该组向量。(将这个新向量添加到现有集合中是没有用的。)

任何两个矢量都可以相加。它们可以相乘。它们的乘法有两种类型,点积和叉积。参考此处。

矩阵:

*矩阵是数字的 2D 阵列。它们代表转换。2 * 2 矩阵的每一列表示在 2D 空间被应用该变换之后的 2 个基本向量中的每一个。它们的空间表示是 W ∈ ℝ 有 3 行 2 列。

一个矩阵的向量积叫做那个向量的变换,而一个矩阵的矩阵积叫做变换的合成。

只有一个矩阵不对向量做任何变换。就是单位矩阵( I )。***I 列代表基矢。*****

矩阵的行列式用 det()表示矩阵所描述的线性变换的比例因子。****

为什么数学视角对深度学习研究者很重要?因为它们帮助我们理解基本对象的基本设计概念。他们也帮助设计深度学习问题的创造性解决方案。但是不用担心,有很多语言和软件包为我们做这些实现。但是知道它们的实现也很好。

python 编程语言的 numpy 就是这样一个库。

有很多学习数字的资源。(这对学习深度学习很重要,如果用 python 的话。)看这里

在这里,np.array 创建了一个 numpy 数组。

np.random 是一个包含随机数生成方法的包。

点法是计算矩阵间乘积的方法。

我们可以改变 numpy 数组的形状并检查它。

这里可以看到,W.x 的乘积是一个矢量,加上 b,b 是一个标量。这会自动将 b 扩展为转置([1,1])。 这种 b 到几个位置的隐式复制称为广播。(一会儿我们会深入了解。)

你注意到转置这个词了吗: 一个矩阵的转置是矩阵的镜像跨过对角线(从矩阵的左上到右下。)

**## numpy code for transpose
import numpy as np
A = np.array([[1,2],
              [3,4],
              [5,6]])
B = np.transpose(A) 
##or
B = A.T**

矩阵类型:

****对角矩阵:除主对角元素外,所有元素为零。

diagonal matrix

****单位矩阵:对角值为 1 的对角矩阵。

identity matrix

**## numpy code to create identity matrix
import numpy as np
a = np.eye(4)**

对称矩阵:与其转置矩阵相等的矩阵。A =转置(A)

****奇异矩阵:行列式为零,列线性相关的矩阵。它们的秩小于矩阵的行数或列数。

矩阵分解:

****矩阵分解矩阵分解是将矩阵分解成矩阵的乘积。有许多不同的矩阵分解;每一种都在一类特定的问题中找到用途。最广泛使用的一种矩阵分解叫做特征分解,我们将矩阵分解成一组特征向量和特征值。

方阵的本征向量是非零向量使得乘以仅改变的比例****

A . v=λ。 v

这里 v 是本征向量,λ是本征值。

**## numpy program to find eigen vectors.

from numpy import array
from numpy.linalg import eig
# define matrix
A = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(A)
# calculate eigendecomposition
values, vectors = eig(A)
print(values)
print(vectors)**

特征分解在机器学习中非常有用。这对于降维这样的概念特别有用。

有关特征分解的更多信息,请参考深度学习书籍第 2 章

深度学习中还会用到其他几种矩阵分解技术。看这里。

规范:

过拟合和欠拟合:

当你参加深度学习讲座时,你经常会听到过度适应和欠适应这个术语。这些术语描述了深度学习模型的准确性状态。

This image is the best explanation of overfitting and underfitting.

过拟合是指模型对训练数据学习得太好。它真的窃取了训练数据。在过拟合模型中,训练精度非常高,验证精度非常低。

欠拟合模型无法学习训练数据。在欠拟合模型中,训练和验证精度都非常低。

过度拟合和欠拟合都会导致模型性能不佳。但到目前为止,应用机器学习中最常见的问题是过度拟合。

为了减少过度拟合,我们必须使用一种叫做正则化的技术。*防止对训练数据的强记,从而避免过拟合的风险。*****

深度学习工程师的最重要的职责**是创建一个通常适合输入的模型。正则化有几种方法。最著名的是 L1 正则化(Lasso)和 L2 正则化(Ridge)。**

没有提供这些的细节,但是要理解这些,你必须知道什么是规范。

定额:

范数是向量的大小。向量 x 的范数的一般公式为:

p=2 的 L 范数称为欧几里德范数,因为它是原点和 x. 之间的欧几里德距离

****L 范数就是向量所有元素的和。当系统需要更高的精度时,它用于机器学习。清楚地区分零元素和非零元素。L 范数也被称为曼哈顿范数

还有最大范数,是量值最大的元素的绝对值。

矩阵的 L 范数等价于 frobenius 范数。

frobenius norm.

不仅在正则化,规范也用于优化程序。

好了,现在在所有这些概念和理论之后,我们开始涵盖深度学习所需的最重要的部分。它们是向量化和广播。

矢量化:

这是减少循环执行的技巧,通过提供向量形式的数据使进程并行执行。

许多 CPU 都有“向量”或“SIMD”(单指令多数据)指令集,这些指令集同时对两个、四个或更多个数据应用相同的操作。20 世纪 90 年代初,SIMD 在通用 CPU 上开始流行。

更多详细信息,请查看弗林的分类。

向量化是重写一个循环的过程,它不是处理数组中的一个元素 N 次,而是同时处理(比如说)数组中的 4 个元素 N/4 次。

Numpy 在他们的算法中大量实现了矢量化。这是 numpy 的官方声明。

矢量化描述了没有任何显式循环、索引等。,在代码中——当然,这些事情只是在优化、预编译 C 代码的“幕后”发生。矢量化代码有许多优点,其中包括:

矢量化代码更加简洁,也更容易阅读

更少的代码行通常意味着更少的错误

代码更类似于标准的数学符号(通常更容易正确地编写数学结构)

矢量化会产生更多“Pythonic 式”代码。如果没有向量化,我们的代码将充斥着低效和难以阅读的循环。

代码示例:

**## to add two arrays together.## consider two basic python lists.
a = [1,2,3,4,5]
b = [2,3,4,5,6]
c = []## without vectorization.for i in range(len(a)): 
    c.append(a[i]+b[i])## using vectorization.a = np.array([1,2,3,4,5])
b = np.array([2,3,4,5,6])
c = a+b**

上面的代码示例是一个过于简化的矢量化示例。而当输入数据变大时,矢量化才真正发挥作用。****

关于矢量化的更多细节,请看这里。

广播:

下一个重要的概念是广播。杰瑞米·霍华德爵士在他的一次机器学习讲座中说,广播可能是机器学习程序员最重要的工具和技能。

来自 Numpy 文档:

**The term broadcasting describes how numpy treats arrays with 
different shapes during arithmetic operations. Subject to certain 
constraints, the smaller array is “broadcast” across the larger 
array so that they have compatible shapes. Broadcasting provides a 
means of vectorizing array operations so that looping occurs in C
instead of Python. It does this without making needless copies of 
data and usually leads to efficient algorithm implementations.**

代码示例:

**a = np.array([1.0, 2.0, 3.0])
b = 2.0
 a * b
 array([ 2.,  4.,  6.])this is similar toa = np.array([1.0, 2.0, 3.0])
b = np.array([2.0, 2.0, 2.0])
a * b
array([ 2.,  4.,  6.])**

数组 b 被扩展,从而可以应用算术运算。

广播不是一个新概念。这是一个相对古老的工具,可以追溯到 50 年代。在他的论文 " 符号作为思维工具 "中,Kenneth Iverson 描述了几种数学使用工具,这些工具允许我们以新的视角思考。他第一次提到广播不是作为一种计算机算法,而是作为一种数学过程。他在一个名为 APL 的软件中实现了许多这样的工具。

他的儿子后来扩展了他的想法,继续创造了另一个软件,叫做 J 软件。这一姿态意味着,通过软件,我们得到的是超过 50 年的深入研究,利用这些,我们可以在一小段代码中实现非常复杂的数学函数。

同样非常方便的是,这些研究也在我们今天使用的语言中找到了自己的方式,比如 python 和 numpy。

所以请记住,这些不是一夜之间产生的简单想法。这些就像是思考数学及其软件实现的基本方法。(以上内容摘自 fast.ai 机器学习课程。)

关于 numpy 版本广播的更多细节,看这里

好了,这就够了,这篇文章向初学者介绍了许多新单词和术语。但是我也跳过了几个向量代数的深层概念。这可能是压倒性的,但我仍然使概念尽可能实用,(欢迎反馈!).

由于我刚刚开始深度学习,我决定帮助其他已经开始的人,为他们提供关于深度学习术语和东西的直观文章。所以如果你觉得这些文章有什么错误,请在评论中发表。

以下是一些有用的资源:

深入直观的线性代数视频: 3blue1brown

电子书:https://www.math.ucdavis.edu/~linear/linear-guest.pdf

学习深度学习的最佳站点: fast.ai

一本完整的学习书:深度学习书,作者 Ian Goodfellow。

用于深度学习的线性代数

原文:https://towardsdatascience.com/linear-algebra-for-deep-learning-506c19c0d6fa?source=collection_archive---------4-----------------------

每个深度学习程序背后的数学。

深度学习是机器学习的一个子域,涉及模拟大脑功能和结构的算法,称为人工神经网络。

线性代数是一种连续而非离散的数学形式,许多计算机科学家对它没有什么经验。对线性代数的良好理解对于理解和使用许多机器学习算法,尤其是深度学习算法至关重要。

为什么是数学?

线性代数、概率和微积分是机器学习的“语言”。学习这些主题将有助于更深入地理解底层算法机制,并允许开发新的算法。

当局限于更小的水平时,深度学习背后的一切都是数学。所以在开始深度学习和编程之前,了解基本的线性代数是非常重要的。

src

深度学习背后的核心数据结构是标量、向量、矩阵和张量。从程序上来说,让我们用这些来解决所有基本的线性代数问题。

标量

标量是单个数,是 0 阶张量的一个例子。符号 x ∈ ℝ表示 x 是属于一组实数值ℝ.的标量

深度学习中有不同组的感兴趣的数字。ℕ表示正整数(1,2,3,…)的集合。ℤ指定的整数,结合了正值,负值和零值。ℚ表示可以表示为两个整数的分数的有理数的集合。

少数内置标量类型是 Python 中的 intfloatcomplexbytesUnicode 。在 python 库 NumPy 中,有 24 种新的基本数据类型来描述不同类型的标量。有关数据类型的信息,请参考此处的文档。

在 Python 中定义标量和少量运算:

下面的代码片段解释了标量上的一些算术运算。

<class 'int'>
<class 'float'>
12.5
-2.5
37.5
0.6666666666666666

下面的代码片段检查给定的变量是否是标量。

True
False
True

向量

向量是单个数字的有序阵列,是一阶张量的一个例子。向量是称为向量空间的对象片段。向量空间可以被认为是特定长度(或维度)的所有可能向量的全部集合。由ℝ^3 表示的三维实值向量空间经常被用来以数学方式表示我们的三维空间的真实世界概念。

为了明确地识别向量的必要分量,向量的第 I 个标量元素被写成 x[i]。

中的深度学习向量通常表示特征向量,其原始成分定义了特定特征的相关程度。这种元素可以包括二维图像中一组像素的强度的相关重要性,或者金融工具横截面的历史价格值。

在 Python 中定义矢量和少量运算:

<class 'list'>
[1, 2, 3, 4, 5, 6]
[5 7 9]
<class 'numpy.ndarray'>
[-3  6 -3]

矩阵

矩阵是由数字组成的矩形阵列,是二阶张量的一个例子。如果 m 和 n 是正整数,即 m,n ∈ ℕ,那么 m×n 矩阵包含 m*n 个数字,有 m 行和 n 列。

完整的 m×n 矩阵可以写成:

将整个矩阵分量显示简化为以下表达式通常很有用:

在 Python 中,我们使用 numpy 库来帮助我们创建 n 维数组。这些基本上都是矩阵,我们使用矩阵方法,传入列表,从而定义一个矩阵。

$python

>>> import numpy as np
>>> x = np.matrix([[1,2],[2,3]])
>>> x
matrix([[1, 2],
        [2, 3]])

>>> a = x.mean(0)
>>> a
matrix([[1.5, 2.5]])
>>> # Finding the mean with 1 with the matrix x.
>>> z = x.mean(1)
>>> z
matrix([[ 1.5],
        [ 2.5]])
>>> z.shape
(2, 1)
>>> y = x - z
matrix([[-0.5,  0.5],
        [-0.5,  0.5]])
>>> print(type(z))
<class 'numpy.matrixlib.defmatrix.matrix'>

在 Python 中定义矩阵和少量运算:

矩阵加法

矩阵可以添加到标量,向量和其他矩阵。这些操作中的每一个都有精确的定义。这些技术在机器学习和深度学习中经常使用,因此值得你熟悉它们。

矩阵-矩阵加法

c = A+B(A 和 B 的形状应该相等)

方法 shape 返回矩阵的形状,add 接受两个参数并返回这些矩阵的和。如果矩阵的形状不一样,它会抛出一个错误,说,加法不可能。

矩阵标量加法

将给定标量与给定矩阵中的所有元素相加。

矩阵标量乘法

将给定标量乘以给定矩阵中的所有元素。

矩阵乘法

形状为(m×n)的 a 和形状为(n×p)的 B 相乘得到形状为(m×p)的 C

src

矩阵转置

通过转置,您可以将行向量转换为列向量,反之亦然:

a =[aijmxn

AT=[a ji ]n×m

张量

张量的更一般的实体包括标量、矢量和矩阵。在物理科学和机器学习中,有时有必要使用二阶以上的张量。

src

我们使用像 tensorflow 或 PyTorch 这样的 Python 库来声明张量,而不是嵌套矩阵。

在 PyTorch 中定义简单张量

Python 中很少对张量进行算术运算

更多关于张量和 PyTorch 的文档请点击这里。

重要链接

要开始使用 python 进行深度学习:

[## 使用 Python 进行深度学习

人脑模仿。

towardsdatascience.com](/deep-learning-with-python-703e26853820) [## 机器学习导论

机器学习是一种从例子和经验中学习的想法,而不是显式编程。而不是…

towardsdatascience.com](/introduction-to-machine-learning-db7c668822c4)

结束语

感谢阅读。如果你觉得这个故事有帮助,请点击下面的👏去传播爱。

特别感谢 Samhita Alla 对本文的贡献。

用于深度学习的基础线性代数

原文:https://towardsdatascience.com/linear-algebra-for-deep-learning-f21d7e7d7f23?source=collection_archive---------0-----------------------

线性代数的概念对于理解机器学习背后的理论至关重要,尤其是对于深度学习。它们给你更好的直觉,让你知道算法到底是如何工作的,这让你能够做出更好的决定。所以,如果你真的想成为这个领域的专业人士,你就不能逃避掌握它的一些概念。这篇文章将向你介绍在机器学习中使用的线性代数的最重要的概念。

目录:

  • 简介
  • 数学对象
  • 计算规则
  • 矩阵乘法性质
  • 求逆和转置
  • 总结
  • 资源

介绍

线性代数是数学的一种连续形式,应用于整个科学和工程领域,因为它允许您对自然现象建模并有效地计算它们。因为它是一种连续而非离散的数学形式,许多计算机科学家对此没有太多的经验。线性代数也是几乎所有数学领域的核心,如几何和泛函分析。它的概念是理解机器学习背后的理论的一个至关重要的先决条件,特别是如果你正在使用深度学习算法。在开始机器学习之前,您不需要了解线性代数,但在某些时候,您可能希望更好地了解不同的机器学习算法在幕后是如何工作的。这将帮助你在机器学习系统的开发过程中做出更好的决策。所以如果你真的想成为这个领域的专业人士,你就必须掌握线性代数中对机器学习很重要的部分。在线性代数中,数据由线性方程表示,线性方程以矩阵和向量的形式呈现。因此,您主要是在处理矩阵和向量,而不是标量(我们将在下一节讨论这些术语)。当您拥有合适的库(如 Numpy)时,只需几行代码就可以非常容易地计算复杂的矩阵乘法。(注:这篇博文忽略了对机器学习不重要的线性代数概念。)

数学对象

数量

标量就是一个简单的数字。例如 24。

矢量

向量是有序的数字数组,可以在行或列中。向量只有一个索引,它可以指向向量中的一个特定值。例如,V2 指的是向量中的第二个值,在上图中是-8。

[数]矩阵

矩阵是有序的 2D 数列,它有两个指数。第一个指向行,第二个指向列。例如,M23 指的是第二行第三列中的值,即上面黄色图形中的 8。一个矩阵可以有多个行数和列数。请注意,向量也是矩阵,但只有一行或一列。

黄色图形示例中的矩阵也是一个 2×3 维矩阵(行×列)。下面你可以看到矩阵及其符号的另一个例子:

张量

你可以把张量想象成一个排列在规则网格上的数字阵列,轴的数量是可变的。张量有三个索引,第一个指向行,第二个指向列,第三个指向轴。例如,T232 指向第二行、第三列和第二个轴。这是指下图中右侧张量的值 0:

张量是上述所有概念中最通用的术语,因为张量是一个多维数组,它可以是一个向量,也可以是一个矩阵,这取决于它所包含的索引数。例如,一阶张量是一个向量(1 个索引)。二阶张量是一个矩阵(2 个指数),三阶张量(3 个指数)和更高阶张量称为高阶张量(3 个或更多指数)。

计算规则

1.矩阵标量运算

如果你对一个矩阵进行乘、除、减或加标量,你对矩阵的每个元素都要这样做。下图完美地说明了乘法的这一点:

2.矩阵向量乘法

矩阵乘以向量可以被认为是矩阵的每一行乘以向量的列。输出将是一个与矩阵行数相同的向量。下图显示了这是如何工作的:

为了更好地理解这个概念,我们将通过计算第二个图像。为了得到结果向量的第一个值(16),我们取要与矩阵相乘的向量的数字(1 和 5),然后将它们与矩阵第一行的数字(1 和 3)相乘。这看起来像这样:

11 + 35 = 16

我们对矩阵第二行中的值做同样的处理:

41 + 05 = 4

再次对于矩阵的第三行:

21 + 15 = 7

这是另一个例子:

这是一种小抄:

3.矩阵-矩阵加法和减法

矩阵-矩阵的加法和减法相当简单明了。要求是矩阵具有相同的维数,并且结果是矩阵也具有相同的维数。您只需将第一个矩阵的每个值与其在第二个矩阵中的对应值相加或相减。见下文:

4.矩阵-矩阵乘法

如果你知道如何将一个矩阵乘以一个向量,那么将两个矩阵相乘也并不难。请注意,只有当第一个矩阵的列数与第二个矩阵的行数匹配时,才能将矩阵相乘。结果将是一个与第一个矩阵行数相同、与第二个矩阵列数相同的矩阵。它的工作原理如下:

您只需将第二个矩阵分解成列向量,并将第一个矩阵分别乘以这些向量。然后你把结果放入一个新的矩阵(而不把它们加起来!).下图一步步解释了这一点:

这又是一张小抄:

矩阵乘法性质

矩阵乘法有几个特性,允许我们将大量计算捆绑到一个矩阵乘法中。我们将在下面逐一讨论。我们首先用标量来解释这些概念,然后用矩阵来解释,因为这会让你更好地理解这个过程。

1.不可交换

标量乘法是可交换的,但矩阵乘法不是。这意味着当我们乘标量时,73 和 37 是一样的。但是当我们把矩阵相乘时,AB 和 BA 不一样。

2.联合的

标量乘法和矩阵乘法都是结合律。这意味着标量乘法 3(53)与(35)3 相同,矩阵乘法 A(BC)与(AB)C 相同。

3.分布的

标量乘法和矩阵乘法也是分布式的。这意味着
3(5 + 3)与 35 + 33 相同,A(B+C)与 AB + AC 相同

4.单位矩阵

单位矩阵是一种特殊的矩阵,但是首先,我们需要定义什么是单位矩阵。数字 1 是一个恒等式,因为你乘以 1 的所有东西都等于它本身。因此,每个矩阵乘以一个单位矩阵等于它自己。例如,矩阵 A 乘以它的单位矩阵等于 A。

你可以通过一个事实来识别一个单位矩阵,即它的对角线上有 1,而其他值都是 0。它也是一个“方阵”,这意味着它的行数与列数相匹配。

我们之前讨论过矩阵乘法是不可交换的,但有一个例外,即如果我们用一个单位矩阵乘以一个矩阵。因此,以下等式成立: AI = IA = A

反转和转置

矩阵求逆和矩阵转置是两种特殊的矩阵性质。同样,我们将从讨论这些性质如何与实数相关开始,然后讨论它们如何与矩阵相关。

1.相反的

首先,什么是逆?一个数乘以它的倒数等于 1。请注意,除了 0 以外,每个数字都有一个倒数。如果你把一个矩阵乘以它的逆矩阵,结果就是它的单位矩阵。下面的例子展示了标量的反函数是什么样子的:

但不是每个矩阵都有逆矩阵。如果一个矩阵是“方阵”并且有逆矩阵,你可以计算它的逆矩阵。不幸的是,讨论哪些矩阵有逆矩阵超出了这篇文章的范围。

为什么我们需要一个逆?因为我们不能分解矩阵。没有除以矩阵的概念,但是我们可以用逆矩阵乘以一个矩阵,结果本质上是一样的。

下图显示了一个矩阵乘以它的逆矩阵,从而得到一个 2 乘 2 的单位矩阵。

使用 Numpy 可以很容易地计算矩阵的逆矩阵(如果有的话)。以下是文档的链接:https://docs . scipy . org/doc/numpy-1 . 14 . 0/reference/generated/numpy . Lina LG . inv . html

2.移项

最后,我们将讨论矩阵转置的性质。这基本上是一个矩阵的镜像,沿着 45 度轴。得到矩阵的转置是相当简单的。它的第一列是矩阵转置的第一行,第二列是矩阵转置的第二行。将 mn 矩阵转换成 nm 矩阵。同样,A 的 Aij 元素等于 Aji(转置)元素。下图说明了:

摘要

在本文中,您了解了机器学习中使用的线性代数的数学对象。你学会了如何乘、除、加、减这些数学对象。此外,你已经了解了矩阵的最重要的性质,以及为什么它们使我们能够进行更有效的计算。除此之外,你已经学习了什么是逆矩阵和转置矩阵,以及你可以用它们做什么。虽然机器学习中也使用线性代数的其他部分,但这篇文章为您提供了最重要概念的适当介绍。

资源

深度学习(书)——伊恩·古德菲勒、约书亚·本吉奥、亚伦·库维尔

https://machine learning mastery . com/linear-algebra-machine-learning/

吴恩达在 Coursera 上的机器学习课程

https://en.wikipedia.org/wiki/Linear_algebra

https://www . mathsisfun . com/algebra/scalar-vector-matrix . html

https://www . quant start . com/articles/scalar-vectors-matrix-and-tensors-用于深度学习的线性代数-第一部分

https://www . aplustopper . com/understanding-scalar-vector-quantities/

[## 向量和矩阵

向量是机器学习中最重要的概念之一,因为许多错误都是由于拥有矩阵/向量…

machinelearning-blog.com](https://machinelearning-blog.com/2017/11/04/calculus-derivatives/)

https://machinelearning-blog.com】这个帖子最初发表在我的博客上(【T10”)。

R:预测电影受欢迎程度中的线性和贝叶斯建模

原文:https://towardsdatascience.com/linear-and-bayesian-modelling-in-r-predicting-movie-popularity-6c8ef0a44184?source=collection_archive---------4-----------------------

该选哪部电影?

让我们想象一个雨天。你透过窗户向外望去,一切都是灰色的,冰冷的。你抓起你的毯子,坐在你最喜欢的沙发上;这里非常舒适,你刚刚决定这是看电影的完美一天。你想看一部好电影,或者至少是受欢迎的电影。你有几个选择,但其中一些甚至没有在典型的电影网站评级!能够预测人们对这些电影的看法不是很好吗?好吧,也许有解决的办法。根据一些特征来预测一部电影的人气怎么样?我们只需要一个包含电影、一些统计工具和 R studio 的数据集。

在我们的数据集中,有 651 部 随机抽样的 电影在 1970 年至 2016 年期间在美国电影院上映。数据从烂番茄IMDB 获得。该数据集包含每部电影的 32 个特征,包括流派、美国电影协会评分、制作工作室以及它们是否获得奥斯卡提名等特征。所以现在,我们可以问自己:

一部电影的受欢迎程度可以通过考虑它的某些特征来预测吗,比如类型、流派、美国电影协会评分、IMDb 票数以及它是否获奖?

在继续开发任何模型之前,我们需要回答两个问题:我们的结果可以推广吗? 当前数据集可以做哪种类型的推断?。对于第一个问题,我们可以注意到,该数据集中包含的电影是从上述两个来源中随机采样的,并且采样方法没有产生任何偏差,因此,我们可以假设所获得的结果可以推广到 1970 年到 2016 年 之间上映的所有美国电影。另一方面,这是一项观察性研究,因此从该数据中可以发现的关系表明 关联 ,而不是因果关系

准备好开始了吗?等一下。我们所理解的一部电影的“流行”是什么?我们的数据集包括来自两个不同来源的电影样本,我们有两个变量可以潜在地用作流行度* : audience_score(烂番茄上的观众评分)和imdb_rating(IMDB 上的评级)。让我们继续分析这两个变量。首先,我们将检查这些变量之间是否存在相关性。为此,我们将在散点图中绘制两个变量:*

我们可以看到,该图显示了两个变量之间可能的正相关关系。我们将通过使用函数cor对相关性进行数值计算来确认这一点:

正如我们所观察到的,这两个变量之间有很高的相关性。如果我们要将其中一个变量作为响应,最好不要将另一个变量作为自变量。所以我们需要决定选择哪一个作为响应变量。我们可以利用histogram和汇总统计来分析它们的分布,做出明智的选择。让我们从imbd_rating开始:

**

然后,我们可以对audience_score做同样的事情:

**

我们可以看到,变量imbd_rating显示了一个接近正态的分布,其平均值为 6.493,中位数为 6.00。另一方面,变量audience_score显示出更均匀的分布,平均值为 62.36,中位数为 65.00。因为它的分布,我们将选择只考虑imdb_rating

在决定将哪个变量作为我们的响应变量后,我们需要探索我们的解释变量。我们可以分析我们感兴趣的变量的分布,包括在我们的模型中,通过绘制每个变量的直方图,并获得总结描述表。对于那些分类的变量,我们可以使用内置函数table创建一个比例表。另一方面,我们可以为连续变量创建一个数据框,并应用函数summary。我不会在这里展示整个代码,但是例如,在我们的数据集中,分析显示投票数的分布是右偏的。为了对此进行调整,我们可以对这些值进行对数转换(log_votes)。

之后,我们可以分析我们的探索变量和响应变量之间的相互作用。对于这项任务,我们可以根据探索变量是数值型还是分类型来绘制箱线图或散点图。我将只展示重要的发现。

从获得的情节和概要描述中,可以看出,在我们的数据集中,那些获得过奥斯卡奖的电影或导演获得过奥斯卡奖的电影似乎具有稍高的评级。此外,给出的投票数显示了与 IMDB 评级的微弱正相关。最后,变量best_actor_winbest_actress_win看起来具有相同的分布,并且与imdb_rating有相似的关联,所以我们将把这两个变量合并成一个新的变量main_oscar_win

现在,我们对我们的反应变量有了一个很好的想法,也暗示了哪些变量对预测一部电影的受欢迎程度可能很重要。是时候开始建模了!。我们将采取两种方法:首先,我们将做一个多元线性回归,然后,我们将开发一个贝叶斯模型。

多元线性回归模型

多元线性回归试图通过对数据拟合线性方程来模拟两个或多个独立变量或解释变量与响应变量之间的关系。

我们的目标是达成一个简洁的模型,这就是更简单的模型,具有巨大的解释预测能力。为了做到这一点,我们有两个模型选择选项:向前选择和向后排除。在第一种情况下,我们从一个空模型开始,一次添加一个预测器。我们将选择第二个选项:向后排除意味着从包含所有候选的模型开始,并且一次丢弃一个预测器,直到达到最节省的模型。在我们的例子中,我们的第一个完整模型将包括我们之前发现的对预测电影受欢迎程度可能很重要的六个变量:genrebest_pic_winbest_dir_winmain_oscar_winlog_votesmpaa_rating。在 R 中,我们可以使用函数lm建立一个线性模型:

现在我们有了完整的模型,我们可以使用几个标准来删除变量:p 值和调整后的 R。我们将选择 p 值作为排除标准,因为在这种情况下,我们的目标是创建一个仅使用具有显著性的变量来显示最高预测值的模型。

在运行包含所有相关变量的完整模型后,我们获得了 0.3582 的调整后 R,这意味着我们仍然可以改进模型。为了做到这一点,我们可以从每次移除具有最高 p 值的变量开始,直到模型中剩余的所有变量都是显著的。所以我们模型中 p 值最高的变量是main_oscar_win

再次运行我们的简单模型后,我们可以看到现在我们调整后的 R 是 0.3594。我们可以通过再次消除具有最高 p 值的变量来进一步改进我们的模型。这种情况下会是best_pic_win

我们现在看到,调整后的 R 是 0.3595,与我们之前在步骤 1 中的模型没有不同,但不同的是,这次涉及的所有变量都是显著的。出于实际考虑,我不会在这里展示它,但移除任何其他变量都会降低调整后的 R。因此,我们认为这是我们的最终模型。

对于线性回归,有一个非常重要的概念需要记住:共线性。当两个变量高度相关时,它们被认为是共线的。包含共线预测值使模型估计变得复杂。

因此,在这一点上,我们可以看看我们的变量,看看我们感兴趣的变量是否显示某种程度的共线性。在我们的数据集中,我们有混合变量,这是因为我们有一些分类变量和一些连续变量,所以在这种情况下,测量共线性的一种方法是使用 方差膨胀因子 (VIF) 用于量化普通线性回归中多重共线性程度的 VIF,计算为包含多个项的模型的方差与仅包含一个项的模型的方差之比。简而言之,它告诉我们由于模型中存在共线性,回归系数的方差增加了多少。所以,让我们来计算一下:

我们的预测值都没有很高的 VIF,所以我们可以假设多重共线性在我们的模型中不起作用。

现在,是时候在我们模型中运行一些诊断了。多元回归模型取决于以下四个假设:

  1. 每个数字解释变量与响应变量线性相关
  2. 残差接近正态分布,平均值为 0
  3. 残差的可变性几乎是恒定的
  4. 残差是独立的

我们将在我们的模型环境中逐一测试这些假设:

  1. 我们模型中唯一的数字变量是log_values。因此,我们可以通过检查残差图来探索第一个假设。

该图显示残差在 0 附近随机分散,这表明数值探索变量和响应变量之间存在线性关系。

2.为了检查这种情况,我们将首先执行残差直方图,然后执行残差 Q-Q 图。

正如我们在上面看到的,分布直方图和残差 Q-Q 图显示接近正态分布,也模拟了在原始imdb rating变量中观察到的左侧偏斜。

3.现在,我们需要检查残差对于预测响应变量的低值和高值是否同样可变。然后,我们将检查残差与预测值的关系图。

残差随机分散在宽度为 0 左右的恒定带中。

4.最后,我们将检查残差的独立性:

上面的图没有显示任何特定的模式,所以可以假设残差是独立的,因此观察值也是独立的。

贝叶斯模型

通常,我们被教导用传统的频率统计来解决问题。然而,还有另一种方法,它有时因主观而被削弱,但它更直观或更接近我们在日常生活中思考概率的方式,但却是一种非常强大的工具:贝叶斯统计。这个理论所依赖的一些关键概念有:条件概率贝叶斯定理。**

条件概率是在一个事件发生的情况下,另一个事件发生的概率。如果已知或假设事件 B 已经发生,那么我们感兴趣的事件 A 给定 B 的条件概率就写成 P (A|B)。

当两个事件是独立的,意味着 A 的发生不影响 B 的发生时,A 和 B 的合取概率(换句话说,两个事件都为真的概率)写成 P ( A 和 B )= P(A) P(B)。但如果 A 条件 B 发生则不是这样,这里的合取概率是p(AB)=p(A)p(B|A)。

这里,经过一些数学计算后,可以推导出贝叶斯定理,并表示如下:

**p(A|B)=p(A)p(B|A/p(B)

换句话说:给定的 B 发生的概率等于 A 发生的无条件概率乘以 A 发生时 B 发生的概率,再除以 B 的无条件概率。

这个定理有一个强大的解释,叫做历时解释,意思是随着时间的推移,一些事情正在发生,它提供了一个工具来更新假设提供新数据的概率。在这种解释中,我们方程中的术语隐含着一些其他的概念:

  • p ( A )是我们看到数据之前假设的概率,叫做先验概率,或者就叫先验*。*
  • p (A|B)是我们的目标,这是我们看到数据后假设的概率,称为后验*。*
  • p ( B |A)是假设下数据的概率,称为似然*。*
  • p ( B )是数据在任何假设下的概率,称为归一化常数*。*

当我们想要在贝叶斯方法下建立一个模型时,有一个元素是关键的:贝叶斯因子。贝叶斯因子是两个竞争假设(通常是无效假设和替代假设)的似然概率之比,它帮助我们量化一个模型对另一个模型的支持。在贝叶斯建模中,先验分布的选择是分析的关键组成部分,可以修改我们的结果;然而,当我们添加更多的数据时,先验开始变弱。当分析师没有太多先验信息时,非信息先验是方便的。

在 R 中,我们可以使用BAS包进行贝叶斯回归。我们将使用贝叶斯模型平均( BMA ),它提供了一种解释模型不确定性的机制,并且我们需要指出函数的一些参数:

先验:策尔纳-西奥·柯西(使用针对多变量情况扩展的柯西分布

模型先验:统一(为所有模型分配相等的概率)

方法:马尔可夫链蒙特卡罗 ( MCMC )(提高模型搜索效率)

我们现在将打印为该模型获得的边际包含概率:

之后,我们可以使用函数summary来查看变量包含的零一指标的前 5 个模型。

它还显示了一个列,该列具有最高概率模型的每个模型的贝叶斯因子( BF )、模型的后验概率(postpross)、模型的其余部分、模型的维度( dim )以及在所选先验分布下的对数边际可能性( logmarg )。

最后,我们可以利用函数image来可视化对数后验概率和模型等级。

在上图中,每一行对应于完整模型中包含的每个变量,还有一行用于截距。在每一列中,我们可以看到所有可能的模型(2 个⁶,因为我们有 16 个变量)按后验概率排序,从最好到最差排列在顶部(从左到右)。

*从上面的模型和图片可以看出:

feature_film边际概率为 0.999, 并且出现在所有五个顶级模型中的
critics_score边际概率为 0.999 并且也出现在所有五个顶级模型中的
runtime边际概率为 0.98 并且出现在所有五个顶级模型中的
drama边际概率为 0.57 并且出现在五个顶级模型中的三个
imbd_num_votes边际概率为 0.99 并且出现在五个顶级模型中的三个
截距 也有边际概率为 1,出现在所有五大顶级型号

据此,最佳型号包括截距、feature_filmcritics_scoredramaimbd_num_votesruntime*

我们现在可以获得 BMA 下的系数估计和标准差,以便能够检查重要变量系数的边际分布。为此,我们将使用函数coef并使用plot绘制它们

垂直线对应于系数等于 0 的后验概率。另一方面,成形曲线显示了系数非零的可能值的密度。值得一提的是,线的高度与其概率成比例。这意味着截距和feature_filmcritics_scoreimbd_num_votesruntime没有表示非零概率的线。

最后,我们可以使用confint方法获得系数的 95%可信区间(真实均值包含在给定区间内的概率为 0.95)。

BAS包为我们提供了一种简单的方法,只需使用函数plotwhich选项就可以获得模型的图形摘要。

  1. 残差与拟合图

理想情况下,我们不会看到异常值或非常数方差。然而,在这种情况下,我们可以看到预测值有一个常数,但有两个异常值。

2.模型概率

此图按采样顺序显示模型的累积概率。该图显示,累积概率在 300 次模型试验后开始变得平稳,因为每个额外的模型仅增加了累积概率的一个小增量。模型搜索在大约 1400 处停止,而不是 2 个⁵组合的枚举。

3.模型复杂性

该图显示了每个模型的维度,即回归系数的数量,包括截距与模型边际可能性的对数。在这种情况下,我们可以看到从 5 到 12 维可以达到最高的对数边际。

4.边际包含概率

在这种情况下,我们可以观察每个协变量的边际后验包含概率,大于 0.5 的边际后验包含概率显示为红色(解释数据和预测的重要变量)。在图表中,我们可以看到之前已经显示的关于哪些变量对最终得分有影响。

预测

现在是时候测试一下 我们两款的预测能力了!我们会用 2016 年上映的电影“ Zootropolis ”。相应信息从 IMDB 网站RottenTomatoes 获得,与分析数据一致。

**

正如我们在上面看到的,真实的imdb_rating是 8,这与我们的贝叶斯模型预测的非常接近。

那么我们能得出什么结论呢?从线性回归和贝叶斯模型中,我们了解到,实际上可以通过考虑每部电影的特征数据来预测电影的受欢迎程度。

在线性回归分析中,可以建立一个简洁的、多变量的线性模型,该模型能够在一定程度上预测电影的受欢迎程度,即 IMDb 评分,并选择四个具有统计意义的预测值。然而,重要的是要记住,我们最终模型的调整后 R 仅为 0.3595,因此这意味着 35.95%的可变性由模型解释。在贝叶斯模型中,我们最终得到了一个同样满足贝叶斯假设的简约模型。从这两个模型中,我们可以看出贝叶斯模型的预测更接近真实的 IMDb 评级。

参考文献:

  • 彭罗杰 D. (2016) 探索性数据分析用 R. LeanPub
  • 唐尼艾伦 B. (2012) 想想贝叶斯。Python 中的贝叶斯统计。 绿茶出版社

2016 年总统选举数据与各种任意选择的数据的线性相关性

原文:https://towardsdatascience.com/linear-correlations-of-2016-presidential-election-data-to-various-arbitrarily-chosen-data-f909e532ffb6?source=collection_archive---------18-----------------------

出于好奇(和无聊),我收集了总统选举投票的数据,并将它们与各种类型的死亡率、性传播疾病、免疫率、犯罪活动和教育分数相关联。

请记住,这些图表和摘要代表了一种相当简单的统计分析,单个自变量的线性回归通常不足以解释因变量。但是,现在是凌晨 3 点,我喝了太多咖啡,无法入睡——不管怎样,让我们找点乐子吧!数据在状态级别上进行分析(N_max = 50)。

除非另有说明,所有示例都适用于具有单个独立变量的简单线性模型(直接参见下文)。具有缺失数据的实例已从分析中排除。

Figure 1.: A mathematical representation of a simple linear model with a single independent variable.

恶性肿瘤死亡率(每 10 万人)与投票给特朗普的人数(%):

Figure 2.: A scatterplot relating age adjusted mortality rate due to malignant neoplasms (i.e. cancer, in incidents per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.21
p_F = 0.0004824 ***
p_t[𝝱0] = 0.856997
p_t[𝝱1] = 0.000482 ***

有趣的是,将癌症导致的死亡率数据与特朗普的选票联系起来,会产生一种相对较弱(见 R _adj)但似乎很重要(见 p_F)的关系。这个特定模型中的异常值似乎是 NC、UT 和 WI。这种关系不适用于克林顿选民。

心脏病死亡率(每 10 万人)与投票给特朗普的人数(%)

Figure 3.: A scatterplot relating age adjusted mortality rate due to heart disease (in incidents per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.2553
p_F = 0.0001084 ***
p_t[𝝱0] = 0.020797 *
p_t[𝝱1] = 0.000108 ***

这个模型显示了相关的迹象。虽然相关性很弱,但也相当重要。该模型中的异常值也出现在 NC、UT 和 WI 中。

机动车事故死亡率(每 10 万人)与投票给特朗普的人数(%)

Figure 4.: A scatterplot relating age adjusted mortality rate due to motor-vehicle accidents (in incidents per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.4948
p_F = 7.376 * 10^(-9) ***
p_t[𝝱0] = 2.79 * 10^(-12) ***
p_t[𝝱1] = 7.38 * 10^(-9) ***

这是一个意想不到的结果。有机动车事故问题的州似乎在 2016 年支持特朗普。这一次,相关性实际上处于中等范围。事实上,当用克林顿选票替代特朗普选票时,可以观察到类似的密切关系(但方向相反)。

Figure 5.: A scatterplot relating age adjusted mortality rate due to motor-vehicle accidents (in incidents per 100,000) to percentage of people voting for Clinton in each state.

R²_adj = 0.3971
p_F = 5.648 * 10^(-7) ***
p_t[𝝱0] < 2 * 10^(-16) ***
p_t[𝝱1] = 5.65 * 10^(-7) ***

进一步考察特朗普选民的模型,Breusch-Pagan ( p = 0.1193)和 Score test ( p = 0.1449)表明数据中不存在异方差。夏皮罗-维尔克(p = 0.6651)、科尔莫戈罗夫-斯米尔诺夫(p = 0.8544)和安德森-达林(p = 0.4715)正态性检验都表明数据来自正态分布。德宾-沃森检验(p = 0.89)表明误差不相关。

因此,我们或许可以有把握地预测某个州在 2016 年总统选举中的投票情况,只需使用机动车事故死亡率。或者,我们可以利用各州的投票记录来预测它们的机动车事故死亡率。

自杀死亡率(每 10 万人)与投票给特朗普的人数(%)

Figure 6.: A scatterplot relating age adjusted mortality rate due to suicide (in incidents per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.24
p_F = 0.0001811 ***
p_t[𝝱0] = 2.26 * 10^(-8) ***
p_t[𝝱1] = 0.000181 ***

该模型还显示出显著相关性的迹象,尽管在支持特朗普的州和自杀死亡率之间存在微弱的相关性。相反,支持克林顿的州显示出较低的死亡率——甚至更合适。

Figure 7.: A scatterplot relating age adjusted mortality rate due to suicide (in incidents per 100,000) to percentage of people voting for Clinton in each state.

R²_adj = 0.4636
p_F = 3.196 * 10^(-8) ***
p_t[𝝱0] < 2 * 10^(-16) ***
p_t[𝝱1] = 3.2 * 10^(-8) ***

对 Trump 投票模型运行诊断会产生以下结果:

Breusch-Pagan p = 0.1763463                 | No heteroskedasticity!
Score test p = 0.08569949                   | No heteroskedasticity!
Shapiro-Wilk p = 0.2942                     | Normal distribution!
Kolmogorov-Smirnov p = 0.8451               | Normal distribution!
Anderson-Darling p = 0.3797                 | Normal distribution!
Durbin-Watson p = 0.704                     | Uncorrelated errors!

凶杀死亡率(每 10 万人)与投票给特朗普的人数(%)

Figure 8.: A scatterplot relating age adjusted mortality rate due to homicide (in incidents per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.1366
p_F = 0.007208 **
p_t[𝝱0] = 2.61 * 10^(-16) ***
p_t[𝝱1] = 0.00721 **

这个模型显示,杀人道德率和特朗普支持度之间的相关性很弱。然而,参数估计似乎产生了一个非常好的 t 检验统计量。可能有影响的异常值是 HI、LA 和 TX。

药物中毒死亡率(每 10 万人)与投票给特朗普的人数(%)

Figure 9.: A scatterplot relating age adjusted mortality rate due to drug poisoning (in incidents per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.0179
p_F = 0.7115
p_t[𝝱0] < 2 * 10^(-16) ***
p_t[𝝱1] = 0.711

在 2016 年选举中支持特朗普的州与药物中毒死亡率之间既没有显著也没有明显的相关性。

关于死亡率的结论

与支持克林顿的州相比,2016 年支持特朗普的州似乎因各种原因而倾向于遭受高死亡率。最突出的例子是与机动车辆和自杀有关的死亡。这一明显规律的一个显著例外是药物中毒死亡率——这是两个变量之间没有显著或明显相关性的唯一例子。

婴儿死亡率(每 1,000 名活产婴儿)与投票给特朗普的人数(%)

Figure 10.: A scatterplot relating rate of infant deaths (per 1,000 live births) to percentage of people voting for Trump in each state.

R²_adj = 0.256
p_F = 0.0001239 ***
p_t[𝝱0] = 0.000297 ***
p_t[𝝱1] = 0.000124 ***

当谈到特朗普的支持率和婴儿死亡率时,似乎支持特朗普的州的婴儿死亡率也略高。尽管这种关系很重要,但相对较弱,两个变量之间只有轻微的相关性。

非西班牙裔黑人婴儿死亡率(每 1,000 名活产婴儿)与投票给特朗普的人的比率(%)

Figure 11.: A scatterplot relating rate of non-hispanic black infant deaths (per 1,000 live births) to percentage of people voting for Trump in each state.

R²_adj = 0.3689
p_F = 6.537 * 10^(-5) ***
p_t[𝝱0] = 0.0225 *
p_t[𝝱1] = 6.54 * 10^(-5) ***

当我们只研究非西班牙裔黑人婴儿死亡的例子时,相关性更高,模型总体上更适合。如预期的那样,在这个模型上运行诊断程序会产生相当不错的结果。

Breusch-Pagan p = 0.4146038                 | No heteroskedasticity!
Score test p = 0.2699911                    | No heteroskedasticity!
Shapiro-Wilk p = 0.3525                     | Normal distribution!
Kolmogorov-Smirnov p = 0.8966               | Normal distribution!
Anderson-Darling p = 0.5787                 | Normal distribution!
Durbin-Watson p = 0.44                      | Uncorrelated errors!

不出所料,支持克林顿的州的趋势正好相反:

Figure 12.: A scatterplot relating rate of non-hispanic black infant deaths (per 1,000 live births) to percentage of people voting for Clinton in each state.

R²_adj = 0.3361
p_F = 0.0001565 ***
p_t[𝝱0] = 2.85 * 10^(-12) ***
p_t[𝝱1] = 0.000156 ***Breusch-Pagan p = 0.5336099                 | No heteroskedasticity!
Score test p = 0.3860135                    | No heteroskedasticity!
Shapiro-Wilk p = 0.2888                     | Normal distribution!
Kolmogorov-Smirnov p = 0.4213               | Normal distribution!
Anderson-Darling p = 0.2453                 | Normal distribution!
Durbin-Watson p = 0.514                     | Uncorrelated errors!

西班牙裔婴儿死亡率(每 1,000 名活产婴儿)与投票给特朗普的人的比率(%)

Figure 13.: A scatterplot relating rate of hispanic infant deaths (per 1,000 live births) to percentage of people voting for Trump in each state.

R²_adj = 0.09937
p_F = 0.03432 *
p_t[𝝱0] = 1.74 * 10^(-5) ***
p_t[𝝱1] = 0.0343 *

在 2016 年大选中支持特朗普的州与拉美裔婴儿死亡率之间存在疏忽的关系。

关于婴儿死亡率的结论

根据死亡率数据,婴儿死亡率也趋向于更高的特朗普支持率。在非西班牙裔黑人婴儿死亡率方面尤其如此,这种关系非常明显,模型拟合得非常好。

衣原体感染率(每 10 万人)与投票给特朗普的人数(%)

Figure 14.: A scatterplot relating rates of Chlamydia (per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.01594
p_F = 0.6329
p_t[𝝱0] = 1.7 * 10^(-8) ***
p_t[𝝱1] = 0.633

特朗普的支持度和衣原体感染率之间似乎没有明显或显著的关系。

淋病率(每 10 万人)与投票给特朗普的人(%)

Figure 15.: A scatterplot relating rates of Gonorrhea (per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.02107
p_F = 0.1582
p_t[𝝱0] = 1.13 * 10^(-15) ***
p_t[𝝱1] = 0.158

特朗普的支持率和淋病发病率之间似乎也没有明显或显著的关系。

梅毒发病率(每 10 万人)与投票给特朗普的人(%)

Figure 16.: A scatterplot relating rates of Syphilis (per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.04053
p_F = 0.08614
p_t[𝝱0] < 2 *10^(-16) ***
p_t[𝝱1] = 0.0861

特朗普的支持率和梅毒发病率之间似乎也没有明显或显著的关系。

关于性传播疾病的结论

性传播疾病和特朗普的支持率之间似乎没有明显的联系。

19-35 个月儿童的估计 MMR 疫苗接种覆盖率(%)与投票给特朗普的人(%)

Figure 17.: A scatterplot relating estimated MMR vaccination coverage among children aged 19–35 months (%) to percentage of people voting for Trump in each state.

R²_adj = 0.07459
p_F = 0.03083 *
p_t[𝝱0] = 0.00221 **
p_t[𝝱1] = 0.03083 *

在不太理想的拟合模型上存在非常小的相关性,表明特朗普支持度和 MMR 疫苗接种覆盖率之间存在潜在的负相关性。

19-35 个月儿童的 DTaP 疫苗接种覆盖率(%)与投票给特朗普的人群(%)

Figure 18.: A scatterplot relating estimated DTaP vaccination coverage among children aged 19–35 months (%) to percentage of people voting for Trump in each state.

R²_adj = 0.2246
p_F = 0.0003003 ***
p_t[𝝱0] = 1.33 * 10^(-6) ***
p_t[𝝱1] = 3 * 10^(-4) ***

有适度的证据表明,各州在 2016 年总统大选中支持特朗普,并降低了 DTaP 免疫的覆盖率。模型诊断似乎没有发出任何危险信号。

Breusch-Pagan p = 0.6658235                 | No heteroskedasticity!
Score test p = 0.6299109                    | No heteroskedasticity!
Shapiro-Wilk p = 0.7211                     | Normal distribution!
Kolmogorov-Smirnov p = 0.7435               | Normal distribution!
Anderson-Darling p = 0.6068                 | Normal distribution!
Durbin-Watson p = 0.296                     | Uncorrelated errors!

19-35 个月儿童中 HepB 疫苗接种覆盖率(%)与投票给川普的人群(%)

Figure 19.: A scatterplot relating estimated HepB vaccination coverage among children aged 19–35 months (%) to percentage of people voting for Trump in each state.

R²_adj = 0.05479
p_F = 0.05585
p_t[𝝱0] = 0.1628
p_t[𝝱1] = 0.0558

没有明显或显著的证据表明 HepB 疫苗接种覆盖率与 2016 年总统选举中对特朗普的支持之间存在关系。

19-35 个月儿童 HepA 疫苗接种覆盖率(%)与投票给特朗普的人群(%)

Figure 20.: A scatterplot relating estimated HepA vaccination coverage among children aged 19–35 months (%) to percentage of people voting for Trump in each state.

R²_adj = 0.01044
p_F = 0.4857
p_t[𝝱0] = 4.1 * 10^(-5) ***
p_t[𝝱1] = 0.486

就像 HepB 的情况一样,HepA 数据也缺乏与 2016 年总统选举数据的关系。

19-35 个月儿童轮状病毒疫苗接种覆盖率(%)与投票给特朗普的人群(%)

Figure 21.: A scatterplot relating estimated Rotavirus vaccination coverage among children aged 19–35 months (%) to percentage of people voting for Trump in each state.

R²_adj = 0.08274
p_F = 0.02417 *
p_t[𝝱0] = 2.22* 10^(-5) ***
p_t[𝝱1] = 0.0242 *

虽然这是一个可以接受的拟合,但这两个变量之间的相关性太小,无法做出任何推断。

关于疫苗接种的结论

除了 DTaP 疫苗接种覆盖率之外,所有疫苗接种覆盖率都没有随着特朗普的支持数据而变化。另一方面,DTaP 疫苗接种覆盖率似乎与特朗普支持率成反比。

暴力犯罪率(每 10 万人)与投票给特朗普的人的比率(%)

Figure 22.: A scatterplot relating rate of violent crime(per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.009291
p_F = 0.4624
p_t[𝝱0] = 5.1 * 10^(-13) ***
p_t[𝝱1] = 0.462

这两个变量之间没有明显的联系。

谋杀和非过失杀人的比率(每 10 万人)与投票给特朗普的人的比率(%)

Figure 23.: A scatterplot relating rate of murder and non-negligent manslaughter (per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.04231
p_F = 0.08158
p_t[𝝱0] < 2 * 10^(-16) ***
p_t[𝝱1] = 0.0816

这两个变量之间没有明显的联系。

强奸率(每 10 万人)与投票给特朗普的人(%)

Figure 24.: A scatterplot relating rate of rape (per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.05454
p_F = 0.05627
p_t[𝝱0] = 8.62* 10^(-13) ***
p_t[𝝱1] = 0.0563

这两个变量之间没有明显的联系。

抢劫率(每 10 万人)与投票给特朗普的人(%)

Figure 25.: A scatterplot relating rate of robbery (per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.07853
p_F = 0.02741 *
p_t[𝝱0] < 2 * 10^(-16) ***
p_t[𝝱1] = 0.0274 *

尽管模型拟合良好,但这两个变量之间没有明显的联系。

严重袭击率(每 10 万人)与投票给特朗普的人(%)

Figure 26.: A scatterplot relating rate of property crime (per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.05783
p_F = 0.05096
p_t[𝝱0] < 2 * 10^(-16) ***
p_t[𝝱1] = 0.051

这两个变量之间没有明显的联系。

财产犯罪率(每 10 万人)与投票给特朗普的人的比率(%)

Figure 27.: A scatterplot relating rate of property crime (per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.008801
p_F = 0.2368
p_t[𝝱0] = 2.45 * 10^(-9) ***
p_t[𝝱1] = 0.237

这两个变量之间没有明显的联系。

入室盗窃率(每 10 万人)与投票给特朗普的人(%)

Figure 28.: A scatterplot relating rate of burglary (per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.08126
p_F = 0.02526 *
p_t[𝝱0] = 1.1 * 10^(-13) ***
p_t[𝝱1] = 0.0253 *

尽管模型拟合良好,但这两个变量之间的相关性太低,无法对它们之间的关系做出结论。

盗窃率(每 10 万人)与投票给特朗普的人的比率(%)

Figure 29.: A scatterplot relating rate of larceny-theft (per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.0008896
p_F = 0.3121
p_t[𝝱0] = 3.96 * 10^(-8) ***
p_t[𝝱1] = 0.312

这两个变量之间没有明显的联系。

机动车辆盗窃率(每 10 万人)与投票给特朗普的人的比率(%)

Figure 30.: A scatterplot relating rate of motor-vehicle theft (per 100,000) to percentage of people voting for Trump in each state.

R²_adj = 0.01918
p_F = 0.7815
p_t[𝝱0] < 2 * 10^(-16) ***
p_t[𝝱1] = 0.781

这两个变量之间没有明显的联系。

关于暴力和财产犯罪的结论

暴力和财产犯罪与 2016 年总统选举中对特朗普的支持之间似乎没有关系。

WalletHub 教育程度和教育质量得分(1-100)与投票给特朗普的人(%)

Figure 31.: A scatterplot relating WalletHub Educational Attainment and Quality of Education Score (1–100) to percentage of people voting for Trump in each state.

R²_adj = 0.4414
p_F = 8.66 * 10^(-8) ***
p_t[𝝱0] < 2 * 10^(-16) ***
p_t[𝝱1] = 8.66 * 10^(-8) ***

有相对证据表明,各州在 2016 年总统大选中支持特朗普,并降低了教育程度和教育质量。模型诊断似乎没有发出任何危险信号。

Breusch-Pagan p = 0.7193591                 | No heteroskedasticity!
Score test p = 0.7333875                    | No heteroskedasticity!
Shapiro-Wilk p = 0.6670                     | Normal distribution!
Kolmogorov-Smirnov p = 0.9474               | Normal distribution!
Anderson-Darling p = 0.5443                 | Normal distribution!
Durbin-Watson p = 0.812                     | Uncorrelated errors!

根据这些结果,对特朗普的热情似乎与教育程度和教育质量成反比。

最终总结

  1. 特朗普的热情与教育程度和教育质量呈负相关。
  2. 特朗普热情与 DTaP 疫苗接种覆盖率负相关。
  3. 特朗普的热情与非西班牙裔黑人婴儿和整体婴儿死亡率正相关。
  4. 特朗普的热情与恶性肿瘤、心脏病、机动车事故、自杀和凶杀死亡率呈正相关。
  5. 克林顿的热情与自杀死亡率呈负相关。
  6. 特朗普的热情与性传播疾病之间,或者特朗普的热情与暴力和财产犯罪之间,不存在明显的联系。

来源:

  1. 联邦选举委员会(2017 年)。2016 年联邦选举:美国总统、美国参议院和美国众议院的选举结果。
  2. 徐,J.Q .,墨菲,S.L .,科查内克,K.D .,巴斯蒂安,b .,阿里亚斯,E. (2018)。死亡人数:2016 年最终数据。国家生命统计报告,67(5)。国家健康统计中心。
  3. 疾病控制和预防中心(2017 年)。2016 年性传播疾病监测。亚特兰大:美国卫生与公众服务部。
  4. 罗森,L.M .,巴斯蒂安,b .,华纳,m .,可汗,d .,崇,Y. (2017)。药物中毒死亡率:美国,1999-2016 年。国家健康统计中心。
  5. Hill,H. A .,Elam-Evans,L. D .,Yankey,d .,Singleton,J. A .,& Dietz,V. (2016)。19-35 个月儿童的疫苗接种覆盖率——美国,2015 年。MMWR。发病率和死亡率周报,65(39),1065–1071。
  6. 美国司法部联邦调查局。(2018).美国的犯罪,2017。
  7. 贝尔纳多河(2018)。2018 年美国受教育程度最高和最低的州。钱包枢纽。
.CSV and .description files available [here](http://www.franjoivankovic.com/2018/12/09/linear-correlations-of-2016-presidential-election-data-to-various-arbitrarily-chosen-data)!

线性回归—详细概述

原文:https://towardsdatascience.com/linear-regression-cost-function-gradient-descent-normal-equations-1d2a6c878e2c?source=collection_archive---------0-----------------------

有人问我 为什么我们使用线性回归?我回答了,对于的预测。他又问我什么是预测? 我用一个情况回答“假设你和我走在一条路上。我们来到了十字路口,现在我告诉你,我们将直走。这种情况会发生五次。现在在第六个十字路口。我问你我们将走哪条路。你的回答会是,我们会直走。这你说的就叫预测。他问我下一个问题我们是怎么做到的?我解释说,每当我们处于十字路口时,我们会查看数据,或者在这种情况下,我以前的回答,并考虑我们假设我们将直走。**

什么是线性回归?这是一种对因变量和自变量之间的关系进行建模的方法。又一个问题什么是自变量和因变量?现在下图有一些关于房子的数据。我们有“房子的面积”和“房子的成本”。我们可以看到,成本取决于房子的面积,当面积增加时,成本也会增加,当面积减少时,成本也会减少。所以我们可以说成本是因变量面积是自变量。在线性回归的帮助下,我们将对房屋成本和房屋面积之间的关系进行建模。****

Figure 1 : Example of House(Area vs Cost) Data set

模拟这种关系的最好方法是绘制一张成本和房子面积之间的图表。X 轴表示房屋的面积,Y 轴表示造价。回归会怎样?它将尝试通过这些点拟合直线。左图显示绘制的点,右图显示拟合这些点的线。

Figure 2 :Plotting Area of the house (X-axis) Vs Cost of house(Y-axis)

如果我们想借助上图预测房屋面积为 1100 平方英尺的房子的成本,可以按照下图所示进行,因为你可以看到 1100 平方英尺房子的成本大约是 35。

Figure 3 : Finding Cost of House when Area of house is 1100sq feet

在深入之前,我们应该理解一些术语,我将用它们来推导和解释数学解释。

Figure 4: Terms and Notations

  • M :=训练样本
  • x :=输入特征/变量。这些可以不止一个。
  • y :=输出特征/变量。
  • (x,y) :=训练示例。例:(1000,30)

这条线在数学上是如何表示的?

Figure 5: Hypothesis h(x)

h(x)在数学上表示线,因为现在我们只有一个输入特征,该方程将是线性方程,它也类似于线方程 "Y = mx + c "。现在我们来看看选择θ的值会对行产生什么影响。

Figure 6 : The value of theta will have effect the slope and intercept of the line. As you can in left and right images.

为什么是线性的?线性是基本的构建模块。我们将在后面讨论更复杂的问题,这些问题可能需要用到非线性函数或高次多项式

如何最好地拟合我们的数据?为了最好地拟合我们的数据,我们必须选择θ的值,使得 h(x)和 y 之间的差异最小。为了计算这个,我们将定义一个误差函数。正如你在下图中看到的。-

  • 误差函数由 h(x) — y 之差定义。
  • 我们将绝对误差作为误差的平方,因为有些点在线的上方和下方。
  • 为了得到所有点的误差,我们使用了求和法。
  • 平均,然后除以 2,以使计算更容易。它对总误差没有影响。

Figure 7 : Error Function Derivation(source : www.google.com/images))

现在来看一下θ和误差函数(J)之间的关系。我们将绘制θ和误差函数之间的图表。右下角的图像显示了 X 轴代表θ,Y 轴代表 J(θ)误差函数的图形。我们将假设θ0 为零。这意味着直线将始终通过原点。

Figure 8.1 : Plotting h(x) when theta_0 = 0 and theta_1 = 1

  • 我们假设了一些点(1,1),(2,2),(3,3),并假设θ0 = 0,θ1 = 1。我们计算了误差,显然它将是零。

Figure 8.2 : Calculation Of Error for Figure 8.1

Figure 8.3 : Plotting h(x) when theta_0 = 0 and theta_1 = 0.5

  • 然后,我们用值 0 和 0.5 重复相同的过程,我们得到的误差是 0.58,你也可以在图像中看到。这条线与给定点不太吻合。

Figure 8.4 : Calculation Of Error for Figure 8.3

Figure 8.5 : Graph between Error Function and Theta_1

  • 现在,如果取更多的θ值,我们会得到一些类似手绘的图(右下角),因为我们可以最小化θ1 = 1

但不幸的是,我们不能总是让θ0 = 0,因为如果我们可以,一些数据点就像下图所示,我们可以采取一些截距,或者我们永远无法达到最佳拟合,而θ0 有一些值,我们将绘制一个 3D 图,如右图所示。它将永远是保龄球形的图形。

Figure 9 : 3D plot while considering both Theta(source : www.google.com/images))

3D 再现很难研究。所以我们不会研究它们。我们将在 2D 绘制它们也被称为等高线图

在下图中,你会看到假设的等高线图。这些日食在图像中代表了什么?

  • 同一次月食中的任何一点都会给我们相同的误差函数值,因为左下图中用粉色表示的三个点会有相同的误差函数值。
  • 红点描述了左侧图像的假设,您将得到θ0(intecept)= 800 和θ1(slope)=-0.5,而在右下图中,θ0(intecept)= 500 和θ1(slope)= 0。所以你可以画一条平行于 x 轴的线。
  • 在左图中,红点远离椭圆的中心,线也不是很适合,但在右图中,读数更接近椭圆的中心,线也比左图更适合。因此,我们也可以得出结论,椭圆的中心将是θ的最小值或最佳值,这将最适合给定的数据点

Figure 10 : Contour Plots(source : www.google.com/images)

我们已经写了成本函数,但是如何最小化它呢?所以我们有解决问题的方法

  • 梯度下降
  • 正规方程

梯度下降

我们站在山顶,360 度环视四周。我们想朝着走下坡路的方向迈出一小步。在最佳方向的情况下,应该是最陡下降的方向。然后,我们到达一个点,我们遵循相同的步骤,直到我们到达地面的情况下,如下图。

Figure 11 : Gradient Descent (source : https://codesachin.wordpress.com/tag/gradient-descent/)

还有一件事。你确定你会一直达到同样的最小值吗?我可以保证你不确定。在梯度下降的情况下,你不能确定。让我们来看看山的问题。如果你从右边开始走几步,完全有可能到达完全不同的最小值,如下图所示

Figure 12 : Problem with Gradient Descent(source : https://codesachin.wordpress.com/tag/gradient-descent/)

我们将讨论梯度下降的数学互穿,但让我们理解如下一些术语和符号:

  • 阿尔法是学习率,描述你迈出的步伐有多大。
  • 导数给出了‘theta’切线的斜率,可以是正的也可以是负的,导数告诉我们将增加或减少‘theta’。
  • 同时更新意味着应该同时更新两个θ。

推导将由下式给出

Figure 13 : Gradient Descent Derivation

正规方程

由于梯度下降是一个迭代过程,正规方程有助于一次找到最优解。他们使用矩阵乘法。图像中解释了公式和符号。下图将解释我们的例子中的 X 和 y。X 的第一列总是 1,因为它将乘以θ0,我们知道θ0 是我们与轴的截距。

Figure 14 : Normal Equation with Example

下图解释了法线方程的推导过程。他们使用矩阵符号和性质。

这张图片解释了

  • θ矩阵
  • x '矩阵
  • 假设被扩展
  • 使用这些矩阵,我们可以重写上一步给出的假设

Figure 15: Notations in Normal Equations

图 16 解释了以下内容

  • 我们将在误差函数中替换我们的假设。
  • 我们假设 z 矩阵如步骤 2 所示
  • 误差函数可以重写为步骤 3。所以如果你把 Z 矩阵的转置和 Z 矩阵相乘。我们会得到第一步的等式
  • 我们可以分解步骤 2 中的 z,如步骤 4 所示。
  • 根据步骤 6 中给出的属性。我们将重写步骤 7 中给出的 z。大写 X 也被称为设计矩阵是小 X 的转置

Figure 16 : Normal Equation Derivation Part 1

  • 在等式中代入 z
  • 展开误差方程,然后对θ求导,使其等于 0。
  • 我们会找到解决办法的。如下图所示

Figure 17: Normal Equation Derivation Part 2

梯度下降法与正规方程的比较

  • 在梯度下降的情况下,我们需要选择α,θ的初始值,但是正规方程我们不需要选择α或θ。
  • 梯度下降是一个迭代过程,而正规方程马上给你答案。
  • 随着要素数量的增加,法线方程的计算速度会变慢,但梯度下降在要素数量非常大的情况下表现良好。

我们已经看到,线性回归是一种强大的算法,可用于建立关系模型并基于该关系预测值。我们还讨论了最小化误差的方法,以便我们可以获得我们的参数的最佳值。线性回归在分类问题上表现不佳。我们将在下一篇文章中讨论是什么算法克服了这个限制。继续读。

如果你想和我交流。请随时在 LinkedIn 上与我联系。

[## Sameer Negi —自动驾驶汽车培训生— Infosys | LinkedIn

查看 Sameer Negi 在全球最大的职业社区 LinkedIn 上的个人资料。Sameer 有 3 份工作列在他们的…

www.linkedin.com](https://www.linkedin.com/in/sameer-negi-356881115/)

线性回归-详细视图

原文:https://towardsdatascience.com/linear-regression-detailed-view-ea73175f6e86?source=collection_archive---------0-----------------------

Figure 1 : Linear Regression Graph ( Source: http://sphweb.bumc.bu.edu/otlt/MPH-Modules/BS/R/R5_Correlation-Regression/R5_Correlation-Regression_print.html)

线性回归用于寻找目标和一个或多个预测值之间的线性关系。有两种类型的线性回归-简单和多重。

简单线性回归

简单线性回归有助于发现两个连续变量之间的关系。一个是预测变量或自变量,另一个是响应变量或因变量。它寻找统计关系,而不是确定性关系。如果一个变量可以被另一个精确地表达,那么两个变量之间的关系就是确定的。例如,使用摄氏温度可以准确预测华氏温度。统计关系在确定两个变量之间的关系时不准确。比如身高和体重的关系。

核心思想是获得最适合数据的线。最佳拟合线是总预测误差(所有数据点)尽可能小的线。误差是点到回归线的距离。

(完整代码—https://github . com/SSaishruthi/Linear _ Regression _ Detailed _ Implementation)

实时例子

我们有一个数据集,其中包含有关“学习小时数”和“获得分数”之间关系的信息。已经观察了许多学生,记录了他们的学习时间和成绩。这将是我们的训练数据。目标是设计一个模型,如果给定学习的小时数,可以预测分数。使用训练数据,获得将给出最小误差的回归线。这个线性方程然后被用于任何新的数据。也就是说,如果我们给出学生学习的小时数作为输入,我们的模型应该以最小的误差预测他们的分数。

Y(pred) = b0 + b1*x

b0 和 b1 值的选择必须使误差最小。如果将误差平方和作为评估模型的指标,则目标是获得一条最能减少误差的直线。

Figure 2: Error Calculation

如果我们不平方误差,那么正负点就会互相抵消。

对于具有一个预测器模型,

Figure 3: Intercept Calculation

Figure 4: Co-efficient Formula

探索‘B1’

  • 如果 b1 > 0,那么 x(预测值)和 y(目标值)具有正的关系。也就是 x 的增加会增加 y。
  • 如果 b1 < 0, then x(predictor) and y(target) have a negative relationship. That is increase in x will decrease y.

探索‘B0’

  • 如果模型不包括 x=0,那么预测将变得没有意义,只有 b0。例如,我们有一个关于身高(x)和体重(y)的数据集。取 x=0(即身高为 0),将使方程只有 b0 值,这是完全没有意义的,因为在实时身高和体重永远不会为零。这是由于考虑了超出其范围的模型值。
  • 如果模型包括值 0,那么“b0”将是 x=0 时所有预测值的平均值。但是,将所有预测变量设置为零通常是不可能的。
  • b0 值保证剩余具有平均值零。如果没有' b0 '项,那么回归将被强制越过原点。回归系数和预测都会有偏差。

系数从正规方程

除了上述方程外,模型的系数也可以通过标准方程计算。

Figure 5: Co-efficient calculation using Normal Equation

θ包含所有预测值的系数,包括常数项“b0”。正规方程通过对输入矩阵求逆来执行计算。计算的复杂性将随着特征数量的增加而增加。当特征的数量变大时,它变得非常慢。

下面是该等式的 python 实现。

Figure 6: Python implementation of Normal Equation

使用梯度下降优化

正规方程的复杂性使得它很难使用,这就是梯度下降法发挥作用的地方。成本函数相对于参数的偏导数可以给出最佳系数值。

(梯度下降的完整详情在https://medium . com/@ saishruthi . TN/math-behind-gradient-descent-4d 66 EB 96d 68d)

梯度下降的 Python 代码

Figure 7: Python Implementation of gradient descent

残差分析

随机性和不可预测性是回归模型的两个主要组成部分。

预测=确定性+统计

确定性部分被模型中的预测变量覆盖。随机部分揭示了预期值和观察值不可预测的事实。总会有一些信息被遗漏。这个信息可以从剩余信息中获得。

我们通过一个例子来解释一下残数的概念。考虑一下,当给定一个地方的温度时,我们有一个预测果汁销售的数据集。回归方程预测的值与实际值总会有一些差异。销售额不会与真正的产值完全相符。这种差异被称为剩余。

残差图有助于使用残差值分析模型。它绘制在预测值和残差之间。他们的价值观是标准化的。该点与 0 的距离指定了该值的预测有多差。如果该值为正值,则预测值较低。如果该值为负,则预测值为高。0 值表示完全预测。检测残差模式可以改进模型。

残差图的非随机模式表明该模型,

  • 缺少对模型目标有重要贡献的变量
  • 缺少捕捉非线性(使用多项式项)
  • 模型中的术语之间没有交互

残留物的特征

  • 残差不显示任何模式
  • 相邻残差不应相同,因为它们表明系统遗漏了一些信息。

剩余实现和情节

Figure 8: Residual Plot

(其他一些参考资料— 1 ) & ( 参考资料— 2)

模型评估指标

R 平方值

该值的范围从 0 到 1。值“1”表示预测器完全考虑了 y 中的所有变化。值“0”表示预测器“x”没有考虑“y”中的任何变化。

1.回归平方和(SSR)

这给出了估计回归线离水平“无关系”线(实际产量的平均值)有多远的信息。

Figure 9: Regression Error Formula

2.误差平方和

目标值围绕回归线变化的程度(预测值)。

Figure 10: Sum of Square Formula

3.平方和总计(SSTO)

这表明数据点围绕平均值移动了多少。

Figure 11: Total Error Formula

Python 实现

Figure 12: Python Implementation of R-Square

R 平方的取值范围是否总是在 0 到 1 之间?

如果回归线强行穿过一个点,R2 的值可能最终为负。这将导致回归线强行穿过原点(无截距),产生的误差高于水平线产生的误差。如果数据远离原点,就会出现这种情况。

(模式详情—https://medium . com/@ saishruthi . TN/is-r-sqaure-value-always-between-0-to-1-36 a8d 17807 D1)

【相关系数(r)

这与“r 平方”的值有关,可以从符号本身观察到。它的范围从-1 到 1。

r = (+/-) sqrt(r)

如果 b1 的值为负,则‘r’为负,而如果 b1 的值为正,则‘r’为正。它是无单位的。

零假设和 P 值

零假设是研究者利用以前的研究或知识提出的最初主张。

低 P 值:拒绝指示预测值与响应相关的零假设

高 P 值:预测值的变化与目标值的变化无关

获得的回归线

Figure 13: Final Regression line over test data

完整代码:https://github . com/SSaishruthi/Linear _ Regression _ Detailed _ Implementation

这是一个由材料(如吴恩达教授的课程,Siraj Raval 的视频等)编辑而成的教育帖子。)在我的旅途中帮助了我。其他参考资料在内容附近说明。

— —未完待续

从头开始线性回归

原文:https://towardsdatascience.com/linear-regression-from-scratch-cd0dee067f72?source=collection_archive---------1-----------------------

数据科学正处于巅峰,使用机器学习模型你可以做很多事情,从预测股票价格到生成著名的蒙娜丽莎的假画(哦,这应该是一个秘密)。线性回归是最容易实现的机器学习算法之一,我们将在本文中探讨这种算法。

什么是线性回归?

线性回归是一种用于定义因变量( Y )和自变量( X )之间关系的方法。简单地写为:

其中 y 为因变量, m 为比例因子或系数, b 为偏差系数, X 为自变量。偏差系数为该模型提供了额外的自由度。目标是在 XY 之间画一条最佳拟合线,估计 XY 之间的关系。

但是我们如何找到这些系数,我们可以用不同的方法找到它们。一种是普通最小二乘法方法和梯度下降方法。我们将实现普通的最小均方方法。

普通最小均方误差

之前我们讨论了估算 XY 到一条直线的关系。例如,我们获得样本输入和输出,并在 2d 图上绘制这些分散点,类似于下图:

图中看到的线是我们要完成的实际关系,我们希望最小化模型的误差。这条线是穿过大多数散点的最佳拟合线,也减少了误差,误差是从点到线本身的距离,如下图所示。

而线性模型的总误差是各点误差之和。即,

rI =I 点与 i 点T34 点点之间的距离。

n = 总点数。

我们将每个距离平方,因为有些点会在线上,有些点会在线下。我们可以通过最小化 r 来最小化线性模型的误差,因此我们有

其中 x 是输入变量 X 的平均值,而 y 是输出变量 Y. 的平均值

现在让我们用 python 实现这个方法(有趣的部分)。

要继续下去,你需要 python 和你那令人敬畏的自我。使用 pip 我们将安装以下依赖项

  • numpy
  • 熊猫
  • matplotlib

我们将使用包含不同人的头部大小和大脑重量的数据集。该数据集可在本次回购中获得。

我们从导入数据集和依赖项开始

#import libraries
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import pandas as pddataset = pd.read_csv('dataset.csv')
print(dataset.shape)
dataset.head()(237, 4)

让我们找出头部大小和大脑重量之间的关系。

# initializing our inputs and outputs
X = dataset['Head Size(cm^3)'].values
Y = dataset['Brain Weight(grams)'].values# mean of our inputs and outputs
x_mean = np.mean(X)
y_mean = np.mean(Y)#total number of values
n = len(X)# using the formula to calculate the b1 and b0
numerator = 0
denominator = 0
for i in range(n):
    numerator += (X[i] - x_mean) * (Y[i] - y_mean)
    denominator += (X[i] - x_mean) ** 2

b1 = numerator / denominator
b0 = y_mean - (b1 * x_mean)#printing the coefficient
print(b1, b0)# output : 0.26342933948939945 325.57342104944223

现在我们有了偏差系数(b)和比例因子(m)。用数学术语来说:

***Brain weights =  325.57342104944223 + 0.26342933948939945 * Head size***

现在我们有了一个线性模型。

让我们用图表来描绘它。

#plotting values 
x_max = np.max(X) + 100
x_min = np.min(X) - 100#calculating line values of x and y
x = np.linspace(x_min, x_max, 1000)
y = b0 + b1 * x#plotting line 
plt.plot(x, y, color='#00ff00', label='Linear Regression')#plot the data point
plt.scatter(X, Y, color='#ff0000', label='Data Point')# x-axis label
plt.xlabel('Head Size (cm^3)')#y-axis label
plt.ylabel('Brain Weight (grams)')plt.legend()
plt.show()

我们需要能够衡量我们的模型有多好(准确性)。有许多方法可以实现这一点,但我们将实现均方根误差决定系数 ( R 分数)。

均方根误差是所有误差之和除以数值个数的平方根,或者从数学上讲,

这里的是第 与第 预测的输出值。现在我们会找到 RMSE。

*rmse = 0
for i in range(n):
    y_pred=  b0 + b1* X[i]
    rmse += (Y[i] - y_pred) ** 2

rmse = np.sqrt(rmse/n)print(rmse)#output : 72.1206213783709*

让我们找到我们的 R 分数,以便能够从数学上衡量我们的线性模型的准确性:

SST 是平方和的总和, SSR 是残差平方和的总和。

R 的分数通常在 0 到 1 之间。如果模型完全错误,它也会变成负数。现在我们将找到 R 的分数。

*sumofsquares = 0
sumofresiduals = 0for i in range(n) :
    y_pred = b0 + b1 * X[i]
    sumofsquares += (Y[i] - y_mean) ** 2
    sumofresiduals += (Y[i] - y_pred) **2

score  = 1 - (sumofresiduals/sumofsquares)print(score)#output : 0.6393117199570003*

0.63 当然不差,但我们可以通过以下方式提高分数:

  • 获取更多数据集
  • 改进功能
  • 适合多种型号等

结论

线性回归是所有机器学习算法的基础,也是最容易获得的,我们已经实现了普通最小均方方法来根据头部大小预测大脑重量,并且还使用均方根误差决定系数 ( R 分数)来测量准确度。代码可以在这个回购上找到。

信用:https://mubaris.com/posts/linear-regression/

用 6 行 Python 实现线性回归

原文:https://towardsdatascience.com/linear-regression-in-6-lines-of-python-5e1d0cd05b8d?source=collection_archive---------2-----------------------

在这篇简短的帖子中,我想分享一种方法,使用这种方法,您可以用 6 行 Python 代码执行线性和多元线性回归。

Check out the video version of this post if you prefer that !

在统计学中,线性回归是一种对因变量和一个或多个自变量之间的关系进行建模的线性方法。如果您想了解更多关于线性回归及其实现方式的信息,请查看这两种从头开始执行线性回归的方法:

[## 使用梯度下降的线性回归

在本教程中,你可以学习梯度下降算法的工作原理,并从头开始用 python 实现它。首先…

towardsdatascience.com](/linear-regression-using-gradient-descent-97a6c8700931) [## 使用最小二乘法的线性回归

线性回归是最简单的机器学习形式。在这篇文章中,我们将看到线性回归是如何…

towardsdatascience.com](/linear-regression-using-least-squares-a4c3456e8570)

今天,为了快速执行线性回归,我们将使用库 scikit-learn。如果您还没有它,您可以使用 pip 安装它:

pip install scikit-learn

现在让我们从几个导入开始:

我们需要 numpy 来执行计算,pandas 来导入本例中 csv 格式的数据集,matplotlib 来可视化我们的数据和回归线。我们将使用 LinearRegression 类来执行线性回归。

现在让我们执行回归:

我们在 Y_pred 中有我们的预测。现在让我们可视化数据集和回归线:

Data set in blue, Regression line in red

就是这样!您可以使用您选择的任何数据集,甚至可以使用 sklearn.linear_model 中的 Linear Regression 类执行多元线性回归(多个独立变量)。这个类也使用普通的最小二乘法来执行这个回归。因此,与其他技术相比,精确度不高。但是如果你想做一些快速预测,并对给你的数据集有所了解,那么这是一个非常方便的工具。

在这里找到数据集和代码:https://github . com/chasing infinity/ml-from-scratch/tree/master/03% 20 linear % 20 regression % 20 in % 202% 20 minutes

有问题吗?需要帮助吗?联系我!

电子邮件:adarsh1021@gmail.com

领英:https://www.linkedin.com/in/adarsh-menon-739573146/

推特:https://twitter.com/adarsh_menon_

insta gram:https://www.instagram.com/adarsh_menon_/

Python 中的线性回归

原文:https://towardsdatascience.com/linear-regression-in-python-9a1f5f000606?source=collection_archive---------1-----------------------

在线性回归中,在给定用于定型模型的定型数据的情况下,您试图构建一个允许您预测新数据值的模型。这将变得清晰,因为我们通过这个职位的工作。

Courtesy of Department of Statistics, ITS Surabaya

以上,我们可以看到简单的线性回归方程。y 变量被认为是我们的反应或因变量。这是我们打算预测的,比如销售是一个热门选择。

B0 是 y 轴截距,即 X=0,直线与 y 轴相交。B1X 本质上是我们的 B1(我们的 X 对我们的 y 的影响量),以及我们的 X,它是我们的特征/独立变量。与我们的 y 变量不同,多个 X 可以与相应的 beta(每个的系数)一起使用。这允许我们创建一个具有许多特征(X)变量的模型来预测 y 中的值。随机误差分量是不可约误差。

第一步:可视化

使用可视化,你应该能够判断哪些变量与 y 有线性关系。

在这种情况下,我们使用“销售”作为我们的回答/y。用您预期的功能列表替换测试版的变量列表

Seaborn Pairplot

要使用的附加参数:

size=:允许您操纵渲染的 pairplot 的大小

kind= 'reg ':将尝试添加最佳拟合线和 95%置信区间。目标是最小化误差平方和。

第二步:SK 学习—设置变量

Scikit-Learn 期望 X 是一个特征矩阵(Pandas Dataframe),y 是一个响应向量(Pandas Series)。让我们从如下分离变量开始。

处理您的功能(X):

在本例中,我们使用 TV、Radio 和 Social 列作为预测变量。

处理您的回答(y):

如果您想知道为什么大写的 X 表示特性,小写的 y 表示响应,这主要是由于惯例。

第三步:SK Learn —拆分我们的数据

将 X & y 分成训练集和测试集:

通过将 X 和 y 变量传递给 train_test_split 方法,我们能够通过将 4 个变量分配给结果来捕获数据中的分割。

第四步:SK Learn —训练我们的模型

首先,我们需要导入 sklearn.linear_model 来访问 LinearRegression。然后它需要被实例化,模型适合我们的训练数据。这是下面看到的。

Instantiate and fitting model to training data

第五步:解释系数

这些系数将允许我们用β值来模拟我们的方程。linreg 变量(分配给 LinearRegression 对象)能够使用下面的代码提取截距和系数。

Extracting data from model

截距就是你的 B0 值;并且每个系数将是通过的 X 的相应β(按照它们各自的顺序)。

第六步:根据你的模型进行预测

基于您的模型进行预测就像使用下面的代码一样简单:向 predict 方法传递您的测试数据。给定新的测试 X 数据,这将返回 y 的预测值。

Returns results of y predictions given X data in X_test

第七步:模型评估

有三个主要指标用于评估线性模型。这些是:平均绝对误差(MAE),均方误差(MSE),或均方根误差(RMSE)。

梅:最容易理解。代表平均误差

MSE:类似于 MAE,但噪声被夸大,较大的误差被“惩罚”。它比 MAE 更难解释,因为它不是基本单位,然而,它通常更受欢迎。

RMSE:最流行的度量,类似于 MSE,然而,结果是平方根,因为它是基本单位,所以更容易解释。建议将 RMSE 作为解释您的模型的主要指标。

下面,您可以看到如何计算每个指标。它们都需要两个列表作为参数,一个是您的预测值,另一个是真实值

第八步:特征选择

获得误差度量后,请注意哪些 X 对 y 的影响最小。移除其中一些特征可能会提高模型的准确性。

因此,我们开始了一个反复试验的过程,这个过程从头开始,直到一个令人满意的模型产生。以下步骤可能对这一特定部分有用。

  1. 替换特征列
  2. 训练 _ 测试 _ 分割您的数据
  3. 使用 linreg.fit 再次将模型拟合到 linreg
  4. 使用(y_pred = linreg.predict(X_test))进行预测
  5. 计算 RMSE
  6. 重复直到 RMSE 满意

Python 中的线性回归;预测湾区的房价

原文:https://towardsdatascience.com/linear-regression-in-python-predict-the-bay-areas-home-price-5c91c8378878?source=collection_archive---------0-----------------------

动机

为了预测湾区的房价,我选择了来自湾区房屋销售数据库Zillow 的房价数据集。该数据集基于 2013 年 1 月至 2015 年 12 月期间售出的房屋。它有很多学习的特点,数据集可以从这里下载。

数据预处理

import pandas as pd
sf = pd.read_csv('final_data.csv')
sf.head()

有几个功能是我们不需要的,比如“info”、“z_address”、“zipcode”(我们有“neighborhood”作为位置变量)、“zipid”和“zestimate”(这是 Zillow 估算的价格,我们不希望我们的模型受此影响),所以,我们将放弃它们。

sf.drop(sf.columns[[0, 2, 3, 15, 17, 18]], axis=1, inplace=True)sf.info()

“zindexvalue”的数据类型应该是数字,所以让我们更改一下。

sf['zindexvalue'] = sf['zindexvalue'].str.replace(',', '')
sf['zindexvalue'] = sf['zindexvalue'].convert_objects(convert_numeric=True)sf.lastsolddate.min(), sf.lastsolddate.max()

('01/02/2013 ',' 12/31/2015')

日期集中的房屋出售时间在 2013 年 1 月至 2015 年 12 月之间。

我现在使用 describe()方法来显示数字变量的汇总统计信息。

sf.describe()

计数、平均值、最小值和最大值行是不言自明的。std 显示标准偏差,25%、50%和 75%的行显示相应的百分位数。

为了了解我们正在处理的数据类型,我们为每个数字变量绘制了一个直方图。

%matplotlib inline
import matplotlib.pyplot as plt
sf.hist(bins=50, figsize=(20,15))
plt.savefig("attribute_histogram_plots")
plt.show()

Figure 1. A histogram for each numerical variable

一些直方图有点向右倾斜,但这并不异常。

让我们创建一个带有纬度和经度的散点图来可视化数据:

sf.plot(kind="scatter", x="longitude", y="latitude", alpha=0.2)
plt.savefig('map1.png')

Figure 2. A scatter plot of the data

现在让我们从最贵到最便宜的区域进行颜色编码:

sf.plot(kind="scatter", x="longitude", y="latitude", alpha=0.4, figsize=(10,7),
    c="lastsoldprice", cmap=plt.get_cmap("jet"), colorbar=True,
    sharex=False)

Figure 3. The Bay Area housing prices

这张图片告诉我们,最贵的房子是在北部地区。

我们要预测的变量是“最后成交价格”。所以我们来看看每个自变量和这个因变量的相关程度。

corr_matrix = sf.corr()
corr_matrix["lastsoldprice"].sort_values(ascending=False)

当完工面积和浴室数量增加时,最终售价往往会上升。你可以看到建造年份和上一次销售价格之间有一个小的负相关。最后,接近零的系数表示没有线性相关性。

我们现在将使用 Pandas 的scatter_matrix函数来可视化变量之间的相关性。我们将只关注几个有希望的变量,它们似乎与最后的销售价格最相关。

from pandas.tools.plotting import scatter_matrixattributes = ["lastsoldprice", "finishedsqft", "bathrooms", "zindexvalue"]
scatter_matrix(sf[attributes], figsize=(12, 8))
plt.savefig('matrix.png')

Figure 4. a scatter matrix

预测最后销售价格的最有希望的变量是完成的平方英尺,所以让我们放大它们的相关散点图。

sf.plot(kind="scatter", x="finishedsqft", y="lastsoldprice", alpha=0.5)
plt.savefig('scatter.png')

Figure 5. Finished sqft vs. Last Sold Price

相关性确实很强;你可以清楚地看到上升的趋势,而且这些点不是太分散。

因为每个房子有不同的平方英尺,每个社区有不同的房价,我们真正需要的是每平方英尺的价格。于是,我们添加了一个新的变量“price_per_sqft”。然后,我们检查这个新的独立变量与最后销售价格的相关性。

sf['price_per_sqft'] = sf['lastsoldprice']/sf['finishedsqft']
corr_matrix = sf.corr()
corr_matrix["lastsoldprice"].sort_values(ascending=False)

不幸的是,新的 price_per_sqft 变量只显示了与最后销售价格非常小的正相关性。但是我们仍然需要这个变量来对邻居进行分组。

数据里有 71 个小区,我们准备分组。

len(sf['neighborhood'].value_counts())

71

以下步骤将邻域聚类成三组:1 .价格低;2.高价低频;3.高价高频。

freq = sf.groupby('neighborhood').count()['address']
mean = sf.groupby('neighborhood').mean()['price_per_sqft']
cluster = pd.concat([freq, mean], axis=1)
cluster['neighborhood'] = cluster.indexcluster.columns = ['freq', 'price_per_sqft','neighborhood']cluster.describe()

这些是低价格社区:

cluster1 = cluster[cluster.price_per_sqft < 756]
cluster1.index

索引(【‘湾景’,‘中央里士满’,‘中央日落’,‘克罗克亚马逊’,
‘戴利市’,‘钻石高地’,‘精益求精’,‘森林山’,
‘森林山延伸’,‘金门高地’,‘英格莱赛德’,‘英格莱赛德高地’,‘英格莱赛德露台’,‘内公园边’,
‘内里士满’,‘内日落’,‘湖岸’,‘小好莱坞’,
‘默塞德高地’,‘米申台’,‘戴维森山庄园’,
‘海景’,‘外宣’,‘外

这些是高价格和低频率的社区:

cluster_temp = cluster[cluster.price_per_sqft >= 756]
cluster2 = cluster_temp[cluster_temp.freq <123]
cluster2.index

索引(['布埃纳维斯塔公园','中央滨水区—多克帕奇','科罗纳高地','海特—阿什伯里','湖边','孤山','中城露台',
'北海滩','北部滨水区','帕纳萨斯—阿什伯里','普雷斯迪奥高地','海崖','圣弗朗西斯伍德','电报山','双峰'],dtype='object ',name='neighborhood')

这些是高价格和高频率的社区:

cluster3 = cluster_temp[cluster_temp.freq >=123]
cluster3.index

索引(['Bernal Heights ',' Cow Hollow ',' Downtown ',' Eureka Valley-Dolores Heights-Castro ',' Glen Park ',' Hayes Valley ',' Lake ',' Lower Pacific Heights ',' Marina ',' Miraloma Park ',' Mission ',' Nob Hill ',' Noe Valley ',' North Panhandle ',' Pacific Heights ',' Potrero Hill ',' Russian Hill ',' South Beach ',' South ' Market ',' Van Ness-civice centre ',' Yerba

我们根据集群添加一个组列:

def get_group(x):
    if x in cluster1.index:
        return 'low_price'
    elif x in cluster2.index:
        return 'high_price_low_freq'
    else:
        return 'high_price_high_freq'
sf['group'] = sf.neighborhood.apply(get_group)

在执行上述预处理后,我们不再需要以下列:“address,lastsolddate,latitude,longitude,neighborhood,price_per_sqft”,因此,我们从分析中删除它们。

sf.drop(sf.columns[[0, 4, 6, 7, 8, 13]], axis=1, inplace=True)
sf = sf[['bathrooms', 'bedrooms', 'finishedsqft', 'totalrooms', 'usecode', 'yearbuilt','zindexvalue', 'group', 'lastsoldprice']]
sf.head()

我们的数据看起来很完美!

但是在构建模型之前,我们需要为这两个分类变量创建虚拟变量:“usecode”和“group”。

X = sf[['bathrooms', 'bedrooms', 'finishedsqft', 'totalrooms', 'usecode', 'yearbuilt', 
         'zindexvalue', 'group']]
Y = sf['lastsoldprice']

n = pd.get_dummies(sf.group)
X = pd.concat([X, n], axis=1)m = pd.get_dummies(sf.usecode)
X = pd.concat([X, m], axis=1)drops = ['group', 'usecode']
X.drop(drops, inplace=True, axis=1)X.head()

这是我们的数据在创建虚拟变量后的样子:

训练并建立线性回归模型

from sklearn.cross_validation import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=0)from sklearn.linear_model import LinearRegression
regressor = LinearRegression()
regressor.fit(X_train, y_train)

搞定了。我们现在有一个工作的线性回归模型。

计算 R 的平方:

*y_pred = regressor.predict(X_test)
print('Linear Regression R squared": %.4f' % regressor.score(X_test, y_test))*

线性回归 R 的平方:0.5619

因此,在我们的模型中,Y 的 56.19%的可变性可以用 x 来解释。这并不令人兴奋。

计算均方根误差(RMSE)

*import numpy as np
from sklearn.metrics import mean_squared_error
lin_mse = mean_squared_error(y_pred, y_test)
lin_rmse = np.sqrt(lin_mse)
print('Linear Regression RMSE: %.4f' % lin_rmse)*

线性回归 RMSE: 616071.5748

我们的模型能够预测测试集中每栋房子的价格,误差在 616071 美元以内。

计算平均绝对误差(MAE):

*from sklearn.metrics import mean_absolute_errorlin_mae = mean_absolute_error(y_pred, y_test)
print('Linear Regression MAE: %.4f' % lin_mae)*

线性回归 MAE: 363742.1631

随机森林

让我们尝试一个更复杂的模型,看看结果是否可以改进 RandomForestRegressor:

*from sklearn.ensemble import RandomForestRegressorforest_reg = RandomForestRegressor(random_state=42)
forest_reg.fit(X_train, y_train)*

RandomForestRegressor(bootstrap = True,criterion='mse ',max_depth=None,max_features='auto ',max_leaf_nodes=None,
min _ infinity _ split = 1e-07,min_samples_leaf=1,
min_samples_split=2,min_weight_fraction_leaf=0.0,
n_estimators=10,n_jobs=1,oob_score=False,random_state=42,
详细

*print('Random Forest R squared": %.4f' % forest_reg.score(X_test, y_test))*

随机森林 R 的平方】:0.6491

*y_pred = forest_reg.predict(X_test)
forest_mse = mean_squared_error(y_pred, y_test)
forest_rmse = np.sqrt(forest_mse)
print('Random Forest RMSE: %.4f' % forest_rmse)*

随机森林 RMSE: 551406.0926

好多了!让我们再试一次。

梯度推进

*from sklearn import ensemble
from sklearn.ensemble import GradientBoostingRegressor
model = ensemble.GradientBoostingRegressor()
model.fit(X_train, y_train)*

GradientBoostingRegressor(alpha = 0.9,criterion='friedman_mse ',init=None,learning_rate=0.1,loss='ls ',max_depth=3,max_features=None,max_leaf_nodes=None,min _ infinity _ split = 1e-07,
min_samples_leaf=1,min_samples_split=2,min_weight_fraction_leaf=0.0,n _ estimators = 100,预排序='auto ',random_state

*print('Gradient Boosting R squared": %.4f' % model.score(X_test, y_test))*

梯度增强 R 的平方】:0.6616

*y_pred = model.predict(X_test)
model_mse = mean_squared_error(y_pred, y_test)
model_rmse = np.sqrt(model_mse)
print('Gradient Boosting RMSE: %.4f' % model_rmse)*

渐变助推 RMSE: 541503.7962

这是我们迄今为止最好的结果,所以,我认为这是我们的最终模型。

特征重要性

我们在模型中使用了 19 个特征(变量)。让我们找出哪些特性是重要的,反之亦然。

*feature_labels = np.array(['bathrooms', 'bedrooms', 'finishedsqft', 'totalrooms', 'yearbuilt', 'zindexvalue', 
                           'high_price_high_freq', 'high_price_low_freq', 'low_price', 'Apartment', 'Condominium', 'Cooperative', 
                          'Duplex', 'Miscellaneous', 'Mobile', 'MultiFamily2To4', 'MultiFamily5Plus', 'SingleFamily', 
                           'Townhouse'])
importance = model.feature_importances_
feature_indexes_by_importance = importance.argsort()
for index in feature_indexes_by_importance:
    print('{}-{:.2f}%'.format(feature_labels[index], (importance[index] *100.0)))*

最重要的特征是完工面积、zindex 值、浴室数量、总房间数、建造年份等等。最不重要的特征是公寓,这意味着不管这个单元是否是公寓,对出售价格都无关紧要。总的来说,这 19 个特性大部分都用上了。

轮到你了!

希望这篇文章能让你对机器学习回归项目有一个好的了解。正如你所看到的,大部分工作都在数据争论和准备步骤中,这些程序消耗了花在机器学习上的大部分时间。

现在是时候走出去,开始探索和清理您的数据了。尝试两三个算法,然后告诉我进展如何。

创建这篇文章的源代码可以在这里找到。我将很高兴收到关于上述任何反馈或问题。

现实生活中的线性回归

原文:https://towardsdatascience.com/linear-regression-in-real-life-4a78d7159f16?source=collection_archive---------0-----------------------

用数学解决现实世界的问题

Photo by Roman Mager on Unsplash

我们在学校里学到了很多有趣和有用的概念,但有时我们不太清楚如何在现实生活中运用它们。

一个可能被广泛低估的概念/工具是线性回归

假设你正计划和你的两个好朋友去拉斯维加斯旅行。你从旧金山出发,知道要开大约 9 个小时的车。你的朋友负责聚会的运作,而你负责所有相关的后勤工作。你必须计划好每一个细节:时间表,什么时候停下来,在哪里,确保你准时到达那里...

那么,你做的第一件事是什么?你悄悄地从地球上消失,不再回你朋友的电话,因为他们会在你当派对警察的时候玩得很开心?!不,你给自己一张白纸,开始计划吧!

你清单上的第一项是什么?预算!这是一次 9 小时——大约 1200 英里——的有趣旅程,所以路上总共 18 小时。后续问题:我应该拨多少钱买汽油?

这是一个非常重要的问题。你不会想在高速公路中间停下来,可能只是因为没油而走了几英里!

你应该花多少钱买汽油?

你带着以科学为导向的心态来处理这个问题,认为必须有一种方法根据你旅行的距离来估计所需的钱数。

首先,你看一些数据。

在过去的一年里,你一直在努力跟踪你的汽车的效率——因为谁没有呢!—所以在你电脑的某个地方有这个电子表格

The beauty of dummy data 😄

在这一点上,这些只是数字。从这个电子表格中获取任何有价值的信息都不太容易。

然而,像这样绘制,很明显,在没有加满油箱的情况下,你能开多远是有某种“联系”的。不是说你以前不知道,但是现在有了数据,事情就变得很清楚了。

你真正想弄清楚的是

"如果我开 1200 英里,我要付多少油钱?"

为了回答这个问题,你将使用到目前为止你已经收集的数据,并用它来预测你将花费多少。这个想法是,你可以根据过去的数据——你辛辛苦苦记录的数据点——对未来——你的拉斯维加斯之旅——进行估计性的猜测。

你最终得到一个数学模型,描述了行驶里程和加满油所花的钱之间的关系。

一旦这个模型被定义,你可以向它提供新的信息——你从旧金山开车到拉斯维加斯有多少英里——这个模型将预测你需要多少钱。

Example of plot of your dataset (data from the past) and your predictions (data from the future)

该模型将使用过去的数据来了解行驶总里程数和支付的总油费之间的关系。

当呈现给它一个新的数据点时,你从旧金山开车到拉斯维加斯有多少英里,模型将利用它从所有过去的数据中获得的知识,并提供它的最佳猜测——一个预测,即你来自未来的的数据点。

回头看看你的数据,你会发现,通常,你在汽油上花的越多,在汽油耗尽之前你能开的时间就越长——假设汽油价格保持不变。

如果你让最好地描述——或者“解释”——上图中的关系,它看起来会是这样的

很明显,行驶里程和汽油总费用之间有一个线性关系。因为这种关系是线性的,如果你花更少/更多的钱——例如,油箱加满一半——你就能开更少/更多的里程。

因为这种关系是线性的,而且你知道从旧金山到拉斯维加斯的车程有多长,所以使用线性模型将帮助你预测你将为汽油花费多少预算。

线性回归模型

最能描述总行驶里程和总支付汽油费用之间关系的模型类型是 线性回归模型 。回归部分在这里,因为你试图预测的是一个数值。

这里有几个概念需要解释:

  • 因变量
  • 独立变量
  • 拦截
  • 系数

你要为汽油预算的金额取决于你要开多少英里,在这种情况下,从旧金山到拉斯维加斯。因此,为天然气支付的总费用是模型中的因变量

另一方面,拉斯维加斯哪儿也不去,所以从三藩市到拉斯维加斯你需要开多少英里与你在加油站支付的费用无关——行驶的英里数是模型中的独立变量。让我们暂时假设油价保持不变。

由于我们只处理一个独立变量,该模型可以指定为:

这是一个简单版本的线性组合,其中只有一个变量。如果你想在计算中更加严谨,你也可以在这个模型中加入每桶石油的价格作为独立变量,因为它会影响天然气的价格。

模型的所有必要部分都准备好了,剩下的唯一问题是:B0、B1 和 B2 呢?

B0,*读作“Beta 0”,是模型的截距,意思是当每个因变量都等于零时,你的自变量取的值。你可以把它想象成一条穿过轴的原点的直线。***

Different intercept values for the linear model: y = Beta0+ 2x

“β1”和“β2”是所谓的系数。模型中的每个独立变量都有一个系数。它们决定了描述模型的回归线的斜率。

如果我们以上面的例子为例,一个由 y= Beta0 + Beta1x,指定的模型,并使用不同的 Beta 1 值,我们会得到这样的结果

Different coefficient values for the linear model: y = 1 + Beta1x

这些系数解释了因变量的变化率,即当每个自变量变化一个单位时,你要支付的汽油价格。

因此,在上面蓝线的情况下,自变量 x 每改变一个单位,因变量 y 就改变 1 倍。
因此,对于绿线,该效应是因变量 x 单位变化的 4 倍

普通最小二乘法

至此,我们已经讨论了线性模型,甚至对截距和系数插入不同的值进行了实验。

然而,为了计算出你去拉斯维加斯旅行要付多少油钱,我们需要一种机制来估算这些价值。

有不同的技术来估计模型的参数。其中最流行的是普通最小二乘法(OLS)

普通最小二乘法的前提是最小化模型的残差的平方和。即数据集中预测值和实际值之间的差异,即距离。

通过这种方式,模型计算出最佳参数,因此回归线中的每个点都尽可能地接近数据集。

在预算练习的最后,有了模型参数,你就可以输入你期望驾驶的总里程,并估计你需要为汽油分配多少。

很好,现在你知道你应该为汽油预算 114.5 美元!

你会注意到我们的模型中没有参数β0。在我们的用例中,有一个截距——或者当因变量等于零时有一个常数值——没有多大意义。对于这个特定的模型,我们强迫它通过原点,因为如果你不开车,你就不会花任何油钱。

下一次,当你发现自己需要根据一系列可以用直线描述的因素来估算一个数量时——你知道你可以使用线性回归模型

感谢阅读!

野外线性回归

原文:https://towardsdatascience.com/linear-regression-in-the-wild-335723a687e8?source=collection_archive---------11-----------------------

在一次数据科学家职位的面试中,我接到了一个家庭作业,我想和你分享一下。

面试官给我发了一个 CSV 文件,里面有实测量 xy 的样本,其中 y 是一个响应变量,可以写成 x 的显函数。众所周知,在标准偏差的意义上,用于测量 x 的技术比用于测量 y 的技术好两倍。

任务:将 y 建模为 x 的函数。

这是我需要的所有进口货:

import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
from scipy.stats import probplotimport matplotlib.pyplot as plt
%matplotlib inlinedata = pd.read_csv('data.csv', names=['x', 'y'])
data.head()

让我们将数据可视化,看看是否容易用肉眼捕捉到模式:

data.plot.scatter('x', 'y', title='data')

这看起来很像线性回归的情况。首先,我将手动移除异常值:

data = data[data['x'] < 600]
data.plot.scatter('x', 'y', title='data without outliers')

我将使用LinearRegression来拟合最佳线条:

lr = LinearRegression().fit(data[['x']], data['y'])
data.plot.scatter('x', 'y', title='linear regression')
lr_predicted_y = lr.predict(data[['x']])
plt.plot(data['x'], lr_predicted_y)

fitting a line through the data

视觉上看起来很有说服力,但我会验证线性回归假设,以确保我使用的是正确的模型。

如果你对线性回归假设不熟悉,你可以在文章用假设深入回归分析,绘制&解中阅读。

首先,我们将绘制残差图:

residuals = lr_predicted_y - data['y']
plt.scatter(x=lr_predicted_y, y=residuals)
plt.title('residuals')

  • 残差中似乎没有自相关。
  • 异方差在这里看起来也不是问题,因为方差看起来几乎是恒定的(除了图的左边部分,但是没有太多的数据,所以我会忽略它)。
  • 多重共线性在这里不相关,因为只有一个因变量。
  • 残差应呈正态分布:我将使用 QQ-plot 验证:
probplot(residuals, plot=plt)

这看起来相当正常…

我的结论是,假设线性关系,x 和 y 之间的关系最好建模为

print 'y = %f + %f*x'  % (lr.intercept_, lr.coef_)>>> y = 70.023655 + 2.973585*x

给定 x (两者都有测量误差),或者换句话说,线的系数,我们得到了计算 y 所需参数的一致估计值。

到目前为止,我所做的只是简单的线性回归。关于这个任务有趣的事情是 x 有测量误差(这在真实世界用例中是典型的)。

如果我们想要在给定精确的 x 值(没有测量误差)的情况下估计计算 y 所需的参数,我们需要使用不同的方法。使用简单的线性回归而不考虑随机噪声的 x 导致线斜率略小于真实的线斜率(描述没有测量误差的 x 的线)。你可以阅读这个维基页面来了解原因。

我将使用戴明回归,这是一种当两个变量 xy 的误差被假设为独立且正态分布,并且它们的方差比(表示为 δ )已知时可以使用的方法。这种方法非常适合我们的环境

在标准偏差的意义上,用于测量 x 的技术比用于测量 y 的技术好两倍。

所以在我们的设置中, δ 是 2 的平方。

使用在维基页面中找到的公式,我们得到

cov = data.cov()
mean_x = data['x'].mean()
mean_y = data['y'].mean()
s_xx = cov['x']['x']
s_yy = cov['y']['y']
s_xy = cov['x']['y']
delta = 2 ** 2slope = (s_yy  - delta * s_xx + np.sqrt((s_yy - delta * s_xx) ** 2 + 4 * delta * s_xy ** 2)) / (2 * s_xy)
intercept = mean_y - slope  * mean_x

使用戴明回归,将 xy 之间的关系建模为

print 'y = %f + %f*x'  % (intercept, slope)>>> y = 19.575797 + 3.391855*x

让我们绘制两个模型:

data.plot.scatter('x', 'y', title='linear regression with & without accounting for $x$ error measurements')
plt.plot(data['x'], lr_predicted_y, label='ignoring errors in $x$')
X = [data['x'].min(), data['x'].max()]
plt.plot(X, map(lambda x: intercept + slope * x, X), label='accounting for errors in $x$')
plt.legend(loc='best')

我们拟合了两个模型:一个是简单的线性回归模型,另一个是考虑到 x 中的测量误差的线性回归模型。

如果我们的目的是给定一个具有测量误差的新的 x 来计算 y (由与训练模型时使用的测量误差相同的分布产生),则更简单的方法可能就足够了。

如果我们想在一个没有测量误差的世界里,将 y 的真实关系描述为 x 的函数,我们应该使用第二个模型。

这是一个很好的面试问题,因为我学到了一种新的模式,这是非常整洁的:)

尽管这并不是如标题所示的线性回归的真实例子(好吧,我撒谎了),这篇文章确实展示了许多人没有注意到的一个重要概念:在许多情况下,因变量是以不准确的方式测量的,这可能需要加以考虑(取决于应用)。

小心退步!

这个帖子最初是我在 www.anotherdatum.com发的。

如何建立简单的线性回归模型?

原文:https://towardsdatascience.com/linear-regression-model-899558ba0fc4?source=collection_archive---------2-----------------------

这篇文章是关于一步一步地为 ML 初学者实现简单的线性回归模型,并有详细的解释。

如果你是机器学习的新手,请查看 这篇 的帖子,了解机器学习及其基础知识。

简单线性回归模型背后的逻辑是什么?

顾名思义,线性回归遵循从一个给定自变量的值确定一个因变量的值的线性数学模型。还记得学校里的线性方程吗?

y=mx+c

其中 y 是因变量,m 是斜率,x 是自变量,c 是给定直线的截距。

我们也有多元回归模型,其中多个自变量用于计算一个因变量。

我已经用 Jupyter 笔记本实现了。您可以选择使用任何 Python IDE 所以让我们开始吧..

步骤 1:导入库

Step 1

Python 中已经开发了用于实现机器学习模型的库。

第一个名为 matplotlib 的库用于在最后一步绘制图形。“plt”用作变量名,用于在前面的代码中使用该库。

sklearn 是 python 中的官方机器学习库,用于各种模型实现。

numpy 用于将数据转换成数组,供 sklearn 库实际使用。

熊猫是用来访问的。数据集的 csv 文件。

步骤 2:加载数据集

我们的数据集是. csv 文件类型。Pandas 变量 pd 用于通过 read_csv()函数访问数据集。

第三步:分解为自变量和因变量

我们通过 iloc(索引位置)值定义 x 为数据集中的自变量。[]用于定义数组元素。":"[]内表示考虑数据集中的所有行,并使用" "分隔。我们指定要用作自变量或因变量的列数,从数据集中的零开始计数。

步骤 4:将数据分为训练数据和测试数据

现在,整个数据集被分为训练集和测试集,这样预测就不会过拟合或欠拟合,从而获得正确值。train_test_split()是 scikit learn 的内置函数,用于拆分 x 和 y 变量数据。“test_size”参数用于将整个数据集(30%)的 1/3 划分为测试数据,其余部分作为训练数据。将 random_state 设置为 null 将不允许从数据集中获取随机值。

第五步:选择模型

我们重塑我们的自变量,因为 sklearn 期望一个 2D 数组作为输入。

这里的线性回归是我们的模型,模型的变量名为“lin_reg”。我们也可以用许多其他模型来尝试相同的数据集。该部分因型号而异,否则所有其他步骤都与此处描述的相似。

第六步:符合我们的模型

现在,我们通过用自变量和因变量训练模型,使我们的模型适合线性回归模型。

第七步:预测输出

最后,我们的模型使用自变量的测试值来预测因变量“lin_reg_pred”。

我们可以看到异常值的系数、截距值,以及预测值(lin_reg_pred)和因变量的实际测试值(y_test)的均方误差和方差。内置方法使用预定义的公式计算每个值。

第八步:绘制图表

我们最终希望以图形格式可视化实际数据值和预测数据值。matplotlib 变量“plt”用于使用“scatter()”绘制点,使用“plot()”函数绘制异常值。

输出可能因不同的系统功能而异。我得到的输出如下:

Output

Output Graph

就是这个!我们的第一个线性回归模型实现了!下面是我们在这里实现的整个模型的完整代码的链接。

[## ditsme/机器学习

机器学习——我所有的机器学习项目

github.co](https://github.com/ditsme/MachineLearning)

在 LinkedIn 上关注我:www.linkedin.com/comm/mynetwork/discovery-see-all?use case = PEOPLE _ FOLLOWS&follow member = dit modi

线性回归:建模和假设

原文:https://towardsdatascience.com/linear-regression-modeling-and-assumptions-dcd7a201502a?source=collection_archive---------7-----------------------

Source: HD Wallpapers

回归分析是一种功能强大的统计过程,用于查找数据集中的关系,重点关注自变量(预测值)和因变量(结果)之间的关系。它可用于构建推理或预测模型。在回归分析的几种方法中,线性回归奠定了基础,并被广泛用于几个现实世界的应用中。

在这篇文章中,我们将着眼于建立一个线性回归模型进行推理。我们将使用的数据集是从 Kaggle 获得的保险费用数据。这个数据集由 1,338 个观察值和 7 列组成:年龄、性别、bmi、儿童、吸烟者、地区和费用。

我们要问的关键问题是:

  1. 医疗收费和数据集中的其他变量有关系吗?
  2. 我们建立的模型有多有效?
  3. 我们能做些什么来改进模型?

Source : Google Images

我们从导入所需的主要库和数据开始:

library(magrittr)
library(car)
library(broom)
library(ggplot2)fileName <- './input/medicalCost/insurance.csv'insurance <- read.csv(fileName)
summary(insurance)

从摘要中可以得出一些简单的观察结果:

  1. 参与者的年龄从 18 岁到 64 岁不等。
  2. 大约 49.48%的参与者是女性。
  3. 参与者的 bmi 从 15.96 到 53.13 不等。
  4. 只有 20.48%的参与者是吸烟者。

让我们从建立一个线性模型开始。在简单的线性回归中,只有一个预测因子和一个结果,我们将采用多元线性回归,有多个预测因子和一个结果。

多元线性回归遵循以下公式:

这个线性方程中的系数表示预测值和响应之间的加性关系的大小。更简单地说,在保持其他一切不变的情况下,x1 的单位变化将导致结果中β1 的变化,依此类推。

医疗收费和预测因素有关系吗?

我们的第一步是发现结果和预测之间是否有任何关系。

无效假设是任何预测值和反应之间没有关系,这可以通过计算 F 统计量来检验。F 统计量的 p 值可用于确定是否可以拒绝零假设。

我们将从使用所有预测值拟合多元线性回归模型开始:

lm.fit <- lm(formula = charges~., data = insurance) 
*#Here '.' means we are using all the predictors in the dataset.
* 
summary(lm.fit)

具有非常低的 p 值(< 2.2e-16)的高 F 统计值意味着可以拒绝零假设。这意味着预测因素和结果之间存在潜在的联系。

RSE(剩余标准误差)是对不可约误差(即使我们知道真实回归线也无法减少的误差)的标准偏差的估计;因此,不可约)。简单来说,就是实际结果与真实回归线的平均偏差。RSE (6062)的大值意味着我们的模型与真实回归线的高偏差。

R-squared (R)衡量模型可以解释的结果中可变性的比例,并且几乎总是在 0 和 1 之间;该值越高,模型就越能更好地解释结果的可变性。然而,由于 R 平方的膨胀,预测因子数量的增加通常会导致 R 值的增加。调整 R 的平方调整 R 的值以避免这种影响。较高的调整后 R 值(0.7494)表明数据中超过 74%的方差可以用模型来解释。

性病。误差给出了预测器的估计系数与预测器的实际系数之差的平均值。它可以用来计算估计系数的置信区间,我们将在后面看到。

预测器的 t 值告诉我们它的估计系数距离 0 有多少个标准差。预测值的 Pr ( > |t|) 是估计的回归系数的 p 值,这与说明看到回归系数的 t 值的概率相同。预测值的非常低的 p 值(< 0.05)可用于推断预测值和结果之间存在关系。

我们的下一步应该是回归分析的验证。这可能意味着验证模型的潜在假设,用不同的预测值检查模型的结构,寻找模型中没有足够好地表示的观察值,等等。我们将研究其中的一些方法和假设。

哪些变量与医疗费用有很大关系?

既然我们已经确定了预测因素和结果之间的关系,我们的下一步将是找出是否所有或只有一些预测因素与结果相关。

如果我们查看上面估计系数的 p 值,我们会发现并非所有系数都具有统计显著性(< 0.05)。这意味着只有预测因子的子集与结果相关。

我们可以查看各个 p 值来选择变量。当预测值的数量(7)与观察值的数量(1338)相比非常小时,这可能不是问题。然而,由于多重测试问题,当预测值的数量大于观察值的数量时,这种方法将不起作用。选择预测值的更好方法是特征/变量选择方法,如前向选择、后向选择或混合选择。

在使用这些方法进行特征选择之前,让我们尝试使用仅具有显著 p 值的特征进行线性回归。

lm.fit.sel <- lm(charges~age+bmi+children+smoker+region, 
    data = insurance)

我们将这与混合选择(T4)进行比较,混合选择是向前和向后选择的结合。这可以在 R 中使用 stepAIC() 函数来完成,该函数使用 Akaike 信息标准 (AIC)从多个模型中选择最佳模型。

**#selecting direction = "both" for mixed selection** 
step.lm.fit <- MASS::stepAIC(lm.fit, direction = "both", 
    trace = FALSE)

让我们比较一下这两种模型:

step.lm.fit$call
lm.fit.sel$call

逐步选择给出的模型与我们通过选择具有显著 p 值的预测因子得到的模型相同(在这种情况下有效)。

有什么多重共线性特征吗?

多重回归中的多重共线性是一种现象,其中两个或多个预测因子彼此高度相关,因此一个预测因子可用于预测另一个预测因子的值。多重共线性的问题是,它会使估计预测者对结果的个别影响变得更加困难。

多重共线性可以使用方差膨胀因子(VIF)来检测。任何预测值的 VIF 是其在完整模型中的估计系数的方差与仅适合其自身结果时的估计系数的方差之比(如在简单线性回归中)。VIF 为 1 表示不存在多重共线性。通常,大于 5 或 10 的 VIF 值被视为多重共线性的指标。在这种情况下,消除多重共线性的最简单方法是丢弃 VIF 值较高的预测值。

**vif**(**step**.lm.fit) %>%    
    **knitr**::kable()

在我们的例子中,没有一个预测值有很高的 VIF 值。因此,在我们的例子中,我们不需要担心多重共线性。

Source: Google Images

关系是线性的吗?

通过应用线性回归,我们假设预测值和结果之间存在线性关系。如果潜在的关系远远不是线性的,那么我们所做的大多数推论都是可疑的。

可以使用拟合值对残差的残差图来确定模型的非线性。任何观测值的残差是实际结果与模型拟合结果之间的差异。残差图中模式的存在意味着模型的线性假设有问题。

**#**type = "rstandard" draws a plot **for** standardized residualsresidualPlot(step.lm.fit, type = "rstandard")

蓝线表示拟合值和标准残差之间的平滑模式。在我们的例子中,曲线表示数据中的轻微非线性。

通过查看分量残差图 (CR 图),可以进一步探究非线性。

**ceresPlots**(**step**.lm.fit)

粉色线(残差线)是预测值和残差之间关系的模型。蓝色虚线(组件线)代表最佳拟合线。预测因子的两条线之间的显著差异意味着预测因子和结果没有线性关系。

这种不一致可以在 bmi 的 CR 图中看到。解决这一问题的方法之一是引入模型预测值的非线性变换。让我们试着给这个模型添加一个 bmi 的非线性转换。

**#update**() **can** **be** **used** **to** **update** **an** **existing** **model** **with** **new requirements****step**.lm.fit.new <**-** **update**(**step**.lm.fit, .~.+**I**(**bmi**^1.25))  **ceresPlots**(**step**.lm.fit.new)

bmi 的 CR 图在残差线和成分线之间不再有差异。

我们可以使用 ANOVA 来检查新模型是否明显优于以前的模型。低 p 值(<0.05) for the new model will mean we can conclude that it is better than the previous model:

anova(step.lm.fit, step.lm.fit.new, test = "F")

Since the model with non-linear transformation of bmi 有足够低的 p 值(< 0.05),我们可以得出结论,它比之前的模型更好,虽然 p 值很小。

我们来看看这个新模型的剩余剧情。

residualPlot(step.lm.fit.new, type = "rstandard")

查看新模型的残差图,标准残差的整体模式没有太大变化。

Source: Google Images

解决非线性问题的另一种方法是在一些预测器之间引入一个交互。与 bmi 较低且不吸烟的人相比,吸烟且 bmi 较高的人可能要支付更高的费用。让我们更新模型,在 bmi吸烟者之间引入一种相互作用,看看这是否会产生影响:

lm.fit1 <- update(step.lm.fit.new, ~ .+bmi*smoker)residualPlot(lm.fit1, type = "rstandard", **id**=TRUE)

anova(step.lm.fit.new, lm.fit1, test = "F")

不仅关系变得更加线性,残差图中出现的模式更少,而且新模型明显优于以前的模型(没有相互作用),这可以从 p 值(< 2.2e-16)中看出。

*#checking the value of adjusted r-squared of new model* summary(lm.fit1)$adj.r.squared

模型的 R 值也提高到了 0.84 以上。

误差项的非恒定方差

误差的恒定方差(同方差)是线性回归模型的另一个假设。例如,在误差的非恒定方差(异方差)的情况下,误差项可能随着响应变量的值而变化。识别异方差的一些图形方法是残差图中存在漏斗形状,或者残差图中存在曲线。在上面的情节中,我们没有看到任何清晰的模式。

统计方法是 Breusch-Pagan 测试的扩展,可在 cars 包中作为 ncvTest() 获得。它假设误差方差不变的零假设,而另一个假设是误差方差随着反应水平或预测因子的线性组合而变化。

**#** non-constant error variance test 
ncvTest(lm.fit1)

非常低的 p 值(~0.000023)意味着可以拒绝零假设。换句话说,误差具有非恒定方差的可能性很高。

解决这个问题的方法之一是转换结果变量。

**yTransformer** <**-** 0.8 
**trans**.lm.fit <**-** **update**(**lm**.fit1, **charges**^**yTransformer**~.)# **non-constant** **error** **variance** **test** 
**ncvTest**(**trans**.lm.fit)

residualPlot(trans.lm.fit, type = "rstandard", id=T)

p 值约为 0.94 意味着我们不能拒绝误差项方差不变的零假设。然而,从残差图中可以看出,模型的非线性略有增加。这可以通过观察单个预测因子和结果之间的关系来进一步确定。

误差项的相关性

线性回归模型的一个重要假设是连续误差项是不相关的。估计回归系数的标准误差是根据这一假设计算的。如果连续误差项相关,估计回归系数的标准误差可能会大得多。

我们可以使用德宾-沃森测试来检查误差项的自相关性。无效假设是连续误差没有自相关。

set.seed(1)**#** Test **for** Autocorrelated Errors 
durbinWatsonTest(trans.lm.fit, max.lag = 5, reps=1000)

5 个滞后中没有一个的 p 值小于 0.05。因此,我们不能拒绝连续误差不相关的零假设,得出连续误差相互独立的结论。

解释

让我们看看最终模型的实际电荷与拟合值,并将其与初始模型的结果进行比较。绘制 fitted_vs_actual 的函数,在下一个块之前使用,在这里是:

*#fitted values of initial model*fitted_init <- predict(lm.fit, insurance, 
    interval = "confidence") %>%   
    tidy()
g1 <- fitted_vs_actual(fitted_init, "Initial Model")*#fitted values of final model*fitted_final <- predict(trans.lm.fit, insurance,
    interval = "confidence")^(1/yTransformer) %>% 
    tidy()
g2 <- fitted_vs_actual(fitted_final, "Final Model")*#creating the two plots side-by-side* 
gridExtra::grid.arrange(g1,g2, ncol = 2)

最初的模型能够逼近低于 17,000 美元的实际费用,但是随着实际费用超过 20,000 美元,实际费用和拟合值之间的差距不断增大。根据初始模型,接近 50,000 美元的实际费用被拟合为接近或低于 40,000 美元,并且该差距继续向上增加。

相比之下,新模型中的拟合值更接近实际费用,尽管仍有许多变化未被该模型解释。它仍然是最初模型的一个重大改进。

我们可以查看预测值的估计系数及其置信区间,以解释它们如何定义模型。

confint(trans.lm.fit) %>%   
    tidy() %>%   
    tibble::add_column(coefficients = trans.lm.fit$coefficients,
        .after = 2) %>%   
    knitr::kable()

在上表中,X2.5 和 X97.5 标记了回归系数 95%置信区间的下限和上限。这些是使用估计系数的标准误差计算的。例如,对于年龄,估计系数约为 33.69,95%置信区间介于约 31.56 至约 35.83 之间。这意味着,根据模型,保持其他一切固定,年龄增加 1 岁将导致 charges^(0.8).值增加 33.69(因为我们转换了结果)。但是,这是一个估计值,因此有变动的余地。置信区间说明了这种变化,表示在大约 95%的情况下,charges^(0.8 值的变化将在 31.56 和 35.83 之间,保持其他一切固定。

让我们将这些影响形象化,以更好地理解预测因素与模型结果之间的关系。获得模型对转换结果影响的函数是这里的。

plot_effect('age', 'age') %>% 
    ggplot(aes(x = age, y = fit)) + 
    theme_bw() + 
    geom_line() + 
    geom_ribbon(aes(ymin = lower, ymax = upper), alpha = 0.5)

对于其他预测因子的平均值,保险费随着年龄的增加而增加。在体重指数吸烟者之间的互动中可以看到更有趣的效果:

plot_effect('bmi*smoker', 'bmi') %>% 
    ggplot(aes(x = x.bmi, y = fit)) + 
    facet_wrap(~x.smoker) + 
    theme_bw() + 
    geom_line() + 
    geom_ribbon(aes(ymin = lower, ymax = upper), alpha = 0.5)

不吸烟者,不管他们的 bmi 如何,对于其他预测指标的平均值来说,他们的保险费用大多较低。低 bmi 吸烟者的保险费较低,尽管仍高于任何 bmi 值的非吸烟者。此外,随着他们 bmi 的增加,吸烟者的保险费用也迅速增加。

结论

我们建立的模型可用于推断不同的预测因素如何影响结果。它远非完美。它们仍然存在非线性和误差的非恒定方差。此外,应该分析异常值和杠杆点,以找到更好的模型。当用于预测新的、看不见的数据的结果时,它可能不会(并且很可能不会)给出类似的结果。为了将其用于预测,应该采取更具体的措施来确保模型的准确性,如交叉验证。它仍然有助于提供预测和结果之间的重要关系的良好估计。这些估计可以用来以更有用和更直观的方式总结数据。

你可以在这里看到原帖,或者在 LinkedIn 上找到我。

来源

  • 统计学习导论及其应用。
  • 维基百科(一个基于 wiki 技术的多语言的百科全书协作计划ˌ也是一部用不同语言写成的网络百科全书ˌ 其目标及宗旨是为全人类提供自由的百科全书)ˌ开放性的百科全书
  • Quick-R
  • 如何统计
  • 堆叠交换
  • 堆栈溢出

线性回归:钱球—第 1 部分

原文:https://towardsdatascience.com/linear-regression-moneyball-part-1-b93b3b9f5b53?source=collection_archive---------4-----------------------

大众体育故事的统计案例研究

“The macro view of an old baseball on a wood surface” by Joey Kyber on Unsplash

概观

因 2011 年的电影 Moneyball 而走红的最引人注目的体育分析故事之一,2002 年的奥克兰运动家队创造了历史,在 2002 年 8 月 13 日至 9 月期间连续赢了 20 场比赛

奥克兰运动家队(通常被称为运动家队)在那个赛季的成功很大程度上归功于他们的总经理比利·比恩和前助理总经理保罗·德波斯塔。

DePodesta 毕业于哈佛大学经济学,于 1999 年加入美国棒球协会,并很快开始整合棒球统计数据分析,以评估和购买球员。( Sabermetrics )

这种方法在 2002 年历史性的赛季后受到关注,当时比利·比恩购买了被严重低估的球员,以取代赛季开始前离开的关键球员。由于奥克兰运动家队严重的预算限制,比利求助于 DePodesta 正在研究的方法,以购买被低估的球员来满足加州球队的工资。

Brad Pitt as Billy Beane and Jonah Hill as Paul DePodesta’s counterpart in the movie Moneyball. Source

本文试图重现 Paul DePodesta 的部分分析,以展示最简单的监督学习技术(也称为线性回归)的威力。

放弃

这一分析与麻省理工学院 edXAnalytics Edge课程中的案例研究非常相似。然而,我为本文选择的编程语言是 Python,而不是前面提到的课程中使用的 R。

线性回归

线性回归是机器学习中的一种监督学习算法,它起源于统计学原理。它主要用于模拟一个解释变量(通常为 y ,)与一个或多个自变量(用 X. 表示)之间的关系,当只有一个自变量用于预测 y,时,称为简单线性回归或线性回归,而当有多个自变量时,称为多元线性回归。

Linear Regression equation. Source

称为回归系数的β项指的是 x 变量和因变量 y. 之间的关系,让我们用一个例子来说明这一点。

方程式:

房价= 50000+1.35×(房屋面积平方)+ ε

上面的等式是一个回归函数的例子,该函数用于在给定房屋面积(平方英尺)的情况下确定房屋价格。

1.35 是β的值,表示房子每增加 1 平方英尺,房子的价格就会增加 1.35 美元。如果β的值为-1.35,那么房屋面积每增加 1 平方英尺就会有 1.35 美元的单位 d **房价下降。****

误差项ε用于表示残差或 Y 的实际值和预测值之间的差异。它告诉我们我们的预测值与实际值有多远。

残差公式:

ε=yŷt23】**

其中 y 表示实际值,而 ŷ 表示我们的模型预测的 y 值。

Plot of Simple Linear Regression with one independent variable. Source

我不会详细讨论β值是如何计算的,模型是如何优化的。相反,让我们直接进入模型构建框架。

资料组

我使用的数据集是从 baseball-reference.com 收集的来自 Kaggle 的 Moneyball 数据集。

探索数据

使用 pandas 库将数据读入 python。

*df = pd.read_csv("baseball.csv")
df.head()*

我们需要在这里定义一些术语:

  • RA 代表允许运行。
  • RS 代表得分得分。
  • OBP 代表基数百分比。
  • SLG 代表段塞百分比。
  • 巴是击球手。
  • OOBP 是对手的 OBP。
  • OSLG 是对手的 SLG。
  • w 代表该赛季的获胜次数。

增加一个新变量 RD,作为 RS 和 RA 之间的差值。

此外,我们将只保留年< 2002 in order to replicate the data prior to the 2002 season.

We will use plots in order to find insights regarding the distributions of the numerical variables.

Histograms of numerical features

Observe that all four features(variables) are approximately 正态分布的记录。得分得分和允许得分的图表似乎都稍微向左倾斜。运行评分图的尾部似乎比允许运行图的尾部厚。

Statistical analysis clip from Moneyball.(2011) Source

根据 DePodesta 在片段中的角色,为了进入 2002 年的季后赛,运动家队需要至少 99 场胜利。让我们试着想象这种洞察力。

*# Plotting scatterplotplt.figure(figsize=(10,8))
plt.scatter(x=moneyball0.W,y = moneyball0.RS,c="red")
plt.scatter(x=moneyball1.W,y = moneyball1.RS,c="blue")
plt.xlabel("Wins")
plt.ylabel("Runs Scored")
plt.axvline(x = 99)*

从上面的图中我们看到,DePodesta 估计的 99 胜是有道理的,因为似乎只有 3 个观察值(红色)没有以≥ 99 胜进入季后赛。

DePodesta 还计算出,为了进入季后赛,湖人队至少需要 814 分,并且只允许 645 分。这意味着得分得分和允许得分之间的差距大约需要 169(RD)。让我们来看看研发和成功之间的关系。

*x = np.array(moneyball.RD)
y = np.array(moneyball.W)# Deriving slope,intercept valuesslope, intercept = np.polyfit(x, y, 1)
abline_values = [slope * i + intercept for i in x]#Plotting the figureplt.figure(figsize=(10,8))
plt.scatter(x, y)
plt.plot(x, abline_values, 'b')
plt.title("Slope = %s" % (slope))
plt.xlabel("Run Difference")
plt.ylabel("Wins")
plt.show()*

我们可以清楚地看到,两个变量之间的关系是线性的。

*print(np.corrcoef(x,y))output:[[ 1\.          0.93851498]
 [ 0.93851498  1\.        ]]*

此外,研发和获胜次数之间有很强的相关性0.9385。

因此,我们的探索性数据分析证实了 DePodesta 的估计到目前为止是正确的。在研究的下一部分,我们将建立回归模型来进一步验证 DePodesta 的分析。

请继续关注第二部分。

来源

  1. *【https://www.edx.org/course/analytics-edge-mitx-15-071x-3 *
  2. http://www.imdb.com/title/tt1210166/
  3. https://en.wikipedia.org/wiki/Linear_regression
  4. http://www.numpy.org/
  5. https://matplotlib.org/

线性回归:钱球—第二部分

原文:https://towardsdatascience.com/linear-regression-moneyball-part-2-175a9dc72e89?source=collection_archive---------3-----------------------

大众体育故事的统计案例研究

“The macro view of an old baseball on a wood surface” by Joey Kyber on Unsplash

这篇文章是线性回归的续集:金钱球-第一部分。如果你还没有检查,我强烈建议你这样做。

概述

在前一篇文章结束时,我们已经建立了 RD(运行差异)和 W(成功)之间的线性关系。

我们还发现,RD 和 w 之间有非常强的正相关,为 0.9385。在本文中,我们将继续研究数值变量之间的关系,并建立一些模型来预测奥克兰运动家队在 2002 年的表现。

公式

让我们再看一下数据。

df = pd.read_csv("baseball.csv")
df.head()

现在,让我们来看看计算一些对大多数人来说似乎晦涩难懂的数字项的公式。

按基数百分比:

Formula for calculating On-base Percentage. Source

点击量

b:以球(保送)为基础

HBP:投球命中

阿瑟:击球

科幻:牺牲苍蝇

击发百分比:

Formula for calculating Slugging percentage. Source

1B,2B,3B:单打,双打,三连冠

HR:全垒打

阿瑟:击球

击球率:

Formula for calculating Batting average. Source

点击量

阿瑟:击球

探索性数据分析

我们可以看到,前面讨论的所有三个统计数据都以某种方式影响了球队得分的次数。我不会详细解释每个变量。你需要知道的是 OBP,SLG 和 AVG 是特定球队得分的有力指标。

让我们通过绘制这些变量与 RS(得分运行)之间的关系来验证这些假设:

Relationship between OBP, SLG,BA and RS respectively

在每个变量和得分之间有明显的线性关系。

**# Correlation between On-base percentage and runs scored.**print(np.corrcoef(moneyball.OBP,moneyball.RS))output:[[ 1\.          0.90490915]
 [ 0.90490915  1\.        ]]**# Correlation between Slugging percentage and runs scored.**print(np.corrcoef(moneyball.SLG,moneyball.RS))output:[[ 1\.          0.92638433]
 [ 0.92638433  1\.        ]]**# Correlation between batting average and runs scored.**print(np.corrcoef(moneyball.BA,moneyball.RS))output:[[ 1\.          0.83162475]
 [ 0.83162475  1\.        ]]

根据经验,0.7 以上的相关性被认为是强正相关。我们所有的变量都满足这条规则。

类似地,我们可以假设 OOBP(对手的 OBP)和 OSLG(对手的 SLG)与 RA(允许跑垒)有类似的关系。

在我们看到这些变量和 RA 之间的关系之前,我注意到在 OOBP 和 OSLG 列中有几个缺失值。为了画出正确的关系,我们必须去掉这几行观察数据。在以后的文章中,我会解释我们可以“估算”缺失数据的各种方法。

moneyballnew = moneyball.dropna()

我们将缩减的数据集存储到一个新的变量中。

现在让我们看看这些变量与 RA 之间的关系:

Model 大楼

我们现在将建立回归模型,以预测得分、允许得分和获胜。

python 中的 scikit-learn 库在使用很少几行代码构建各种各样的机器学习模型方面非常强大。我们将利用这个库来建立我们的模型。

我们的第一个模型用于预测“得分”。我们的自变量是上垒率、击球率、击球率。

**# Extracting our variables from the dataframe.**
x = moneyball[['OBP','SLG','BA']].values
y = moneyball[['RS']].values**# Calling our model object.**
RS_model = LinearRegression()**# Fitting the model.**
RS_model.fit(x,y) **# Printing model intercept and coefficients.**
print(RS_model.intercept_)
print(RS_model.coef_)Output:[-788.45704708]
[[ 2917.42140821  1637.92766577  -368.96606009]]

因此,我们的模型具有以下形式:

RS =-788.46+2917.42×(OBP)+1637.93×(SLG)-368.97×(巴)

在这一点上,我们注意到一些奇怪的事情。我们的模型有一个负系数的变量,也就是击球率。这是反直觉的,因为一个击球率高的球队应该有更多的得分。这种情况代表了一种被称为 多重共线性 的现象,其导致多重线性回归模型中的差异。

为了避免多重共线性,我们必须添加一个 交互变量 或者删除导致差异的变量。为了简单起见,让我们把 BA 从模型中去掉。

**# Extracting our variables from the dataframe.**
x = moneyball[['OBP','SLG']].values
y = moneyball[['RS']].values**# Calling our model object.**
RS_model = LinearRegression()**# Fitting the model.**
RS_model.fit(x,y)**# Printing model intercept and coefficients.**
print(model.intercept_)
print(model.coef_)Output:[-804.62706106]
[[ 2737.76802227  1584.90860546]]

我们的改良模型是:

RS =-804.63+2737.77×(OBP)+1584.91×(SLG)

类似地,我们使用对手的上垒百分比和对手的击球百分比作为独立变量来建立“允许跑垒”的模型:

**# Extracting our variables from the dataframe.**
x = moneyballnew[['OOBP','OSLG']].values
y = moneyballnew[['RA']].values**# Calling our model object.**
RA_model = LinearRegression()**# Fitting the model.**
RA_model.fit(x,y)**# Printing model intercept and coefficients.**
print(RA_model.intercept_)
print(RA_model.coef_)Output:
[-837.37788861]
[[ 2913.59948582  1514.28595842]]

允许运行的型号:

RA =-837.38+2913.60×(OOBP)+1514.29×(OSLG)

最后,我们从运行差异中预测成功的模型:

**# Extracting our variables from the dataframe.**
x = moneyball[['RD']].values
y = moneyball[['W']].values**# Calling our model object.**
W_model = LinearRegression()**# Fitting the model.**
W_model.fit(x,y)**# Printing model intercept and coefficients.**
print(W_model.intercept_)
print(W_model.coef_)Output:[ 80.88137472]
[[ 0.10576562]]

成功的模式:

W = 80.88 + 0.11 ×(RD)

模型预测

以下是奥克兰运动家队 2001 年季后赛前的统计数据。

OBP: 0.339

比重:0.430

OOBP: 0.307

OSLG: 0.373

让我们将这些值代入上述模型以生成预测。

**# Prediction for runs scored.**
RS_model.predict([[0.339,0.430]])Output:
array([[ 804.98699884]])**# Predictions for runs allowed.**
RA_model.predict([[0.307,0.373]])Output:
array([[ 621.92581602]])

因此,我们的模型预测了以下情况:

805 卢比

RA 约 622

这意味着 RD = 183。

最后,我们将研发纳入我们的 wins 模型:

**# Prediction for wins.**
W_model.predict([[183]])Output:
array([[ 100.23648363]])

将我们的模型结果与实际结果和 De Podesta 的估计进行比较,我们得到:

很不寻常,不是吗?与现实相比,我们模型的预测实际上相当准确。

结论

最后,我们总结了线性回归应用于 Sabermetrics 的案例研究。需要注意的重要一点是,在这个案例研究中,我对我们的回归模型做了很多假设。在以后的帖子中,我将深入讨论回归假设以及如何避免违反它们。

我希望你们都喜欢这篇关于线性回归的分为两部分的博文。如果你喜欢我的内容,我将非常感谢鼓掌和关注。完整的代码可在这里获得。

我期待着问题,评论,关注。下次见,伙计们。✌🏽

参考

  1. http://www.espn.com/mlb/statistics
  2. https://www.baseball-reference.com/

波士顿住房数据的线性回归

原文:https://towardsdatascience.com/linear-regression-on-boston-housing-dataset-f409b7e4a155?source=collection_archive---------2-----------------------

Credits: http://www.wbur.org/radioboston/2013/09/18/bostons-housing-challenge

在我之前的博客中,我介绍了线性回归和梯度下降的基础知识。为了获得动手操作的线性回归,我们将采用原始数据集并应用我们所学的概念。

我们将获取包含波士顿不同房屋信息的住房数据集。这些数据最初是 UCI 机器学习知识库的一部分,现在已经被删除。我们也可以从 scikit-learn 库中访问这些数据。该数据集中有 506 个样本和 13 个特征变量。目标是使用给定的特征来预测房屋的价格值。

所以让我们开始吧。

首先,我们将导入所需的库。

接下来,我们将从scikit-learn库中加载住房数据并理解它。

我们打印出boston_dataset的值来理解它包含的内容。print(boston_dataset.keys())慨然

dict_keys(['data', 'target', 'feature_names', 'DESCR'])
  • 数据:包含各种房屋的信息
  • 目标:房价
  • 特征名称:特征的名称
  • 描述:描述数据集

使用boston_dataset.DESCR了解更多功能,所有功能的描述如下:

**CRIM**: Per capita crime rate by town
**ZN**: Proportion of residential land zoned for lots over 25,000 sq. ft
**INDUS**: Proportion of non-retail business acres per town
**CHAS**: Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)
**NOX**: Nitric oxide concentration (parts per 10 million)
**RM**: Average number of rooms per dwelling
**AGE**: Proportion of owner-occupied units built prior to 1940
**DIS**: Weighted distances to five Boston employment centers
**RAD**: Index of accessibility to radial highways
**TAX**: Full-value property tax rate per $10,000
**PTRATIO**: Pupil-teacher ratio by town
**B**: 1000(Bk — 0.63)², where Bk is the proportion of [people of African American descent] by town
**LSTAT**: Percentage of lower status of the population
**MEDV**: Median value of owner-occupied homes in $1000s

变量MEDV表示的房屋价格是我们的目标变量,剩下的是 特征变量 ,我们将基于这些变量来预测房屋的价值。

我们现在将使用pd.DataFrame将数据加载到 pandas 数据帧中。然后我们使用head()打印前 5 行数据

我们可以看到数据中缺少目标值MEDV。我们创建一个新的目标值列,并将其添加到 dataframe 中。

数据预处理

加载数据后,最好查看数据中是否有任何缺失值。我们使用isnull()计算每个特征的缺失值的数量

但是,该数据集中没有缺失值,如下所示。

探索性数据分析

探索性数据分析是训练模型前非常重要的一步。在本节中,我们将使用一些可视化工具来理解目标变量与其他特征之间的关系。

让我们先画出目标变量MEDV的分布。我们将使用seaborn库中的distplot函数。

我们看到MEDV的值呈正态分布,很少有异常值。

接下来,我们创建一个相关矩阵来度量变量之间的线性关系。可以通过使用 pandas 数据帧库中的corr函数来形成相关矩阵。我们将使用 seaborn 库中的heatmap函数来绘制相关矩阵。

相关系数范围从-1 到 1。如果该值接近 1,则意味着这两个变量之间有很强的正相关性。当它接近-1 时,变量具有很强的负相关性。

观察:

  • 为了拟合线性回归模型,我们选择那些与我们的目标变量MEDV高度相关的特征。通过查看相关矩阵,我们可以看到RMMEDV (0.7)有很强的正相关性,而 as LSTATMEDV (-0.74)有很强的负相关性。
  • 为线性回归模型选择特征的重要一点是检查多重共线性。特征RADTAX具有 0.91 的相关性。这些特征对彼此之间有很强的相关性。我们不应该同时选择这两个特征来训练模型。查看这个以获得解释。具有-0.75 相关性的特征DISAGE也是如此。

基于以上观察我们将RMLSTAT作为我们的特征。使用散点图,让我们看看这些特性如何随MEDV变化。

观察:

  • 价格随着 RM 值的线性增加而增加。很少有异常值,数据似乎上限为 50。
  • 随着物价的上涨,价格有下降的趋势。尽管它看起来并不完全是一条直线。

准备用于训练模型的数据

我们使用 numpy 库提供的np.c_来连接LSTATRM列。

将数据分成训练集和测试集

接下来,我们将数据分成训练集和测试集。我们用 80%的样本训练模型,用剩下的 20%进行测试。我们这样做是为了评估模型在未知数据上的表现。为了分割数据,我们使用 scikit-learn 库提供的train_test_split函数。最后,我们打印出训练集和测试集的大小,以验证拆分是否正确发生。

*(404, 2) 
(102, 2)
(404,)
(102,)*

训练和测试模型

我们使用 scikit-learn 的LinearRegression在训练集和测试集上训练我们的模型。

模型评估

我们将使用 RMSE 和 R2 分数来评估我们的模型。

***The model performance for training set** 
-------------------------------------- 
RMSE is 5.6371293350711955 
R2 score is 0.6300745149331701 **The model performance for testing set** 
-------------------------------------- 
RMSE is 5.137400784702911
R2 score is 0.6628996975186952*

这是一个好的开始。在接下来的博客中,我们将探讨提高模型性能的方法。

完整的 Jupyter 笔记本可以在这里找到。

结论

在这个故事中,我们对波士顿住房数据集应用了线性回归的概念。我建议也尝试其他数据集。

这里有几个可以查找数据的地方

感谢阅读!!

在本系列的下一部分,我们将讨论多项式回归。请继续关注这个空间。

线性回归(第 1 部分):类型,例子,梯度下降的例子

原文:https://towardsdatascience.com/linear-regression-part-1-types-examples-gradient-descent-example-2e8c22b05f61?source=collection_archive---------8-----------------------

5 分钟机器学习实现示例(第 3 部分)。用 python 实现线性回归中的机器学习模型。

Linear Regression

先决条件: 机器学习类型及算法列表

线性回归 是统计学和机器学习中最常见、约 200 年历史且最容易理解的一种。如前一篇文章所解释的,它属于预测建模。预测建模是这里的一种建模,对于给定的输入(X) 可能的输出(Y) 是基于先前的数据或值预测的。

类型

  1. 简单线性回归:一个自变量 为特征。考虑一下 房子的价格 只基于一个领域,即地块的大小,那么这将是一个简单的线性回归。
  2. 多元线性回归:多个自变量 为特征。如果房子的价格不仅仅取决于地块面积的大小,还取决于经济,那么它就被认为是多元线性回归,这在大多数现实世界中是可行的。

方程式:

Y = a X+ b

这里的主要目的是找到最佳拟合线,该线最小化误差(点与线之间距离的平方和)。取点和线 之间的 距离,并对它们中的每一个进行 平方 以去除 负值 ,然后对这些值求和,从而给出需要最小化的误差。

如何将误差降至最低??

考虑下面的例子,其中绘制了三个点。

在我们需要最小化线和三个点之间的距离的地方画一条随机线

这里的误差是从点到红色线的距离。

错误的 ie。点和线之间的距离被总结并表示如下。

现在让我们把线向任何方向移动,画出误差。

在这里,由于线已经远离点,误差增加,误差被累加,如下所示。

这里,线向相反的方向移动,因为之前误差增加了,结果如下。

与以前的实例相比,这里的错误被最小化。

误差仍然可以被最小化,如下所示。

但是由于它导致负值,我们实现梯度下降(最小二乘法),其中误差值被平方,这仅导致可以精确测量误差的正值(这样做是因为距离不能以负值测量)。

数学上

  1. 红线误差:3 + 4 + 6 = 10 平方— — 4 + 9 + 25 = 38
  2. 黄线误差:4 + 5 + 7= 13 平方— 9 + 16 + 36 = 61
  3. 蓝线误差:1 + 2 + 4 = 7 平方— — 1 + 4 +16 = 21
  4. 最小误差:1–3+1 =-1这是没有意义的,但平方后得到 1 + 9 + 1 = 11

所以这里 61 > 38 > 21 > 11 是有意义的,而不是处理难以想象和处理的负距离。

因此,与其他实例相比,梯度下降(最小二乘法)是找到最小误差的最佳方法。

在下一篇文章中,我举了一个现实世界的例子,并实现了即将到来的线性回归(机器学习),敬请关注!!!!

更多参考文献:

  1. 人工智能是真实存在的还是只是这十年的炒作??
  2. 人工智能:定义、类型、实例、技术
  3. 人工智能 vs 机器学习
  4. 为什么机器学习能实现人工智能?
  5. 机器学习类型和算法

接下来我有 线性回归(第二部分) 接下来一定要关注我的 LinkedInTwitterinsta gram获取更多更新。如果你喜欢这篇文章,请鼓掌并分享它。

在这里加入我们的 WhatsApp 社区。

简化线性回归-普通最小二乘法与梯度下降法

原文:https://towardsdatascience.com/linear-regression-simplified-ordinary-least-square-vs-gradient-descent-48145de2cf76?source=collection_archive---------2-----------------------

什么是线性回归? 线性回归是一种寻找自变量和因变量之间关系的统计方法。让我们用一个简单的数据集来解释线性回归模型。

Table 1 : Sample Salary Data

Figure 1: Scatter Plot Diagram

为什么我们称它们为自变量和因变量?

Table 2: Sample dataset with independent & dependent variables hints

如果以我们的示例数据集为例,“工作经验年数”列是自变量,“年薪 1000 美元”列的值是因变量。我们的自变量是独立的,因为我们不能用数学方法确定经验的年限。但是,我们可以根据多年的经验来确定/预测工资列的值(因变量)。如果你看数据,依赖列值(薪水在 1000 美元)是根据多年的经验增加/减少的。

总平方和(SST):SST 是一个样本的平均值与该样本中各个值之间所有平方差的总和。它在数学上用公式表示。

Table: SST Calculation

SST 输出的平方和为 5226.19 。为了对线截距进行最佳拟合,我们需要应用线性回归模型来尽可能减小 SSE 值。为了确定斜率截距,我们使用以下等式

y = mxb,

  • “m”是斜率
  • x’→独立变量
  • b '是截距

我们将使用普通的最小二乘法来寻找最佳线截距(b)斜率(m)

普通最小二乘法(OLS)方法

为了使用 OLS 方法,我们应用下面的公式来找到方程

我们需要计算斜率‘m’和线截距‘b’。下面是计算这些值的简单表格。

Table 4: OLS method calculations

m = 1037.8/216.19
m = 4.80
b = 45.44-4.80 * 7.56 = 9.15
因此,y = mx+b→4.80 x+9.15
y = 4.80 x+9.15

让我们将 OLS 方法的结果与 MS-Excel 进行比较。是的,我们可以在 Microsoft Excel 中测试我们的线性回归最佳直线拟合。

Figure 2: Linear Regression using MS-Excel

精彩!我们的 OLS 方法与 MS-Excel 输出的“y”非常相似。

  • 我们的 OLS 方法输出→y = 4.80 x+9.15
  • MS-Excel 线性调节器。输出→y = 4.79 x+9.18

让我们通过使用我们的输出方程再次计算 SSE。

Table 5: SSE calculations again after OLS method implementation

现在,误差平方和从 5226.19 显著降低到 245.38。

普通的最小二乘法看起来简单,计算容易。但是,这种 OLS 方法既适用于单自变量和单因变量的单变量数据集,也适用于多变量数据集。多变量数据集包含单个自变量集和多个因变量集,需要我们使用一种叫做“梯度下降”的机器学习算法。

梯度下降算法

梯度下降算法的主要目标是最小化成本函数。这是最大限度减少误差(实际值和预测值的差异)的最佳优化算法之一。

我们来表示假设 h,它是函数或者是一个学习算法。

目标类似于上面的操作,我们在斜率“m”中找出截距线“y”的最佳拟合。同样使用梯度下降算法,我们将通过应用θ0 和θ1 的各种参数来计算出最小成本函数,并查看斜率截距,直到它达到收敛。

在一个真实世界的例子中,找到一个最佳方向走下坡路是相似的。

Figure 3: Gradient Descent 3D diagram. Source: Coursera — Andrew Ng

我们向趴下的方向迈一步。从每一步开始,你都要再次观察方向,以便更快地下山和更快地下山。在该算法中使用类似的方法来最小化成本函数。

我们可以使用成本函数来衡量假设函数的准确性,公式如下

梯度下降为线性回归

为什么我们在方程中使用偏导数?偏导数表示作为变量变化的函数的变化率。在我们的例子中,我们改变θ0 和θ1 的值,并确定变化率。为了将变化率值应用于θ0 和θ1,下面是用于θ0 和θ1 的等式,以将其应用于每个时期。

要找到最佳最小值,请重复上述步骤,对θ0 和θ1 应用不同的值。换句话说,重复步骤直到收敛。

Figure 4: Gradient Descent for linear regression. Source: http://sebastianraschka.com/ — Python Machine Learning, 2nd Edition

  • 其中,α(a)是学习速率/下坡需要多大的步长。

梯度下降算法的类型

有三种梯度下降算法:

1.批次梯度下降
2。随机梯度下降
3。小批量梯度下降

批量梯度下降

  • 在批量梯度下降中,为了计算成本函数的梯度,我们需要对每个步骤的所有训练样本求和
  • 如果我们有 3 百万个样本(m 个训练样本),那么梯度下降算法应该对每个时期的 3 百万个样本求和。要移动一步,我们要用 300 万次来计算每一步!
  • 批量梯度下降不太适合大型数据集
  • 下面是批量梯度下降算法的 python 代码实现。

随机梯度下降(SGD)

  • 在随机梯度下降中,我们在每次迭代中使用一个示例或一个训练样本,而不是使用整个数据集来对每个步骤求和
  • SGD 广泛用于大型数据集训练,计算速度更快,并且可以并行训练
  • 在计算之前,需要随机打乱训练样本
  • 下面是 SGD 的 Python 代码实现

小批量梯度下降

  • 它类似于 SGD,它在每次迭代中使用 n 个样本,而不是 1 个。

概要:

在总结中,对以下主题进行了详细解释。

  • 线性回归的自变量和因变量
  • 普通最小二乘法(OLS)和误差平方和(SSE)详细信息
  • 线性回归模型的梯度下降及梯度下降算法的类型。

参考:

线性回归烂透了。

原文:https://towardsdatascience.com/linear-regression-sucks-27a5215e50c0?source=collection_archive---------3-----------------------

线性回归。这是有史以来第一种被深入研究的回归分析,是任何监督学习课程的基础,是…你明白了吧。很糟糕。

在现实世界中,线性回归(GLS)表现不佳有多种原因:

  • 对异常值和质量差的数据很敏感—在现实世界中,数据经常受到异常值和质量差的数据的污染。如果异常值相对于非异常值数据点的数量多于几个,那么线性回归模型将偏离真正的基本关系。
  • 它要求所有变量都是多元正态的(单变量高斯到更高维的推广)—使用非线性变换将非正态变量变换为正态变量(例如,通常对数变换可以解决这个问题)可能会引入多重共线性效应。
  • 它假设变量之间没有(或很少)多重共线性(即变量相互独立)——这使得模型极其不稳定。虽然测试和删除很简单,但这可能会很痛苦。
  • 它假设了 homoscedassity(希腊语: homo “相同” skedasis “分散”)——也就是说,误差项的标准差是恒定的。如果线性回归是蓝色的(最佳线性无偏估计量),它们还必须是不相关的,并且具有零均值
  • 它要求我们的因变量和预测变量之间的关系是线性的——嗯,这是它的名字(我仍然认为值得一提,尽管这篇文章是关于线性估计量的)。

作为一个典型的经验法则,使用参数方法,如线性回归,当你的数据是高质量的,这样的方法会更有效。非参数方法(不假设数据的某种潜在分布)在交换中使用数据的效率较低,无法消除某种类型的假设。

但是这些非参数线性方法是什么呢?这里有几个我最喜欢的。

泰尔森估计器

Theil-Sen 估计量可以有效地计算,并且对异常值不敏感。即使数据是正态分布的并且数据是高质量的(即不存在异常值),它仍然比最小二乘回归有竞争力。低效率的问题(它以 O(n)运行),但是使用诸如随机采样或者甚至一些确定性方法的方法,这可以减少到 O(n log n)。此外…这几乎不是一个深度卷积神经网络,你不会用这些简单的方法进行大量的计算。

从概念上讲,这非常简单:计算因变量和自变量之间所有组合的所有斜率值的中值,由此斜率可以通过使用(yj-)/(XJ-Xi)来确定。

最小修剪正方形

最小修整平方是一种稳健的回归方法(一种旨在规避某些回归模型的一些缺点的回归形式),与 Theil-Sen 和即将推出的 MM 估计器一样,它对异常值的影响不敏感。

LTS 不是像标准最小二乘法那样最小化所有 n 个点的残差平方和,而是最小化一个 k

Theil Sen, it’s a fairly inefficient method.

MM 估计值

1973 年,Peter J. Huber 引入了一种称为 M-估计(M 代表“最大似然型”)的回归方法,该方法对响应中的异常值稳健,但对解释变量不稳健,由于显而易见的原因,该方法并不理想。然而,它非常有效。

然后是 S-估计(S 代表“比例”)技术,其思想是找到一个平面,使残差比例的稳健估计最小化。它对异常值和杠杆点有很强的抵抗力,但是对于实际应用来说效率太低。

最后,像一个无畏的骑士骑着种马投入战斗一样,MM 估计出现了,它结合了 S 估计的稳健性和 M 估计的效率。它的工作原理是找到一个稳健的 S 估计,使残差标度的 M 估计最小化,它保持不变,同时找到参数的接近 M 估计。

少数几篇论文将 MM 估计量与最小修整平方和 OLS 进行了比较,MM 估计量是其中的首选。

贝叶斯稳健回归

Normal vs Student-T distributions

将正态分布替换为具有大约 5 个自由度的重尾 t 分布(但要进行测试和比较)在各种实际情况下都能很好地工作。贝叶斯稳健回归依赖于这样的分布。t 分布的尾部有更多的“肉”,这意味着我们在那里采样的概率比在正态分布的相同位置采样的概率更高。异常值对我们的估计影响较小,因为似然函数假设异常值更有可能出现。

其原因是因为高相关性将使设计矩阵(您的数据)与其自身一起转置(计算估计量所需的步骤)奇异,因此无法求逆,因为行列式为零,所以不存在估计量。即使它几乎是奇异的,也很可能是计算不稳定的。

注意,如果你考虑异方差,那么线性回归往往是最好的结果…我猜它实际上并不总是很糟糕。

http://iacmc.zu.edu.jo/ar/images/stories/IACMC2016/39.pdf

线性回归:更简单的方法

原文:https://towardsdatascience.com/linear-regression-the-easier-way-6f941aa471ea?source=collection_archive---------0-----------------------

线性回归是神奇的机器学习世界中最棒的入门途径!也是最简单易学的算法。

我将更多地关注代码,而不是理论,因为代码更有趣:)但只是为了激发你大脑中静止的线性回归神经元。

线性回归:这是一种寻找具有“最佳拟合线”的模式的方法(因此,“线性”懂了吗?)在你的数据里。

看起来像这样(对于任何 x 或 y 轴)

Fig: Linear Regression Example

在本例中,我们将使用“load_boston”数据集,即 scikit learn 提供的波士顿房价数据集。

完整代码:)

Fig: Linear Regression with sklearn (Boston Housing dataset)

代码洞察:

上述代码分为 5 个步骤..

  1. 加载预先打印数据集。

Fig: Importing the Dataset

sklearn.datasets 导入 load_boston

load = load_boston()

上面的第一行从数据集集合中导入 load_boston 数据集,该集合存在于 sklearn 库中。

第二行只是将 load_boston 放入 load 变量中以备后用。很简单…

导入 pprint

【pprint . pprint(波士顿)

导入 preetprint 库,它用来使我们的输出看起来简洁易懂,然后我们就可以简单地打印它了。

注意:-当我们预测时,没有必要使用最后两行 preety 打印。因为您不需要再次打印数据文件,所以此属性打印仅用于您理解数据集文件的目的。

2.创建数据帧

Fig: Creating two (DataFrame) array of data

在这里,我们将使用熊猫创建两个数据帧。Dataframe 只是一个用来制作数据集或数组的花哨词。 df_x 包含具有列= boston 的房屋的数据或特征。features_names 也是出现在数据集中的一个数组,以便更清楚地理解, df_y 分别包含目标价格。

3.选择模型(即线性回归)

Fig: Selecting LinearRegression() model

虽然很简单,但我们从 sklearn 库中导入了 LinearRegression() 模型,并将该模型赋予变量 model ,以便在代码中进一步使用。

4.分裂测试随机性训练数据集。

Fig: Train and Test Splitting

这里,我们使用来自 sklearn 库的 train_test_split 。上面代码中的这个函数需要四个参数 data DataFrame、 target DataFrame、test_size、random_state(只是为了混洗数据)。

注意:在上面的行中,由于 test_size =0.2,train_size 自动给定为 0.8,因此,test_size + train_size = 0.2+0.8 = 1

5.列车预测

Fig: Train and predict the dataset

在上面的代码中, fit (aka TRAINING ) 函数采用两个参数 x_train,y_train 并用给定的数据集训练模型。

接下来,我们将使用选择的模型(即 LinearRegression())从 x_test 数据集预测y _ test,并将预测值数组放入结果变量中。然后我们只是打印第五个预测值(即结果[5])和完整的 y_test 数据集。你应该从别的地方得到 5 ,只要记住在列表中从 0 开始计数,而不是从 1 开始计数。

结果

Fig: Results

可以看到,第一个【25.43573299】是对数组中第五个元素的预测,即 70 — — 24.2, 相当接近。如果你想知道第一行随机数是什么,嗯…它是相对于随机选择的 y_test 数据集值的序列号(在第 4 步中)。

只是一个线性回归的 gif 来理解一下。

完整代码: Github

关注我,获取类似帖子。

脸书推特领英谷歌+ 上联系我

如果你有任何意见或问题,请写在评论里。

鼓掌吧!分享一下!跟我来。

乐意帮忙。荣誉……..

你会喜欢的以前的故事:

  1. 交叉验证代码可视化:有点意思

  2. DIY Arduino 无线键盘

3.激活函数解释:神经网络

4.感知器是什么鬼?

5.Tensor flow 中的“张量”是什么鬼?

使用梯度下降的线性回归

原文:https://towardsdatascience.com/linear-regression-using-gradient-descent-97a6c8700931?source=collection_archive---------0-----------------------

在本教程中,你可以学习梯度下降算法的工作原理,并从头开始用 python 实现它。首先我们看看什么是线性回归,然后我们定义损失函数。我们学习梯度下降算法如何工作,最后我们将在给定的数据集上实现它并进行预测。

The values of m and c are updated at each iteration to get the optimal solution

这是这段视频的书面版本。如果你喜欢,就看着它!

线性回归

在统计学中,线性回归是一种对因变量和一个或多个自变量之间的关系进行建模的线性方法。设 X 为自变量, Y 为因变量。我们将定义这两个变量之间的线性关系如下:

Source: http://www.nabla.hr/SlopeInterceptLineEqu.gif

这是你在高中学过的一条线的方程。 m 是直线的斜率,c是 y 轴截距。今天,我们将使用这个等式用给定的数据集来训练我们的模型,并针对任何给定的 X 值来预测 Y 的值。我们今天的挑战是确定 mc 的值,使得对应于这些值的线是最佳拟合线或给出最小误差。

损失函数

损失就是我们预测的 mc 的误差。我们的目标是最小化这一误差,以获得最准确的 m和 c值。
我们将使用均方差函数来计算损失。该功能有三个步骤:

  1. 对于给定的 x,求实际 y 值和预测 y 值的差(y = mx + c)。
  2. 平方这个差值。
  3. 求 x 中每个值的平方的平均值。

Mean Squared Error Equation

这里 yᵢ是实际值,ȳᵢ是预测值。让我们用ȳᵢ:的值来代替

Substituting the value of ȳᵢ

所以我们求误差的平方,然后求平均值。因此得名均方误差。既然我们已经定义了损失函数,让我们进入有趣的部分——最小化它并找到 mc.

梯度下降算法

梯度下降是一种寻找函数最小值的迭代优化算法。这个函数就是我们的损失函数。

了解梯度下降

Illustration of how the gradient descent algorithm works

想象一个山谷和一个没有方向感的人想要到达谷底。他走下斜坡,在斜坡陡的时候迈大步,在斜坡不那么陡的时候迈小步。他根据当前位置决定下一个位置,当他到达他的目标山谷底部时停下来。
让我们试着对 mc 应用梯度下降,一步一步接近它;

  1. 最初设 m = 0,c = 0。设 L 为我们的学习率。这控制了 m 的值随着每一步变化的程度。l 可以是一个小值,如 0.0001,以获得良好的精度。
  2. 计算损失函数关于 m 的偏导数,将 x,y,m,c 的当前值代入其中,得到导数值 D

Derivative with respect to m

Dₘ是关于 m 的偏导数的值。类似地,让我们找到关于 c ,Dc 的偏导数:

Derivative with respect to c

3.现在,我们使用以下等式更新 mc 的当前值:

4.我们重复这个过程,直到我们的损失函数是一个非常小的值或理想的 0(这意味着 0 误差或 100%的准确性)。我们现在剩下的 mc 的值将是最佳值。

现在回到我们的类比, m 可以被认为是人的当前位置。 D 相当于斜坡的陡度 L 可以是他移动的速度。现在,我们使用上面的等式计算出的新值 m 将是他的下一个位置,而 L×D 将是他将要走的步数。坡度越陡( D 越大),他的步幅就越大,坡度越缓( D 越小),他的步幅就越小。最后,他到达了谷底,这相当于我们的损失= 0。
现在有了 mm和 cc的最佳值,我们的模型就可以进行预测了!

实施模型

现在让我们把上面的一切都转换成代码,看看我们的模型在运行!

1.4796491688889395 0.10148121494753726

梯度下降是机器学习中最简单也是最广泛使用的算法之一,主要是因为它可以应用于任何函数来优化它。学习它是掌握机器学习的基础。

在这里找到数据集和代码:https://github . com/chasing infinity/ml-from-scratch/tree/master/02% 20 linear % 20 regression % 20 using % 20 gradient % 20 descending

有问题吗?需要帮助吗?联系我!

【adarsh1021@gmail.com】电子邮件:T4

领英:https://www.linkedin.com/in/adarsh-menon-739573146/

推特:https://twitter.com/adarsh_menon_

insta gram:【https://www.instagram.com/adarsh_menon_/】T21

参考文献:

[## 机器学习的梯度下降法

优化是机器学习的一大部分。几乎每个机器学习算法都有一个优化算法…

machinelearningmastery.com](https://machinelearningmastery.com/gradient-descent-for-machine-learning/) [## 梯度下降——初学者指南

简介:

towardsdatascience.com](/gradient-descent-a-beginners-guide-fa0b5d0a1db8)

在 10 行代码中使用梯度下降进行线性回归

原文:https://towardsdatascience.com/linear-regression-using-gradient-descent-in-10-lines-of-code-642f995339c0?source=collection_archive---------0-----------------------

我的目标是最终为其他优化技术写出这样的文章。让我们从梯度下降开始。注意:这不是一个全面的指南,因为我浏览了很多东西。

在我们学习机器学习和人工智能的旅程中,在深入之前了解基础知识很重要。基础知识是理解更复杂的架构形式所需的构建模块。例如,在没有首先理解导数是什么、如何以及为什么起作用之前,你不会想要学习常微分方程。机器学习也是如此。通过使用梯度下降作为我们的优化技术来理解线性回归将有助于我们在未来理解更复杂的模型。

我记得有一次向一群数据科学家解释我为这家公司创建的随机森林分类模型。我试着用逻辑回归做一个类比,因为我假设我在房间里的数据科学家同事会知道这件事。他们中的很多人说他们不熟悉它。我感到震惊,因为我们在这里谈论一个更先进的方法,但他们甚至不知道什么是逻辑回归模型。别这样。

线性回归、成本和梯度下降

线性回归是我们可以建立关系模型的最基本的方法之一。我们这里的模型可以描述为 y=mx+b,其中 m 是斜率(改变陡度), b 是偏差(在图中上下移动线条), x 是解释变量, y 是输出。如果我们认为有线性关系,我们就使用线性回归。比如说下面的 x 轴是学习 _ 时间而 y 轴是考试 _ 分数

Source: https://i.imgur.com/oZ6CBpi.png

一条直线最好地描述了这种关系,因为学生学习得越多,他或她的考试分数就越高。使用指数、正弦或对数函数来模拟这种关系是没有意义的。线性模型为我们提供了简单性;线性关系很容易理解和解释。请注意,现实世界中的关系并不总是线性的,因此我们使用更高级的方法,如神经网络,这是通用的函数逼近器。更多关于神经网络的信息。

通过调整 mb ,我们可以创建一条最佳描述关系的直线。我们怎么知道我们接近了?通过使用一个叫做成本函数的东西。它直接告诉我们成本。高成本值意味着它很贵——我们的近似值远远不能描述真实的关系。另一方面,低成本值意味着它很便宜——我们的近似值接近描述这种关系。

对于线性回归,我们使用一个被称为均方误差或 MSE 的成本函数。我们取实际数据点的平方值减去近似值。我们的近似值可以使用我们拥有的当前值 mb 来计算:y _ approx = m _ current * x+b _ current。之后,我们将所有这些值相加,然后除以我们拥有的数据点数,实际上就是取平均值。现在你明白为什么它被称为均方误差了。

Source: https://i.stack.imgur.com/19Cmk.gif

你现在可能在想,“这听起来很棒,但是我们怎么才能发现mb??蛮力??"暴力是没有用的。更有效的方法是梯度下降。想象一下,蒙着眼睛试图找到最低点,如下图所示。你要做的是检查左右两边,然后感觉哪一个把你带到一个较低的点。你每走一步都这样做,直到检查左右两边把你带到一个更高的点。

Source: https://iamtrask.github.io/img/sgd_no_lines.png

背后的数学并不像看起来那么复杂。我们在这里所做的是对成本函数应用关于 m和 b的偏导数,以将我们指向最低点。如果你记得你的数学,零的导数意味着你处于局部最小值或最大值。这意味着我们越接近零,越好。当我们的导数接近(如果不是)零时,我们也不可避免地会得到成本函数的最低值。

Source: https://spin.atomicobject.com/wp-content/uploads/linear_regression_gradient1.png

寻找 m 和 b 的最佳值的过程就是最小化我们的导数。训练机器学习算法或神经网络实际上就是最小化成本函数的过程。

编程吧

在这里,我将使用 Python 来编写我们的线性回归模型。我使用 Python 是因为它是我从事数据科学的首选语言。此外,Python 对于专家和初学者来说都很棒。这种语言是为了可读性而设计的,所以无论你已经编程多年还是刚刚编程一天,浏览别人的代码仍然是相当容易的。

**def** *linear_regression*(X, y, m_current=0, b_current=0, epochs=1000, learning_rate=0.0001):
     N = **float**(**len**(y))
     **for** i **in** **range**(epochs):
          y_current = (m_current * X) + b_current
          cost = **sum**([data**2 **for** data **in** (y-y_current)]) / N
          m_gradient = -(2/N) * **sum**(X * (y - y_current))
          b_gradient = -(2/N) * **sum**(y - y_current)
          m_current = m_current - (learning_rate * m_gradient)
          b_current = b_current - (learning_rate * b_gradient)
     **return** m_current, b_current, cost

Xy 是我们的输入参数。另一方面, m_currentb_current 分别是我们的斜率和偏置项,在我们试图找到最佳数值时,这两项都会更新,以便我们得到的方程最符合我们的数据。这里的时期指的是我们训练模型的次数,以找到模型拟合数据的最佳斜率和偏差。最后, learning_rate 这里指的是收敛的速度,意思是梯度下降找到最佳参数的速度。

为了进一步理解 learning_rate ,让我们回到我们蒙着眼睛寻找最低点的例子。大的学习率意味着我们迈出的步伐太大,你可能会完全错过最低点。然而,太小的学习率意味着我们将花费很长时间到达底部。试着在两者之间取得平衡。

重要的一点是 for 循环:

**for** i **in** **range**(epochs):
     y_current = (m_current * X) + b_current
     cost = **sum**([data**2 **for** data **in** (y-y_current)]) / N
     m_gradient = -(2/N) * **sum**(X * (y - y_current))
     b_gradient = -(2/N) * **sum**(y - y_current)
     m_current = m_current - (learning_rate * m_gradient)
     b_current = b_current - (learning_rate * b_gradient)

我们迭代 1000 次,因为 1000 听起来不错。真的取决于你想迭代多少。超参数微调是一项正在进行的研究,所以你可能想看看!

我们用上面看到的公式计算斜率和偏差的梯度。然后,我们通过减去学习率时间和各自的梯度值来更新斜率和偏差。学习速度将决定我们达到收敛的速度。经过 1000 次迭代后,我们返回 m_currentb_currentcost

恭喜你!那是你机器学习和人工智能旅程的第一步。获得梯度下降如何工作的直观感受,因为这实际上也用于更高级的模型。这里的目标是学习基础知识,而你我的朋友刚刚迈出了第一步。现在你可以去学更多的东西了!

使用最小二乘法的线性回归

原文:https://towardsdatascience.com/linear-regression-using-least-squares-a4c3456e8570?source=collection_archive---------0-----------------------

线性回归是最简单的机器学习形式。在这篇文章中,我们将看到线性回归是如何工作的,并从头开始用 Python 实现它。这是上面视频的文字版。如果你喜欢的话,就看着吧。

线性回归

在统计学中,线性回归是一种对因变量和一个或多个自变量之间的关系进行建模的线性方法。在一个独立变量的情况下,它被称为简单线性回归。对于一个以上的独立变量,这个过程称为多元线性回归。我们将在本教程中处理简单的线性回归。
X 为自变量 Y 为因变量。我们将定义这两个变量之间的线性关系如下:

这是你在高中学过的一条线的方程。 m 是直线的斜率, c 是 y 轴截距。今天,我们将使用这个等式用给定的数据集来训练我们的模型,并针对任何给定的 X 值来预测 Y 的值。

我们今天的挑战是确定 mc 的值,它给出了给定数据集的最小误差。我们将通过使用最小二乘法来实现这一点。

查找错误

因此,为了最小化误差,我们首先需要一种计算误差的方法。机器学习中的损失函数仅仅是预测值与实际值有多大差异的度量。
今天我们将使用二次损失函数来计算我们模型中的损失或误差。它可以定义为:

我们对它求平方是因为,对于回归线以下的点,y-p将为负,我们不希望总误差为负值。

最小二乘法

现在我们已经确定了损失函数,剩下唯一要做的就是最小化它。这是通过找到 L 的偏导数,使其等于 0,然后找到 mc 的表达式来实现的。在我们完成数学计算后,我们只剩下这些等式:

这里,x̅是输入 X 中所有值的平均值,而ȳ是期望输出 Y 中所有值的平均值。这是最小二乘法。现在我们将在 python 中实现这个并进行预测。

实施模型

1.287357370010931 9.908606190326509

不会有太多的准确性,因为我们只是简单地取一条直线,并迫使它以最好的方式适应给定的数据。但是你可以用它来做简单的预测或者了解真实值的大小/范围。对于机器学习的初学者来说,这也是很好的第一步。

在这里找到数据集和代码:https://github . com/chasing infinity/ml-from-scratch/tree/master/01% 20 linear % 20 regression % 20 using % 20 lost % 20 squares

有问题吗?需要帮助吗?联系我!

电子邮件:adarsh1021@gmail.com

领英:https://www.linkedin.com/in/adarsh-menon-739573146/

推特:https://twitter.com/adarsh_menon_

insta gram:https://www.instagram.com/adarsh_menon_/

使用 Python 进行线性回归

原文:https://towardsdatascience.com/linear-regression-using-python-b136c91bf0a2?source=collection_archive---------3-----------------------

线性回归通常是每个数据科学家遇到的第一个机器学习算法。这是一个简单的模型,但每个人都需要掌握它,因为它为其他机器学习算法奠定了基础。

线性回归可以用在哪里? 这是一种非常强大的技术,可以用来了解影响盈利能力的因素。它可以通过分析前几个月的销售数据来预测未来几个月的销售。它还可以用来获得关于客户行为的各种见解。在博客结束时,我们将建立一个类似下图的模型,即确定一条最符合数据的线。

这是我将要讲述的机器学习系列的第一篇博客。人们可能会被网络上大量关于机器学习算法的文章淹没。我写这篇博客的目的有两个。它可以作为进入机器学习领域的人的指南,也可以作为我的参考。

目录

  1. 什么是线性回归
  2. 线性回归假设
  3. 训练线性回归模型
  4. 评估模型
  5. scikit-learn 实现

什么是线性回归

线性回归模型的目标是找到一个或多个特征(自变量)和一个连续目标变量(因变量)之间的关系。当只有一个特征时,称为单变量线性回归,如果有多个特征,称为多元线性回归。

线性回归假设

线性回归模型可以由下面的等式表示

  • Y 是预测值
  • θ ₀是偏置项。
  • θ ₁,…, θ ₙ为模型参数
  • x ₁、 x ₂,…、 x ₙ为特征值。

上述假设也可以表示为

在哪里

  • θ 是模型的参数向量,包括偏差项 θ
  • xx ₀ =1 的特征向量

数据集

让我们创建一些随机数据集来训练我们的模型。

使用上述代码生成的数据集的曲线图如下所示:

训练一个线性回归模型

在这里,模型的训练意味着找到参数,以使模型最适合数据。

我们如何确定最佳拟合线?
预测值与观测值之间的误差最小的线称为最佳拟合线或回归线。这些误差也被称为 残差 。残差可以通过从观察数据值到回归线的垂直线来可视化。

Image Credits: http://wiki.engageeducation.org.au/further-maths/data-analysis/residuals/

为了定义和测量我们模型的误差,我们将成本函数定义为残差平方和。成本函数表示为

其中假设函数 h(x) 表示为

并且 m 是我们的数据集中训练样本的总数。

为什么我们取残差的平方而不是残差的绝对值? 我们更希望惩罚远离回归线的点,而不是靠近回归线的点。

我们的目标是找到模型参数,使成本函数最小。我们将使用梯度下降来找到这个。

梯度下降

梯度下降是许多机器学习算法中使用的通用优化算法。它反复调整模型的参数,以最小化成本函数。梯度下降的步骤概述如下。

  1. 我们首先用一些随机值初始化模型参数。这也被称为 随机初始化
  2. 现在我们需要测量成本函数如何随着参数的变化而变化。因此,我们计算成本函数 w.r.t 对参数 θ ₀、 θ ₁、…、 θ ₙ的偏导数

类似地,成本函数 w.r.t 对任何参数的偏导数可以表示为

我们可以立刻计算所有参数的偏导数,使用

其中 h(x)

3.计算导数后,我们更新参数如下

其中 α学习参数

我们可以一次更新所有参数,

我们重复步骤 2、3,直到成本函数收敛到最小值。如果 α 的值太小,代价函数需要更大的时间收敛。如果 α 过大,梯度下降可能超过最小值,最终可能无法收敛。

Source: Andrew Ng’s course on Coursera

为了演示梯度下降算法,我们用 0 初始化模型参数。方程变成 Y = 0。梯度下降算法现在尝试更新参数的值,以便我们达到最佳拟合线。

当学习速度非常慢时,梯度下降需要更长的时间来找到最佳拟合线。

当学习率正常时

当学习率任意高时,梯度下降算法会超过最佳拟合线,甚至可能找不到最佳拟合线。

从头开始实施线性回归

下面给出了具有梯度下降的线性回归的完整实现。

模型参数如下所示

The coefficient is [2.89114079]
The intercept is [2.58109277]

最佳拟合线的绘图

下面给出了成本函数与迭代次数的关系图。我们可以观察到,成本函数最初随着每次迭代而降低,并且在近 100 次迭代之后最终收敛。

到目前为止,我们已经从头开始实施线性回归,并使用梯度下降来寻找模型参数。但是我们的模型有多好呢?我们需要一些方法来计算我们模型的准确性。让我们看看各种指标来评估我们上面构建的模型。

评估模型的性能

我们将使用均方根误差( RMSE )和决定系数( R 得分)来评估我们的模型。

RMSE 是残差平方和的平均值的平方根。

RMSE 的定义是

RMSE 的分数是 2.764182038967211。

R 得分或决定系数解释了通过使用最小二乘回归可以将因变量的总方差减少多少。

R

SSₜ 是我们把观测值的平均值作为预测值的误差总和。

是残差的平方和

*****SSₜ -*** 69.47588572871659
***SSᵣ -*** 7.64070234454893
**R²** score - 0.8900236785122296**

如果我们使用观察值的平均值作为预测值,方差是 69.47588572871659,如果我们使用回归,总方差是 7.6407023454893。通过回归分析,我们将预测误差降低了 89%。

现在让我们尝试使用流行的 scikit-learn 库来实现线性回归。

Scikit-learn 实现

sckit-learn 是一个非常强大的数据科学库。完整的代码如下所示

模型参数和模型的性能指标如下所示:

**The coefficient is [[2.93655106]]
The intercept is [2.55808002]
Root mean squared error of the model is 0.07623324582875013.
R-squared score is 0.9038655568672764.**

这几乎类似于我们从零开始实现线性回归时所获得的结果。

这个博客到此为止。完整的代码可以在这个 GitHub repo 中找到。

结论

我们已经学习了线性回归和梯度下降的概念。我们还使用 scikit-learn 库实现了该模型。

在本系列的下一篇博客中,我们将获取一些原始数据集并构建一个线性回归模型。

示例线性回归

原文:https://towardsdatascience.com/linear-regression-with-example-8daf6205bd49?source=collection_archive---------0-----------------------

对于外行来说什么是机器学习和线性回归

机器学习-虚构的故事。从前有一个医生。他会看着人,预测她/他是否缺乏血红蛋白(红细胞)。几乎所有的时候,他的预言都会在检验病人的血液时实现。

他会怎么预测?让我们假设脸色苍白,身体疲劳是低血红蛋白(血红蛋白)的症状。如果这个人的体重较轻,那么出现这种症状的可能性就更大,因为血红蛋白含量低。医生“根据他过去的经验”会在看完病人后“预测”。

如果我们能让计算机也学习这样的东西并做出这样的预测会怎么样。假设我们有量化的变量,比如苍白和疲劳。

线性回归

我们在数学课上见过如下方程。y 是我们想要的输出。x 是输入变量。c =常数,a 是直线的斜率。

y = c + axc = constant
a = slope

输出根据输入线性变化。

  • y 是由输入 x 决定的输出。x 值对 y 的影响程度由“a”决定。在具有轴“x”和“y”的二维图形中,“a”是直线的斜率。
  • c '是常数(x 为零时 y 的值)。

历史数据

假设我们有大量的历史数据,其中提供了输入值“x”和输出/结果值“y”。

我们也知道 x 的变化对 y 的影响是线性的。这意味着,如果我们取这些 x 和 y 的值,然后画出图表,我们会得到这样的图表。不完全相同,但有点像这样,其中似乎有一个线性方向的点杂乱。https://en.wikipedia.org/wiki/Linear_regression

我们想干什么

我们想看看历史数据,找出' c '和' a '的值。让我们称 c 为常数,a 为重量。如果我们能算出 c 和 a 的值,那么我们就能预测任何新 x 的 y 值。

怎么办

正如你从图表中看到的,虽然这些点形成了一条直线,但是它们并不在同一条直线上。所以我们无法知道 c 和 a 的 100%完美值,但是我们可以找到最佳拟合线,如上图红色所示。

这意味着我们的输出将是近似的。可能与实际值略有偏差。但是对于大多数商业应用程序来说,它工作得很好。

细节如何

看图表中的点。如果我们算出一条线,它到图中每个点的距离是最优的/最小的。这意味着“最佳拟合线”,如上图中红色所示。我们的目标是在上图中画出红线。

因此,我们在图上为 c 和 a 的某个随机值画一条随机线。假设我们保持 c 和 a 都是 1 (c=1,a=1),并在图上为每个(至少 2 个)x 画一条线。根据 x 的值,这条线可能会在以下位置之一结束

  • 在点的左侧朝向 y 轴。更垂直。
  • 在点朝向 x 轴的右侧。更横。
  • 介于点之间,但仍不是最佳拟合线。

由于这是一条随机的线,我们需要一种机制将这条线反复缓慢地移动到最适合样本数据的地方(图中的点)。

所以,实际上我们需要

  • 找出它的最佳拟合线
  • 如果不是最佳拟合线,则将其移向最佳拟合线。这意味着我们必须改变 c 和 a 的值。
  • 我们需要改变多少 c 和 a 的值,向哪个方向改变?我们将使用梯度下降和最小二乘法相结合的方法来实现这些目标。这些解释如下。

数学

对于样本数据中的每一项(也称为训练集),从我们的估计线(c=1,a=1)中获取 y 的值。姑且称之为 h(y)吧。

  • 同样,我们有 y,它是每个样本数据的真实值。
  • 我们将近似的 h(y)和 y 之差表示为 h(y) — y,将该差平方。所以对于一个样本,我们有(h(y)-y)^ 2
  • 对所有样品都这样做。假设我们的样本量为“m”,我们得到每个样本量的差的平方,对其求和(从 1 到 m 求和),得到其平均值(即除以 m),使其减半(因为差的平方的一半提供更好的结果)。我们现在有了成本函数。我们需要最小化这个成本函数。这意味着我们需要最小化我们的线与样本数据(点)的距离,以获得最佳拟合线。

成本函数的更多解释在—https://www . coursera . org/learn/machine-learning/lecture/rktp 3/cost-function

  • 但是我们有两个变量,c 和 a,我们需要不断改变,以得到最佳拟合线。
  • 对于 c 和 a 的初始组合,我们需要找到移动多少,然后移动它。一旦我们有了 c 和 a 的新值的新线,然后再次计算每个点的距离,并继续这样做,直到我们发现我们没有移动太多,例如移动得很少。

这基本上意味着我们的线离图上的点还很远。

  • 由于我们需要独立地改变 c 和 a,我们将使用偏导数。因此,我们将得到上述成本函数的导数 wrt c,然后是 wrt a。记住,我们有一个样本的 h(y )= c+ax
  • 因此,成本函数 wrt 'c '的偏导数的结果将是

  • 并且成本函数 wrt‘a’的偏导数的结果将是

  • 现在我们决定步长,也就是在每次迭代中我们想要采取多大或多小的步长。让我们称之为阿尔法,我们设置这个值为 0.01。它可以是基于数据的任何合适的值。
  • 所以 c 移动的距离是

  • a 移动的距离是

  • 上面的 farmulae 不仅会给出我们移动的距离,还会给出方向,例如,如果我们最初绘制的随机像更垂直,必须向下移动以达到最佳拟合,则新值将减少,例如 a 将从 1 变为 0.99。但是,如果我们最初的随机线是水平的,必须向上移动以达到最佳拟合,那么新值将会更多,例如,a 将从 1 变为 1.01。
  • 如前所述,当我们意识到我们几乎不动了或者经过一定次数的迭代后,我们就停下来。这意味着我们已经达到了最佳拟合线,即红线。

例子

没有例题练习的学习是什么?

让我们以印度的乘用车销售数据为例。为了简单起见,我们假设只有一个变量,即该国的 GDP 对销售有影响。在现实中,有更多的因素,如汽车贷款利率等,但这是下一篇文章。为此,让我们把重点放在印度汽车销售量与 GDP 的线性方程上。

样本数据

我查看了过去几年印度乘用车的销售情况。还检查了每年的 GDP。看着这两个数据,我突然意识到“当前年度”GDP 的影响会对“下一年度”的汽车销售产生影响。因此,无论哪一年的国内生产总值减少,下一年的销售就会减少,当国内生产总值增加时,下一年的汽车销售也会增加。因此,他们说为 ML 分析准备数据更重要,这也是最需要花费时间的地方。

让我们用等式 y = c + ax。

y =当年售出的汽车数量

x =上一年的国内生产总值。

我们需要找到 c 和 a。

下面是数据表。我将这些数据保存在一个名为“vehicle_sale_data”的文件中。请注意,售出车辆的数量以 10 万卢比为单位(10 万卢比= 10 万卢比)。

year,GDP,4wheeler_passengar_vehicle_sale(in lakhs)
2011,6.2,26.3
2012,6.5,26.65
2013,5.48,25.03
2014,6.54,26.01
2015,7.18,27.9
2016,7.93,30.47

第一列=年份,这在下面的代码中没有多大用处

第二栏——上一年的 GDP。这是等式中的 x。

第三列——售出的车辆数量。如果我们知道今年的 GDP,这就是我们想要预测的明年的情况。

模型创建

我们将使用 python 来创建模型。下面是步骤。

  • 阅读文件。“gdp_sale”字典将有关键字,因为 gdp 和值是销售额。
def read_data() :
    data = open("vehicle_sale_data" , "r")
    gdp_sale = collections.OrderedDict()
    for line in data.readlines()[1:] :
        record = line.split(",")
        gdp_sale[float(record[1])] = float(record[2].replace('\n', "")) return gdp_sale
  • 计算步骤,到达新的“c”和“a”。第一次,我们将传递初始值' c '和' a '。此函数将在移动一步后计算新 c 和新 a 的值。这个函数需要反复调用,直到它稳定下来。
def step_cost_function_for(gdp_sale, constant, slope) :
    global stepSize
    diff_sum_constant = 0 *# diff of sum for constant 'c' in "c + ax" equation*
    diff_sum_slope = 0  *# diff of sum for 'a' in "c + ax" equation*
    gdp_for_years = list(gdp_sale.keys()) for year_gdp in gdp_for_years: *# for each year's gdp in the sample data*
        *# get the sale for given 'c' and 'a'by giving the GDP for this sample record*
        trg_data_sale = sale_for_data(constant, slope, year_gdp) *# calculated sale for current 'c' and 'a'*
        a_year_sale = gdp_sale.get(year_gdp) *# real sale for this record*
        diff_sum_slope = diff_sum_slope + ((trg_data_sale - a_year_sale) * year_gdp) *# slope's (h(y) - y) * x*
        diff_sum_constant = diff_sum_constant + (trg_data_sale - a_year_sale) *# consant's (h(y) - y)* step_for_constant = (stepSize / len(gdp_sale)) * diff_sum_constant *# distance to be moved by c*
    step_for_slope = (stepSize / len(gdp_sale)) * diff_sum_slope *# distance to be moved by a*
    new_constant = constant - step_for_constant *# new c*
    new_slope = slope - step_for_slope *# new a* return new_constant, new_slope
  • 用于获取汽车销售的函数,提供了 c、a 和 x 的值。上述函数用于每个样本数据(gdp)。
def sale_for_data(constant, slope, data):
    return constant + slope * data   *# y = c + ax format*
  • 迭代以获得最佳权重,即 c 和 a 的最佳值。如果 c 和 a 在下一次迭代中的移动不超过 0.01,迭代将停止。
def get_weights(gdp_sale) :
    constant = 1
    slope = 1
    accepted_diff = 0.01 while 1 == 1:  *# continue till we reach local minimum*
        new_constant, new_slope = step_cost_function_for(gdp_sale, constant, slope)
        *# if the diff is too less then lets break*
        if (abs(constant - new_constant) <= accepted_diff) and (abs(slope - new_slope) <= accepted_diff):
            print "done. Diff is less than " + str(accepted_diff)
            return new_constant, new_slope
        else:
            constant = new_constant
            slope = new_slope
            print "new values for constant and slope are " + str(new_constant) + ", " + \
                  str(new_slope)
  • 当然还有主要的功能
def main() :
    contant, slope = get_weights(read_data())
    print "constant :" + contant + ", slope:" + slopeif __name__ == '__main__':
    main()

我得到的等式是

y(汽车销量)= 1.43 + 3.84 * x

  • x 是 GDP 的值

因此,如果我们今年的 GDP 为 7.5,那么我们明年的乘用车销量将为-1.43 7.5 * 3.84 = 30.23

完整的项目

完整的程序如下。它也在 github 的 https://github . com/skhurana 333/ml/blob/master/linearregsinglevariant . py 上

*# sales of vehicle as a function of GDP (for India)*import collectionsstepSize = 0.01 def read_data() :
    data = open("vehicle_sale_data" , "r")
    gdp_sale = collections.OrderedDict()
    for line in data.readlines()[1:] :
        record = line.split(",")
        gdp_sale[float(record[1])] = float(record[2].replace('\n', "")) return gdp_sale def sale_for_data(constant, slope, data):
    return constant + slope * data   *# y = c + ax format* def step_cost_function_for(gdp_sale, constant, slope) :
    global stepSize
    diff_sum_constant = 0 *# diff of sum for constant 'c' in "c + ax" equation*
    diff_sum_slope = 0  *# diff of sum for 'a' in "c + ax" equation*
    gdp_for_years = list(gdp_sale.keys()) for year_gdp in gdp_for_years: *# for each year's gdp in the sample data*
        *# get the sale for given 'c' and 'a'by giving the GDP for this sample record*
        trg_data_sale = sale_for_data(constant, slope, year_gdp) *# calculated sale for current 'c' and 'a'*
        a_year_sale = gdp_sale.get(year_gdp) *# real sale for this record*
        diff_sum_slope = diff_sum_slope + ((trg_data_sale - a_year_sale) * year_gdp) *# slope's (h(y) - y) * x*
        diff_sum_constant = diff_sum_constant + (trg_data_sale - a_year_sale) *# consant's (h(y) - y)* step_for_constant = (stepSize / len(gdp_sale)) * diff_sum_constant *# distance to be moved by c*
    step_for_slope = (stepSize / len(gdp_sale)) * diff_sum_slope *# distance to be moved by a*
    new_constant = constant - step_for_constant *# new c*
    new_slope = slope - step_for_slope *# new a* return new_constant, new_slope def get_weights(gdp_sale) :
    constant = 1
    slope = 1
    accepted_diff = 0.01 while 1 == 1:  *# continue till we reach local minimum*
        new_constant, new_slope = step_cost_function_for(gdp_sale, constant, slope)
        *# if the diff is too less then lets break*
        if (abs(constant - new_constant) <= accepted_diff) and (abs(slope - new_slope) <= accepted_diff):
            print "done. Diff is less than " + str(accepted_diff)
            return new_constant, new_slope
        else:
            constant = new_constant
            slope = new_slope
            print "new values for constant and slope are " + str(new_constant) + ", " + \
                  str(new_slope) def main() :
    contant, slope = get_weights(read_data())
    print "constant :" + contant + ", slope:" + slopeif __name__ == '__main__':
    main()

线性回归:当你想在爱荷华州开一家新的酒店时该怎么做

原文:https://towardsdatascience.com/linear-regressions-or-what-to-do-when-you-want-to-open-a-new-liquor-store-in-iowa-25fa619331b9?source=collection_archive---------0-----------------------

你是说爱荷华州的一家酒店?多好的主意啊!你说你不知道你想在哪里打开它?好吧,让我帮你缩小范围!

你看,爱荷华州碰巧在 data.Iowa.gov 时间发布了他们所有的酒类销售数据。它实际上足够详细,我可以告诉你,托莱多的 Twin Town Liquor 在 2015 年购买了 16 瓶 Dekuyper Sour Apple Pucker Traveler,州政府从这笔交易中获得了 50.40 美元。

让我们来看看爱荷华州有多少钱在流动:

https://public.tableau.com/views/IowaLiquorSales2015/Sheet1?:embed=y&:display_count=yes&publish=yes

从技术上讲,我们谈论的是一个月内所有产品支付给州政府(爱荷华州唯一的酒类经销商)的成本。我们将不得不用这个来代表利润。我的目标是查看给定城市中每家商店的平均购买量,以及如果再增加一家商店会是什么样子。一旦你找到了价值最高的产品,你就必须做更多的市场调查,找出竞争对手,估计零售价格(利润率),并准确地计算出放在哪里。我们只关注第一部分:找到我们的目标城市。

游戏的名字叫“线性回归”。基本上,这是一种获取多种输入并预测一种结果的方法。需要大量的假设来确保这是正确的模型。我们将跳过这一步,讨论如何用 Python 实现它。

直接进入主题,我们可以看看清理后的数据是什么样的,以及我们必须处理哪些列。

Some of the features I narrowed down to. Let’s test them out.

上面你可以看到我的精炼数据集,我缩小到每月每个商店的购买总量。使用由 https://www.census.gov/愉快地提供的一些额外的人口信息,我添加了每个商店人口的列。我们将按城市对每月信息进行平均,以找到我们最好看的位置。首先,我们从数据和我们希望能够用于预测的特征中创建我们的目标。特征是变量,如人口、数量或前几个月的销售额,或我们认为可能预测年度总销售额的任何其他因素。我已经有了一些想法,但最终决定使用每家商店的人口,一个城市中有多少家商店进行竞争,以及一月、二月和三月的数据,尝试看看使用这三个月是否可以预测全年。

很好,现在有了我们的预测变量(特性),让我们建立模型,看看我们是否可以计算出我们的目标平均年商店销售额。

对我们有好处。我们的模型解释了平均年商店销售额变化的 91%!但是,我们还希望确保我们的误差尽可能低(这里显示的是均方根误差),这意味着我们需要确保我们用来预测的一切实际上都有助于模型。让我们引入套索正则化来告诉我们哪些变量是重要的。

好吧。看起来销量不如销量有预测性。它们实际上应该是相互作用的变量,因为它们关系非常密切(唯一的区别是单位体积的价格)。我们会去掉这些,还有城市中的平均商店,只保留每个商店的销售额和人口。

好东西!我们使用套索正则化来去除一些实际上损害我们模型的变量。精确度提高了,我们的误差降低了。但这还不是正式的。这些都是我们用来建立模型的数据。现在我们需要在模型从未见过的数据上测试它。

不错!干得好,先生们。剩下唯一要做的就是做我们 2016 年的预测!为此,您只需重新训练完整数据集上的数据(不要将其分为测试和训练),然后对 2016 年的变量使用 lm.predict(X_2016)。您应该会得到一个类似这样的列表:

我们开个酒铺吧!

你可以在这里查看我的代码:https://github.com/dale-wahl/Iowa_liquor_sales我建议坚持写博客要点文件夹中的代码,但是如果你有点虐待狂,整本书都在那里。

线性时间与对数时间——大 O 符号

原文:https://towardsdatascience.com/linear-time-vs-logarithmic-time-big-o-notation-6ef4227051fb?source=collection_archive---------2-----------------------

你好。在两个多月不写/不碰代码之后,我终于回来了。我被所有的婚礼准备和计划所困扰。没有婚礼策划人,很难举办一场海外婚礼。但是这一切都是值得的,因为我们的婚礼是值得的!结婚热已经过去了,现在是时候回忆我的想法,回到编码上来了。

在我开始找工作之前,很难决定先复习什么。我想我应该从经典开始——算法和数据结构,编程的核心。在任何系统中,随着数据的增长,如果使用了正确的算法,性能应该不是问题。

今天,我写了一篇关于两种大 O 符号的博客,线性和对数算法。

先介绍一下大 O 符号的背景。

渐近分析

渐近分析是基于数学计算的,基本上是随着输入数据集的增长来衡量算法的效率(感谢维基百科!).根据应用场合的不同,还有其他类型的渐近分析,但在计算机科学中,它通常被格式化为大 O 符号

线性与对数

为了容易理解大 O 记数法,我们来比较一下这两种算法:线性 — O(n)和对数 — O(log n)。

作为一个例子,我们将尝试在一个排序的数组中寻找一个数字。

let numberList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

线性 O(n) —随着数据的增长,性能变得越来越低效。

线性或“强力”技术中,性能取决于输入大小。对于我们的例子,我们将通读数组中的每一项,并搜索我们需要的数字。很简单!

*//Logarithmic Time - O(n)*func linear(key: Int) {
for (index, number) in numberList.enumerated() {
     if number == key { 
        print("Value found in index \(index)")
        break
  }
 }
}

当然,这对于我们的小数据集是可行的,但是一旦你有了成千上万甚至数百万的数据,这就不是很有效了。

对数 O(log N)-通过重复将数据集减半直到找到目标值来缩小搜索范围。

使用二分搜索法-这是一种对数算法,查找数组中的中值并将其与目标值进行比较。根据目标值高于、低于或等于中值,算法将向上或向下遍历。

func binarySearch(key: Int, iminIndex: Int, imaxIndex: Int) {let midIndex = round(Double(iminIndex + imaxIndex)/2)
let midNumber = numberList[Int(midIndex)]
var result = ""***//using recursion, we can go up or down the array and reduce the*** range
if midNumber > key { ***//target is less than the median so traverse downwards*** binarySearch(key: key, iminIndex: iminIndex, imaxIndex:   Int(midIndex) - 1) } else if midNumber < key { ***//target is greater than the median so traverse upwards*** binarySearch(key: key, iminIndex: Int(midIndex) + 1, imaxIndex: imaxIndex) } else if midNumber == key { ***//Found it!***

 print("Found it at index \(midIndex)")} else { 

  print("Value \(key) not found")
}
}

该算法的大部分是在开始,但是随着我们从数组中丢弃不相关的范围并继续减半直到我们找到目标值,它慢慢变平。

通过下面的图表,我们可以很容易地比较大多数算法如何在较小的数据集上具有相似的性能,但随着数据的增长而不断变化。

Excerpt from Swift Algorithms and Data Structures by Wayne Bishop

如你所见,还有其他类型的大 O 符号,我将在接下来的几天里讨论。再见了。

参考文献:

Wayne Bishop 的 Swift 算法和数据结构

大 O 批注入门

维基百科:)

自然语言处理中的语言学知识

原文:https://towardsdatascience.com/linguistic-knowledge-in-natural-language-processing-332630f43ce1?source=collection_archive---------1-----------------------

自从进入自然语言处理(NLP)以来,我一直想写一些关于它的高层次介绍,提供一些我理解的结构,并给出该领域的另一个视角——与使用深度学习进行 NLP 的流行形成对比。

NLP 中的分析阶段

NLP Pyramid — Coursera Natural Language Processing

给定一个句子,传统上,以下是如何分析一个句子以获得更深层次见解的不同阶段。

1.形态学

在这个阶段,我们关心的是组成句子的单词,它们是如何形成的,以及它们如何根据上下文而变化。其中的一些例子包括:

  • 前缀/后缀
  • 单一化/多元化
  • 性别检测
  • 单词变形(修饰单词以表达不同的语法类别,如时态、格、语态等..).其他形式的词形变化包括词形变化(动词的词形变化)和词形变化(名词、形容词、副词等的词形变化)。
  • 词汇化(单词的基本形式,或词尾变化的反义词)
  • 拼写检查

Morphological analysis of a sentence — Spacy.io

2.语法(解析)

在这个阶段,我们更关注句子中单词的关系——句子是如何构成的。

在某种程度上,语法就是我们通常所说的语法——黑客的 NLP

为了获得这种理解,句法分析通常是在句子层次上进行的,而词法分析是在单词层次上进行的。当我们建立依存关系树或处理词类时,我们基本上是在分析句子的句法。

Dependency tree of a sentence — Spacy.io

3.语义学

一旦我们理解了句法结构,我们就更有准备去理解句子的“含义”(有趣的是,NLP 中的实际含义是什么——点击这里进入关于这个主题的 Twitter 讨论)。

此阶段执行任务的一些示例包括:

  • 命名实体识别(NER)
  • 关系抽取

Named entity recognition of a sentence — Spacy.io

在上面的例子中,以 Spacy 为例;谷歌、苹果和亚马逊已经被标记为一个基于其 NER 注释者的组织。虽然谷歌和亚马逊是一个简单的例子,但苹果却相当不同,因为它可能是一种水果,也可能是一家公司——苹果。在这种情况下,给出的结果是基于基于来自训练数据集的统计分析的预测。

4.语用学

在这个层面上,我们试图从整体上理解文本。我们在此阶段试图解决的常见问题有:

  1. 主题建模
  2. 共指/回指
  3. 摘要
  4. 问答

摘要

自然语言处理作为一个研究领域实际上并不新鲜。如果一个人已经精通深度学习,那么认为传统的 NLP 方法(即将文本分解成更小的结构、解析、注释含义)不再需要。

然而,在标签数据很难获得,并且需要高精度的情况下(例如,当一个人在紧迫的截止日期内时间紧迫,结果确实需要准确,否则产品不会推出),传统的 NLP 真正发挥了作用。

理解上述主题并不是解决 NLP 相关任务所必需的。对我来说,这更像是一种审视我以前解决的不同问题的方式,以及我可以改进的其他差距或领域。

免责声明:在写这篇文章的时候,我读了很多 Coursera 的 NLP 课程,维基百科,还有我最近最喜欢的 NLP 材料网站——黑客的 NLP。很可能你在这里看到的一些东西是这些来源之间的大杂烩,所以预先警告我可能会忘记在需要的地方正确引用它们的内容。

参考资料:

[1] 自然语言处理| Coursera

[2] 维基百科,自由百科

[3] 自然语言处理—简介—面向黑客的自然语言处理

[4] 语言特点,空间. io

LinkedIn 劳动力报告:各行各业都非常需要数据科学技能

原文:https://towardsdatascience.com/linkedin-workforce-report-data-science-skills-are-in-high-demand-across-industries-1510b06382a6?source=collection_archive---------11-----------------------

LinkedIn 平台作为一个独特的信息来源,为员工和求职者面临的动态提供了有益的见解,从那些寻求学习新技能的人到那些转向新角色的人。

该平台拥有超过 5 亿名会员。仅在美国,LinkedIn 就拥有超过 1.5 亿会员。因此,它可以提供关于美国劳动力的有价值的趋势。

根据就业导向服务机构 2018 年 8 月的报告,美国各行业对数据科学技能的需求正在上升。

事实上,高需求导致全国缺乏 151,717 名具有数据科学技能的专业人员。

美国数据科学家 DevZero 热衷于向人们传授他的技能,他提到“今天的行业非常依赖数据,在很大程度上依赖于它们的战略决策过程,这使得对数据科学家的需求急剧增加。”

数据科学技能需求增加

数据科学涉及使用各种科学工具和流程来创造可用数据的价值。

科学方法、公式和算法通常用于从结构化和非结构化数据中获得全面的见解和提取有用的模式。

以前,数据科学领域不被认为是有利可图的,数据科学家过剩。

例如,2015 年,一家美国雇主想要雇用一名数据科学家,不必费力寻找有技能的人。

当地的人才短缺较少,雇主在雇用候选人时有很多选择。

然而,三年后的今天,情况不再相同:数据科学技能在美国几乎每个大城市都供不应求

事实上,据说这种短缺非常普遍,不仅限于科技和金融领域。

就业相关搜索引擎 Indeed.com 估计,美国数据科学家的平均年收入为 131,651 美元。

2018 年 8 月 LinkedIn 劳动力报告

LinkedIn 劳动力报告指出,在未来五年内,数据分析师和科学家将成为最受欢迎的专业人士。

IBM 和世界经济论坛的预测证实了这一点,这些预测认为,到 2020 年,每年对数据开发、数据科学和数据工程相关职位的需求将达到近 70 万个。

下表显示了从 2015 年 7 月到 2018 年 7 月,美国一些主要城市缺乏数据科学技能的加剧情况。技能短缺标有加号(+)而过剩标有减号(-)。

根据 LinkedIn 企业通信团队的说法,与数据科学领域相关的一些关键见解值得注意:

  • 将 2018 年 7 月的夏季招聘与前一年相比,2018 年的招聘更加强劲,全国所有行业的总招聘人数增长了 4.6%。
  • 2018 年 6 月至 7 月,经季节性调整的全国招聘人数也增长了 0.5%。农业、制造业和运输与物流被指定为 6 月份招聘人数同比增幅最大的行业,分别增长了 26%、12.3%和 12%。
  • 数据科学领域的技能缺口是真实存在的。仅在三年前,整个国家的数据科学技能过剩,雇主有一系列专业人员可供选择,几乎不短缺。
  • 今天的情况有很大不同,全国各地都经历着严重的短缺。例如,纽约市正面临 34,032 名数据科学家的严重短缺,洛杉矶需要大约 12,251 名数据科学专业人员,旧金山湾区估计短缺 31,798 人。
  • 随着人们转向更强的就业市场,如德克萨斯州奥斯汀,移民现象十分猖獗。奥斯汀在美国排名第一。通过吸引更多工人,该市的招聘人数比去年增加了 14.3%。
  • LinkedIn 已经证实,目前在奥斯汀的 10,000 名会员中,有 105 人是在过去 12 个月里迁移到这座城市的。其中,10.5%来自休斯顿,7.6%来自旧金山,4.8%来自纽约市。向奥斯汀的大规模迁移可以归因于它所标榜的蓬勃发展的技术中心,表现为数据存储技术的巨大技能缺口和对开发工具的迫切需求。

包扎

鉴于对不同领域和行业的见解,2018 年 8 月 LinkedIn 劳动力报告在帮助员工以最佳方式指导职业生涯方面大有作为。

正如该报告所指出的,数据科学在当今所有行业都非常重要,给自己定位可以帮助你做出人生中最大的职业转变。

由于该领域巨大的技能缺口,你可以学习数据科学,增加获得工作的机会;数据科学是未来最需要的技能。

那么,你对数据科学领域存在的技能差距有什么看法?

请在下面分享你的评论。

LISSA:基于现成高等教育数据的面向学生的学习分析仪表板

原文:https://towardsdatascience.com/lissa-a-student-facing-learning-analytics-dashboard-based-on-readily-available-higher-education-ab32bca31ae?source=collection_archive---------5-----------------------

不是每个人都喜欢阅读冗长的科学论文,但是仍然有很多有趣的东西。所以我打算试着开始一个新习惯:把我冗长乏味的论文变成更容易消化的博文。如果大多数人都不读这些科学,那这些科学还有什么意义呢?为了让你开心,我会尽量简短,因此我会省略很多细节。但如果你真的渴望了解更多,你可以随时查看原始论文!

本文基于 2017 年 6 月发表在IEEE Transactions on Learning Technologies上的论文“Learning Analytics Dashboards to Support Adviser-Student Dialogue”。

在博士期间,我主要专注于学习仪表板。这些仪表板中的大部分仍然侧重于教师和研究人员作为用户,但我的目标是通过数据可视化让学生了解自己的过程,从而增强他们的能力。我设计并评估了许多仪表盘,但有一个很突出:LISSA,或“在学习期间接受我的指导和 T21 的支持的收入仪表盘”。LISSA 支持学习顾问和学生之间的对话,目前正在鲁汶大学的一系列学位中使用。

Setup of an advising session. LISSA is displayed on a screen visible to both study adviser and student.

在我们的研究中,我们涉及了一群研究顾问(同样,简单的版本:详见论文)。这些学习顾问负责为特定项目的一年级学生提供学习建议和与内容相关的支持。他们是第一年课程内容、当前项目组织和监管方面的专家,既有针对具体项目的,也有针对整个大学的。

研究顾问帮助我们深入了解他们是如何工作的,以及在这些咨询会议中他们的需求是什么。这些会议是在办公室环境中与学生(偶尔与家长)的私人谈话。这些学生通常没有完美的学习生涯:他们学习有困难,会受益于个性化的课程计划,一年中没有获得足够的学分,或者只是希望重新定位于新的课程。

研究顾问有多种工具和网站供他们使用。但是为每个特定的学生组合和解释这些多种渠道的信息需要努力和时间,并且容易出错。此外,数据往往不完整。

仪表板

使用以用户为中心的快速原型设计方法,我们从最初设计的草图D3.js / 流星开始创建我们最终的交互原型。这里有两张最终设计的截图(2017 年年中,今天我们的一个新博士生接手并做了一点重新设计):

From left to right: positioning test results for July and September (ijkingstoets), mid-term tests (tussentijdse toetsen), January and June exams. Above each period: histograms of peer performance for that period and an indicator of the student’s position in relation to grades of peers in the different test periods. Each course result is accompanied with a histogram of peer performance for that specific course. Failed courses can be planned for re-sits. Length of bachelor in years is predicted through historical data.

现在来看一些细节…

年度概览

LISSA 按时间顺序概述了每个关键时刻,直到举行咨询会议的时期:定位考试(一种无后果的入学考试)、期中考试、一月考试和六月考试的成绩。顶部显示了学生表现的总体趋势:学生路径由直方图组成,显示了每个关键时刻学生在同龄人中的位置。

每门课程都用它的名字和分数(满分 20 分)来表示。绿色、橙色和红色编码代表成功的考试、可接受的分数(学生可以要求通过有限的 8-9/20 的分数)和失败的课程。该课程附有一个柱状图,显示了同学的表现以及学生在其中的位置(黑色突出显示)。

规划

对于六月的课程,计划九月的重考是很重要的。考试太少会导致学分门槛问题,而考试太多很可能会导致失败。失败考试旁边的复选框让指导老师和学生选择几门课程。“重考成功率图表”使用历史数据来提供对过去成功通过所选数量的考试的学生人数的洞察。

预言;预测;预告

堆叠预测栏提供了与学生具有相似概况(基于通过或未通过考试的数量)的学生的历史数据:它显示了具有相似九月重考的学士课程持续时间的分布(三-四-五年或辍学/“NIET”)。

数据源

为了可视化关键时刻,需要关于学生成绩的数据。这包括本年度所有一年级学生填写课程和课程直方图、学生路径和课程直方图。关于一月、六月和九月期间的所有等级都可以在 KU Leuven 数据仓库中获得。

堆叠的预测条基于往年的一年级学生成绩。这提供了预测三年、四年、五年或更长时间的学士学位所需的数据。

我们使用 Python 脚本创建了一个数据处理管道,将不同的文件和格式转换成一个简单的表示,并导入到 MongoDB 中。

吸取的教训

学习分析数据的作用

LA 仪表板通常是为具有特定数据要求的特定机构开发的。部署 LISSA 所需的学习分析数据非常基本:学生在关键时刻的成绩和关于学生成功的数据(来自历史成绩数据)。大多数高等教育机构通常都有这种数据,但仅限于工作人员。然而,我们已经表明,将这些数据放在学生建议环境中,可以帮助支持学生,提供对他们进步的见解,并帮助规划他们的未来。

LISSA 是基于事实数据。考试成功率和学士持续时间显示了历史上发生的事实,并没有提供计算估计。这种可靠的数据可视化方式让研究顾问和学生对他们给出和接受的建议感到放心。

关于社会经济地位、父母教育、性别和高中成绩的个人背景数据可以提供进一步的见解,并帮助研究顾问更好地了解学生的情况。然而,这些不可改变的数据并没有给学生提供可操作的见解。因此,研究如何以道德的方式整合这些数据是很重要的。

学习顾问的角色

LISSA 有助于多层次的洞察力,但这些洞察力受益于研究顾问的指导。即使数据是客观的,仍然需要领域专家进行批判性和反思性的解释。过于自信的学生可能会把总体的负面结果解释为一个可以克服的问题,而学习顾问可以建议和计划一个更可行的计划,防止学生在错误的选择上浪费时间。LISSA 可能会以负面的方式描述学生,而与学生的讨论可能会揭示容易解决的问题,例如学习方法的改变、新计划或态度的改变。如果没有研究顾问的指导,这些学生可能会选择不继续他们的学士课程。

LISSA 仍然为个人意见和隐性经验留有余地,因为它们仍然在建议会议中发挥重要作用,允许研究顾问强调某些结果,以推动他们走上正确的道路。许多外部因素,如通过讨论收集的信息和以前学习顾问对学生的经验,会影响偏离事实数据或以不同方式解释数据的决定。

透明度

在半结构化的访谈和研讨会期间,出现了关于让学生面对数据的伦理问题。

一些学习顾问没有向有大量课程不及格的学生展示 LISSA。虽然一些学生可能会从“大开眼界”中受益,但学习顾问更喜欢将 LISSA 作为一种激励工具。

LISSA 的一个重要作用是能够在同龄人中定位学生。总的来说,直方图的使用被认为是非常有用的,并且定位具有积极的效果,例如当一个坏的分数在同龄人中仍然是好的,或者课程不及格率非常高时,激励学生。一些学习顾问担心会失去动力:一个处于直方图低端的学生可能会认为成功完成这门课程是一个无法实现的目标。

然而,学生们要求在会议之外接触 LISSA。但是研究顾问担心,如果没有他们的指导,可视化的数据可能会被严重误解:害怕失败的学生或过于自信的学生可能会错误地解释数据。父母可以扮演一个消极的角色,要么太努力,要么把平庸的结果解释为不可克服。没有学位的父母对高等教育缺乏了解可能会阻止学生追求一个可实现的学位。这些问题可能会导致关于考试和学习职业规划的错误决策。研究顾问确实看到了提供精简信息的潜力,但这种精简意味着什么,必须进一步讨论和评估。

希望你喜欢这个关于 LISSA 和我们发现的简短概述。它目前被部署在比利时最大的大学之一的鲁汶大学的多个校区。如果您想了解更多的经验教训,或者评估过程和结果的更多细节,请查看原始论文或者给我一个 ping!

关于我在 http://svencharleer.com/的更多信息

深度学习云服务提供商列表

原文:https://towardsdatascience.com/list-of-deep-learning-cloud-service-providers-579f2c769ed6?source=collection_archive---------14-----------------------

现在有很多地方可以租到你的 GPU。我列出了我能找到的所有拥有 GPU 的云提供商,因为我在任何地方都找不到完整的列表。

NVIDIA Tesla V100 for NVLINK

我计划比较一些供应商。如果你有兴趣看的话,请跟我来。

我把亚马逊和谷歌包括在内两次,因为它们都有两种截然不同的产品。

Medium 不便于插入带有可点击链接的表格。如果你想点击这些,请查看 GitHub repo 中的列表。

如果你对这个列表有任何补充,请在的 GitHub repo 上添加它们,这样我就不会错过它们。

希望这个小清单对你有帮助。如果你有,请鼓掌😃!

免费必读机器学习书籍列表

原文:https://towardsdatascience.com/list-of-free-must-read-machine-learning-books-89576749d2ff?source=collection_archive---------2-----------------------

机器学习是人工智能的一种应用,它使系统能够自动学习并根据经验进行改进,而无需显式编程。在这篇文章中,我们列出了一些你应该考虑浏览的最好的免费机器学习书籍(没有特别的顺序)。

海量数据集的挖掘

作者: Jure Leskovec,Anand Rajaraman,Jeff Ullman

基于斯坦福计算机科学课程 CS246 和 CS35A,本书面向计算机科学本科生,不要求任何先决条件。这本书已经由剑桥大学出版社出版。

统计学习导论(R 中的应用)

作者:加雷斯·詹姆斯,丹妮拉·威滕,特雷弗·哈斯蒂和罗伯特·蒂布拉尼

这本书包含了统计学习方法的序言以及一些 R 实验室。

深度学习

作者:伊恩·古德菲勒、约舒阿·本吉奥和亚伦·库维尔

这本深度学习教材是为那些处于机器学习特别是深度学习初级阶段的人设计的。这本书的网络版现在可以免费获得。

黑客的贝叶斯方法

作者:卡姆·戴维森-皮隆

这本书从计算的角度向你介绍了贝叶斯方法和概率编程。这本书基本上是那些对数学不甚了解的人的天赐之物。

理解机器学习:从理论到算法

作者: 沙莱夫-施瓦茨和沙伊本-大卫

对于精通数学的人来说,这是理解机器学习背后的魔力的最值得推荐的书籍之一。

深度学习教程

作者:蒙特利尔大学丽莎实验室

使用 Theano 的深度学习教程,如果你愿意进入这个领域,是必读书,而且绝对免费。

Scikit-Learn 教程:科学数据处理的统计学习

作者:安德里亚斯·穆勒

探索统计学习,本教程解释了使用机器学习技术的目的是统计推断。该教程可以免费在线获得。

机器学习(算法视角)

作者:斯蒂芬·马斯兰德

这本书为学习机器学习和人工智能的工程和计算机科学学生提供了很多东西。不幸的是,这本书由 CRC 出版社出版,由 Stephen Marsland 撰写,并不是免费的。然而,我们强烈建议你投资这个。此外,所有的 python 代码都可以在线获得。这些代码是学习 python 的很好的参考资料。

用 Python 构建机器学习系统

作者:威利·里歇特和路易斯·佩德罗·科埃略

这本书也不是免费的,但包括它服务于我们的列表正义。这是一个最终的实践指南,以获得最大的机器学习与 python。

这些是我们推荐的一些最好的机器学习书籍。有别的想法吗?请在下面评论你的一些令人敬畏的机器学习书籍。

对使用人工智能感兴趣?你可以注册免费 ParallelDots 账号,使用触手可及的人工智能。

必读的免费数据科学书籍列表

原文:https://towardsdatascience.com/list-of-must-read-free-data-science-books-bfae4c5c5a16?source=collection_archive---------7-----------------------

数据科学是一个跨学科的领域,包含了统计学、机器学习、贝叶斯等领域的方法和技术。它们都旨在从数据中产生特定的见解。早些时候,我们列出了一些你应该考虑阅读的最好的机器学习书籍的清单。在本文中,我们列出了一些优秀的数据科学书籍,涵盖了数据科学领域的各种主题。

数据科学基础

作者:布鲁姆、霍普克罗夫特和坎南

这本书是数据科学的现代理论课程讲座的伟大融合。

UFLDL 教程

供稿:吉泉恩亚姆、传友富、麦一凡、孙嘉玲

本教程旨在让你熟悉无监督特征学习和深度学习的主要思想。

Python 数据科学手册

作者:杰克·范德普拉斯

这本书介绍了使用 Python 处理数据所必需的核心库:特别是 IPython、NumPy、Pandas、Matplotlib、Scikit-Learn 和相关的包。

动手机器学习和大数据

作者:卡里姆·阿尔卡西

这本书是学习机器学习和大数据概念的绝佳来源。

思考统计

作者:艾伦·唐尼

Think Stats 强调可以用来探索真实数据集和回答有趣问题的简单技术。这是最值得推荐的数据科学书籍之一。

想贝叶斯

作者:艾伦·唐尼

《思考贝叶斯》是使用计算方法对贝叶斯统计的介绍。这本书用 Python 代码代替数学,用离散逼近代替连续数学。

EE263:线性动力系统简介

作者:礼萨·纳西里·马哈拉蒂

桑杰教授的这份汇编强调了应用线性代数和线性动力系统在电路、信号处理、通信和控制系统中的应用。博伊德教授前几年课程笔记的链接可以在这里找到。

凸优化——博伊德和范登堡

作者:史蒂芬·博伊德和列文·范登堡

这本书提供了一个全面的主题介绍,并详细说明了如何解决这类问题的数字效率很高。

元启发式的本质

作者:肖恩·卢克

这是一套关于元启发式算法的开放式课堂讲稿,面向本科生、从业者、程序员和其他非专家。

CIML

作者:哈尔·多梅三世

CIML 是一套介绍性材料,涵盖了现代机器学习的大多数主要方面(监督学习,非监督学习,大幅度方法,概率建模,学习理论等)。).

这些是我们推荐的一些最好的数据科学书籍。有别的想法吗?请在下面评论您的一些令人敬畏的数据科学书籍列表。

对使用人工智能感兴趣?你可以免费注册账号使用人工智能。

强化学习入门🤖

原文:https://towardsdatascience.com/lite-intro-into-reinforcement-learning-857ca5c924d9?source=collection_archive---------7-----------------------

这是对强化学习(RL)的简要介绍,用简单的术语讲述了基础知识。我们从 RL 的简要概述开始,然后进入一些解决 RL 问题的技术的实际例子。最后,你甚至会想到可以应用这些技术的地方。我想我们都同意建立我们自己的人工智能(AI)并让机器人为我们做家务是很酷的。

…让我们开始吧!

1)什么是 RL?🧐

“强化学习是机器学习(人工智能)的一个领域,起源于强化的心理学概念,涉及软件代理的决策,以最大化模型环境中期望的回报概念。”

如今,强化学习已经在人工智能和机器学习(ML)技术中找到了自己的路,然而它的起源来自行为心理学。美国心理学家 E. L .桑代克在 20 世纪中期引入了强化这个术语。然后,另一位名叫 B.F .斯金纳的美国心理学家跟进桑代克的研究,提出了一种新的学习过程,称为操作性条件反射 (OC)。也是在那个时候,一位美国应用数学家 R. E. Bellman 开发了动态编程,这有助于用计算机解决 RL 问题。从那时起,RL 已经大量转移到数字世界,这也许要归功于加拿大计算机科学家 R. S .萨顿在 20 世纪末开创了计算强化学习并出版了他有影响力的 RL 教科书。这让我们可以把机器学习作为最突出的领域来呈现,并投入到大规模实施的决策中。

…行为心理学的强化🐹

是一种效应 当一个有机体暴露在特定的刺激下,促使它执行习得的行为时,它会强化未来的行为。它被用在特定类型的条件作用中,这些条件作用使用刺激来表现作为学习的一部分的反应。在 OC 中,行为由环境中可察觉的变化控制,也称为环境刺激,它是影响活动的外部事物。例如,环境刺激是生物体可以检测到的不同表现形式,例如,我们的身体可以检测到触觉、声音、视觉等。为了把它带回到强化,OC 使用强化或惩罚来修改行为的可能性。同样,它也包括自愿行为,可以用下面的动物行为例子来描述。

  • 一只狗可以被训练得在受到狗食奖励时跳得更高,这意味着它的行为被狗食强化以执行特定的动作

[Klein & Abbeel 2018]

…机器学习中的强化🤖

是对软件代理的后续动作的一种效果,即在给予奖励后探索模型环境以强化其未来行为。软件代理被发送到模型环境中,带着实现某些预期目标的意图采取行动。这种代理可以被认为是计算机程序,它们因执行正确的动作而受到奖励,或因执行错误的动作而受到惩罚,并从它们的经验中学习。什么是对什么是错一般取决于环境,但正确的行动通常是通向实现目标的最佳途径(不管是什么)的行动,如下例所示。

  • 迷宫(环境)中的智能体可以被编程为自主地(通过奖励)找到最快的方式(行动)如何逃离它(目标)
  • 海洋(环境)中的智能体可以被编程为自主地(通过奖励)寻找最长的方式(行动)如何在水下生存以恢复受损的珊瑚礁(目标)

…让我们看看如何通过数学模型来定义这样的理论 RL 示例!

2)如何定义 RL 问题?✍

“RL 任务的公式化可以通过结合马尔可夫决策过程和‘正确’策略来完成,当解决模型环境时,软件代理可以将它们用于自己的决策。”

马尔可夫决策过程(MDP)提供了一个简洁的数学框架来模拟 RL 中的决策。MDP 用于决策者(软件代理)部分控制结果而其余结果是随机的情况。它为代理配备了关于状态动作转移概率奖励折扣因子的知识。这些属性以及其他一些常用术语将在下文中“简略”描述。

maze example — grid world [Klein & Abbeel 2018]

🐹代理人 - >为你干脏活的家伙!

🗺环境 - >一个宇宙/空间/世界,一个智能体在其中完成工作,例如,它可以是一个随机(随机生成的)网格世界,描述了上图中的迷宫

🏔状态 - >环境中代理的特定状态/位置

💃🕺action (a) - >可能导致新状态的代理行为

🤷‍转移概率(P) - >智能体在环境中如何移动的概率,即智能体在特定状态下的行为将/不会导致其他可能状态的可能性

💵奖励(R) - >从字面上看,一些钱作为奖励,或者一些化石燃料作为惩罚,也就是消极的奖励,因为一个代理人的决定进入了一个状态

⚖️折扣因子****【ɣ】->帮助代理专注于其工作,不会因收到的奖励大小而分心,例如,它通过计算未来和当前奖励的重要性差异来衡量收到的奖励

👴🏻体验 - >代理通过进入一个环境并执行一些动作而获得的体验,例如观察新状态、奖励等习得的行为。

🔮策略****【π】->告诉代理如何在状态中行动,甚至如何从起点到目标,即它是从状态到选择每个可能行动的概率(转移概率)的映射……策略可以是对环境中每个状态给出一个行动的 MDPs 的解决方案,例如" π(s) - > a "

这一切都是为了获得长期回报!💰

M DPs 都是关于长期奖励,所谓延迟 奖励。这些奖励导致代理在环境中试图解决的任务(目标)的完成。例如,一个代理可以通过进入一个特定的状态获得一个重要的短期奖励,即所谓的即时奖励。然而,走这条立即获得回报的道路可能不是完成任务的最佳方式。这取决于在一个环境中如何设置奖励。

...是时候回答一些问题了!

…代理如何找到新的状态?👀

它是通过跃迁来完成的,即一些跃迁函数 T(s,a,r,s’) 它描述了一个过程中智能体如何发现一个新的状态。在一个模型环境中,一个代理处于某个状态(s),采取一个动作(a),然后为此获得一个奖励(r),并通过这个过程找到一个新的状态(s′)。

…代理商如何知道在美国有多好?👍

在 RL 中,决策是由一个代理人完成的,这个代理人通常需要知道处于一个给定的状态或执行他们给定的动作有多好。例如,一个代理人想知道预期的回报,也就是未来的回报,这取决于他将要采取的行动。许多 RL 算法通过估计状态或状态-动作对的函数,称为值函数来解决这种需求。这些功能是用特定的行为方式(策略)来定义的。价值函数用于组织和结构化策略的搜索,这是 RL 的关键思想之一!

Bellman equation — value function calculating values in states for MDPs

O 如何利用价值函数的一种方法是贝尔曼方程,它是基本 RL 方程之一,根据问题的不同可以采用多种形式。上面的等式是针对 MDP 的一个示例。它展示了如何获取处于特定状态的值(V)并在该状态下遵循策略(π)。具体来说,它使用该州的奖励和下一个州(sʹ).)的转移概率(P) &值的贴现和

MDPs 的最终目标是什么?🏒 🥅

MDPs 中的目标通常是找到最优策略。它是使长期预期报酬最大化的。正如下面的高级定义所示,最优策略返回在某些环境状态下要采取的特定操作。通过遵循策略(π)并在特定时间(t)经历一系列状态来计算折扣奖励的期望总和。

optimal policy (π*) — finding the right actions in states for MDPs

maze example — map [Klein & Abbeel 2018]

…现在想象一个代理人有一张如上图所示的迷宫地图,那么它将知道在每种情况下做什么才能得到钻石或不被杀死,因为每个州都有一个特定的行动(绿色箭头),这就是“有政策”的意思!

…那么,在这个迷宫示例中,RL 在哪里?‍🕵️‍

It 是有的,但这取决于我们对迷宫(环境)了解多少,以及我们试图完成什么。只有当一个主体采取行动寻找回报的迷宫的所有特征都已知时,它才能用 MDP 来完整地描述。然后,一个代理知道每个状态中的所有动作,并且新的状态和奖励这样的动作导致。然而,一个代理仍然需要找出哪一系列的行动能最佳地导致最终的回报/目标,即找出最佳策略。这有时被称为离线规划,可以通过使用 MDPs 的知识并找到策略来解决,这实际上不是 RL 问题。

然而,在这个“真实”的世界中,存在任意大小的环境,它们可以是巨大的和组合的。例如,一个迷宫可以有许多可能的动作和结果的状态。然后,不一定有任何关于转换或奖励的知识,直到代理实际尝试一些动作并弄清楚这一点!这有时被称为在线学习,它仍然假设 MDPs 并继续寻找策略,但它更具有“真正的”RL 性质。这意味着代理从数据中学习,这与仅使用静态数据的离线情况形成对比。总之,RL 问题可以用 MDP 来表示,就其主要性质而言,MDP 可能是复杂且不完整的。

…让我们看看如何利用引入的 MDP 定义来解决 RL 任务!

3)如何解决 RL 问题?🎮

RL 问题可以用动态规划、时间差异学习或策略梯度方法(T21)来解决。然而,通常有必要通过使用深度神经网络&来帮助在更复杂环境中运行的代理找到良好的近似解决方案,这些技术可以解决基本的探索-开发权衡。”

解决 RL 问题的方法因环境的性质而异,比如我们对环境了解多少,或者我们想在环境中解决什么任务。一般来说,RL 应用可以用 MDPs 来表示,用某种形式的动态规划 (DP)方法来解决。DP 是一种优化技术,它将问题分成更小的任务,并递归地解决它们。它们也可以用仅使用 DP 的某些方面的方法来解决,例如在时间差异 学习 (TD)方法中。在 TD 方法中,算法通过将蒙特卡罗方法的采样(估计期望值)与 DP自举(在其他估计的基础上更新估计)相结合来学习。现代 RL 解决方案之一是策略梯度** (PG)方法,它可以直接逼近最优策略,而无需使用任何近似值函数。PG 方法通常是通过深度神经网络实现的,深度神经网络是多层连接的人工神经网络(ann)。还有许多其他方法来解决 RL 问题,但它们都有一个相似的目的利用学习过程中的经验并以某种方式获得环境的未知属性,如 MDP 中的概率或奖励。**

RL 通过表格或近似解求解!🤖 🍽 📐

  1. 简单 MDPs 中,解决方案大多通过表格解决方案找到,其中表格(数组)表示近似值函数,因为这里的环境很小或很简单。他们经常可以找到精确的解决方案,例如找到精确的最优政策或最优价值函数[萨顿&巴尔托 2017]。换句话说,它是关于在完全描述的环境中,在可能无限的时间和数据上找到最优策略或最优价值函数。算法通过对环境的所有状态的值&策略的递归来计算这一点。这可以通过前一节中引入的策略和值的等式的递归的某种变体来完成,或者也可以通过它们的迭代的某种变体来完成,例如进行值迭代策略迭代
  2. 在复杂的 MDP中,解决方案大多是通过近似解找到的,这些近似解可以将以前在不同状态中遇到的情况推广到其他情况,因为这里的环境很大。换句话说,解决问题在很大程度上转变为寻找一个计算量不大的好的近似解决方案,因为我们不能指望在这样的环境中找到最优政策或最优价值函数【萨顿&巴尔托 2017】。此外,在这种情况下,通常有必要通过 ann 来帮助代理完成他们的工作。例如,人工神经网络可以通过充当非线性函数逼近器和学习价值函数或最大化预期回报来处理代理人的经验。

…现在似乎是再次回答一些问题的好时机!

…那么,代理解决任务的最佳方式是什么?🎢

It 通常是代理在完成环境中的任务时,能够在探索和利用之间找到正确平衡的一种方法。探索是从数据中学习的能力,而开发是使用你目前所知的能力。这两种能力对一个特工来说都很重要。然而,这在 RL 中实际上是一个困难的任务,因为当试图为一个环境提出策略时,这两者会发生冲突。

T 这种冲突可以通过寻找“好”策略的两种不同学习方法来处理,即策略上的学习策略外的学习。他们都试图通过确保无限频繁地选择所有动作来评估或改进策略,这意味着代理只是继续选择它们。主要区别在于,政策上的学习为用于决策的政策做,而政策外的学习为不同于用于生成数据的政策做【萨顿&巴尔托 2017】。它们都可以通过一些函数逼近来解决,这在复杂环境中非常有用。然后,通常会有收敛或这种近似解的稳定性的挑战,但我们不会在本介绍材料中谈论这些:)**

…算法能区分代理的目标和习惯吗?☯

是的,算法可以做得很好,实际上在各个领域都有不同的术语来描述这种行为上的区别。在认知科学中,这是关于反思** 反思决策和选择。在 RL 中,如果我们考虑目标导向习惯性行为之间的这种心理差异,它是关于基于模型的 无模型的算法。基于模型的方法通过代理环境的模型提前计划来选择动作。无模型算法通过访问存储在策略或行动值函数中的信息来做出决策【萨顿&巴尔托 2017】。**

让我们回到上一节介绍的 MDP 术语。无模型算法最有可能的工作,比如 TD 学习,将是 MDP 中并非所有属性都已知的工作。此外,关于计划的相当通俗的术语,无模型算法将解决在线学习的情况,而基于模型的算法将解决离线计划的情况。

…有哪些常见的 RL 算法?🔦

It 也许值得一提的是 RL 中的基本算法,它们在某种程度上可用于近似解,因为这就是 RL 实现的全部内容。有两种不同的算法称为 Q-learningSARSA 属于 TD 方法。他们都需要一些行动价值评估来提出他们的政策,也就是说,他们必须首先了解行动的价值,以选择最佳行动。主要的区别也许是他们的政策学习类型;一个是非政策,另一个是政策。然后,有两个不同的算法叫做加强演员评论家属于 PG 方法。他们可以学习一些参数化的政策,这些政策可以在不咨询价值函数的情况下选择行动(行动-价值估计)[萨顿&巴尔托 2017]。参数化策略是表示为称为参数的一些独立量的函数的策略,例如,参数可以是实现 PG 方法的神经网络的权重。

到总结, TD 算法可以学习行动值,然后使用它们来确定行动选择,而 PG 算法可以学习参数化策略,使行动能够在不咨询行动值估计的情况下采取【萨顿&巴尔托 2017】。换句话说,它是关于用值函数而不是参数来表示策略。

…这听起来可能有点令人困惑,所以让我们在 RL 介绍文本的其余部分只看 Q-learning!

…Q-learning 是如何工作的?🎛

Q-learning 是一种无模型算法,实现了属于 TD 方法的偏离策略学习。它通过状态-动作对将代理的学习建立在经验的基础上,而没有转移概率的明确说明。字母 Q 代表“质量”处于一种状态,用代表状态-动作对的 Q 值来表示。高 Q 值意味着与低 Q 值相比,在那里(在这种状态下)更好。****

0010Q 学习通常遵循某个勘探-开采策略并且学习与采取最优策略相关的 Q 值。它存储每个环境状态的 Q 值,并在学习时直接更新它们,即它使用自己的转换(存储的数据)来直接产生方程的解。目标是通过近似如下所示的 Q 函数来推断最优策略(π*)。

Q-learning — optimal policy

0100Q 学习可以通过计算为环境中的每个状态产生 Q 值的等式来解决,例如下面的等式。它包含了一个叫做学习率** (α)的东西,它决定了代理在探索和利用方面如何学习(代理什么都学,什么都不学)。还有贴现因子 (ɣ),它通过设立一个即时或延迟满足的代理(又名近视或远视代理)来决定未来奖励的重要性。通俗地说,这个等式产生的新 q 值粗略地证明了当一个代理处于状态(s)并试图做某事(a)时,某事已经发生(sʹ)。**

Q-learning — equation for Q values

Q-learning 可以使用一个来存储数据,作为其最简单的实现版本。然而,对于大型问题(有许多状态或动作的环境),这可能不可行。这就是神经网络作为函数逼近器发挥作用的地方,它允许在表格做不到的地方扩大规模。它们为解决方案提供了更多的灵活性,但代价是牺牲了一点稳定性。不考虑具体的 Q-learning 实现,在选择动作的时候也需要有一个游戏计划。在我们下面的编码示例中,我们使用了一个带有ε贪婪策略多臂强盗算法,用于决定关于勘探-开发困境的动作

…所以让我们直接开始实施我们自己的 RL 示例吧!

4)编码示例:通过 Q 学习解决的迷宫💻

“我们将通过表格和神经网络实现对 Q 学习算法进行编码,尝试用 RL 解决一些众所周知的类似迷宫的环境。”

q-用表格学习🤖 🎛 🍽

()ka ggle 内核版本运行在您的浏览器中 )

用人工神经网络学习🤖 🎛 ☎️

()ka ggle 内核版本在您的浏览器中运行 )

结论

我们刚刚学习了学习过程的一些应用,这可能有助于读者开始思考 RL。我们看到,问题可以用 MDP 来定义,并用使代理能够在各种情况下工作的方法来解决。然后,我们编写了自己的 RL 解决方案,解决迷宫般环境中的一些情况。还有许多其他的计算方法来解决 RL 问题,但希望这篇文章只是简单地传达了 RL 的基本思想,并为那些寻找快速起点的人服务。

现在,我建议你亲自动手制作自己的 RL 应用程序!也许从探索更多强化学习过程的例子开始,但同时尝试用强化学习解决它们。这可能有助于你以后在 ML 空间创建独特的解决方案……这个空间现在充斥着大量可爱的图片🐱&🐶 😃

参考

  • R.萨顿和巴尔托:《强化学习:导论》,第二版,布拉德福德出版社,2017 年
  • D.Klein 和 p . abbe El:《cs 188 人工智能导论》,课程笔记,加州大学柏克莱分校,http://ai.berkeley.edu,2018(已下载)

收音机上的小盒子:现代流行音乐听起来都一样吗?

原文:https://towardsdatascience.com/little-boxes-on-the-radio-does-modern-pop-music-all-sound-just-the-same-69052c51b709?source=collection_archive---------15-----------------------

1965-2015 年公告牌热门 100 首歌曲分析

我对为我的下一个项目进行一些基本的音乐分析很感兴趣,所以我四处打探有希望的数据集。我最终选择了这个公告牌年终热门 100 首歌曲的数据阵列,它给出了 50 年间流行音乐的一个很好的快照(至少是在给定年份在电台播放的音乐)以及一个有前途的语言分析。虽然我最初只是打算探索这些数据(尤其是歌词),看看音乐是如何变化的,但我发现了一些证据,表明歌曲随着时间的推移变得越来越相似。

在检查了一些歌曲后,我发现并非所有的歌词都完全准确(或真实),所以我用 geniusR 从 genius.com 那里搜集歌词,并尽可能多地填补漏洞。此外,我利用了真正优秀的 spotifyR 包,从 Spotify 的海量数据库中获取了关于每首曲目的一些基本音乐参数(速度、音调等等)。

随着时间的推移,宋的情绪变得更加“消极”

对于抒情内容的分析,我选择通过 syuzhet 包使用逐行情感测量。我最初是一个词一个词地分析歌曲,但因为大多数词都是中性的,所以它没有像看一整行歌词(词与词的总和)那样有洞察力。从那以后,相对简单地考察作为年份函数的宋情绪:

虽然总体情绪仍然大于零,但随着时间的推移,情绪明显(几乎完全线性)下降(线性模型,p <0.0001). Digging a little deeper, I think we can attribute this decrease to multiple factors. First and foremost, curse words (from ‘ass’ and ‘damn’ on up) are all associated with negative sentiment, independent of their context (the sentence “he looked damn fine” is negative overall, even though contextually it could be interpreted as positive). It’s definitely an incredible understatement to say that hip hop has grown in popularity from 1965 to today ),所以我认为有理由将“负面情绪”的增加至少部分归因于热门 100 强中嘻哈和说唱歌曲数量的增加。此外,虽然,我想说的是,歌曲在其他流派中也多少有些消极/不太积极,与歌词的粗俗无关。例如,比较这四首几十年前的“积极”歌曲

对于这些更现代、总体上“消极”的歌曲(在这两种情况下,更积极的情绪→更红的文本和更消极的情绪→更蓝的文本):

我认为现在的乐观、快乐摇滚、流行和灵魂乐歌曲比过去少了(谢天谢地,这也意味着像“美味美味/我肚子里有爱”这样的歌词也少了)。如今,你也不太可能在流行电台上听到像凯特·斯蒂文斯这样的民谣诗人,或者像杰克逊五兄弟这样的放克/舞蹈/摩城乐队;这并不是说当前的音乐艺术家不再存在于这种类型的音乐中,这可能只是因为这种类型的音乐不再受欢迎/有利可图,以至于无法获得主流电台时间的很大一部分。

随着时间的推移,歌曲变得越来越罗嗦

进一步分析歌词,还有另一个明显的效果:现代歌曲比 20 世纪 60 年代的歌曲有更多的词。为了控制歌曲变得越来越长的事实(也许部分是由于技术的进步),我决定可视化这种效果的最好方法是每分钟字数(WPM)。

Words per minute (WPM) for each song. Red line represents the median WPM for each year. The most notable outlier from the oldies, ‘I Like it Like That’ by the Dave Clark Five (1965) squeezes nearly 300 words into a 90 second song (annotated at far left). Even so, it’s still in a completely different league from rap songs like Ice Cube’s ‘Bop Gun (One Nation)’ .

从 1990 年左右开始并持续到现在,WPM 值的增加是显而易见的。再说一次,考虑到嘻哈音乐流行的时间线,我并不觉得这有什么特别令人惊讶的(不管怎样,“冰冰宝贝”(1990 年)是第一首在公告牌排行榜上排名第一的说唱单曲。如图所示,数据集中 WPM 值最高的都是 hip hop 曲目,而且都是 1990 年以后发行的。将 WPM 可视化为十年长度的直方图(左)也清楚地表明了这一点:从 90 年代中期开始,一直持续到现在,很大一部分歌曲的 WPM 值远远高于前几十年观察到的 WPM 值。

此外,最近几十年来,进入 Billboard 100 的歌词稀疏的歌曲比例越来越小。与 1965-1995 年相比,当时大约 1/4 到 1/3 的歌曲每分钟不到 50 WPM,很少有 1995-2015 年的 Billboard 歌曲如此稀疏。如前图所示,WPM 值最低的三首歌都是在 1985 年之前发行的,基本上没有任何歌词(除了“灵魂手指”,它有不朽的歌词:“灵魂手指!灵魂手指!灵魂手指”被邻居小孩喊

速度随时间变化

从抒情内容和情感分析继续,我接下来深入研究了 Spotify 为每首歌曲计算的音乐特征的选择。首先,我检查了节奏,用每分钟节拍数(BPM)来衡量。

虽然我们肯定没有看到像抒情或 WPM 那样戏剧性的变化,但歌曲节奏随着时间的推移有一些变化。

用每十年的直方图可视化 BPM(左图)会使其中一些趋势更加清晰。最突出的是,现代歌曲中似乎有三组相对不同的节奏:~90 BPM、~ 120 BPM 和~170 BPM。这与 1995 年以前的歌曲有些不同,1995 年以前的歌曲在 120 BPM 左右形成了一个大的、相对连续的分布。其他研究表明,大多数嘻哈歌曲都在 90 BPM 左右,而 120-130 BPM 是最受欢迎的节奏。另一方面,150-200 BPM 的歌曲可能只是被 Spotify 的算法误认为实际 BPM 两倍的歌曲(阿黛尔的《你好》、埃利·古尔丁的《像你一样爱我》、Fall Out Boy 的《世纪》都被错误地识别为> 150 BPM)。因此,相对于老歌来说,现代流行歌曲可以更清楚地分为两个相对不同的群体(慢节奏和“理想”节奏)。

现代歌曲更加同质化(在某些方面)

最后,我看了看其他音乐特征,看看关于流行音乐的的【T2 常见的 抱怨 是否属实,歌曲现在真的彼此更相似了。我发现三个音乐特征似乎可以佐证这一理论:歌曲时长、音乐情绪和能量。

(Left) Billboard Hot 100 songs plotted by their duration (top), mean overall linguistic sentiment (middle), and overall energy (bottom). (Right) The standard deviations for each of these three measures has steadily decreased over time.

这三个指标中的每一个都显示出它们的方差随着时间的推移而显著下降,粗略地说,这意味着现代歌曲比过去更加相似(至少在持续时间、情感和能量方面)。这种相似性的增加也可以通过按十年创建歌曲的树状图来可视化,根据音乐特征进行聚类,并以 500 的距离进行切割。在这里,我们再次看到现代音乐比过去的歌曲有更大程度的相似性(树中的组更少)。

在某种程度上,这也很容易解释:随着时间的推移,音乐制作人已经知道什么样的歌曲最有可能流行,并将其资源用于制作尽可能多的这类歌曲。根据你的观点,这要么意味着音乐整体在走下坡路(不太可能),要么只是收音机现在没有以前有趣了(更有可能)。我当然很难想象像“管状钟”这样 20 多分钟的乐器怪物会再次成为今年 100 首最受欢迎的歌曲之一。这是否是一件好事是一个解释的问题。

CNN 活动地图的实时可视化(使用 Tensorflow.js)

原文:https://towardsdatascience.com/live-visualisations-of-cnns-activation-maps-using-tensorflow-js-27353cfffb43?source=collection_archive---------7-----------------------

CNN 中有哪些激活图?

简单地说,激活图是特定卷积层的输出。我们可以使用激活图来可视化 CNN。

(这里,卷积层被称为卷积层,后跟最大池。)

激活地图有帮助吗?

是的,它们对 CNN 的可视化很有用,我们也可以部分地回答这样的问题:“CNN 是如何做决策的?”,“CNN 学哪些东西?”

剩余博文分为以下主题。

  1. CNN 详情
  2. 将 Keras 模型转换为 Tensorflow.js 模型
  3. 运行推理并保存激活图
  4. 显示激活图

CNN 的细节

对于实时可视化,我们需要更小的 CNN,它甚至可以在 CPU 上实时输出预测。所以,任何卷积层数少的 CNN 都可以。作为机器学习课程的一部分,我训练了紧凑型 CNN (3 Conv。层+ 2 FC 层)用于使用面部图像的二元性别分类。CNN 在包含 40k 张面部图像的 IMDB-WIKI 面部数据集【1】的子集上接受训练。受过训练的 CNN 有 0.94 F1 分。

CNN 架构的更多细节可以在这里找到。

Activation Map of First Layer

Activation Map of Second Layer

Activation Map of Third Layer

将 Keras 模型转换为 Tensorflow.js 模型

CNN 在 Keras 中实现,保存为 Keras 模型。有一种简单的方法可以将 keras 模型转换为 Tensorflow.js 兼容模型。

转换模型的步骤如下。官方文件可以在这里找到。

# install dependency 
$ pip install tensorflowjs# Converting Model
$ tensorflowjs_converter --input_format keras \
                       path/to/my_model.h5 \
                       path/to/tfjs_target_dir

输出填充将如下所示:

$ ls tfjs_traget_dir
model.json
group1-shard1of1 
group2-shard1of1
...
...
group6-shard1of1

运行推理并保存激活图

现在,是时候用 CNN 模型预测性别了。为简单起见,我们假设我们的面部图像来自现场直播。

您可以查看完整代码,其中包含使用 tracking.js 提取面部图像,然后调整为固定大小(50x50)的实现。

# loading Model 
genderAI = await tf.loadModel('[https://immortal3.github.io/OnlineActivationMap/res/model/model.json'](https://immortal3.github.io/OnlineActivationMap/res/model/model.json'));

我们可以直接使用推论,但那样我们就只有最终结果了。我们希望在前进过程中保存激活图以便可视化。

# Final Prediction
const genderprediction = model.predict(face_image);

在前进过程中保存激活地图。

# list containing input for every layer
var input = []# First Layer;s Input is Facial Image
input.push(tf.tidy(() => { return tf.expandDims(facialImage,0).asType('float32').div(255.0)}));

# passing Input to every layer and saving output as input for next layer    
for (var i = 1; i <= 12; i++) {
   input.push(genderAI.layers[i].apply(input[i-1]));
}

# Saving activationmaps (note that we are displaying activation map after applying max pool)     
const firstconvactivationmap = input[2];
const secondconvactivationmap = input[4];
const thirdconvactivationmap = input[6];

显示激活地图

为了可视化,我们可以使用 ploty.js 中的热图。您可以查看包含实现的完整代码。

现场演示:https://immortal3.github.io/OnlineActivationMap/

完整代码:【https://github.com/immortal3/OnlineActivationMap /

关于我:【https://immortal3.github.io/about/】T4

(注意:对于 Mac 用户来说,tensorflow.js 存在一些问题,因此,它可能会工作,也可能不会工作。)

使用 Python 和天桥 API 从 OpenStreetMap 加载数据

原文:https://towardsdatascience.com/loading-data-from-openstreetmap-with-python-and-the-overpass-api-513882a27fd0?source=collection_archive---------1-----------------------

你有没有想过德国大部分 Biergarten 在哪里,或者瑞士隐藏着多少家银行? OpenStreetMap 是一个伟大的开源世界地图,它可以让我们对这些和类似的问题有所了解。隐藏了大量的数据,充满了有用的标签和地理信息,但是我们如何得到这些数据呢?

Biergarten in Germany, can you guess the big peak?

从 OpenStreetMap (OSM)下载地图数据有多种方式,如他们的 wiki 所示。当然,你可以下载整个 Planet.osm 文件,但是在本文发表时,你需要释放超过 800 GB 的空间,才能将整个数据集放在你的计算机上等待分析。如果你只需要处理某个区域,你可以使用各种格式的提取,比如原生[.OSM](https://wiki.openstreetmap.org/wiki/OSM_XML)(存储为 XML)、[.PBF](https://wiki.openstreetmap.org/wiki/PBF_Format)(T2 的压缩版本)、 ShapefileGeoJSON 。也可能有不同的 API,如本地 OSM API命名 API 。在本文中,我们将只关注override API,它允许我们从 OSM 数据集中查询特定的数据。

快速浏览一下 OSM 数据模型

在我们开始之前,我们必须看看 OSM 是如何构成的。在 OSM 数据模型中,我们有三个基本组件,分别是节点方式关系,它们都有一个 id。许多元素都带有标签,这些标签描述了被表示为键值对的特定特性。简单来说,节点是地图上的点(以纬度和经度表示),如下图所示,这是一张在伦敦的长凳的图片。

另一方面,方式是节点的有序列表,它可以对应于一条街道或一所房子的轮廓。这里有一个麦克索利在纽约的旧啤酒馆的例子,在 OSM 也可以找到。

最后一个数据元素是一个关系,它也是一个有序列表,包含节点、路径甚至其他关系。它用于建模对象之间的逻辑或地理关系。例如,这可用于大型结构,如凡尔赛宫中的包含多个多边形来描述建筑。

使用天桥 API

现在我们来看看如何从 OSM 加载数据。天桥 API 使用定制的查询语言来定义查询。这需要一些时间来适应,但幸运的是有 Martin Raiferover Turbo,它可以方便地直接在浏览器中交互评估我们的查询。假设您想要查询咖啡馆的节点,那么您的查询如下所示

node["amenity"="cafe"]({{bbox}}); out;

其中查询源代码中的每条语句都以分号结束。该查询首先指定我们想要查询的组件,在本例中是一个节点。我们在查询中应用了一个按标签过滤的方法,寻找所有键值对为"amenity"="cafe"的节点。在文档中可以找到不同的标签过滤选项。有各种各样的标签可供选择,一个常见的关键字是 amenity ,它涵盖了各种社区设施,如咖啡馆、餐厅或只是一张长椅。为了对 OSM 其他可能的标签有一个大概的了解,看看 OSM 地图功能taginfo

另一个过滤器是边界框过滤器,其中{{bbox}}对应于我们要在其中搜索的边界框,并且只在天桥 Turbo 中工作。否则,您可以通过经纬度中的(south, west, north, east)指定一个边界框,如下所示

node["amenity"="pub"]
  (53.2987342,-6.3870259,53.4105416,-6.1148829); 
out;

你可以试试天桥涡轮。正如我们之前在 OSM 数据模型中看到的,也有可能拥有相同属性的方法和关系。我们也可以通过使用一个 union block 语句来获得这些结果,该语句收集一对括号内的语句序列的所有输出,如

( node["amenity"="cafe"]({{bbox}});
  way["amenity"="cafe"]({{bbox}});
  relation["amenity"="cafe"]({{bbox}});
);
out;

下一种过滤查询的方法是通过元素 id 过滤。下面是查询node(1); out;的例子,它给出了经度接近于零的世界本初子午线。

另一种过滤查询的方法是按地区指定,可以像指定area["ISO3166-1"="GB"][admin_level=2];一样指定,这样我们就可以得到英国的地区。我们现在可以使用它作为查询的过滤器,方法是将(area)添加到我们的语句中,如

area["ISO3166-1"="GB"][admin_level=2];
node["place"="city"](area);
out;

该查询返回英国的所有城市。也可以使用关系或方式作为区域。在这种情况下,区域 id 需要通过将2400000000添加到其 OSM id 中,或者在有关系的情况下,通过添加3600000000从现有的 OSM 方式中导出。请注意,并不是所有的路/关系都有一个区域对应物(即那些标有area=no的路/关系,以及大多数没有定义name=*的多多边形将不属于区域)。如果我们将英国的关系应用到前面的例子中,我们就会得到

area(3600062149);
node["place"="city"](area);
out;

最后我们可以指定查询数据的输出,这由 out 动作配置。到目前为止,我们将输出指定为out;,但是还有各种可以追加的附加值。第一组值可以控制输出信息的详细程度或详细程度,如文档中描述的idsskelbody(默认值)、tagsmetacount

此外,我们可以添加地理编码信息的修改。geom为每个对象添加完整的几何图形。当返回没有关联坐标的关系或路径,并且您想要获得它们的节点和路径的坐标时,这很重要。例如,查询rel["ISO3166-1"="GB"][admin_level=2]; out geom;不会返回任何坐标。值bb仅将边界框添加到每个路径和关系,而center仅添加同一边界框的中心(不是几何图形的中心)。

排序顺序可通过ascqt进行配置,分别按对象 id 或四块索引排序,后者明显更快。最后,通过添加一个整数值,您可以设置要返回的最大元素数。

结合我们目前所学的知识,我们最终可以查询德国所有比尔加滕的位置

area["ISO3166-1"="DE"][admin_level=2];( node["amenity"="biergarten"](area);
  way["amenity"="biergarten"](area);
  rel["amenity"="biergarten"](area);
);
out center;

Python 和天桥 API

现在,我们应该已经很好地掌握了如何使用 transition API 查询 OSM 数据,但是我们现在如何使用这些数据呢?下载数据的一种方法是使用命令行工具 curlwget 。为了做到这一点,我们需要访问其中一个over API 端点,在这里我们将按照格式http://overpass-api.de/api/interpreter?data=query查看。当使用 curl 时,我们可以通过运行以下命令下载查询的 OSM XML

curl --globoff -o output.xml [http://overpass-api.de/api/interpreter?data=node(1);out;](http://overpass-api.de/api/interpreter?data=node(1);out;)

其中先前精心制作的查询出现在data=之后,并且该查询需要被 urlencoded 。为了使用方括号和花括号而不被 curl 解释,--globoff很重要。该查询返回以下 XML 结果

<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="Overpass API 0.7.54.13 ff15392f">
<note>The data included in this document is from www.openstreetmap.org. 
      The data is made available under ODbL.</note>
<meta osm_base="2018-02-24T21:09:02Z"/> <node id="1" lat="51.4779481" lon="-0.0014863">
    <tag k="historic" v="memorial"/>
    <tag k="memorial" v="stone"/>
    <tag k="name" v="Prime Meridian of the World"/>
  </node></osm>

文档中有多种输出格式可供选择。为了下载 JSON 格式的查询结果,我们需要在查询的开头添加[out:json];,如

curl --globoff - o output.json [http://overpass-api.de/api/interpreter?data=[out:json];node(1);out;](http://overpass-api.de/api/interpreter?data=[out:json];node(1);out;)

给我们之前的 JSON 格式的 XML 结果。您也可以通过访问http://overpass-api.de/api/interpreter?在浏览器中测试查询 data =[out:JSON];节点(1);出;

但是我已经承诺使用 Python 来获得结果查询。我们现在可以用 Python 运行我们众所周知的 Biergarten 查询,方法是使用 requests 包来访问天桥 API 和 json 包,以从查询中读取结果 json。

import requests
import jsonoverpass_url = "http://overpass-api.de/api/interpreter"
overpass_query = """
[out:json];
area["ISO3166-1"="DE"][admin_level=2];
(node["amenity"="biergarten"](area);
 way["amenity"="biergarten"](area);
 rel["amenity"="biergarten"](area);
);
out center;
"""
response = requests.get(overpass_url, 
                        params={'data': overpass_query})
data = response.json()

在这种情况下,我们不必为我们的查询使用 urlencoding,因为这由requests.get负责,现在我们可以存储数据或直接进一步使用数据。我们关心的数据存储在elements键下。那里的每个元素都包含一个type键和一个id键,前者指定它是节点、路还是关系。因为我们在查询中使用了out center;语句,所以我们为每条道路和关系获取了一个存储在center键下的中心坐标。在节点元素的情况下,坐标就在lat, lon键下面。

import numpy as np
import matplotlib.pyplot as plt# Collect coords into list
coords = []
for element in data['elements']:
  if element['type'] == 'node':
    lon = element['lon']
    lat = element['lat']
    coords.append((lon, lat))
  elif 'center' in element:
    lon = element['center']['lon']
    lat = element['center']['lat']
    coords.append((lon, lat))# Convert coordinates into numpy array
X = np.array(coords)plt.plot(X[:, 0], X[:, 1], 'o')
plt.title('Biergarten in Germany')
plt.xlabel('Longitude')
plt.ylabel('Latitude')
plt.axis('equal')
plt.show()

另一种用 Python 访问 over float API 的方法是使用 overpy 包作为包装器。在这里你可以看到我们如何用 overpy 包来翻译前面的例子

import overpyapi = overpy.Overpass()
r = api.query("""
area["ISO3166-1"="DE"][admin_level=2];
(node["amenity"="biergarten"](area);
 way["amenity"="biergarten"](area);
 rel["amenity"="biergarten"](area);
);
out center;
""")coords  = []
coords += [(float(node.lon), float(node.lat)) 
           for node in r.nodes]
coords += [(float(way.center_lon), float(way.center_lat)) 
           for way in r.ways]
coords += [(float(rel.center_lon), float(rel.center_lat)) 
           for rel in r.relations]

overpy 的一个优点是它从响应中检测内容类型(即 XML、JSON)。如需更多信息,请查看他们的文档。你可以将这些收集到的数据用于其他目的,或者像在 openstreetmap-heatmap 项目中一样,用 Blender 将其可视化。这就把我们带回了标题图片,正如你可能已经猜到的,它显示了德国比尔加藤的分布。

Image from openstreetmap-heatmap

结论

从获取特定区域内的建筑的需求开始,我发现在 OSM 有多少不同的东西可以发现,我迷失在地理空间兔子洞。看到 OSM 还有多少有趣的数据有待探索是令人兴奋的,甚至包括在 OSM 找到建筑物的 3D 数据的可能性。由于 OSM 是基于贡献的,你也可以探索 OSM 是如何随着时间的推移而增长的,以及有多少用户加入了本文中的文章,该文章使用 pyosmium 检索某些地区的 OSM 用户统计数据。我希望我启发了你,让你带着新装备的工具去 OSM 深处发现新奇和有趣的发现。

感谢阅读!如果你喜欢这篇文章,请继续展示你的爱,并关注我更多的文章。还有,在 LinkedIn 或者Twitter上随时联系我。

本文原载于janakiev.com

用于异常检测的局部异常因子

原文:https://towardsdatascience.com/local-outlier-factor-for-anomaly-detection-cc0c770d2ebe?source=collection_archive---------2-----------------------

关于局部异常因子的简短综述

局部异常值因子(LOF)是一个分数,表示某个数据点是异常值/异常值的可能性。

LOF ≈1 没有异常值

≫1 之外

首先,我引入一个参数 k ,它是 LOF 计算要考虑的邻居数量。LOF 是一种计算方法,通过查看某一点的相邻点来找出其密度,并在稍后将其与其他点的密度进行比较。使用正确的数字 k 并不简单。虽然小的 k 具有更局部的焦点,即仅查看附近的点,但是当数据中有很多噪声时,它更容易出错。然而,大的 k 可能会遗漏局部异常值。

The density of the red point to its nearest neighbors is not different from the density to the cloud in the upper right corner. However, it is probably an outlier compared to the nearest neighbors’ density.

k 距离

定义了这个 k 之后,我们可以引入 k-distance ,它是一个点到其邻居k的距离。如果 k 为 3,则 k 距离将是一个点到第三个最近点的距离。

The red point’s k-distance is illustrated by the red line if k=3.

可达性距离

k 距离现在用于计算可达性距离。这个距离度量就是两点之间的最大距离和第二点的 k 距离。

reach-dist(a,b) = max

基本上,如果点 a 在点 bk 邻域内, reach-dist(a,b) 将是 bk-distance 。否则就是 ab 的真实距离这只是一个“平滑因子”。为简单起见,将这视为两点之间的通常距离。

局部可达性密度

reach-dist 然后用于计算另一个概念——局部可达性密度(lrd)。为了获得点 a 的 lrd,我们将首先计算 a 到其所有 k 最近邻居的可达性距离,并取该数字的平均值。lrd 就是平均值的倒数。请记住,我们讨论的是密度,因此,到下一个邻居的距离越长,相应点所在的区域就越稀疏。因此,密度越低——反之亦然。

lrd(a) = 1/(总和(reach-dist(a,n))/k)

凭直觉,局部可达性密度告诉我们从我们的点到下一个点或点群要走多远。它越低,密度越小,我们要走的路就越长。

The lrd of the upper right point is the average reachability distance to its nearest neighbors which are points (-1, -1), (-1.5, -1.5) and (-1, -2). These neighbors, however, have other lrds as their nearest neighbors don’t include the upper right point.

力线

然后将每个点的 lrd 与它们的 k 邻居的 lrd 进行比较。更具体地说,将计算并平均每个点与其相邻点的 lrd 的 k 比率。LOF 基本上是 a 的邻居的 lrd 与 a 的 lrd 的平均比值。如果该比率大于 1 ,则点 a 的密度平均小于其相邻点的密度,因此,从点 a 开始,我们必须比从 a 的相邻点到其下一个相邻点行进更长的距离才能到达下一个点或点群。请记住,点 a 的邻居可能不认为 a 是邻居,因为他们的可及范围内有更近的点。

总之,一个点的 LOF 表示该点相对于其相邻点的密度。如果一个点的密度远小于其相邻点(≫1 附近)的密度,则该点远离密集区域,因此是异常值。

参考

布鲁尼格、M. M .、克里格尔、H. P .、Ng、R. T .、桑德、J. (2000 年 5 月)。LOF:识别基于密度的局部异常值。在 ACM sigmod 记录(第 29 卷,№2,第 93–104 页)。ACM。

用于相似项目搜索的位置敏感散列

原文:https://towardsdatascience.com/locality-sensitive-hashing-for-music-search-f2f1940ace23?source=collection_archive---------0-----------------------

一种识别近似最近邻的有效方法。

Source: Unsplash

动机

每个人都知道 Shazam ,这款应用可以让你在几秒钟内识别出任何一首歌曲。它识别歌曲的速度不仅让我惊讶,也让我想知道他们是如何用一个巨大的歌曲数据库(大约 1000 万)做到这一点的。我意识到这可以通过使用音频指纹和敏感灰化来实现(我很确定 Shazam 使用了一些先进的技术)。本文试图解释实现一个程序来执行音乐搜索(通常是类似的项目搜索)的步骤和概念。

音频指纹识别是从固定持续时间的音频流中识别独特特征的过程。可以为所有现有的歌曲识别这种独特的特征,并将其存储在数据库中。当我们听到一首新歌时,我们可以从录制的音频中提取相似的特征,并与数据库进行比较,以识别这首歌。然而,在实践中,这种方法将面临两个挑战:

  1. 识别歌曲所需的独特特征/特征向量的高维度
  2. 将记录的音频特征与数据库中所有歌曲的特征进行比较在时间和存储器方面是昂贵的

第一个挑战可以使用 PCA 等降维技术来解决,第二个挑战可以使用聚类和最近邻搜索的组合来解决。位置敏感哈希(以下简称 LSH)可以通过以下方式解决这两个问题

  1. 将高维特征减少到更小的维度,同时保持可区分性
  2. 以高概率将相似的对象(在这种情况下是歌曲)分组到相同的桶中

LSH 的应用

在开始了解 LSH 之前,值得注意的应用领域包括

  • 推荐系统
  • 近似重复检测(文档、在线新闻文章等。)
  • 分层聚类
  • 全基因组关联研究
  • 图像相似性识别(VisualRank)
  • 音频相似性识别
  • 数字视频指纹

优步利用 LSH 检测 平台滥用 (假账、支付欺诈等。).使用 LSH 可以构建一个 Shazam 风格的应用程序或 Youtube 大小的推荐系统。

什么是 LSH?

LSH 是一种基于哈希的算法,用于识别近似最近邻。在正常最近邻问题中,空间中有一堆点(我们称之为训练集)并且给定一个新点,目标是识别训练集中最接近给定点的点。这种过程的复杂性是线性的[对于那些熟悉 Big-O 符号的人来说,O(N),其中 N 是训练集的大小]。近似最近邻算法试图将这种复杂度降低到亚线性(小于线性,但是可以是任何值)。亚线性复杂度是通过减少查找相似项目所需的比较次数来实现的。

LSH 的工作原理是,如果特征空间中有两个彼此靠近的点,它们很可能具有相同的散列(数据的简化表示)。LSH 主要不同于传统的散列法(又名加密),因为加密散列法试图避免冲突,而 LSH 的目标是最大化相似点的冲突。在加密散列法中,对输入的微小扰动会显著改变散列,但是在 LSH 中,微小的失真会被忽略,从而可以容易地识别主要内容。哈希冲突使得相似的项目很有可能具有相同的哈希值。

位置敏感哈希(Locality Sensitive Hashing,LSH)是一种通用的哈希技术,顾名思义,它旨在保留数据的本地关系,同时显著降低数据集的维度。

既然我们已经建立了 LSH 是一个哈希函数,其目的是最大化相似项目的冲突,让我们正式定义:

如果对于高维特征空间中给定的两个点 a,b,1,则散列函数 h 是局部敏感的。如果 a 和 b 接近 2,Pr(h(a) == h(b))为高。如果 a 和 b 相差 3,Pr(h(a) == h(b))为低。识别接近物体的时间复杂度是亚线性的。

LSH 的实施

了解了什么是 LSH,是时候了解如何实现它了。实现 LSH 需要理解如何生成哈希值。构建 LSH 的一些流行方法有

在本文中,我将给出一个使用随机投影方法实现 LSH 的演练。好奇的读者可以从链接的 URL 中了解其他方法。

迂回随机投影法

随机投影是一种在低维特征空间中表示高维数据的技术(降维)。它因其在低维空间中近似保持关系(成对距离或余弦相似性)的能力而受到关注,同时计算成本较低。

随机投影背后的核心思想是,如果向量空间中的点具有足够高的维数,那么它们可以以近似保持点之间距离的方式被投影到合适的低维空间中。

以上陈述是对 约翰逊-林登施特劳斯引理 的解释。

考虑一个用矩阵 D 表示的高维数据,有n个观察值(矩阵的列)和d个特征(矩阵的行)。可以用随机投影矩阵 R 将其投影到 k 维的低维空间,其中k<<d。从数学上讲,较低维度的表示 P 可由下式获得

随机投影矩阵 R 的列被称为随机向量,这些随机向量的元素独立于高斯分布(零均值,单位方差)提取。

使用随机投影方法的 LSH

在这个 LSH 实现中,我们构建了一个所有可能箱的表,其中每个箱由相似的项目组成。每个 bin 将由一个按位哈希值表示,该哈希值是由一系列 1 和 0 组成的数字(例如:110110,111001)。在这种表示中,具有相同按位哈希值的两个观察值比具有不同哈希值的观察值更可能相似。生成按位哈希表的基本算法是

Dot product of random vector and observation 1 > 0, which gives a bit value of 1. Similarly, dot product of random vector and observation 2 < 0 and the resulting bit value will be 0.

  1. 创建长度为dk个随机向量,其中k是按位散列值的大小,d是特征向量的维数。
  2. 对于每个随机向量,计算随机向量和观察值的点积。如果点积的结果为正,则将位值指定为 1,否则为 0
  3. 连接为k点积计算的所有位值
  4. 对所有观察重复上述两个步骤,以计算所有观察的哈希值
  5. 将具有相同哈希值的观察值分组在一起以创建 LSH 表

下面是构建这种哈希表的代码片段:

考虑以下示例,其中我们的目标是通过为三个 5 维输入向量创建 2 位哈希值来找到相似的向量。

随机投影向量可以从高斯分布(零均值和单位方差)生成。

使用投影矩阵进行点积,并计算三个向量的哈希值,如下图所示。

我们可以从上面的例子中推断出,与 vec1 和 vec3 或者 vec2 和 vec3 相比,vec1 和 vec2 更有可能是相似的(相同的哈希值)。我们可以观察到,与其他两种组合相比,vec1 和 vec2 的余弦相似性最大,这证实了随机投影方法的输出。

这种想法背后的直觉是,如果两个点完全对齐,即,从原点具有完美的相关性,则它们将在相同的散列容器中。类似地,相隔 180 度的两个点将在不同的仓中,而相隔 90 度的两个点有 50%的概率在相同的仓中。

此外,由于随机性,不可能将所有相似的项目正确分组。为了克服这个限制,通常的做法是创建多个散列表,并且如果它们在至少一个表中的同一个 bin 中,则认为观察值a类似于b。还值得注意的是,多个表更好地概括了高维空间,并分摊了不良随机向量的贡献。

在实践中,哈希表的数量和哈希值(k)的大小被调整以调整召回率和精确度之间的折衷。

下面是构建多个哈希表的代码片段:

回到音乐识别

回到音乐识别的问题,一般的算法是:

  1. 为数据库中的所有歌曲构建特征向量
  2. 使用上面定义的类构造 LSH 哈希表,并适当选择表的数量和哈希大小。
  3. 对于新录制的音频,构建特征向量并查询 LSH 表
  4. 将录制音频的特征向量与步骤 3 中返回的匹配进行比较。根据特征向量的元素,用于比较的度量可以是 L2 距离、余弦相似性或雅克卡相似性。
  5. 返回具有最低/最高指标值(取决于所选指标)的结果作为匹配项

在步骤 4 中,对数据子集(比整个数据库小得多)执行相似歌曲标识的比较。这是快速计算的主要原因。此外,没有一个哈希表存储高维特征向量,节省了大量内存。最后,可以修改步骤 5,使其成为一个推荐系统。

这种音乐搜索算法的实现可以在这里找到。

结论

我希望您已经了解了什么是 LSH,以及它是如何实现内存效率和计算量的。

你能抽出时间来读这篇文章真是太棒了!如果你觉得这有帮助,请考虑分享。

关于我

我最近从旧金山大学的数据科学硕士项目毕业,正在寻找机器学习方面的职业机会。你可以访问我的 网站 或者 LinkedIn 了解更多关于我的背景和我做过的项目。

附加参考流程

逻辑理论—基本符号

原文:https://towardsdatascience.com/logic-theory-basic-notation-d8cf44cb297b?source=collection_archive---------15-----------------------

第二部分——简要介绍连接词、蕴涵和量词

逻辑理论的起源始于一个论证的概念。大多数逻辑教科书都包含一个开放的、核心的论点定义,听起来很像下面这样:

一个论点包含一个或多个特殊的陈述,称为 前提 ,作为一个理由来相信一个进一步的陈述,称为结论,是真实的

前提是逻辑理论的原子:一切都是由它们构成的。前提是一个声明性的陈述,即必须严格地评估为真或假。单个前提被称为原始前提美国有 50 个州(这是正确的)。将多个前提连接在一起形成一个复合前提美国有 50 个州迈阿密今天下雪了(这是假的)。如何连接多个语句?就像你在前面的例子中看到的,使用你已经熟悉的操作符,但是需要它们自己的语言语法。

连接词

类似于数学的其他分支,前提有它们自己的一套基本运算符(加、减等)。在逻辑理论中,五个基本逻辑连接词,统称为 连接词 ,填补了这个角色。它们总结在下表中,假设字母 P & Q 代表两个原始前提:

如果您接触过任何级别的编程,那么很有可能对上表有所了解。这是因为连接词是普通语言语法的核心&几乎总是为每个连接词指定一些特殊字符(&& = and,| = or,等等……)。

五个连接词中的哪一个用作两个前提之间的逻辑连接符,根据被修改的前提的真值来确定复合陈述的总真值。这里有一个重要的原则,乍一看似乎有悖常理,但值得一提:当分析复合语句时,没有必要知道 P & Q 实际上说了什么,只需要知道这些部分是真还是假。

含义

在这五个连接词中,有一个立即值得进一步研究——蕴涵,也就是 if-then 语句。蕴涵是 P → Q 的标准形式的连接词,其中 P 被称为假设(或前因),Q 被称为结论(或后果)。

虽然隐含具有上面定义的标准形式,但是还有其他三种常见的条件类型值得回顾。以下四个条件句简单却很常见&通过将条件句与所介绍的核心连接词结合起来,形成了强大的复合陈述:

条件本身是一个复合前提,也就是说,它严格地评估为真或假。对于任何蕴涵,就像任何其他连接词一样,复合前提的真值由其两个独立前提的真值决定。与上面介绍的定义相对应,例如,当假设为假时,蕴涵为,当结论为真时,蕴涵为;这就只剩下一种方式让一个蕴涵为假:当假设为真时,结论为假。

如果这看起来像是要在精神上跟踪很多东西,就像我一样,那么请放松&请放心,在不久的将来,强大的工具会让分析复杂的条件像遵循蓝图一样简单。我们将使用的主要工具是一个漂亮的逻辑 101 工具,名为 真值表 。然而,在我们进入真值表之前,让我们快速绕道,填补我们基本逻辑理论符号知识的最后一个缺口。检查一个特殊的场景——以下陈述是前提吗?

x 大于十

量词

根据我们在开篇段落中引入的严格定义,前提必须评估为真或假——语句不能是不明确的或开放式的。这意味着变量,就像我们从代数开始就习惯看到的那样,在逻辑理论中是一个禁忌;至少没有一些修改。

上面加粗的语句是而不是被认为是一个前提,因为 x 可能是 5 或 25,使得语句为真或为假,但目前都不是。然而,这并不意味着我们必须从我们的工具集中删除变量。这里的利用变量的一种方式;这个过程叫做 量化 ,这是一种在逻辑中标注未知变量界限的巧妙方法。看看下面的更新语句,这是前提吗?

为所有 x,x 大于一百

现在我们已经定义了变量的宇宙o r 域,这个陈述不再含糊不清——它现在是一个前提,因为它评估为绝对假。这种“for all x”的用法在逻辑理论中被称为应用一个 量词。 量词主要有两种。第一个,我们刚刚看到的,被恰当地命名为 全称量词。 由一个倒过来的“a”所口述,∀很容易记住它代表一个 ll 或宇宙内每一个可能的实例所作的陈述。检查第二处改动:

存在一个大于一百的 x

再一次,在不移除变量的情况下,我们找到了一种方法,通过应用一个量词,将一个陈述转换成一个前提,因为这个陈述现在严格地评估为。这第二类量词被称为 存在量词 。由一个反过来的“e”表示,∃,它通常读作“存在”或“有”这两个量词总结如下:

在真值表上

现在,基本符号已经过时了,是时候通过真值表跳到基本的应用形式了。在下一部分,我们将首先从定义逻辑中的等价开始;为了使用真值表来分析我们介绍的四个条件中的哪一个(如果有的话)是彼此相等的。在检查了几个示例语句后,我们将最终进入逻辑理论的核心:证明。

来源

逻辑:形式推理的理论
数学的基础

数据的逻辑单元

原文:https://towardsdatascience.com/logical-units-for-data-36778b4c9433?source=collection_archive---------6-----------------------

我在试图用现有数据库进行数据分析或机器学习的客户身上看到的一个谬误是,单个数据库中的单个文档代表了发送到数据分析或机器学习软件的唯一逻辑数据单元。换句话说,对于每个文档,CSV 中应该有一行,或者 JSON 中应该有一个数据结构。

这假设目标软件将把关系放在一起,或者分割聚集的数据,但是这两者都不容易或者特别有用。相反,当我们从现有数据库创建数据集时,我们应该深入研究对任务有意义的逻辑单元。

在某些情况下,单个文档代表多组数据。一个简单的例子可能是发票,其中每个行项目可能代表一组单独的数据。如果有三个行项目,数据集中应该有三行。发票中的公共数据(如日期和发票号)将被复制到每一行中。

在其他情况下,一组文档一起代表一组数据。我们不应该期望目标软件将来自两个数据库的数据放在一起,也不应该期望数据分析师找到一种方法来聚合它们,而是应该将各个部分放在一行中。一个例子可能是产品数据库和定价数据库,其中产品和价格应该放在一起。虽然在系统中将它们分开可能有很好的理由,但是如果将它们分开,数据分析可能会复杂得多。

当然,这引出了更复杂关系的概念。我们谈到的发票可能只有一个项目编号,因此我们希望从产品和定价数据库中提取产品和标准价格,以便与发票的每一行相匹配。数据分析师可以使用它来确定平均折扣百分比,甚至该百分比在一段时间内或旺季的趋势。

虽然这些都是数据分析的好例子,但同样的概念也适用于机器学习。通常,机器学习系统会使用自然语言处理。数据集通常更像一个故事,而不是一行。但是,当我们整理叙述时,我们可能希望从我们的产品数据库中提取数据,从反馈数据库中提取关于产品的评论,以及在讨论数据库中提及产品的讨论。

太多时候,机器学习被视为倾倒大量数据,并期待机器“弄清楚”。但是这既不现实也没有效率。机器学习是人类创造力和软件处理能力之间的一种合作形式。正如我在我之前的文章中提到的,我们必须是老师,只有当我们给人工智能系统提供高质量的信息时,我们才能从它们那里获得高质量的洞察力。

在创建下一个数据集之前,考虑一下数据是否已经处于适合特定种类分析所需的逻辑单元中。如果不是,那就把信息分解或汇总起来,这样可以节省时间和金钱,并获得更好的结果。这项任务越往后推进,难度越大,效果越差。

如果你喜欢这篇文章,请在下面给它一些爱,或者分享给别人。

顺便说一下,如果您的公司部分或全部使用 Notes/Domino 数据库,Genii 软件可以帮助您快速轻松地创建这样的拆分或组合数据集。观看我们的视频五个问题——Midas LSX 的数据挖掘,观看简短演示。

登录光泽&梦想仪表板

原文:https://towardsdatascience.com/login-luster-dreaming-of-dashboards-9200aa7d9e18?source=collection_archive---------8-----------------------

我真的相信仪表盘是你在任何应用上看到的最重要的页面,不管应用的性质如何。当然,也有我们不同意的例子,比如“给我<专题>页面,这就是我所需要的,不要浪费我的时间!”对此,我认为这些特定的应用程序和服务没有以一种为用户提供价值的方式利用仪表板页面。

多年来,dashboard(登录后通常看到的第一个页面)旨在通过将链接放在一个漂亮的页面上来帮助您导航应用程序,以便轻松快速地找到您的路。其他服务,如亚马逊,利用第一个登录屏幕,通过提出建议和提醒你重新订购经常购买的商品,让你购买更多产品。像 TumblrPinterest 这样的应用程序设计了他们的登录屏幕来展示最近的内容以吸引用户。

因此,为了各公司的目标,我将把重点放在追踪信息对用户有用的应用上。我知道公司需要设计他们的页面,以最好地服务于他们的高层次目标,例如增加日常活跃用户活动,但对于大部分应用程序来说,设计一个仪表板页面的意图是通知用户是非常宝贵的。

一个有用的仪表板设计的主要例子是以收入为中心的性能指标。例如,当你登录 Square 时,你会看到一个关于你最近业绩的简单概述,显示总销售额、过期发票、客户频率等等。这个页面不仅通知你,还提醒警告确认。提醒你客户未付的发票。看到低销售额可能会被认为是对你的警告,事情可能会变得更好(也许你的网站关闭了,你不知道)。该页面通过合计销售额的增长来确认您最近的努力是成功的。

另一个确凿的例子是 Fitbit 。无论您登录电脑还是打开移动设备上的应用程序,都会显示您最近的活动总数,包括步数、睡眠、饮食等。再一次,这种仪表板设计告知用户他们的成功和失败。

但是,如果我们进一步发展这个仪表板模型,并以一种我们可以为用户提供更多帮助的方式来设计它,会怎么样呢?最近,以健康为导向的科技公司已经在他们的应用程序中加入了可爱的小建议。例如, FitbitJawbone 会提出建议,帮助你获得更好的睡眠。但是想象一下,如果我们更进一步,使用用户的数据做出假设,而不仅仅是提出宽泛的建议,会怎么样?

将人工智能,更具体地说是机器学习,集成到软件中的可能性几乎是无限的,但前提是我们开始考虑未探索领域的场景。有了机器学习,我们可以设计能够真正自我设计的仪表板,只向用户显示最相关和最重要的(隐藏的)信息。

同意还是不同意?欢迎在下面评论或在推特上给我发消息。感谢阅读:)

逻辑回归

原文:https://towardsdatascience.com/logistic-regression-2b555e5f80e6?source=collection_archive---------1-----------------------

“方程中的美比让它们适合实验更重要……”—保罗·狄拉克

这也就是所谓的分类。这在很多情况下会用到,我们希望将输入分类到预定义的类中。为了前任。将电子邮件标记为垃圾邮件/非垃圾邮件,根据商业门户的数据预测客户的年龄组等。
线性回归 中,输出域是一个连续的值域,即它是一个无限集合,而在逻辑回归中,我们要预测的输出
只需要很少的离散值。即它是有限集。为简单起见,让我们考虑一个二元分类,其中 y 只能取两个值,1(正)和 0(负)。就像线性回归一样,我们需要从一个假设开始。由于输出域是有界的(0,1 ),因此产生超出此范围的值的假设没有意义。**

****

plot of f(x) for x belongs to (-10, 10)

给定上述一组逻辑回归模型(为什么设置?因为θ是可变的)我们需要找到最佳拟合模型的系数θ,其最好地解释了训练集。为此,我们需要从一组由θ参数化的概率假设开始,然后通过最大似然找到θ。
让我们从
伯努利分布开始,它是一个随机变量的概率分布,取值为 1 的概率为 p,取值为 0 的概率为 q= 1-p。

****

线性回归中我们* 通过将对数似然的导数等于零来求系数。我们像以前一样评估了可能性的导数,但是得到的 Ex(3)不是我们可以解决的数学上封闭的方程。(记住 x 和 theta 都是 eq 中的向量,h 是非线性函数)
我们仍然可以通过使用称为 梯度上升的强力算法来找到系数。 我们从某个系数开始,然后不断迭代更新θ,直到似然函数收敛。***

例子 让我们以维基百科例子
假设我们希望回答以下问题:

一个由 20 名学生组成的小组花 0 到 6 个小时准备考试。学习时间的长短如何影响学生通过考试的概率?

****

Plot of derived model for the range (0,6)

逻辑回归:使用 Python 的简化方法

原文:https://towardsdatascience.com/logistic-regression-a-simplified-approach-using-python-c4bc81a87c31?source=collection_archive---------3-----------------------

逻辑回归的目的是什么?

在逻辑回归中,我们希望用一个或多个自变量(X)来模拟因变量(Y)。是分类的方法。该算法用于分类的因变量。使用一个函数对 y 进行建模,该函数为 x 的所有值提供介于 0 和 1 之间的输出。在逻辑回归中,使用了 Sigmoid (也称为逻辑)函数。

The Sigmoid Function

使用混淆矩阵的模型评估

在我们对一些训练数据训练了逻辑回归模型之后,我们将评估模型对一些测试数据的性能。为此,我们使用混淆矩阵。混淆矩阵是一个表格,通常用于描述分类模型对一组真实值已知的测试数据的性能。下面给出了一个混淆矩阵。

在这里,TP 代表真正值,这是我们预测为是,而实际值为真的情况。TN 代表 True Negative,这是我们预测为 no 而实际值为 false 的情况。FP 代表假阳性,即我们预测为是而实际值为假的情况。FN 代表假阴性,即我们预测为否而实际值为真的情况。

我们从混淆矩阵中推断出什么?

混淆矩阵帮助我们确定模型预测正确的频率,或者换句话说,模型的准确性。根据上表,它由下式给出:

(TP + TN ) /总计= 100 + 50 / 165 = 0.91

这意味着该模型 91%是正确的。混淆矩阵也用于测量误差率,误差率由下式给出:

(FP + FN ) /总计= 15 /165 = 0.09

模型有 9%的误差。

在本文中,我们将处理 python 中建模逻辑回归的非常简单的步骤。

带详细解释的 Python 代码

我们将观察数据、分析数据、可视化数据、清理数据、构建逻辑回归模型、拆分成训练和测试数据、进行预测并最终对其进行评估。这些都会一步一步来。我们将要处理的数据是在 kaggle.com可用的‘泰坦尼克号数据集’。这是一个非常著名的数据集,通常是学生学习基于分类的机器学习的第一步。我们试图预测分类:生存或死亡

首先,我们将导入 numpy 和 pandas 库:

import numpy as np
import pandas as pd

让我们进行可视化导入:

import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

我们将继续把泰坦尼克号的数据集导入熊猫的数据框架。之后,我们将检查数据帧的头部,以便清楚地了解数据帧中的所有列。

train=pd.read_csv('titanic_train.csv')
train.head()

我们遇到的大多数数据都有缺失数据。我们将检查丢失的数据,也将它们可视化以获得更好的想法并删除它们。

train.isnull()

在这里,我们找到了布尔值。True 表示值为 null,False 表示值为 False,反之亦然。由于有大量的数据,我们使用 seaborn 库来可视化空值。那样的话,我们的任务就容易多了。

sns.heatmap(train.isnull())

年龄和客舱列具有空值。我在之前的博客中已经处理过 NA 值的处理问题。请看看它。

摆弄数据并充分利用可视化库来享受数据带来的乐趣总是一个好习惯。

sns.countplot(x='Survived',data=train)

这是一个计数图,显示了幸存的人数,这是我们的目标变量。此外,我们可以根据性别和乘客等级绘制计数图。

sns.countplot(x='Survived',hue='Sex',data=train)

在这里,我们看到一种趋势,即女性比男性存活的更多。

sns.countplot(x='Survived',hue='Pclass',data=train)

从上面的情节可以推断,属于 3 班的乘客死的最多。

我们可以用更多的方式来可视化数据。然而,我不在这里讨论它们,因为我们需要到达模型构建的步骤。

数据清理

我们希望填充缺失的年龄数据,而不是仅仅删除缺失的年龄数据行。一种方法是填写所有乘客的平均年龄(插补)。然而,我们可以更聪明地处理这个问题,按乘客级别检查平均年龄。例如:

plt.figure(figsize=(12, 7))
sns.boxplot(x='Pclass',y='Age',data=train,palette='winter')

我们可以看到,在较高的阶层中,较富裕的乘客往往年龄较大,这是有道理的。我们将根据年龄的 Pclass 使用这些平均年龄值进行估算。

def impute_age(cols):
    Age = cols[0]
    Pclass = cols[1]

    if pd.isnull(Age):if Pclass == 1:
            return 37elif Pclass == 2:
            return 29else:
            return 24else:
        return Age

现在应用那个函数!

train['Age'] = train[['Age','Pclass']].apply(impute_age,axis=1)

现在让我们再检查一下热图。

sns.heatmap(train.isnull(),yticklabels=False,cbar=False)

太好了!让我们继续下去,并放弃机舱柱。

train.drop('Cabin',axis=1,inplace=True)

转换分类特征

我们需要使用 pandas 将分类特征转换为虚拟变量!否则,我们的机器学习算法将无法直接将这些特征作为输入。

train.info()

sex = pd.get_dummies(train['Sex'],drop_first=True)
embark = pd.get_dummies(train['Embarked'],drop_first=True)

在这里,我们正在模拟性别和登上专栏。在虚拟化之后,我们将删除剩余的不需要的列。

train.drop(['Sex','Embarked','Name','Ticket'],axis=1,inplace=True)

我们将把新的 sex 和 apolloed 列连接到 dataframe。

train = pd.concat([train,sex,embark],axis=1)

现在,数据帧看起来像这样:

测试列车分离

from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(train.drop('Survived',axis=1), 
                                                    train['Survived'], test_size=0.30, 
                                                    random_state=101)

训练和预测

from sklearn.linear_model import LogisticRegression
logmodel = LogisticRegression()
logmodel.fit(X_train,y_train)
predictions = logmodel.predict(X_test)

估价

我们可以使用分类报告来检查精确度、召回率、f1 分数

from sklearn.metrics import classification_report
print(classification_report(y_test,predictions))

The Classification Report

关于逻辑回归的所有内容都在一篇文章中

原文:https://towardsdatascience.com/logistic-regression-b0af09cdb8ad?source=collection_archive---------4-----------------------

每个伟大的领袖背后都有一个更伟大的后勤专家。

与其他算法不同,逻辑回归很容易被年轻的开发人员误导。可能是因为人们还认为它是一个回归机器学习算法。

逻辑回归是一种统计机器学习算法,它通过考虑极端情况下的结果变量来对数据进行分类,并尝试制作一条对数线来区分它们。

像我五岁一样解释

逻辑回归是线性回归的兄弟,但与其名称不同,逻辑回归是一种分类算法。

让我们复习一下第一个线性回归:

公式:

在哪里,

  • y =必须预测的值
  • m =直线的斜率
  • x =输入数据
  • c = y 截距

有了这些值,我们可以预测 y 值,例如。

  • 这里的蓝点是 x 值(输入数据)。
  • 现在使用输入数据,我们可以计算斜率和 y 坐标,这样我们的预测线(红线)应该覆盖大部分的点。
  • 现在使用这条线,我们可以预测给定 x 值的 y 的任何值。

现在,线性回归需要注意的一点是,它适用于连续数据,但如果我们的分类算法需要线性回归,我们需要进一步调整我们的算法。

首先,我们需要定义一个阈值,如果我们的预测值低于阈值,那么它属于第 1 类,否则属于第 2 类。

现在,如果你在想“哦,这很简单,我们必须用阈值和 vola 来定义线性回归,它变成了分类算法,这里面有一个技巧。我们必须自己定义阈值,对于大型数据集,我们将无法计算阈值。此外,一旦定义了阈值,即使我们的预测值发生变化,阈值也是相同的。

更多参考请点击这里

另一方面,逻辑回归产生逻辑曲线,该曲线的值限于 0 和 1 之间。

逻辑回归类似于线性回归,但曲线是使用目标变量“几率”的自然对数而不是概率构建的。此外,预测值不必呈正态分布或在每组中具有相等的方差。

如果你还是不明白,那么我推荐你看下面的视频,它用简单的方式解释了逻辑回归。

公式

为了解释逻辑回归,我需要一些物理媒介来表达我在这个数字媒介中的知识。

所以我在笔记本上写了逻辑回归公式,然后拍了照片贴在这里。

如果你想要 pdf 版本,点击这里

page 1 of 7

page 2 of 7

page 3 of 7

page 4 of 7

page 5 of 7

page 6 of 7

page 7 of 7

用 python 实现

  • 用 python 从头开始实现逻辑回归算法,并在每个步骤中进行解释,上传到我的 Github 库。
  • 在 Scikit learn 的帮助下实现逻辑回归也被添加到我的 Github 存储库中。****

** [## 2796 gaur av/逻辑回归-已解释

简单而详细的解释逻辑回归用于机器学习问题。…

github.com](https://github.com/2796gaurav/Logistic-regression-explained)**

优势

  • 最简单的机器学习算法之一,但效率极高。
  • 方差很低。
  • 它也可以用于特征提取
  • 使用随机梯度下降,逻辑模型可以很容易地用新数据更新。

不足之处

  • 不能很好地处理大量的分类变量。
  • 它需要非线性特征的变换。
  • 它们不够灵活,无法自然地捕捉更复杂的关系。

应用程序

  • 图像分割和分类
  • 地理图像处理
  • 手写识别
  • 垃圾邮件检测

何时使用

  • 当我们需要调整比值比时,我们知道一个以上的风险因素。
  • 当卡方检验不显著时。

此外,我将添加其他机器学习算法。这篇文章的主旨是深入了解逻辑回归,不使用任何硬词,从头开始解释。此外,如果您想实现逻辑回归,从这些数据集开始,您可以在注释部分用代码注释您的预测得分。

如果你想学习更多的机器学习算法,请跟随我,因为我将添加我所知道的所有机器学习算法。

先前我已经以一种非常基本的信息方式添加了朴素贝叶斯解释。

** [## 关于朴素贝叶斯的一切

一个简单而深入的学习经验,在例子的帮助下从零开始学习一个机器学习算法。

towardsdatascience.com](/all-about-naive-bayes-8e13cef044cf)

在那之前,

快乐编码:)

别忘了拍手拍手拍手…

**

人口普查收入数据的逻辑回归分类器

原文:https://towardsdatascience.com/logistic-regression-classifier-on-census-income-data-e1dbef0b5738?source=collection_archive---------5-----------------------

在这篇博客中,我们将分析来自 UCI 机器学习知识库的人口普查数据集

数据集包含三个文件:

我们将使用逻辑回归来构建分类器。如果你不知道逻辑回归,你可以看看我之前的博客。

我们将看到如何建立一个实用的机器学习项目。一般来说,任何机器学习项目都需要以下步骤:

  • 定义问题陈述
  • 探索性数据分析
  • 训练模型
  • 微调模型
  • 保存模型

所以让我们开始吧。

定义问题陈述

数据包含匿名信息,如年龄、职业、教育、工人阶级等。目标是训练一个二元分类器来预测收入,它有两个可能的值'> 50K '和'< 50K '。数据集中有 48842 个实例和 14 个属性。数据很好地融合了分类值、数值值和缺失值。

首先,我们将导入所需的库

import numpy as np
import pandas as pd
import io
import requests
import seaborn as sns
from matplotlib import pyplot as plt
import pickle
import os
from pandas.api.types import CategoricalDtypefrom sklearn.base import BaseEstimator, TransformerMixin
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import FeatureUnion
from sklearn.model_selection import cross_val_score%matplotlib inline

下载数据

我们将编写一个小脚本来下载 URL 列表的内容,并将它们保存在一个文件夹中,而不是手动下载数据集。以后我们可以直接使用下载的数据,而不是每次都打网络。您也可以将此代码用于任何机器学习项目。

def load_dataset(path, urls):
    if not os.path.exists(path):
        os.mkdir(path)

    for url in urls:
        data = requests.get(url).content
        filename = os.path.join(path, os.path.basename(url))
        with open(filename, "wb") as file:
            file.write(data)

我们将在当前工作目录中创建一个data文件夹,并存储 URL 的内容。

urls = ["http://archive.ics.uci.edu/ml/machine-learning-  databases/adult/adult.data",
        "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.names",
        "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.test"]load_dataset('data', urls)

接下来,我们使用read_csv函数将数据加载到一个pandas数据帧中。

columns = ["age", "workClass", "fnlwgt", "education", "education-
           num","marital-status", "occupation", "relationship",
          "race", "sex", "capital-gain", "capital-loss", "hours-per-
           week", "native-country", "income"]train_data = pd.read_csv('data/adult.data', names=columns, 
             sep=' *, *', na_values='?')
test_data  = pd.read_csv('data/adult.test', names=columns, 
             sep=' *, *', skiprows=1, na_values='?')

数据值前后有一些空格。为了修剪所有的空白,我们使用分隔符‘ *, *’。测试数据集有一个奇怪的第一行,因此我们使用skiprows=1跳过这一行。数据集中缺失的值用?表示

接下来,我们将探索数据。这是构建模型之前的重要一步。

探索性数据分析

让我们使用train_data.info()获得更多关于训练数据的信息

RangeIndex: 32561 entries, 0 to 32560 
Data columns (total 15 columns): 
age               32561 non-null int64 
workClass         30725 non-null object 
fnlwgt            32561 non-null int64 
education         32561 non-null object 
education-num     32561 non-null int64 
marital-status    32561 non-null object 
occupation        30718 non-null object 
relationship      32561 non-null object 
race              32561 non-null object 
sex               32561 non-null object 
capital-gain      32561 non-null int64 
capital-loss      32561 non-null int64 
hours-per-week    32561 non-null int64 
native-country    31978 non-null object 
income            32561 non-null object

观察结果

  • 训练数据集中有 32561 个样本
  • 数据集中既有分类列也有数值列
  • 工作类别职业本国有缺失值

类似地,对于测试数据集

  • 16281 个样品
  • 没有没有丢失的值

让我们借助一些可视化工具来看看数字和分类数据。

处理数值列

我们使用select_dtypes函数选择数字列。

num_attributes = train_data.select_dtypes(include=['int'])
print(num_attributes.columns)['age', 'fnlwgt', 'education-num', 'capital-gain', 'capital-loss',        'hours-per-week']

变量年龄每周工作时间不言自明。

  • fnlwgt :取样重量
  • education-num :受教育的总年限
  • 资本收益/资本损失:工资以外的投资收入

fnlwgt 与目标变量收入无关,在建立模型之前将被移除

数据可视化

num_attributes.hist(figsize=(10,10))

使用train_data.describe()可以收集更多关于数据的信息

观察结果

  • 数字属性都没有缺失值
  • 这些值在不同的范围内。许多机器学习模型要求值在相同的范围内。我们将使用 sklearn 库中的 StandardScaler 来缩放特性。

处理分类列

cat_attributes = train_data.select_dtypes(include=['object'])
print(cat_attributes.columns)['workClass', 'education', 'marital-status', 'occupation',        'relationship', 'race', 'sex', 'native-country', 'income']

数据可视化

我们将使用 seaborn 包中的countplot

sns.countplot(y='workClass', hue='income', data = cat_attributes)

sns.countplot(y='occupation', hue='income', data = cat_attributes)

观察结果

  • education 只是列 education-num 的字符串表示。我们将删除教育栏目。
  • 变量工作类别职业母国有缺失值。我们将用该列中出现频率最高的值替换每列中缺失的值。

我们需要不同地处理数字和分类属性。数字属性需要缩放,而对于分类列,我们需要填充缺失的值,然后将分类值编码成数字值。为了应用这些转换序列,我们将使用 sklearn 的管道类。我们还将构建可直接用于管道的定制变压器。

创建管道

sklearn 内置了很多变形金刚。然而,如果内置的转换器不能为您完成工作,您可以构建一个定制的转换器。你需要做的就是继承 BaseEstimatorTransformerMixin 类。您还需要实现 fittransform 方法。

  • fit: 应该返回 self 的一个实例
  • 转换:转换逻辑可在此添加

列选择器管道

sklearn 没有提供库来直接操作 pandas 数据帧。我们将编写自己的自定义转换器,它将选择相应的属性(数字或分类)

class ColumnsSelector(BaseEstimator, TransformerMixin):

  def __init__(self, type):
    self.type = type

  def fit(self, X, y=None):
    return self

  def transform(self,X):
    return X.select_dtypes(include=[self.type])

数字数据管道

我们使用上面定义的列选择器转换器选择数字属性,然后使用标准缩放器缩放数值。

num_pipeline = Pipeline(steps=[
    ("num_attr_selector", ColumnsSelector(type='int')),
    ("scaler", StandardScaler())
])

如果我们调用num_pipelinefittransform方法,它会在内部调用管道中定义的所有转换器的fittransform方法。在这种情况下,列选择器和标准缩放器转换器。

分类数据管道

我们需要替换分类列中缺失的值。我们将用每列中出现频率最高的值替换缺失的值。sklearn 带有估算器来处理缺失值。然而,输入器仅适用于数值。我们将编写一个定制的转换器,它将接受我们需要替换缺失值的列的列表,以及用于填充缺失值的策略

class CategoricalImputer(BaseEstimator, TransformerMixin):

  def __init__(self, columns = None, strategy='most_frequent'):
    self.columns = columns
    self.strategy = strategy

  def fit(self,X, y=None):
    if self.columns is None:
      self.columns = X.columns

    if self.strategy is 'most_frequent':
      self.fill = {column: X[column].value_counts().index[0] for 
        column in self.columns}
    else:
      self.fill ={column: '0' for column in self.columns}

    return self

  def transform(self,X):
    X_copy = X.copy()
    for column in self.columns:
      X_copy[column] = X_copy[column].fillna(self.fill[column])
    return X_copy

所有的机器学习模型都需要数值。我们将使用 pd.get_dummies 将分类值转换成数值。这类似于使用 OneHotEncoder ,只是 OneHotEncoder 需要数字列。

我们需要在使用 pd.get_dummies 之前合并训练和测试数据集,因为测试数据集中可能存在训练数据集中不存在的类。为此,在fit方法中,我们将连接训练和测试数据集,并找出一列的所有可能值。在transform方法中,我们将把每一列转换成分类类型,并指定该列可以接受的类别列表。get_dummies 将为该列的类别列表中不存在的类别创建一个全零的列。

转换器还接受一个参数dropFirst,它指示我们是否应该在使用 pd.get_dummies 创建虚拟列之后删除第一列。我们应该删除第一列以避免多重共线性。默认情况下,该值设置为True

class CategoricalEncoder(BaseEstimator, TransformerMixin):

  def __init__(self, dropFirst=True):
    self.categories=dict()
    self.dropFirst=dropFirst

  def fit(self, X, y=None):
    join_df = pd.concat([train_data, test_data])
    join_df = join_df.select_dtypes(include=['object'])
    for column in join_df.columns:
      self.categories[column] = 
          join_df[column].value_counts().index.tolist()
    return self

  def transform(self, X):
    X_copy = X.copy()
    X_copy = X_copy.select_dtypes(include=['object'])
    for column in X_copy.columns:
      X_copy[column] = X_copy[column].astype({column:
                CategoricalDtype(self.categories[column])})
    return pd.get_dummies(X_copy, drop_first=self.dropFirst)

完整的分类管道

cat_pipeline = Pipeline(steps=[
    ("cat_attr_selector", ColumnsSelector(type='object')),
    ("cat_imputer", CategoricalImputer(columns=
          ['workClass','occupation', 'native-country'])),
    ("encoder", CategoricalEncoder(dropFirst=True))
])

完成管道

我们有两条变压器管道,即 num_pipelinecat_pipeline 。我们可以使用功能联合来合并它们

full_pipeline = FeatureUnion([("num_pipe", num_pipeline), 
                ("cat_pipeline", cat_pipeline)])

现在我们有了构建模型的所有管道,让我们为模型准备数据并构建它。

我们将删除不需要的列

train_data.drop(['fnlwgt', 'education'], axis=1, inplace=True)
test_data.drop(['fnlwgt', 'education'], axis=1, inplace=True)

训练模型

我们将创建训练数据集的副本,并分离特征向量和目标值。

train_copy = train_data.copy()
train_copy["income"] = train_copy["income"].apply(lambda x:0 if 
                        x=='<=50K' else 1)X_train = train_copy.drop('income', axis =1)
Y_train = train_copy['income']

接下来,我们将X_train传递给我们构建的full_pipeline

X_train_processed=full_pipeline.fit_transform(X_train)model = LogisticRegression(random_state=0)
model.fit(X_train_processed, Y_train)

测试模型

test_copy = test_data.copy()
test_copy["income"] = test_copy["income"].apply(lambda x:0 if 
                      x=='<=50K.' else 1)X_test = test_copy.drop('income', axis =1)
Y_test = test_copy['income']

我们将应用于训练数据集的相同变换应用于测试数据集。

X_test_processed = full_pipeline.fit_transform(X_test)predicted_classes = model.predict(X_test_processed)

模型评估

我们将使用来自 sklearn 的 accuracy_score 来确定模型的准确性

accuracy_score(predicted_classes, Y_test.values)

准确率为 85.2%

让我们画出混淆矩阵

cfm = confusion_matrix(predicted_classes, Y_test.values)
sns.heatmap(cfm, annot=True)
plt.xlabel('Predicted classes')
plt.ylabel('Actual classes')

X 轴代表预测类,Y 轴代表实际类。我们如何解读混淆矩阵?1.2e+04当实际类别为 0 时,模型正确预测类别为 0 的次数。同样,对于其余的情况也可以得出结论。

交叉验证

我们将使用stratified fold将我们的数据集分成 k 个文件夹。在每次迭代中,k-1个折叠被用作训练集,剩余的折叠被用作验证。我们使用 StratifiedKFold,因为它保留了每个类中样本的百分比。

如果我们使用 KFold ,我们可能会面临引入采样偏差的风险,即训练集可能包含大量收入大于 50K 的样本,而测试集包含更多收入小于 50K 的样本。在这种情况下,从训练数据构建的模型将不能很好地适用于测试数据集。而 StratifiedKFold 将确保在训练和测试数据集中每个类都有足够的样本。

我们将使用 cross_val_score 进行交叉验证。参数cv决定交叉验证策略。如果整数值被传递给cv,则使用 StatifiedKFold

cross_val_model = LogisticRegression(random_state=0)
scores = cross_val_score(cross_val_model, X_train_processed, 
         Y_train, cv=5)
print(np.mean(scores))

我们将每次迭代中获得的所有得分的平均值作为我们模型的最终得分。

交叉验证的准确率为 85.0%。

微调模型

我们可以通过调整参数来微调我们的模型。sklearn 附带了 GridSearchCV 来对估计器的指定参数值进行彻底搜索。

# penalty specifies the norm in the penalization
penalty = ['l1', 'l2']# C is the inverese of regularization parameter
C = np.logspace(0, 4, 10)random_state=[0]# creating a dictionary of hyperparameters
hyperparameters = dict(C=C, penalty=penalty, 
                  random_state=random_state)

使用 GridSearchCV 寻找最佳参数

clf = GridSearchCV(estimator = model, param_grid = hyperparameters, 
                   cv=5)
best_model = clf.fit(X_train_processed, Y_train)
print('Best Penalty:', best_model.best_estimator_.get_params() ['penalty'])
print('Best C:', best_model.best_estimator_.get_params()['C'])

最佳参数是

Best Penalty: l1 
Best C: 1.0

使用最佳模型进行预测

best_predicted_values = best_model.predict(X_test_processed)
accuracy_score(best_predicted_values, Y_test.values)

最佳参数模型的准确率为 85.2%

保存模型

我们已经完成了创建和测试模型的所有艰苦工作。如果我们可以保存模型以备将来使用,而不是重新训练它,那就太好了。我们将把我们的模型保存在 pickle 中。

filename = 'final_model.sav'
pickle.dump(model, open(filename, 'wb'))

从 pickle 加载模型

saved_model = pickle.load(open(filename, 'rb')) 

现在我们可以使用该模型进行预测。

这个博客到此为止。完整的 Jupyter 笔记本可以在这里找到。

结束语

我们已经学会了建立一个完整的机器学习项目。在这个过程中,我们构建了可以与 sklearn 的管道类一起使用的自定义转换器。我们还学会了微调我们的模型,并保存它以备将来使用。

如果有什么地方我可以做得更好,请告诉我。

感谢阅读!!

posted @ 2024-10-13 15:15  绝不原创的飞龙  阅读(293)  评论(0)    收藏  举报