差分隐私的高级介绍
在隐私和实用性之间取得平衡
在一个数据科学家眼里,你生命中的每一刻都是一个数据点。从你的牙膏品牌到你挥手的次数,我们经常认为理所当然的细节是可以用来推断我们行为和意图的关键因素。这些由跨国组织挖掘的见解可以用来使我们集体生活的各个方面更加方便和有趣,但代价是我们的私人信息被暴露甚至被利用。
以美国第二大百货零售商 Target 为例,该公司在 2012 年决定实施一种看似直观的方法,根据客户的特定需求定制他们的购物体验。目标是找出哪些客户最有可能怀孕,然后根据计算出的可能性向这些客户发送与怀孕相关的广告。我们可以将 Target 的想法解释为双管齐下的方法:1 .存储或合并数据以分析怀孕买家的趋势。2.应用技术或算法将新客户的数据点与以前客户的购买模式相关联,以确定一个人想要孩子的可能性。当 Target 在一名少女的家人知道她怀孕之前向她发送了与孕产相关的广告(混合了来自不同部门的广告)时,Target 的倡议成为了隐私和机器学习算法交汇处的许多讨论的中心(来源:福布斯关于的文章“Target 如何在她的父亲之前发现一名少女怀孕了”)。这些隐私问题不仅适用于出于营销目的的数据收集和存储,也适用于从人口普查数据到社交媒体的各种应用。
因此,大数据、机器学习和数据科学的出现使得重新考虑隐私成为必要,这是有道理的。
差分隐私被认为是可以帮助我们实现这一目标的最先进的概念之一,并且已经被苹果、优步、美国人口普查局和其他组织所使用。
在这篇文章中,我将概括介绍什么是差分隐私,为什么它是相关的,它是如何实现的,以及如何使用它。
什么是差分隐私?
差分隐私(DP)的主要前提包括确保数据主体不受其进入或参与数据库的影响(例如,不受伤害),同时最大化查询的效用/数据准确性(与随机/空输出相对)。
DP 保证:
- 原始数据不会被查看(也不需要修改)。
- 维护受试者的隐私将比从数据中挖掘重要的洞察力更有价值。
- 对后处理的弹性;对差分私有算法的输出进行后处理不会影响算法的差分私有性。换句话说,对数据库没有额外知识的数据分析师不能简单地通过考虑 DP 算法的输出来增加隐私损失(来源:【differential 隐私的算法基础】 )。
基于概述的保证,这意味着如果数据分析师/对手依赖于仅相差一个数据条目的数据库,最终结果改变的概率将不会受到该数据条目的存在/不存在/修改的影响(结果最多改变一个倍数)。换句话说,当使用 DP 时,分析师或对手不能根据查询的输出来区分数据库。
Taken from Ian Goodfellow and Nicholas Papernot’s blog post “Privacy and machine learning: two unexpected allies”
然而,与他/她对从数据中挖掘出的结论的感知相关的个人的伤害或收益不受 DP 概念的保护。DP 的正式(数学)定义如下:
Taken from Differential Privacy: A Survey of Results
Cynthia Dwork 在论文 “差分隐私的承诺算法技术教程” 中用一个简单的例子演示了 DP:
正在为一项研究向个人收集数据(玛丽是一名吸烟者,是研究参与者之一)。这项研究得出的结论是,吸烟极有可能致癌。差异隐私保证:
- 分析趋势的数据科学家或数据库经理不能直接访问原始数据。
- 诸如 Mary 的保险费之类的服务不会基于她在数据集中的参与而改变。
然而,这项研究的结论性分析(“吸烟可能导致癌症”)对伤害/好处的效用留给了玛丽的感知;玛丽可以选择相信“基于这项研究的发现,我可以通过戒烟来预防潜在的癌症”,与这种说法完全相反,或者别的什么。
为什么这很重要?
“数据是信息时代的污染问题,保护隐私是环境挑战。”— 布鲁斯·施奈尔
确保隐私对于许多应用至关重要,包括维护敏感信息的完整性,消除对手根据个人身份信息跟踪用户的机会(PII)等。DP 对各种应用都有吸引力,因为它保证了以下隐私“需求”:
DP 消除了数据分析师可能不得不使用的任何潜在方法来区分特定个人与其他参与者,或将特定行为与之前识别的个人相关联,以便相应地定制内容/服务;因此,DP 确保与参与研究相关的隐私风险不会显著增加( 【辛西娅·德沃克的“差分隐私” ) )。
这是因为无法直接访问原始数据,并且使用个人独有的发现来专门针对或影响特定个人违反了个人在数据集中的存在不应影响其接受服务的机会的规则。此外,使用 DP 不需要成为隐私或 DP 专家(即深入了解 DP 的内部机制),而且如上所述,DP 对后处理具有弹性。DP 还延伸到群体隐私,尽管增加群体的规模会削弱 DP 界限( *“差异隐私:结果调查”*作者 Cynthia Dwork )。
我们现在可以看到,上面呈现的 Target 从购买行为中预测母性的例子可能是对差分隐私概念的违反。在预测一名少女怀孕的案例中(如这里的所述,Target 应该将个人的购买趋势与其他期待孩子的客户的其他模式相关联,并开始根据她在数据集中的参与情况专门为她量身定制广告。如果她被从数据集中删除,Target 将不会向她发送与生育相关的广告,这违反了差异隐私的概念。
作为一个题外话,重要的是要注意到思考这样的道德场景并不是这么简单。销售的目标是通过说服顾客他/她需要某件商品来激励顾客购买该商品。Target 向购买了与其他顾客相似的商品的个人提供有针对性的广告,这可能侵犯了差分隐私,因为 Target 使用从组织收集的数据来帮助顾客了解公司可能提供的潜在好处,并根据他们的个人需求定制购物体验。
此外,也有反对我提到的立场的论点。一种观点强调,如果目标确实使用了该算法,它也不会是完全准确的(没有算法是完全准确的),因此会犯许多错误(即误报)。另一个角度(在《金融时报》的文章《大数据:我们正在犯一个大错误吗?》中解释))声明 Target 邮件列表上的每个人都会收到与孕产相关的广告和其他类型的广告。不仅仅是期待的顾客。
这是如何工作的?
虽然 DP 本身不是一个算法,但将 DP 的应用程序想象成位于数据分析师和数据库之间的一个软件会有助于理解它是如何工作的:
Taken from Microsoft’s “Differential Privacy for Everyone”, page 4
查询是由用户传递给 DP 警卫的输入;一个示例查询可能是“计算数据库中的行数”。差分隐私有许多变体——本节讨论ε-差分隐私,它不同于(ε,δ)-差分隐私和 DP 的其他(较弱)版本(如果您想了解 DP 的其他版本,请参见“我们的数据,我们自己:通过分布式噪声生成的隐私”)。
DP 的主要目标之一是在隐私损失(由ε测量,为此需要选择一个值,例如 0.01)和效用最大化(可以通过数据精度等许多参数测量)之间进行平衡。ε = 0 的值导致完全的私密性,但缺乏实用性,而较高的ε值导致私密性缺乏,但具有良好的实用性。(摘自 《差分隐私的承诺:算法技术教程》 )。
如微软白皮书“每个人的差分隐私”中所述,DP 技术将原始数据作为输入,从原始输入数据中找到答案,然后基于各种因素(例如,数据库的大小、查询的类型等)引入失真。)
在查询函数 f 上,隐私机制 k 用 f(X)+(lap(δf/ε))^k 以分布 lap(δf/ε)添加噪声)独立地响应 f(x)的 k 个分量中的每一个。
——摘自辛西娅·德沃克的《Differential 隐私:调查结果》
换句话说,DP“守卫”的作用是为查询(定义为函数 f )的真实答案(定义为f(x)】+(lap(δf/ε))^k)中的每个 k 输出项添加噪声;DP 防护的输出或最终结果称为响应。**
让我们把它分解一下。
噪声是通过拉普拉斯分布(在上式中表示为 Lap )添加的,这类似于正态分布/钟形曲线——正态分布和拉普拉斯分布都是单一模型(具有一个峰值)和对称的概率分布类型(分布的左侧和右侧同等平衡)。然而,主要的区别是拉普拉斯分布有一个更尖锐的峰值,正如 Statistics How To 在他们的文章中解释的那样。
A picture of the Laplace Distribution from Frank McSherry’s blog post “Differential Privacy for Dummies”
值得注意的是,也可以使用其他机制来代替拉普拉斯分布。例如,虽然拉普拉斯机制对于任何具有实数作为输出的函数都有效,但是指数机制可以用于相反的情况(没有实数作为输出的函数)并且是添加噪声不实际的情况;类似于的指数机制函数给定一个数据集,使用测量输出质量的效用函数产生一个输出/对象*(来源:摘自“differential 隐私:结果调查” 和 “野外差分隐私当前实践和公开挑战教程” )。*
使用 DP 时,我们需要计算查询的敏感度(敏感度表示为δf,查询表示为函数 f
Taken from Differential Privacy: A Survey of Results
查询的敏感性有助于我们了解个人数据对计算的影响程度,从而了解需要添加的噪声量。 f 的灵敏度通常较小,因此,在大多数情况下,DP 算法不需要添加太多噪声;当ε(隐私损失)的值固定时,较大的敏感度用作需要添加更多噪声来掩盖数据的警告(来源: “隐私的构建块:差分隐私机制” ,作者:Graham Cormode)。
需要注意的重要一点是,随着更多的问题被问及,DP 的隐私保证会减弱。这将我们带到顺序和并行合成的正式定义:
***“顺序合成:*如果你执行两个(或更多)差分隐私计算,它们共同提供差分隐私,其参数由你使用的参数的总和限定” ( 《差分隐私:图解入门》 )。
*根据顺序合成的定义,如果您有两个差分私有计算,这意味着结果将是ε1 + ε2 差分私有(摘自 Graham Cormode 的“隐私的构建块:差分私有机制”)。并行组合涉及“释放每个具有ε-差分隐私的单元”,而不是顺序组合提出的总和(如 Graham Cormode 的“隐私的构建块:差分私有机制”中所述)。如“ 差分隐私:结果调查 *,中所述,“通过在每个查询上运行具有拉普拉斯噪声分布的差分隐私算法,可以为任何查询序列确保差分隐私。另外要补充的一点是调查中提到的,敏感性和隐私损失(这是添加噪声所需的参数)与数据库的大小和数据库本身无关;较大的数据库导致对普通查询的差分私有算法具有较高的准确性。除了关于如何最大化 DP 在不敏感查询上的潜力的细节以及产生差分隐私的数学证明/定理之外,关于这一点的进一步讨论可以在调查中找到。
这一节可以用这个定理来概括:
Taken from Differential Privacy: A Survey of Results
这是如何使用的?
- 美国人口普查局在 2008 年的 OnTheMap 应用程序中实现了 DP,以确保居住人口数据的隐私性。阅读这篇文章中的更多细节:" 保护美国统计数据的保密性:在人口普查局采用现代披露避免方法 " 由约翰·m·阿伯德博士撰写。
- 苹果在苹果机器学习杂志的文章 “大规模隐私学习” 中描述了利用 DP 的三种用例:发现流行的表情符号,识别使用 Safari 访问的资源密集型网站,以及发现新词的使用。苹果实现的一个新颖方面是他们使用了三种不同的私有算法——私有计数均值草图算法、私有哈达玛计数均值草图和私有序列片段拼图。
Taken from the article “Learning with Privacy at Scale” from Apple’s Machine Learning Journal
- 微软应用 DP 来掩盖个人在其地理位置数据库中的位置;这种方法包括随机删除、添加和打乱单个数据点。其实现的一个新颖方面是创建了 PrivTree ,在给定原始数据和一些其他参数(要使用的拉普拉斯噪声的比例、用于决定是否应该发生节点分裂的阈值等)的情况下。),可以实现差分私有算法,并为几乎任何种类的位置数据输出噪声数据。
**
Pictures taken from Microsoft’s blog post “Project PrivTree: Blurring your “where” for location privacy”
- 优步将差分隐私作为其数据分析管道和其他开发工作流程的一部分。他们的实现的一个新颖方面是使用弹性敏感度,这种技术允许您计算查询的敏感度,并满足优步苛刻的性能和可伸缩性要求。
Taken from Uber Security’s Medium article “Uber Releases Open Source Project for Differential Privacy”
- 谷歌实施了 DP 作为其随机可聚合隐私保护顺序响应(RAPPOR)技术的一部分,该技术允许数据分析师研究客户的数据,而无需查看单个数据点。他们实现的一个新颖方面是,DP 的实现是为了在 RAPPOR 执行的两个重要步骤中保证客户端隐私:永久随机响应确保隐私不受生成的噪声的影响,而瞬时随机响应防止攻击者使用永久随机响应。
Taken from the paper “RAPPOR: Randomized Aggregatable Privacy-Preserving Ordinal Response” by Úlfar Erlingsson, Vasyl Pihur, and Aleksandra Korolova
额外资源
这篇文章仅仅触及了不同隐私的表面。如果你想进一步探索动态规划的内部机制和应用,有很多很好的资源;其中一些包括:
- 在微软的研究网站这里可以找到关于 DP 的出版物概要。
- Georgian Impact 的媒介文章《差分隐私简介》除了对拉普拉斯噪声计数机制的模拟。
- 《差分隐私小教程》Borja Balle 著。
- 《科学美国人》文章“数字隐私:保护数据的新方法”
- Frank McSherry 关于差分隐私的博客帖子(其中一些包含用于演示目的的代码),比如这篇帖子。
- 宾夕法尼亚州立大学课程 的课堂讲稿和课程材料数据隐私中的算法挑战
- 演讲幻灯片:“野外的不同隐私:当前实践和公开挑战指南”。
- 如果你想了解我们如何将 DP 应用于机器学习,我推荐你阅读尼古拉斯·帕伯诺特和伊恩·古德菲勒的博客文章“隐私和机器学习:两个意想不到的盟友?”和马丁·阿巴迪及其同事的论文“具有差异隐私的深度学习”。
- 如果你对机器学习和隐私之间的交集感兴趣,请查看 NeurIPS 2018 " 隐私保护机器学习研讨会。
感谢您的阅读!
原载于 2018 年 11 月 20 日demystifymachinelearning.wordpress.com*。*
基于后见之明的数据科学博士学位方法
最近刚完成计算机科学(更具体地说是数据科学)的博士学位,事后回想起来,我发现有些事情我会采取不同的做法。我的目标是这篇文章对那些刚刚开始或考虑攻读数据科学博士学位的人有用。
Photo by Glen Noble on Unsplash
r 与 Python
我博士的开始日期是 2014 年 9 月,我最初在 KNIME (一个基于可视化节点的数据挖掘工具)中做了一些初步的研究。然而,我发现用 KNIME 编写任何相当复杂的东西都需要创建一个定制的 KNIME 节点。节点创建需要大量样板代码,通常会导致 Eclipse 出现问题(在我看来,Eclipse 是一个糟糕的编辑器——希望事情已经发生了变化,因为我自 2014 年以来就没有接触过它)。
有人可能会问,“你为什么首先使用 KNIME?”这是一个合理的问题。答案是,我的主管参与的以前的研究有一个为它开发的自定义 KNIME 插件,所以从这个开始似乎是个好主意。
因为我要停止使用 KNIME,所以我需要用一个新的工具来替换它,这个选择我缩小到了 R 或 Python。当时,在 2014 年,R 和 Python 似乎在可用的机器学习库中拥有平等的地位。出于几个原因,我最终选择了 R:
- Python 的缩进:我真的不喜欢 Python 的强制缩进。我目前的看法是,我仍然不喜欢它,我只是咬紧牙关,遵守它的规则。
- 统计计算:R 是为统计和分析而设计的语言,而 Python 是为通用计算而设计的。我的想法是,R 将允许更容易地调查数据,因为语言本身就是为这项任务设计的。
至于为什么我希望选择 Python: Python 是迄今为止最受欢迎的编程语言,根据 2018 年 8 月 TIOBE 指数 Python 排名第 4,R 排名第 18。2014 年9 月,Python 是#8,R 是#21。也许我当时就应该看看这个榜单,看到这两种语言流行的趋势。
此时,Python 已经开发了大量的库和资源。另一个问题是 R 的古怪之处,dplyr 试图通过使代码看起来更合理来解决它——我希望我在开始时就知道这一点,而不是在结束时发现这一点。
在我的研究过程中,我确实为 R 写了一个包,我认为如果这个包是为 Python 开发的,它实际上可能不仅仅是我一个人在使用。事实上,一名硕士生正在开发我研究的未来工作部分。我最后一次和他交谈时,他告诉我他将从事 Python 的工作,而我的回答是“我希望我已经那样做了”。我相信他可能要做的第一件事是用 Python 重写 R 包的许多功能,因为这些功能非常常见——几乎是基本的——来操作我在博士学位期间分析的数据。
制作更多互动作品
这一点不是为了研究方面的事情,我可以说这是可选的,因为它不会影响最终结果,也不会提高生产率。在我读博士期间,我根据我正在分析的数据制作了几个互动项目:
- 允许用户输入特征的用户界面和经过训练的分类器将做出预测。
- 用过滤器列表更改下拉列表,图形将根据下拉列表中的项目更新—数据将应用不同的过滤器。
这些都是非常基本的东西,但是对于向我的主管解释概念有很大的帮助,而且交互性远比静态图表更令人愉快。我希望我能开发出更多这样的东西。这也可以包括动画图表——这很容易用 D3.js 来完成,并且可以为演示制作一些引人注目的幻灯片。
第一个项目使用了gWidgetstcltk——一个交互式 GUI 生成器——它就像这个包的名字一样有趣。第二个项目使用了闪亮的——一个交互式网络应用构建器——实际上使用起来很有趣,尤其是与 gWidgetstcltk 相比。
减少脚本依赖性
我绝大多数的工作都是由原型组成的,这些原型从未产生任何有意义的结果。其中一些原型是独立的,但随着我继续攻读博士学位,这些原型变得越来越相互依赖:
每个脚本的结构如下:
- 导入库
- 函数定义
- 执行函数的耗时代码
当脚本#2 需要使用脚本#1 中定义的函数时,就会产生脚本依赖性,因此它会运行整个脚本#1 来将定义的函数加载到 R 工作空间中。
每当运行脚本#2 时,运行脚本#1 的第一个问题是,这会导致每次都运行耗时的代码。为了解决这个问题,我不得不返回到脚本#1 并编写一些额外的代码,这样耗时的代码只有在脚本#1 直接运行时才会被执行(而不是从另一个脚本)。
第二个问题是这变成了一团乱麻。一种解决方案是将函数定义与执行代码完全分离,将它们放在各自的文件中。
第三个问题是,脚本#1 中的重构函数会对每个使用重构函数的依赖脚本产生连锁反应。这个问题的潜在解决方案让我想到:
(非常小的)持续集成
一个持续的集成环境,它只是运行所有的脚本(或子集)来检查它们是否还在工作。
数据的版本控制
随着我收集和处理的数据越来越多,我在博士期间使用的数据量也在增加。我最终通过将数据复制并粘贴到存储每个原型的文件夹中来复制每个项目的数据,所以在某种程度上,这是对数据版本化的一种粗略尝试。数据量不是很大,所以在这方面这不是很大的问题。但是将它放在一个包含最终原型的代码库中(在那里已经分析了结果),并链接到提交,会是一个简单得多的解决方案。
结论
我不认为我会再去读一个博士,但希望这对潜在的博士生或刚开始读博士的人有用。很明显,这不是一份详尽的清单,而是一份我应该做却没有做的清单。
免责声明:我提到的软件/技术在我读博士时可能已经改变,我的观点是基于我使用它们时的状态
RTS 人工智能研究的历史
RTS 游戏中的 AI 研究有着丰富的历史。十多年来,研究人员一直致力于构建能够击败最佳人类选手的机器人,但仍有很长的路要走。在 BlizzCon 2016 上,DeepMind 和暴雪宣布了一项合作,这导致了星际争霸 2 人工智能研究的开放 API。
这篇文章的目标是涵盖 RTS 游戏和人工智能研究的一些发展,这些发展可能有助于这一结果。要更全面地了解 RTS 游戏的研究,请查看由翁塔诺等人和罗伯逊和沃森撰写的调查文章
StarCraft II, Blizzard Entertainment
在过去的十年里,研究人员已经从孤立地研究 RTS 游戏中的不同人工智能技术,过渡到在更复杂的游戏中合作和竞争,在这些游戏中,不同的技术面对面地进行匹配。为了使这项工作取得成功,下列条件是必要的:
- 开放 API 供研究人员构建和评估机器人
- 竞赛让研究人员能够比较不同的技术
- 回放学习算法用于训练
- 人类对手评估机器人的性能
随着 2009 年 Brood War API 的发布,这些条件中的大部分都得到了满足,但该平台的封闭性使得研究人员难以自动化训练 AI 系统的过程。随着开放的星际争霸 2 环境的宣布,研究人员将有很大的机会开发能够在 RTS 游戏中实现专家级性能的系统。以下是我认为对实现这一目标具有重要意义的一些事件。如果有我应该包括的其他重要事件,请在评论区留言。
1998 年
《星际争霸 1》发行
原版《星际争霸》于 1998 年 3 月发行,资料片《育雏战争》于同年 11 月发行。《星际争霸》风靡全球,并在韩国引发了一场职业游戏热潮。
在有星际争霸之前,有 1995 年发行的魔兽争霸 2。魔兽争霸 2 的一个克隆版本在 1998 年以 Freecraft 的名字首次发布,后来被重新命名为 Wargus。这个克隆体是建立在 Stratagus 游戏引擎上的。Freecraft 是 RTS AI 研究的一个重要项目,因为最初的大部分工作都是使用 Wargus 作为测试平台。
2001 年
对游戏人工智能的学术兴趣一篇关于游戏人工智能的开创性文章是约翰·莱尔德和迈克尔·范·伦特的文章,发表在 2001 年的《人工智能杂志》上。这是一篇意义重大的文章,因为它是 AAAI 最早承认实时游戏是人工智能研究的优秀环境的出版物之一。它还帮助改变了学术研究人员的心态,从试图将现有的方法应用于游戏,转而考虑为游戏建立新的和专门的方法。
2002 年
魔兽争霸 III 发布
魔兽争霸 III 附带的一个很棒的特性是一个高度可扩展的地图编辑器,它被用来创建像 DOTA 初始版本一样的独特内容。地图编辑器也有一些脚本功能,可以用来创作自定义的人工智能。然而,以这种方式创作的 AI 仅限于单个地图,并且脚本语言仅向作者提供命令的子集。一些研究人员能够在这个框架内实现他们的人工智能技术,但不可能测试不同的机器人。
2003 年
RTS 游戏被提议作为人工智能试验台
Michael Buro 和 Timothy Furtak 在 2003 年发表了一篇文章声称 RTS 游戏提出了许多需要解决的新问题,以便构建人类级别的人工智能。他们还提议开发一个开源的 RTS 游戏引擎,供人工智能研究社区使用。
State Estimation in StarCraft
2004 年
第二年,Michael Buro 发布了第一个开源 RTS 引擎版本, ORTS 。该游戏能够在图形和非图形模式下运行,这使得机器人能够在数千个游戏会话中快速训练。使用 ORTS 的一个主要挑战是,虽然有人类玩家的界面,但没有专家玩家可以评估机器人。
ORTS Game Engine
第一个沃格斯研究
Freecraft 更名为沃格斯,使用了 Stratagus 游戏引擎。Wargus 的主要优势之一是它是开源的,这为研究人员使用他们想探索的任何技术开放了平台。Wargus 面临的一些挑战是缺乏用于分析的回放,缺乏活跃的玩家基础,以及用于测试机器人相互之间的网络代码有限。马克·庞森是第一批发表关于使用沃格斯作为人工智能测试平台的文章的研究人员之一。
TIELT 提出
2004 年提出的 AI 项目之一是 TIELT 系统,这是一个为多个游戏标题提供一致 API 的 AI 框架。该系统的目标之一是使研究人员能够为一个游戏构建人工智能,并将学到的知识转移到新的游戏中。例如,在 Wargus 中学到的领域知识可能适用于其他 RTS 游戏。我将 TIELT 包括在这个讨论中,因为 DeepMind 和暴雪合作的成果之一将是一个 API 和潜在的示例数据集。对于这个 API 来说,重要的是不要对人工智能如何运行做出假设。TIELT 的挑战之一是它不提供对游戏状态的直接访问,这限制了可以利用它的人工智能技术的数量。这个系统的许多目标现在在脸书的 ELF 平台上实现了。
TIELT Architecture [Aha and Molineaux, 2004]
2005 年
沃格斯的强化学习
沃格斯很快成为研究人员构建 RTS AI 的环境。2005 年,研究人员开始探索诸如强化学习的技术,这是 AlphaGo 使用的策略之一。Wargus 的工作最终开始停滞不前,因为不同的研究人员无法相互评估工作,而是依赖于性能而不是硬编码脚本的小集合。
2006 年
第一届 ORTS 竞赛
2005 年,第一届 ORTS AI 竞赛公布,赛事在斯坦福的 AIIDE 2006 大会上举行。第一届比赛有 4 个参赛项目,比赛规模逐年增长,直到 2009 年结束。
2007 年
ICCup 推出
国际赛博杯是星际争霸的第三方托管天梯服务器。这个服务器对人工智能研究很重要,因为你可以在这个服务器上运行机器人,但不能在官方的暴雪服务器上运行。这个服务器的另一个好处是,它为玩家提供了一个字母分数,他们可以使用它来轻松地交流他们的技能。比如我 2010 年认真打球的时候顶多是个 D+玩家。
2008 年
首次星际争霸人工智能研究
虽然之前有关于星际争霸的出版物,但我所知道的第一篇专注于星际争霸人工智能构建的文章发表于 2008 年。谢和孙建立了一个模型,通过挖掘成千上万的录像来预测玩家正在制造哪些建筑和单位。
Build-Order prediction in StarCraft
2009 年
育雏战争 API 发布
2009 年,我发现了一个名为 BWAPI(育雏战争 API)的 Google 代码项目,它提供了对星际争霸的编程访问。该库通过使用第三方 DDL 工具将 API 注入星际争霸运行时来工作,并暴露了一组用于调用游戏内函数的钩子。从那以后,这个项目的贡献者规模不断扩大,并被移植到多种语言。它现在托管在 GitHub 上,有一个 Java 版本。
2010 年
星际争霸 2 发售
2010 年,星际争霸 2 自由之翼发售,竞技育雏大战场面持续活跃了几年。资料片《虫群之心》发布于 2013 年,《虚空的遗产》发布于 2015 年。
首届星际争霸赛
首届星际争霸赛 AI 赛在 AIIDE 2010 举行。主赛事由伯克利 Overmind 团队赢得。比赛还包括一场人机表演赛,人类选手轻松击败了人工智能对手。
UC Berkeley Overmind Team
2011 年
第二届 AIIDE 星际争霸赛
阿尔伯塔大学的 Dave Churchill 接手了第二届以及随后几届的 AIIDE 星际争霸赛。他编写了一个自动运行锦标赛的锦标赛框架,并改变了一些规则以促进合作,例如要求提交的内容是开源的。
学生星际 AI 锦标赛
第二届星际 AI 锦标赛开始了,重点是学生提交。该锦标赛与年度会议无关,每年举办几次锦标赛。
2013 年
星际争霸 BroodWar 机器人天梯
Krasi0 为星际争霸机器人开发了一个天梯系统,现在 24/7 运行。这为研究人员评估不同的人工智能方法提供了一个环境。
2014 年
星际争霸 2 自动化玩家
Matt web corner演示了可以通过拦截 DirectX 命令来构建星际争霸 2 机器人,以便推断游戏状态。这种方法的一个主要限制是机器人只能访问当前显示在屏幕上的游戏状态。
2016
AlphaGo 击败 Lee Sedol
2016 年 3 月,DeepMind 的 AlphaGo 系统击败围棋世界冠军 Lee Sedol。胜利之后,很多人预计《星际争霸》将是 DeepMind 尝试的下一个挑战。
脸书加入
2016 年,来自脸书的人工智能研究人员开始使用《星际争霸》作为强化学习试验台。他们发表了一篇关于星际争霸中微观管理的文章。该机器人参加了 AIIDE 2017 竞赛,但它的学习方法被更关注脚本的机器人胜过。
在 BlizzCon 2016 上,DeepMind 宣布他们正在与暴雪合作开发一个开放的人工智能框架。随着谷歌和脸书竞相打造一个能够胜任职业星际争霸游戏的机器人,竞争开始升温。
2017
星际争霸 2 API 发布 暴雪在 8 月 9 日发布了用于编写 bot 的星际争霸 2 API。还宣布了一个用于编写机器人的研讨会。
触发人工神经元的历史
这一切都是从四年前我了解到深度信念网开始的。当时,人们说“这是由生物神经网络启发的”,我只是接受了这一点。在我深入研究之后,我的脑海中涌现出许多问题,尤其是当我看到 乙状结肠函数 时。起初,这对我来说似乎很荒谬,因为这个 sigmoid 函数只是将任何给定的数字映射到范围-1 到 1。那么,我们为什么需要这个?。我的第一个猜测是,也许它只是使输出正常化,所以在某些时候它不会爆炸。这个问题一直留在我的脑海角落里,静静地坐着,等待着有一天被回忆起来。
几年过去了,我一直在质疑很多其他的东西。直到几周前,我才接触到一本关于计算神经科学的书。我读了这本书,我在那本书的第三章找到了答案。它描述了神经元如何表现的几种计算模型,我发现了人们最近使用的深度学习模型的联系,以及人们更喜欢使用当前模型的原因。在本文中,我将总结我所知道的人们用来模拟神经元的一些神经元模型,并试图将计算神经科学与应用人工智能联系起来。由于我既不是计算神经科学家也不是生物学家,可能会有一些不准确的信息,如果有的话,我会很乐意纠正它们。
计算神经科学和人工智能
在我看来,这两个主题虽然关注的方向不同,但仍然紧密相关。我称之为习得智力的因果关系。这篇文章是从两个角度写的。
The causality of learned intelligence
在模拟模型时,计算神经科学的重点是了解大脑如何工作,以及如何才能接近真实的大脑。反过来,人工智能试图基于提出的理论、观察结果和近似模型来构建智能系统。
基本人工神经元结构
神经元是一种细胞。与我们身体中的其他细胞相同(如红细胞)。它的主要任务是传输和处理信息(编码为电脉冲)。据我所知,对于所有不同的人工神经元模型,人工神经元的结构是相同的。它有许多输入(x)和一个输出(y)。就发送电脉冲(信息)而言,一个神经元与其他所有神经元之间的连接能力可以不同,这种能力称为连接强度。
Basic structure of artificial neuron
计算神经科学中的神经元模型
漏整合和发射神经元(1907)
这个模型通常缩写为 IF-model。它来源于当两个连接神经元在两个膜中都有电势差时产生的尖峰(由化学反应、转移的离子等引起)。正如基尔霍夫定律所说,两个端点之间的电位差导致电流从一端流向另一端。
该模型对每个输入的电流进行积分(求和),并改变神经元膜中的电位值。如果神经元膜上的电位值达到一定的电位阈值,神经元就会发出一个尖峰信号。出现尖峰后,神经元膜将其值重置为静息电位。然而,在膜中存在渗漏(阻力因子),并且该渗漏因子将在膜复位后重新启动(抵消)静息电位。
在这种模式下,有两种产生尖峰的独特情况:
- 当输入电流恒定并且低于膜的电位阈值,并且它们的总和仍然低于膜的电位阈值(非激发尖峰)时
- 当输入电流恒定且低于膜的电位阈值,并且它们的总和高于膜的电位阈值(激发尖峰)时
这两种情况都被称为亚阈值,在亚阈值中,神经元表现为线性。在第一种情况下,不会产生尖峰。在后者中,由于神经元膜的电容性行为,它产生周期性的尖峰。
但是,这种模式有一些限制:
- 该模型的亚阈值条件没有给出实际发生在真实神经元中的各种产生的尖峰。
- 真正的大脑由大量相互连接的神经元组成。如果将该模型集成到大规模网络中,它将变得不容易处理。
麦卡洛克-皮茨神经元(1943 年)
麦卡洛克-皮茨神经元模型没有考虑神经元如何工作的所有细节,而是忽略了所有细节,例如微分方程、重置膜电位等,并且仅考虑神经元模型的主要特征。甚至使其离散。
The McCulloch-Pitts Neuron model, o for output, h for threshold
这个想法是,给定一些输入值,如果输入值的总和超过阈值,神经元将输出 1,否则神经元将输出 0。这种神经元模型适用于较大的网络。
伊兹基科维奇神经元(2003)
与 IF-neuron 相比,该模型的计算效率相对更高,并且产生尖峰的可能性更大。该模型引入了两个微分方程,一个用于更新膜电位,另一个用于更新“恢复变量”。它还引入了简单的复位条件。
神经元如何学习?
如果我们再看一下上一节中的基本人工神经元结构,我们可以得出结论,最影响神经元输出的是神经元之间的连接强度。我们可以简单地说,当我们学到一些东西时,连接强度会根据我们学到的东西以某种方式形成。我们获得了一个新的信息(如图像、新闻、歌曲等),我们是通过感官从体外环境中获得的。信息会从输出神经元到输入神经元反向传播到网络,并影响神经元之间的连接强度。比如我们现在的知识是“树上的叶子都是绿的”。但是,当我们看到一片棕色的叶子时,新的信息“有一片棕色的叶子”将与我们当前的知识进行比较,并且我们当前的知识将被更新为“不是树上所有的叶子都是绿色的”。以前存储信息“树中的所有叶子都是绿色的”的连接强度,现在存储“树中的所有叶子都不是绿色的”。
人工智能中的桥接神经元模型和人工神经元——激活函数
在计算神经科学中,神经科学家尽可能接近真实的神经元,并或多或少地考虑神经元的细节。为了使模型在大型网络中可计算,需要一个可计算但有代表性的模型,并且在计算和精度之间总是有一个折衷。
从之前描述的所有模型中,有一个主要的相似特征在神经元模型中非常重要,即触发的尖峰。简而言之,神经元的基本任务是在给定一些输入的情况下产生一个尖峰。这个主要特性可以用数学的方式表示为一个函数,称之为 激活函数 。
人工智能中的人工神经元
模拟真实神经网络的人工神经元网络是人工神经网络。对于每个人工神经元,都有一个数学函数。人工神经网络应该具有学习新信息的能力。神经元模型中的连接强度在人工神经网络中称为参数。为了形成参数,我们需要像大脑那样通过将新信息从输出传播到输入来训练神经网络。它被称为反向传播。在反向传播过程中,可以使用微分计算比较当前知识和新知识。从数学的角度来看,并不是所有的函数都是可微的。因此,找到一个既可微分又具有良好性能(近似真实神经元)的激活函数有点棘手。
除此之外,一个好的模型是更一般化的模型。想象一个孩子正在学习动物的名字。老师教他“狗、马、鸡”是动物。如果在那之后,孩子可以知道老师以前从未教过他的动物种类,例如“一头牛,一只山羊”也是动物,因为它们与马有相似的解剖结构,即使有时孩子说“一只鸡”不是动物,这是错误的,这意味着他可以概括他所学的东西。
但如果孩子只知道“狗、马、鸡”是动物,其他的不是动物,即使他回答得很完美,也不是一个概括的问题。这就是所谓的过度拟合。下面是几种激活功能。它们都有自己的优点和局限性。人们可以根据需要使用任何激活功能。
乙状结肠功能
Sigmoid 函数具有与 logistic 函数相似的曲线(“S”形曲线)。如果输入是相对较大的负值,则输出为零,如果输入是相对较大的正值,则输出为一,否则输出值介于 0 和 1 之间。
Sigmoid function
优势:
- 因为输出在 0 到 1 的范围内,如果我们想表示某件事情发生的概率,这个激活函数是有用的。
校正线性单位(ReLU) (2010)
如果输入小于零,ReLU 使输出为 0。如果输入大于 0,则输出与输入相同的值。
ReLU function
优势:
- 与具有指数常数的 sigmoid 函数不同,计算导数(梯度/微分)ReLU 在训练中相对更快。如果输入小于 0,消除(产生零)输出会使整个网络更加稀疏。
- 产生与输入值相同的输出值(恒等式)使得导数更容易计算(相同值的导数将总是 1),因此网络不会遭受 消失梯度 的问题。
还有 ReLU 的其他变体,、漏 ReLUs (LReLUs) 、参数化 ReLUs (PReLUs) 。
指数线性单位(ELU) (2016)
ELU 的功能与瑞路相似。而不是在输入小于零时产生输出 0。如果输入小于零,它用特定的函数计算,否则它输出与输入相同的值。因此,如果输入小于零,输出将为负。
优势:
- 尽管仍然像 ReLU 一样解决消失梯度问题,但如果输入小于零,eLU 通过使用负输出使平均激活值(类似于将数据集归一化为平均零)趋向于零。这使得学习速度更快。
高斯误差线性单位(GELU) (2016)
这个激活单元根据输入比其他输入大多少来随机缩放输入。高斯的累积分布函数用于确定比例因子。该单元具有与自适应退出类似的功能。
优势:
- 一个非凸的非线性函数使它比 ELU 和 ReLU 具有更大的灵活性。它还具有更好的通用性,有助于获得更高的精度。
综上
这篇文章只是我对发生的事情和我之前发现的事情的看法,对一些人来说可能非常肤浅。另外,我刚才描述的话题只是神经元的一小部分,一个 激活功能 ,一件小事却影响巨大。
无论如何,知道人类能在多大程度上推动自己去了解自己真的很令人兴奋。计算、推断和建立智能系统的新方法的发明一直在迅速增加。计算神经科学家和人工智能科学家都在尽最大努力改善目前的状况。每个月都有新的方法、理论、模型被发明出来。我打算把这篇文章写得尽可能简单,让每个有兴趣的人都能理解。所以,如果有一点复杂的语言或术语,或者无法解释的词,请原谅我。
python NumPy 数组的搭便车指南
A hitchhiker guide to python NumPy Arrays
如果您正在使用 python 进行数据科学研究,那么您要么使用过 NumPy,要么肯定听说过它。大多数需要将数据存储在内存中的统计分析都使用 Numpy。
有人可能会问为什么是 NumPy?难道 python 列表或其他数据结构不能做同样的事情吗?
嗯,是也不是,在 NumPy 中没有什么是不能通过 python 列表或使用其他数据结构来完成的,但是,NumPy 提供了一个有效的存储和更好的方式来处理使用简单 API 的数学运算的数据,其好处远远超过了编写自己的代码。
NumPy 为数学运算提供了高效的存储和更好的数据处理方式
为什么使用 NumPy 数组?
NumPy 用于创建 同构 n 维数组(n = 1…n)。与 Python 列表不同,NumPy 数组的所有元素都应该是同一类型。因此,如果提供了数据类型,下面的代码无效
numpy_arr = np.array([1,2,"Hello",3,"World"], dtype=np.int32) # Error
然而,对于 python 列表,这是一个有效的代码
py_arr = [1,2,"Hello",3,"World"] # Valid Code
考虑到可以在 NumPy 数组上执行的数学运算,NumPy 数组被创建为同构数组。对于异构数据集,这是不可能的。
让我们看看 NumPy 为我们提供了什么额外的好处,以及它如何简化我们的编程生活,尤其是处理数学计算的编程。
1.NumPy 使用更少的内存来存储数据
与 python 列表相比,NumPy
数组占用的内存要少得多。它还提供了指定内容的数据类型的机制,这允许进一步优化代码。
作为一个例子,我们可以使用 python list 和使用numpy.array(...)
创建一个简单的 6 个元素的数组,它所占用的内存量的差异是相当惊人的。参见下面的例子
如果这种差异看起来令人生畏,那就准备好接受更多。如果我们知道我们计划拥有的单个数据的最大数量,就有可能对 NumPy 数组做进一步的优化。
在上面的例子中,NumPy 默认认为这些整数是8 Bytes
整数,但是,如果我们知道数据的最大范围,我们可以用 NumPy 数组提供数据类型。例如,我们可以使用1 Byte
整数存储到255
的数字,使用2 Bytes
整数存储到65535
的数字
优化的内存分配不仅限于存储数字,它还扩展到存储字符串。但是,由于 NumPy 数组主要用于数学计算,string 将很少被存储和使用。然而,知道需求是否出现是很好的
类似地,NumPy 数组在存储浮点值方面提供了相当大的节省。
现在我们知道了 NumPy 的内存优势,让我们继续了解它如何允许我们创建多维数组
2.使用 NumPy 创建 n 维数组
n 维数组通常用于创建矩阵或张量,也主要用于数学计算目的。与基于 python 列表的 n 维数组相比,NumPy 不仅节省了内存使用,还提供了大量额外的好处,使数学计算变得容易
这是我们可以用 NumPy n 维数组做的一系列事情,否则很难做到。
只要多重因子产生相同数量的元素,数组的维数就可以在运行时改变。例如,2 * 5 的矩阵可以转换为 5 * 2,1 * 4 可以转换为 2 * 2。这可以通过调用数组上的 NumPy *.reshape(...)*
函数来完成
NumPy 也可以为一个数组生成一组预定义的数。使用 *numpy.arange(...)*
功能可以生成一组预定义的数字(包括小数步长)。这个函数的输出总是一维的数字集合。但是,我们可以对这个输出使用 reshape 来生成我们选择的维度。
NumPy 提供了使用预先填充的 1 和 0 创建 n 维数组的 API,其中矩阵的所有成员不是 0 就是 1。最有可能的用途之一是为机器学习创建一个稀疏或密集的矩阵。
默认情况下,NumPy 使用浮点 *float64*
数据类型来创建 1 和 0,但是可以使用 *dtype*
选项将数据类型更改为整数,如下图
正如 *.reshape(x,y)*
可以将一个数组转换成多维数组,同样,使用 *.ravel()*
函数可以从任意多维数组创建一个一维数组
3.n 维数组的数学运算
如前所述,NumPy 不仅可以有效地存储数据,还可以非常容易地对数据进行数学运算。对 n 维数组的任何操作都与数学运算非常相似。
NumPy n 维数组使得对其执行数学运算变得极其容易
这是 NumPy 的主要 USP,因为它被广泛用于数据分析社区。python 列表离它能做的还差得很远。例如,考虑将 python 列表乘以 2。这是我们将得到的
py_arr = [1,2,3] * 2
# Generates [1,2,3,1,2,3]
而 numpy 数组产生输出,每个数组元素乘以 2
np_arr = np.array([1,2,3]) * 2
# Generates [2,4,6]
类似地,我们也可以对 numpy 数组进行其他数学运算,如加、减和除
np_arr = np.array([1,2,3]) + 2
# Generates [3,4,5]
一个多维矩阵的运算就像我们使用两个数一样简单
np_arr1 = np.array([[1,2,3],[4,5,6]])
np_arr2 = np.array([[1,2,3],[4,5,6]])np_arr3 = np_arr1 * np_arr2
#Generates
# [[ 1 4 9]
# [16 25 36]]np_arr3 = np_arr1 + np_arr2
#Generates
# [[ 2 4 6]
# [ 8 10 12]]
NumPy 内置的数学函数还允许我们执行复杂的数学运算,如 sqrt、mean 和 median。
np.sqrt(np_arr1)
#generates
# [1\. 1.41421356 1.73205081]
# [2\. 2.23606798 2.44948974]]np.mean(np_arr1) #generates 3.5
np.median(np_arr1) #generates 3.5
还有额外的内置成员函数来获取数组的更多细节,包括 sum、min 和 max
np_arr1.sum() # 21
np_arr1.min() # 1
np_arr1.max() # 6
4.在 NumPy 数组中查找元素
在处理数据集时,有时我们需要从可用的数据集中找到特定的数据。虽然 NumPy 为相同的功能提供了多种功能,但其中三种功能会比其他功能使用得更频繁。他们是where, nonzero
和count_nonzero
Where
和nonzero
函数返回与 True 语句相关的索引。例如
np_arr = np.array([1,2,0,4,5])
find = np.where(np_arr > 2)
#returns [3,4]
和
np_arr = np.array([1,2,0,4,5])
find = np.nonzero(np_arr)
# return [0,1,3,4]
最后可以通过使用count_nonzero(...)
函数来计算 numpy 数组中非零元素的个数
n_arr = np.array([1,2,3,0,3,0,2,0,0,2])
np.count_nonzero(n_arr)
# returns 6
这些方法在计算矩阵的稀疏度或密度时非常有用。
在机器学习中有其自身用途的最后一种方法是找到 NumPy 数组的形状。这是使用.shape
完成的。例如
n_arr = np.array([1,2,3,0,3,0,2,0,0,2])
n_arr.shape
# Generates => (10,)
n_arr = np.array([[1,2],[3,0]])
# Generates => (2,2)
5.最后的想法
上面提供的例子仅仅描述了 NumPy 功能的最小集合。虽然不全面,但是应该对什么是 NumPy 以及我们为什么要学习和使用它有足够的了解。
这就是这篇文章的全部内容。将在另一篇文章中提出另一组有趣的 NumPy 功能
感谢阅读…!!!
达克什
人工智能科…不要!
我如饥似渴地阅读了 HBR 的文章——机器学习改善公司工作流程的 8 种方式。虽然这篇文章包含了一些非常好的观点,但我完全不同意创建人工智能卓越中心的建议。值得称赞的是,两位作者确实对彼此脱节的创新孤岛提出了警告。
我更大的问题是机器学习太重要了,不能被隔离在创新实验室里!Frank Chen 提供了机器学习将如何嵌入产品的最佳类比。根据陈的说法,机器学习类似于关系数据库,从电子商务到猫视频,关系数据库一直是当前所有数字产品和体验的核心。关系数据库在存储和排序数据方面非常出色。
机器学习应用同样将是未来体验的基础。不同的是,ML 的度量单位是预测。回到这篇文章,人工智能 COE 和关系数据库 COE 一样荒谬。
相反,我建议采用 ML 优先的方法。那么——这在实践中应该如何运作呢?
创新的类型
基本上有三种类型的创新:
- 渐进式创新——这是持续调整和改进的改善方法。
- 破坏性渐进主义——这是间隙空间中的创新,导致“曲棍球棒”的结果。想想看——苹果应用商店的推出。
- 突破性创新——这在商业中极为罕见,在自然界几乎从未出现过。思考——优步的创造和共享经济的兴起。
对于这类创新的精彩分析,请看谷歌前首席信息官 Doug Merrill 的这篇 Google Talk 。这是相当过时,但仍然非常相关。
虽然机器学习将创造一些激进的创新,但我认为更有趣的机会是创造具有破坏性影响的增量变化。
你如何发现颠覆性渐进主义的机会?良好的开端是从您的客户(外部或内部)开始,并遵循以下步骤:
- 规划顾客的旅程
- 确定旅程中的空白区域,在那里顾客正在离开或者没有以某种关键的方式得到服务
- 你在收集有效数据吗?例如,您是否正在收集客户的人口统计数据、当前表达的意向信号、这些信号对公司的价值等
- 有没有办法建立一个模型来传递一个独特的信息,提高客户转化的机会?
以上所有的步骤都是渐进的变化,但是总的来说(并且是大规模的),它们可以带来不成比例的巨大成果。对我来说,这是机器学习的更大机会——不是藏在某个 COE 里,而是在取悦你的客户的前线。
人工智能玩疯狂图书馆,结果是可怕的
这是 1982 年。迈克尔·杰克逊的《T2》惊悚片《T3》是世界上最畅销的专辑。外科医生最近植入了世界上第一颗人造心脏。时代杂志刚刚选择了“计算机”作为年度风云人物。但是现在这些都不重要了,因为你已经在 8 小时的家庭汽车旅行中呆了 30 分钟,你已经厌倦了。
你会在 iPhone XS 上打开 Instagram 自娱自乐吗?没有,苹果还在为大家翘首以待的 Apple IIe 的发布做准备。你有没有看最新的哈利波特书?没那么快,J. K .罗琳才高中毕业。取而代之的是,你拿起新削好的 2 号铅笔,画出这个:
疯狂图书馆?你指的是那种简单而巧妙的游戏吗?一个玩家向另一个玩家要一系列单词,然后用这些单词填充一个故事模板,接着就是欢乐。是的,那个疯 Libs。
回到我们的故事…你和你的弟弟设法通过 30 分钟玩游戏。最终,你的兄弟厌倦了这个游戏,出于你新的厌倦,你开始自己玩。因为你没有耐心,你就直接跳到故事,然后开始以你认为合适的方式填写空白。这是我们在本文中关注的 Mad Libs 的退化单机版。
自 1982 年以来,世界发生了巨大的变化。首先,伯特被释放了。伯特?“你问吧。"你是指最近达到最新技术水平的BI directionEn coderR代表从 T 变压器 是的,那个伯特。你可能会问,伯特和疯狂图书馆有什么关系?嗯,就像 X 一代一样,从某种意义上说,伯特是在疯狂图书馆长大的。请允许我澄清…
BERT 是一种语言表示模型——一种将人类语言翻译成计算机可以理解的数学形式的模型,实现了从自动问答到情感分析的各种应用。但是为了表现语言,伯特首先得理解它。那么伯特是如何学习人类语言的呢?正如论文所解释的:
为了训练深度双向表示,我们采用了一种简单的方法,即随机屏蔽一定比例的输入标记,然后只预测那些被屏蔽的标记
BERT learned by reading 11,000 books and all of English Wikipedia
换句话说,伯特通过猜测文本中缺失的单词(“记号”)来学习语言。本质上,伯特玩的是疯狂图书馆,或者至少是前面描述的单人游戏,骗子版本。然而,BERT 也有一个答案(被删除的单词),因此它可以学习预测“正确”的答案。BERT 非常擅长这个练习,因为它重复了数百万次,涵盖了英语维基百科中的所有文本以及 11,000 本书。通过这样做,伯特学会了语言的基本结构,然后可以应用于更有用的任务。
实验
我用一些真实的疯狂库测试了伯特,从神奇的计算机开始,这是一首歌颂大约 1982 年个人计算机最新进展的颂歌:
From Mad Libs #11 (1982)
为了运行 BERT,我们求助于来自 HuggingFace 的优秀的 Python 实现,它构建在深度学习框架 PyTorch 之上。这个库使得我们完成填空任务变得非常容易:
注意,我们严格专注于填空,以及诸如复数名词、身体的一部分等标签。被忽略。
结果
伯特令人惊讶且有些令人不安的解决方案如下所示:
BERT’s solution
看起来 BERT 已经利用了它所有的关于现代计算机的知识:移动设备,亚马逊购物门户,人类替代品,甚至更糟。(注意,用于训练伯特的文本包括 786 部科幻小说,这可能解释了反乌托邦倾向)。
这里有一个更好的例子,表明 BERT 也可以给出更可预测的结果,尽管有时有些夸张:
BERT has strong feelings about sneakers
免责声明:预测一个句子中缺失的单词并不是 BERT 的最终目标;这是伯特利用现有数据学习语言的第一步。通常情况下,BERT 随后会针对特定任务进行微调,例如自动问答。BERT 已经在许多这些最终任务上取得了最先进的成果,所以不要根据它疯狂的库实力来判断 BERT:)
在这里 了解更多关于我的可视化和可解释性工作 。你可以在 Twitter 上找到我@Jesse _ vig。
Apache Spark 大数据之旅:第 1 部分
关于了解 Apache Spark 用于大数据处理的系列文章的第一篇。
我的大数据之旅始于 2018 年 5 月。十多年来,我一直是一名软件工程师,参与并领导了一些 Sky Betting & Gaming 最大的产品和服务的开发。在此期间,我学到了很多关于如何构建和操作可扩展应用程序的知识——从对日志和指标的需求,到性能优化和可维护性。当我被要求成为我们数据部落的工程经理时,我既兴奋又极度紧张——我以前领导过小团队,但对大数据一无所知。所以我决定学!
“你从哪里开始做这样的事情?”这是我经常问自己的问题。大数据生态系统非常庞大。所以我问我团队中的一位首席工程师他们会推荐什么,Apache Spark 是他们的首选。
什么是火花?
从 Apache Spark 网站:
Apache Spark是用于大规模数据处理的统一分析引擎。
用人类的话来说,Spark 是一个分布式计算框架,当查询内存数据集时,它有一个跨多种语言的通用接口,用于 SQL 和 MapReduce 之类的东西。由于是分布式的,Spark 可以在一个机器集群上处理非常大的数据集。
为什么是火花?
从工程角度来看,Spark 有多种语言版本:Scala、Java、Python 和 r。这看起来是一个相当大的胜利,因为它没有限制我们可以租用特定语言的内容。Spark 有自己的 DSL ( 领域特定语言),这在所有实现中都是相同的,这意味着尽管选择了不同的实现语言,但还是有一种通用语言。我们的数据科学团队使用 PySpark 和 Spark 的组合,更广泛的团队使用 Scala——我们让团队(大部分)选择他们自己的工具。
Spark 对数据框架的使用非常适合通常的软件工程和应用程序设计原则,例如单元测试、数据建模、单一责任原则等等。又一次大获全胜。我可以像以前一样继续构建应用程序(我是12 因子原则的忠实粉丝)。
Spark 还附带了一个 SQL 接口,对于大多数曾经需要在某个地方存储和查询数据的程序员/工程师来说,这通常是很熟悉的。
如果你感兴趣的话,Spark 甚至有一个流媒体库。虽然我不会马上这么做(虽然我是 Apache Kafka 的超级粉丝),但它对未来的学习(我想也是商业用例)很有吸引力。
我们开始吧
Apache Spark 似乎令人望而生畏(就像任何新事物一样),我发现自己又在问*“我从哪里开始?”我坚信从头开始理解事物会让你成为更好的工程师。这一点,加上在某个地方实际练习使用 Spark 的需要,引导我构建一个小型本地 Spark 独立集群。*
注:我是 Docker 的忠实粉丝。它为你提供了一种打包方式,并以一种非常便携的方式分发。我需要在自己的机器上安装的惟一依赖项是 Docker 本身。我将在我所有的例子中使用 Docker,所以你可能想从这里的中得到它。我还在运行 OSX,它对 Docker 有一些小的限制,但我们可以解决它们。
我们的首要任务是找到一个合适的包含 Java 版本的 Docker 映像。作为开源软件的粉丝,我选择了使用 OpenJDK。我不是一个膨胀的粉丝,并决定 Alpine Linux 是正确的选择。幸运的是,我们可以使用已经可用的图片。让我们开始创建我们的docker 文件。**
在一个名为 Dockerfile 的空目录下创建一个新文件。在顶部添加以下一行:
*FROM openjdk:8-alpine*
现在我们可以构建我们的映像,它使用 OpenJDK 映像作为基础。通过运行以下命令构建映像:
*docker build .*
这将提取基础图像并创建我们自己的图像版本。您将看到类似于以下输出的内容:
*Successfully built 68ddc890acca*
我们不再在每次构建图像时记录输出散列,这一次我们将标记图像,给它命名以便更容易使用(当然,用您自己的名字替换$MYNAME)。这是对上面的构建命令的一个小小的调整:
*docker build -t $MYNAME/spark:latest .*
现在,我们可以使用我们给它的标签来引用它,而不是使用生成的散列来引用构建的映像。通过使用标签名运行容器进行测试,如下所示:
*docker run -it --rm $MYNAME/spark:latest /bin/sh*
这个图像还没有多大用处,因为它只包含 Java。让我们安装一些实用程序,我们将需要下载和安装 Spark。我们将需要wget
来下载包含 Spark 的归档文件,并需要tar
来从该归档文件中提取文件。我们还需要bash
来管理一些事情。在 Dockerfile 中的新行上,添加以下内容(我们需要包含--update
,这样 Alpine 就有了一个新的存储库列表,可以从中下载二进制文件):
*RUN apk --update add wget tar bash*
现在重建图像并观察wget
、tar
和bash
的安装。
我们现在可以下载并安装 Spark。我们将使用基于 Scala 2.11 和 Hadoop 2.7 的 Spark (2.4.0)的最新版本(不要担心 Hadoop,我们对此不感兴趣…还没有)。将以下内容添加到您的docker 文件中的新行,并进行编译:
*RUN wget [http://apache.mirror.anlx.net/spark/spark-2.4.0/spark-2.4.0-bin-hadoop2.7.tgz](http://apache.mirror.anlx.net/spark/spark-${SPARK_VERSION}/spark-${SPARK_VERSION}-bin-hadoop2.7.tgz)*
Docker 非常聪明,它将重用我们之前构建的层*,所以现在它所要做的就是下载 Spark 归档文件。一旦构建完成,映像将包含 Spark 归档文件,供我们安装。安装就是简单地从档案中提取 Spark 并把它放在一个合适的地方。将另一行添加到 Dockerfile 中,这样做(为了可读性,我将命令分成多行。rm
是简单地清理下载的归档文件)然后构建:*
*RUN tar -xzf spark-2.4.0-bin-hadoop2.7.tgz && \
mv spark-2.4.0-bin-hadoop2.7 /spark && \
rm spark-2.4.0-bin-hadoop2.7.tgz*
恭喜你!现在,您已经在 Docker 映像上下载并安装了 Spark。是时候测试一下了!让我们开始一个容器,并得到一个外壳。注意构建图像结束时的 ID 输出,因为我们现在将使用它。在您的 shell 中运行以下命令:
*docker run --rm -it $MYNAME/spark:latest /bin/sh*
然后我们将在容器内部运行的外壳中结束,用它来启动 Spark Master 。当开始成功启动时,Spark 需要几个选项。这些是主服务器监听的端口、WebUI 的端口和主服务器的主机名:
*/spark/bin/spark-class org.apache.spark.deploy.master.Master --ip `hostname` --port 7077 --webui-port 8080*
希望您应该看到一堆日志输出!如果有,恭喜你!您已经成功开始运行 Spark Master。
下一步是将一些 Worker 添加到集群中,但是首先,我们需要在 Master 上设置一些配置,以便 Worker 可以与它对话。为了使事情变得简单,我们将为 Master 提供一个合适的名称,并公开 Master 端口(最后一个命令中的--port
选项),同时使 WebUI 对我们可用。通过使用 CTRL+C 和 CTRL+D 停止主 shell 并退出容器。现在您应该在本地 shell 中了。只需调整docker run
命令,添加--name
、--hostname
和-p
选项,如下所示,然后运行:
*docker run --rm -it --name spark-master --hostname spark-master \
-p 7077:7077 -p 8080:8080 $MYNAME/spark:latest /bin/sh*
运行docker ps
,您应该看到容器运行时的输出如下(我已经删除了一些输出,以使其适合代码块):
*CONTAINER ID PORTS NAMES
3dfc3a95f7f4 ..:7077->7077/tcp, ..:8080->8080/tcp spark-master*
在容器中,重新运行命令来启动 Spark Master,一旦启动,您应该能够浏览到 http://localhost:8080 并看到集群的 WebUi,如下图所示。
Spark Master WebUI
添加工作节点
正如我提到的,我正在使用 Docker for Mac,这使得 DNS 很麻烦,并且如果不运行本地 VPN 服务器或其他东西来解决这个问题,通过 IP 访问容器几乎是不可能的——这超出了本文的范围。幸运的是,Docker 有自己的网络功能(具体细节也不在本文讨论范围之内),我们将用它来为本地集群创建一个网络。创建网络非常简单,只需运行以下命令:
*docker network create spark_network*
我们不需要指定任何特定的选项,因为默认选项对我们的用例来说已经很好了。现在,我们需要重新创建我们的主服务器,以将其连接到新网络。运行docker stop spark-master
和docker rm spark-master
删除当前运行主机的实例*。要在新网络上重新创建主服务器,我们可以简单地将--network
选项添加到docker run
,如下所示:*
*docker run --rm -it --name spark-master --hostname spark-master \
-p 7077:7077 -p 8080:8080 --network spark_network \
$MYNAME/spark:latest /bin/sh*
这与我们第一次运行 Spark Master 时没有什么不同,只是它使用了一个新定义的网络,我们可以使用这个网络来连接工作人员,以使集群工作👍。现在主节点已经启动并运行,让我们向它添加一个 Worker 节点。这就是 Docker 的魔力真正闪耀的地方。要创建一个 Worker 并将其添加到集群中,我们只需启动同一个 docker 映像的新实例并运行命令来启动 Worker。我们需要给这个工作者一个新的名字,但是除了这个命令之外,其他的基本保持不变:
*docker run --rm -it --name spark-worker --hostname spark-worker \
--network spark_network \
$MYNAME/spark:latest /bin/sh*
要在容器上启动 Spark Worker,我们只需运行:
*/spark/bin/spark-class org.apache.spark.deploy.worker.Worker \
--webui-port 8080 spark://spark-master:7077*
当它启动并连接到主机时,您应该看到输出的最后一行:
*INFO Worker:54 - Successfully registered with master spark://spark-master:7077*
主服务器将输出以下行:
*INFO Master:54 - Registering worker 172.21.0.2:37013 with 4 cores, 1024.0 MB RAM*
恭喜你!您已经使用 Docker 设置了一个 Spark 集群!
但是这有用吗?
为了检查它是否工作,我们可以加载主 WebUI,我们应该看到 Worker 节点列在“Workers”部分下,但这实际上只是确认了将 Worker 连接到主 WebUI 的日志输出。
Spark Master WebUI with Worker
为了进行真正的测试,我们需要在集群中实际运行一些 Spark 代码。让我们运行 docker 映像的一个新实例,这样我们就可以运行安装 Spark 时提供的一个示例。同样,我们可以重用现有的 docker 映像,并简单地启动一个新的实例,用作驱动程序(向集群提交应用程序的东西)。这个不需要--hostname
、--name
和-p
选项:**
**docker run --rm -it --network spark_network \
$MYNAME/spark:latest /bin/sh**
在容器中,我们可以通过运行以下命令向集群提交应用程序:
**/spark/bin/spark-submit --master spark://spark-master:7077 --class \
org.apache.spark.examples.SparkPi \
/spark/examples/jars/spark-examples_2.11-2.4.0.jar 1000**
提供的示例计算出哪个 Pi 正在使用集群。
当应用程序运行时,您应该能够在 Spark Master WebUI 中看到:
Spark Master WebUI — Running Application
完成后,您将在日志中看到 Pi 输出的值:
**Pi is roughly 3.1414459514144597**
您还会在 WebUI 中看到完整的应用程序报告:
Spark Master WebUI — Completed Application
用 Docker Compose 把它钩在一起
Docker Compose 是 Docker 提供的一个简洁的工具,我们可以将其用作编排工具,这样我们就不必自己在许多终端窗口中运行命令了。我们本质上是将各种命令缝合在一起,并将一些东西参数化,这意味着我们可以简单地运行docker-compose up
,集群就开始运行了。
为了实现这一点,我们可以创建一些脚本来复制到映像并在容器启动时运行。我们将创建的第一个是设置 Spark Master。创建一个名为start-master.sh
的新文件,并添加以下命令:
**#!/bin/sh/spark/bin/spark-class org.apache.spark.deploy.master.Master \
--ip $SPARK_LOCAL_IP \
--port $SPARK_MASTER_PORT \
--webui-port $SPARK_MASTER_WEBUI_PORT**
我们没有在脚本中直接指定 IP、Master 和 WebUI 端口,而是将它们参数化,这意味着我们可以将它们作为环境变量提供。从而在主设备监听的配置(端口)方面提供了更大的灵活性。要将脚本放到图像上,我们需要复制它。然而,在此之前,我们需要确保脚本是可执行的。只要运行chmod +x start-worker.sh
就可以了。现在将脚本添加到图像中,在最后一个RUN
命令下面的 Dockerfile 中,添加以下内容:
**COPY start-master.sh /start-master.sh**
在我们重新构建映像之前,我们也将为 Worker 创建一个类似的脚本。创建一个名为start-worker.sh
的新文件,并添加以下命令:
**#!/bin/sh/spark/bin/spark-class org.apache.spark.deploy.worker.Worker \
--webui-port $SPARK_WORKER_WEBUI_PORT \
$SPARK_MASTER**
同样,我们已经对配置进行了参数化,以提供更大的灵活性。使新脚本可执行(chmod +x start-worker.sh
),并在 Dockerfile 中添加另一个COPY
行,以将脚本添加到图像中:
**COPY start-worker.sh /start-worker.sh**
重建并运行。如果一切顺利,您将进入容器中的一个 shell,该容器中的脚本位于文件系统的根目录中:
**bash-4.4# pwd
/
bash-4.4# ls -l
total 72
...
-rwxr-xr-x 1 root root 357 Dec 6 11:56 start-master.sh
-rwxr-xr-x 1 root root 284 Dec 6 17:10 start-worker.sh
...**
回来后,我们将使用docker-compose
来编排集群。
创建一个名为docker-compose.yml
的新文件,并输入以下内容:
**version: "3.3"
services:
spark-master:
image: $MYNAME/spark:latest
container_name: spark-master
hostname: spark-master
ports:
- "8080:8080"
- "7077:7077"
networks:
- spark-network
environment:
- "SPARK_LOCAL_IP=spark-master"
- "SPARK_MASTER_PORT=7077"
- "SPARK_MASTER_WEBUI_PORT=8080"
command: "/start-master.sh"
spark-worker:
image: $MYNAME/spark:latest
depends_on:
- spark-master
ports:
- 8080
networks:
- spark-network
environment:
- "SPARK_MASTER=spark://spark-master:7077"
- "SPARK_WORKER_WEBUI_PORT=8080"
command: "/start-worker.sh"
networks:
spark-network:
driver: bridge
ipam:
driver: default**
我们在这里所做的就是指定要使用的映像名,设置主机名和容器名,显示正确的端口并连接到我们在底部创建的网络,设置一些环境配置和启动时要运行的命令。我们还将 Worker 设置为依赖于正在运行的主服务器。
要启动集群,我们只需运行docker-compose up
。Docker Compose 的一个优点是,我们可以通过简单地在 Compose 命令中添加一个--scale
选项来扩展 Workers。假设我们需要 3 个工作节点,我们运行:
**docker-compose up --scale spark-worker=3**
就这样。我们完了。下次我们开始学习在 Scala 中构建我们自己的应用程序时,请继续收听。
监督机器学习之旅
关于监督式 ML 的一些实例、提示和想法
今年早些时候,通过我在康乃尔理工的 MBA 项目,我和一位了不起的教授卢茨·芬格一起上了一堂很棒的机器学习入门课。Lutz 的课程激励我更深入地挖掘 ML 和 AI,所以我最近在 Udacity 上开始了一个动手操作的机器学习课程,我觉得这会很好地增加我的背景。到目前为止,我已经完成了关于监督学习的部分,并希望分享我的初学者对我所学到的东西的看法,并思考这项技术的潜在影响。
你可以在这里 的课程/项目中找到我的 python 文件。相关文件夹为choose_your_own, decision_tree, naive_bayes, and svm
监督学习概述
监督学习是机器学习任务,它学习基于示例输入-输出对将输入映射到输出的函数(Stuart J. Russell,Peter Norvig (2010) 人工智能:一种现代方法 )
我觉得这个定义相当直观;该算法从“监督”历史动作/数据点中学习以产生输出。在监督机器学习中,有几十种不同的方法,但我最近的研究集中在朴素贝叶斯、支持向量机(SVM)、决策树和随机森林,然后进一步讨论如何在 Python/ scikit-learn 中使用这些算法。
我不会在这里重复每种方法的细节,但是如果你想要一个概述,我建议你参加这个课程或者浏览 Google 了解细节。但是,我确实想指出一些重要的经验,以及我如何看待这些经验对我未来发展的影响。
监督/课程外卖
与任何数据驱动方法一样,数据质量和结构对受监督模型输出的有用性有着巨大的影响。这并不令人惊讶,但令人惊讶的是,为了改进模型或性能,可以修改传入数据的方式有多种。虽然我没有太深入地研究功能选择/工程,但简单地处理数据量以及测试与训练数据的比例对准确性、性能和潜在的过度拟合有着巨大的影响。
至少从我初学者的角度来看,Scikit-learn (sklearn)非常容易使用。对于每种算法(不包括导入),只需 4 行代码即可训练、预测和计算模型的精度。这显然也忽略了之前发生的所有数据准备工作以及在初次运行之后发生的调整工作,但是通过这种简单的方式,在同一数据集上运行许多不同的模型是很快的。这使您有机会对同一数据尝试许多不同的模型,帮助您找到解决问题的正确方法。当我把我的工作从 PyCharm 转移到 Jupyter 笔记本电脑时,对同一数据运行许多不同的模型变得更加容易。
通过在同一数据集上创建和运行多个模型的练习,可以很容易地用各种各样的参数调整模型。幸运的是,Sklearn 和 Juypter 的结合使得这个游戏非常容易玩。我也没有使用大量的数据集,所以迭代相当快。正是在这一步,我开始看到经营这些模型的艺术方面。要在准确性、速度和可推广性之间取得适当的平衡,需要调整各种模型和数据方面。就过度拟合数据集的倾向而言,我所研究的每一个模型都有不同的弱点,但每一个都有独特的属性来防止这种情况。例如,使用 SVM,您可以调整 C 和 Gamma 级别以直接平衡分类边界,从而提高准确性和泛化能力。
分析文本识别数据
我想在野外发现的数据集上测试我所学的东西,所以我从加州大学欧文分校下载了字母识别数据集以供使用。数据集包含在一个文本文件中,其中包含 16 个代表扫描信件图像的标准化数字特征。然后,它会提供相应的标签。数据集相当简单,试图将这些数据点分类成不同的字母似乎是数据的一个很好的用例。
从这个分析代码中可以发现 在这里
我首先将数据读入 Pandas 数据帧,研究一些数据点,然后将它们作为 NumPy 数组分成要素和标签。除了非常容易从数据帧中分离出数组之外,我还发现了另一个非常酷的 Sklearn 模块preprocessing
,它允许我在一行中缩放特性的值。我后来发现,由于我的数据集相当小(~20k 行),预处理最终只为我节省了几秒钟的训练和预测时间,但在处理更大的数据集时,这似乎是一个有用的步骤。最后,我使用 Sklearn 的train_test_split
来创建我的训练和测试数据集,分别利用默认的 75%-25%分割。
我的下一步是根据我的问题/数据考虑我想尝试的模型类型。我知道我需要擅长分类的东西,可以在相当多的维度上分离数据,不需要超快,并且有参数来控制拟合。对我来说,SMV 和 Random Forest 符合这里的要求,所以我继续测试它们。
支持向量机
我在 SVM 的第一次测试获得了 94.6%的准确率,训练和预测总共只花了 4.5 秒。我认为这已经很不错了,但我继续调整一些参数,看看是否能提高精度。用kernel
和C
参数做实验,我能够得到超过 97%的准确率。将 C 值提高到 1000 似乎给了我最大的准确性提升,而内核似乎没有太多积极的影响(这是我需要进一步研究的)。内核的另一个奇特之处是,其中一些内核,如 sigmoid 内核,将精确度降低到了 43.44%。我不太精通如何应用“内核技巧”,所以这对于我来说可能比那些了解内核的人更有意思。
Training time: 2.0 s
Prediction time: 1.484 s
Accuracy 0.9718
对于其他数据集,我发现 SVM 非常慢,但由于这个数据集较小且没有时间限制,SVM 证明是一个很好的选择。随着时间的推移,我想做更多的验证,以确保我的模型不会过度拟合,并看看我是否可以通过调整伽马来提高准确性。
随机森林
我想尝试的另一个模型是随机森林。我过去曾使用决策树将数据分类成组,因此一个健壮的随机森林似乎是迎接这一挑战的一大进步。默认的射频分类器返回了 93.36%的准确率,但只用了 0.197 秒,明显快于 SVM。我首先尝试将min_samples_split
修改为 25,然而这只会降低我的精确度。不知道为什么,我转向了n_estimators
值,我首先将其更新为 200。这使我的准确率提高到了 96.4%,但总的训练/预测时间增加到了 3.5 秒,仍然比 SVM 快。最后,我试着将n_estimators
提高到 1000,精度提高了 0.2%,但时间增加了 11 秒。为了改进 RF,我希望花时间调整或加权特征,并研究样本分割如何改进模型。
Training time: 2.998 s
Prediction time: 0.275 s
Accuracy 0.9692
按照我的标准,这两个模型似乎都表现得很好,但每次运行都会引发不同的问题。这些意想不到的结果使得 ML 成为一个有趣的话题,激发了许多人对这个主题的好奇心!
如果可以,应该吗?
在一个以技术为重点的大学校园里,我每天都会听到很多次“我们使用机器学习来做 x ”,通常我认为这是一件好事,但在应用这些工具之前,我们需要更加批判性地思考。我之前提到过 Sklearn“非常容易”使用,在某种程度上,我确实认为“预测”一个结果就像它这么容易有点儿可怕。人们抓住了使用 ML 的想法和它在某些情况下的强大力量,但是他们忘记了考虑正在做出的决策的含义或答案的有效性。仅仅因为我们能做到,我们就需要停下来想想我们是否应该做到。
感谢阅读!
生产力例行程序之旅
这一切都是从我搬到马德里开始的。
“Downtown”, Puebla, Mex. Image credit: Sheila Montes
零点
我从小就渴望知识。学习我感兴趣的东西给了我一种完整的感觉。然而,碰到我对一个主题的理解的极限是许多深刻的内部反思的原因。
我决定攻读“大数据和商业智能”硕士学位,因为我来自一个完全不同的非技术领域。这是一个巨大的挑战。
我心中只有一个明确的目标: 强势完成我的程序。我 几乎感觉自己像一匹眼睛被半遮着的赛马;刚好能看清前面是什么。因为当你下定决心要冲过终点线的时候,其他事情都不重要。
一些灵感
就像重力一样。拥有一个包罗万象的动机变得显而易见,最终,就像重力一样,对像你一样的人有一种明显的吸引力。在那里,我与一位巴拉圭软件工程师合作,他的友谊我至今仍珍视。
黄金法则:找到和你一样的人…或者有引力或者
第一次常规尝试。
拼命学习,爱上田野。
新的国家,新的习惯,新的人,新的旅程开始了。
随着日子一天天过去,你会开始有时间感;日常活动、周末、天气、你什么时候做饭、你什么时候买杂货、锻炼或者给家人打电话。这个清单可以一直列下去,所以我的第一课是:
**试错:**好的套路是在几次尝试之后出现的
我有一份兼职工作,所以时间优化是关键。
冬天的时候,我在早上 8 点左右醒来,刚好够早喝上一杯咖啡。我可以带着我的 iPad 在上班的路上学习。幸运的是,我的工作是在商学院关注学生的需求,并为即将到来的学术课程提案做研究。第二部分很美好,我可以研究我的笔记,阅读与我的领域相关的论文和文章。
午餐结束后,我返回火车去上课,在那 40 分钟的旅途中,更多的是同样的事情;Ipad 和 10 多张幻灯片。多亏了至少 3 杯咖啡,有时还有红牛,还有溅在我脸上的冷水,我总能在 7 个小时的讲座中保持专注。我在课堂上喝饮料,这样当休息时间开始时,我可以学习,和我的教授交谈,或者和我的同事讨论课程。
夜幕降临时,他们得到了应得的休息。我只是在回家的路上欣赏我的音乐,健身,为第二天做饭,给家人打电话。
环境决定一切
My temple of study in my 4x4 room
第二次常规尝试。
实习,SQL 和绘图。
夏天敲响了我们的门,人们向南方迁移,去西班牙最美丽的地中海海滩。我也在打包行李,但我的目的地是北方,比利牛斯山附近的一个小城市,在那里我在一家小型科技咨询公司实习了 4 个月。
我早上 6 点左右醒来,天气非常适合跑步,城市空无一人。一顿丰盛的早餐,洗个冷水澡,然后去上班。
这些是我学到的最有价值的经验:
- 。通常会有很多工作要做,因此保持高效率很有价值
- 时间管理至关重要。 我看到项目经理在开 3 分钟的会!
- *宁静高于一切 *。有一天,我陪着首席运营官去拜访一个客户。总经理和其他 4 名高级员工开始对该项目提出许多抱怨和质疑。他认真听取了每个人的意见,然后开始以更健康、更有成效的方式引导会议。每个人都微笑着离开了房间
- SQL,你只要学会就行了。 你懂 SQL?我被问到的第一个问题。然后我意识到它可以成为你完成第一课的最好的朋友。
当我到家的时候,已经快 8 点了,仍然是晴朗无云的天空,正准备进行另一次跑步。我在工作中投入了很多精力,但我想做得更多,所以我重拾了童年时擅长的一个老习惯,画画。我买了一个全新的笔记本和木炭,开始在我的工作室画画。周末的时候,我会去公园阅读佩德罗·多明戈斯的《大师算法》。这本书给了我继续学习的力量。佩德罗采用故事的方式来谈论机器学习,指出它的历史、未来以及它如何影响我们的生活。
Image source: Pixabay
第三次常规尝试
课本、MOOCS、播客、Python、SAS 和我缺乏编程技能。
这是 2017 年初,回到马德里,另一场冒险即将开始。这个叫做风险管理。
是的,我在银行工作。
事实证明,这是我经历过的最长的通勤时间,每天坐地铁两个小时甚至更多。
是时候想想如何以富有成效的方式度过这 10 个小时了!
我早上 6:30 左右醒来,去喝咖啡吃早餐。我不得不在 7:45 离开家,这样我可以在 9:00 到达。在我上班的路上,我混合阅读和播客,主要是中型和 KDnuggets 文章。在播客中找到大量与数据科学相关的内容真是太棒了。奇怪的是,除了音乐之外,我从来没有消费过音频内容,所以坐上地铁开始听确实非常令人兴奋,我最喜欢的播客是:
- 我和克里斯和维迪亚一起笑得很开心。学习机器学习给我留下了印象,除了被介绍到一个精选的学习机器学习的书籍列表。我认同克里斯的个人经历。
- 机器学习指南ML 算法的一些严肃音频学习
- O’Reilly 数据显示与像 Paco Nathan 这样的高级嘉宾进行超级有趣的谈话。
SAS 是我在工作中第一次真正接触编程。了解 SQL 的基础知识对我帮助很大。我不想撒谎,每次我在 SAS 编辑器里写东西的时候,我都觉得自己是个坏蛋。我主要做的是编写脚本来自动化报告、风险研究的数据挖掘,以及其他一些很酷的事情,比如试图解决金融世界中的数学悖论。
为什么
我编程的所有这些分析。它们是干什么用的?他们给公司带来价值了吗?可视化足够简单来解释数据吗?
在我进入银行的早期,我的老板找到我,告诉我要阅读大量的文档,主要是为了理解风险管理背后的艺术以及我们做事的原因。他告诉我“为什么”比“如何”重要得多,换句话说,首先要了解业务逻辑,编程可以在过程中学习。
黄金教训:从那以后,我在工作时总是问自己同样的问题。
经过几个月的锻炼和每天的学习后,只剩下非常有限的时间来做基础训练;洗衣服,打扫卫生,吃饭,准备第二天的饭菜。所以我决定减少一点日常活动的强度,一周锻炼两三天,其余时间直接回家学习。
有几天,我呆在办公室里,预订了一间会议室,主要是学习认知课程,阅读福斯特教务长汤姆·福西特的《T2 商业数据科学:你需要了解的数据挖掘和数据分析思维》。
当我深入 DS 时。我意识到 Python 在社区中是多么强大。自从我在硕士时学习 R,我就决定一直学习 Python。
Image credit: Emlie Perron
我从 Udemy 的课程和教材开始,这些帮助我理解了基本原理。虽然我对 Python 代码的美丽感到高兴,但它变得难以理解,可能是因为我的注意力集中在机器学习上。我认为,如果我想掌握 ML 代码,我首先必须真正精通 Python。我猜这只是我太固执了,但是一旦我学会了最基本的,我就直接去买了塞巴斯蒂安·拉什卡的 Python 机器学习。
一本成为我生命中真正宝藏的书。感谢塞巴斯蒂安。
“Python 机器学习”在这篇文章中值得一提。这是一本写得很好的漂亮的书,指导你通过机器学习工作流程的每个方面。方程令人惊讶地解释到最后的细节,所以你可以欣赏数学和代码之间的共生关系。在比你想象的更短的时间内,你将对复杂的算法有深刻的理解
机器学习的夏天。
这是我从克里斯·阿尔邦那里得到的一个想法。关于我的学习,这基本上是我给自己提出的一系列目标。除此之外,我还建立了一些不同的目标,比如 80 小时的游泳和跑步,以更健康的方式改善我的生活。
我有一个很酷的学习组合;阅读“Python 机器学习”和 Coursera 吴恩达课程。这种方法给了我宝贵的见解。我终于开始学习 Python 中的 ML 代码,并将其与 Andrew 完美的教学方式相结合。而且,因为我对数学充满了冒险精神,所以我抓住了统计学习的要素。如果我不理解代码的逻辑,我会回到那些 Udemy 课程和 Python 教科书。
2017 年夏天,我就在那里。在 Google Drive 电子表格中记录我的进展,并记下这样的笔记:
***2017 年 6 月 26 日。*与吴恩达一起复习线性代数。抽认卡很有帮助!
2017 年 12 月 7 日。 “开始领悟感知机背后的数学。对向量和矩阵感到舒适”**
2017 年 7 月 23 日。“周末休息。跟我姑娘吃印度菜!”
2017 年 7 月 31 日。“决策树和随机森林。40 分钟游泳,需要改善身材!”
2017 年 8 月 3 日。“神经网络,迄今为止最复杂的算法。旧笔记学习;EDA、二维分析、正态性检验和假设对比”
2017 年 12 月 8 日。“去巴塞罗那!”
我现在在哪里?
我是一家大型电信公司的全职数据分析师。
一路上,我生活中的事情发生了变化,有更多的时间做这个,更少的时间做那个。
我的学习永远不会停止。
我正在做我自己的数据科学作品集。
“Python 机器学习”依然是我每次有项目的左右手。
总是阅读数据科学
现在我是一个新播客的忠实粉丝;数据框
我最近偶然发现了罗伯特·张和他的博客。太棒了!
我总是知道这些人要说些什么:塞巴斯蒂安·拉什卡、克里斯·阿尔邦、弗朗索瓦·乔莱、法维奥·瓦斯奎兹、西拉杰·对手、克里斯·奥拉赫、吴恩达、艾伦·唐尼、李飞飞、伊恩·古德菲勒
我仍然尽可能参加每一个数据科学聚会
现在,我开始写作了。希望一切顺利。
我想感谢 Amy Kelly 审阅我的帖子并给我反馈
外行人的算法丛林指南
这是一系列文章中的第三篇,旨在使机器学习对那些没有受过技术培训的人来说更容易理解。以前的文章介绍了机器学习的概念,并讨论了学习过程的一般工作方式。你可以在这里开始系列。
这一期描述了许多常用的机器学习算法家族。这个列表并不详尽,主要集中在两类分类算法上(我最熟悉的)。描述旨在简洁而直观,面向不熟练或没有经验的读者。提供了每个算法家族的简要描述和说明,以及每个家族的一些算法示例。为这些算法的更详细的数学处理和发现更多,提供了进一步的阅读清单。
朴素贝叶斯分类器
朴素贝叶斯分类器是基于相当简单的原理的分类算法家族。这些算法学习哪些输入属性具有与感兴趣的类相关联的高概率和低概率,然后基于这些属性概率计算实例是否属于某个类。例如,如果机动车辆有两个轮子,长度在 1900 毫米和 2500 毫米之间,宽度在 700 毫米和 1000 毫米之间,则可以归类为摩托车。
朴素贝叶斯分类器之所以被称为朴素贝叶斯分类器,是因为统计假设每个变量相互独立,尽管在实践中很少出现这种情况,例如车轮的数量通常与宽度相关。
通常,这些算法需要相对少量的数据来估计参数,这被认为是一个优点。然而,由于底层数学模型的简单性,这些算法通常优于其他算法。
这类算法最早也是最常见的用途之一是文本过滤。在垃圾邮件过滤中,可以基于在电子邮件中发现的某个单词、单词组合或随机文本串将电子邮件分类为垃圾邮件。以类似的方式,这些算法可以用于将文档分类到不同的主题类别中。
有许多替代算法试图克服朴素贝叶斯分类器的独立性假设。最有力的例子之一是平均一相依估计量(AODE),它通常可以产生比朴素贝叶斯更低的误差水平,而只需要适度的额外计算能力。
决策树算法
这是一个使用决策树原理运行的大算法家族,并且已知在许多情况下非常成功。这些算法根据基于实例属性做出的一系列决策(分支)将实例分类到某个类(叶)中。
例如,下图是一个简单的决策树算法,用于根据三个输入(性别、年龄和船上兄弟姐妹和配偶的数量)确定泰坦尼克号上的乘客发生了什么。每片叶子下面的数字代表存活的概率和属于该类的实例的百分比:
Example decision tree for survival of Titanic passengers
决策树算法使用自上而下的归纳学习,通常被称为贪婪算法*(因为它总是决定获取最大份额)。从每个类(叶)开始,根据输入数据是否与该类相关联,将输入数据分成子集。然后,在称为递归划分的过程中,在每个子集(或决策节点)上重复这一过程。当算法到达对分割数据没有进一步价值的决策节点时,学习停止。在我们的泰坦尼克号的例子中,算法将在男性和女性之间分割数据,然后它将确定分割女性数据没有进一步的价值。然后,它将确定首先根据年龄,然后根据 sibsp,拆分男性数据是有价值的。*
决策树算法是健壮的,易于解释,并且可以很好地处理大型数据集。然而,有许多问题它们无法解决,因为底层数据太复杂了。这些算法还可能倾向于从训练数据中创建过于复杂的树,这些树不能很好地概括,最终会过度拟合数据。在某些情况下,可以回过头来简化树。这就是所谓的修剪*。*
基于决策树方法的算法示例包括装袋树*、随机森林和提升树。*
支持向量机
支持向量机是基于多维线性代数原理的非概率算法。这些算法非常适合将样本分为两类的二元问题,并且在输入数据的结构有限时特别有用。
SVM 算法获取数据集中实例的属性,并将这些属性转换成 n 维空间中的向量,其形式为 X = (x1,x2,x3,…,xn) 。
然后,该算法将尝试计算 n 维空间中的超平面或“线”,该超平面或“线”以可能的最大距离分隔两个类别。
下面是一个简单的二维例子。在本例中,位于虚线边缘的向量称为支持向量,用于计算最大分离线,用实线标记。
现代 SVM 算法能够通过挖掘文本串并识别可用于对样本进行分类的文本子集和家族来确定维度和属性的数量。维度,也就是向量长度,可以是数百甚至数千。对这种数据执行计算的复杂性可以非常容易且快速地超越可用计算能力的极限。然而,现代 SVM 算法利用了一个核函数,可以大大降低问题的复杂性。
当训练集不容易线性分离(即,不可能识别分离的超平面)时,线性 SVM 的多种发展已经导致了许多可选方案。例如,软边界可用于某些数据可能被错误分类的情况。最近也有一些算法发展了 SVM 原理,使其适用于两个以上的类,以及非线性和回归问题。
感知器
与 SVM 类似,感知器算法通过将输入属性转换成形式为 X = (x1,x2,x3,…,xn) 的向量来运行。对于训练集中的每个实例,该算法计算权重向量 W = (w1,w2,w3,…,wn) 以形成线性预测函数 W.X,该函数正确预测所有先前的训练集实例。
与大多数其他算法不同,感知器执行在线学习*,这意味着它逐个分析每个训练实例,并在处理每个实例后更新权重向量 W,而不是必须先处理所有实例。与其他算法相比,这可以更加高效和精简。*
然而,如果训练集是线性可分的,感知器算法将仅收敛于权重向量 W。如果不存在将训练数据中的正样本与负样本分开的超平面,则该算法将不能收敛到将正确分类所有训练集样本的 W 上。
感知器的变体可以用来处理多类问题,甚至非线性问题。袖珍算法是一个潜在有用的变体,它处理非线性可分离的训练数据。在处理每个训练实例时,该算法会将迄今为止看到的最佳解决方案保存在“口袋”中。在每个实例中,算法返回“口袋”解,而不是最后一个解,这允许它迭代到训练集上误差最小的解。
神经网络
神经网络算法是目前使用的最复杂的算法之一。它们模仿大脑中神经元的结构,并且它们被设计成以与大脑相似的方式学习。它们通常没有预先设定任何规则,而是通过处理示例来学习。
图像识别是经常使用神经网络的一个常见例子。例如,可以向网络提供狗的图像集合,并告知每只狗的品种。然后,它可以学习狗图像的特征,这允许它预测给它的新图像的品种。
Hey computer — here’s some nice doggy pictures!
人们很自然会问计算机如何模拟神经元网络。实际上,“神经元”之间的信号通常是某种形式的数字,而“神经元”本身是某种数学函数,它处理它接收的信号并吐出新的数字——所以实际上这些算法在数学上模拟了神经元网络的信号到节点的行为。
进一步阅读
我在这里仅仅触及了表面,但是我已经涵盖了你可能听说过的分类算法的主要类别。如果你想真正进入令人愉快的算法世界,比如 BLAST 、 nauty 、 Saucy 或 Mersenne Twister (是的,它们都是算法名称),这里有几个地方你可以看看。请自担风险,尤其是如果你不是数学家、统计学家或计算机科学家。
- 机器学习介绍,Ethem Alpaydin,ISBN 0262028182。这是一本非常好的关于机器学习的宽泛的文本,涵盖了广泛的主题。它是大学课程中非常常见的教材。
- 机器学习:使数据有意义的算法的艺术和科学,彼得·弗拉克,ISBN 1107422221。这是一个非常实际的话题,用具体的例子来说明算法是如何运作的。
- 机器学习基础,Mehryar Mohri 等人,ISBN 026201825X。这本书理论性很强,重点是关键概念的证明。它还涵盖了几种常见的 ML 算法的数学基础。
- 机器学习,概率视角,凯文·P·墨菲,ISBN 0262018020。这本书很好地融合了理论(尤其是概率和统计)和实践,有算法代码的例子和大量插图。
- 信息论、推理和学习算法,大卫·麦凯,ISBN 0521642981。这本书的重点是科学和工程目的的编码。然而,在填字游戏和生物进化的算法上有一些有趣的消遣。
- 统计学习、数据挖掘、推理和预测的要素,特雷弗·哈斯蒂,ISBN 0387848576。一个学术文本,侧重于将与机器学习相关的各种概念结合到一个统计框架中。
- 信息检索简介,克里斯托弗·D·曼宁等,ISBN 0521865719。这本书集中在与文本分类和聚类相关的应用。
最初我是一名纯粹的数学家,后来我成为了一名心理计量学家和数据科学家。我热衷于将所有这些学科的严谨性应用到复杂的人的问题上。我也是一个编码极客和日本 RPG 的超级粉丝。在LinkedIn或Twitter上找我。
计算机视觉外行指南
我今天刚刚在 arXiv 上发现了这个新发表的研究,我认为它非常酷。这是对机器学习未来的迷人一瞥,虽然我已经期待了一段时间,但最终看到一些坚实的研究是惊人的!它基本上是使用遗传算法进化出一串卷积神经网络来创建一个用于图像分类的最优网络。解释我到底在说什么,继续读!
A bunch of animals.
假设我们收集了各种动物的照片,我们想知道每张照片里都有什么。借助我们自己的眼睛、大脑和记忆,我们能做的最基本的事情就是看一张照片,看到它是一只狗的照片,并把它贴上“狗”的标签。对于一台电脑来说,完成同样的任务是一个非常棘手的过程。
几十年前,计算机科学家试图通过构建一个配方来检测个体特征,并将它们放在一起预测照片所描绘的内容,从而以编程方式识别图像。例如,狗有毛皮,长鼻子,大眼睛,长舌头,长尾巴,等等。猫的皮毛较少,脸较圆,眼睛较小,鼻子较平。如果你在照片中找到这些特征,那一定是猫/狗/袋鼠。正如您可能想象的那样,这种技术几乎不起作用。如果照片是从另一个角度拍摄的,这个食谱就没有意义了。每只动物都需要自己特定的食谱来检测,不同的品种或蓬头垢面的宠物将无法识别,它的规模也不太好。这项技术开发费用昂贵,而且在实践中也没有用。
A car hiding in a tree
快进十年左右,科学家们试图将这个过程概括一下。他们将检测圆形,而不是检测鼻子。他们将检测线条或特定图案,而不是皮毛。然后,这些特征的组合将被用于更具预测性。这种方法效果更好,但它仍然需要手动编程来检测特定的形状和特征。它也不总是成功的,有时会令人印象深刻地失败。
然后在 1998 年,一种叫做卷积神经网络(CNN)的全新技术问世了,它试图模仿我们的大脑处理图像的方式。取代手动选择要检测的特征,这些特征将由计算机通过输入大量图像和正确的标签来自动“学习”。然后计算机程序会计算出哪些特征是最重要的,并用它们对照片进行分类。这些特征基本上是简单的数学滤波器,图像通过这些滤波器将其结构简化为关键部分。通过使用多层特征,可以检测更复杂的对象。下面,你可以看到这样一个程序是如何工作的。在第一层中,检测基本形状。在第二种情况下,这些形状被组合起来构建更复杂的形状,比如眼睛和鼻子。最后,在第三层,这些被组合成更高层次的物体,如人脸!
Feature map in a modern CNN
虽然 1998 年开发的 CNN 非常成功,特别是在诸如手写识别等任务方面,但它确实需要巨大的处理能力和大量的训练数据,这两项要求在 1999 年无法轻易满足。因此,在十多年的时间里,当人们继续手动定义特性时,这项技术实际上被搁置了。
最终在 2012 年,大学的研究人员。创建了 AlexNet 。它使用了与原始 CNN 相同的技术,做了一些改动,但是使用了更多的图片。AlexNet 不是几千幅,而是在 1500 万幅图像上进行训练。它不只是几个过滤器,而是计算出数百个。它一发布就把竞争对手扫地出门了。所有程序员现在要做的就是设计网络的基本流程,选择构建模块,神经网络会解决剩下的问题。
在 30 年的时间里,计算机视觉技术进步缓慢,但 AlexNet 改变了这一切。在 2012 年之前,每 4 张图像中就有 1 张被错误识别。AlexNet 将这一比例降低到每 7 天 1 次。从那以后,每 25 张图片中就有 1 张是错误的(例如在谷歌的 Inception 网络中)。那精准度其实比绝大多数人类都强!这就引出了这篇论文。
Google’s Inception V3 network. State-of-the-art in image classification, for now.
过去五年的所有改进都归结于对神经网络的轻微调整,要么通过添加新的数学函数,改变滤波器的顺序和组合,要么增加滤波器捕捉的细节水平。这些“宏参数”可以不断调整以获得最佳结果,但它们需要一点直觉才能正确。本文中的研究人员决定将最后一步自动化。
Relevant XKCD (CC-by-SA-NC Randall Munroe)
他们没有繁琐地设计一个新网络,手动组合不同的功能和过滤器,而是简单地给遗传机器学习算法一个任务——最小化识别误差——并给它提供积木。然后他们让它在一台高速电脑上运行几周。它继续,建立一个基本的神经网络,并计算其图像识别的误差。然后,它进行一些更改,并计算一个新的错误。如果误差较低,则采用该设计,以此类推。事实上,它的改进很像生物进化,通过突变、繁殖和生存。
如果你真的一直读到这篇很长的帖子的结尾,那么感谢你的阅读!毫无疑问,你仍然会奇怪为什么我觉得这很酷。原因是这篇论文不仅揭示了我们(嗯……聪明的男人和女人)在人工智能方面已经走了多远,而且揭示了我们的世界在未来将如何被它塑造。我们正处于这样一个时刻,像我这样的笨猴子可以玩弄困扰数千研究人员几十年的技术。一个拥有 1000 英镑并且事先没有人工智能知识的人可以实现过去花费数百万研究小时的事情。我们所需要的只是一个数据集和一个聪明的想法,我们可以让人工智能做艰苦的工作!我认为这既令人印象深刻又相当可怕!我们还没有到那一步,但总有一天人工智能会取代创造它们的计算机科学家,所以现在就开始为未来做计划是明智的。
在不太遥远的未来,我可以想象一个场景,任何想要制作自己电影的人都可以简单地编写一个带有一些线索和风格元素的电影剧本,将其传递给人工智能,然后人工智能自动创建配乐,合成语音,指导一系列 3d 生成的模型,添加一些特殊效果,并呈现一部完整的照片级逼真的电影。如果有些地方不太对劲,你可以进去调整一下。当胶片相机在 19 世纪 80 年代被发明时,人们没有预测到它会变得如此普遍。当电吉他被发明出来的时候,工程师们尽了最大的努力去消除它所造成的失真,然而今天的摇滚乐就是建立在这样的基础上的。关于人工智能的未来,我很可能是错的,但我迫不及待地想看看会发生什么!希望不是天网
This film was written by an LSTM neural network
延伸阅读,如果你感兴趣:
- 安德烈·卡帕西的精彩演讲*我的大部分素材都是从那里获得的。*
- 费的 TED 演讲,他建立了 ImageNet 数据库
- 人工智能实验 由谷歌
- Siraj Raval 的过顶 Youtube 频道
- 两分钟论文 ,里面展示了一些最酷的人工智能东西!
- 克里斯·奥拉的博客 关于神经网络
动物照片:
- 猫鼬: CC-0 迈克·贾斯敏·范登博加尔德
- 狗和马: CC-0 希拉里·哈利维尔
- 豹子: CC-0
- 鹅: CC-0
- 猕猴:公共领域
- 鸭子: CC-0 马丁·迪金森
- 蜘蛛: CC-by-SA 托马斯·沙汉
- 捷豹: CC-by-SA-ND 瓦莱丽
- 狗: CC-0 Pixabay
- 捷豹: CC-0 突击者摄影
随意分享&在 知识共享许可 下修改这篇文章,如果有需要修改的地方,请告诉我!
使用 TensorFlow 进行线性回归的逐行外行指南
本文是使用 TensorFlow 进行线性回归的逐行外行指南。如果你读这篇文章有困难,考虑在这里订阅中级会员!
线性回归是机器学习之旅的一个良好开端,因为它是一个非常简单的问题,可以通过流行的模块来解决,如 scikit-learn 包。在本文中,我们将讨论使用 TensorFlow 实现线性回归的逐行方法。
linear regression equation
查看上面的线性回归方程,我们首先构建一个图形,通过多次迭代学习斜率( W )和偏差( b )的梯度。在每次迭代中,我们的目标是通过比较输入 y 和预测的y来缩小差距(损失)。也就是说,我们想要修改 W 和 b ,这样 x 的输入就会给我们想要的 y 。求解线性回归也称为寻找最佳拟合线或趋势线。
生成数据集
[第 1、2、3 行]
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
在本文中,我们将使用一些流行的模块,如 numpy 、 tensorflow 和 matplotlib.pyplot 。让我们导入它们。
[第 6、7 行]
x_batch = [np.linspace](https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.linspace.html)(0, 2, 100)
y_batch = 1.5 * x_batch + np.random.randn(*x_batch.shape) * 0.2 + 0.5
首先,我们从生成数据集开始,即 x 和 y 。你可以把 x 和 y 中的每个值想象成图上的点。在第 6 行中,我们希望 numpy 生成 100 个值在 0 和 2 之间的点,均匀分布。结果是一个存储在x_batch
中的 numpy 数组。类似地,我们还想随机生成 y ,这样它的梯度为 1.5 ( W )并且使用np.random.randn()
具有某种形式的随机性。为了让事情变得有趣,我们将 y 轴截距 b 设置为 0.5。
【第八行】return x_batch, y_batch
我们返回 numpy 数组x_batch
和y_batch
。
plt.scatter(x_batch, y_batch) — this is our starting point
这就是generate_dataset()
的剧情样子。请注意,从视觉上看,这些点形成了一条从左下方到右上方的趋势线,但没有穿过原点(0,0)。
构建图表
[第 2 行和第 3 行]
x = tf.placeholder(tf.float32, shape=(None, ), name='x')
y = tf.placeholder(tf.float32, shape=(None, ), name='y')
接下来,我们构建张量流图,帮助我们计算 W 和 b 。这在函数linear_regression()
中完成。在我们的公式y = Wx + b
中, x 和 y 是表示为 TensorFlow 的占位符的节点。将 x 和 y 声明为占位符意味着我们需要在以后传入值——我们将在下一节重新讨论这个问题。请注意,我们现在仅仅是构建图形,而不是运行它(TensorFlow 有惰性评估)。
在tf.placeholder
的第一个参数中,我们将数据类型定义为 float 32——占位符中常见的数据类型。第二个参数是设置为None
的占位符的形状,因为我们希望它在训练期间确定。第三个参数让我们设置占位符的名称。
占位符仅仅是一个变量,我们将在以后的某一天把数据赋给它。它允许我们创建我们的操作和构建我们的计算图,而不需要数据。在 TensorFlow 术语中,我们通过这些占位符将数据输入图表。
【第 5 行】with tf.variable_scope(‘lreg’) as scope:
这一行为第 6 行和第 7 行中的变量定义了变量范围。简而言之,变量作用域允许以层次方式命名变量,以避免名称冲突。详细地说,它是 TensorFlow 中的一种机制,允许在图形的不同部分共享变量,而无需四处传递对变量的引用。请注意,尽管我们在这里没有重用变量,但是恰当地命名它们是一个很好的做法。
with tf.name_scope("foo"):
with tf.variable_scope("var_scope"):
v = tf.get_variable("**var**", [1])
with tf.name_scope("bar"):
with tf.variable_scope("var_scope", reuse=True):
v1 = tf.get_variable("**var**", [1])
assert v1 == v
**print(v.name) # var_scope/var:0
print(v1.name) # var_scope/var:0**
在上面的代码中,我们看到变量(" var ")被重用并被断言为真。要使用同一个变量,只需调用[tf.get_variable](https://www.tensorflow.org/api_docs/python/tf/variable_scope)(“var”, [1])
。
【第六行】w = tf.Variable(np.random.normal(), name=’W’)
与占位符不同, W 被定义为一个[tf.Variable](https://www.tensorflow.org/api_docs/python/tf/Variable)
,其值随着我们训练模型而变化,每次都以较低的损失结束。在第 10 行,我们将解释“损失”是什么意思。现在,我们使用[np.random.normal()](https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.random.normal.html)
设置变量,以便它从正态(高斯)分布中抽取一个样本。
tf。变量—一个变量在调用
*run()*
时维护图中的状态。您通过构造类*Variable*
的实例向图中添加一个变量。
*Variable()*
构造函数需要变量的初始值,可以是任何类型和形状的*Tensor*
。初始值定义了变量的类型和形状。构造后,变量的类型和形状是固定的。可以使用赋值方法之一来更改该值。
请注意,即使现在定义了变量,也必须在使用该值运行操作之前显式初始化它。这是惰性求值的一个特性,我们将在后面进行实际的初始化。
这里 W 真正做的是找到我们最佳拟合线的梯度。之前,我们使用 1.5 的梯度生成数据集,因此我们应该期望经过训练的 W 接近这个数字。为 W 选择起始数字有些重要——想象一下,如果我们可以“随机”选择 1.5,工作就完成了,不是吗?差不多吧…
因为我们的主题是寻找线性回归中的最佳梯度,我需要指出的是,无论我们在哪里初始化 W ,我们的损失函数将总是产生一个最小损失值。这是由于我们的损失函数, W 和 b 的凸性,当我们在这样的图表中绘制它们时。换句话说,这个碗形图形让我们可以确定最低点,不管我们从哪里开始。
One global minimum
然而,对于更复杂的问题,情况并非如此,在这些问题中存在多个局部最小值,如下所示。选择一个不好的数字来初始化你的变量会导致你的梯度搜索陷入局部极小值。这阻止了你达到具有较低损失的全局最小值。
Multiple local minima with one global minimum
研究人员想出了替代的初始化方法,例如 Xavier 初始化,试图避免这个问题。如果您想使用它,请随意使用:
tf.get_variable(…, initializer=[tf.contrib.layers.xavier_initializer()](https://www.tensorflow.org/api_docs/python/tf/contrib/layers/xavier_initializer))
。
【第 7 行】b = tf.Variable(np.random.normal(), name=’b’)
除了 W 之外,我们还要训练我们的 bias b 。如果没有 b ,我们的最佳拟合线将总是穿过原点,而不会学习 y 轴截距。还记得 0.5 吗?我们也需要了解这一点。
【第九行】y_pred = tf.add(tf.multiply(w, x), b)
在分别定义了 x 、 y 和W****、之后,我们现在准备将它们放在一起。为了实现公式y = Wx + b
,我们首先使用[tf.multipl](https://www.tensorflow.org/api_docs/python/tf/multiply)y
将w
和x
相乘,然后使用[tf.add](https://www.tensorflow.org/api_docs/python/tf/math/add)
将变量b
相加。这将执行逐元素的乘法和加法,从而产生张量y_pred
。y_pred
代表预测的 y 值,正如您可能会怀疑的那样,预测的 y 一开始会很糟糕,并且与生成的 y相差甚远,类似于占位符或变量,您可以随意为其命名。
【第 11 行】loss = tf.reduce_mean(tf.square(y_pred — y))
Mean Squared Error (MSE)
计算完y_pred
,我们想知道预测的 y 与我们生成的 y 有多远。为此,我们需要设计一种方法来计算“差距”。这种设计被称为损失函数。这里,我们选择了均方误差(MSE) 又名 L2 损失函数作为我们的“评分机制”。还有其他流行的损失函数,但我们不包括它们。
为了理解我们的 MSE 实现,我们首先使用y_pred — y
找到y_pred
和y
的 100 个点之间的差异。接下来,我们通过对它们求平方([tf.square](https://www.tensorflow.org/api_docs/python/tf/square)
)来放大它们的差异,从而使差异变大(很多)。哎哟!😝
向量大小为 100,我们现在有一个问题—我们如何知道这 100 个值是否代表一个好的分数?通常分数是决定你表现如何的一个数字(就像你的考试一样)。因此,为了得到一个单一的值,我们利用[tf.reduce_mean](https://www.tensorflow.org/api_docs/python/tf/reduce_mean)
找到所有 100 个值的平均值,并将其设置为我们的loss
。
【第 13 行】return x, y, y_pred, loss
最后但同样重要的是,我们在构造它们之后返回所有的 4 个值。
计算图表
有了generate_dataset()
和linear_regression()
,我们现在准备运行程序,并开始寻找我们的最佳梯度 W 和偏差 b !
[第 2、3 行]
x_batch, y_batch = generate_dataset()
x, y, y_pred, loss = linear_regression()
在这个run()
函数中,我们首先调用generate_dataset()
和linear_regression()
来得到x_batch
、y_batch
、x
、y
、y_pred
和loss
。向上滚动查看这两个功能的解释。
[第 5、6 行]
optimizer = tf.train.GradientDescentOptimizer(0.1)
train_op = optimizer.minimize(loss)
然后,我们定义优化器并要求它最小化图中的损失。有几个优化器可供选择,我们方便地选择了梯度下降算法并将学习率设置为 0.1。
我们不会深入优化算法的世界,但简而言之,优化者的工作是最小化(或最大化)你的损失(目标)函数。它通过在每次运行时向最优解的方向更新可训练变量( W 和 b )来实现这一点。
调用最小化函数计算梯度并将它们应用于变量——这是默认行为,您可以使用参数var_list
随意更改。
【第八行】with tf.Session() as session:
在我们构建图形的前面部分,我们说过张量流使用惰性求值。这实际上意味着只有在会话开始时才计算图形。这里,我们将会话对象命名为session
。
【第 9 行】session.run([tf.global_variables_initializer()](https://www.tensorflow.org/api_docs/python/tf/initializers/global_variables))
然后我们通过初始化我们要求变量保存的所有值来启动我们的第一个会话。由于惰性求值,在第一次构建图形时,变量如 W ( w = tf.Variable(np.random.normal(), name=’W’)
)没有初始化,直到我们运行这一行。更多解释见本。
【第 10 行】feed_dict = {x: x_batch, y: y_batch}
接下来,我们需要提出 feed_dict ,它本质上是session.run()
的一个参数。feed_dict
是一个字典,其关键字为tf.Tensor
、tf.placeholder
或tf.SparseTensor
。feed_dict
参数允许调用者覆盖图中张量(标量、字符串、列表、numpy 数组或 tf.placeholder,例如 x 和 y )的值。
在这一行中, x 和 y 是占位符, x_batch 和 y_batch 是生成的值,准备在session.run()
期间填充占位符。
【第 12 行】for i in range(30):
在初始化变量并使用feed_dict
为占位符准备值之后,我们现在进入脚本的核心,定义我们想要“调整”/“训练”权重( W )和偏差( b )的次数。我们在一个完整周期中遍历训练数据的次数( x 和 y )也称为时期/训练步骤。一个完整的循环也被定义为一个前馈和一个反向传播。
前馈时,我们传入 x 、 w 和 b 的值,得到预测的 y 。这将计算用数字表示的损失。由于该图的目标是最小化损耗,优化器将执行反向传播以“调整”可训练变量( W 和 b ),以便下一次我们执行前馈(在另一个时期)时,损耗将会降低。
我们这样向前向后循环 30 次。请注意,30 是一个超参数,您可以自由更改它。还要注意,更多的纪元=更长的训练时间。
[第 13 行]
session.run(train_op, feed_dict)
现在,我们准备通过调用获取的session.run()
和feed_dict
来运行我们的第一个纪元。在这里,session.run()
评估提取的每个张量(train_op
)并用feed_dict
中的值替换相应的输入值。
**fetches**
:单个图形元素、图形元素列表或其值为图形元素或图形元素列表的字典(参见run
的文档)。
当session
对象调用run()
方法时,在幕后发生的事情是,您的代码将运行图的必要部分(节点),以计算提取中的每个张量。由于train_op
指的是optimizer
调用方法minimize(loss)
,那么将通过调用损失函数来计算loss
,损失函数又触发y_pred
、y
、W
、x
和b
进行计算。
下面是来自 TensorFlow 文档的代码。你可以看到提取可以是单例、列表、元组、命名元组或字典。在我们的例子中,我们使用 feed_dict 作为 dictionary 类型的参数。
fetches in session.run()
print(i, “loss:”, loss.eval(feed_dict))
【第 14 行】print(i, “loss:”, loss.eval(feed_dict))
这一行打印出每个时期的损失。在左侧,您可以看到每个时期的损失值都在减少。
使用loss.eval()
和feed_dict
作为参数计算损失值。
[第 16、17 行]
print('Predicting')
y_pred_batch = session.run(y_pred, {x : x_batch})
30 个纪元后,我们现在有一个训练有素的 W 和 b 供我们执行推理。与训练类似,可以使用session.run()
对相同的图进行推理,但这一次,获取将是 y_pred 而不是 train_op ,我们只需要输入 x 。我们这样做是因为 W 和 b 已经被训练过,并且预测的 y 可以仅用 x 来计算。注意在tf.add(tf.multiply(w, x), b)
中,没有 y 。
到目前为止,我们已经声明了 3 个session.run()
,所以让我们回顾一下它们的用法,因为session.run()
是我们运行操作和评估图中凸榫的命令。第一次我们做的是初始化我们的变量,第二次在训练期间传递我们的 feed_dict,第三次运行预测。
[第 19–23 行]
plt.scatter(x_batch, y_batch)
plt.plot(x_batch, y_pred_batch, color='red')
plt.xlim(0, 2)
plt.ylim(0, 2)
plt.savefig('plot.png')
我们用生成的x_batch
和y_batch
以及我们预测的线(用x_batch
和y_pred_batch
)绘制图表。最后,我们有我们的预测线很好地画在下面。花点时间回顾一下我们的第一个神经网络如何计算出梯度和 y 截距,并欣赏机器学习的魔力!
plt.plot(x_batch, y_pred_batch) — we drew the line of best fit
[第 25、56 行]
if __name__ == "__main__":
run()
不需要解释——你可以做得更好。😉
最后
投身机器学习并不容易。有人从理论开始,有人从代码开始。我写这篇文章是为了让自己理解基本概念,并帮助那些正在接触机器学习或 TensorFlow 的人入门。
你可以在这里找到最终代码。如果您发现任何错误,并希望提出建议或改进,请随时发表评论或发 tweet me 。🙏
一个长期的数据科学路线图不会帮助你在几个月内成为专家
成为数据科学家的几点思考?这既不容易也不快速,需要很多努力,但如果你对数据科学感兴趣,这是值得的。
不时有人问我:如何成为一名数据科学家?有哪些课程是必须的?需要多长时间?你是怎么成为 DS 的?我已经回答过这个问题几次了,所以在我看来,写一篇文章可能是一个帮助有抱负的数据科学家的好主意。
关于我
我在 MSU 经济学院获得了硕士学位,并在 ERP 系统实施领域做了大约 4 年的分析师/顾问。它包括与客户交谈,讨论他们的需求并使之形式化,编写文档,向程序员解释任务,测试结果,组织项目和许多其他事情。
但这是一份压力很大的工作,有很多问题。更重要的是,我并不真的喜欢它。尽管我喜欢和数据打交道,但大多数事情并不鼓舞人心。因此,在 2016 春夏,我开始寻找其他东西。我在精益六适马拿到了绿带,但是附近没有机会。有一天我发现了大数据。经过几周的谷歌搜索和阅读大量文章,我意识到这可能是我梦想的职业。
我辞职了,8 个月后,我在一家银行获得了第一份数据科学家的工作。从那以后,我在几家公司工作过,但我对数据科学的热情仍然很高。我已经完成了 ML 和 DL 的几门课程,做了几个项目(如一个聊天机器人或一个数字识别 app ),参加了许多 ML 比赛和活动,在 Kaggle 上获得了三枚银牌等等。因此,我有一些学习数据科学和作为数据科学家工作的经验。当然,我还有很多东西要学,还有很多技能要掌握。
放弃
这篇文章包含了我的观点。有些人可能不同意他们的观点,我想指出,我不想冒犯任何人。我认为任何希望成为数据科学家的人都必须投入大量的时间和精力,否则他们会失败。声称你可以在几周或几个月内成为 ML/DL/DS 专家的课程或 MOOCs 并不完全真实。你可以在几周/几个月内获得一些知识和技能。但是如果没有大量的练习(这不是大多数课程的一部分),你就不会成功。
你确实需要内在的动力,但是,更重要的是,你需要自律,这样你才能在动力消失后继续工作。
让我再重复一遍——你需要自己做事情。如果你问最基本的问题,甚至没有尝试使用 Google/StackOverflow 或思考几分钟,你将永远无法赶上专业人士。
在我参加的大多数课程中,只有大约 10-20%的人完成了课程。大多数辍学者没有奉献精神或耐心。
谁是数据科学家?
有很多图片展示了数据科学家的核心技能。就本文的目的而言,它们都是好的,所以让我们看看这一个。这表明你需要数学和统计,编程和开发,领域知识和软技能。
太多了!怎么可能知道这一切?嗯,真的要花很多时间。但是这里有一个好消息:没有必要什么都知道。
2018 年 10 月 21 日在 Yandex 有一场有趣的讲座。据说有许多类型的专家,他们拥有上述技能的不同组合。
数据科学家应该在中间,但事实上他们可以在三角形的任何部分,在三个领域中的任何一个都有不同的层次。
在本文中,我将谈论通常被认为的数据科学家,即那些能够与客户交流、执行分析、构建模型并交付模型的人。
转行?这意味着你已经有了!
有人说转行很难。虽然这是真的,有一个职业可以转换,意味着你已经知道一些东西。也许你有编程和开发的经验,也许你在数学/统计领域工作过,或者你每天都在磨练你的软技能。最起码你在你的领域有专业知识。所以总是试着利用你的优势。
来自 Reddit 的路线图
事实上将会有两个路线图:)
第一个来自 Reddit,来自这个话题:
首先,读他妈的哈斯提,提白拉尼,还有谁。第 1-4 章和第 7-8 章。如果你不明白,继续读,直到你明白。
如果你愿意,你可以读这本书的其余部分。你可能应该知道,但我会假设你都知道。
以吴恩达的 Coursera 为例。用 python 和 r 做所有的练习,确保所有的答案都是一样的。
现在忘掉这些,去读深度学习的书吧。将 tensorflow 和 pytorch 放在一个 Linux 盒子上,运行示例,直到得到它。做 CNN 和 rnn 的事情,只是前馈神经网络。
一旦你完成了所有这些,就可以上 arXiv,阅读最新的有用文章。文献每隔几个月就有变化,所以要跟上。
那里。现在你可能在大多数地方都能被雇佣。如果你需要简历填充,那么一些 Kaggle 比赛。如果有调试问题,请使用 StackOverflow。有数学题,多读。如果你有人生问题,我不知道。
从其中一条评论来看:
直到不够为止。。想出一个没有训练数据的新问题,并想出如何收集一些数据。学会写一个刮刀,然后做一些标注和特征提取。在 EC2 上安装所有东西并自动化它。编写代码,随着新数据的出现,在生产中不断地重新训练和重新部署您的模型。
虽然简短、苛刻且非常困难,但这份指南非常棒,它会让你达到一个可雇佣的水平。
当然,数据科学还有许多其他方法,所以我将提供我的方法。它并不完美,但它是基于我的经验。
我的路线图
有一项技能会让你走得很远。如果你还没有,我敦促你开发它。这个技能是…形成思想,搜索信息,找到它并理解它。说真的!有些人无法表达思想,有些人无法找到最基本问题的解决方案,有些人不知道如何正确创建谷歌查询。这是一个基本的、必须的技能,你必须完善它!
- 选择一门编程语言,学习它。通常会是 Python 或者 r,我强烈推荐选择 Python。我不会列出原因,因为已经有很多关于 R/Python 的争论,我个人认为 Python 更加通用和有用。花 2-4 周时间学习语言,这样你就可以做一些基本的事情。对所使用的库有一个大致的了解,比如 pandas/matplotlib 或者 tydiverse/ggplot2。
- 通过安德鲁·吴的 ML 课程。它是旧的,但它给了一个伟大的基础。在 Python/R 中完成任务可能是有用的,但不是必需的。
- 现在再选一门好的 ML 课程(或几门)。对于 R 用户我推荐 Analytics Edge ,对于 Python 用户— mlcourse.ai 。如果你懂俄语,Coursera 上的这个课程也很棒。在我看来 mlcourse.ai 是这三个里面最好的。为什么?它提供了很好的理论和一些艰难的任务,这可能已经足够了。然而,它也教人们参加 Kaggle 比赛,并制作独立的项目。这对于练习来说非常有用。
- 学习 SQL。在大多数公司中,数据都保存在关系数据库中,所以你需要能够得到它。让自己习惯使用选择,分组,CTE,连接和其他东西。
- 尝试处理原始数据,以获得处理脏数据集的经验。
- 虽然前一点可能不是必要的,这一点是强制性的:完成至少 1 或 2 个完整的项目。例如,对某些数据集进行详细的分析和建模,或者创建一个应用程序。要学习的主要内容是如何创造一个想法,计划其实施,获得数据,使用它并完成项目。
- 去 Kaggle,学习内核,参加比赛。
- 加入一个好的社区。我加入了 ods.ai —一个由 15k+活跃的俄罗斯数据科学家组成的社区(顺便说一下,这个社区对任何国家的数据科学家开放),它给了我很大的帮助。
研究深度学习是一个完全不同的话题。
这仅仅是开始。遵循这个路线图(或做类似的事情)将帮助你开始成为数据科学家的旅程。剩下的就看你自己了!
现在你也可以在我的网站这里阅读这篇博文。
看看梯度下降和 RMSprop 优化器
简短的解释
1.介绍
有无数的超参数,你可以调整,以提高你的神经网络的性能。但是,并不是所有这些都会显著影响网络的性能。您选择的优化器是决定您的算法是收敛还是爆炸的一个参数。有相当多的优化器可供选择,让我们来看看最广泛使用的两个。
2.梯度下降优化器
梯度下降可能是所有优化器中最流行和使用最广泛的。这是一种寻找神经网络最优值的简单而有效的方法。所有优化器的目标是达到全局最小值,其中成本函数达到最小可能值。如果你尝试在三维空间中形象化成本函数,它将类似下图。
Convex cost function
Stochastic Gradient Descent - AlgorithmFor each example in the data
- find the value predicted by the neural network
- calculate the loss from the loss function
- find partial derivatives of the loss function, these partial derivatives produce gradients
- use the gradients to update the values of weights and biases
每当我们找到梯度并更新权重和偏差的值时,我们就向最佳值靠近了一步。在我们开始训练我们的神经网络之前,我们的成本会很高,这由上图中的 A 点表示。通过训练神经网络的每一次迭代(寻找梯度并更新权重和偏差),成本降低并向全局最小值移动,该最小值由上图中的点 B 表示。下面的模拟将提供一个更好的直观理解,当我们迭代训练我们的模型时,我们如何达到全局最小值。
我们的成本函数并不总是像上面图片中描绘的那样平滑。很多时候,这些成本函数是非凸的。非凸函数的问题是,你有可能陷入局部极小值,你的损失可能永远不会收敛到全局最小值。看看下面的图片。
Non-Convex cost function
从上图可以看出,图中有两个最小值,两个中只有一个是全局最小值。我们的神经网络很有可能会错过全局最小值而收敛到局部最小值。有一些方法可以限制网络收敛,例如:我们可以改变学习速率或使用动量等。
2.1 学习率
Different learning rate
学习率可能是梯度下降和其他优化器最重要的方面。让我用一个类比来更好地解释学习率。把成本函数想象成一个坑,你将从顶部开始,你的目标是到达坑的底部。你可以把学习率想象成你要到达坑底(全局最小值)的那一步。如果你选择一个大的值作为学习率,你将会对权重和偏差值做出剧烈的改变,也就是说,你将会经历巨大的跳跃来达到底部。还有一个巨大的概率,你会越过全局极小值(底部),最终在坑的另一边,而不是底部。学习率大,你永远无法收敛到全局极小值,永远在全局极小值附近徘徊。如果你选择一个小的值作为学习率,你会失去超过最小值的风险,但是你的算法会有更长的时间收敛,也就是说,你采取更短的步骤,但是你必须采取更多的步骤。因此,你必须训练更长的时间。此外,如果成本函数是非凸的,您的算法可能很容易陷入局部最小值,它将无法摆脱和收敛到全局最小值。学习率没有通用的正确值。这归结于实验和直觉。
2.2 带动量的梯度下降
几乎总是,带动量的梯度下降比标准梯度下降算法收敛得更快。在标准的梯度下降算法中,你会在一个方向上迈出较大的步伐,而在另一个方向上迈出较小的步伐,这会降低算法的速度。在下图中,您可以看到标准梯度下降在 y 方向上的步长较大,在 x 方向上的步长较小。如果我们的算法能够减少在 y 方向上采取的步骤,并将步骤的方向集中在 x 方向上,我们的算法将收敛得更快。这就是动量所做的,它限制了一个方向的振荡,这样我们的算法可以收敛得更快。此外,由于 y 方向的步数受到限制,我们可以设置更高的学习率。
Standard gradient descent
3.RMSprop 优化器
RMSprop 优化器类似于带有动量的梯度下降算法。RMSprop 优化器限制垂直方向的振荡。因此,我们可以提高我们的学习率,我们的算法可以在水平方向上采取更大的步骤,收敛得更快。RMSprop 和梯度下降之间的区别在于梯度是如何计算的。以下等式显示了如何计算 RMSprop 的梯度和带动量的梯度下降。动量的值用β表示,通常设置为 0.9。如果你对优化器背后的数学不感兴趣,你可以跳过下面的等式。
Gradient descent with momenttum
RMSprop optimizer
有时 v_dw 的值可能非常接近 0。然后,我们体重的价值可能会膨胀。为了防止梯度爆炸,我们在分母中包括一个参数ε,它被设置为一个小值。
4.结论
优化器是神经网络的重要组成部分,了解它们的工作方式将有助于您选择哪一个用于您的应用程序。我希望这篇文章有助于做出这个决定:)
机器人技术一览
通过初创公司 Clearpath Robotics 简要介绍机器人行业及其竞争格局。
这是我对一家投资组合公司案例研究的精简版。与 Clearpath Robotics 或其团队没有任何关系。(最初发布于 2017 年 3 月 20 日)
关于 Clearpath:
Clearpath Robotics 自其创始人——4 名雄心勃勃的滑铁卢学生——发现他们“为了更大的利益而制造机器人”的热情以来,已经走过了漫长的道路
自 2009 年以来,Clearpath Robotics 引领了一场实施智能机器人的运动,这些机器人可以执行危险的任务,以减轻人类的危险。Clearpath 的自动驾驶汽车是一项无与伦比的自动化技术,其潜力超出了农业和采矿等工业目的。目前,Clearpath 的机器人解决方案及其硬件、软件和服务已经整合到 500 多个全球品牌的日常流程中。
“Clearpath 的最终目标是将人类从履行中心完全移除。从长远来看,我们的目标是建立一个制造或履行设施,在那里,你可以真正地关灯,因为一切都是自动化的。”
- 西蒙·德雷克斯勒 Clearpath 的工业系统总监
概述 Clearpath 的 3 个不同支柱:人工智能进步,机器人自主和工业自动化,它们将在稍后进行审查。
Culminated based on my findings
机器人行业:
机器人领域是一个具有高增长潜力的蓬勃发展的市场。机器人是一个独立的数十亿美元的全球市场,能够转移到工业环境之外的新行业,在这些行业中,他们的现代技术仍然高度适用和有需求。
根据当前趋势,到 2020 年,机器人的市场价值预计将达到 410 亿美元,其中 15 亿美元将用于机器人扩展到 B2C 模式。这与像 Clearpath 这样的初创公司的可能性相一致,它们只将企业作为唯一的客户群。
下面是 12 年期间(2002 年至 2014 年)数据的可视化,代表了该行业在购买数量方面的巨大增长。
Based on source
此外,机器人的未来市场将由两个主要部门驱动:工业和服务。很明显,机器人产业只会继续快速扩张,在全球范围内扩大规模。最值得注意的是,在未来几年,服务行业将有更大的市场进入机会,让公司将机器人应用于受过高等教育的角色,如客户服务。
全球市场:
目前,亚洲是机器人领域支出最多的地区,占全球市场总额的 65%以上。此外,据预测,到 2019 年,他们的支出将翻一番,这表明了令人难以置信的增长,但也为 Clearpath 等公司提供了巨大的市场机会,让他们在不久的将来探索扩张方案。
众所周知,中国生产了全世界几乎一半的商品。事实上,中国的进口仅占其出口的 35%[,而出口最近在 2013 年增加到 43.1%](http://www.economist.com/news/leaders/21646204-asias-dominance-manufacturing-will-endure-will- make-development-harder-others-made)。随着中国工资上涨,许多大公司选择将生产外包给菲律宾等成本更低的国家。随着中国作为制造业世界工厂的有希望的主导地位,其减少劳动力的需求,以及其强大的机器人市场机会,中国似乎是 Clearpath 的 Otto 等产品的下一个成功扩张地点。
从不同的角度来看,与其他大型国际机器人公司相比,Clearpath 仍然被认为是一家规模小得多的初创公司。由于他们的团队和库存更小,新的业务环境可能弊大于利,因为它将带来大量的新费用和硬件需求的突然增加,而 Clearpath 无法满足这些需求。鉴于他们目前的公司状况,他们目前留在加拿大境内可能更容易。
编辑 : Geek+ ,一家成立 1.5 年的中国北京公司,正在为仓库建造机器人(类似于亚马逊的 Kiva 机器人),本周在 A 轮中筹集了 1400 万美元。
Clearpath 的竞争对手:
为了分析 Clearpath 的独特地位和研究强大的市场参与者,我们必须重新审视前面提到的 3 个支柱。哪些主要竞争对手正在同一个领域进行创新,并专注于创造一系列自主、智能和高效的士兵?
值得注意的竞争对手包括Fetch Robotics**:一家最近在硅谷成立的初创公司,旨在通过其旗舰产品 Freight、Seegrid Corp😗*一家 3D 视觉导航的创新者,希望通过自主机器人解决方案来提高生产率,并希望改造下一代视觉和自动导向车辆。
Positioning map
尽管 Clearpath 面临着挑战和不断增加的竞争对手,但这家初创公司有一个整体的价值主张,无法被其他人轻易超越。Clearpath 的基础设施不仅允许轻松的企业集成、即时实施和无缝的整体体验,而且 Clearpath 致力于卓越的客户服务,这在很大程度上帮助他们在社区中扬名立万。
Clearpath 的未来展望:
检查伙伴关系
1。地理扩张
正如之前提出的潜在扩张战略,Clearpath 在进入全球市场时并不具备规模优势。然而,机器人行业内的一些强大的参与者有,未来的合作伙伴关系可以帮助 Clearpath 支撑这一弱点。
Grenzebach **,**是一家德国公司,几十年来一直以家族企业的方式运营。专注于工业自动化,他们的移动设备 Carry 被编程为处理材料运输任务。随着品牌在欧洲和亚洲广泛使用他们的技术,Grenzebach 仍然远远没有统治北美,因为他们只进入了一个国家(美国)。Grenzebach 在德国、美国和亚洲拥有 3000 家工厂和设施,未来与 Clearpath 的合作对双方都有利。通过与 Grenzebach 合作,Clearpath 有能力轻松地扩展到我们的邻国,各州,以及亚洲市场,因为 Grenzebach 的物理设施。对于 Grenzebach 来说,Clearpath 是加拿大领先的机器人初创公司,拥有一个有前途的研究团队,他们的创新速度比典型的大公司更快。此外,在 Clearpath 的帮助下,Grenzebach 最终可以通过进入加拿大市场来覆盖北美的所有地区。
2。产业扩张
考察潜在合作伙伴的另一种方式是考察行业扩张机会。根据麦肯锡&公司的预测,到 2025 年,医疗保健、服务和制造等行业的先进机器人市场预计将产生高达 4.5 万亿美元的经济影响。
“对于私人控股的 Clearpath 来说,即使是一小块蛋糕,也意味着数十亿美元。自 2010 年以来,clear path 的合作伙伴关系推动其收入同比增长了 200%。”
有鉴于此,Clearpath 可以探索与领先的医疗机构合作的选择,这些机构规模庞大,但不一定有人力或时间自己发明先进的机器人技术。医院将通过整合 Clearpath 受益,因为许多程序将变得更加高效。同样,这将是 Clearpath 的理想合作伙伴,因为他们可以将其产品扩展到医疗保健领域,收集有价值的第一手数据以进行改进,如果医疗机构是国际机构,还可能进行跨境合作。
检查收购
1。大型公司收购
2012 年,一家致力于为航运中心制造自动化机器人的机器人公司被亚马逊以 7 . 75 亿美元的巨额交易收购,该交易给了他们所有研发的独家权利。 Kiva Systems,现在被称为亚马逊机器人,只在亚马逊自己的工厂内使用。
大公司刚刚开始赶上贝佐斯的步伐,因为他们最近注意到机器人和制造业之间的正相关和巨大增长。[像 IBM 和微软这样的大公司对机器人初创公司进行了无数次新投资。](http://www.geekwire.com/2016/sarcos-robotics-raises-10-5m-microsoft-caterpillar-ge-heavy-duty-ro botics-technology/)
2015 年, GE Ventures 公开了其作为 Clearpath Robotics 战略长期投资者的角色。
“我们相信机器人技术将极大地改善通用电气服务的行业,”
通用电气风险投资公司的董事总经理拉尔夫·泰勒-史密斯。
这反映了 GE 未来的发展方向。由于通用电气对自动机器人非常感兴趣,Clearpath 提供了他们希望在自己的服务中实现的创新,这使得阿格成为 Clearpath 的潜在收购者,交易类似于亚马逊的交易。
2。扩展采集
参照 Clearpath 目前较小的规模,他们可能更容易受到不断变化的市场的影响,对新的竞争准备不足。尤其是在文化层面和工厂程序上的差异。Clearpath 可以通过大型外国机器人公司的收购自动放弃这种担忧。此外,一个更大的公司会非常有兴趣追求 Clearpath 的独特和先进的创新,将其引入他们的外国(也许是未开发的)市场。
ABB 集团 **,**是一家总部位于瑞士的自动化公司,通过自动化和机器人技术解决公用事业、交通和工业领域的问题。米语,ABB 两年前创造的双臂机器人是世界上第一个鼓励人机互动的协作机器人。这不仅与 Clearpath 的目标一致,而且从向新行业和新国家扩张的角度来看,被收购将大有裨益。
结论:
总之,Clearpath 正在人工智能、全自动机器人和工业自动化的支柱下创造令人难以置信的发明,同时通过其现代应用来完成培养前瞻性思维、高效和安全的工作环境的使命。根据我对 Clearpath 当前竞争格局的简要分析,他们最大的优势是:提供全面的基础设施系统以及全球机器人市场需求巨大的高度先进的技术创新。Clearpath Robotics 是一家快速增长的初创公司,有可能在 Grenzebach 等合作伙伴的帮助下,或被 GE 等更大的公司收购后,扩大地理范围,进入新的行业。
随着人工智能发展研究的深入,我们继续努力复制人类智能或更高的智能,机器人行业是一个即将到来的巨人,我们必须感到兴奋,但同时保持警惕。
感谢阅读!在此之前和之后,我从未深入研究过机器人技术,我可能会再次成为一名软件狂热者。
这是我上个月的一篇文章:
注意:这是我的第一篇媒体文章,也是我第一篇试图分析一个应用程序和一个行业的文章
medium.com](https://medium.com/@diane.huang/thoughts-on-wechat-and-what-it-means-for-north-americas-digital-app-market-641e5063f1ac)
我们连线吧!😃
对酒精消费的调查
从人们的饮酒习惯,你能说出他们来自哪里吗?
根据世界卫生组织提供的一组国家级人均酒精消费量的数据,我很想知道各个地区的酒精偏好。
幸运的是,R 库(countrycode)可以很容易地将国家名称转换成 ISO3 代码、地区和大陆。然后我们可以使用 library(rworldmap)将其可视化。
我们可以使用 plot.ly 查看国家级别的消耗量。气泡大小是指总消耗量,单位为升。
我们对地区饮料偏好进行了观察:
- 加勒比人和亚洲人倾向于消费更多的烈酒和少量的葡萄酒
- 除此之外,世界各地的啤酒消费量最高
如果在地图上画出每个国家的消费量,除了明显知道伊斯兰国家消费很少的酒以外,我们可以看到:
- 整个美洲(北部、中部和南部)都喝很多啤酒
- 欧洲人似乎对葡萄酒比对烈酒更感兴趣
这是我的# 100 days 项目的第 3 天。完整的代码可以在 github 这里找到。
二分搜索法树一瞥
本周我一直在学习算法和数据结构,所以我想我们应该深入研究一下技术面试中常见的数据结构,二分搜索法树。对我来说,学习一个新主题的最好方法是看它如何应用于现实世界的问题,所以我将从解决特定问题的角度来介绍这个主题。
让我们假设你在一家软件工程公司工作,一个客户向你提出了一个问题。他们为一个只有一条跑道的小机场工作。他们要求您开发一个预订系统,该系统将跟踪着陆的飞机,以便没有重叠。他们希望能够为您的申请提供一个时间T
,该时间代表两次航班着陆之间的最短时间,以分钟为单位。最后,他们希望应用程序在 O(log n)中运行。
让我们首先考虑什么样的数据结构最适合这个问题。第一个想到的是一个Unsorted list / Array
结构,但是几乎所有你想用数组做的事情都将以线性时间运行(O(N)
)。插入以恒定的时间运行,然而,搜索是线性的,当一架新飞机请求着陆时间时,我们将需要搜索一个可用的时隙。
下一个逻辑步骤是Sorted Array
,这允许我们使用二分搜索法在O(log N)
中找到请求的时间,并且我们可以通过将它与它之前和之后的下一个相邻时间进行比较来验证恒定时间(O(1)
)中的槽。当我们试图插入新的预订时,问题出现了。要将一个新元素插入到一个排序的数组中,我们必须将插入点之前的所有其他元素向前移动 1,这是在线性时间内完成的,这违反了我们的最后一个要求。
考虑到这一点,我们继续进行Sorted Linked Lists
。这种结构允许在恒定的时间内插入,但是剥夺了我们应用二分搜索法的能力,这将我们的搜索时间复杂度降低到线性时间。
现在我们已经讨论了各种可能性,最符合我们需要的数据结构是排序数组,那么我们如何解决它的插入问题呢?这就是二叉查找树发挥作用的地方。二叉查找树(BST),也称为有序二叉树,是一种基于节点的数据结构,其中每个节点不超过两个子节点。每个子节点必须是另一个二叉查找树的叶节点或根节点。左侧子树仅包含键小于父节点的节点;右边的子树只包含键大于父节点的节点。
二叉查找树为我们提供了一些有趣的时间复杂性。为了搜索,我们必须遍历所有元素。因此,在二叉查找树中搜索的最坏情况复杂度为 O(n)。对于插入元素,它必须作为一片叶子插入到正确的位置,以保持二叉查找树不变量为真。因此,我们需要遍历所需的元素来找到它的正确位置,其最坏情况的复杂度为 O(n)。最后,对于删除,我们必须遍历所有元素来找到要删除的目标。因此,二叉树中的删除具有 O(n)的最坏情况复杂度。通常,这些操作的时间复杂度是O(H)
,其中H
是 BST 的高度。树的高度被定义为从节点到叶子的最长路径。这不应该被混淆
所以现在,我想象你对着你的电脑屏幕大喊“O(H)
的复杂性不符合客户给我们的O(log N)
的要求!”。放轻松,老虎,我们会成功的。让我们讨论树的高度的最好和最坏的情况。
Worst Case Scenario
在最坏的情况下,每次我们添加一个叶子,它都会被添加到相同的路径中。如果将一系列递增的数字添加到树中,就会出现这种情况,因为每个数字都比上一个数字大,它总是会选择正确的路径。这导致树的高度为N
,因此如果我们的目标是这棵树的叶子,那么无论何时我们都必须遍历它,我们将不得不查看每一个元素。该树的时间复杂度为O(N)
。
Best Case Scenario
在最好的情况下,我们所有的节点均匀地分布在整个树中。没有一条路比另一条路更长。这被称为平衡树,它为我们在其上执行的操作提供了最佳的运行时间。每次你选择一个分支往下走,你实际上是把你必须搜索的节点数减半,就像一个。是的…你猜对了,二分搜索法算法。平衡二叉树的高度将是log N
,因此其基本操作的时间复杂度也将是O(log N)
。
现在唯一需要回答的问题是如何保持我们的树木平衡。有许多不同的算法来平衡一棵树,我们将使用 AVL 树(以发明者命名)作为这个例子,因为它是第一个被发明的这样的数据结构。在 AVL 树中,任何节点的两个子树的高度最多相差 1;如果在任何时候它们相差一个以上,就要进行重新平衡以恢复该属性。这保证了在一般和最坏的情况下,查找、插入和删除都需要花费O(log N)
时间。
为了保持 AVL 树的平衡,我们必须记录两个孩子的身高差。差额由abs(Height(RightSubtree) — Height(LeftSubtree))
计算。只要结果小于 1,我们就知道我们的树符合 AVL 定义。请注意,这个公式永远不会产生大于 2 的值,因为我们一次只会向已经平衡的树中添加一个节点。当一棵 AVL 树变得不平衡时,我们必须对它的子树进行旋转以重新平衡结构。
Blatantly stolen image from Wikipedia.
由α, β and γ
表示的三角形代表N
大小的子树。当在树上执行旋转时,它的顺序遍历是不变的,这允许我们的树保持它的排序性质。
最简单的解决模式是我喜欢称之为线模式。在这种情况下,节点沿直线向右或向左延伸。在这种情况下,旋转中间节点(在这个例子中是B
)将平衡我们的树。
在大多数情况下,右旋转或左旋转将平衡树。然而,有一个实例,其中插入创建了之字形图案,其中单次旋转不会改变树的最终平衡。在左边的例子中,我们在B
上执行向左旋转。在这种情况下,旋转只是移动节点,因此树现在是右偏而不是左偏。
Double Rotation
对此的解决方案是首先在底部节点上执行旋转,使其符合线型。然后,您可以像在线型中一样旋转中间节点,并平衡您的树。这就是所谓的双旋转。
让我们回到我们的问题上来。当插入一个节点时,我们必须遍历树,一旦我们找到它的插入点,我们就可以检查它的父节点和子节点是否离它至少有K
远。如果满足所有验证,我们的函数将返回一个true
,否则返回一个false
。在 AVL 树中插入一个新节点可以在O(log N)
时间内完成,搜索可以以相同的复杂度完成。
我希望这有助于照亮二分搜索法树和他们的力量。作为临别礼物,我留给你一张来自维基百科的 gif,它很好地概述了 AVL 树中的插入和旋转。
AVL Tree Insertion and Rotation
*一如既往,如果您喜欢此内容或有任何反馈,请在下面留下评论 *
《权力的游戏》回顾
《权力的游戏》被公认为是这十年来最好的惊险、动作、战略、奇幻电视剧。该片于 2011 年上映,在很短的时间内就获得了认可,全球平均收视率达到 2570 万。这部剧是根据乔治·R·R·马丁写的系列丛书*【冰与火之歌】*改编的。
如果你还没看这部剧或读过这本书,下一部分会有剧透提醒
关于这个节目—
该剧展示了整个系列中的许多“家族”,但主要集中在其中的四个——坦格利安、史塔克、兰尼斯特和拜拉席恩。它讲述了四大家族如何不择手段地试图获得铁王座。
“字面上任何可能的意思”
故事从劳勃·拜拉席恩坐在铁王座上开始,奈德·史塔克是国王之手,瑟曦·兰尼斯特是他的妻子,丹妮莉丝·坦格利安和她的哥哥流亡海外。在这一系列的某个时候,劳勃去世,他的儿子乔佛里成为下一任国王。他的第一个命令是砍掉内德的头,他实际上是罗伯特的好朋友和助手。与此同时,丹的哥哥也被多斯拉克人杀死,她成了多斯拉克人卓戈·卡奥的妻子。在展览的后期,一系列事件发生了(按顺序)
- 内德的儿子罗柏·史塔克试图为父亲报仇,在一次晚宴上被他认为是自己忠诚的人杀死。
- 乔佛里在他叔叔提利昂的婚礼上喝啤酒时中毒身亡。
- 提利昂得知他最爱的女人实际上是被他雇佣并逃跑后,杀死了他的父亲泰温。
- 琼恩·雪诺死了,并再次由梅丽珊卓转世。(他什么都不知道)。
- 坦格利安家族的丹妮莉丝,她名字中的第一个,未燃烧者,安达尔人、洛依纳人和先民的女王,弥林的女王,大草海的卡丽熙,王国的守护者,七大王国的女统治者,锁链的破坏者和龙之母。
- 琼恩·雪诺现在是北境之王,瑟曦是铁王座和七大王国的女王,丹妮莉丝现在在维斯特洛的龙石岛。白鬼要来维斯特洛了,而且
- 冬天来了…
关于数据集—
Kaggle 基于书籍中的信息提供了来自三个数据源的数据集。
- 首先是 battles.csv 包含克里斯·阿尔邦的《五王之战》数据集,可以在这里找到:https://github.com/chrisalbon/war_of_the_five_kings_dataset。这是一个伟大的系列中所有战斗的集合。
- 其次,我们有来自艾琳·皮尔斯和本·卡勒的角色-死亡。这个数据集是作为他们的贝叶斯生存分析的一部分创建的,可以在这里找到:http://allendowney . blogspot . com/2015/03/Bayesian-Survival-Analysis-for-game-of . html
- 最后,我们有了一个更全面的人物数据集和人物预测。这来自冰与数据之歌的团队,他们是从http://awoiaf.westeros.org/刮来的。还包括他们对哪个角色会死的预测,其方法论可以在这里找到:https://got . show/machine-learning-algorithm-predicts-death-game-of-thrones
在这些数据中,你能找到哪些关于这个奇幻世界复杂政治格局的洞见?
接近—
正如前面提到的,我们需要在数据集内部找到洞察力,基本上我们需要对它进行 EDA。关于这篇文章,我们将分析 battles.csv 数据集,在后续文章中,我们将尝试获得尽可能多的见解(以及其他数据集)。
我在这里问的问题是——哪一个国王赢得了最多的战斗,用了多少人?
我们将首先尝试绘制一些当前特征的图表,然后尝试查看它们是否显示任何有用的信息。
笔记本—
要获得带有适当解释、输出和数据集文件的完整代码,请参考我的 GitHub 帐户—
在 GitHub 上创建帐户,为《权力的游戏》的开发做出贡献。
github.com](https://github.com/saahil1292/Game-Of-Thrones)
参考文献—
- http://quizfactory.com/simple/got2/desktop/top.jpg
- https://www . quora . com/How-much-people-watch-Game-of-Thrones/answer/Tini-Bancroft?srid=MrHW
- https://www . quora . com/What-the-full-title-of-daene rys-Targa ryen/answer/Mahesh-Shrestha-23?srid=MrHW
机器学习方法——构建酒店推荐引擎
source: Expedia
人工智能驱动的个性化,旅游推荐
所有在线旅行社都在争先恐后地满足亚马逊和网飞设定的人工智能驱动的个性化标准。此外,在线旅游世界已经成为一个竞争激烈的空间,品牌试图通过推荐、比较、匹配和分享来吸引我们的注意力(和钱包)。
在本帖中,我们的目标是为 Expedia 的用户创建最佳酒店推荐,这些用户正在搜索要预订的酒店。我们将把这个问题建模为一个多类分类问题,并使用集成方法建立 SVM 和决策树,以预测用户在给定他(或她)的搜索细节的情况下可能预订哪个“酒店群”。
数据
数据是匿名的,几乎所有的字段都是数字格式。数据集可以在 Kaggle 找到,我们将使用 train.csv 和 destinations.csv,前者捕获用户行为的日志,后者包含与用户对酒店的评论相关的信息。
下面的图 1 提供了 train.csv 的模式:
Figure 1
下面的图 2 提供了 destinations.csv 的模式:
Figure 2
import datetime
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inlinefrom sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
from sklearn.pipeline import make_pipeline
from sklearn import preprocessing
from sklearn.preprocessing import StandardScaler
from sklearn import svm
为了能够在本地处理,我们随机抽取 1%的记录。之后我们还有大量的记录在 241179。
df = pd.read_csv('train.csv.gz', sep=',').dropna()
dest = pd.read_csv('destinations.csv.gz')
df = df.sample(frac=0.01, random_state=99)
df.shape
(241179,24)
电子设计自动化(Electronic Design Automation)
目标是根据用户搜索中的信息,预测用户将预订哪个酒店。总共有 100 个集群。换句话说,我们正在处理一个 100 级的分类问题。
plt.figure(figsize=(12, 6))
sns.distplot(df['hotel_cluster'])
Figure 3
数据分布在所有 100 个集群中,并且数据中存在偏斜。
特征工程
日期时间、入住日期和退房日期列不能直接使用,我们将从中提取年和月。首先,我们定义了几个函数来实现这一点,我们还定义了一个函数来与 destination.csv 合并。
from datetime import datetime
def get_year(x):
if x is not None and type(x) is not float:
try:
return datetime.strptime(x, '%Y-%m-%d').year
except ValueError:
return datetime.strptime(x, '%Y-%m-%d %H:%M:%S').year
else:
return 2013
passdef get_month(x):
if x is not None and type(x) is not float:
try:
return datetime.strptime(x, '%Y-%m-%d').month
except:
return datetime.strptime(x, '%Y-%m-%d %H:%M:%S').month
else:
return 1
pass
def left_merge_dataset(left_dframe, right_dframe, merge_column):
return pd.merge(left_dframe, right_dframe, on=merge_column, how='left')
处理日期时间列:
df['date_time_year'] = pd.Series(df.date_time, index = df.index)
df['date_time_month'] = pd.Series(df.date_time, index = df.index)from datetime import datetime
df.date_time_year = df.date_time_year.apply(lambda x: get_year(x))
df.date_time_month = df.date_time_month.apply(lambda x: get_month(x))del df['date_time']
处理 srch_ci 列:
df['srch_ci_year'] = pd.Series(df.srch_ci, index=df.index)
df['srch_ci_month'] = pd.Series(df.srch_ci, index=df.index)# convert year & months to int
df.srch_ci_year = df.srch_ci_year.apply(lambda x: get_year(x))
df.srch_ci_month = df.srch_ci_month.apply(lambda x: get_month(x))# remove the srch_ci column
del df['srch_ci']
处理 srch_co 列:
df['srch_co_year'] = pd.Series(df.srch_co, index=df.index)
df['srch_co_month'] = pd.Series(df.srch_co, index=df.index)# convert year & months to int
df.srch_co_year = df.srch_co_year.apply(lambda x: get_year(x))
df.srch_co_month = df.srch_co_month.apply(lambda x: get_month(x))# remove the srch_co column
del df['srch_co']
初步分析
在创建新特性并删除无用的特性后,我们想知道是否有任何东西与 hotel_cluster 有很好的关联。这将告诉我们是否应该更加关注任何特定的功能。
df.corr()["hotel_cluster"].sort_values()
Figure 4
没有与 hotel_cluster 线性相关的列,这意味着对特征之间的线性关系建模的方法可能不适合该问题。
战略
快速谷歌搜索后,不难发现,对于搜索目的地、酒店国家、酒店市场的已知组合,肯定有助于找到酒店集群。就这么办吧。
pieces = [df.groupby(['srch_destination_id','hotel_country','hotel_market','hotel_cluster'])['is_booking'].agg(['sum','count'])]
agg = pd.concat(pieces).groupby(level=[0,1,2,3]).sum()
agg.dropna(inplace=True)
agg.head()
Figure 5
agg['sum_and_cnt'] = 0.85*agg['sum'] + 0.15*agg['count']
agg = agg.groupby(level=[0,1,2]).apply(lambda x: x.astype(float)/x.sum())
agg.reset_index(inplace=True)
agg.head()
Figure 6
agg_pivot = agg.pivot_table(index=['srch_destination_id','hotel_country','hotel_market'], columns='hotel_cluster', values='sum_and_cnt').reset_index()
agg_pivot.head()
Figure 7
与目标表和我们新创建的聚合数据透视表合并。
df = pd.merge(df, dest, how='left', on='srch_destination_id')
df = pd.merge(df, agg_pivot, how='left', on=['srch_destination_id','hotel_country','hotel_market'])
df.fillna(0, inplace=True)
df.shape
(241179,276)
实现算法
我们只对预订活动感兴趣。
df = df.loc[df['is_booking'] == 1]
获取要素和标签。
X = df.drop(['user_id', 'hotel_cluster', 'is_booking'], axis=1)
y = df.hotel_cluster
朴素贝叶斯
from sklearn.naive_bayes import GaussianNBclf = make_pipeline(preprocessing.StandardScaler(), GaussianNB(priors=None))
np.mean(cross_val_score(clf, X, y, cv=10))
0.10347912437041926
k 近邻分类器
from sklearn.neighbors import KNeighborsClassifierclf = make_pipeline(preprocessing.StandardScaler(), KNeighborsClassifier(n_neighbors=5))
np.mean(cross_val_score(clf, X, y, cv=10, scoring='accuracy'))
T5 0.25631461834732266
随机森林分类器
我们通过k-折叠交叉验证来报告性能测量,并且流水线使得构建评估器更加容易。
clf = make_pipeline(preprocessing.StandardScaler(), RandomForestClassifier(n_estimators=273,max_depth=10,random_state=0))
np.mean(cross_val_score(clf, X, y, cv=10))
0.24865023372782996
多类逻辑回归
from sklearn.linear_model import LogisticRegressionclf = make_pipeline(preprocessing.StandardScaler(), LogisticRegression(multi_class='ovr'))
np.mean(cross_val_score(clf, X, y, cv=10))
0.3045543572367767
SVM 分类器
SVM 非常耗时。然而,我们取得了更好的结果。
from sklearn import svmclf = make_pipeline(preprocessing.StandardScaler(), svm.SVC(decision_function_shape='ovo'))
np.mean(cross_val_score(clf, X, y, cv=10))
0.3228727137315005
似乎我们需要做更多的特征工程来改善结果。敬请期待进一步的改进!
源代码可以在 Github 上找到。祝你一周愉快!
机器学习入门:几乎没有数学——第 1 部分
机器学习课程的介绍总是以大量数学内容开始,这往往会吓倒初学者,并使他们远离它。在这里,我会试着复习机器学习的一些重要概念,除了数学,差不多。我还将尝试为每个术语附上一些简单的例子。这里涉及的大多数概念都与监督学习和预测建模有关。
这里讨论的所有解释都是实际概念的淡化版本。如果你对这些感兴趣,我强烈推荐回到数学上来获得更多的见解!
(机器)学习
如果由 P 测量的计算机程序在 T 中的任务的性能随着经验 E 而提高,则称该计算机程序从关于某类任务 T 和性能测量 P 的经验 E 中学习。—汤姆·米切尔
机器学习模型
机器学习模型可以被视为机器学习系统的数学(有时是架构)表示,包括但不限于输入和输出数据的表示、学习中涉及的算法、定义学习过程的参数和模型的架构。
人口
与所考虑的实验相关的所有可能的例子的集合。这是机器学习模型试图预测的,目标人群的分布。
特征空间(输入)
特征空间是模型的输入空间,变量(除了我们想要预测的目标变量)存在于此。特征可以是数字的,也可以是分类的。例如,汽车的重量和速度是数字特征。这辆车是雪佛兰还是特斯拉是一个明确的特征。
如果您使用颜色、速度、品牌和型号来描述一组汽车,那么这些属性的所有可能值构成了特征空间。
特征向量 X
特征空间中的每个条目被称为 n 维特征向量,其中 n 是定义特定数据点的特征的数量。
如果您要使用汽车的某些特征来定义汽车,特征列表将形成特征向量。例如:[橙色,280 英里/小时,2800 磅]是一个三维特征向量,具有 3 个特征,颜色,速度和重量。
标签空间(输出)
与每个特征向量相关联的标签或目标变量的集合构成了标签空间。
可以有各种车野马 GT,跑车,卡玛洛等。所有这些都是定义它们的功能集的标签。
真实标签 y
这是与一个特定数据点相关联的实际标签。
示例
一个例子是包括特征和标签的数据点。手头数据集中可用的示例可能不会完全穷尽数据分布。
Roadster[橙色,280 英里/小时,2800 磅]就是数据集中的一个例子。如果我们有一个只属于一家公司的 100 辆汽车的数据集,这并不意味着我们可以预测其他公司的汽车,因为它们可能有完全不同的数据分布。根据特斯拉汽车公司的数据,很难对福特汽车做出预测。
预测标签 y^
它是机器学习模型为给定特征向量预测的标签。它可能正确,也可能不正确。
vector【橙色,280 英里/小时,2800 磅】可以预测为跑车或橙色沙滩车。
训练集
用于训练机器学习模型的一组示例。
验证集
这是用于在训练过程中检查模型当前状态的训练集的子集(有时与训练集分开)。这并不直接有助于模型的训练。验证集可用于训练模型的参数或为模型提供评估度量。
测试设备
除非经过训练,否则模型无法访问的数据点集。它用于测试模型的训练状态。
Different data splits
分类
分类模型是将数据分类或归类为 2 个(二元分类器)或更多个(多类分类器)类的模型。
我们将尝试理解模型如何使用小数据集进行学习:
让我们绘制这个数据集,每个轴代表一个特性值:
现在我们将在这些点上标记给定的标签:
如果我们试图用直线来区分这两类,理论上可能会有无限可能的直线:
如果我们添加另一个点,可能的行数会减少:
添加更多点…
更多…
现在,如果我们从相同的数据分布中得到一个新点,我们知道根据我们的蓝线将该点分类到哪里。这条蓝线是从训练好的模型中获得的假设。
我们仍然不能确定我们的蓝线是否是原始人口分界线的实际代表。考虑下面这条线,它也将两类点分开。
如果我们得到更多的点,这条线实际上可能会改变它的位置。这就是为什么你可能总是听说,机器学习中更多的数据通常会产生更好的结果。
回归
简单线性回归是一种对标量标注和一个或多个解释性要素之间的关系进行建模的线性方法。通常,回归模型用于预测连续值,如温度、重量、利率等。
考虑另一个绘制在图表上的玩具数据集:
蓝线描述了分布点的大致位置。
现在,如果我们将数据分布中的更多点添加到训练集中,线条会完全改变:
我们从同一数据分布中添加的任何新点都将位于这条蓝色曲线上。给定两个特征之一的值,我们可以根据它在曲线上的位置预测另一个特征的值。前任。如果给定 x1 = 3,那么根据曲线,x2 = 1
培养
随着模型不断看到新的点,线的位置也在不断移动。这是学习的过程(在监督学习的情况下)。我们得到的点越多,学习过程就越好,模型的准确性就越好。
假设
它是我们认为尽可能接近描述数据的真实函数(或模型)的函数(或模型)。在我们的分类示例中,我们获得的蓝线是一个这样的假设,它描述了这样的数据,即该线一侧的所有点都属于相似的类。
假设空间
假设空间是可以用 n 个特征表示的所有可能的模型或函数的集合,不一定描述数据。必须从这个假设空间中选择目标函数。给定 2 个变量,在 2 维中可能有无限多条曲线。
探索的
它可以被认为是一个简单的假设空间或决策,直观地帮助我们最终选择正确的模型或函数。例如,在我们的分类示例中,我们凭直觉决定选择不同形式的直线,而不是圆或正方形,因为很明显,一条线就足以分隔这些点。这是我们的启发。我们可以选择一些圆来包含这两个类,但是这将会把测试空间限制在那些从训练数据中获得的圆上。如果我们选择了其他形状,可能需要更多的尝试才能到达最终的线条。正确选择启发式算法有助于更快地达到目标函数。
指标函数
目标函数是实际代表原始数据分布的函数。如果我们可以访问所有可能的数据点,我们就可以训练一个模型来学习目标函数。
参数
模型参数是内部变量,其值可以从数据中确定。在训练期间,模型参数值得到更新。
选择机器学习模型
现在我们知道了一些相关的基本术语,让我们来看看如何选择机器学习模型:
- 定义问题陈述。是分类问题还是回归问题?
- 获取所需数据。
- 基于初始数据分析选择一种启发式方法。
- 根据启发和手头的任务选择机器学习模型。
既然我们已经介绍了基础知识,我们将在下一篇文章中尝试看到一个感知器模型。同样,这里涵盖的概念是淡化的版本。我将推荐吴恩达在 Coursera 上的机器学习课程,对这些主题进行深入的数学展望。