TowardsDataScience-博客中文翻译-2016-2018-十九-

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

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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

如何在数据科学面试中胜出:统计学

原文:https://towardsdatascience.com/how-to-ace-data-science-interviews-statistics-f3d363ad47b?source=collection_archive---------2-----------------------

这是正在进行的数据科学职位面试系列的一部分。可以查看一下第一部分,这里涵盖 SQL、*,第三部分关于 R 和 Python* 这里

对于从事或试图从事数据科学工作的人来说,统计学可能是你需要发展的最大和最令人生畏的知识领域。这篇文章的目标是把你需要知道的东西减少到有限数量的具体想法、技术和方程式。

当然,这是一个雄心勃勃的目标——如果你打算长期从事数据科学,我仍然希望在你的职业生涯中继续学习统计概念和技术。但我的目标是为你提供一个基线,让你通过面试,尽可能短而轻松地实践数据科学。我将用关键术语和资源来结束每一节,以便进一步阅读。让我们开始吧。

可能性

概率是统计学的基础,经常在面试中出现。学习基础知识是值得的,不仅仅是因为这样你就可以通过面试官喜欢问的典型概率脑筋急转弯,还因为它会增强和巩固你对所有统计学的理解。

概率是关于随机过程的。经典的例子是像掷硬币和掷骰子这样的事情——概率为你提供了一个框架来确定一些事情,比如你希望在一定次数的投掷中掷出多少个 6,或者在没有正面朝上的情况下掷出 10 个公平硬币的可能性。虽然这些例子可能看起来很抽象,但它们实际上是分析人类行为和处理非确定性过程的其他领域的重要思想,因此对数据科学家来说至关重要。

我喜欢的学习或重新学习概率的方法是从组合学开始,这将提供一些关于随机过程如何表现的直觉,然后继续我们如何从这些过程中推导出期望和方差的规则。熟悉这些话题会让你通过一次典型的数据科学面试。

为了专门准备你可能会被问到的概率问题,我会找一些示例问题(这是一个合理的列表,但还有许多其他问题)并在白板上完成它们。练习制作概率树来帮助形象化和思考问题。

阅读内容:的第 1-4 章和第 6-8 章这个概率介绍将涵盖你需要知道的几乎所有内容。

关键思想:随机变量、连续变量与离散变量、排列、组合、期望值、方差

概率分布

与上述主题密切相关的是概率分布。概率分布就是描述随机变量的单个观察值等于特定值或值范围的可能性的分布。换句话说,对于任何给定的随机过程,都有一系列可能的值,并且随机过程的单次抽取有可能采用这些值中的一个。概率分布为给定过程的所有可能值提供了可能性。

与概率一样,了解分布是理解推断和预测统计的先决条件,但你也可能会收到专门关于它们的面试问题。最典型的例子是:您有一个行为类似于 X 的流程——您将使用什么分布来建模该流程?回答这些类型的问题只是将随机过程映射到合理的分布,这篇博文很好地解释了如何做到这一点。

读什么:上面提到的概率介绍的第 5 章,还有这篇关于常见分布的博文

关键思想:概率密度函数、累积分布函数、偏斜度、峰度、均匀分布、正态(高斯)分布、博文中描述的其他分布

中心极限定理和假设检验

一旦你掌握了概率和分布,你就可以专注于科学家是如何进行推理的。关键在于,一旦你有了描述概率分布行为的工具,我们用来总结数据(通常只是平均值)的描述性统计就可以被建模为随机变量的集合。

方便的是,有一个定理告诉我们,给定一个足够大的样本,随机变量的均值会变成正态分布。这被称为中心极限定理(CLT),我已经在这里写了一些细节。如果您已经学习了这方面的内容,那么这篇文章是一个很好的入门或复习的地方。

使用 CLT,我们可以评估给定均值来自特定分布的可能性,这种想法允许我们测试假设。例如,我们可能有一组人的平均身高,并想测试其来自一个平均身高大于 6 英尺的随机过程的假设。知道均值是正态分布的,就可以评估这个命题,并拒绝或未能拒绝我们的假设。

假设检验的面试问题要么是将某些场景映射到适当的检验,要么是阐述假设检验的一些关键思想:p 值、标准误差等。下面的阅读材料将涵盖后一种类型的问题,但对于前一种练习是最好的方法。获取一些样本数据集并尝试提出实际问题,然后阐明假设并选择测试来评估它们。假设你必须向面试官解释这些决定,并相应地练习这些解释。

读什么:Coursera 课程的前三段视频和 dartmouth probability book 中关于假设检验的章节。

关键思想:中心极限定理、样本统计分布、标准误差、p 值、单尾和双尾检验、一型和二型误差、T 检验、其他假设检验

随机化和推断

继续上面的想法,测试人口平均身高等于 6 英尺的假设是合理的,但作为数据科学家,你更经常对因果问题感兴趣。也就是你想知道做 X 会不会导致 y。

例如,一个类似这样的问题:“住在加州会让你变高吗?”更像是科学家想要回答的问题。天真的方法是测量加州人的身高,并测试他们的平均身高大于非加州人的平均身高的假设。然而不幸的是,简单地测量和比较观察到的数据总是会对真正的因果关系产生有偏见和不正确的估计。在这个例子中,有许多与居住在加州相关的事情也会影响人们的身高,所以我们实际上并不知道居住在加州是否会让人变高,或者这些其他事情是否有责任。

解决这个问题的方法是随机化。我们可以随机分配人们住在加州或不住在加州,然后测量这些人的身高。这确保了待遇是两组之间唯一有系统差异的东西,所以身高的任何差异一定是住在加利福尼亚的结果。

这就是企业进行实验的原因,或者如他们在行业 A/B 测试中所称的那样。当您想要了解决策或产品对业务指标的真正因果影响时,随机实验是对结果有信心的唯一方法。

不像概率或分布,除了非常专业的角色,你面试的任何一部分都不太可能关注因果关系。也就是说,理解为什么相关性并不意味着因果关系,以及相对于使用观察数据,何时有必要进行真正的随机测试非常重要,并且肯定会成为数据科学面试过程中出现的话题。你在这方面的准备可能仅限于阅读,而不是白板或解决问题,但它仍然非常重要。

读什么:我有两篇相关的文章,应该会有帮助:一篇关于非实验数据的极限,另一篇关于如何分析 A/B 测试数据。这篇关于网络实验的文章应该很好地完善了基础知识。

如果你想更深入一点,哥伦比亚大学有一些关于因果统计推断的好材料。除此之外,它还介绍了潜在结果框架和 Rubin 因果模型,我强烈推荐给任何对实验感兴趣的人。

关键观点:随机化、因果关系、偏见、自我选择、概化、潜在结果、鲁宾因果模型

预测和机器学习

最后,我们来预测。这是很多人最感兴趣的东西——它包括图像识别、视频推荐、网络搜索和文本翻译等各种主题。显然,这是一个巨大的领域,但我假设你面试的是一个更通才的职位,在这种情况下,任何领域的专业知识都不会被假定。

相反,你希望能够解决面试官抛给你的任何特定的预测问题,并提供一个合理的方法来开始解决它。这通常意味着你需要准备好讨论如何选择一个模型,评估该模型的有效性,然后改进该模型。面试时,我会把问题分解成这三个步骤。

当选择一个模型时,你的决定主要基于以下几点:结果变量的类型和分布,因变量和自变量之间关系的性质,你拥有的数据量,期望的可解释性水平。同样,这里没有正确的答案(尽管经常有错误的答案),所以你只是希望能够对你要做的决定和它们所暗示的权衡进行明智的讨论。

您可能还会被问到您希望在模型中包含哪种特征作为独立变量(预测值)。这主要是一个领域知识的练习:它更多的是关于理解行业和哪些数据可能预测感兴趣的结果,而不是关于统计。讨论还可能涉及特征工程,这将涉及如何以及何时转换变量的一些直觉,以及选择预测器的数据驱动方式(即正则化、降维以及自动特征选择)。

评估模型是一门相对简单的艺术,它涉及到用来验证模型和减轻任何过度拟合问题的维持数据集。关于这个主题的 wiki 可能足以作为一个基线。此外,您希望熟悉不同的评估指标:准确性、ROC 曲线、混淆矩阵等。这种东西是很少开放的,我不期望进入它的微观细节。粗略地了解一下为什么需要维持集以及不同评估指标的优缺点就足够了。

第三步是改进,主要是对特征工程主题进行重新组合,并决定是否有必要收集更多的数据。面试时,确保你第一次尝试一个模型时,给你留下了改进的空间——否则你将很难回答接下来不可避免的关于如何改进的问题。

读什么:学习统计学习的所有元素足以通过面试。

关键思想:回归与分类、线性与非线性、监督与非监督、特征工程、交叉验证、ROC 曲线、精确召回、偏差-方差权衡、提升、打包

请不要死记模型

我概述了一种学习数据科学面试统计学的方法,从基础开始,逐步发展到更高级的技术。这不是武断的——这是因为理解数学构建模块将允许你有效地推理不同的模型,做出好的决定,并明智地谈论你以前从未想过的话题或技术。

相反的方法,不幸的是我和其他人尝试过的方法,是从金字塔的顶端开始,只是记住不同的技术。这是难以置信的无效,因为你最终很难理解一堆脱离上下文的孤立想法,因为你缺乏将所有东西粘在一起并允许你思考新想法的基础知识。所以请不要这样。从概率开始,转向分布,然后处理推理和预测。你会过得更轻松的,我保证。

一如既往,我很乐意回答问题,并在下面的评论中接受反馈。我肯定我在试图涵盖如此广泛的主题时错过了许多东西,所以请随意说出。祝你面试好运!

额外学分:时间序列,贝叶斯

这一部分只是为了突出我没有涉及的内容。我已经谈到了相当传统的推理和预测方法,但是还没有涉及到两个大的统计学领域,这两个领域以非常不同的方式处理这些问题。

一个是时间序列数据的分析,研究一段时间内的数据,以及当数据生成过程不是静态的时你需要应用的特殊技术。第二种是贝叶斯统计,它采用一种完全不同的统计方法,决定将某个领域的先验知识纳入概率评估。这两个领域都很重要,值得了解,但是对于一个典型的多面手面试来说,深入这两个领域中的任何一个都是不寻常的。

如果你现在对学习贝叶斯统计感兴趣,我推荐这篇 datascience.com 邮报作为初学者友好的介绍。时间序列在本帖中有所介绍。

如何赢得面对面的数据科学面试

原文:https://towardsdatascience.com/how-to-ace-the-in-person-data-science-interview-584ca11df08a?source=collection_archive---------1-----------------------

我以前写过关于我最近找工作的文章,但是这篇文章只关注面对面的面试。那一整天,试着让他们眼花缭乱,交叉你的手指,希望你已经为扔给你的东西做好了准备。在参加了大量这样的面试后,我发现他们倾向于遵循一些非常标准的时间表。

你可能会遇到 3-7 个不同的人,在与这些不同的人见面的过程中,你可能会涉及到:

  • 说说你自己吧
  • 行为问题
  • “白板”SQL
  • “白板”代码
  • 谈论你简历上的项目
  • 简单的分析问题
  • 问你自己的问题

说说你自己吧

我以前在谈论手机屏幕时提到过这一点。我处理这件事的方式永远不会改变。人们只想听到你能说出你是谁,你在做什么。我的是某种变体:

我是一名数据科学家,拥有 8 年使用统计方法和分析解决各行业业务问题的经验。我擅长 SQL,R 建模,目前正在学习 Python。

行为问题

几乎每一家与我交谈过的公司都提出了应该用星型模式回答的问题。我在数据科学访谈中看到的最常见的明星问题是:

  • 告诉我你向非技术人员解释技术成果的一次经历
  • 告诉我你改进流程的一次经历
  • 告诉我一个与难相处的利益相关者相处的时间,它是如何解决的

这里的目标是简明清晰地解释的情况、任务、行动和结果

我对“技术结果”问题的回答大概是这样的:

Vistaprint 是一家为小型企业在线销售营销材料的公司(请务必给出背景,面试官可能不熟悉该公司)。我有机会使用 k-means 进行客户行为细分。这包括创建 54 个变量,标准化数据,大量的分析等等。当需要与利益相关者分享我的成果时,我真的将这些信息提升了一个层次,构建了这个故事。我没有谈论方法,而是谈到了谁是客户群,以及他们的行为有何不同。我还强调了这种划分是可行的!我们可以在我们的数据库中识别这些客户,开发针对他们的活动,我给出了我们可能尝试的具体活动的例子。这是我向非技术利益相关者解释技术成果的一个例子。(之后一定要重述问题)。

对我来说,这些问题需要一些准备时间。我从自己的经历中思考了一些最好的例子,并练习说出答案。这次有回报了。在整个面试过程中,我一遍又一遍地被问到同样的问题。

白板

白板 SQL

面试官让你站在白板前回答一些 SQL 问题。如果一份工作描述要求 SQL,这是公平的游戏。在大多数情况下,他们会在白板上贴几张纸。一个是包含(例如)id 和姓名的表(我们称之为 NamesTable),另一个可能包含 id、日期和购买(我们称之为 PurchasesTable)。您明白了这个想法,您将编写 SQL 查询来回答他们的问题。

他们会问一系列问题,例如:

  • 写一个查询来获得所有的名字—
*select names from NamesTable*

  • 编写一个查询来获取姓名和购买情况—
select names, purchasesfrom NamesTable as njoin PurchasesTable as pon n.id = p.id

  • 编写一个查询来获取在某个日期(他们随机选择的日期,这里是 2017 年 12 月)之后购买的商品的名称和购买次数
select names, purchasesfrom NamesTable as njoin PurchasesTable as pon n.id = p.id where p.dates > ‘2017–12–31’

  • 编写一个查询来获取至少购买过两次的人的姓名和购买次数
select names, count(purchases) as cntfrom NamesTable as njoin PurchasesTable as pon n.id = p.idgroup by nameshaving count(purchases) ≥ 2

  • 你明白了。一位面试官曾经问过我一个需要返回到同一个表的查询,但我还没有经历过比这更复杂的查询。

白色登机代码

正如我在之前的文章中提到的。两家不同的公司连续两天问我 FizzBuzz。用 Python 写解决方案的一种可能方式(只是拍了一张我电脑的截图)如下:

编码问题很可能涉及到一些循环、逻辑语句,并且可能需要你定义一个函数。如果在职位描述中提到了某种特定的语言,他们可能希望看到这种语言的答案。招聘经理希望确保当你说你会编程时,你至少已经掌握了一些基本的编程知识。

你简历上的项目

我曾经被问到过我在简历中提到的所有方法(回归、分类、时间序列分析、MVT 测试等)。我在简历中没有提到我硕士学位的论文,但当被问及我以前是否有贝叶斯方法的经验时,我会随意引用它。面试官接着问了一个关于我论文中用到的先验分布的问题。

我在 9 年前完成了论文,不记得以前的事,告诉他我需要跟进。我确实跟进了,并把他的问题的答案发给了他。他们确实给了我一份工作,但这不是你想看到的情景。如果你要引用某样东西,要能对着它说话。即使这意味着在面试前通过查看维基百科来刷新你的记忆。简历上的东西和你提到的项目应该是全垒打。

简单分析题

将会问一些基本问题,以确保你了解数字是如何工作的。这个问题可能需要你画一张图或用一些代数来得到答案,这将表明你有一些商业背景,可以解释正在发生的事情。关于转换率、平均销售价格变化的问题,为什么在这种情况下收入会下降?在这种情况下,您会选择什么型号?通常我会被问两三个这类问题。

在一次面试中,我被问到一个概率问题。他们问掷骰子的期望值是多少。然后有人问我,如果骰子以某种方式加权,那么骰子的期望值是多少。我不被允许使用计算器。

我提出的问题:

  • 告诉我一个你认为是高绩效/高潜力员工的人的行为。

老实说,我用上面的问题来试着了解你是否需要一周工作 60 个小时并在周末工作来成为一个出类拔萃的人。我经常在周末工作,因为我喜欢我所做的事情,如果这是意料之中的,我就不会喜欢。

  • 你正在使用什么软件?

真的,我喜欢在手机刷屏的时候把这个问题解决掉。我个人对为 SAS 商店工作不感兴趣,所以我想提前了解一下。对于这个问题,我最喜欢的回答是“你可以使用任何你喜欢的开源工具,只要它适合这个问题。”

  • 关于我的技能和资格,还有什么我可以告诉你的,让你知道我非常适合这份工作吗?

这是你的机会,让他们告诉你是否有你还没有涉及的,或者他们可能关心的事情。你不想在离开面试时,觉得他们没有得到决定是否聘用你所需的一切。

  • 我什么时候能得到你的消息?

我还询问了报告结构,当然,我还询问了在开始工作后不久我将从事什么类型的项目(如果这还不清楚的话)。

摘要

祝你在数据科学面试中取得巨大成功。希望你能遇到很多优秀的人,并有一个积极的经历。每次面试后,记得发送感谢信!如果你没有收到录用通知,或者没有接受某家公司的录用通知,仍然可以登录 LinkedIn,向他们发送联系请求。你永远不知道什么时候未来的时机会更好,你们的道路可能会交叉。

如果你喜欢这篇文章,请访问我的网站!这里

触及机器学习的本质:CLT 简介

原文:https://towardsdatascience.com/how-to-analyze-learning-short-tour-of-computational-learning-theory-9d93b15fc3e5?source=collection_archive---------7-----------------------

作为机器学习的实践者,了解计算学习理论的基础可以极大地增强你的能力。

介绍

假设,这是一个阳光明媚的日子,你有朋友来访,你最喜欢的餐馆在 12 英里外开了一家分店。一般来说,你会避免长途驾驶,但是今天你会出去吃午饭吗?你是否有这种情况的过去的例子(一些因素是积极的,一些是消极的),从中你制定了一个规则?

这就是我们如何从过去的经验和行为中学习,形成规则,并将其应用于当前的情况。机器也没有什么不同。但是这种机器学习背后也有一个理论。

C 计算 L 收入 T 理论( CLT )是统计学/机器学习/人工智能(总的来说)的一个分支,它处理关于分析我们(人和机器)从数据中学习规则和模式的能力的基本界限和定理。

超越了我们经常听到的特定算法的领域——回归、决策树、支持向量机深度神经网络——并试图回答关于整个机器学习企业的限制和可能性的根本问题

这就是我们如何从过去的经验和行为中学习,形成规则,并将其应用于当前的情况。机器也没有什么不同

听起来很刺激?请继续阅读,快速浏览这个领域…

有哪些基本问题?

当研究机器学习时,很自然会想知道什么一般规律可以支配机器(和非机器)学习者。举个例子,

  • 是否有可能独立于学习算法,识别出天生困难或容易的学习问题类别?
  • 你能描述出确保成功学习所需的或足够的培训示例的数量吗?
  • 如果允许学习者向培训师提问,而不是观察随机抽样的培训示例,这个数字会受到什么影响?
  • 在学习目标函数之前,你能描述一个学习者会犯的错误的数量吗?
  • 有人能描述学习问题类固有的计算复杂性(T21)吗?

下面是令人失望的答案:所有这些问题的一般答案还不知道。

但是我们可以专注于任何实际机器学习任务中最常出现的特定设置,****—归纳学习 一个未知的目标函数,只给定这个目标函数的训练示例和一组候选假设

在这种情况下,我们主要关心的问题是,

  • 多少个训练示例足以成功学习目标函数,以及
  • 学习者会犯多少错误才能成功

正如我们将看到的,根据学习问题的属性,为这些度量设置数量界限是可能的,

  • 学习者考虑的假设空间的大小或复杂性
  • 目标概念必须达到的近似精度
  • 学习者输出成功假设的概率
  • 向学习者展示培训示例的方式

CLT 试图回答关于整个机器学习事业的限制和可能性的基本问题。

关键词的图示

为了进行全面的讨论,我在这里尝试定义一下在 CLT 普遍使用的基本关键词。

****数据:一组给定的例子,我们试图从中学习目标概念。

目标概念(又名规则)**:这是我们试图从数据中学习的隐藏模式例如,“我们出去吃午饭 如果 天气晴朗我们有朋友 如果 最喜欢的美食餐馆就在附近 我们有朋友

这种规则是根据属于命题逻辑的陈述编写的,即用 AND、OR、NOT 表达的真值。

****假设空间:这是一组假设,我们希望从中发现目标概念。在这个例子中,假设的“智能”选择应该看起来像我们上面写的作为目标概念的逻辑连接短语。但是它们可以更简单或者看起来不同,

  • 如果天气晴朗
  • 如果我们有朋友或者天气晴朗

注意上面两个假设和目标概念之间的细微差别。这两个假设不够丰富,不足以抓住真正的目标概念,如果应用于给定的数据,它们会有误差。****

为什么?

因为它们不属于“析取陈述的连词”形式,即(X1 & X2)|(X3 & X4)|(X5 & amp!X6)。它们过于简单和笼统,无法捕捉所呈现数据的所有细微差别。

因此,这个故事的寓意是,你在机器学习(这里是分类)任务中搜索目标概念是否会成功,很大程度上取决于你选择工作的假设空间的丰富性和复杂性。

预测器和响应变量**:这些是不言自明的。“?”、‘最喜欢的餐厅距离、‘有朋友吗?“T9”是预测变量,“出去吃午饭”是响应变量。****

感觉抽象?需要具体例子吗?

还记得分类的决策树吗?这里有两个这样的树,以及它们在关于上述学习问题的假设空间方面的丰富性。

如果你阅读从根开始向下到一片叶子的树的边所满足的条件,你会自动得到和上面一样的命题逻辑陈述。试试看。

Rich and ‘poor’ hypothesis space illustrations

因此,这个故事的寓意是,你在机器学习(这里是分类)任务中搜索目标概念是否会成功,很大程度上取决于你选择工作的假设空间的丰富性和复杂性。

假设空间的大小?那里有个陷阱!

那么,这里假设空间的大小是多少呢?

如果你用所有三个预测变量构建树,你可以从其中的任何一个开始,然后你可以在深度)处有 n 的叶子,如果你使用所有的预测变量。但是你可以选择在所有的叶子上写“是”和“不是”。所以,大小可以和 O(n2(2n)).一样大对于这个例子,有 3 个变量,我们可以得到 32(2(3–1)= 48 棵树!这 48 棵树分别代表一种不同的假设。很多都是多余的,用简单的思考就能消除,但那是题外话。****

那么,如果我们考虑一个足够丰富、足够大的假设空间,是否保证能找到目标概念(给定足够的数据)?

没有。

****考虑一个简单线性回归问题

有多少预测值? 1 。那么,什么是假设空间大小呢?2?4?

答案是——无限****

你能在一个平面上画多少条直线?

你对无害的最小二乘误差最小化回归算法的尊重是不是越来越大了?毕竟,能够从那些无限的可能性中找到最优的路线【T3:-)

但问题是——即使假设空间无限大,我们也不能指望在这个回归任务中找到真正的目标概念。

这是因为真正的概念存在于另一个空间,其大小是一个‘更大的无限’。在这个例子中, yx 之间的真实函数关系可能是二次函数关系。这意味着二次项的无限可能性+线性项的无限可能性+截距的无限可能性。****

除非我们决定在我们的假设空间中包含一个二次项,否则我们将永远无法找到真正的函数,即使在只有线性项(和截距)的无限大的空间中。

****所以,很多时候,我们需要更丰富的空间,而不一定是更大的。而且,像灭霸一样,我们需要不断担心和寻找哪个无限大小的空间最适合我们必须学习的特定数据集!

那么,CLT 试图估算的关键量是什么呢?

在很大程度上,CLT 关注的不是个别的学习算法,而是以他们考虑的假设空间、训练样本的呈现等为特征的学习算法的大类。它试图推理的关键量是,

  • 样本复杂度 :一个学习者
    需要多少训练样本才能收敛(大概率)到一个成功的假设?
  • 计算复杂度 :一个学习者需要多大的计算努力才能收敛(大概率)到一个成功的假设?
  • 错误界限 :在收敛到一个成功的假设之前,学习者会错误分类
    多少训练样本?

Model complexity and learning curve show how much data and what class of hypothesis space we need

有各种各样的方法来说明对学习者来说“成功”意味着什么我们可以指定,为了成功,学习者必须输出一个与目标概念相同的
假设。或者,我们可以简单地要求它输出一个大多数时候与目标概念一致的假设,或者它通常输出这样一个假设。

同样,我们必须指定学习者如何获得训练样本。训练示例有可能是由一位乐于助人的老师提供的,或者是由学习者执行精心计划的实验获得的(想一想 A/B 测试或科学实验),或者是根据学习者控制之外的一些自然过程随机生成的(想一想随机点击流,癌细胞与药物的相互作用)。正如我们所料,上述问题的答案取决于我们心目中的特定环境或学习模式。****

“大概近似正确”(PAC)的神奇世界

在这种理论设置下,我们假设所有观察到的数据都是从一个未知但固定(非时变)的分布过程中产生的,该分布过程的参数不会受到我们从中抽取样本的过程的影响。此外,不失一般性,我们可以假设无噪声测量过程。

H 为假设空间, D 为未知真分布, c 为目标概念。假设在观察了一些数据d* 后,学习算法 L 输出一个它认为是【c的最佳逼近的假设*****

这里衡量错误/成功的标准是什么?误差在哪里 ch 的预测不一致。

Image credit: “Machine Learning”, by Tom Mitchell

我们的目的是描述目标概念的类别,这些目标概念可以从合理数量的随机抽取的训练样本和合理数量的计算可靠地学习****

我们没有无限的时间、计算能力、存储或传感器带宽。因此,我们并不试图使误差为零。为此,我们需要看到由生成的每一个可能的实例。出于同样的原因,我们限制自己检查有限的训练样本,并使用多项式时间算法。**

此外,假设训练样本是随机抽取的,
学习者遇到的训练样本
总会有一些非零概率是误导的。

因此,我们将只要求它的误差被某个常数
限制,该常数可以任意变小。此外,我们不会要求学习者对随机抽取的训练样本的每个序列都成功,相反,我们的要求只是它的
失败概率由某个常数限制,该常数可以任意变小

简而言之,我们只要求学习者 大概学习 一个 近似正确 的假设。

有了这些设置,我们说我们的概念类 C ,目标概念 c 所属的, PAC-learnable如果学习算法在用数据【d】进行训练后能够输出假设 h 具有一定高的 概率 和一定低的 误差 并且计算量是 1/ 误差******

样本复杂性界限

这里我们不讨论形式上的证明,但是根据上一节中讨论的概念,可以推导出一个非常简单和优雅的数学界限来回答下面的问题。

“当假设空间具有一定大小时,以一定概率学习近似正确的假设所需的最小训练样本数是多少?”

界限由下式给出,

这叫做 豪斯勒束缚 。这个不等式很容易证明我们在任何机器学习任务的实践中所经历的以下事实,

  • 我们需要更多的训练数据来减少测试/泛化错误
  • 该算法需要“看到”更多的训练样本,以增加其学习的信心,即减少出错的可能性
  • 更丰富、更大的假设空间意味着在寻找正确假设时要搜索更大的维度,这就需要更多的训练样本

我们短暂的旅行到此结束,但更多的“学习”还在前面

对这种类型的复杂性界限有一种普遍的批评,认为它们过于悲观,不能代表实际的学习问题。关于这个话题有很多争论,你可以从我在本文末尾提供的参考资料中读到一些。

一个关于无限假设空间的自然问题出现了。样本界是否趋于无穷大?原来有一个概念叫做' VC-dimension ' (V 在这里代表 Vladimir Vapnik ,支持向量机的发明者),它有助于保持许多实际学习问题的样本复杂度有限,即使是线性回归或核机器这样的无限假设空间。但是我们可以在另一篇文章中讨论这些高级概念。

我希望这篇文章能够引发一些关于基本机器学习理论的有趣概念,并有助于激发您学习这些主题的兴趣。

要获得关于这些主题的优秀教程,请观看此视频,

可供参考的资料

  1. 《机器学习》,汤姆·米切尔(1997)。
  2. CMU PAC 学习教程
  3. PAC 学习、VC 维度和基于边界的边界
  4. " PAC 学习是不可判定的"
  5. "学习算法的效率和计算限制"

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

如何在命令行上探索美国大学 2017 排名?(第一部分—数据预览)

原文:https://towardsdatascience.com/how-to-analyze-us-university-ranks-2017-with-bash-part-i-data-preview-e39b8f2ffee9?source=collection_archive---------7-----------------------

Keep exploring data @ Bash shell, image adopted with thanks from unsplash.com

大学排名已经成为许多机构的共同任务,每个机构都根据几个加权类别提出不同的排名。这些排名的例子有:世界大学网络计量学排名、QS 世界大学排名、世界大学学术排名等等。第一个排名衡量了大学的知名度及其在网络上的全球表现。最后两项试图根据会员获得的奖项、引用和出版物等类别来衡量大学的表现。雇主,尤其是跨国公司的雇主,使用排名来寻找大学来招聘毕业生,因此进入一所排名靠前的大学有助于在竞争激烈的就业市场中找到工作。

在这个项目中,我们将使用一个从 data.world 获得的简单(公开可用)数据集,名为:美国新闻大学排名 2017 版。从这些数据中,使用 Bash 我们将探索不同的特性,并最终发现一个关于学费和大学排名相关性的有趣事实。

学习目标
通过完成这些,您将学会使用以下 Bash 命令:

head —输出文件的第一部分
tail —与头cat相对—连接并打印文件
sort —整理文件内容
uniq —删除重复条目

在我们继续之前,让我们通过在桌面上创建一个文件夹来设置我们的工作环境。为此,假设我们的计算机上有一个基于 Linux 的操作系统(例如 Ubuntu ),让我们首先启动一个命令行并导航到我们的分析文件夹:

cd ~/Desktop
mkdir unirankingdata
cd unirankingdata

这将在你的桌面上创建一个文件夹unirankdata。接下来,我们下载数据。

您应该从下面的网页下载数据,因为我们已经稍微简化了数据,让我们将数据保存为:unirank.csv

wget https://www.scientificprogramming.io/datasets/unirank.csv

数据集预览
这个数据集很小(玩具),原则上我们可以在文本编辑器或 Excel 中打开它。然而,真实世界的数据集通常更大,而且整体打开起来很麻烦。让我们假设它是一个大数据(和非结构化数据),我们希望得到数据的一个潜在峰值。当你接触到新数据时,这通常是你要做的第一件事——预览;首先,了解数据包含的内容、组织方式以及数据是否有意义是非常重要的。

为了帮助我们预览数据,我们可以使用命令“head ”,顾名思义,它显示文件的前几行。

head  unirank.csv

然而,您会发现最初的输出并不是很有趣,因此我们安装了一个名为csvkit的工具,这是一套用于转换和使用 CSV 的命令行工具(install: sudo pip install csvkit)。

这将极大地帮助我们未来的分析。在我们安装了csvkit之后,我们重新运行head命令,但是通过csvkit套装的csvlook命令输出管道|:

head  unirank.csv | csvlook

您应该会看到输出到屏幕上的文件的前10行,要看到比前10行更多的行,例如第25,请使用-n选项:

head -n 25 unirank.csv | csvlook 

这里,数据集名称unirank.csv是一个命令行参数,它被赋予命令head-n是一个选项,它允许我们覆盖10行的默认设置。这种命令行选项通常用破折号后跟字符串、空格和选项值来指定(例如-n 25)。看下面最后的结局(想不想看直播?):

The unirank.csv data set preview (head -n 25 unirank.csv)

从文件的前 25 行,我们可以推断出数据被格式化为具有分隔值的文件。从第一行(通常称为标题行)和前几行数据可以推断出列内容:NameCityStateTuition and feesUndergrad EnrollmentRank见第二部 🚀!

[该项目是'学习在 Bash Shell 和 Linux 中分析数据课程的一部分。]

相关作品

[## 学习在 Bash Shell 和 Linux 中分析数据——学习科学编程

一个简单的课程演示了 Bash shell 在处理真实数据集时的使用

www . scientific 编程. io](https://www.scientificprogramming.io/learn-bash/)

如何提出数据科学可以解决的问题?

原文:https://towardsdatascience.com/how-to-ask-questions-data-science-can-solve-e073d6a06236?source=collection_archive---------0-----------------------

我的学生经常很难找到好的数据科学问题。

通常,这是因为他们还没有弄清楚问题如何映射到数据解决方案。我发现将布鲁姆的分类法与数据技术结合起来描绘一幅更清晰的画面是很有见地的。

数据科学工具初看起来可能非常有限,但是我们可以用工具的语言重新表述大多数现实世界的问题。

我们可以问什么样的问题?

布鲁姆的分类法对教育者用来引导学生的学习目标进行了分类。我发现对洞察力进行分类也很有用。毕竟,如果我们提供适用的洞察力,我们就扮演了教育者的角色。

布鲁姆的分类学也提出了我们可以问的问题来测试学生。这些相同的问题带来了卓越的见解。

我们将学习过程分为 6 个目标,每个目标都有相关的问题。作为数据科学家,我们可以提出、解决和分享这些问题来获得洞察力。

布鲁姆分类法中的认知目标

  • 记得吗——什么人,什么事,什么地方,什么时候发生了什么事?
  • 了解— 你能总结一下发生了什么吗?
  • 应用— 当……发生时会发生什么?
  • 分析— 什么是……的关键部分和关系?
  • 评估— 这是最好的方法吗?
  • 创造——你能预测在新的条件下……会发生什么吗?

可用工具

(从业者可能想跳过这个概述)

这个行业有很多工具,但是你可以把它们分成几个部分。

R/Python/SQL/Etc

用 SQL,R,Python 等进行数据操作。允许我们搜索和汇总数据。

这些工具回答与记忆和理解相关的问题。“我的最大用户最后一次购买是什么时候?”

假设检验

仅仅因为我们按组划分数据并不意味着我们找到了关系。 假设检验 告诉我们我们的数据是否适用于新的情况。"猫的图片比狗的图片带来更多的流量吗?"

场景分析

情景分析 分析各种条件下未来可能出现的多种结果。我们创造许多可能的场景,然后预测会发生什么。"如果我们提高产品价格,会发生什么?"

优化

优化 是一个巨大的领域,但它一般会问简单却难以回答的,最大化和最小化问题。"什么样的供应路线能最大限度地降低递送包裹的成本?"

强化学习

强化学习实时观察数据并优化结果。"在游戏 Flappy Bird 中,我应该什么时候点击才能生存?"

统计建模与机器学习

这变得很棘手,因为这些是巨大的领域。让我们来看几个主要任务:

  • 分类和回归——“多少…?”,“什么样的…?”
  • 特征选择——“什么变量是相关的?”
  • 降维——“我的数据的关键组成部分是什么?”
  • 聚类——“我能对我的数据进行分类吗?”
  • 异常检测——“这个观察奇怪吗?”

分类回归

分类和回归回答诸如“我的数据和一个或多个结果之间有关系吗?”分类重点预测群体“这是 A 还是 B?”。回归关注数量“多少—或—多少?”

特征选择

特征选择确定数据中的哪些特征与特定结果相关。假设我们想要识别一种水果是苹果还是橘子。我们在数据中使用颜色和甜度作为水果的特征。一个特征选择算法将缩小颜色作为一个有用的鉴别器,因为苹果和橘子都是甜的。

降维

降维获取数据并将其降维至核心成分。这就像图像压缩,我们用较少的信息显示相同的图像。假设我们有一次性刀叉和餐盘的销售数据。一个维度缩减可能显示一次性用具销售的一列。我们大概会问“我的销售数据中的关键模式是什么?”

聚类

聚类试图获取数据,并自动将相似的观察结果组合在一起。我们可以把我们的数据组织和处理成几种类型的观察结果的集合。我们问“我是否有任何不同类型的客户,或者他们都是完全独特的?”

异常检测

异常检测回答一个观测值是否属于数据集。我们大概会问“这个温度读数正常吗,还是很奇怪?”需要注意的是,我们通常可以简化这个问题。一个分类问题,询问“这是不是很奇怪?”就像是的异常探测。

它们是如何组合在一起的?

我在下面列出了常见的数据科学问题,按照布鲁姆的分类法整理。每个问题都被重新表述,以使用一种常见的数据科学技术。问题按照从最容易回答到最难回答的顺序排列。

记住— 什么人,什么事,什么地方,什么时候发生了什么事?

我们用 SQL、R、Python 等来回答关于数据收集和操作的记忆问题。

特定用户使用什么浏览器浏览本网站?

我们使用 SQL、R 或 Python 在数据中找到用户,以及他们使用的浏览器。

特定用户是如何找到这个网站的?

我们使用 SQL、R 或 Python 以及记录的流量源在我们的数据中找到用户。

明白— 你能总结一下发生了什么吗?

我们通过汇总或总结数据来回答理解性问题。

我的用户倾向于使用什么浏览器?

同样,使用 SQL、R 或 Python,我们可以在数据中按浏览器统计用户数量。

应用— 当…,会发生什么?

我们通过要求我们的结果一般化来回答应用问题。 假设检验交叉验证实验方法 是保证通用性的技术。

晒太阳的时间和植物的高度有关系吗?

这是一个 回归 的问题,Y = f(X)。Y =植物高度。f 代表捕捉关系的任何模型。X =植物在阳光下度过的时间。

这款空调在未来 3 年会出现故障吗:会还是不会?

这是一个 分类 的问题,Y = f(X)。Y = {失败,不要失败}。f 代表捕捉关系的任何模型。x 是记录空调故障历史和相关特征的数据。

哪种动物出现在给定的图片中?

这也是一个 分类 问题,Y = f(x),有时也叫多类分类。Y = {狗猫马其他}。f 代表捕捉关系的任何模型。数据 X 是编码成表格形式的图像。

该客户购买产品的可能性是多少?

这是一个 分类 问题,Y=f(X),Y = {买,不买}。x 是与客户购买习惯相关的数据。许多算法将能够给你落入特定类别的概率。

这笔银行交易是否属于欺诈?

这是一个 分类 的问题,Y=f(x)。Y = {欺诈,不欺诈}。x 是银行交易数据。异常检测也可以处理这个问题。异常检测即使你没有贴上欺诈标签的过往数据,也可能行得通,但这是个更难的问题。

分析—……的关键部分和关系是什么?

要回答分析问题,你需要将数据分解开来,寻找模式。 特征选择降维聚类 是关键工具。

哪些因素最能预测电力需求?

这是一个回归与 特征选择 Y=f(X)的问题。Y =所需电量。f 代表任何能捕捉你的数据和电力需求之间关系的模型。x 可能具有价格、温度、季节、地区和许多其他特性。为了找到最重要的因素,我们使用 特征选择 来去除不预测电力需求的因素。

苹果和橘子的主要区别是什么?

这是一个 分类特征选择 的问题,Y=f(X)。Y = {苹果,橘子}。f 代表捕捉数据中关系的任何模型。x 有很多特征,比如身高,体重,颜色,味道,和韧性。 特征选择 找到最能区分苹果和橙子的特征。

在我的 HVAC 系统中,哪组传感器倾向于相互变化(或相反)?

这是一个 聚类 问题,因为我们将相似的传感器彼此分组。我们将传感器数据组织为行,将读数的时间组织为列。**

在我的暖通空调系统中,哪种传感器组合最能显示系统的整体健康状况?

这是一个 降维 的问题。我们获取大量数据,并将其转化为几个关键绩效指标。在这种情况下,我们将不同传感器的数据组织为不同的列。

哪些观众喜欢同类电影?

这很奇怪,因为我们试图将相似的用户和相似的电影分组。这是典型的 推荐引擎 我们还可以写一个更简单的应用程序为“这个用户喜欢这组电影吗?”或者甚至简单到“这个用户会喜欢这部电影吗?”

成功的 CEO 有哪些共同的领导实践?

这乍一看像是一个分组问题。一旦你读懂了字里行间的意思,就会回到关键的区别上来。所有成功的 CEO 都要吃饭,所有不成功的 CEO 也一样。我们对预测成功的因素更感兴趣。

评估— 这是最好的方法吗?

要回答评估问题,您需要将您的数据推断到复杂的假设案例中。

我们能否通过更好地为不同产品定价来节省资金?

这就归结为 场景分析 。我们提出了几种定价方案,然后用模型预测它们的效果。这就很可能涉及到回归 ,以及批判性思维。

创造— 你能预测在新的条件下……会发生什么吗?

创造问题要求你创造新的最优解。

我的送货车应该走什么路线?

这是一个众所周知的 优化 问题。主要标准是在按时交货的同时,尽量减少燃料费用。

我们应该在哪里设立新的办公地点?

这里我们需要优化到一个特定的标准。一个简单的就是利润最大化,但实际上考虑的更多。为了编写一个优化,我们需要能够评估位置。这将我们带回到应用、分析和评估阶段。

我应该把这个广告放在网页的什么位置,这样浏览者最有可能点击它?

你可以把它写成一个优化,但是还有更好的选择。移动一个广告并观察它的表现并不昂贵。这意味着我们可以实验,而不是提前决定。尝试定位广告并测试其效果。你甚至可以通过 A/B 测试 或者 强化学习 来自动化这个过程。

我的自动冷却和加热系统应该将温度调高、调低还是保持不变?

这是 强化学习 的好区域。您的冷却系统会根据输入数据进行调整,如电价、时间和您的偏好。

有了锤子,一切都成了钉子

我们应该先提问。很容易陷入我们的数据和工具中。我们忘记了还有更广泛的问题可以解决。

数据问题遵循从容易到困难的连续体。问许多小问题会带来进步,让你获得意想不到的真知灼见。

如果您觉得这很有帮助,请推荐并分享,点击💚这样其他人就能看到了。

作为数据科学家,如何提出正确的问题

原文:https://towardsdatascience.com/how-to-ask-the-right-questions-as-a-data-scientist-913621907411?source=collection_archive---------7-----------------------

要定义问题陈述

在我们作为数据科学家讨论如何通过提出正确的问题来定义问题陈述之前,让我们试着理解一下为什么提出正确的问题如此重要。

长话短说,当我第一次开始我的第一个数据科学家实习时,我对这个项目非常兴奋,只想尽快动手,对大局没有清晰的认识。

我明白我试图解决的问题。但是我没有深入细节来定义目标和目的。更糟糕的是,我没有质疑给我的用于分析和预测的数据集。经过两个星期的数据清理和分析,我才意识到我对数据做了错误的假设——这一切都是因为我对问题和数据缺乏了解。

这是我的小故事。

我相信提出正确的问题和定义问题陈述是许多数据科学初学者(包括我)面临的一些挑战。

你看。提问很简单。每个人都能做到。但是问正确的问题有些微妙,因为我们不知道什么正确的问题被认为是正确的

在这篇文章中,我将与你分享一些关于如何提出正确的问题并随后定义问题陈述的要点和指南。我希望这将重新定义或在某些方面帮助你的方法来应对这些挑战。

我们开始吧!

如何通过提出正确的问题来定义问题陈述?

(Source)

不管承认与否,定义问题陈述(或数据科学问题)是数据科学管道中最重要的步骤之一。

一个定义明确的问题已经解决了一半

—查尔斯·凯特林

在接下来的部分中,我们将通过四个阶段来定义问题陈述。

所有的问题都应该朝着这个方向发展,以便在形成问题陈述之前更好地理解项目。

1.了解需要解决的问题

需要确定的机会是什么?您的利益相关者面临的痛点是什么?

通常情况下, Kaggle 竞赛上的问题陈述都是定义明确的,我们被给予数据集来处理,而不必担心问题陈述如何对他人有益,或者如何获得数据等。

太好了。

现在的问题是,在真实的工作环境中,问题是没有定义的。他们看起来模棱两可。他们含糊不清。

而且大多数时候(如果不是全部的话),利益相关者只会给我们一个问题:我有这个“问题”,你能帮我解决这个吗?句号。

短而不甜。

我们的任务是帮助他们将问题框定为数据科学问题陈述,真正设身处地地为他们着想,从他们的角度看待事物和问题。

换句话说,我们需要有同理心。

提问可以帮助你更好、更深入地理解问题的问题,因为利益相关者拥有问题的领域知识。我们的任务是从他们那里学习领域知识,并将我们的技术知识与数据结合起来,提出一个推动商业价值的解决方案。

2.根据问题评估形势

一旦我们确定了一个数据科学问题,接下来要做的事情就是评估与该问题相关的情况。

这意味着我们需要谨慎分析风险、成本、收益、意外情况、法规、资源和情况要求。

为了进一步说明,这通常可以分解为以下几个问题:

  • 问题的要求是什么?
  • 有哪些假设和约束?
  • 有哪些资源可用?这是在人员和资金方面,如计算机系统(GPU、CPU 可用)、仪器等。

3.了解项目的潜在风险和收益

这一步是可选的,取决于项目的大小和规模。

一些项目可能只是处于探索阶段,因此,如果项目投入生产,潜在的风险可能会更低,将来会有更大的收益。

  • 与这个项目相关的主要成本是什么?
  • 潜在的好处是什么?
  • 追求项目有什么风险?
  • 潜在风险的偶然性是什么?

回答这些问题有助于您更好地了解情况,以及更好地理解项目所涉及的内容。深入了解项目有助于我们评估之前定义的问题陈述的有效性。

4.定义评估项目的成功标准(或衡量标准)

这很重要。

你不希望有一个雄心勃勃的项目,有一个问题陈述要解决,最后才意识到你没有任何度量来衡量和评估项目的成功。

这可以归结为一个简单的问题:你希望在项目结束时实现什么?

成就应该是可衡量的,而不是无法量化的抽象事物。一些指标可能不会立即可用,因此需要数据收集和预处理。

当问正确的问题时,您必须与利益相关者讨论要使用的度量标准,这种讨论应该总是在早期进行。

定义成功标准非常重要,因为这将帮助您在项目的整个生命周期中评估项目。

最后的想法

(Source)

最终,我们的最终目标是制定更好的问题和定义明确的问题陈述,以使用数据科学方法解决问题,并生成业务见解和推动可行的计划。

感谢您的阅读。我希望这篇文章能让你了解提出正确问题的重要性,以及如何构建问题陈述。

一如既往,如果您有任何问题或意见,请随时在下面留下您的反馈,或者您可以随时通过 LinkedIn 联系我。在那之前,下一篇文章再见!😄

关于作者

阿德蒙德·李 目前是东南亚排名第一的商业银行 API 平台 Staq 的联合创始人/首席技术官。

想要获得免费的每周数据科学和创业见解吗?

你可以在 LinkedIn 、 Medium 、 Twitter 、脸书上和他联系。

** [## 阿德蒙德·李

让每个人都能接触到数据科学。Admond 正在通过先进的社交分析和机器学习,利用可操作的见解帮助公司和数字营销机构实现营销投资回报。

www.admondlee.com](https://www.admondlee.com/)**

如何使用购买数据和几行 Python 代码自动细分客户

原文:https://towardsdatascience.com/how-to-automatically-segment-customers-using-purchase-data-and-a-few-lines-of-python-36939fb587a4?source=collection_archive---------9-----------------------

用简单的数据分析技术学习“客户细分”的小型教育项目

Automatic Customer Segmentation using Recency/Monetary Matrix — Right: Photo by Michael on Unsplash

您为什么应该关注客户细分?要向客户提供个性化体验,细分是关键。它可以洞察客户的行为、习惯和偏好,使您能够提供量身定制的营销活动,增加您的成功几率,并通过量身定制的内容改善客户体验。

Customer Segmentation

我们要建造什么?使用交易购买数据,我们将能够创建一个 2 x 2 价值矩阵来创建 4 个客户群。每一组都将根据两个维度来区分其他组:(1)当前客户价值,和(2)潜在客户价值。

我们要用什么技巧?我们将使用 RFM 模型从交易型采购数据中创建所需的功能。RFM 模式代表着:

  • 最近:他们最后一次购买是什么时候?
  • 频率:他们购买的频率和持续时间?
  • 货币价值/销售额:他们购买了多少?

它通常用于在每三个问题的交叉点识别最高价值的客户。为了构建 2 x 2 矩阵,我们将只使用 RFM 的 R &。

RFM Model

我们使用的是什么数据?我们将使用 Tableau(也称为“全球超市”)提供的购买样本数据集。它通常用于预测和时间序列分析。它包含 1500 多个不同的客户和 4 年的购买数据。因为我们做的是行为细分,而不是人口统计细分,我们将通过只过滤 B2C 细分市场(消费者)和美国国家来消除一些潜在的人口统计偏见。

我们采取什么方法?

  • 步骤 0: 在客户级别加载、过滤、清理和聚合数据,
  • 第一步:为每个客户创建 RFM 功能,
  • 第 2 步:为了实现细分自动化,我们将使用 80%的分位数来表示近期和货币(我们也可以使用 k-mean 聚类或杠杆业务知识来创建存储桶,例如,全球超市企业用户将活跃客户视为最近订单不到 100 天的人)。
  • 第三步:计算 RM 评分,对客户进行排序,
  • 第四步:可视化价值矩阵,探究一些关键数字。

蟒蛇道:

  • 步骤 0: 在客户级别加载、过滤、清理和聚集数据
import matplotlib as plt
import numpy as np
%matplotlib inline  
import warnings
warnings.filterwarnings('ignore')
import pandas as pd
url = '[https://github.com/tristanga/Data-Analysis/raw/master/Global%20Superstore.xls'](https://github.com/tristanga/Data-Analysis/raw/master/Global%20Superstore.xls')
df = pd.read_excel(url)
df = df[(df.Segment == 'Consumer') & (df.Country == 'United States')]
df.head()
  • 步骤 1: 为每个客户创建 RFM 功能
df_RFM = df.groupby('Customer ID').agg({'Order Date': lambda y: (df['Order Date'].max().date() - y.max().date()).days,
                                        'Order ID': lambda y: len(y.unique()),  
                                        'Sales': lambda y: round(y.sum(),2)})
df_RFM.columns = ['Recency', 'Frequency', 'Monetary']
df_RFM = df_RFM.sort_values('Monetary', ascending=False)
df_RFM.head()

  • 第 2 步:为了实现自动分割,我们将使用 80%的分位数来表示近期和货币
# We will use the 80% quantile for each feature
quantiles = df_RFM.quantile(q=[0.8])
print(quantiles)
df_RFM['R']=np.where(df_RFM['Recency']<=int(quantiles.Recency.values), 2, 1)
df_RFM['F']=np.where(df_RFM['Frequency']>=int(quantiles.Frequency.values), 2, 1)
df_RFM['M']=np.where(df_RFM['Monetary']>=int(quantiles.Monetary.values), 2, 1)
df_RFM.head()

  • 第三步:计算 RFM 分数,对客户进行排序
# To do the 2 x 2 matrix we will only use Recency & Monetary
df_RFM['RMScore'] = df_RFM.M.map(str)+df_RFM.R.map(str)
df_RFM = df_RFM.reset_index()
df_RFM_SUM = df_RFM.groupby('RMScore').agg({'Customer ID': lambda y: len(y.unique()),
                                        'Frequency': lambda y: round(y.mean(),0),
                                        'Recency': lambda y: round(y.mean(),0),
                                        'R': lambda y: round(y.mean(),0),
                                        'M': lambda y: round(y.mean(),0),
                                        'Monetary': lambda y: round(y.mean(),0)})
df_RFM_SUM = df_RFM_SUM.sort_values('RMScore', ascending=False)
df_RFM_SUM.head()

  • 第四步:形象化价值矩阵,探索一些关键数字
# 1) Average Monetary Matrix
df_RFM_M = df_RFM_SUM.pivot(index='M', columns='R', values='Monetary')
df_RFM_M= df_RFM_M.reset_index().sort_values(['M'], ascending = False).set_index(['M'])
df_RFM_M# 2) Number of Customer Matrix
df_RFM_C = df_RFM_SUM.pivot(index='M', columns='R', values='Customer ID')
df_RFM_C= df_RFM_C.reset_index().sort_values(['M'], ascending = False).set_index(['M'])
df_RFM_C# 3) Recency Matrix

Final Matrix

一些简单销售的外卖/速赢&营销策略示例?

  • 处于“空闲”阶段的客户很少,他们的平均收入高于“明星”阶段。因为它们很少,所以应该很容易与业务合作,以了解在客户级别发生了什么。根据分析,可能会有一个简单的快速获胜方法:通过电话或会议重新激活他们中的一些人,希望他们回到“明星”行列(例如,参与的客户)。
  • “轻量级”客户的平均最后订单时间非常长(超过 1 年,而“参与型”客户为 60-70 天)。利用优惠券发起简单的重新激活活动可能会带来一些新订单,并帮助其中一些客户转向“新”类别(例如,已参与的客户)。

Simple Tactics Examples

该笔记本在 Github 上有售。感谢你阅读我的帖子,如果你喜欢,请鼓掌。如果您想在您的组织内进行简单或更复杂的 RFM 细分,请随时联系我。

通过 Python k-means 了解 RFM 更多信息的其他有趣读物:

[## 用于客户细分的 k-均值聚类:一个实例

客户细分是一个听起来似乎很简单的概念。概括地说,目标是将客户分为…

www.kimberlycoffey.com](http://www.kimberlycoffey.com/blog/2016/8/k-means-clustering-for-customer-segmentation)

如何用 SHAP 避开机器学习黑箱

原文:https://towardsdatascience.com/how-to-avoid-the-machine-learning-blackbox-with-shap-da567fc64a8b?source=collection_archive---------9-----------------------

Kazimir Malevich’s 1915 “Black Square”

我相信我们都同意这样的观点,机器学习给科技产品带来了巨大的进步,因此也给我们所有人的福祉带来了巨大的进步。然而,从事机器学习的公司和研究人员面临一个巨大的挑战:“黑盒算法”

黑盒算法可以被宽泛地定义为其输出不容易解释或者完全不可解释的算法。意思是你从一个输入得到一个输出,但是你不明白为什么。更不用说 GDPR 对“解释权”的强化,避免黑盒算法事关透明度和问责制——这是任何公司都应该努力追求的两个价值观。

考虑到这一点,我最近开始探索的一个非常好的工具是 SHAP,它代表沙普利附加解释

什么是 SHAP?

这个框架通过提供直观和交互式的可视化,旨在显示哪些特征与某个预测和模型整体更相关,从而使任何机器学习算法本质上都变得“可解释”。

我不会过多地钻研理论部分——SHAP 背后的 UWashington 的研究团队在他们的 NIPS 论文中解释了这一点——但基本想法是在最初训练的模型之上训练一个更简单和可解释的模型(即线性回归或决策树),以便它接近最初的预测。这样,这些预测现在可以用更简单的模型来解释了。

我想和你们分享我在一个开放数据集上的框架实现,以及我们能从它那里得到什么类型的解释。

SHAP 教了我们什么?

我从波士顿数据集开始(查看功能首字母缩略词含义的链接)。该数据集包含由美国人口普查局收集的有关波士顿地区住房的信息,其中的目标变量是中值房价。我在这个数据集上训练了一个 XGBoost 学习者,使用 GridSearch 进行了超参数优化。

现在,让我们看看 SHAP 的输出。

预测解释器

第一张图表旨在解释个人预测。在这种情况下,我选择了测试集的第一个样本。我们可以看到,该模型预测的中值房价为 16.51 英镑(16 510 美元)。此外,我们可以看到哪些功能有助于提高(红色)或降低(蓝色)该值。在这种情况下,LSTAT 等于 4.98 是证实目标变量的最明确的特征,这意味着它提高了预测值。另一方面,RM、NOX 和 DIS 的值会降低预测值。

模型解释器

这张图表的目的是从整体上解释这个模型。它将所有样本绘制在 x 轴上(在本例中,按照相似性排序,但可以在组合框中更改),并将它们的预测值绘制在 y 轴上。此外,基于特征值,它还具有每个样本的每个特征的单独贡献。

在本例中,我选择了样本号 60 (x 轴),其预测值为 10.01 (y 轴),其中 RM 和 LSTAT 是最相关的要素,但它们会降低预测值。但是,只要将鼠标悬停在其他样本上,就可以看到特征值及其影响如何变化,以及预测结果如何变化。

依赖图

在这个图表中,我们可以看到两个特征是如何根据它们在模型中的影响而相互关联的,通过 SHAP 值(模型中特征相关性的度量)来衡量。SHAP 值也可以被视为一个几率——值为-2 意味着观察到该特征会将你获胜的对数几率降低 2,这里的“获胜”只是意味着拥有一栋更昂贵的房子。

在这种情况下,我们可以看到,对于低于 7 (x 轴)的 RM 值,SHAP 值(y 轴)实际上总是负的,这意味着该特征的较低值会将预测值向下推。此外,如果 RM 等于 6,则 SHAP 值可以在-2.5 和 0 之间,具体取决于 RAD 的值。这意味着,如果你也有一个良好的高速公路(RAD)的可达性,那么拥有更少的房间(RM)就不那么糟糕。请注意,RM 低于 5 和高于 7 时,这种垂直分布变窄了很多,这证明其他功能(如 RAD)失去了很多影响。

汇总图

这两个图表显示了相同输出的不同可视化,这是对模型作为一个整体的特性相关性的一般评估。第一个图表有一些附加信息,因为它考虑了每个单独预测的特征相关性(描述为一个点)。此外,对于每个特征,它显示了该特征的较高或较低值如何影响它同意或不同意预测的事实。

作为一个例子,我们可以看到 LSTAT 是迄今为止最有影响力的特征,无论是积极的还是消极的。在这种情况下,较低的 LSTAT 值似乎会对预测产生积极影响。我们还可以看到,RM 具有相反的行为—更高的值导致更高的预测值。

当我们考虑缩略语的含义时,这一切都是有意义的。预计较低的人口比例(LSTAT)和较高的房间数量(RM)都会导致更贵的房子。

正在总结…

没有什么比尝试更好的了,对吧?我的建议是:从一个开放的数据集开始,也许是一个分类数据集,如虹膜数据集,训练一个适当的模型并运行框架。

提示:另外,看看斯科特·伦德伯格在 TDS 上的帖子,他是《SHAP》的原创者之一😉

荟萃分析中的三个常见错误

原文:https://towardsdatascience.com/how-to-avoid-three-common-mistakes-in-meta-analysis-eb64427e8569?source=collection_archive---------7-----------------------

元分析已经成为一种流行的工具,用来综合研究一个普通研究问题的大量工作的数据。由于这提供了一种假定的客观方法来总结大量数据,它已经成为制定健康指南时证据的黄金标准。

然而,荟萃分析中有几个问题会导致不准确。由于这些限制,元分析——或者借用早期批评者的一个术语“超级愚蠢”——几乎自该方法问世以来就一直受到批评。

有几个工具有助于确保元分析的质量,这将在本文稍后概述。但是首先,让我们考虑一下这个(虚构的)摘录,它来自一个荟萃分析的结果部分,我将用它来简要说明荟萃分析中的三个常见问题:

“正如假设的那样,综合七项研究的八个效应大小的荟萃分析表明,社交媒体的使用与自我报告的焦虑水平正相关[r = .073,95% CI ( .004,0.142];p = .038 图 1A】。Egger 的回归测试表明没有发表偏倚的证据(p = .19 图 1B)。”

Figure 1. The relationship between social media usage and self-reported anxiety. The forest plot (a) visualises point estimates for a set of hypothetical studies with filled squares. The diamond reflects the estimated summary effect size. The funnel plot (b) illustrates each effect size against its standard error

当这位虚构的作者——他恰好也在发行一本关于社交媒体危险的书——最初搜索研究时,他们实际上找到了 9 项符合入选标准的研究。然而,九项研究的荟萃分析的汇总效应大小[r= . 062,95%可信区间(- .004,0.127)]与. 061 的p值相关(图 2)。

Figure 2. The original set of studies for the assessment of the relationship between social media usage and self-reported anxiety. Upon realising that the removal of study six would result in a statistically significant result, our fictitious researcher removed this study using a post hoc justification. Meta-analysis pre-registration would have prevented a post hoc adjustment of exclusion criteria dressed up as being a priori

由于这一结果会阻碍出版(和图书销售)的机会,他们进一步研究了研究六,该研究报告称社交媒体使用和焦虑水平之间存在负相关。这项研究恰好是纳入荟萃分析的最早研究。

研究六没有包括 Instagram 的使用(在 2012 年开始流行),所以他们调整了资格标准,只包括 2013 年以来发表的研究,这是由(事后)假设证明的,即 Instagram 的使用与焦虑最相关。

Is Instagram usage associated with anxiety? Probably not, but our fictitious author used this idea as a post hoc justification for removing a study from their meta-analysis

随着研究的删除,荟萃分析变得具有统计学意义。虽然这个虚构的场景乍一看似乎很极端,但在 2000 多名接受调查的心理学家中,近 40%的人承认,在考虑了这样做的影响后,他们已经排除了数据。

预注册您的分析计划

荟萃分析预注册为分析灵活性提供了一种补救措施,因为它提供了研究者分析意图的先验记录。在上面的例子中,排除标准在分析之前就已经指定了。

对预注册分析的一个常见批评是它们没有提供分析的灵活性。然而,这是不正确的,因为预先登记并没有将研究人员锁定在特定的计划中,而是有助于清楚地描述预先计划的和探索性的分析。

在上面的例子中,研究者可以自由地报告他们的分析,但是他们必须陈述他们的推理,这充其量是站不住脚的。作为指导,系统评价和荟萃分析方案的首选报告项目( PRISMA-P )文件提供了荟萃分析方案中应解决的项目列表。

荟萃分析预注册有多种选择。首先,遵循 PRISMA-P 指南的带时间戳的荟萃分析协议可以上传到开放科学框架。

第二,如果荟萃分析调查了一个健康相关的结果,它可以在 PROSPERO 预先注册。PROSPERO 网站通过一步一步的登记表来指导研究人员,该登记表用于生成预注册记录。这些记录可以修改,但任何更改都有时间戳。

第三,元分析方案可以提交给许多期刊进行同行评议,如系统综述。虽然同行评审过程显然比上传方案花费更多的时间,但它可以提供重要的反馈,从而改善荟萃分析。

第四,可以使用注册报告格式提交荟萃分析,其中荟萃分析分两个阶段进行审查。在第一阶段,荟萃分析介绍和方法部分在数据收集前进行同行评议。如果研究原理和方法被认为是合适的,杂志将提供最终论文的临时验收。

An overview of the Registered Reports format (Source: Center for Open Science)

一旦收集和分析了数据,论文再次提交给第二阶段审查,第二阶段审查包括与第一阶段相同的导言和方法,但增加了结果和结论。在第二阶段的审查中,重点是结果和解释是否符合预先批准的方法。

重要的是,论文的接受不取决于结果的统计学意义。截至 2018 年 8 月,有 42 种期刊提供注册报告荟萃分析,其中大多数期刊发表生物行为科学的研究。

出版偏差

在荟萃分析中,发表偏倚是一个公认的问题。由于有统计学意义的研究更有可能被发表,对于任何给定的研究领域,很可能有几个不重要的研究被搁置在研究者的文件抽屉里,这对荟萃分析没有帮助。

How much data is left to be forgotten in file drawers or lab archives?

因此,荟萃分析汇总效应大小可能不能最好地代表“真实”效应大小。评估发表风险的一种常见方法是构建漏斗图,根据方差(例如,标准误差)的测量值绘制影响大小。对称的漏斗图表明发表偏倚的风险较低。尽管目测漏斗图来评估不对称的证据存在固有的主观性,但许多研究人员仍然依赖这一工具。

现在让我们回到我们想象中的书房。由于我们虚构的研究人员意识到主观漏斗图评估的问题,他们通过构建漏斗图客观地评估了不对称性。由于研究人员不擅长从漏斗图中识别不对称,他们遵循建议,进行了艾格回归测试来补充漏斗图(图 1A)。

It can be hard to subjectively decide whether a funnel plot looks asymmetrical, especially if there’s a conflict of interest

统计显著性检验表明漏斗图不对称。在这种情况下,测试没有统计学意义( p = .19)。因此,我们的研究人员得出结论,不存在发表偏倚的风险。然而,仔细观察这些数据会发现,这个结论很可能是不正确的。

对漏斗图及其相关测试的一个常见误解是,它们测量的是发表偏倚,而实际上它们测量的是 小研究偏倚。这种类型的偏倚可能包括发表偏倚,但也包括通常与小型研究相关的其他类型的偏倚,如研究质量。

一个相对简单的漏斗图修改,称为轮廓增强漏斗图,可以帮助更好地理解与小研究偏倚相比的发表偏倚的风险。对于给定范围的效应大小和方差,可以计算出每一点的统计显著性水平。因此,可以在漏斗图上显示统计显著性的范围(例如, p = .05 至. 01)。

将我们的原始漏斗图(图 3A)与轮廓增强漏斗图(图 3B)进行比较,发现尽管没有漏斗图不对称的明显证据,但一半包含的效应大小的p-值非常接近. 05。可用的 p 值的一半如此接近 0.05 是非常不可能的。要么这些重要的研究也是选择性分析的结果,要么存在一些未发表的研究。

Figure 3. A comparison of conventional meta-analysis funnel plots vs. contour-enhanced funnel plots. Compared to the original funnel plot (a), which is also presented in Fig 1B, a contour enhanced funnel plot (b) visualises ranges of statistical significance. The gray-shaded region corresponds to p-values between .10 and .05, whereas the dark gray-shaded region corresponds to p-values between .05 and .01

已经开发了几种措施来纠正荟萃分析中的偏差,如 p 曲线、 p 均匀和三参数选择模型,后者展示了优越的性能。但是如果没有未发表的研究,这些方法充其量只能是估计。这种情况的一个合理的解决方案是进行元分析,只包括预先注册的实证研究,如 Gronau 及其同事最近关于“权力姿态”的元分析。

The idea that adopting an ‘expansive’ body posture makes people feel more powerful makes for a nice story (and TED talk) but the evidence supporting this effect is shaky

现在我们来看看荟萃分析中的最后一个常见问题:效应大小依赖性。请注意,在之前的荟萃分析例子中,有八个效应量,但只有七项研究?这是因为从研究四中提取了两个效应大小(图 1A)。这是一个常见的现象,因为论文有时会报告几个结果指标。

然而,由于这些效应大小来自相同的研究人群,它们在统计上是相关的。由于典型的荟萃分析程序假设效应大小在统计上是独立的,合并相关的荟萃分析会导致有偏的结果。

有几种方法可以解决荟萃分析中的统计相关性问题。首先,您可以简单地为每个研究选择一个效应大小。虽然简单明了,但需要一个预先指定的系统来帮助选择所选的效果大小,否则很容易选择最大的效果。此外,这种方法从您的分析中排除了潜在的有价值的效应大小。要包括一项研究中的多种效应,可以对效应进行统计汇总。但要做到这一点,你需要包括一个研究内相关性的测量,这几乎从来没有在论文中报道过。

如果论文包含原始数据,可以计算出几乎同样罕见的研究内相关性。因此,如果采用这种方法,研究人员几乎总是需要估计研究内的相关性。或者,稳健方差估计可用于说明效应大小依赖性,无需了解研究内相关性。

元分析是更好地理解不同研究领域的重要工具。这种方法可以提供一个研究领域的更客观的总结,而不是简单地“计票”重要和不重要结果的数量。

但是就像几乎所有的统计工具一样,如果使用不当,元分析会导致不准确的推论。通过这篇文章,我希望已经提供了一个简要的概述,强调了元分析中的一些常见问题和这些问题的实际解决方案。

这是一篇文章的编辑版本,这篇文章将发表在由挪威科技大学的学生创办的心理学杂志《NTNU 》上。这里的是一篇可引用的文章的预印本,执行本文所述分析的 R 脚本和数据可从这里的获得。我感谢 Psykologisk Tidsskrift 的编辑好心地允许我以博客的形式转贴这篇文章。

如何成为一个糟糕的数据科学家!

原文:https://towardsdatascience.com/how-to-be-a-bad-data-scientist-434dfb5a209c?source=collection_archive---------4-----------------------

所以,你想成为一名数据科学家,或者更好地说,你认为你现在是一名数据科学家,并且你已经为你的第一份工作做好了准备…我们要确保你不是我下面列出的“想成为数据科学家”的刻板印象之一,否则你很可能会在面试中遭到无数次拒绝。我不认为这是所有刻板印象的完整列表。其实如果你还能想到其他的刻板印象,请在评论里分享吧!这只是我随着时间的推移见过或见过的一些人的刻板印象,可悲的是,这些人似乎一遍又一遍地重复着。

我想成为一名数据科学家【因为钱】我该从哪里开始?

这种类型的人听说数据科学可以赚大钱,并想从中分一杯羹…这种类型的人很少知道学习完成工作所需的知识和技能需要付出大量努力。这类人也很少知道数据科学是一项持续的研究工作。很少有一条清晰的解决之道摆在你面前。对于深度学习来说更是如此,每天都有新的技术和想法涌现,你必须提出新的想法。如果你需要在社交媒体上发布问题“我从哪里开始?”你不具备成为一个人的条件。获得一种学习一切的态度,建立一种创新精神,然后再回来。

我会做数据科学,请给我“干净”的数据。

如果你刚刚学完一门数据科学课程,或者希望学完几门。如果你进行了一个或几个类似 Kaggle 的比赛,你可能会有这样的印象:数据都是经过清理的(或基本上准备好了),通过几条语句或命令,就可以很好地为机器学习做好准备了。事情是那些课程和竞赛为你准备了数据,让你更快的去了解问题的核心,学习机器学习的题材。在现实生活中,数据无处不在。它是不受控制的,你必须自己准备。你可能要自己去收集。大多数数据科学家的工作很大一部分是处理数据、准备数据、清理数据等。如果你还没有这样做,找出一个你自己的问题,端到端地解决它,然后再回来。

我不懂数学或者我不擅长数学,但是人们说我可以做数据科学。

不,这是一个谬论。如果你没有数学头脑,总有一天你会陷入无法再进步的境地。好的是可以学数学。首先,走出“这太难了”的综合症。反正数据科学比较难,最好从数学这种简单的开始。学点微积分,学点统计学,学说话,学数学思考然后以后再回来。

给我一个“很好”定义的问题。

有些人只是希望他们的小盒子有明确定义的接口,什么进来,什么应该出去。再一次,一个刚刚在这个领域做了一些很好的课程的人的综合征…在现实中,不仅数据是混乱的,而且你必须解决的问题是混乱的,不明确的,模糊的…你必须弄清楚它。有时候你可以自己定义,自己提炼,有时候你要接受这种杂乱,自己摆弄。如果你不能得到模糊和近似的目标,并通过思考、研究和与利益相关者的讨论来完善它们,直到找到解决方案,就不要指望成为数据科学家。这里有一个很大的误解是,如果你有一个博士学位,你就可以对这个问题免疫…嗯,没那么快,我见过博士和其他人一样在这个问题上挣扎。所以,长点骨气,接受挑战,然后再回来。

我学过数据科学,我有一个博客/作品集/…我可以做任何事情。

没那么快。这种人学习数据科学,更加以营销为导向,知道它可以帮助建立个人品牌,建立自己的投资组合或写博客、文章等。但是从来没有在现实生活中亲自尝试过。那个人认为他什么都知道,他能解决任何问题。这种类型的人很可能独自对数据科学和机器学习可以实现的东西的过度宣传负责,并且对专业人员来说是一个问题,而不是任何帮助。做些真正的工作,变得诚实些,然后再回来。

如果你想成为一名数据科学家,这可以归结为一个简单的秘诀。努力学习,努力工作。你必须走自己的路,并投入热情。沿着你的兴趣寻找增长知识,了解它,尝试事情。不断学习新的东西,不仅仅是相关的科目。不要把自己局限在课程上,找真实世界的例子来练习,对你能做什么,对你知道什么和不知道什么保持诚实。做个善良的人类!

原载于 2018 年 2 月 27 日【thelonenutblog.wordpress.com

封面图片由Pixabay组成。

如何成为一名数据科学家

原文:https://towardsdatascience.com/how-to-become-a-data-scientist-8c0ea546ab81?source=collection_archive---------1-----------------------

几周前,我编写并发布了我的第二个 Kaggle 内核。我被他们的“ML 和数据科学的状态”调查所吸引,并认为我将能够提取一些有趣的见解。考虑到大多数编写内核的人很可能是已经建立的数据科学家,我想大多数编写内核的人会对如何开始之外的事情感兴趣。

令我惊讶的是,我赢得了他们每周一次的内核奖,我的内核最终得到了比我写它时想象的更多的关注。

无论如何,我写这篇文章是为了分享我通过编写内核所学到的东西。让我们开始吧。

程序设计语言

据我所知,有两种语言在数据科学社区中使用得最多,它们是 Python 和 R。我个人更喜欢 R,但我很好奇这在现实世界中是如何进行的。

在这里,我根据职位比较了在工作中选择 Python 或 R 作为主要编程语言的受访者人数。事实证明,除了统计学家和运筹学之外,Python 几乎在每一个角色中都胜出。然而,在这两个角色中,尤其是对于运筹学来说,样本量很小,结果可能不太显著。

专业和可能的职位

我还在上高中,所以当然还没到必须申报专业的时候。我很想知道什么专业倾向于扮演什么角色,所以我制作了一个图表来比较大学专业和职位。

当然,计算机科学专业的学生会成为计算机科学家、程序员和软件工程师。数学专业进入预测建模,数据科学和统计学,物理专业倾向于研究。

我个人喜欢这张图的地方是,我仔细检查了这张图,以确保每个职位至少有一个人来自曾经的专业。对我来说,这说明只要激情还在,你在学校学的东西不应该束缚你去做你想做的事情。

学习资源

学习数据科学的在线资源永远不会短缺。有时候,这些资源的数量可能会让人不知所措,所以我很好奇,想看看调查的受访者认为哪些是最有用的。

事实证明,人们发现创建项目、参加课程和参加 Kaggle 挑战是学习数据科学最有用的方式。这确实反映了我所认为的真实情况;我喜欢做兼职项目,亲眼目睹了它们如何帮助我成长为一名工程师。

重要的工作技能

调查中的另一个问题是问受访者他们认为什么技能在工作中最有用。我用这个问题的数据重新创建了上一个问题的图表,来看看这些技能是如何相互叠加的。

Python 和统计学知识无疑被认为是最有用的工作技能。r 在这里有点落后于 Python,这反映了我们在第一张图中看到的情况。让我感到有趣的一件事是,MOOCs(大规模开放在线课程)在有用性方面得分最低,而在最后一张图中,课程被认为是学习数据科学最有用的资源之一。可能受访者没觉得 MOOCs 应该作为求职时的一个认证?我不能肯定地说,但是那是我最好的猜测。

现实世界中的傻瓜

受访者还被问及他们认为哪些技术在工作中最有用。我创建了一个表格,对所有受访者以及特定角色进行了分析。

与我们到目前为止所看到的一样,Python 被评为整个行业的头号技术,在这里展示的每个角色中都是如此。r 紧随其后,在业界排名第三,SQL、Jupyter、Unix 和 TensorFlow 在每个角色中都有出现。这向我表明,这些可能是在不久的将来要掌握的最重要的技术。

现实世界中的方法

与上一个问题类似,受访者被问及他们在工作中最常用的数据科学方法。

在这里,我们可以看到数据可视化、交叉验证、逻辑回归和决策树被用于每个角色。自然语言处理和神经网络被机器学习工程师更频繁地使用是可以理解的,而其他角色则有其他特定于他们的方法。

结论

我喜欢处理这么大的数据集,它最终非常适用于我将来可能要做的事情。如果你是一名数据科学家新手,并且正在寻找着手点,我的图表强烈支持几条建议:

  1. 学习 Python。Python 和 R 已经存在了几十年,但正如我们在第一张图中看到的,Python 在基本场景中胜出。我们也可以在第四个和第五个显示中看到这一点。老实说,我相信你很难找到一家完全不使用 Python 的公司,所以你应该准备好了。
  2. 主修计算机科学或数学。正如我在创建第二个图表后提到的,每个专业在每个职位上都有一定的影响力。但是从柱状图上可见的比例来看,几乎每个角色中,CS 专业和数学专业都是最丰富的。虽然这不是必须的,但是这两个专业中的一个或两个可能会给你一点优势。
  3. 做项目,上课程,参加 Kaggle 挑战。正如我们在第三张图中看到的,在学习数据科学的有用方法方面,有几个明显的赢家,这三个赢家赢了很多。我个人同意他们所有人的观点,并且将来肯定会继续这样做。
  4. 了解最广泛使用的工具。我们似乎有无限多的工具可用,但这项调查让我们看到了被认为是最重要的工具。这里列出的工具太多了,所以如果您想知道从哪里开始,一定要进一步分析上面的表格。

我希望这能帮助你弄清楚从哪里开始!如果你有兴趣看看我是如何使用调查的数据集创建这些图表的,你可以在这里查看我的内核。如果你有任何问题要问我,我很乐意回答。祝你好运!

如何成为数据科学家(第 1/3 部分)

原文:https://towardsdatascience.com/how-to-become-a-data-scientist-part-1-3-8706a62b809e?source=collection_archive---------0-----------------------

需要数据科学培训? 浏览哈佛创新实验室行业思想领袖和专家开发的课程

我是专门从事数据科学领域的招聘人员。产生这个项目的想法是因为我最常被问到的一个问题是:“我如何获得数据科学家的职位?”引起我注意的不仅仅是这个问题的规律性,还有这个问题的不同背景。仅举几个例子,我曾与以下人士进行过这样的对话:软件工程师、数据库开发人员、数据架构师、精算师、数学家、学者(不同学科)、生物学家、天文学家、理论物理学家——我还可以继续下去。通过这些对话,很明显,有大量的错误信息存在,这使得人们不知道他们需要做什么,才能进入这个领域。

因此,我决定调查这个主题,以突破废话,并为任何希望进入商业数据科学的人提供有用的资源——无论你是刚刚起步,还是已经拥有所有必要的技能,但没有行业经验。所以我开始着手回答两个非常宽泛的问题:

  • 数据科学需要哪些技能,你应该如何去掌握这些技能?(第一、第二和第三章)
  • 从就业市场的角度来看,你可以采取哪些措施来最大化你在数据科学领域获得就业的机会?(第四章)

为什么我有资格写这个?嗯,我每天都和数据科学家交谈,要成为一名有效的招聘人员,我需要了解职业道路,如何成为一名优秀的数据科学家,以及雇主在招聘时需要什么。所以我对这件事已经有了一些了解。但我也想直接从走过这条路的人那里找到答案,所以我开始与不同背景的数据科学家交谈,看看我能挖掘出什么。这让我开始了一段旅程,经历了前软件工程师、前天体物理学家甚至前粒子物理学家,让我兴奋的是,他们都参与了 21 世纪最大的科学突破之一。

第一章:什么是数据科学?

不同类型的数据科学

所以你决定成为一名数据科学家。太好了,你上路了。但是现在你又多了一个选择,那就是:你想成为什么样的数据科学家?因为——承认这一点很重要——虽然数据科学作为一种职业已经被认可了很多年,但对于它到底是什么还没有一个普遍接受的定义。

事实上,“数据科学家”一词被视为一个宽泛的职位,因此它有多种形式,具体需求取决于行业、业务和相关角色的目的/产出。因此,某些技能组合比其他技能组合更适合某些职位,这就是为什么通往数据科学的道路并不统一,而是可以通过一系列不同的领域,如统计学、计算机科学和其他科学学科。

目的是决定数据科学采取何种形式的最大因素,这与已经出现的 A 型-B 型分类有关(参见此处,作者 Michael Hochster: 什么是数据科学?)。概括地说,分类可以概括为:

  • 面向人的数据科学(A 类),即支持循证决策的分析
  • 例如,软件数据科学(B 类):我们在网飞和 Spotify 看到的推荐系统

随着该领域的成熟,我们可能会看到这些定义的进一步演变,这就是我们将引入第一位专家的地方:亚尼尔·塞鲁西(记住这些名字,因为我们将从头到尾回到它们)。 Yanir 目前是 Car Next Door(一家支持汽车共享的初创公司)的数据科学主管,他在博客中写了这个话题:数据科学家是一个无用的职位吗?如果你喜欢这篇文章,可以看看 Yanir 的其他文章——他是一位经常发表关于数据科学各种主题的雄辩的作家。

承认这个头衔

在我们深入研究之前,有必要花点时间思考一下“数据科学”中的“科学”,因为从某种意义上说,所有科学家都是数据科学家,因为他们都以这样或那样的形式处理数据。但是,以工业界普遍认为的数据科学为例,究竟是什么使它成为一门科学呢?很棒的问题!答案应该是:‘科学方法’。鉴于科学的多学科性质,科学方法是将这些领域结合在一起的唯一方法。如果你答对了,给你满分。

然而,职称在行业中的应用往往非常松散,因此并非所有的数据科学家都是真正的科学家。但是问问你自己:如果你的角色不涉及实际的科学,你能证明称自己为科学家是正确的吗?就我个人而言,我看不出像“分析师”这样的替代职位有什么问题,或者任何最适合这个职位的职位。但也许这只是我,也许我称自己为招聘科学家会更好。

对于这方面的精彩讨论,我强烈推荐肖恩·麦克卢尔的这篇文章:数据科学家:无愧于标题 ( 是的,我承认——我剽窃了标题)

这样一来,我们将通过考虑你需要掌握哪些领域的专业知识(如果你还没有掌握)来继续这一探索。

1.问题解决

如果这不是你的首要任务,那就修改它。立刻。所有科学学科的核心是解决问题:伟大的数据科学家是伟大的问题解决者;就这么简单。需要进一步证明吗?我在这个项目中遇到的每一个人,无论背景或当前的工作情况如何,都提到这是数据科学中最重要的因素。

显然,你需要拥有解决问题的工具,但它们仅仅是:工具。从这个意义上说,甚至统计/机器学习技术也可以被认为是你解决问题的工具。新技术出现,技术进化;唯一不变的是解决问题

在某种程度上,你解决问题的能力是由你的本性决定的,但同时,只有一种方法可以提高:经验,经验,经验。我们将在第三章再次讨论这一点,所以在这一点上,只要记住这重要的一课:你只能通过做来掌握一些东西。

在我们继续之前,我想把你引向 Sean McClure 的另一个伟大的帖子:你应该关心的唯一技能 (只是澄清一下,我不会因为这些指点而收到任何报酬,但我完全接受它。肖恩——如果你正在读这篇文章,你可以随时给我寄钱。

2.统计学/机器学习

好吧,看了上面的内容,看起来我似乎轻视了统计学和机器学习。但是我们在这里谈论的不是一个电动工具;这些都是复杂的(在某种程度上)深奥的领域,如果您不具备专业知识,您将无法很快解决数据科学问题。

为了对这些术语提供一些急需的澄清,机器学习可以被视为一个多学科领域,它是从人工智能/计算机科学和统计学发展而来的。它通常被视为人工智能的一个子领域,尽管这是真的,但重要的是要认识到,没有统计就没有机器学习(ML 严重依赖统计算法才能工作)。长期以来,统计学家不相信机器学习,这两个领域之间的合作是一个相对较新的发展(参见统计学习理论),有趣的是,只有当统计学家接受 ML 结果时,高维统计学习才会发生(感谢 Bhavani Rascutti,Teradata 高级分析领域负责人)。

对于那些对更详细的描述感兴趣的技术读者来说,可以看看 Leo Breiman 在 2001 年发表的这篇经典论文:统计建模:两种文化。

3.计算

  • 编程—我们只需要简单地谈一下编程,因为显而易见:这是绝对必须的。如果你不能编写一个独特的算法或者建立一个统计模型,你如何应用这个理论呢?
  • 分布式计算 —并非所有企业都拥有海量数据集,但考虑到当今世界,培养使用大数据的能力是明智的。).简而言之:单个计算机的主内存是不够的,如果你想在数百个虚拟机上同时训练模型,你需要掌握分布式计算和并行算法。

为什么标感叹号?就我个人而言,我觉得“大数据”这个用词不当很可笑。这个术语经常被混淆,经常被用作所有分析的总括术语。此外,海量数据(以及存储和管理这些数据的技术)不再像以前那样新鲜,因此它从我们的词典中消失只是时间问题。关于这一点的更广泛的讨论,Sean McClure 还有一个明智的帖子: 数据科学和大数据:两个非常不同的野兽 (这现在变得越来越荒谬了——我发誓我从来没有和那个人说过话)。

  • 软件工程 —对于 A 类数据科学,让我明确一点:工程是一门独立的学科。因此,如果这是你想成为的数据科学家类型,你不需要成为一名工程师。但是,如果你想将机器学习算法投入生产(即 B 型),你将需要在软件工程方面有很强的基础。

4.数据争论

数据清理/准备是数据科学至关重要的固有部分。这会占用你大部分的时间。如果您未能从数据集中移除噪声(例如,错误/缺失值、非标准化类别等)。),那么模型的准确性就会受到影响,最终会得出不正确的结论。因此,如果你不准备花时间和精力在这一步上,你的高级技术知识就变得无关紧要了。

同样值得注意的是,数据质量是商业组织中的一个长期问题,许多企业在数据存储方面都有复杂的基础架构。因此,如果你还没有准备好面对这种环境,并且想要使用干净的数据集,那么很不幸,商业数据科学不适合你。

5.工具和技术

你现在应该已经意识到,发展你作为解决问题的数据科学家的能力应该优先于其他一切:技术不断变化,最终可以在相对较短的时间内学会。但是我们不应该完全忽略它们,所以了解当今使用最广泛的工具是很有用的。

从编程语言开始,R 和 Python 是最常见的;所以如果你有选择的话,也许在你做实验的时候可以使用其中的一个。

特别是在 A 类数据科学中,在直观的仪表板中可视化数据的能力对于与非技术业务利益相关者进行交流非常强大。你可能有最好的模型和最好的见解,但是如果你不能有效地展示/解释这些发现,那还有什么用呢?你用什么工具来观想真的不重要——可以是 R,或者 Tableau(这似乎是目前最流行的),但老实说——工具并不重要。

最后,SQL 很重要,因为它是工业中与数据库交互最常用的语言;无论我们谈论的是关系数据库,还是结合大数据技术使用的 SQL 衍生产品。这是数据争论的主要原因——至少在大规模工作时(即不在内存中)。总之:这真的值得你花时间去做。

6.沟通/商业敏锐度

这不应该被低估。除非你进入非常具体的领域,也许是纯研究领域(尽管我们不得不承认,工业界没有很多这样的职位),绝大多数数据科学职位都涉及业务互动,通常是与不具备分析能力的个人打交道。

有能力将业务问题及其发生的环境概念化是至关重要的。将统计见解转化为建议的行动和对外行观众的影响是绝对重要的,特别是对于 A 型数据科学。我和 Yanir 聊到这个,他是这么说的:

“我发现有些技术人员不注意非技术人员在开始使用行话时眼神变得呆滞,这很奇怪。设身处地为听众/读者着想真的很重要”

摇滚明星

可能还不清楚:我讽刺性地使用了这个标题。不——数据科学家不是摇滚明星、忍者、独角兽或任何其他神话生物。如果你打算这样称呼自己,也许你应该好好照照镜子。但是我跑题了。我想在这里指出的一点是:有一些数据科学家在以上所有方面拥有专家级的能力,也许更多。它们很稀有,非常珍贵。如果你有成为其中一员的天赋和愿望,那就太好了——你会成为炙手可热的财富。但如果不是,请记住:你可以专攻数据科学的某些领域,而且通常情况下,优秀的团队由具有不同专长的数据科学家组成。决定关注什么可以追溯到你的兴趣和能力,这很好地引导我们进入旅程的下一章。

第二章:向内看

现在我们正在取得进展。成功消化了第一章的信息后,你就差不多准备好开始制定你的个人目标了。但是首先——需要一些自省——所以喝杯咖啡,找个安静的地方,好好思考一下:

  1. 你为什么想成为一名数据科学家?
  2. 你对什么类型的数据科学感兴趣?
  3. 你已经拥有哪些天生的能力或相关技能?

为什么这很重要?简而言之:数据科学是一个专家领域,所以除非你已经掌握了我们在第一章中介绍的很多内容,否则这不是一个容易(或快速)的旅程。这里有一个重要的信息,它回答了第一个和第二个问题:你需要有正确的理由去走这条路,否则——很有可能——当事情变得艰难时,你会放弃(它会的)。

要详细说明这一信息,输入迪伦霍格。迪伦之前是一名软件工程师,现在是 Search Party 的数据科学主管,这是一家初创公司,它建立了一个利用机器学习(NLP)将雇主和相关候选人联系起来的平台(招聘的未来!).考虑到他已经完成了从软件工程到数据科学的转变(他仍在继续这一旅程),我们讨论了需要什么,他说:

“不管教育或经历如何,有一些更基本的东西,那就是你的好奇心、决心和坚韧。当你遇到一个问题的时候有很多次:也许算法没有按照它需要的方式执行,或者也许技术是一个难题。无论哪种方式,你都可以学习机器学习算法或软件工程最佳实践,但如果你没有真正下定决心,你就会放弃,无法完成它”

这就对了:当你学习的时候,你不会只是面对问题;在你的职业生涯中,你会不断地面对它们,所以你最好确保你有正确的动机,而不仅仅是因为你认为你的头衔中有“科学家”很酷。

但是第三个问题呢?为什么你的相关技能很重要?嗯,你从哪里开始会影响你最适合哪种类型的数据科学,以及你需要为你感兴趣的领域学习什么。因此,为了充分回答这个问题,有必要从更广泛的科学领域开始,探索数据科学的典型路径。

注意:在许多定量学科中,你会发现有能力过渡到数据科学的人。我不会在这里一一介绍,但重点是:如果你花时间真正理解数据科学的不同细微差别,无论你的背景如何,你都应该能够弄清楚你当前的技能组合有多相关。

其他科学学科

这不是通向数据科学的最常见途径;统计学和计算机科学是,我们将考虑下一步。但是随着许多领域的科学家拥有高度相关的技能组合(尤其是在物理领域),许多人已经实现了这一飞跃。

要解释原因,请允许我介绍我在引言中提到的那个人:Will Hanninger,澳大利亚联邦银行的数据科学家。在前世,威尔是欧洲粒子物理研究所的粒子物理学家,在那里他致力于希格斯玻色子的发现(非常酷),这是他不得不说的:

“在物理学中,你自然会学到很多你在数据科学中需要的东西:编程、操纵数据、获取原始数据并以一种有用的方式对其进行转换。你学统计学,这很重要。最重要的是:你学会了如何解决问题。这些是数据科学家所需的基本技能”

因此,这些技能是高度可转移的,主要选项是:解决问题。差异往往出现在工具和技术上;例如,虽然机器学习是数据科学的同义词,但它在更广泛的科学中不太常见。无论如何,我们在这里谈论的是非常聪明的人;他们有能力在短时间内学习工具和技术。

为了这个项目,我还见到了肖恩·法雷尔;Sean 的背景是天体物理学,他进入了 Teradata Australia 的商业数据科学领域,在那里他写了一篇关于这个主题的精彩博文:为什么科学的损失是数据科学的收获。下面这段话特别相关:

“直到最近,还没有任何成为数据科学家的正式培训途径。大多数数据科学家都有统计学或计算机科学的背景。然而,虽然这些其他的职业道路发展了上面列出的一些技能,但它们通常不能涵盖所有的技能。统计学家在数学和统计方面很强,但通常编程技能较弱。计算机科学家在编程领域很强,但通常对统计学没有很强的理解。两人都有很好的(但不同的)数据分析技能,但都难以创造性地解决问题,这可能是最难教授的技能”

为了避免误解,请记住这里的上下文。肖恩并不是说所有来自统计学或计算机科学的数据科学家都缺乏创造性的解决问题的能力;他的论点是,科学对于解决问题非常有效,可以说比统计学/计算机科学更有效。

统计数字

根据你的观点,统计学可以被看作是一种促进科学进程的数学工具,或者说:它本身就是一门科学。鉴于这种模糊性,如果你是统计学出身,你准备好数据科学了吗?抛开语义不谈,它取决于几个因素:

  • 首先,你有机器学习技术的经验吗?正如我们在第一章中所学的,统计建模和机器学习是相关的,它们在许多方面有重叠。然而,后者在应用于大规模数据集时具有显著的优势,并且随着机器学习在所有行业领域的采用不断增加,它实际上是所有类型的数据科学的同义词
  • 其次,冒着重复我自己的风险:你对数据科学的哪个领域感兴趣?显然,统计学背景更适合 A 类职位,所以如果你的目标是 B 类工作,你需要学习
  • 最后,你有处理数据的实践经验吗?数据争论通常是统计领域的相对弱点,正如我们所知,它是商业数据科学的重要组成部分

计算机科学/软件工程

如果你已经学习了高水平的人工智能/计算机科学,那么你很可能已经处于 B 型数据科学的有利位置。但是还有另一条常走的路要考虑:有经验的软件工程师想进入数据科学。

软件工程师可能有,也可能没有机器学习的经验——这要看情况。但无论如何,这种背景显然更适合 B 型数据科学,这需要在软件工程原则方面有坚实的基础。我与澳大利亚联邦银行的高级数据科学家 James Petterson(之前是一名软件工程师)讨论了这个问题,以下是他对此事的看法:

“很多数据科学工作都是软件工程。不总是指设计健壮的系统,而是简单地写软件。许多任务你可以自动化,如果你想运行实验,你必须写代码,如果你能快速完成,它会产生巨大的差异。当我读博士的时候,我每天必须运行数万个实验,在这种规模下,手动操作是不可能的。拥有工程背景意味着我可以快速完成这项工作,而许多来自其他背景的学生却在基本的软件问题上苦苦挣扎:他们确实擅长数学,但实现他们的想法需要很长时间”

迪伦补充道:

“当你想在生产环境中创建一个机器学习算法的健壮实现时,良好的软件工程实践是非常有价值的。它是各种各样的东西,比如可维护的代码,共享的代码库,这样多人就可以在上面工作,比如日志记录,能够调试生产中的问题,可伸缩性,要知道一旦事情增加,你已经以这样的方式设计了它,这样你就可以并行化它,或者在需要时添加更多的 CPU。因此,如果你在寻找需要将这些东西放到一个平台上的角色类型,而不是做探索性研究或回答特定的业务问题,软件工程是非常有价值的。”

我认为这说明了一切,但总结一下:如果你是一名软件工程师,有良好的数学倾向,你就有很好的条件成为(B 型)数据科学家,前提是你准备好投入工作以掌握统计学/机器学习。

数学

做一个明显的声明:数学支撑着数据科学的所有领域。因此,期待许多数学家现在从事数据科学家的工作似乎是合理的。然而,直接来自数学的相对较少,这种特殊性使我的兴趣达到顶峰。

一种解释是,与其他相关研究领域相比,数学专业(纯数学和应用数学)的毕业生较少,但这并不能说明全部情况。因此,为了更深入地挖掘,我向 BuildingIQ(一家使用先进算法优化商业建筑能源使用的初创公司)的首席数据科学家鲍里斯·萨夫科维奇求助。Boris 拥有电气工程和应用数学背景,并在当时与许多数学家合作,他提供了以下见解:

“许多数学家热爱理论问题、漂亮的方程以及在定理中看到深刻的含义,而商业数据科学是经验性的、混乱的和肮脏的。虽然一些数学家喜欢这一点,但许多人讨厌它。现实世界是复杂的,你不能用沙箱保护一切,你必须分清轻重缓急,欣赏他人的激励,权衡短期、中期和长期的数学和技术,担心收益递减(80/20 法则),处理深层理论和深层实践,以及两者之间的一切。简而言之:你必须灵活应变,才能应对现实世界。这也是商业数据科学的最终目的:找到更快更好的赚钱的实用解决方案。对于那些拥有深厚数学/理论背景、希望彻底了解一切的人来说,这可能非常困难,我已经看到许多数学博士在从研究/学术界过渡到商业数据科学时非常挣扎。”

值得注意的是,Boris 指的更多的是纯数学家,他补充说,在他的职业生涯中,他也与许多优秀的应用数学家合作过。这似乎合乎逻辑,因为纯数学可能会吸引那些热爱理论的人,而不是现实世界的问题。理论工作不会涉及太多与数据的互动,这对于数据科学来说非常重要。

当然也有例外,这最终取决于个人性格,而不仅仅是某人所学的。很明显:数学毕业生学到的很多东西都是高度可转移的,所以掌握特定的统计/机器学习技术应该不会太难(如果还不知道的话)。

就适用性而言,大多数数学家可能最适合学习 A 类数据科学的工具和理论。然而,有研究计算机科学的数学家(理论计算机科学本质上是数学的一个分支),因此有背景的人可能更适合 B 型数据科学。

从所有这些中可以吸取一个重要的教训,那就是理解商业数据科学所涉及的现实。如果你真正理解挑战,并且那是你正在寻找的,那么就去争取吧。但是如果你对理论的热爱超过了对实际应用的热爱,你可能需要重新评估你的想法。

空白画布

如果你刚刚开始,也许你在上学,你喜欢数学、科学和计算,你喜欢数据科学这个东西的声音,那么好消息是:你可以选择你的道路,而不受现有背景的约束。现在有许多特定的数据科学相关课程,涵盖了计算机科学和数学/统计。做好长期的准备;你不会在一夜之间成为数据科学家,我们将在第二部分看到,我们将研究:如何学习。

点击此处查看如何成为数据科学家的第二部分。

原载于www.experfy.com**

如何成为数据科学家,第 2 部分:尝试解决问题

原文:https://towardsdatascience.com/how-to-become-a-data-scientist-part-2-try-to-solve-the-problem-f9b9746f6eb9?source=collection_archive---------3-----------------------

一旦你开始尝试解决你的问题,事情终于有了进展。

  1. 获取数据。
  2. 清理数据。
  3. 看数据。
  4. 汇总数据。

获取数据

“80%的时间花在准备数据上,20%的时间抱怨需要准备数据。”— 一个随机的博客

为什么这是如此昂贵值得自己的职位。相反,这里是给初露头角的数据科学家的快速建议。

Credit: Nick Rosener (twitter).

对数据的含义要精确。这通常意味着询问他人、阅读代码、阅读文档以及查看数据的分布。例如,字段有值的频率。过度信任的一个常见例子是,看到一个名为“年龄”的用户字段,说“啊,用户的年龄”,然后立即将其插入另一个系统(比如,一个模型构建器)。但也许这个领域在一年前才开始被填充,或者只在某些平台上,并且经常是空白的。更糟糕的是,以偏概全的空白(老用户没有价值,某些平台的用户没有价值)。或者也许“年龄”是他们成为用户的时间,也就是说,不是你想的那样。要发现这些东西,就要和人交谈,看数据。你必须和人们交谈,因为有时他们知道。但是,你必须看数据,因为有时他们会说谎(有意或无意)。

学习 SQL 。大量数据存储在关系数据库中,可通过 SQL 访问。还有很多在 Hive 中,可以通过 HiveQL 访问,Hive QL 是经过扩展和修改的 SQL。即使对于文本文件,您也将使用表的概念(固定命名的列和行)。

对于文本,使用 制表符分隔值(TSV)文件 它们易于读写,可以从许多地方导出,可以轻松粘贴到 google 电子表格或 Excel 中进行共享。

对于简单的任务, 用 UNIX 命令行 进行处理。大约从 1990 年开始,UNIX 成为我的朋友的时间比大多数人都长。我仍然一直这样做,以获得十大最常见的事情:

cut-F5-d "" foo . tsv | sort | uniq-c | sort-rn | head-10

不要刮。有时候你想要的数据在公共网站上。人们写着铲运机去抢它。这个实用有用,但是我不爱。可能是偷。这很常见。如果你能找到一个许可的来源就更好了。

清理数据

在分析过程中,我所有的清洗都是手动的。这可能很糟糕。我很诚实。

我查看数据记录的示例,并总结数据。如果有些东西看起来不可思议(例如,字段数量错误的行,混乱的文本),我会删除它们。但是,不要去除太多或者以偏概全。

作为偏差的一个例子,如果 20%的记录有一个字段“type”为空,这些可能不是随机的,它们是某种类型的数据。也许是最重要的数据。你不能只是推销他们。对于具有未知字段值的记录(例如,键入 empty,键入“NULL”),我通常将它们留在(标记为“NULL”或“empty”)中,以便向任何观看的人展示其中的奥秘。

另一个例子是一个格式良好的异常数据记录。推销它,让你的结果更容易用图表表示,更容易理解,多么令人满意。例如,这里的是职业冰球运动员的职业积分和比赛的帖子:

National Hockey League (NHL) career scoring. Credit: beerleaguetips.com.

顶部有一个巨大的异常值。我们应该推销它吗?

那是韦恩·格雷兹基,10 岁时被昵称为【伟大的那个】。他太有名了,我的浏览器知道把格雷特斯基改成格雷茨基。Reddit 说“韦恩和他的兄弟布伦特保持着一对兄弟得分最多的 NHL 记录。韦恩 2857,布伦特 4。”我对曲棍球一无所知,但他的故事鼓舞人心:他不高,不强壮,也不快;他通过创造力、练习和团队合作打破了每一项记录。

丢掉一分是多么容易,但我们可能会丢掉格雷茨基。从这一点上我们可以学到很多东西。

看数据

人们是惊人的视觉模式匹配者。

下面是一个示例数据集:X 均值 54.26 标准差,Y 均值 47.83 标准差 26.93,X 和 Y 的相关性为-0.06。

不知道那个?

以下是完整数据(142 行):

)(那)(就)(是)(我)(们)(的)(一)(个)(小)(人)(,)(我)(们)(都)(没)(想)(到)(这)(些)(事)(,)(只)(是)(这)(个)(小)(人)(,)(只)(是)(这)(个)(小)(人)(,)(只)(是)(这)(个)(小)(人)(,)(只)(是)(这)(个)(小)(人)(,)(只)(是)(这)(个)(小)(人)(,)(只)(是)(这)(个)(小)(人)(,)(只)(是)(这)(个)(小)(人)(。 )(那)(就)(是)(我)(们)(的)(一)(年)(里)(,)(我)(们)(都)(不)(知)(道)(了)(,)(我)(们)(还)(不)(知)(道)(,)(我)(们)(还)(有)(些)(不)(知)(道)(吗)(,)(我)(们)(还)(不)(知)(道)(,)(我)(们)(还)(是)(不)(知)(道)(,)(我)(们)(们)(还)(不)(知)(道)(,)(我)(们)(们)(还)(不)(知)(道)(,)(我)(们)(还)(有)(些)(不)(知)(道)(理)(,)(我)(们)(还)(不)(能)(不)(知)(道)(理)(。 )(我)(们)(都)(没)(想)(到)(这)(些)(事)(,)(我)(们)(还)(没)(想)(到)(这)(些)(事)(,)(我)(就)(没)(想)(到)(这)(些)(事)(了)(。 )(我)(们)(都)(没)(想)(到)(这)(些)(事)(,)(我)(们)(还)(没)(想)(到)(这)(些)(事)(,)(我)(就)(没)(想)(到)(这)(些)(事)(,)(我)(们)(还)(没)(想)(到)(这)(些)(事)(。

仍然不承认吗?

这里有一个图表:

Datasaurus says: don’t trust summary statistics, always look at the data.

是的,这是阿尔贝托·开罗的 Datasaurus ,他一直在互联网上转来转去,告诉我们看看这些数据。(这是安斯科姆的四重奏的异想天开的版本,创作于 1973 年,目的相同:相同的统计数据,不同的数据。)

计算机研究人员(我想说是数据科学家)进一步发展了这个概念,向展示了如何使用模拟退火将几乎相同的汇总统计数据突变成不同的形状。

重点是,看数据。

在 Datasaurus 的例子中,我们完成了。它是一只恐龙。在我看来,霸王龙可以用 8000 磅的压力咬人,让骨头“爆炸”我们需要更多的分析吗?

总结数据

从数据中获得洞察力或价值。这包括以一种有用的方式总结它:要么是描述性的(“这是一只霸王龙”)要么是预测性的(给定一个输入,预测它是不是一只霸王龙,或者可能是什么)。两者都有用。两者都是数据科学任务。

(最后,人们所认为的数据科学,这一节既太长又不够详细!我很同情,但我的目标是快速游览。)

描述性分析

一种常见的技术是概率。一个概率往往是

(有趣事物的数量)/(事物的数量)

很多数据科学都是计数,学习如何处理计数。

善于精确定义“事物的数量”。数数从思考开始。当考虑解决一个问题时,试着定义一个概率。

一个很大的优势是,人们对思考概率相当放心:“80%的”,“80%的的几率在上升”,以及“我们的目标至少是 75%

事实上,它们太舒服了。他们对不确定性几乎完全不感兴趣(即“80%正负 10%”),但这很重要。

在实际应用中,您必须处理低计数,即缺少数据。当你除以一个低计数,你得到一个嘈杂的概率。即使是“大数据”,你通常也只对其中的一部分感兴趣。示例:推荐内容的一种方法是预测每个项目有人会参与的概率(特写,购买,..)看完后,并把大概率项目排序到最上面。如果只有一个人看了那个东西,他们参与了,概率是 100%。所以,如果你按这个概率排序,大量不受欢迎的东西会排在最前面。但是这个概率并不是精确地说 100%,存在不确定性。在这种情况下(单个视图),很多。怎么办?

最简单的方法是在没有足够数据的情况下(在这个例子中,没有足够的视图)得出任何结论。判断“够不够”是艺术,不是科学。多少个视图就够了?我很想看到更多关于这门艺术的实际讨论。我认为大多数从业者只是挑选一些东西。有些人变得更正式,这很复杂。

你可以保留数据,但用置信区间陈述不确定性,而不是抛出数据。对于二项分布的随机变量:1.96 * sqrt(p *(1-p)/n),我已经使用了一千次(a 的正态近似)置信区间,其中 p 是概率,n 是观察次数,1.96 是一个乘数,它给出了 95%的置信区间。(也就是说,粗略地说,如果你将一个类似的实验运行 100 次,其中 95 次的概率在你计算的区间内。)这个工具有很多假设,这意味着它可能会被误用。实际上,在我提到的例子中,p=1,所以区间会是 0,这显然是错误的。事实上,我认为贝叶斯主义者会声称这个公式总是错的,因为你对概率有一个先验的信念,而这个信念没有被恰当地使用。我要跳过一个完整的讨论,太长了。简而言之,学习概率、二项分布的随机变量及其置信区间。

陈述不确定性的另一种方式是使用假设测试,即假设(断言)的统计测试,例如,“某人在看到该内容后参与其中的概率高于平均水平。”进行这种测试的一种方法是计算一个 T2 p 值 T3、罗纳德·费雪推广的 T4 T5。统计学家可能会对我的过度简化感到愤怒,但 p 值大致是“一个结果随机出现的概率”。因此,你可以说,“有人在看到这些内容后参与其中的概率高于平均水平,p=0.01”,意思是“有 1%的可能性,这个结论实际上是随机噪声。”统计学家称之为“第一类错误”(我从来不记得是第一类还是第二类,我更喜欢“假阳性”),并进一步用短语“不正确地拒绝真零假设”为自己披上了一件隐形斗篷关键是,如果你想得出一个结论,给它加上一个 p 值是处理不确定性的第一步。越小越好,因为这样你的结论就不太可能是随机噪声。费希尔提出 p < 0.05 被认为是显著的,从那以后人们就一直使用它,尽管不清楚他是否对这个想法的实现感到满意。

一个大问题是 p 值黑客攻击:人们进行不同的研究,以不同的方式分析,查看不同的数据,每当 p 值为 0.05 时,他们就使用(或发布)结果。我的朋友 John Riedl 曾经开玩笑说,科学论文中 20 个结论(使用 p 值)中有 1 个是随机噪声。呵呵,只有认真。如果你让人类来解决这个问题,情况会变得更糟,因为他们有强烈的动机发表结果,或者得出他们已经相信的结论。关于 p 值有很多争议。

几个想法。首先,至少一个置信区间或 p 值代表一个健全性检查。它有助于快速抛弃人们从没有不确定性或大量数据的图表中得出的大量垃圾结论。其次,任何单一的定量结论都是一个更大故事的一部分。如果你想更确定,随着时间的推移收集多条证据。如果你根据一个证据做出一个非常重要的决定,要有一个好的理由。第三,选择你的战斗。有时候你需要高度的确定性,往往不是。不到万不得已不要抓狂。

(处理不确定性的另一种方法是贝叶斯方法:先有一个信念,然后根据数据调整这个信念。例如,加法平滑,它有很多花哨的术语,但却是一个简单而美丽的想法:在分子和分母上加一些东西,这样如果没有数据,你仍然可以得到一个合理的数字。比如说,参与我们例子的总体概率。但是,分子和分母加什么更有艺术)

xkcd on p-values.

其他聚合

有时你的解决方案不是一个概率,但它几乎总是一个集合:数据的总结。

最常见的后一种概率是平均值。关于平均值有很多需要了解的。同样的处理低计数,你可以推销他们,把他们的置信区间,使用假设检验,或使用先验。一个最重要也是最美丽的数学思想,中心极限定理说,将不同的事物加在一起(技术上独立的、同分布的随机变量,具有有限的非零方差)趋向于一个钟形曲线。因为平均值是将事物相加(然后除以事物的数量),所以平均值的集合趋向于一个钟形曲线。关于钟形曲线有很多要了解的,由于篇幅原因,我将再次跳过。

The central limit theorem explains why bell curves show up everywhere.

预言

我谈到了描述。现在我们来谈谈预测。

"很难做出预测,尤其是对未来的预测。"— 丹麦谚语

这是软件极客们兴奋的地方:回归、聚类、神经网络、决策树、深度学习等等。我不能在这里面面俱到。预测(“监督学习”)的最短故事是:

  • 给你的数据贴上真实的标签(好的或坏的例子)
  • 定义一个总结预测数据的模型
  • 定义一个误差(或损失)函数,将测试集上的实际值与预测值进行比较(不用于计算模型!!)
  • 尽量使误差变小

这里有值得兴奋的美丽,但它通常只是整个任务的一小部分。那种美诱使人们关注这一部分。其余的(挑选正确的问题,获取和清理数据,..)可能对结果的影响更大,往往事倍功半。别人说的这个好。

xkcd on machine learning.

又一个集合,这次更有趣:一个神经网络。在一种常见的算法中,你将网络中的“神经元”与输入和输出连接起来,将训练样本作为输入,查看输出,当网络出错时,你会在下一次将其调整为更正确的(例如使用反向传播)。在给出大量示例后,该网络是训练数据的汇总,能够在给定输入的情况下准确预测输出。当网络是“深”的,即具有许多层时,这也被称为“深度学习”。

我过去常常对神经网络和深度学习感到烦躁。它产生预测,但不是理解。我认为我们应该寻求理解。然而,当你想要预测时,对于像图像或声音识别这样的模糊任务,这些技术比其他任何技术都好得多,以至于我不得不忽略我的偏执。

深度学习是我们这个时代的戏剧性故事之一。最近几年,深度学习系统赢得了 ImageNet 挑战赛,这是一项年度竞赛,旨在检测和标记图像中的对象,将其标记为来自某个类别(例如,将图像标记为其中有一只“狗”)。2012 年,分类错误率开始大幅下降:

ImageNet Large Scale Visual Recognition Challenge error rates. 0.1 is a 10% error rate.

事实上,Andrej Karpathy 估计他自己(人类!)2014 年误差为 5.1%,2015 年被电脑“打败”。(注意 Karpathy 说 5.1%只是权衡曲线上的点估计。他知道不确定性。然而,一个惊人的故事。)

这里的其他技术工具是逻辑回归(产生可解释的模型系数)和梯度增强决策树(比线性方法更好地处理数据中的非线性和交叉特征)。

这里还有很多要说的,但是当图片和文字的比例仍然很高的时候,我要停下来,继续第 3 部分的工作。

这是一个系列的一部分。0 部分是 这里的

上一篇: 如何成为一名数据科学家,第一部分:找到一个好问题

接下来: 如何成为一名数据科学家,第三部分:给人讲讲

如何成为一名优秀的数据科学家

原文:https://towardsdatascience.com/how-to-become-a-good-data-scientist-d0f86e28060a?source=collection_archive---------9-----------------------

在对如何成为一名糟糕的数据科学家大谈特谈之后,我想我应该就如何成为一名优秀的数据科学家给出一些提示,以此来平衡竞争环境。奖牌的另一面。

我强烈的感觉是,如果你只是因为就业或薪水的原因而进入这个领域,你的起步就错了。你应该先看看你的激情。有趣的是,我们花了几秒钟时间在 Dictionary.com上查找激情这个词的定义:

热情

[ 帕什 n]

名词

  1. 任何强烈的或引人注目的情感或感觉,如爱或恨。

2.强烈的感情或欲望;爱情;热情。

3.性欲强;欲望。

4.强烈的爱或性欲的例子或经历。

5.一个对其有强烈的爱或性欲的人。

6.对任何事物强烈或过分的喜爱、热情或渴望:对音乐的热情。

7.这种喜爱或渴望的对象:准确性成了他的一种爱好。

希望你对数据科学的热情范围不涉及定义 2、3、4 或 5。而是受到对数据科学的强烈喜爱和热情的驱使!如果是这样的话,你就在正确的轨道上,我的第一个建议是:不要试图一口吞下大海。放大激情的一个方面,首先激起你的兴趣。看看如何将它应用到现实世界的问题中,并在过程中学习。例如,就我而言,我很久以前就对人工生命充满热情。这在 2012 年左右演变成一种强化学习、遗传算法和遗传编程的形式。随着时间的推移,我对机器学习和深度学习的兴趣越来越大,通过阅读书籍,参加在线课程和在攻读硕士学位期间参加研究生课程来了解它。当时,我希望将它应用到我的硕士论文项目中,但有时计划会发生变化。所以,简而言之,你需要跟随你的心。

如果你采用这种方法,你将会避免我在第一篇文章中提到的许多陷阱。您不会期望一个“干净”的数据集作为您的输入,因为您已经将它应用到您所学的一些真实案例中。你将一路学习如何收集数据、如何清理数据、如何解读数据……这将在两个方面让你受益。首先,您将学习一项基本技能,即数据清理。但最重要的是,它会增长你的好奇心。这是我从未见过任何一门课程能做到的。再说一次,我不认为这是一项你可以在几周内获得的技能,它需要你通过反复练习获得的思维转变。

沿着你的激情前进的另一个好处是,如果你还没有必要的数学背景,你会在前进的道路上抓住它。如果你觉得数学很难,当你通过自己充满激情的实验扩展你的知识时,根据需要抓住它们可能更容易!我也要重申,不管你怎么想或者被告知,数学并不那么难。此外,如果你以积极的态度开始,告诉自己你能做到,那么你就更容易得到它们。

这种方法的下一个好处是你必须定义和提炼你的问题。你将决定什么对你来说是重要的,你的“研究”问题是什么,以及它与你正在进行的活动有什么关系。我在读硕士的时候,看到两种类型的学生。那些已经有一个研究议程,一个他们想探索的问题,或者至少早些时候和他们的导师坐下来,根据他们的兴趣和热情设置这样一个研究问题的人。这些学生通常做高质量的报告,学习与回答他们的研究问题高度相关的课程,并在他们的研究领域变得非常精通。第二种类型的学生等待他们的导师给他们一个研究项目,从来没有真正参与其中,做了一般或很差的陈述,参加了任何课程,但没有真正看到它们与他们的研究课题有什么关系:嗯,在大多数情况下,他们没有……最终可能仍然毕业,但有一个课题要忘记……你想像第一种类型的学生一样,即使你自己做,你也想控制它并获得好处。

最后,写或谈论你的发现和学习对你有好处。我发现它有助于理清我的想法,并(有时)从其他志同道合的同行那里获得一些反馈。总而言之,学术论文不是交流你的发现的唯一方式,如果你有热情,博客、视频、报告都可以帮助你。学术论文的优势当然在于同行评议系统,它能为你的研究提供反馈,但如果它不适合你的实际情况,你就不应该把自己局限于单一的交流媒介。坦率地揭露你所发现的,不要宣称你是你不是或还不是的东西。到时候,其他人会承认你是一名数据科学家,那一天你会知道你肯定是一名数据科学家!

和我之前的文章一样,努力学习:当你遵循个人研究/兴趣目标时,学习会更容易。努力工作:同样,当你追随一种激情时,事情会变得更容易(不一定容易)。在任何时候都要对自己(也对他人)诚实,告诉他们你知道或发现了什么。如果你在第一天就认为自己是一名成熟的数据科学家,你可能不会为成为一名数据科学家付出必要的努力。另一方面,如果你追随自己的兴趣和激情,你可能会在认为自己是数据科学家之前成为一名数据科学家。

原载于 2018 年 3 月 5 日【thelonenutblog.wordpress.com】

封面照片由 玛格达埃勒斯 像素

如何成为一名机器学习工程师?

原文:https://towardsdatascience.com/how-to-become-a-machine-learning-engineer-ce81821a025f?source=collection_archive---------6-----------------------

source : engadget

最近我在我的团队中发布了一个机器学习工程师的职位。我收到了很多人的问题,他们很好奇,想了解这个职位本身,如何准备这个职位,以及它面临什么样的问题?

数据科学 vs 机器学习工程

让我们从定义职位本身开始。什么是机器学习工程?是新事物吗?它与所谓的 21 世纪最性感的工作数据科学家有什么不同吗?

当人们发明数据科学家这一术语时,他们在寻找擅长以下方面的超级英雄:

via Big Data [sorry] & Data Science: What Does a Data Scientist Do

1-获取数据、清理数据、发现问题、提出正确的问题以及为不同的 KPI 设定正确的衡量标准。

2-进行必要的统计分析,提出关于解决方案的不同假设

3-使用统计方法验证不同的建议解决方案。

4-在某些时候,解决方案可能不仅仅是一个数学模型(方程),它可能包括一些需要使用机器学习的复杂性。因此,通过不同的迭代开发一个合适的 ML 模型变得很有必要。

5-一旦这个模型准备好了,你需要设计一个工程系统,除了其他方面需要仔细的工程设计以确保这个模型的持续有效性之外,还要为这个模型服务。

6-对模型结果进行必要的连续分析和调查,以及必要的监控。

它们确实存在于我们的星球上,但非常罕见;)

Photo by Franki Chamaki / Unsplash

由于人类获取知识和跟上各个不同子领域不断变化的能力有限,专业化就成了必须。我们开始看到不同的职位描述在前面提到的工作流程的不同区域工作。

例如,一些对基础设施更感兴趣的数据工程师/科学家专门从事数据工程。这给了他们更多的带宽来吸收不同分布式处理系统的内部(例如:Apache Spark,Apache Hadoop,..因此能够扩展这些系统来处理非常定制的用例,这些用例可能不容易用标准 API 来处理

我们可以列出 6 个概况,它们共同组成了一个有能力的数据团队,能够推动其组织成为数据驱动的,然后在稍后阶段成为人工智能驱动的。

  • 数据分析师和数据即
  • 数据科学家
  • 数据工程师
  • 机器学习工程师
  • 数据基础设施工程师
  • 数据操作

然而,很难将这一点推广到每一个组织,因为在考虑数据团队保护伞下的每个配置文件之间的界限时,每个组织的需求和规模是决定性因素。

那么什么是机器学习工程师呢?

Photo by Wes Hicks on Unsplash

我将引用 Oreilly 的优秀文章对他们的描述如下:

  • 他们比典型的数据科学家拥有更强的软件工程技能。
  • 机器学习工程师能够与维护生产系统的工程师一起工作。他们还编写干净的代码。
  • 他们了解软件开发方法、敏捷实践和现代软件开发人员使用的所有工具:从 Eclipse 和 IntelliJ 等 ide 到持续部署管道的组件。
  • 他们参与软件架构和设计
  • 因为他们的重点是让数据产品在生产中发挥作用,所以他们从整体上考虑问题,并考虑日志记录或 A/B 测试基础设施等组件。
  • 他们了解生产中监控数据产品的具体问题。有许多关于应用程序监控的资源,但机器学习有更进一步的要求。数据管道和模型可能会过时,需要重新培训,或者它们可能会受到对手的攻击,而这些攻击对于传统的 web 应用程序来说毫无意义。

如何获得体验?

Photo by Ali Yahya on Unsplash

  • 做一个扎实的软件工程师
  • 获得 ML 经验
  • 理论部分,你可以在 Coursera、Edx 或 Udacity 上选修任何一门现有的 MOOCs。一个选择是 Udacity 机器学习工程师 Nanodegree 。
  • 通过在真实数据上做真实项目获得实践经验。如果你还没有问题的话,Kaggle 是最好的来源:)
  • 读,听,看。互联网上有许多精彩的文章、播客和视频会议。

为了前任。这里是一个博客,讨论我的经验,建立我们的内部 ML 基础设施平台,这将让你先睹为快真实世界的 ML 工程经验。

[## 缩放机器学习@ Careem

我们如何构建我们的内部 ML 平台?

medium.com](https://medium.com/careem-tech/yoda-scaling-machine-learning-careem-d4bc8b1be195)

推荐资源

博客

  • [ 走向数据科学
  • 【激情学习】—不要脸的塞;如果你想收到关于机器学习、数据工程和其他主题的帖子,请务必订阅。
  • [机器学习掌握]

播客

  • [ 机器学习— SE Daily
  • [ 奥莱利数据显示

理论背景:

https://www . quora . com/What-is-the-successed-courses-I-take-in-my graduate-studies-to-a-Machine-Learning-Engineer/answer/Alex-Smola-1

面试是什么样的?

似乎大多数公司会像面试其他软件工程师一样面试你。另外,可能会就你的机器学习理论知识、数据工程、ML 产品设计进行面试。

更多详情可以阅读小寒曾作为机器学习工程师的面试经历。

[## 我在五天内面试了硅谷的五家顶级公司,幸运的是获得了五份工作邀请

以下是我的做法和我的想法

medium.com](https://medium.com/@XiaohanZeng/i-interviewed-at-five-top-companies-in-silicon-valley-in-five-days-and-luckily-got-five-job-offers-25178cf74e0f)

哪里可以找到合适的机会?

包括五大在内的大公司大多都有自己的机器学习和数据团队。如果你有合适的经验,应该很容易找到合适的机会。你随时可以从 Linkedin 开始。

包裹

对于机器学习工程岗位的什么、哪里、怎么做的问题,我尝试给出了一些答案。如果能分享一下进入该领域的经验就好了。一如既往地感谢阅读!

你喜欢你读到的东西吗?

在 Twitter @_ahmdkamal _ 上关注我,获取关于#AI 和#tech 的有趣更新。

你知道你最多可以放弃 50 个👏到本帖** 😉 ?!

鼓掌让其他人看到&鼓励我在 medium 上发布更多高质量的内容!

原载于blog . Ahmed Kamal . me

如何开始自己的数据科学之旅!

原文:https://towardsdatascience.com/how-to-begin-your-own-data-science-journey-2223caad8cee?source=collection_archive---------0-----------------------

嘿,你好,

不久以前,商人们常常去找这些占星家预测他们的下一个财政年度会如何。尽管这是毫无根据和不确定的,但人们习惯于根据这一点或该领域某个专家的建议来做决定。但是现在我们在前进,已经前进到这样一个程度,我们接受一切基于事实和数字的东西。

我们生活在一个数据丰富的世界,你去达美乐点披萨,他们问的第一件事就是你的号码,通过这个手机号码,他们获取了从地址到过去订单的所有信息,但数据仅限于此吗?或者我们能从这些数据中做些别的什么吗?这就是数据科学家发挥作用的地方。

现在,让我们谈谈用于分析数据的工具。

  1. SAS——统计分析系统的缩写,用于高级分析、数据管理和商业智能。这是一个由 NCSU 从 1966 年到 1976 年开发的授权软件。SAS 仍然被广泛使用,大多数财富 500 强公司都使用 SAS。
  2. R-R 语言是一种用于分析和统计模型的开源语言。许多开源库是为 R 语言创建的。主要用于命令行界面
  3. Python——我个人最喜欢的,Python 是革命性的,今天在这篇文章中我们将使用 Python。这是一种高级编程语言,由 Guido Van Rossum 创建。它是开源的,因此每天都有很多库被创建。事实上,如果你想在机器学习和人工智能领域做出一番事业,Python 是最理想的语言。

今天我们将研究用于数据科学的 Python。

 import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    %matplotlib inline

这里我们导入了三个基本的依赖项,大约 90%的项目需要您导入这三个依赖项。那么这些依赖是什么呢?

  1. numpy——这是一个内置的 python 库,有助于执行数学函数,如矩阵乘法、转换等
  2. Pandas 最重要的库,该库用于导入数据集和创建数据框。这可以进一步用于分析或预测,无论你想做什么!
  3. matplotlib——这是一个用于数据可视化和表示的工具。
  4. % matplotlib inline—因为我要使用 jupyter(Ipython notebook)笔记本,所以我希望我的输出(图形)在笔记本内部。
train = pd.read_csv('train.csv')

现在我们已经准备好了,我们使用上面的命令导入数据。pd 是上面提到的熊猫的简称(进口熊猫为 pd)。read_csv 是熊猫图书馆内部的一个函数。train.csv 文件位于 anaconda 目录中。我们已经成功地将该文件上传到我们的 python 生态系统中,并创建了一个数据框,并且准备好执行功能了!

train.head()

什么是头?人体的上部,不是吗?类似地,pandas 使用 head 函数给我们一个关于数据帧顶部的概述。默认情况下,head()会返回数据帧的前 5 行。

同样,如果我们输入 head(20 ),它将返回前 20 行!有趣不是吗?

类似地,我们可以使用 tail()来查看数据帧的最后 5 个(默认情况下)。

head()的输出将是:-

output for the head() command

现在,我们已经获得了数据框的前 5 行和前 5 列。

最重要的是首先要知道你在处理什么样的数据集,像大小、形状和描述这样的问题是非常重要的,而且随着我们的进一步发展也非常有用,那么关于数据集,我们需要知道哪些关键的事情呢?由于很少有数据集是巨大的,并且处理起来会很痛苦,我们需要找到有用的信息并消除不需要的信息,这听起来很容易,但识别这些信息可能很难。据说研究数据集的形状是一种很好的做法。

shape and size of the data

这里我们可以看到数据有 891 行和 12 列,总数据大小为 10692。

让我们来看一些关于我们现在拥有的数据的基本统计数据

Basic statistics about the data

在这里可以看到数据的统计数据,如计数、平均值、百分位数、标准偏差。当我们处理一些财务数据或绩效相关数据时,这些数据非常重要。

接下来,我们将进行一些数据可视化,这是数据科学必须掌握的最重要的技能之一。正如在导入数据集的过程中所讨论的,我们使用 matplotlib,尽管如果你在 google 上搜索它,还有各种其他的库,但是 matplotlib 在这里服务于我们的目的。

对于数据科学家来说,知道使用哪种表示是非常重要的,我们将首先讨论这一点,然后讨论代码。

表现类型

当我们将数据可视化时,我们头脑中必须有一些东西,

  1. 一张图上要显示多少个变量?
  2. 一个数据点有几个项目还是很多?
  3. 我们是否显示一段时间的数据?还是我们在分组?

这些因素影响图表的选择。

Which chart ?

上图有助于我们确定何时使用哪种图表类型。

但是强烈建议学习一下数据可视化,掌握它。因为许多公司想要数据来告诉我们这个故事。

可视化工具,如 Tableau,PowerBI 可以通过创建一个非常有用的仪表板来告诉我们关于整个数据的故事。

现在,我们看看如何使用 matplotlib 在 python 中可视化数据

Age vs number of passengers (Age distribution of passengers)

我们已经将 matplotlib 作为 plt 导入,这里我们首先从定义 figsize 开始,这意味着图形大小。通常,如果我们没有定义 figsize,它会被设置为默认值,然后我们使用我们的数据并绘制年龄。

我们可以设置标签,xlabel 表示 x 轴标签,ylabel 表示 y 轴标签,title 用于定义图形的标题。

看到图表后,我们可以从数据中推断出一些东西,所有的事情都可以推断出什么呢?

  1. 年轻人更加积极。
  2. 老年人真的很少。
  3. 22 岁的人最高。
  4. 最老的旅行者是 79 岁。

通过观察图表,我们可以推断出更多信息。

类似地,我们也可以从数据集制作许多其他图表,

Survival of people by age

数据集通过使用二进制来告诉我们一个人是否幸存,这很有趣,不是吗?这就是我们如何为我们的需求争论数据,我们将在以后使用统计模型预测更多的事情。

让我们继续,训练我们的计算机根据现有的数据来预测是否有乘客幸存。

机器学习算法

到目前为止,我们已经了解了如何导入数据、可视化数据以及如何从数据中进行推断,现在我们将了解要使用哪些算法以及何时使用?

有两种机器学习算法

  1. 监督学习:-当我们有标签数据时,我们使用监督。机器在数据点的值标签中寻找模式。
  2. 无监督学习:-当我们没有标记的数据时,我们使用它。该机器将数据组织成组并进行比较以找到关系。

监督学习的例子是回归,非监督学习是朴素贝叶斯。

[## 十大机器学习算法

顶级机器学习算法正在数据科学领域取得进展。这里解释的是其中的 10 大…

www.dezyre.com](https://www.dezyre.com/article/top-10-machine-learning-algorithms/202)

此链接将帮助您了解哪种算法是最适合的,以及要使用哪种算法。

但是对于这些数据,我们将使用逻辑回归,我们如何做呢?

逻辑回归帮助我们预测数据的真假。基本上,将一组数据提供给机器,机器使用回归公式进行计算,并以二进制格式给出答案

根据维基百科,在统计、逻辑回归,或者逻辑回归,或者逻辑回归模型、、是回归模型,其中因变量(DV) 是分类。本文涵盖了一个二元因变量的情况——也就是说,它只能取两个值,“0”和“1”,分别代表通过/失败、赢/输、活着/死了或健康/生病等结果。因变量有两个以上结果类别的情况可以在多项逻辑回归中进行分析,或者,如果多个类别是有序的,则在有序逻辑回归中进行分析。在经济学术语中,逻辑回归是定性反应/离散选择模型的一个例子。

那么逻辑回归在这方面如何帮助我们呢?

我们保留了二进制格式的列。所以这不是问题,但我们需要将性别列更改为 1 和 0,这样我们就可以预测是否将性别作为变量之一。

要求我们再次导入 python 库中内置的 sklearn,用于统计工具。Sklearn 服务于所有目的,是一个非常强大的工具。

我们如何做到这一点?

from sklearn.linear_model import LogisticRegression 

我们导入 sklearn 库中的逻辑回归。

逻辑回归的先决条件是有两组数据

  1. 训练数据—该数据用于训练计算机
  2. 测试—测试数据通常很小,用于检查机器对数据的准确性

Converting genders into binary format

在将它们转换成二进制格式后,我们现在可以使用 LogisticRegression 函数来预测我们的结果。

首先,我们将来自训练幸存列设置为逻辑回归模型的输出,以便理解。

因为我们有一个单独的训练和测试数据集,我们可以很容易地使用它,而不需要使用训练和测试分割功能。

Prediction using logistic regression

让我们一步一步来,

  1. 我们将幸存列标记为我们的标签(输出),并使用 data_train(变量)作为我们的训练输入,而不使用幸存列
  2. 然后我们导入 sklearn,并定义模型(变量)以使用逻辑回归函数。
  3. 然后我们拟合我们的模型,这是我们的计算机试图识别模式的地方。这使得我们的计算机能够在类似的数据传入时给出预测。
  4. 我们有一个单独的数据叫做测试,在那里幸存下来的不存在。我们使用 predict 函数根据训练数据集预测结果。

这就是计算机如何通过学习进行预测。下次我们将其他模型,也将看到什么是准确性得分和矩阵得分。

希望你喜欢它并从中得到一些东西,如果有,请分享,下次再见。

如何在 30 分钟或更短时间内建立贝叶斯模型

原文:https://towardsdatascience.com/how-to-build-a-bayesian-model-in-30-minutes-or-less-fd7a23ca1ecf?source=collection_archive---------18-----------------------

你有一个问题,你认为可能需要一些贝叶斯模型

我被问到的一个常见问题是你如何启动

在本教程中,我将带您了解一个新的数据集,这个数据集是一个教育数据集。我对数据一窍不通,也没有具体的领域知识。我改编了来自 PyMC3 文档的模型。

然后,我使用诸如 Arviz 之类的工具来评估模型,解释和评估你的建模决策。我用这个来通知一个更好的模型,我们从对模型的评估中看到,第二个模型要好得多。您可以在Github—census_data笔记本中查看活页夹链接。

我们的第一步是建立一个模型。我们在上面的截图中描述过。

[gallery ids="2034,2033,2032 " type = " rectangle "]

我们做观想阶段。

我们看到我们的第一个模型很差,看看plot_ppc图,我们的模型根本不符合观察到的数据。这是穷人。

如何改进模型?

我们可以利用我们在建模过程中获得的知识来认识到,Beta 分布是一个差的分布,而且过于紧密,我们还可以看到各种模型指标都很差。(这些都在笔记本里)。让我们从贝塔分布转换到伽玛分布,看看会发生什么。

我们看到第二种模式要好得多。查看红色后验预测图如何更好地拟合黑色观察数据。这是一个更好的模型。

关键要点是什么?

从一个例子的模型开始,然后看看它在你的建模用例中的表现,这是一个好主意。关键是完善和批评你的模型。你可以在上面看到我是如何使用像样本后验预测这样的工具来批评和改进模型的。

将这种形象内在化是很好的——盒子循环,这是你在建立贝叶斯模型时需要的工作流程。

关键的事情是,你将你对你试图建模的领域的了解整合到模型中。当我从贝塔分布转到伽玛分布时,你会看到上面的情况。这与您可能习惯的一些机器学习工作流不同。

想了解更多?

如果这满足了你的胃口,你可能想了解更多。你可以在这里注册一个为期 5 天的免费贝叶斯统计电子邮件课程,或者如果你已经确信你可以购买概率编程初级课程。在我的课程中,我给出了近 4 个小时的视频来解释贝叶斯建模的概念。我涵盖了诸如“自动驾驶汽车安全吗”的例子,我介绍了一系列新的概率编程工具,我还在 Arviz 上做了独家截屏。如果你能跟随这篇博文并理解它,那么这个课程就是为你而设的。

如何构建个性化推荐的协同过滤模型

原文:https://towardsdatascience.com/how-to-build-a-collaborative-filtering-model-for-personalized-recommendations-using-tensorflow-and-b9a77dc1320?source=collection_archive---------3-----------------------

基于张量流和张量流变换的推荐模型

2020 年 4 月更新:请注意,现在有一种更简单的方法可以做到这一点。阅读本文关于构建 模型的建议使用 BigQuery ML

在本文中,我将带您逐步了解如何使用 TensorFlow 的 Estimator API 来构建用于产品推荐的 WALS 协同过滤模型。最近,我的同事 Lukman Ramsey 发布了一系列解决方案,详细介绍了如何构建推荐模型— 阅读这些解决方案,了解什么是推荐以及如何建立端到端系统。

Recommending chocolates to users is a collaborative filtering problem

在本文中,我将用 Apache Beam 替换原始解决方案中对 Pandas 的使用——这将允许解决方案更容易地扩展到更大的数据集。因为上下文存在于解决方案中,所以我将在这里简单地深入技术细节。完整的源代码在 GitHub 上。

步骤 1:提取原始数据

对于协同过滤,我们不需要知道任何关于用户或内容的属性。本质上,我们需要知道的只是 userId、itemId 和特定用户对特定项目的评价。在这种情况下,我们可以用花在页面上的时间作为评级的代理。Google Analytics 360 将 web 流量信息导出到 BigQuery,我就是从 BigQuery 中提取数据的:

#standardSQL
WITH visitor_page_content AS (

   SELECT  
     fullVisitorID,
     (SELECT MAX(IF(index=10, value, NULL)) FROM UNNEST(hits.customDimensions)) AS latestContentId,  
     (LEAD(hits.time, 1) OVER (PARTITION BY fullVisitorId ORDER BY hits.time ASC) - hits.time) AS session_duration 
   FROM `cloud-training-demos.GA360_test.ga_sessions_sample`,   
     UNNEST(hits) AS hits
   WHERE 
     # only include hits on pages
      hits.type = "PAGE"

   GROUP BY   
     fullVisitorId, latestContentId, hits.time
     )

# aggregate web stats
SELECT   
  fullVisitorID as visitorId,
  latestContentId as contentId,
  SUM(session_duration) AS session_duration 

FROM visitor_page_content
  WHERE latestContentId IS NOT NULL 
  GROUP BY fullVisitorID, latestContentId
  HAVING session_duration > 0
  ORDER BY latestContentId

查询本身特定于报纸设置 Google Analytics 的方式,特别是他们设置自定义维度的方式,您可能需要使用不同的查询来提取数据,如下表所示:

这是进行协同过滤所需的原始数据集。显然,你将使用什么样的 visitorId、contentId 和 ratings 取决于你的问题。除此之外,其他一切都很标准,您应该能够照原样使用它。

步骤 2:创建枚举的用户和项目 id

WALS 算法要求枚举用户 id 和项目 id,也就是说,它们应该只是交互矩阵中的行号和列号。因此,我们需要获取上面的 visitorId,它是一个字符串,并将它们映射到 0,1,2,…我们需要对项目 id 做同样的事情。此外,评级必须是小数字,通常为 0-1。因此,我们必须调整 session_duration。

为了进行这种映射,我们将使用TensorFlow Transform(TFT)——这是一个允许您使用 Apache Beam 创建预处理数据集进行训练的库,然后在推理期间将该预处理作为 tensor flow 图的一部分来应用!

下面是我使用 TFT 的预处理功能的关键:

**def** preprocess_tft(rowdict):
    median = 57937
    result = {
      'userId' : tft.string_to_int(rowdict['visitorId'], vocab_filename='vocab_users'),
      'itemId' : tft.string_to_int(rowdict['contentId'], vocab_filename='vocab_items'),
      'rating' : 0.3 * (1 + (rowdict['session_duration'] - median)/median)
    }
    *# cap the rating at 1.0*
    result['rating'] = tf.where(tf.less(result['rating'], tf.ones(tf.shape(result['rating']))),
                               result['rating'], tf.ones(tf.shape(result['rating'])))
    **return** result

预处理 BigQuery 中由 visitorId、contentId 和 session_duration 组成的行的结果是一个名为 result 的 Python 字典,它包含三列:userId、itemId 和 rating。

tft.string_to_int 查看整个训练数据集,并创建一个映射来枚举访问者,并将该映射(“词汇表”)写入文件 vocab_users。我对 contentId 做了同样的事情,创建了 itemId。通过将 session_duration 调整到 0–1 之间来获得评级。我的缩放基本上去掉了极长会话持续时间的长尾,这可能代表了在阅读报纸文章时关闭笔记本电脑的人。需要注意的关键点是,我使用纯张量流函数(如 tf.less 和 tf.ones)来进行这种裁剪。这很重要,因为这种预处理函数必须在推理(预测)过程中作为张量流服务图的一部分来应用。

使用 Apache Beam 将预处理功能应用于训练数据集:

transformed_dataset, transform_fn = (
          raw_dataset | beam_impl.AnalyzeAndTransformDataset(preprocess_tft))

步骤 3:写出 WALS 训练数据集

WALS 的训练集由两个文件组成,一个文件提供特定用户评定的所有项目(按行排列的交互矩阵),另一个文件提供评定了特定项目的所有用户(按列排列的交互矩阵)。显然,这两个文件包含相同的数据,但是有必要分割数据集,以便可以并行处理它们。我们也可以在进行枚举的同一个 Apache Beam 管道中这样做:

users_for_item = (transformed_data
    | 'map_items' >> beam.Map(**lambda** x : (x['itemId'], x))
    | 'group_items' >> beam.GroupByKey()
    | 'totfr_items' >> beam.Map(**lambda** item_userlist : to_tfrecord(item_userlist, 'userId')))

然后,我们可以在云数据流上执行 Apache Beam 管道。这是一个完全托管的服务,所以我们不必到处设置基础设施和安装软件(完整代码见 GitHub 中的笔记本)。

此时,我们将拥有以下文件:

items_for_user-00000-of-00003
...
users_for_item-00000-of-00004
...transform_fn/transform_fn/saved_model.pb
transform_fn/transform_fn/assets/
transform_fn/transform_fn/assets/vocab_items
transform_fn/transform_fn/assets/vocab_users
  1. ` ''项目的用户''以 TFExample 格式包含每个项目的所有用户/评级。这里的项目和用户是整数(不是字符串),即 itemId 不是 contentId,userId 不是 visitorId。等级被缩放。
  2. items_for_user 以 TFExample 格式包含每个用户的所有项目/评级。这里的项目和用户是整数(不是字符串),即 itemId 不是 contentId,userId 不是 visitorId。等级被缩放。
  3. vocab_items 包含从 contentId 到枚举 itemId 的映射
  4. vocab_users 包含从 visitorId 到枚举 userId 的映射
  5. saved_model.pb 包含我们在预处理过程中进行的所有张量流变换,因此它们也可以在预测过程中应用。

步骤 4:编写张量流代码

TensorFlow 中有一个基于估算器 API 的 WALS 实现。我们使用它的方式与使用任何其他估计器一样——参见 GitHub repo 中的函数 read_dataset()和 train_and_evaluate()。

更有趣的是我们如何使用训练好的估计量进行批量预测。对于特定用户,我们希望找到前 K 项。这可以在 TensorFlow 中通过以下方式实现:

**def** find_top_k(user, item_factors, k):
  all_items = tf.matmul(tf.expand_dims(user, 0), tf.transpose(item_factors))
  topk = tf.nn.top_k(all_items, k=k)
  **return** tf.cast(topk.indices, dtype=tf.int64)

批量预测包括为每个用户调用上述函数,但是要确保当我们写出输出时,我们写出的是字符串 visitorId,而不是数字 userId(contentId/userId 也是如此):

**def** batch_predict(args):
  **import** **numpy** **as** **np**

  *# read vocabulary into Python list for quick index-ed lookup*
  **def** create_lookup(filename):
      **from** **tensorflow.python.lib.io** **import** file_io
      dirname = os.path.join(args['input_path'], 'transform_fn/transform_fn/assets/')
      **with** file_io.FileIO(os.path.join(dirname, filename), mode='r') **as** ifp:
        **return** [x.rstrip() **for** x **in** ifp]
  originalItemIds = create_lookup('vocab_items')
  originalUserIds = create_lookup('vocab_users')

  **with** tf.Session() **as** sess:
    estimator = tf.contrib.factorization.WALSMatrixFactorization(
                         num_rows=args['nusers'], num_cols=args['nitems'],
                         embedding_dimension=args['n_embeds'],
                         model_dir=args['output_dir'])

    *# but for in-vocab data, the row factors are already in the checkpoint*
    user_factors = tf.convert_to_tensor(estimator.get_row_factors()[0]) *# (nusers, nembeds)*
    *# in either case, we have to assume catalog doesn't change, so col_factors are read in*
    item_factors = tf.convert_to_tensor(estimator.get_col_factors()[0])*# (nitems, nembeds)*

    *# for each user, find the top K items*
    topk = tf.squeeze(tf.map_fn(**lambda** user: find_top_k(user, item_factors, args['topk']), 
                                user_factors, dtype=tf.int64))
    **with** file_io.FileIO(os.path.join(args['output_dir'], 'batch_pred.txt'), mode='w') **as** f:
      **for** userId, best_items_for_user **in** enumerate(topk.eval()):
        f.write(originalUserIds[userId] + '**\t**') *# write userId \t item1,item2,item3...*
        f.write(','.join(originalItemIds[itemId] **for** itemId **in** best_items_for_user) + '**\n**')

为了进行训练和批量预测,我们可以在 Cloud ML Engine 上运行 TensorFlow 模型,同样不需要任何基础设施:

gcloud ml-engine jobs submit training $JOBNAME \
   --region=$REGION \
   --module-name=trainer.task \
   --package-path=${PWD}/wals_tft/trainer \
   --job-dir=$OUTDIR \
   --staging-bucket=gs://$BUCKET \
   --scale-tier=BASIC_GPU \
   --runtime-version=1.5 \
   -- \
   --output_dir=$OUTDIR \
   --input_path=gs://${BUCKET}/wals/preproc_tft \
   --num_epochs=10 --nitems=5668 --nusers=82802

像这样硬编码 nitems 和 nusers 有点难看。因此,我们可以回到我们的 Beam 管道,让它将 nitems 和 nusers 也写入文件,然后简单地执行“gsutil cat”来获得适当的值 GitHub 上的完整代码可以做到这一点。

以下是输出结果的一个示例:

6167894456739729438	298997422,262707977,263058146
3795498541234027150	296993188,97034003,298989783

实际上,每个 visitorId 有 3 个项目。

第 5 步:行和列因子

虽然进行产品推荐是 WALS 的主要用例,但另一个用例是寻找表示产品和用户的低维方法,例如,通过对项目因子和列因子进行聚类来进行产品或客户细分。因此,我们实现了一个服务函数来将这些返回给调用者(同样,完整代码请参见 GitHub):

**def** for_user_embeddings(originalUserId):
      *# convert the userId that the end-user provided to integer*
      originalUserIds = tf.contrib.lookup.index_table_from_file(
          os.path.join(args['input_path'], 'transform_fn/transform_fn/assets/vocab_users'))
      userId = originalUserIds.lookup(originalUserId)

      *# all items for this user (for user_embeddings)*
      items = tf.range(args['nitems'], dtype=tf.int64)
      users = userId * tf.ones([args['nitems']], dtype=tf.int64)
      ratings = 0.1 * tf.ones_like(users, dtype=tf.float32)
      **return** items, users, ratings, tf.constant(True)

管弦乐编曲

注意,本文只是关于替换原解决方案中的机器学习训练和批量预测部分。原始解决方案还解释了如何进行编排和过滤。它们在哪里?

此时,我们现在有了一个 BigQuery 查询、一个 Beam/Dataflow 管道和一个潜在的 AppEngine 应用程序(见下文)。你如何一个接一个地定期运行它们?按照解决方案中的建议,使用 Apache Airflow 来执行此流程编排。

过滤

如果你向顾客推荐巧克力,那么推荐一种他们已经尝试过的巧克力是可以的,但是如果你向用户推荐报纸文章,那么避免推荐他们已经读过的文章是很重要的。

与原始解决方案不同,我的批量预测代码不会过滤掉用户已经阅读过的文章。如果重要的是推荐不包括已经阅读/购买的项目,那么有两种方法可以做到这一点。

更简单的方法是在找到 top_k 之前,将对应于已经读取的项目(这里是评级< 0.01 的项目)的条目清零:

**def** find_top_k(user, item_factors, read_items, k):
  all_items = tf.matmul(tf.expand_dims(user, 0), 
                        tf.transpose(item_factors))
  all_items = tf.where(tf.less(read_items, 
                               0.01*tf.ones(tf.shape(read_items))),
                       all_items,
                       tf.zeros(tf.shape(all_items)))
  topk = tf.nn.top_k(all_items, k=k)
  **return** tf.cast(topk.indices, dtype=tf.int64)

这样做的问题是滞后-您可能不会推荐用户昨天阅读的项目(因为它在您的训练数据集中),但批量预测代码确实可以实时访问阅读的文章流,因此您将推荐他们几分钟前阅读的文章。

如果这种滞后是您想要避免的问题,那么您应该使批量预测中的 k 更高(例如,即使您打算只推荐其中的 5 篇,您也会从推荐者那里获得 20 篇文章),然后在 AppEngine 中进行第二级过滤,如原始解决方案中所建议的那样。

摘要

您现在可以进行批量预测、在线预测和训练,而无需设置任何集群!另外,TensorFlow Transform 允许我们简化元数据的计算和项目/用户的映射,以适应 WALS 范式。

感谢我的同事 Lukman Ramsey 和 Yiliang Zhao 对本文提出的有益意见和建议。

Python:如何构建卷积网络分类器:耐克 vs 阿迪达斯鞋子

原文:https://towardsdatascience.com/how-to-build-a-convolutional-network-classifier-81eef880715e?source=collection_archive---------3-----------------------

Nike Basketball Shoes

我为#100DaysOfMLCode 做的一个实验是建立一个图像分类器,用来区分耐克和阿迪达斯的篮球鞋。我的数据集中目前有 140 张图片。我正致力于增加这个数字,以提高分类器的准确性,并开始使用生成式对抗性网络来创建独特的篮球鞋设计。

通过 140 张图像,我能够使用 4 层卷积网络在耐克和阿迪达斯的鞋子之间实现 91%的准确性。我通过 sentdex 提供的教程学会了如何做到这一点,下面的链接是开始使用 tflearn API 构建图像识别模型的一个很好的资源。

[## Python 编程教程

从初级到高级的 Python 编程教程,涵盖了各种各样的主题。所有视频和文本教程都是…

pythonprogramming.net](https://pythonprogramming.net/convolutional-neural-network-kats-vs-dogs-machine-learning-tutorial/)

我将这段代码修改成适合我的自定义数据集。为了从 sentdex 的示例到我自己的示例提高性能,我增加了图像大小,并添加了更多的卷积层。另外,我使用 PIL 库代替 opencv 进行图像预处理。

所有代码和数据都可以在 github 上找到:

[## CShorten/NIKE_vs_ADIDAS

NIKE _ vs _ ADIDAS 耐克和阿迪达斯篮球鞋之间的图像识别分类器。数据集可在…

github.com](https://github.com/CShorten/NIKE_vs_ADIDAS)

随着将来添加更多数据,我将更新这个存储库。请在 twitter @ CShorten30 上关注我,以获得关于此数据集的更新。

在第一个代码块中,我们导入了除 tensorflow 和 tflearn 之外所需的所有依赖项。PIL 用于预处理和加载图像,numpy 用于将我们的图像数据存储在数组中并将其提供给我们的模型,os 用于与我们的文件系统接口,random 用于混洗数据,这样我们就不会有一个由 20 个连续的 nike 图像和 20 个连续的 adidas 图像组成的数据集,tqdm 用于在您加载数据时提供加载栏,matplotlib.pyplot 用于可视化我们的错误和图像。

TRAIN_DIR/TEST_DIR 变量用于存储数据的相对路径。在本例中,我调整了所有图像的大小,使其具有正方形的尺寸,如 sentdex 示例所示。IMG 大小为 120 会产生(120,120)大小的图像。在未来的实验中,我可能会尝试调整图像的大小,使其高度/宽度更好地代表原始数据,例如(80,140)。

LR = 1e-3 表示学习率。我还没有尝试用学习率参数进行实验,因为我相信 adam 优化算法会对这些简单的实验进行相应的调整。

这个函数将为我们的图像分配标签。从这个函数中有两点要注意。

I .数据集中的每个图像都被标记为类似“阿迪达斯 _1”或“耐克 3”的东西,因此 img . split(“”)可以将其分成[“阿迪达斯”、“1”],并且我们可以比较[0]元素,即耐克或阿迪达斯来分配类别标签。

二。一键编码,我第一次尝试的时候用[0]或[1]来编码类标签。然而,这将不如在诸如[1 0]或[0 1]的向量中编码类那样有效。一键编码也可以很容易地扩展为拥有多个类。例如,如果我们想包含锐步鞋,我们可以将锐步编码为[0 0 1],耐克编码为[1 0 0],阿迪达斯编码为[0 1 0]。

该函数用于从磁盘加载训练数据,并将其带入我们的程序。如果您正在跟随 sentdex 教程,我已经留下了大量的注释块来指示如何使用 PIL 而不是 opencv。这段代码的另一个有趣之处是 train_data 中结果张量的格式。我们看到我们有一个包含矩阵和向量的数组。这些张量的格式化是 numpy 库提供给我们的令人难以置信的特性之一。另外,我不知道您可以使用。np.save('train_data.npy ',train_data)函数中的 npy 扩展。

该函数用于加载没有类别标签的测试数据。这个函数的大部分和上面的一模一样。

接下来,我们运行 create_train_data()函数,您可以看到我们从 tqdm 库中获得的黑色加载栏。接下来,我想要绘制一个图像,以确保数据集被正确加载,并查看新调整的尺寸如何使图像看起来更好。正如我们在上面的图像中看到的,120 x 120 的分辨率产生了一个明显失真的图像,这个图像太高了。但是,你仍然可以清楚地看到阿迪达斯的三条条纹。我认为这个数据集中最重要的视觉特征是区分阿迪达斯条纹和耐克标志。

这是美国有线电视新闻网的代码,如果你想刷新自己的工作原理,我强烈推荐这个视频:

我仍在熟悉这些内核参数,如高度、宽度、步幅、填充等。所以我决定从 sentdex 导入这段代码,并将其视为一个黑盒示例。

尽管有上面的评论,我最终决定使用 90%的训练数据来训练模型,因为我真的没有那么多数据来开始。当我们使用 model.fit 函数来评估模型运行情况时,这段代码用于留出一些数据进行验证。

当我浏览 sentdex 的例子时,我不确定这段代码是否有必要,因为看起来我们已经在 create_train_set()函数中格式化了数据,尽管如此。

这是我们用来实际拟合模型的代码。我在加载 tensorboard 来可视化参数更新时仍然有些问题。然而,这个控制台输出仍然非常有趣,因为您可以试验您的模型参数,例如图像的大小、训练数据量、卷积层数、卷积核维数和历元数。根据这一评估,我们有大约 92–93%的准确率,我对此非常满意。

最后,我们使用这个代码块加载我们的测试数据,并了解模型的执行情况。正如我们在上面的例子中看到的,只有一只勒布朗鞋被误归类为阿迪达斯的。图像上方的概率列表显示了模型对每只鞋属于每个类别的置信度。例如,在第一张图片中,我们看到模型认为只有 0.2%的可能性是耐克鞋,而 99.7%的可能性是阿迪达斯鞋。

总之,当我第一次加载数据并运行模型时,我得到的结果非常糟糕。然而,一旦我开始调整卷积层数,调整图像大小,使用学习率值和历元数,我开始得到一个令人敬畏的结果。

如果您使用自己的数据集尝试 sentdex 的教程,如果一开始它似乎不起作用,请不要气馁。在放弃之前,尝试调整模型的超参数。此外,如果你想链接到本教程的视频演练,这里是:

感谢您的阅读,如果您自己做这件事有困难,请联系我们!

https://github.com/CShorten/NIKE_vs_ADIDAS

CShorten

Connor Shorten 是佛罗里达大西洋大学计算机科学专业的学生。对软件经济学、深度学习和软件工程感兴趣。

这是从哪里来的

这个故事发表在值得关注的杂志上,每天都有成千上万的人前来了解塑造我们喜爱的产品的人们的想法。

关注我们的出版物,查看更多由 Journal 团队报道的产品和设计故事。

如何建立数据科学管道

原文:https://towardsdatascience.com/how-to-build-a-data-science-pipeline-f24341848045?source=collection_archive---------1-----------------------

从 y 开始。专注于形式化预测问题,建立工作流程,并将其转化为生产,而不是优化您的预测模型。一旦前者做到了,后者就好办了。

如果你喜欢这个博客,看看这个关于同一话题的 播客

当一个运行良好的预测工作流最终投入生产时,它是如何工作的,这一点没有争议。数据源被转换成一组特征或指标 X ,描述预测将作用的每个实例(客户、设备、资产)。然后,预测器将 X 转化为可操作的信息 y_pred (客户端会流失吗?,设备会失效吗?,资产价格会涨吗?).在某些不稳定的市场中(例如,广告定位),预测然后通过完全自动化的流程货币化,在其他情况下,它被用作决策支持,并有一个人在循环中。

The data flow in a data science pipeline in production.

这听起来很简单,但有效且盈利良好的预测工作流的例子很少。公司在建造过程中苦苦挣扎。他们需要问的问题是:

  • 谁构建这个工作流?我需要涵盖哪些角色和专业知识?
  • 构建过程是怎样的?步骤是什么,每一步我需要什么专业知识?
  • 这些步骤的成本和风险是什么,我如何控制它们?

围绕数据挑战的炒作给人一种错误的印象,即数据科学家和预测分数是这一过程的主要驱动力。即使是自 90 年代以来就存在的工业流程(例如 CRISP-DM 和 Dataiku )也通常将数据科学家放在中心位置,并在流程的最后进行部署。虽然他们没有错,但他们大多是不相关的。构建和优化预测器很容易。困难的是找到业务问题和它将改进的 KPI,搜寻数据并将其转换为可消化的实例,定义工作流的步骤,将其投入生产,并组织模型维护和定期更新。

公司通常从一个看似显而易见的事情开始:要求他们的 IT 部门建立大数据基础设施并构建一个数据湖。然后他们雇佣了第一批数据科学家。这些刚从学校毕业的专家和一些 Kaggle challenges,带着数据科学工具包,渴望将他们的手放在数据上。他们可以预测任何事情,他们做到了!他们与业务部门交谈,找到已经存在标签的合理预测目标,尝试十几个模型,对它们进行超测,并选择最佳的。他们建立 POC 并向业务部门发送报告。然后重新开始。

The usual way to construct a data science workflow.

大多数概念验证从未投入生产。业务部门不知道该拿他们怎么办。他们无法解读分数。这个预测目标似乎很合理,但是他们不知道如何用他们的 y_pred 赚钱。如果是这样的话,将 POC 投入生产似乎是不可逾越的。代码必须重写。实时数据必须被导入工作流程。需要满足操作约束。决策支持系统需要与用户的现有工作工具集成。模型维护、用户反馈、回滚需要到位。与数据科学家从事的安全 POC 相比,这些操作通常成本更高、风险更大,而且 POC 根本无法推动这一过程。

我下面描述的过程不会解决这些问题,但是它给你一个顺序,在这个顺序中你至少可以处理和控制成本和风险。首先,不惜任何代价找到一位首席数据官(或者更确切地说是一位数据价值架构师),他已经将一个预测性的工作流程投入生产。你的 CDO 不需要知道最新的深度学习架构,但她应该对公司的业务和数据科学流程都有广泛的了解。她应该发挥核心作用,推动这一进程。

尽早让它上船是很重要的。您需要您的数据湖,但更重要的是,您需要数据工程师从第一天起就考虑生产。但这并不是第一步。第一步是弄清楚你是否需要一个预测

所以,从 y 开始,预测目标。

你的 CDO 应该与业务部门密切合作,找出他们想知道的东西。是什么推动了他们的决策?对 y 的更好预测将如何提高底线(成本下降,利润上升,生产率上升)?一旦你有了你的 y ,试着尽可能地将预测误差货币化。没有什么比良好的货币化指标更能让你的(未来)数据科学家高兴的了。他们会知道,提高 2%的分数会让你成为百万富翁;更重要的是 将知道你可以在你的数据科学团队上花费多少。

一旦你巩固了 y 和度量标准,

去寻找数据,

在你的数据湖和其他地方找到指标,这些指标可能与你的预测目标相关。原则上,您仍然不需要数据科学家来做这件事,这个过程应该由 CDO 和业务部门来推动(毕竟,他们知道他们使用什么信息来做决策,这通常是一个很好的基线)。但是,如果有人知道公开的和可购买的数据,这可能会有所帮助。在这里,您绝对需要与 IT 部门交流,以便了解当这些指标需要实时收集时的运营成本。数据科学家需要这些信息。如果在每个客户端上存储一个新功能每天要花费 4TB,那么这个事实就决定了预测器的外观。

现在雇佣一名数据科学家,最好是能开发生产质量软件的。让他

构建实验设置和基线工作流

用简单的预测来检验它是否能投入生产。此时,您已经为数据科学家知道如何处理的全面实验数据科学循环做好了准备。你可能需要一个深度学习专家,但很可能你可以外包和众包你的第一个模型,例如,通过与我们一起做 RAMP 。

如果你喜欢你读的东西,就在中、 LinkedIn 、&、 Twitter 上关注我吧。

如何构建数据科学产品组合

原文:https://towardsdatascience.com/how-to-build-a-data-science-portfolio-5f566517c79c?source=collection_archive---------0-----------------------

A portfolio is one way to show people you are that data science unicorn.

如何在数据科学领域找到工作?了解足够多的统计学、机器学习、编程等知识以便能够找到工作是很困难的。我最近发现的一件事是,相当多的人****可能拥有找到工作所需的技能,但没有作品集。虽然简历很重要,但拥有一份公开证明你数据科学技能的作品集可以为你的工作前景创造奇迹。即使你有推荐人,向潜在雇主展示你能做什么而不是仅仅告诉他们你能做什么也是很重要的。这篇文章将包含各种数据科学专业人士(数据科学经理、数据科学家、社交媒体图标或其组合)和其他人讨论投资组合中应该包含什么以及如何引起注意的链接。就这样,让我们开始吧!

投资组合的重要性

除了通过制作文件夹来学习的好处,文件夹也很重要,因为它可以帮助你找到工作。出于本文的目的,让我们将投资组合定义为您的数据科学技能的公开证据。我是从数据营的首席数据科学家大卫·罗宾逊那里得到这个定义的,当时他在模式分析博客上接受了玛丽莎·杰玛的采访。当他被问到他在工业界的第一份工作时,他说,

对我来说,最有效的策略是做公共工作。在博士后期,我写了很多博客,做了很多开源开发,这些都有助于向公众证明我的数据科学技能。但我获得第一份行业工作的方式是公共工作中一个特别值得注意的例子。在我读博士期间,我是编程网站 Stack Overflow 的活跃回答者,该公司的一名工程师偶然发现了我的一个答案(一个解释 beta 分布背后的直觉的答案)。这个回答给他留下了深刻的印象,他(通过 Twitter)联系了我,几场面试后我被录用了。

你可能会认为这是一个奇怪的现象,但是你会发现你越活跃,发生这种事情的机会就越大。来自大卫的博客文章,

你做的公开工作越多,发生这种意外的可能性就越大:有人注意到你的工作并给你指出一个工作机会,或者有人在面试你时听说过你做过的工作。

人们经常忘记软件工程师和数据科学家也在谷歌上搜索他们的问题。如果这些人通过阅读你的公共作品解决了他们的问题,他们可能会对你有更好的看法,并向你伸出援手。

绕过经验要求的投资组合

即使是初级职位,大多数公司都希望员工至少有一点点实际生活经验。你可能见过像下面这样的迷因。

问题是,如果你需要经验来获得第一份工作,你如何获得经验?如果有答案,答案是项目。项目也许是工作经验的最佳替代品,或者如威尔·斯坦顿所说,

如果你没有任何数据科学家的经验,那么你绝对必须做独立项目。

事实上,当杰奎琳·诺利斯 面试候选人时,她想听的是对你最近面临的一个问题/项目的描述。

我想听听他们最近参与的一个项目。我问他们这个项目是如何开始的,他们如何确定它值得花时间和精力,他们的过程和他们的结果。我还问他们从这个项目中学到了什么。我从这个问题的答案中获益匪浅:如果他们能讲述一个故事,这个问题如何与更大的图景联系起来,以及他们如何解决做某事的困难。

如果你没有一些数据科学相关的工作经验,这里最好的选择是谈谈你曾经从事过的一个数据科学项目。

投资组合中包含的项目类型

数据科学是一个如此广阔的领域,以至于很难知道招聘经理希望看到什么样的项目。Quora 的数据科学经理 William Chen 在 Kaggle 的 CareerCon 2018 ( 视频)上分享了他对这个主题的想法。

我喜欢那些人们表现出他们对数据感兴趣的项目,而不仅仅是家庭作业。任何种类的期末项目,你探索一个有趣的数据集,发现有趣的结果…努力写下…我真的很喜欢看到真正好的写下人们发现有趣和新奇的事情…有一些可视化和分享他们的工作。

很多人认识到创建项目的价值,但很多人想知道的一个问题是,你从哪里获得有趣的数据集,你用它做什么?Airbnb 的数据科学家杰森·古德曼(Jason Goodman)有一个关于建立数据组合项目的帖子建议,他谈到了许多不同的项目想法,并对你应该使用什么样的数据集提出了很好的建议。他还附和了威廉关于使用有趣数据的观点。

我发现最好的项目组合与其说是做花哨的建模,不如说是处理有趣的数据。很多人用金融信息或 Twitter 数据做事情;这些可以工作,但是数据本身并不那么有趣,所以你要努力工作。

他在文章中的另一个观点是,网络抓取是获取有趣数据的一个很好的方式。如果你有兴趣学习如何用 Python 通过 webscraping 构建自己的数据集,你可以在这里看到我的帖子。如果你来自学术界,需要注意的是,你的论文可以算作一个项目(一个非常大的项目)。你可以在这里听到威廉陈谈论它。

Traffic Cruising Data Science for Social Good Project (https://github.com/uwescience/TrafficCruising-DSSG2017). This is an example of a project I personally find interesting, but there are so many interesting projects out there. Credit (Orysya Stus, Brett Bejcek, Michael Vlah, Anamol Pundle)

不包括在投资组合中的项目类型

我发现,在很多投资组合/简历建议中,有一件事非常普遍(在这篇博文中多次出现),那就是不要在你的投资组合中有共同的项目。

Jeremie Harris 在中提到了不被聘用为数据科学家的 4 种最快方法,

很难想出一个比在你突出的个人项目中突出你在琐碎的概念证明数据集上所做的工作更快的方式来让你的简历被扔进“肯定没有”的一堆。

当你有疑问时,这里有一些对你伤害大于帮助的项目:

*在泰坦尼克号数据集上的生存分类。

*在 MNIST 数据集上的手写数字分类。

*使用 iris 数据集进行花卉种类分类。

下图显示了泰坦尼克号(A)、MNIST 号(B)和虹膜号(C)数据集的部分分类示例。没有太多的方法可以使用这些数据集来区分你和其他申请人。确保列出新颖的项目。

Titanic (A), MNIST (B), and iris (C) classification

投资组合是迭代的

法维奥·瓦兹奎有一篇的优秀文章,他在文章中讲述了自己是如何获得数据科学家这份工作的。当然,他的建议之一是要有一个投资组合。

T4 有一个投资组合。如果你正在寻找一份严肃的数据科学的有偿工作,做一些有真实数据的项目。如果你能把它们发布在 GitHub 上。除了 Kaggle 比赛,找一些你喜欢的事情或者你想解决的问题,用你的知识去做。

另一个有趣的发现是,在求职过程中,你必须不断进步。

我申请了将近 125 份工作(真的,也许你申请了更多),我只收到了 25-30 份回复。有些人只是说:谢谢,但是不用了。我接受了将近 15 次采访。我从每一个人身上学到了东西。变好了。我不得不面对许多拒绝。一些我实际上没准备好的事情。但我喜欢接受采访的过程(说实话,并不是所有人)。我学习了很多,每天编程,看了很多文章和帖子。他们帮了大忙。

随着你了解更多,提高自己,你的作品集也应该更新。这一观点在许多其他建议文章中得到了回应。正如杰森·古德曼所说,

当你公开发布的时候,这个项目还没有完成。发布后,不要害怕继续添加或编辑您的项目!

这个建议在你找工作的时候尤其正确。有很多像 Airbnb 的数据科学家 Kelly Peng 这样的成功人士的故事,他们真的坚持不懈,不断工作和改进。在她的一篇博客文章中,她回顾了她申请和面试了多少个职位。

应用:475

电话采访:50 次

完成数据科学带回家的挑战:9

现场面试:8 次

优惠:2

花费的时间:6 个月

她明明申请了很多工作,还一直在坚持。在她的文章中,她甚至提到你需要从面试经历中不断学习。

记下你被问到的所有面试问题,尤其是那些你没有回答的问题。你可以再次失败,但不要在同一个地方失败。你应该一直学习和提高。

*If you aren’t getting interviews yet, apply for more jobs and keep on finding ways to learn and improve.

将作品集整合到一页简历中

有人发现你的作品集的方法之一通常是通过你的简历,所以这是值得一提的。数据科学简历是关注你的技术技能的地方。你的简历是一个简洁地展示你的资格和适合那个特定角色的机会。招聘人员和招聘经理浏览简历的速度非常快,你只有很短的时间来留下印象。改进你的简历可以增加你获得面试的机会。你必须确保简历中的每一行和每一部分都有价值。

Quora 的数据科学经理 William Chen(T1)给了 9 个让你的数据科学简历变得更好的技巧。注意在下面他的要点的简要总结中,项目和投资组合是要点 6、7、8,甚至可以说是要点 9** 。**

  1. 长度:保持简单,最多一页。这给你快速浏览带来最大的影响。推荐一份简单的单栏简历,因为它很容易浏览。

Sample Resume used in Video (latex: https://github.com/sb2nov/resume)

****2。目标:不包括一个。他们不会帮你把自己和其他人区分开来。他们从更重要的东西(技能、项目、经验等)那里拿走了空间。求职信是非常有选择性的,除非你真的个性化它。

Objectives don’t help you distinguish yourself from other people. A lot of them say very similar things.

****3。课程:列出适用于职位描述的相关课程

Examples of relevant coursework displayed on various resumes.

****4。技能:不要给你的技能打分。如果你想对自己的技能进行评分,使用诸如熟练或熟悉之类的词语。你甚至可以完全排除评估。

Don’t give numerical ratings for your skills

5。技能:一定要列出工作描述中提到的技术技能。你列出技能的顺序可以暗示你最擅长什么。

Examples of how you can list your skills on your resume

****6。项目:不要列出常见的项目或作业。它们对区分你和其他申请人没什么帮助。列出新颖的项目。

7。项目 : 显示结果并包含链接。如果你参加了 Kaggle 竞赛,请填写百分比排名,因为这有助于阅读你简历的人了解你在竞赛中的位置。在项目部分,总会有链接到评论和论文的空间,因为它们可以让招聘经理或招聘人员更深入地挖掘(偏向于现实世界中的棘手问题,在那里你可以学到新东西)。

Good example project sections

请注意,在上面的一个项目部分,一个人有一个额外的博客链接,可以让招聘人员或招聘经理了解更多信息。这是从你的简历中链接到你的投资组合的不同部分的一种方法。

****8。投资组合:填充我们您的在线状态。最基本的是 LinkedIn 个人资料。这有点像一份扩展的简历。Github 和 Kaggle 简介可以帮助展示你的作品。填写每个个人资料,并包括其他网站的链接。填写 GitHub 存储库的描述。包括你的知识分享简介/博客(medium,quora)的链接。数据科学特别是关于知识共享和交流数据对其他人的意义。你不需要做所有的事情,但是选择一些去做(稍后会有更多的介绍)。

****9。经验:让你的经验适合这份工作。经验是你简历的核心,但是如果你没有工作经验你会怎么做?把你的简历集中在独立的项目上,比如顶点项目、独立研究、论文工作或 Kaggle 竞赛。如果你没有工作经验可以写进简历,这些都是工作经验的替代品。避免把不相关的经历写进简历。

如果你想知道听到数据科学经理审阅投资组合和简历,这里有 Kaggle 的 CareerCon 2018 的链接(视频,简历审阅)。

社交媒体的重要性

这与投资组合部分的重要性非常相似,只是分成了子部分。拥有一个 Github 页面、一个 Kaggle 简介、一个 Stack Overflow 等可以为你的简历提供支持。对招聘经理来说,在网上填写个人资料是一个好信号。

正如大卫·罗宾逊所说,

一般来说,当我评估一个候选人时,看到他们公开分享的东西,我会很兴奋,即使这些东西还没有润色或完成。分享任何东西总比什么都不分享好。

数据科学家之所以喜欢看公共作品,是因为正如 威尔·斯坦顿 所说,

数据科学家使用这些工具来分享他们自己的工作,并找到问题的答案。如果你使用这些工具,那么你就是在向数据科学家发出信号,表明你是他们中的一员,即使你从未做过数据科学家。

很多数据科学都是关于交流和呈现数据的,所以拥有这些在线资料是很好的。除了这些平台有助于提供宝贵的经验之外,它们还能帮助你获得关注,让人们看到你的简历。人们可以通过各种渠道在网上找到你的简历(LinkedIn、GitHub、Twitter、Kaggle、Medium、Stack Overflow、Tableau Public、Quora、Youtube 等)。你甚至会发现不同类型的社交媒体可以互相交流。

Github

Github profiles of Jennifer Bryan and Yuan (Terry) Tang

Github 档案是一个强有力的信号,表明你是一个有能力的数据科学家。在简历的项目部分,人们通常会留下 GitHub 的链接,那里存储着他们项目的代码。你也可以在那里写文章和减价。GitHub 让人们看到你构建了什么,以及你是如何构建的。在一些公司,招聘经理会看应聘者的 GitHub。这是向雇主展示你不是假阳性的另一种方式。如果你花时间建立你的 GitHub 档案,你会比其他人得到更好的评价。

值得一提的是,你需要有一些 README.md 的项目描述,因为很多数据科学是关于交流结果的。确保 README.md 文件清楚地描述了您的项目是什么、它做什么以及如何运行您的代码。

卡格尔

参加 Kaggle 竞赛、创建内核以及参与讨论都是展示数据科学家能力的方式。需要强调的是,Kaggle 并不像 Colleen Farrelly 在 quora 问题中提到的那样是一个工业项目。Kaggle 竞赛负责提出一项任务,为您获取数据,并将其整理成某种可用的形式。它的作用是让你练习分析数据和提出模型。注意, Kaggle 特级大师继续参加 Kaggle 比赛是有充分理由的。热沙玛·谢赫有一篇关于 Kaggle 与否的文章,她在文中谈到了 Kaggle 比赛的价值。从她的岗位上,

没错,参加一场 Kaggle 比赛并不能证明一个人有资格成为数据科学家。上一堂课或参加一个会议辅导或分析一个数据集或阅读一本数据科学方面的书也是如此。参加竞赛可以增加你的经验,扩大你的投资组合。它是对您其他项目的补充,而不是对您的数据科学技能的唯一试金石。

我完全同意热沙玛对此的看法。特别是,参加某方面的课程并不能让你成为某方面的专家,也不能给你一份工作。我实际上已经为数据可视化制作了一门名为 Python 的课程,并且我深入研究了关于 Pandas、Matplotlib 和 Seaborn 的内容。它不会马上给你一份工作,也不会让你马上成为 Matplotlib 或 Seaborn 方面的专家,但它会让你的知识更丰富,教会你图书馆如何工作,并帮助你建立自己的作品集。你做的每一件事都能让你更有竞争力。

领英

与受长度限制的简历不同,LinkedIn 简介允许你更深入地描述你的项目和工作经历。Udacity 有一个关于在 LinkedIn 上建立良好个人资料的指南。LinkedIn 的一个重要部分是他们的搜索工具,为了让你出现,你必须在你的个人资料中有 相关关键词 。招聘人员经常在 LinkedIn 上搜索人员。LinkedIn 可以让你看到哪些公司搜索过你,哪些人浏览过你的个人资料。

Checking where your searchers work and how many times people have viewed your profile.

除了公司找到你并向你发送信息,LinkedIn 还有许多功能,如请求推荐。 Jason Goodman 在他的文章中对申请数据科学工作的建议使用 LinkedIn 来间接请求推荐。

我从来没有,从来没有,从来没有在没有工作人员介绍的情况下申请过任何公司…一旦我对一家公司感兴趣,我会使用 LinkedIn 在该公司找到第一或第二级关系。我会写信给那个联系人,询问他们在公司的经历,如果可能的话,他们是否能帮我联系到数据科学团队的某个人。只要有可能,我就亲自开会(喝咖啡或吃午饭),而不是打电话。顺便说一句,特雷·考西最近写了一篇很棒的文章,讲述了如何要求这类会面。我从来不会直接找工作,但他们通常会要我的简历,并提出让我做内部推荐人,或者让我联系招聘经理。如果他们觉得这样做不舒服...我只是感谢他们的时间,然后继续前进。

请注意,他没有马上要求推荐。虽然申请公司时常见的工作建议是获得推荐,但非常重要的是要注意,你仍然需要一份投资组合、经验或某种证明你可以做一份工作。Jason 甚至在他写的和其他文章中提到了投资组合的重要性。

阿曼·达尔米亚通过在多家人工智能公司和初创公司的面试,也学到了类似的东西。

人际关系网是而不是给人们发信息让他们给你推荐。当我刚开始的时候,我经常犯这样的错误,直到我偶然发现一篇文章,它讲述了通过主动提供帮助来与人建立真正联系的重要性。

他的另一个观点是,LinkedIn 非常适合让你的内容/投资组合公开。

人际交往的另一个重要步骤是让你的内容传播出去。例如,如果你擅长某件事,写博客并在脸书和 LinkedIn 上分享。这不仅能帮助别人,也能帮助你。

媒体和/或其他博客平台

拥有某种形式的博客是非常有益的。很多数据科学都是关于交流和呈现数据的。写博客是实践这一点并展示你能做到这一点的一种方式。撰写关于项目或数据科学主题的文章可以让您与社区分享,并鼓励您写出您的工作流程和想法。这是面试时很有用的技巧。

正如大卫·罗宾逊所说,

博客是你练习相关技能的机会。

  • 数据清理 :使用各种数据集的一个好处是,你学会了“随取随用”,无论是以期刊文章 补充文件的形式,还是以电影剧本

  • 统计学 :处理不熟悉的数据可以让你将统计方法付诸实践,写一些交流和教授概念的帖子有助于建立你自己的理解

  • 沟通 :你获得了写作的经验,也获得了构建数据驱动论点的练习。这可能是博客发展的最相关的技能,因为很难在其他地方实践,而且这是任何数据科学职业的基本部分

通过写博客,你可以练习与他人交流发现。这也是宣传自己的另一种形式。关于使用 Scrapy 构建自己的数据集的博客,讽刺的是使用 Conda 的 Python 环境管理教会了我很多,也让我获得了很多平时不会得到的机会。最近,我的 boxplot 博客给我带来了为数据可视化课程创建自己的 Python 的机会。我发现的一个主要好处是,在人们批评我的项目并提出改进建议的整个过程中(尽管博客的评论部分),面试官不会第一个指出这些相同的缺陷。更明显的好处是,通过写博客,你倾向于阅读更多的数据科学/机器学习博客帖子,从而学到更多。

至于在什么平台上写博客,我推荐用 Medium。 Manali Shinde 在她的博客文章如何从零开始构建数据科学作品集中有一个关于她为什么选择 Medium 作为博客的非常好的观点。

我想到在 WordPress 或 Squarespace 等平台上创建自己的网站。虽然这些平台可以托管你自己的投资组合,但我希望有一个地方可以让我获得一些知名度,并有一个很好的标签系统来吸引更多的观众。幸运的是,正如我们所知,Medium 有这些选项(而且也是免费的)。

如果你不知道该写些什么,我建议你看看大卫·罗宾逊的建议。

https://twitter.com/drob

推特

活跃在 Twitter 上是一种很好的方式来识别你所在领域的人,并与他们互动。你也可以在 Twitter 上推广你的博客,这样你的作品集就能更加引人注目。在 twitter 上有很多与人互动的机会。其中一个人在她著名的博客文章“中说: Reshama Shaikh 我如何获得我的第一份数据科学工作?“是,

大卫·罗宾逊慷慨地提出转发你的第一篇数据科学帖子。拥有 2 万多名粉丝,这是一个无法拒绝的提议。

除了自我推销,Twitter 还可以用于其他方面。数据科学 Renee 有一个帖子“如何使用 Twitter 学习数据科学(或任何东西)”,对使用 Twitter 学习技能颇有见地。她文章中的另一个要点是,她的 Twitter 对她的社交网络和获得机会有多大帮助。

我被播客和博客邀请接受采访(其中一些应该很快就会出现),提供合同工作,并免费参加一个会议,可惜我不能去,但很高兴被考虑参加。业内“有名”的人现在都以某种方式来找我合作。

Tableau 公共

并非每个数据科学工作都使用 Tableau 或其他 BI 工具。但是,如果你申请的是使用这些工具的工作,需要注意的是,有一些网站可以让你把仪表盘放在那里供公众使用。例如,如果你说你正在学习或了解 Tableau,在 Tableau Public 上放几个仪表盘。虽然许多公司可能不介意你在工作中学习 Tableau,但公开证明你的 Tableau 技能会有所帮助。如果你想看 Tableau 公开简介的好例子,请参见Orysya Stus’和 Brit Cava 的简介。

结论

Remember a portfolio is a process. Keep on improving.

拥有一份出色的简历一直是求职者向潜在雇主传递技能的主要工具。如今,有不止一种方法可以展示你的技能并得到一份工作。公开证据组合是获得你通常不会得到的机会的一种方式。强调投资组合是一个迭代的过程是很重要的。随着你知识的增长,你的投资组合应该随着时间的推移而更新。永远不要停止学习或成长。甚至这篇博文也会随着反馈和知识的增长而更新。如果你想要面试建议/指南/课程,现在就来看看 Brandon Rohrer 关于如何在数据科学面试中生存的建议、Sadat、面试指南,或者我的关于获得数据科学工作课程的 15 条建议。如果你想要一些通用的数据科学职业建议,我在这里写了一篇关于它的文章。如果你对教程有任何问题或想法,欢迎在下面的评论中或通过 Twitter 联系。

如何使用机器学习构建动态花园

原文:https://towardsdatascience.com/how-to-build-a-dynamic-garden-using-machine-learning-d589468f7c04?source=collection_archive---------4-----------------------

PIcture by jjekafluf

让我们建造一个虚拟花园吧!

这是未来,我们已经在构建大脑接口方面取得了重大进展。我们用它来扩大我们的视野,有时,改变我们对世界的看法。

一个有事业心的园丁决定打造终极花园体验。一片空白的土地。一块空白的画布,等待着被园林设计师的眼光填满。花园的元素可以由花园的设计师来控制。它是动态的,对用户来说是个性化的。设计师如何利用机器学习来建造这样的花园?

让我们训练一个模型,它将挑选一个花园配置显示给用户。这个模型为一个目标而优化。一般的方法是:

1.选择一个目标。让我们选择“回访的高概率”也就是留存率。

2.对影响目标的因素形成一个假设。这些成为 ML 模型中的特征。例如:花园的配置,参观时花园中的总人数,您是否独自一人,您的年龄,天气,您是否带着孩子参观等。就本文的目的而言,让我们假设我们拥有任何我们想象出来的数据,比如一个人当前的情绪。

3.由于存在大量的配置,可能无法从单个配置中高精度地预测目标。为了让用户满意,找到配置的中间表示。因为我们可以了解用户的心情,所以当用户在花园里散步时,我们就可以测量快乐程度。我们建立了一个“幸福旅程”,并以某种方式量化它。然后,我们将这一幸福之旅作为模型中的一个特征来预测目标

4.当一个用户进入花园,你就知道为了目标优化需要给用户的幸福旅程。

5.使用类似近似动态规划的方法来决定使用什么样的花园配置来实现幸福之旅

使用这样的配置可以完整地描述一个花园。

一个神气的 MBA 学生出现了。

“有没有想过加一家奶茶店?

你会赚更多的钱

“好主意。让我开始试验那个"

我们现在有了一个新目标——最大化奶茶店的收入。我们重复这一过程,现在有两个模型——一个是为了留住客户而优化,另一个是为了最大化奶茶店的收入。

试验不同的模型

一起运行这些模型可能会导致配置冲突。例如,如果天气很热,茶叶店的收入模式可能会导致一种配置,即到处摆放香草植物,让你对海绵蛋糕产生饥饿感。保留模式可能会在花园里留下一块空地来晒太阳(这在伦敦很常见),同时被芒果树包围。一个人如何分清轻重缓急?这里有三种可能的方法。

按照优先级顺序堆叠排名目标

可以使用目标的基本排序。如果有冲突,选择保留而不是货币化。但是现实生活更复杂。在免费游戏中,留存率和盈利率通常成反比。如果你在游戏中引入更多的货币化触发和货币紧缩,你可能会增加货币化,但你会减少保留。我经常与其他项目经理进行激烈的辩论——“ARPDAU(每日活跃用户平均收入)的增加是因为人们离开游戏,还是因为更多的人在游戏中消费。到底是哪个,哪个更好?”

一切事物的度量

平衡相互冲突的目标的一种方法是找到一个总括性的度量标准,它包含了您所关心的所有其他度量标准。这可能是收入或终身价值(LTV)。一组用户的 LTV 方程是(%仍在游戏中的用户)x(每个用户在游戏中花费的钱),随时间积分,即留存 x 货币化。这在理论上听起来是一个很棒的主意——让我们在游戏中尽一切努力最大化 LTV,我们就完成了!

如果我们以 LTV 为目标训练一个模型,我们依靠这个模型来学习留存和货币化之间的关系。这是一种危险的情况,因为很难做出产品体验的改变,也很难在更细粒度的度量上测试它们的有效性。例如:与花园中的桉树接触。

这种模式将强化过去一直行之有效的留存和货币化之间的权衡,但这种权衡可能不符合产品的战略重点。“我们需要达到本月的收入目标,尽一切努力”或“让我们专注于让我们的早期用户漏斗正确”。

型号重量

这是堆栈排序方法的一个细微版本。假设我们有一个留存模型(模型 A)和一个货币化模型(模型 B),这些模型预测的概率在 0 到 1 之间。如果我们将留存率排在货币化之前,我们给模型 A 的权重为 1,给模型 B 的权重为 0。这个产品决策可以封装成 1 x 模型 A + 0 x 模型 b。

模型权重可以概括为:

产品决策

得出正确的重量是一个主观的产品决策。“对于第一次来花园的用户,我们不要试图在他们第一次访问时让他们进入茶叶店”或“每次用户访问时增加 5%的货币化模型权重,这样我们每次访问都会增加货币化的可能性”。

最棒的是,没人知道什么会奏效。“工作”的定义到底是什么——在一个目标相互竞争的机器学习环境中,你如何定义成功?事先不可能知道,因为用户的体验与产品决策只差一步。我们为模型设定权重,这些权重的组合会产生特定类型的用户行为。这个用户行为充当模型的训练数据。这就形成了一个非常紧密的学习循环。

这种学习循环的美妙之处在于,现在可以通过提供个性化的用户体验来进行实验。

机器学习模型中的实验通常与尝试不同的算法、调整参数、改变训练特征等相关联,以优化目标。当使用机器学习来改变核心产品体验时,学习循环允许产品经理和数据科学家对用户体验本身进行实验。这是非常有益的,因为产品一直在变化——新的功能被构建,新的内容被发布,不同类型的用户出现来使用你的产品。

“产品变了,车型需要跟上”

持续实验的文化对于使用 ML 进行产品体验至关重要。可以通过尝试不同的模型权重来试验产品决策。新的模型是用不同的特性组合构建的,新的目标是添加的,产品其他方面的变化将改变模型的行为。实验是 ML 产品管理的关键。

接下来:E 探索难度空间 (链接下周五)

构建用于自然语言处理的卷积神经网络

原文:https://towardsdatascience.com/how-to-build-a-gated-convolutional-neural-network-gcnn-for-natural-language-processing-nlp-5ba3ee730bfb?source=collection_archive---------2-----------------------

如何从零开始建立一个门控卷积神经网络(GCNN),用 Pytorch 实现

具有 LSTM 或 GRU 单元的递归神经网络(RNNs)是 NLP 研究人员的首选工具,并在许多不同的 NLP 任务上提供最先进的结果,包括语言建模(LM)、神经机器翻译(NMT)、情感分析等。然而,RNNs 的一个主要缺点是众所周知的训练速度慢,所以过去几年的努力都集中在试图加快它们的速度上。有多种方法可以做到这一点,包括使用预训练模型的,使用更快的 softmax ,以及使用不同的架构,如卷积神经网络(CNN),准递归神经网络(qrns,或变压器架构。在这篇博文中,我将告诉你来自脸书人工智能研究(FAIR)小组的最新研究,他们首次能够使用 CNN 获得语言建模任务的最先进结果。我将解释他们的方法,然后带您一步一步地完成我写的 Pytorch 实现。

RNNs are inherently sequential. Image from https://vimeo.com/238222385

您可能知道,当给定一个单词序列作为输入时,语言建模包括预测序列中的下一个单词。rnn 较慢一个主要原因是输入字符串中的每个单词必须顺序处理:在句子“并行化很有趣”中,单词“并行化”和“是”必须在单词“有趣”之前处理。相比之下,CNN 中的所有元素都是同时处理的,这可以极大地加快处理速度。之前使用 CNN 进行语言建模的尝试明显不如 RNNs 的结果,但在最近一篇名为“带门控卷积网络的语言建模”的论文中,Dauphin 等人(2016)构建了一个卷积语言模型,其产生的结果与 RNNs 具有竞争力,并可以大幅降低计算成本。

CNNs can process information in parallel. Image from https://vimeo.com/238222385

快速提醒一下信息如何通过 RNN 语言模型将会很有帮助。模型的输入是由大小为[ seq_length,emb_sz ]的单词嵌入 X 表示的单词序列,其中 seq_length 是序列长度, emb_sz 是你的嵌入的维度。在 X 通过多个 LSTM 层之后,最终层的输出是大小为[ seq_length,c_out ]的隐藏状态表示 H ,其中 c_out 是该最终层的维度。然后,softmax 步骤为序列中的每一步生成对整个词汇表的预测。

Dauphin 等人的 CNN 类似地将大小为[ seq_length,emb_sz ]的嵌入激活作为输入,但随后使用多层门控卷积来产生最终的隐藏状态输出 H (也是大小为[ seq_length,c_out )。每层包括 1)产生两个独立卷积输出的卷积块,以及 2)使用一个卷积输出来选通另一个卷积输出的选通块。

Figure 1 from Dauphin, et al. (2016), showing GCNN architecture.

卷积块对输入执行“因果卷积”(对于第一层,其大小为[ seq_length,emb_sz ])。正常卷积的窗口宽度为 k ,以当前时间步长为中心(因此包括来自未来和过去时间步长的输入),而因果卷积的窗口仅与当前和先前时间步长重叠(见下图)。这可以通过简单地计算一个输入的正常卷积来实现,该输入已经用左边的 k -1 个元素进行了零填充。因果卷积是必要的,因为如果 CNN 能够从它试图预测的未来时间步长中“看到”信息,那就是欺骗。

TOP: Normal convolution. The convolutional window (width k=3) is centered on the current timestep. BOTTOM: Causal convolution. The input is zero-padded on the left with k-1=2 elements.

如上所述,卷积模块实际上会产生两个独立的卷积输出, AB ,其中一个将通过逐元素乘法来选通另一个。第一卷积输出被计算为 A = XW+b* 。因为 X 是一个大小为[ seq_length,emb_sz ]的张量,所以在用零进行左填充之后,它的大小将为[ seq_length+k-1,emb_sz ]。w 是大小为[ k,in_c,out_c ]的卷积滤波器,其中 in_c 是输入通道数(这里等于第一层的 emb_sz ),而 out_c 是输出通道数。 b 是长度 out_c 的偏置向量。在应用卷积之后,输出 A 将是 size [ seq_length,out_c ]。最后,对 B= XV+c* …执行相同的步骤,即使用不同的卷积滤波器 V 和偏置向量 c 产生第二个输出 B

Gated Linear Unit (GLU), with residual skip connection. A convolutional block with window k=3 produces two convolutional outputs, A and B. A is element-wise multiplied with sigmoid(B), and the residual is added to the output. Image modified from https://vimeo.com/238222385

卷积块的两个输出 AB 然后被传递到门控块。在这一点上,提醒一下 CNN 在图像处理方面发生了什么是很有帮助的…卷积输出 A 可能会通过一个激活机制,如 ReLU:、A . k . A .【X * W+b】。然而,对于 GCNN 的门控块,Dauphin 等人使用了一种他们称之为“门控线性单元”(GLU)的机制,这种机制涉及到将 A 乘以 sigmoid(B ):

乙状窦

或者相当于,

(XW+b)乙状结肠(XV+c)

这里, B 包含“门”,它控制着从 A 到下一层的信息传递。从概念上讲,门控机制很重要,因为它允许选择对预测下一个单词很重要的单词或特征,并提供了一种学习和传递相关信息的机制。类似于 ReLU,门控机制也为层提供非线性能力,同时在反向传播期间为梯度提供线性路径(从而减少消失梯度问题)。

Dauphin 等人还为每一层增加了一个残差 skip 连接(见上图),类似于 ResNet 架构。剩余连接最小化了消失梯度问题,允许网络被建得更深(更多层)。该层的输入( X )在被卷积输出 B. 选通之后,被添加到卷积输出 A

X + (A乙状结肠(B) )

或者相当于,

X + ( (XW+b)乙状结肠(XV+c) )

Bottleneck structure of a visual processing ResNet layer [Figure 5 from He, et al. (2016)]. A k=1 convolution reduces dimensionality from 256 to 64, then a k=3 convolution is performed in the lower dimensional space, then a k=1 convolution increases the dimensionality back to 256.

Dauphin 等人有时在层内使用瓶颈结构,也类似于 ResNet 架构。瓶颈结构的目的是通过首先降低数据的维度来降低卷积运算的计算成本。假设您想要对大小为[seq _ length= 70,in _ c= 600]的输入执行一次 k =4 卷积,输出通道有 600 个。这通常需要大小为[4,600,600]的卷积权重矩阵。相反,瓶颈层首先将数据的维度减少到例如[70,30],然后在更低维度的空间中执行 k =4 卷积,然后最终将数据的维度增加回[70,600]。这种方法只需要[4,30,30]的卷积权重矩阵大小,这在计算上更有效。瓶颈通过使用 k=1 卷积来增加和减少维度(参见下面的 Pytorch 实现)。

Stacking multiple layers, and left-padding the output of each layer. Image from https://vimeo.com/238222385

不管一个层中是否使用了瓶颈结构,GCNN 层都可以堆叠,确保在每一层都左填充前一层的输出。每个层的输入将是 size[seq _ length+k-1,in_c* ],每个层的输出将是 size [ seq_length,out_c ]。Dauphin 等人将这些层中的至少 5 层堆叠在一起,以产生最终的隐藏状态输出 h。然后,他们使用自适应 softmax 从语言模型的词汇表中的巨大单词列表中选择要选择的单词(查看我的博客帖子如何将耗时的 softmax 步骤加速高达 1000%)。*

Pytorch 实现

经过一番搜索,我没有找到一个可以工作的 Pytorch 实现,所以我决定从头构建一个。查看随附的 Jupyter 笔记本以便跟随。对于预处理,你将需要 fastai ,一个运行在 Pytorch 之上的深度学习库,它简化了神经网络的训练。【对于那些想学习最先进的深度学习技术的人,我强烈推荐杰瑞米·霍华德的 fast.ai 课程,在线免费提供】。我决定使用 Wikitext-2 数据集,这是一个相对较小的数据集,包含大约 200 万个标记和大约 3.3 万个词汇,是本文中使用的较大 Wikitext-103 数据集的子集。

如论文中所述,我将数据分成段落。为了有一个标准化的序列长度,我删除了少于 10 个单词或多于 300 个单词的段落。一旦数据被正确格式化为 csv 文件,fastai 就可以很容易地对其进行快速标记和数值化。我创建了定制的数据集、采样器和整理函数,它们可以将数据正确地格式化到数据加载器中。每个迷你批次随机采样序列长度大致相同的段落。我还下载了 GloVe 预训练单词向量,用于模型的单词嵌入。最后,我创建了一个处理训练的 modeler 类。在训练期间,梯度裁剪允许使用大的学习率(lr=1),它与内斯特罗夫动量和权重归一化一起帮助训练快速收敛。

The first few layers of the architecture.

如上所述,迷你批次之间的序列长度不同,但在本文的其余部分,假设 seq_length 等于 70。在嵌入和调整大小之后,第一层的输入 x 是 size [ bs=50,emb_sz= 300 ,seq_length= 70,1],其中 bs 是批量大小, emb_sz 是嵌入维数。我使用一个卷积核大小为 4 的 k ,所以在用 k -1=3 个元素对输入进行左填充后,输入大小为[50,300,73,1]。

我在架构的每一层都使用了瓶颈结构。在第一层,(用 self.inlayer = GLUblock(k,emb_sz,nh,downbot) 调用),我产生两个卷积输出, x1x2 。为了产生 x1 ,第一个 k=1 卷积将输入 x 的维数从[50,300,73,1]降低到[50,15,73,1]。然后,在这个低维空间中执行 k =4 卷积,以产生大小为[50,15,70,1]的输出。最后,一个 k =1 卷积将 x1 的维数增加到大小[50,600,70,1]。同样的三个步骤用于产生 x2 ,然后通过一个 sigmoid 并用于通过逐元素乘法选通 x1 ,以产生输出 x (大小也是[50,600,70,1])。通过使用 k =1 卷积,将残差(在块开始时设置为等于 x )从大小【50,300,70,1】转换为大小【50,600,70,1】,并添加到输出 x

接下来,我将数据 x 通过 4 个门控卷积层。每层都有一个大小为[50,600,70,1]的输入,并产生相同大小的输出。由于输入和输出的维数是相同的(即 in_c==out_c ,所以可以简单地复制残差并将其搁置,直到块结束。如上所述,输入被左填充为大小[50,600,73,1],产生瓶颈卷积输出 x1x2 (大小均为[50,600,70,1]),并且在添加残差以产生该层的输出之前, x1sigmoid(x2) 选通。经过 4 个卷积层后,最终输出通过自适应 softmax 产生模型预测。

Perplexity=76.6 on epoch 49.

我在 Wikitext-2 数据集上运行了这个网络 50 个时期,在第 49 个时期产生了 4.34 的最小损失(困惑=76.6)。这与 Dauphin 等人的结果相比相当不错,他们在更大的 Wikitext-103 数据集上实现了 37.2 的最终困惑度。通过增加模型容量(更多的层,每层更多的隐藏单元),通过训练更长的时间,通过在瓶颈层中使用不太积极的维度减少,以及通过使用更大的数据集(例如 Wikitext-103),我的模型的性能可能更接近于论文中发现的性能。

* [## 用门控卷积网络进行语言建模

vimeo.com](https://vimeo.com/238222385)

Dauphin 等人的结果与最先进的模型具有竞争力,要么接近匹配(Google 十亿字数据集),要么超过(Wikitext-103)基于 LSTM 的模型的最佳发布结果。此外,他们的方法大大降低了计算成本。与配备完整 softmax 的 LSTM 模型相比,他们使用的自适应 softmax 将训练速度提高了约 500%,因此达到给定的困惑值所需的操作明显减少。由于卷积方法可在序列和序列内的标记上并行化,因此 GCNN 模型将处理单个句子的延迟降低了一个数量级*。

Dauphin 等人的论文是许多最近的出版物之一,这些出版物完全放弃了用于 NLP 任务的 rnn,而是依赖于纯粹的注意力或卷积结构。诸如准递归神经网络( QRNN )的其他方法部分地放弃了递归,并且将训练速度提高了一个数量级。看到这些新方法达到最先进的结果,同时大幅降低计算成本,真是令人兴奋!

*然而,作者指出,由于 cuDNN 的 GPU 加速功能针对 LSTM 进行了优化,而不是针对 GCNN 所需的卷积类型,因此处理文本语料库所需的总时间在 RNN 和 GCNN 方法之间仍然相似。对 cuDNN 卷积实现的改进可能会为 GCNN 带来更好的计算性能。

参考文献:

布拉德伯里,詹姆斯,等。“准递归神经网络。”arXiv 预印本 arXiv:1611.01576 (2016)。

Dauphin,Yann .等人,《门控卷积网络的语言建模》arXiv 预印本 arXiv:1612.08083 (2016)。

盖林、乔纳斯等人《卷积序列到序列学习》arXiv 预印本 arXiv:1705.03122 (2017)。

何,,等.“深度残差学习在图像识别中的应用”IEEE 计算机视觉和模式识别会议录。2016.

瓦斯瓦尼、阿希什等人,“你所需要的只是关注。”神经信息处理系统进展。2017.*

如何使用 Tensorflow 对象检测 Api 构建手势控制的网络游戏

原文:https://towardsdatascience.com/how-to-build-a-gesture-controlled-web-based-game-using-tensorflow-object-detection-api-587fb7e0f907?source=collection_archive---------4-----------------------

通过在网络摄像头前挥动你的手来控制游戏手柄。

使用 TensorFlow 对象检测 api,我们已经看到了模型被训练来检测图像中的自定义对象的例子(例如,检测手、玩具、浣熊、 mac n cheese )。自然,下一个有趣的步骤是探索如何在真实世界用例中部署这些模型——例如,交互设计

在这篇文章中,我将介绍一个基本的身体作为输入交互示例,其中来自手部跟踪模型(作为输入的网络摄像头流)的实时结果被映射到基于网络的游戏(Skyfall)的控件上。该系统演示了如何集成一个相当精确的轻量级手部检测模型来跟踪玩家的手部,并实现实时的身体作为输入交互。

想试试吗?项目代码可在 Github 上获得。

[## 维克托迪亚/天崩地裂

skyfall -使用 Tensorflow 对象检测 Api 的手势控制网络游戏

github.com](https://github.com/victordibia/skyfall)

始终可用(Body as)输入

使用人体部分作为输入的好处是始终可用,因为用户不需要携带任何辅助设备。重要的是,利用人体部分进行基于手势的交互已经被证明可以改善用户体验[2]和整体参与度[1]。虽然身体作为输入的想法并不是全新的,但利用计算机视觉、可穿戴设备和传感器(kinect、wii、[5])等的现有方法有时会遇到准确性挑战,不总是可移植的,并且与第三方软件集成也很困难。轻量级深度神经网络(DNNs)的进展,特别是对象检测(见[3])和关键点提取(见[4])的模型,有望解决这些问题,并进一步实现始终可用(身体作为)输入的目标。这些模型使我们能够使用 2D 图像以良好的精确度跟踪人体,并具有与一系列应用程序和设备(桌面、网络、移动设备)轻松集成的优势。虽然从 2D 图像中进行追踪并不能给我们提供太多的深度信息,但它在构建互动方面仍然有着惊人的价值,正如 Skyfall 游戏示例中所示。

Body as input on a large display. Results from a realtime object detection model (applied to webcam feed) are mapped to the controls of a game.

游戏机制

Skyfall 是一个简单的基于网络的游戏,使用 2D 的物理引擎 planck.js 创建。天崩地裂的玩法很简单。3 种类型的球从屏幕顶部随机落下——白色球(值 10 分)、绿色球(值 10 分)和红色球(值-10 分)。球员通过移动球拍抓住好球(白色和绿色球)并避开坏球(红色球)来得分。在下面的例子中,玩家可以通过移动鼠标或在移动设备上触摸(拖动)来控制球拍。

Try out a mouse controlled version of SkyFall: Catch good balls (white, green), avoid bad balls (red) by moving the mouse. Press space bar to pause game and key s to toggle sound. View on Codepen here.

这是一个非常简单有趣的游戏。然而,我们可以让用户用他们的身体(手)来控制球拍,这样会更吸引人。目标是通过使用网络摄像头视频流检测手的位置来实现这一点——不需要额外的传感器或可穿戴设备。

添加基于手势的交互

为了增加手势交互,我们用一个将玩家手的运动映射到游戏手柄位置的系统来代替上面的鼠标控制。在当前的实现中,python 应用程序(app.py)使用 TensorFlow 对象检测 api 检测玩家的手,并通过 websockets 将手的坐标传输到游戏界面——一个使用 FLASK 服务的 web 应用程序。

手检测/跟踪

[## 如何在 Tensorflow 上使用神经网络(SSD)构建实时手部检测器

这篇文章记录了使用 Tensorflow(对象检测 API)训练手部检测器的步骤和脚本。我在……

towardsdatascience.com](/how-to-build-a-real-time-hand-detector-using-neural-networks-ssd-on-tensorflow-d6bac0e4b2ce)

在之前的一篇文章中,我介绍了如何使用 Tensorflow 对象检测 api 构建一个实时手部检测器。请查看的博文,了解更多关于手部跟踪模型是如何构建的。有关加载手模型的任何错误或问题,请参见手跟踪 Github repo 和问题。本例采用了类似的方法,多线程 python 应用程序读取网络摄像头视频,并为检测到的每只手输出边界框。

注意,手检测是在逐帧的基础上完成的,并且系统不会跨帧自动跟踪手。然而,这种类型的帧间跟踪是有用的,因为它可以实现多用户交互,我们需要跨帧跟踪手(想象一群朋友挥舞着他们的手或其他一些共同的对象,每个人都控制着自己的球拍)。为此,当前的实现包括基于朴素欧几里德距离的跟踪,其中在跨帧的相似位置看到的手被分配相同的 id。

一旦帧中的每只手都被检测到(并且分配了跟踪 id),手的坐标就被发送到网络套接字服务器,该服务器将它发送到连接的客户端。

Additional hands, additional paddles … potential for some engaging multiplayer games with friends. A tracking id of 0 is assigned to one hand and 1 to the other. These are then mapped to the paddles on the game interface.

游戏界面

游戏接口连接到网络套接字服务器并监听手部检测数据。每个检测到的手用于生成一个球拍,并且手在视频帧中的坐标用于在游戏屏幕上相对定位球拍。

Realtime detected hand coordinates (center of bounding boxes) are mapped to paddle positions as controls.

后续步骤

当前的实现有一些限制——所以贡献,拉请求是最受欢迎的!

手部检测器改进 这需要收集额外的训练数据并利用数据增强策略来改进手部检测器。这很重要,因为整个交互(和用户体验)依赖于准确和鲁棒的手部跟踪(误报、漏报会导致糟糕的 UX)。

帧间跟踪

当前的实现使用简单的基于欧几里德的度量来跨帧跟踪手(当前帧中的手基于其与先前帧中的手的距离来识别)。如果有几只手重叠,事情会变得复杂——需要一种更鲁棒的跟踪算法。也许集成了 OpenCV 或其他来源的快速跟踪算法…

Tensorflowjs 实现
用一个 TensorFlowjs 实现进行一些实验,它允许整个交互完全在浏览器中原型化!!!Tensorflowjs 带来了许多好处——易于部署(无需 python 或 Tensorflow 安装),无需 websocket 服务器和客户端,易于复制,更多潜在用户…

更新..Tensorflow.js 浏览器实现如何可用。你可以在 CodePen 上试试这里的,完整源代码如下:

[## victordibia/handtrack.js

一个用于直接在浏览器中原型化实时手部检测(边界框)的库。- victordibia/handtrack.js

github.com](https://github.com/victordibia/handtrack.js/)

结论

一些相关的作品。

有一些现有的项目在设计交互时应用了机器学习模型。一个常见的例子是使用 LSTMs 自动完成文本并创建快速电子邮件回复(参见 Google 的智能回复论文),以及最近的实验,其中图像分类模型被用作游戏控制(参见 Google Pair 的可教机器和其他 Tensorflowjs 演示)。这项工作通过探索在创建交互中使用对象检测模型来建立这些趋势。

最后的想法

随着人工智能算法的不断成熟(准确性、速度),有可能利用这些进步来建立更好的交互。这可以是为用户定制内容或预测其预期交互的生成界面、支持基于视觉的新型交互的模型、对话式 UI 等。在这些领域中,越来越重要的是研究这种交互的机制,严格测试这些交互,并创建设计模式,告知如何在交互设计中使用人工智能模型作为一等公民。

收到反馈、评论,想要合作吗?随时联系——Twitter, linkedin 。

注:Skyfall 的早期版本于 2018 年 1 月提交给英伟达杰特森挑战赛。

参考

[1]d . m . Shafer,c . p . Carbonara 和 Popova,L. 2011 年。作为基于运动的视频游戏享受的预测因素的空间存在和感知现实。存在:遥操作者和虚拟环境20(6)591–619。

[2]m . Birk 和 r . l . mandrik,2013 年。控制你的游戏自我:游戏中控制者类型对快乐、动机和个性的影响。关于计算系统中人的因素的 SIGCHI 会议记录—CHI ' 13685–694。

[3]黄,j .,拉特霍德,v .,孙,c .,朱,m .,科拉迪卡拉,a .,法蒂,a .,菲舍尔,I .,沃伊纳,z .,宋,y .,s .,墨菲,K. 2017。现代卷积目标探测器的速度/精度权衡 CVPR

[4]曹,z .,西蒙,t .,魏,s-e,和谢赫,Y. 2016。使用局部相似场的实时多人 2D 姿态估计。

[5]c .哈里森、d .谭和 d .莫里斯,2010 年。Skinput:将身体作为输入表面。第 28 届计算机系统中人的因素国际会议论文集—中国’10453。

我如何使用 Flask 构建一个基于 REST 端点的计算机视觉任务

原文:https://towardsdatascience.com/how-to-build-a-machine-learning-as-a-rails-developer-739cc57ea01c?source=collection_archive---------2-----------------------

这是我熟悉计算机视觉和机器学习技术的过程的后续。作为一名 web 开发人员(理解为“rails 开发人员”),我发现这个不断发展的领域令人兴奋,但是不要每天都使用这些技术。这是探索这一领域的两年旅程的第三个月。如果你还没有阅读,你可以在这里看到第一部分:从 webdev 到计算机视觉和地理和第二部分:两个月探索深度学习和计算机视觉。

总体思路

Rails 开发人员擅长毫不费力地快速构建 web 应用程序。在支架、清晰的模型-视图-控制器逻辑和大量的 ruby gems 之间,具有复杂逻辑的 Rails 应用程序可以在很短的时间内完成。例如,我会毫不犹豫地构建一些需要用户帐户、文件上传和各种数据源的东西。我甚至可以用优秀的文档使它高度可测试。在 Devise、Carrierwave(或许多其他文件上传 gem)、Sidekiq 和所有其他可访问的 gem 之间,我将在 15 分钟内在 Heroku 上启动并运行。

现在,加上一个计算机视觉或机器学习任务,我就不知道该去哪里了。即使我在探索这个领域,除了单词联想或图像分析,我仍然很难找到机器学习概念(神经网络和深度学习)的实际应用。也就是说,有趣的想法(我还没有找到实际应用)是围绕趋势检测和生成对抗网络。

Google search for “how to train a neural network”

作为一名软件工程师,我发现很难理解机器学习在我构建的应用程序中的实用价值。有很多关于模型(机器学习意义上,而不是 web 应用程序/数据库意义上)、神经网络架构和研究的文章,但我没有看到像我这样的 web 开发人员的实际应用。因此,我决定将我已经思考了一段时间的项目的一小部分构建出来。

该项目旨在检测 Instagram 上的优秀涂鸦。最初的想法是使用机器学习来限定“好的涂鸦”看起来是什么样的,然后运行机器学习模型来检测和收集图像。从概念上来说,这个想法听起来很棒,但我不知道如何“训练一个机器学习模型”,我对从哪里开始没有什么感觉。

我开始构建项目的一个简单部分,因为我知道我需要在好的涂鸦上“训练”我的“模型”。我挑选了一些优秀涂鸦艺术家的 Instagram 账户,我知道我可以在那里找到高质量的图像。在抓取 Instagram 账户(由于 Instagram 的 API 限制,这比预期的时间长得多)并分析图片后,我意识到手头的一个大问题。所选的账户很棒,但有许多非涂鸦的图像,主要是人。为了得到“好的涂鸦”图像,我首先需要过滤出人的图像。

The application I built to crawl Instagram created a frontend that displayed graffiti.

通过查看这些图片,我发现每 10 张图片中有多达 4 张是一个人的或者里面有一个人。结果,在开始“训练”一个“好涂鸦”的“模型”之前,我只需要得到一组不包含任何人的图片。

(对非机器学习人员的补充说明:我在某些单词周围使用引号,因为你和我可能对这些单词的实际意思有相同的理解。)

与其有一个复杂的机器学习应用程序来完成一些复杂的神经网络-深度学习-人工智能-随机梯度下降-线性回归-贝叶斯机器学习魔法,我决定简化这个项目,建立一些检测照片中的人并标记他们的东西。我意识到,我之前读过的许多机器学习教程的例子都向我展示了如何做到这一点,所以问题是要让那些教程真正有用。

应用程序(带有代码链接)

我将 Ruby on Rails 用于管理数据库和呈现内容的 web 应用程序。我使用 Ruby 通过 Redis 库 Sidekiq 完成了 Instagram 的大部分图片抓取。这使得运行延迟任务变得容易。

The PyImageSearch article used as reference is great and can be found at https://www.pyimagesearch.com/2017/09/11/object-detection-with-deep-learning-and-opencv/

对于机器学习逻辑,我有一个使用 OpenCV 进行对象检测的代码示例,来自 PyImageSearch.com 教程的。该代码示例并不完整,因为它检测了定型图像模型中 30 个不同项目中的一个,其中一个是人,并在检测到的对象周围画了一个框。在我的例子中,我稍微修改了这个例子,并把它放在一个基于 Flask 的简单 web 应用程序中。

Link to Github: The main magic of the app

我制作了一个 Flask 应用程序,其端点接受带有图像 URL 的 JSON blob。应用程序下载了图像 URL,并通过在检测到的对象周围绘制一个边界框的代码示例对其进行处理。我只关心检测人的代码示例,所以我创建了一个基本条件,为检测人给出特定的响应,为其他所有事情给出一般的响应。

这个简单的端点就是机器学习的魔力。可悲的是,这也是我第一次看到复杂的机器学习“东西”如何与 web 应用程序的其余部分集成的实际可用的例子。

对于那些感兴趣的人来说,这些代码如下。

[## 记住 lenny/Flask-Person 探测器

基于 Flask 的 web 应用程序,使用 OpenCV 的深度神经网络提供了一个 REST 端点…

github.com](https://github.com/rememberlenny/Flask-Person-Detector)

总结体会

我很惊讶我以前没有见过一个简单的基于 Flask 的深度神经网络的实现。我还觉得基于这种实现,当不涉及训练模型时,将机器学习应用到任何应用程序中就像拥有一个具有有用功能的库一样。我假设在未来,模型和利用模型的库的分离将会被简化,类似于一个库如何被“导入”或者使用捆绑器添加。我的猜测是这些工具中的一些是存在的,但是我还没有深入了解它们。

https://www.tensorflow.org/serving/

通过回顾如何访问对象检测逻辑,我发现了一些似乎相关的服务,但最终并不是我所需要的。具体来说,有一个名为 Tensorflow Serving 的工具,它似乎应该是 Tensorflow 的一个简单的 web 服务器,但还不够简单。这可能是我所需要的,但是拥有一个单独运行 Tensorflow 的服务器或 web 应用程序的想法很难实现。

基于 Web 服务的机器学习

我在网上找到的很多机器学习的例子都是非常完备的例子。示例从问题开始,然后提供在本地运行示例的代码。通常,图像是由 file path 通过命令行界面提供的输入,而输出是 python 生成的窗口,显示经过处理的图像。作为一个 web 应用程序,这不是很有用,所以创建一个 REST 端点似乎是一个基本的下一步。

将机器学习逻辑构建到 REST 端点中并不难,但是需要考虑一些事情。在我的例子中,服务器运行在一台台式计算机上,有足够的 CPU 和内存来快速处理请求。情况可能并不总是这样,所以未来的端点可能需要使用 Redis 之类的东西异步运行任务。这里的 HTTP 请求很可能会挂起并超时,因此对于慢速查询,需要考虑一些基本的微服务逻辑。

二元期望和机器学习品牌

最终应用程序的一个大问题是,处理后的涂鸦图像有时会被错误地标记为人。当这幅画包含看起来像一个人的特征时,例如一张脸或身体,物体分类器错误地标记了这幅画。相反,有时人的照片没有正确地将图像标记为包含人。

[GRAFFITI ONLY] List of images that were noted to not have people. Note the images with the backs of people.

Web 应用程序需要二元结论来采取行动。图像分类器将提供关于检测到的物体是否存在的百分比等级。在较大的对象检测模型中,分类器将有一个以上的对象被推荐为可能被检测到。例如,照片中有 90%的可能性是一个人,有 76%的可能性是一架飞机,有 43%的可能性是一只巨大的香蕉。当处理响应的应用程序只需要知道某些东西是否存在时,这不是很有用。

[PEOPLE ONLY] List of images that were classified as people. Note the last one is a giant mural with features of a face.

这带来了质量在任何基于机器学习的过程中的重要性。假设很少有对象分类器或基于图像的过程是 100%正确的,那么 API 的质量是很难衡量的。当谈到这些对象分类器 API 的商业实现时,服务的品牌将在很大程度上受到少数请求的边缘情况的影响。因为机器学习本身是如此不透明,服务提供商的品牌在确定这些服务的可信度方面将更加重要。

相反,由于机器学习任务的质量差异如此之大,一个品牌可能很难向用户展示其价值。当解决机器学习任务的二进制质量与美元金额挂钩时,例如每个 API 请求,免费做某事的能力将很有吸引力。从价格的角度来看,滚动自己的免费对象分类器会比使用第三方服务更好。在成为明显优于自托管实现的首选之前,品牌机器学习服务市场还有很长的路要走。

物体分类的特异性非常重要

最后,当涉及到任何机器学习任务时,特异性是你的朋友。具体来说,当谈到涂鸦时,很难界定形式各异的东西。涂鸦本身是一个包含大量视觉作品的类别。甚至一个人可能很难界定什么是涂鸦,什么不是涂鸦。与检测人脸或水果相比,类别的特异性非常重要。

WordNet 和 ImageNet 的卓越之处在于类别特异性的力量。通过用词和词与词之间的关系对世界进行分类,有一种方法可以证明图像的相似性和差异性。例如,鸽子是一种鸟,但不同于鹰。与此同时,它与飞机或蜜蜂完全不同。这些事物之间的关系允许对它们进行清楚的分类。涂鸦中不存在这种特异性,但需要这种特异性来适当地改进对象分类器。

最终决赛

总的来说,这个应用程序运行良好,非常有帮助。这消除了更多关于机器学习和图像识别服务如何工作的神秘。正如我上面提到的,这个过程也让我更加意识到这些服务的不足和这个领域尚未定义的地方。我绝对认为这是所有软件工程师都应该学会的。在可用的工具变得简单易用之前,我想复杂的生态系统将会有一个很好的导航期。类似于网络标准形成之前的浏览器战争,机器学习提供商之间将会有很多争夺市场份额的竞争。你已经可以在亚马逊、谷歌和苹果等大公司的服务之间看到这一点。在软硬件层面,这一点在 Nvidia 的 CUDA 和 AMD 的价格吸引力之间也非常明显。

更多即将推出!

如何使用马尔可夫链和 Python 构建市场模拟器

原文:https://towardsdatascience.com/how-to-build-a-market-simulator-using-markov-chains-and-python-7923256f8d29?source=collection_archive---------4-----------------------

建模客户行为,可视化 A/B 测试结果,预测用户指标…所有这些都使用一个简单的马尔可夫框架!

final product

在本文中,我的目标是向您介绍(不考虑您的技术能力)马尔可夫链,并使用它来模拟客户行为。

这不会是一个传统的每两行代码片段的“如何做”教程。我写这篇文章的主要目的是为您提供一个可以灵活使用的概念框架,这样您就不必为了学习新东西而编码了。技术细节会不时出现,但我会尽可能地为他们提供直觉。

数据处理

在这次分析中,我将使用我在一次数据马拉松中获得的 Credit Sesame 的分析数据。你可以使用任何你感兴趣的时间范围内的用户数据(例如一周/月/年的数据)。它应该遵循类似于下面的结构。

example data

动作的例子可以是“点击报价/广告”、“点击订阅”等。列也可以是其他指标,如页面浏览量或收入。包括任何你认为对你的建模计划有用的专栏——在我的例子中,就是用户参与。

客户细分

在您的数据集中选择一个特定的日期,并获取该特定日期的新用户数据。我正在模拟新用户在使用 Credit Sesame 网站 30 天内的行为。

new user data on a particular day

接下来,我们将客户分为不同的类别或状态。有许多方法可以做到这一点。

  1. 您可以应用一个评分函数:给每个用户一个分数,表示他们的整体参与度。您可以为您认为影响更高用户参与度的操作(如“会话长度”)赋予更高的权重。
    然后,您可以根据自己的经验将分布划分为 3 个部分(不活跃、活跃和非常活跃)。

Distribution of applied score function

2.应用无监督的算法,比如 k-means:你可以使用聚类算法,比如 k-means,来对参与度相似的客户进行聚类。每个集群都有自己独特的属性,希望这些属性就是您想要建模的属性。您甚至可以将该算法应用于您之前计算的得分函数(单变量数据),使其更加简单。

K-means segments visualized on the score function

after segmentation on first-day data. 1 = inactive user, 2 = active user, 3 = very active user.

分割第一天的数据后,你选择一个时间框架。我选择了一个月,因为我相信 Credit Sesame 有很多回头客,一个月的数据可以捕捉到他们的数量。30 天后,用户将有机会在各个细分市场之间转换:非常活跃的用户可能会变得不活跃,中度活跃的用户可能会变得非常活跃,等等。

对此 30 天后的数据进行分段。确保您考虑了时间框架(例如,平均 30 天的参与度分数)。

segmentation applied to 30-day data

让我们来看看结果:

正如预期的那样,在 30 天内变得不活跃的用户数量上升,而保持活跃和非常活跃的用户数量下降。

应用马尔可夫框架

马尔可夫链基础

马尔可夫链是简单的数学系统,它使用一定的概率规则和固定的假设来模拟状态到状态的运动。

更简单地说,当您有一个具有固定状态(或段)的系统,并且代理/用户可以以一定的固定概率在这些状态之间移动时,您可以使用马尔可夫链对其进行建模。

但是让我们首先看看我们的系统是否满足马尔可夫模型的假设:

  • 假设 1: 有一组有限的状态。在我们的系统中,只有 3 类客户可以进出。
  • 假设 2: 状态间移动的概率是固定的。我承认,这是一个很强的假设。虽然我的系统确实考虑了成千上万的用户数据点,但很容易相信不同的 30 天时间框架的概率方差不应太大。但是,即使有大量的数据,正如我们将在本文后面看到的,我们也必须谨慎。
  • 假设三:状态可达性。任何细分市场中的用户都可以移动到不同的细分市场,而不受任何外部限制。
  • 假设 4: 非循环。在我们的系统中,片段到片段的移动决不是“自动的”,所以这个假设是成立的。

我们的系统对马尔可夫链的大多数假设表现良好。这给了我们对模型估计的一些信心,一旦我们建立了模型,我们就会得到这些。

构建马尔可夫链

马尔可夫链有三个部分,最好用矩阵向量乘法来表示。如果你对线性代数完全陌生,我建议你在阅读本文之前浏览一下这个链接。

N represents the number of segments

我们系统中的初始状态是一个 3×1 向量,表示每个分段中的用户数量。结束状态也是一个 3x1 向量,显示第一个月之后每个细分市场中的用户数量(在我们将初始状态向量乘以概率矩阵之后)。转移概率矩阵是一个 3×3 的矩阵,代表了不同客户群之间的固定转移概率。

那么我们如何计算这些固定概率呢?

从我们记录的片段移动来看。我们观察第一天每个细分市场的用户在 30 天后如何移动到不同的细分市场,并相应地计算概率(相当于比例)。

0.89(图中)指的是第一天第一个细分市场中的某个人在 30 天后仍在同一细分市场中的概率,即不活跃用户在 30 天后仍不活跃的概率。请注意,每列中的概率总和必须为 1。我们对所有细分市场重复这一过程,并构建最终转换矩阵:

Deconstructing the transition matrix for a clearer understanding

different way to visualize the transition matrix

最后,我们把它们组合成这个漂亮的形式:

现在我们已经建模了,我们可以开始有趣的事情了。

绘图结果

给定马尔可夫链,让我们从绘制客户流动趋势开始。

a_val,b_val,c_val = [],[],[]# initial state
init_state = np.array([188969, 81356, 14210])# transition matrix
a = np.array([[ 0.89, 0.75 ,0.49], [ 0.10, 0.22 ,0.44], [ 0.01, 0.03 ,0.07]])for x in range(10):
    a_val.append(init_state[0])
    b_val.append(init_state[1])
    c_val.append(init_state[2])
    b = init_state
    init_state = a.dot(b)# plotting
plt.figure(figsize=(11,8))
plt.plot( [x for x in range(10)], a_val, marker='o', markerfacecolor='blue', markersize=12, color='skyblue', linewidth=4,label='Inactive users')
plt.plot( [x for x in range(10)], b_val, marker='o', markerfacecolor='red', markersize=12, color='pink', linewidth=4,label='Active users')
plt.plot( [x for x in range(10)], c_val, marker='o', markerfacecolor='orange', markersize=12, color='yellow', linewidth=4,label='Very active users')
plt.legend(loc='best')
plt.xlabel('Months')
plt.ylabel('Number of customers')

output

从中我们可以推断出什么?

我们看到,大约 2 个月后,所有三个细分市场都达到了平衡,也就是说,虽然有用户从一个细分市场转移到另一个细分市场,但每个细分市场的客户总数保持不变。

但是有一个条件。我们在这里做了一个非常强有力的假设——我们相信,无论我们预测用户行为的未来有多远,概率都将是固定的。这是非常不可信的。我举个例子:假设你拥有一个销售冬装的网站。在 12 月份购买了几件外套的活跃用户不太可能在 7 月份遵循同样的购物模式。模式可能是季节性的,而我们的马尔可夫模型没有捕捉到这一点!

那我们该怎么办?

我们可以为每个月计算不同的转换矩阵来捕捉这些趋势,也可以将我们的分析范围限制在一个月。由于我只有一个月的数据,我选择后者。如果您确实有更长时间的数据,我会鼓励您将真实数据结果与马尔可夫模型输出进行比较,看看转移概率是否在几个月内保持不变,并相应地进行调整。

我得到的结果如下所示:

Single month analysis of customer flow

应用:

A/B 测试

既然您已经有了一个描述客户行为的模型,我们如何引入“变化”或“干预”,并对它们的影响建模呢?我们的马尔可夫模型识别了两种类型的变化:

1。初始状态的改变:

假设你拥有一家披萨店,你的网站在 12 月 1 日提供买二送一的优惠。你怀疑这种变化会带来更多的活跃用户访问你的网站。当你有 1000 个不同的新访客时,你的假设被证实了,其中有 300 人在同一天真的买了披萨(非常活跃的用户)。你又惊又喜,心想“嗯,我习惯了一天接到 100 个订单:一个月后会怎么样呢?”你只需要调整马尔可夫链的初始状态来解释这种变化。

# CHANGES TO INITIAL STATE - NUMBERS RECEIVED FROM MATRIX VECTOR PRODUCTbefore = (855,130,15) # Without any change
after = (509,389,102) # After placing deal# create plot
plt.figure(figsize=(11,8))
index = np.arange(3)
bar_width = 0.35
opacity = 0.8

rects1 = plt.bar(index, before, bar_width,
                 alpha=opacity,
                 color='b',
                 label='Without deal')

rects2 = plt.bar(index + bar_width, after, bar_width,
                 alpha=opacity,
                 color='g',
                 label='With deal')

plt.xlabel('Segments')
plt.ylabel('Number of Users')
plt.title('Customer behavior after a month')
plt.xticks(index + bar_width- 0.18, ('Inactive','Active','Very Active'))
plt.legend()

plt.tight_layout()
plt.show()

从初始状态由(不活跃=500,活跃=400,非常活跃=100)变为(100,600,300),我们得到上面的结果。在月初有更多活跃和非常活跃的用户,你就增加了在这个月中拥有更多回头客的机会。

2.转移概率的变化:

你意识到这些交易很好,但它们只影响初始状态,这些交易的好处不会持续几个月,即它们是扩大参与用户的短期解决方案。为了有更持久的变化,我们必须引入改变概率的行动。假设你完全重新设计了你的披萨外卖网站,使结账速度提高了 10 倍。这是一种会持续影响每个细分市场中用户数量的行动。为了说明这种类型的变化,我们改变了转移矩阵中的概率。
你可以通过在用户子样本上对新网站进行 A/B 测试来计算改变的概率,或者,你可以使用你自己的试探法和假设来手动改变它们。

假设概率保持不变,我们可以看到客户流如何随着新的转移矩阵而变化。

预测其他指标

您可以预测其他几个用户指标,如客户终身价值、每用户收入等。使用我们上面描述的技术。例如,预测收入变化,计算每个细分市场的平均收入,计算输出状态,并将收入乘以各自细分市场中的用户数。

结论

如果你已经走了这么远,我推荐你。至少,我希望我已经传达了马尔可夫链的美妙之处,以及尽管它们很简单却能提供关键见解的能力(假设关键假设得到满足)。我希望你找到自己的创造性的方法来应用这个模型!

如何使用 LightFm 在 Python 中构建电影推荐系统

原文:https://towardsdatascience.com/how-to-build-a-movie-recommender-system-in-python-using-lightfm-8fa49d7cbe3b?source=collection_archive---------3-----------------------

在这篇博文中,我们将用 python 创建一个电影推荐系统,根据用户的观看历史向他们推荐新电影。在我们开始之前,让我们快速了解一下什么是推荐系统。

courtesy: https://ghanatalksbusiness.com/use-ratings-carefully-performance-reviews/

推荐系统

你可能还不知道推荐系统的定义,但你肯定遇到过。这是因为推荐系统在互联网上无处不在。推荐系统的目的是根据用户的兴趣或使用历史向他们推荐一些东西。所以,下次亚马逊向你推荐一种产品,或者网飞向你推荐一个电视节目,或者在你的 feed 上展示一个很棒的帖子,要明白在引擎盖下有一个推荐系统在工作。

有两种类型的推荐系统。他们是

  1. 基于内容的推荐系统
  2. 协同推荐系统

基于内容的推荐系统

基于内容的推荐系统对用户产生的数据进行处理。数据可以显式生成(如点击赞),也可以隐式生成(如点击链接)。该数据将用于为用户创建用户简档,该用户简档包含用户交互的项目的元数据。它接收的数据越多,系统或引擎就变得越精确。

协同推荐系统

一个协作推荐系统根据相似用户对商品的喜欢程度做出推荐。这个系统会把爱好相似的用户分组。除了用户相似性之外,推荐系统还可以使用项目相似性来执行协同过滤(比如“喜欢这个项目 X 的用户也喜欢 Y”)。

大多数系统将是这两种方法的结合。

以免开始编码

电影推荐系统

首先,我们需要安装一些软件包。

LightFm

LightFM 是许多流行推荐算法的 Python 实现。LightFM 包括 BPR 和 WARP 排序损失的实现(损失函数是预测模型在预测预期结果方面表现如何的度量。).

BPR:贝叶斯个性化排序成对损失:最大化正例与随机选择的负例之间的预测差异。当只有积极的互动存在时,这是有用的。

WARP:加权近似秩成对损失:通过重复采样负样本直到找到违反秩的样本,最大化正样本的秩

LightFm 还包含大量与电影分级相关的数据集。我们将研究这个数据集。所以我们也将安装这个库。

pip 安装灯 fm

接下来,我们将安装两个数学运算包,即 numpyscipy

pip 安装数量

安装 scipy

我们将创建一个名为 recommender.py 的 python 文件。

我们可以从将库导入这个文件开始

import numpy as npfrom lightfm.datasets import fetch_movielensfrom lightfm import LightFM

fetch_movielens 方法是来自 lightfm 的方法,可用于获取电影数据。我们可以获取最低评级为 4 的电影数据。

data = fetch_movielens(min_rating = 4.0)

“数据”变量将包含电影数据,分为许多类别测试和训练。

在监督学习中,使用包含结果的训练数据集来训练机器。然后使用没有结果的测试数据集来预测结果。训练数据是用于构建模型的数据,测试数据是用于测试模型的数据。

我们可以通过打印这些数据来检查这一点

print(repr(data[‘train’]))
print(repr(data[‘test’]))

我们可以看到,训练数据量远大于测试数据量。这是因为通常当您将数据集分为定型集和测试集时,大部分数据都用于定型。

接下来,我们将创建一个带有“扭曲”损失函数的 lightfm 模型

model = LightFM(loss = ‘warp’)

现在,我们可以使用训练数据来训练这个模型,其中历元或迭代值为 30。

model.fit(data[‘train’], epochs=30, num_threads=2)

现在,让我们构建处理这些数据的函数,为任意数量的用户推荐电影。我们的函数将接受模型数据和一组用户标识

def sample_recommendation(model, data, user_ids):

在函数定义中,首先,我们需要得到所有用户和电影的数量。

n_users, n_items = data[‘train’].shape

接下来,我们需要迭代 user_ids。

for user_id in user_ids:

对于每个用户,我们需要找到他们喜欢的已知的正面或电影。这可以从我们掌握的数据中得到。

known_positives = data[‘item_labels’][data[‘train’].tocsr()[user_id].indices]

接下来,我们需要找到用户喜欢的电影。这可以通过 LightFm 的预测方法来完成。该函数的参数是 numpy arrange 的 user_idn_items 变量 arrange

scores = model.predict(user_id, np.arange(n_items))

我们现在可以根据最喜欢到最不喜欢的顺序对分数进行排序。

top_items = data[‘item_labels’][np.argsort(-scores)]

现在预测已经完成,我们可以打印前 3 个已知的阳性和 3 个预测。

print(“User %s” % user_id)print(“ Known positives:”)for x in known_positives[:3]:
 print(“ %s” % x)print(“ Recommended:”)for x in top_items[:3]:
 print(“ %s” % x)

这样,我们的样本 _ 推荐方法就变成了

def sample_recommendation(model, data, user_ids):
    n_users, n_items = data['train'].shape
    for user_id in user_ids:
        known_positives = data['item_labels'][data['train'].tocsr()                                    
                          [user_id].indices]

        scores = model.predict(user_id, np.arange(n_items))

        top_items = data['item_labels'][np.argsort(-scores)]

        print("User %s" % user_id)
        print("     Known positives:")

        for x in known_positives[:3]:
            print("        %s" % x)

        print("     Recommended:")

        for x in top_items[:3]:
            print("        %s" % x)

我们可以通过调用程序中的函数,提供三个随机的 user _ ids 来完成。

sample_recommendation(model, data, [3, 25, 451])

让我们通过命令在终端中运行代码

python recommender.py

我们得到了输出

凉爽的...我们可以看到我们的系统向我们的用户推荐电影。

这是一个推荐系统可以多么容易实现的例子。希望你觉得有用。

代码可以在https://github.com/amkurian/movie-recommendation-system找到

如何建立一个新媒体公司

原文:https://towardsdatascience.com/how-to-build-a-new-media-company-ef3b10ba9b6f?source=collection_archive---------2-----------------------

互联网媒体公司正处于困难时期。旧的商业模式已经跟不上互联网和脸书、谷歌等内容聚合商带来的速度和竞争。由于内容聚合商及其广告服务平台的近乎垄断地位,内容制作商获得的广告销售额比例越来越小。鉴于我们对媒体行业面临的挑战的了解,下面我试着想象一下一家今天成立的媒体公司如何成为这个行业的主要参与者。

在线印刷媒体目前问题的根源在于,为了接触到用户,媒体被迫通过脸书和谷歌这样的内容聚合器来收集内容。在这样做的过程中,他们面临着日益激烈的竞争,因为用户体验被商品化了,许多类似的故事同时出现,并且“追加销售”用户阅读同一出版商的另一个故事变得更加困难。

简单来说,这个问题只有两个答案。一个是成为你的类别中最好的内容提供商,并试图在内容聚合平台上获得巨大的浏览量——最有可能的方式是简单地生产比其他生产商更多的内容。这是 Buzzfeed 选择的道路。这也是一场逐底竞争,因为问题的根源是内容聚合者控制了供求,而这一解决方案根本没有改变这一点。随着内容创作者开始最大化产出,成本上升,假设所有内容提供商都努力最大化产出,收入将基本保持不变。这种策略的受益者是内容聚合者,他们接收更多的内容来吸引更多的观众,这反过来又吸引了更多的内容提供商,并使该行业保持循环。

另一种选择是离开内容聚合器。看看目前在线印刷媒体的参与者,如果没有脸书、谷歌或苹果新闻,没有多少(如果有的话)可以吸引大量观众。原因是在线印刷媒体与离线印刷媒体仍然没有太大区别。一页上有文字,页边空白处有广告。基本上这个行业拿了一份报纸,扫描了一下,然后就退出了。如果媒体想要捍卫他们的利润,那么他们需要建造一条护城河。每个公司的护城河都可能不同,但每个公司的护城河都将基于技术,智能手机和人工智能是一个关键因素。

为了对即将到来的观点转变有一个正确的认识,让我们考虑一个成功的现代媒体公司的案例——Yelp。以为 Yelp 是一家科技公司?再想想。Yelp 是为现代世界设计的城市美食指南。Yelp 有几个关键的特点,使它与你可能仍然在星巴克或报纸 E5 页上找到的离线城市美食指南有很大的不同:

  1. 用户简档(对推荐有用)
  2. 公开评论/评论
  3. 不断更新菜单、开门/关门时间、收视率、位置等。
  4. 定位服务

因为 Yelp 不仅仅是页面上的文字和空白处的一些广告,它已经设法避免了聚合。Yelp 已经将被动阅读城市指南变成了一种动态体验,人们首先打开 Yelp,目标是找到吃饭的地方,但不是用户做所有的工作,而是一系列的给予和索取导致最终的结果。

Yelp 拥有海量数据,包括图片、餐厅排名、评论、餐厅位置信息等。最重要的是,这些数据最好以多种方式分享——创造一种全面的体验,这种体验很难在应用程序之外获得。换句话说,它不仅仅是一页纸上的文字。截至目前,脸书还没有办法将 Yelp 的数据和排名与其他数据和排名进行对比。如果你想要 Yelp 的体验,你必须访问他们的网站或打开他们的应用程序。这是 Yelp 最基本的护城河。一旦你打开应用程序,Yelp 就开始积累你喜欢什么的数据,以便他们能够提供更准确的推荐。这加强了 Yelp 的护城河。

相比之下,《华盛顿邮报》有一系列按类别分组的文章,这些类别是在报纸仍是主要用户接触点的时候定义的,最好通过写在纸上的文字来分享。过去,他们的护城河是由进入壁垒构成的,主要包括送货距离的物理限制以及运行印刷机的成本。同样,城市餐馆指南的护城河是当地的知识和印刷一本杂志的成本。Yelp 通过向用户评论、照片和评级开放平台,对当地的知识加倍投入,并用收集大量餐馆和用户数据的成本取代了印刷杂志的入门成本。

那么,如果《华盛顿邮报》今天才刚刚起步,他们应该如何着手建立一个可持续发展的企业呢?首先,他们需要一个让用户打开《华盛顿邮报》而不是脸书的理由。他们需要利用其内容的独特方面来为用户量身定制体验。

我会假装对《华盛顿邮报》比实际上更熟悉,并推荐一些他们可以创造出无法移植到其他平台的体验的方法。我将从进一步研究他们过去使用的护城河开始。上面我提到了进入壁垒,但我没有提到其他护城河,如本地知识、政府关系、高质量的编辑和专业摄影。在媒体行业,高质量的编辑和专业的摄影在很大程度上是可以想象的。这些是保护新进入者的护城河,但对于与已经建立的媒体竞争来说不是很有用。《华盛顿邮报》与《纽约时报》和《三藩市纪事报》等其他媒体不同的两个方面是对 DC 地区的了解和与政府的联系。

可以效仿 Yelp 的做法,为 DC 居民创建一个开源的、用户生成的内容平台,当地人可以在这个平台上讨论所有事件,从而创造出无与伦比的大量 DC 本地知识。就像 Yelp 一样,评论和帖子的编辑标准会下降,摄影质量也会下降。这个想法与 DC 的 Reddit 页面或带有 DC 过滤器的 Twitter 没有太大区别。

人工智能驱动的语法纠正、人工智能生成的推荐以及基于位置/用户兴趣的内容调用可以进一步推动内容生成。人工智能驱动的语法纠正是相当自明的,它保持了平台和编辑标准的可读性,同时允许更多的内容。人工智能生成的推荐可以想象为当你正在创建一个帖子时,一个弹出窗口会出现,其中有一个与你当前正在写的内容相关的主题和几个问题,以激发你的创造力。从技术角度来说,这仍然有一点距离,但它可以让像我们的华盛顿邮报这样的平台支持缺乏内容的领域,并指导贡献者创建更好、更全面的帖子。基于位置和用户兴趣的内容调用与下面讨论的用户使用数据相关,但通过利用应用使用数据,可以确定每个用户对哪些类别感兴趣和具有哪些专业知识。类似地,通过位置数据,可以知道每个用户经常去的位置。当讨论某个用户子集特别感兴趣的话题时,可以向子集的每个成员发送内容请求,从而提高内容的质量和数量。此外,上述每个功能都是为内容生成者服务的,并将它们保留在《华盛顿邮报》而不是其他平台上,类似于 Snapchat 和 Instagram 过滤器如何帮助用户留存。

由于联邦政府位于 DC,《华盛顿邮报》事实上肯定比非 DC 媒体有更好的政府关系。这可以用来管理政府法案、投票和其他关键信息的数据库,以及从内部关系中收集的笔记。该数据库可以开放为一个 API,供上述在《华盛顿邮报》应用程序中发帖的 DC 居民使用,或者作为一个按使用付费的 API,供需要政府数据的其他媒体使用。具体来说,我正在想象一个华盛顿邮报政府数据机器人,它可以监听平台上发布的内容,当一项法案或立法者的名字被提及时,它可以立即用数据库中的相关信息做出回应。

现在是护城河的新元素:位置和用户数据。通过应用程序的使用模式或直接的用户输入,《华盛顿邮报》应该能够确定每个用户经常光顾的城市地区,以及每个用户的家庭地址和工作地址。因此,当你的邻居发生犯罪时,你可以收到《邮报》的推送通知,并通过应用程序中的订阅源跟踪故事,实时更新并推送到你的手机上。当交通拥挤或你通常去上班的路线上有施工时,邮政可以提前提醒你,并帮助你计划一条新的路线,或者只是让你知道你可能想早点离开。当政府计划在你的公寓旁边建造一个新的地铁站时,猜猜会发生什么——来自邮局的警报,只需回复推送通知,向你的代表发送一封支持或反对建设的信。对于货币化努力来说,最重要的是,当你办公室旁边的餐厅推出新的午餐时间交易时,你可以收到《华盛顿邮报》的推送,里面有优惠券的二维码。

通过跟踪每个用户经常查看、张贴和评论的内容,可以确定每个用户的一些特征。最明显的是每个用户对哪个类别感兴趣。不太明显的是偏好的写作风格、语调、观点和对各种主题的理解程度。通过实验和对人工智能当前极限的一些推动,有可能首先开始根据用户偏好建议内容,最终将各种帖子融入为每个用户定制的定制文章中,在内容质量和用户理解方面具有无与伦比的精确度。由于文章的实时定制/生成以及与用户位置数据和使用数据的密切联系,华盛顿邮报提供的体验只能通过打开华盛顿邮报应用程序来获得。

总之,我们的新华盛顿邮报与今天的华盛顿邮报有很大不同。它雇佣很少真正的编辑或记者。相反,内容是众包和人工智能推动的。其实公司的核心是用户生成的数据和 AI。内容被分解成片段,钉在一起,以一种不可能在任何其他平台上复制的方式动态呈现,迫使观众访问《华盛顿邮报》的应用程序,而不是内容生成器。

应该指出的是,在这种商业模式中仍然有记者和记者的空间,但他们不是负责完整的故事,而是也会贡献一小部分内容——只是比其他用户更频繁。把它看作是一种搅拌锅的方式,也做更多的调查研究,普通人可能没有受过适当的训练。

我相信这个话题还有很多话要说。如果你有评论,就在下面留下,我们继续对话。

如何构建非地理地图#1

原文:https://towardsdatascience.com/how-to-build-a-non-geographical-map-1-8d3373e83d6c?source=collection_archive---------7-----------------------

或者如何映射相似性以进行偶然的数据探索(使用 Python)

地图是数据可视化的强大设计对象。它们通常用于强调元素之间的空间关系和比较多个变量。在非地理数据的情况下,维度减少技术允许我们在二维空间中映射相似性,而不损害初始信息的丰富性。

🔗链接到#第二部分:如何将散点图变成交互式地图

#第 1 部分:降维和可视化

第一步。设置特征和初始尺寸

In a geographical map, each element’s coordinates are inherently defined by its position. An element’s position is made of three parameters: latitude, longitude and elevation. To represent locations on Earth, the geographic coordinate system uses either a spherical coordinate system (globe) or a cartesian coordinate system (flat map). To transform the Earth’s three-dimensional space into a two-dimensional map, we use map projection techniques, the most common of which is the Mercator’s cylindrical projection.

为了以类似地图的方式可视化您的非地理数据,您需要将每个元素(或地图上的点)视为由一组特定的特征(或属性)定义的。

这组要素在整个数据集中必须是常量。这意味着每个元素可以通过给相同的特征赋予不同的值来描述。

This is what your dataset should look like.

要确定哪些属性最能描述您的数据,您可以问自己:

“是什么直观地让两个元素相似,又是什么把它们区分开来?”

在地图上,越靠近的两个元素越相似。距离越远,差异越大。

示例- 根据技能和知识相似性绘制职业图

在本例中,我想使用 ONET 开放式数据库,根据所需技能和知识的相似性来表示职位。

我非常幸运,因为这个数据集组织得非常好。所有的职业都由相同的一套技能(知识也是一样)来描述,并且每个职业都根据重要性(这项技能对完成工作有多重要)和级别(工作所需的专业知识水平)来细分。“数据值”栏指定各自的等级。

ONET skills.xlsx

我将每个技能和知识项目定义为一个单独的特性:

This is what my dataset should look like after cleaning

由于原始数据集的质量,这一部分相当容易:

📝>> Check out the full notebooks here

我现在只剩下一个矩阵,它的行向量是工作(n=640),列是技能和知识参数(p=134)。

在机器学习中,“维度”只是指数据集中的特征(或属性,或变量)的数量。

由于每个元素都是用 134 个参数来描述的,所以我们需要一个 134 维的空间来完整的表示它……很难描绘,不是吗?

让我们看看如何因式分解这个矩阵,以便将其表示为一个二维空间。

第二步。降低维度

我们想要创建一个较低维度的表示,在这里我们保留一些来自较高维度空间的结构。

本能地,我们希望在原始空间中彼此靠近的点在 2D 中彼此靠近。这同样适用于远点。

手工完成这项任务是不可能的。所以我四处寻找降维算法。

没有免费的午餐

在我们讨论它们之前,请注意没有一种算法适合所有问题。这个简单(但经常被遗忘)的事实被幽默地称为“没有免费的午餐”定理。每个模型都依赖于一些假设来简化现实。但是在某些情况下,这些假设会失效。因此,它们产生了不准确的现实版本。

因此,您必须根据数据的约束和问题的性质选择一些合适的算法。然后,尝试一下,看看哪一个最适合你。

Dimensionality reduction — Purpose & method (far from exhaustive)

例如,在我的项目中,我使用降维的唯一目的是数据可视化,而不是作为应用模式识别算法之前的预备步骤。另外,我想制作一张地图。因此,我对作为相似性代理的点之间距离的准确性感兴趣,但我并不真正关心新轴集的可解释性。

这就引出了特征提取算法

a .线性变换

  • 主成分分析

一种众所周知且常用的线性变换算法是主成分分析(PCA)。

在上面的矩阵中,每项工作由 134 个维度描述。很可能在某种程度上,列是线性相关的。当两列完全相关时,我只需要一列来描述另一列。为了在删除维度时降低新表示的不准确性,我最好保留描述数据集中大多数变化的维度。换句话说,去掉不必要的、嘈杂的维度,只保留最有信息量的维度。但是,降低 132 个维度已经很多了。

PCA 不是识别差异最大的维度,而是识别差异最大的方向,即数据最分散的地方。

这些方向被称为主成分(或特征向量),由初始维度的“组合”组成。因此,它们比任何单独的维度提供的信息都多,但与初始维度不同,它们不能被标上特定的特征(因此很难解释)。

PCA 找到一个由一对具有最大方差的正交(不相关)主分量构成的新坐标系,并为数据集中的每个点分配新值以相应地定位它们。

Illustration of what PCA does

本质上, PCA 保留了数据的全局结构,因为它以一种“一刀切”的方式找到了将为整个数据集产生最高方差的坐标系。它不考虑点相对于彼此的初始位置。相反,考虑到维数减少,它关注于尽可能地传播数据。

如果你很难想象我刚才解释的内容,看一看这个可怕的 PCA 互动可视化。

好吧,我们来试试:

1/用 PCA 创建一组“新”特征

首先,您需要从 scikit-learn 库中导入 PCA。

from sklearn.decomposition import PCA

然后,设置n_components。如果你想建立一个二维坐标系统,你设置它,使 PCA 找到 2 个主成分。

pca = PCA(n_components=2)

使用fit_transform将模型与您的数据框架(X)相匹配,并应用维度缩减。

pc = pca.fit_transform(X)

PCA 分别沿着第一和第二主分量建立 640 对坐标的阵列。

2/用 Plotly 可视化

一旦你导入了 plotly…

from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplotinit_notebook_mode(connected=True)import plotly.graph_objs as go

…使用每对坐标的第一个和第二个元素分别作为 x 和 y,绘制散点图:

data = [go.Scatter(x=pc[:,0], y=pc[:,1], mode=’markers’)]

我的数据没有标记,所以检查其表示是否准确的唯一方法是将鼠标悬停在点上,并检查它们的邻居是否“有意义”。

See notebook (Github) >> See graph (Plotly)

如您所见,数据分布得很好,但似乎有很多“异常值”。请注意,我对该算法是否适用于该数据集的判断是高度主观的,取决于我自己对最终可视化的预期。

对于这个项目,我对保存数据的本地结构非常感兴趣。我希望数据集中相邻的聚类在降维后仍然是相邻的。但如上所述,这不是 PCA 的最佳资产。

b .非线性变换

非线性降维(NLDR)方法假设在高维空间中,数据具有一些位于嵌入式非线性流形上的底层低维结构。

我不是数学家,拓扑学是个相当复杂的领域,我就试着打个比方解释一下。

流形在每个点附近类似欧几里得空间。欧几里得空间是你在几何学中学习的最早的定理,如泰勒斯定理,适用的空间。二维流形包括曲面(它们类似于每个点附近的欧几里得平面)。

NLDR 假设,如果嵌入流形是二维的(即使数据是三维或多维的),那么数据也可以在二维空间上表示。

一个很好的方法是在你铺床之前看看你的羽绒被。想象你度过了一个糟糕的夜晚,你的床很乱。如果你要描述羽绒被上的每一点,你需要三个维度。但是羽绒被就像每个点附近的欧几里得平面。所以,可以展平成平面(二维)。

Illustration of non-linear dimensionality reduction, from 3D to 2D

非线性算法擅长保持数据的局部结构,因为它们适应底层数据,对流形的不同区域执行不同的变换。

  • T-分布随机邻居嵌入(t-SNE)

TSNE 是最近流行的基于局部距离测量的非线性可视化方法,因此保留了近邻。然而,它不一定保留全局结构。这意味着它并不总是捕捉集群之间的距离。在我的项目中,这可能是一个问题。

如果你想更好地理解 t-SNE 是如何工作的:这篇文章解释了如何正确阅读 t-SNE 的结果。

1/创建嵌入

就像对 PCA 所做的那样,从 scikit-learn 库中导入 SNE,将n_components设置为 2,并用fit_transform创建嵌入:

from sklearn.manifold import TSNEtsne = TSNE(n_components=2)embedding = tsne.fit_transform(X)

2/看看结果:

See notebook (Github) >> See graph (Plotly)

看起来已经很不错了。让我们试试最后一种方法。

  • 【均匀流形逼近与投影】(UMAP)

新来的 UMAP 试图在保持本地和全球距离之间取得平衡,这正是我所需要的。

UMAP 是相当容易使用的,有几个参数你可以调整(默认是相当好的):

  • n_neighbors:当试图学习数据的流形结构时,限制局部邻域的大小
  • n_components:表示目标空间的维数
  • min_dist:设置低维表示中点之间的最小距离
  • metric:控制如何在输入数据的环境空间(特征空间)中计算距离

更多细节,你可以在这里找到文档(链接到 UMAP) 。

1/创建嵌入

一旦导入了 UMAP,就可以创建嵌入并使用UMAPfit_transform 函数来创建最终的坐标数组(完整的笔记本在这里):

import umapembedding = umap.UMAP(n_neighbors=15, n_components=2, min_dist=0.3, metric=’correlation’).fit_transform(X.values)

2/可视化

分数的分配对我来说似乎很合理。集群在逻辑上相对于彼此定位:

See notebook (Github) >> See graph (Plotly)

包裹

谢谢你看完😃

到目前为止,我们已经构建了一个散点图,其坐标系本身并没有任何明显的意义,而是使用距离作为数据要素之间相似性的代理。可视化是非常基本的,但它展示了地图的前提。

接下来,我们将看到如何给它一个在外观和使用上都类似于地图的格式(链接到#第 2 部分)。

与此同时,请随意分享您鼓舞人心的非地理地图和其他维度缩减方法。

🔗链接到#第 2 部分:如何将散点图变成交互式地图

👉看看我是如何在实践中使用它的:www.tailoredpath.com

📫让我知道你的想法:tailoredpath@gmail.com

如何构建 PostgreSQL 数据库来存储推文

原文:https://towardsdatascience.com/how-to-build-a-postgresql-database-to-store-tweets-1be9c1d48c7?source=collection_archive---------13-----------------------

了解如何从 Twitter API 进行流式传输

人们每天都用 witter 来表达他们的感受或想法,尤其是关于此刻正在发生或刚刚发生的事情;由公司推广产品或服务;被记者用来评论事件或撰写新闻,这样的例子不胜枚举。毫无疑问,分析 Twitter 和 tweets 是一个强大的工具,可以让我们了解我们感兴趣的话题的舆论。

但是我们如何进行这种类型的分析呢?幸运的是,Twitter 为我们提供了一个 API(代表“应用编程接口”),我们可以通过它来创建一个应用程序,并以这种方式访问和过滤公共推文。

第一步是注册我们的 app 为此,我们需要访问 twitter 开发者网站,使用我们的 Twitter 帐户登录,并请求 Twitter 批准开发者身份(从 2018 年 7 月起,Twitter 改变了他们的政策,任何想要访问 Twitter API 和创建应用程序的人都需要申请一个开发者帐户,提供他们打算如何使用它的详细信息,并等待申请获得批准)。在我们收到批准后,我们可以继续创建一个新的应用程序,填写详细信息: Name (其他人没有使用过的 Twitter 应用程序的唯一名称)DescriptionWebsite (这应该是应用程序的主页,但我们也可以将我们的个人网站或 GitHub 存储库 URL。

Creating an app in Twitter Developer account

之后,我们需要创建我们的访问令牌。访问令牌将允许我们的 Twitter 应用程序读取 Twitter 信息,如推文、提及、朋友等:

对于整个分析,我们将使用 JupyterLab 和 Python。因为任何拥有这些信息的人都可以使用它来授权应用程序连接到 Twitter,所以我们将创建一个 python 文件(。py),在这里我们可以存储消费者密钥消费者秘密OAuth 访问令牌OAuth 访问令牌秘密,然后在我们的主 Jupyter 笔记本文件中调用它。

现在我们已经注册了我们的应用程序,获得了我们的令牌/密钥,并将它们存储在一个单独的文件中,第二步是决定一旦我们获得它们,我们将在哪里存储我们的推文。我们应该将它们存储在一个文件中,一个 NoSQL 类型的数据库中,还是一个关系数据库?为了回答这个问题,我们需要了解我们从 twitter 应用程序中获得的信息是如何提供给我们的,以及我们想要用这些信息做什么。

Twitter API总是返回使用 JavaScript 对象符号 (JSON)编码的推文,这是一种非结构化和灵活的类型,基于具有描述对象的属性和关联值的键值对。每条推文包含作者、消息、唯一 ID、时间戳和发布时的创建日期等;每个用户都有一个姓名、id 和关注者数量。正因为如此,我们会立即想到将 tweets 存储在已构建的数据库管理系统(DBMS)中,如 MongoDB,这是一个被视为原生 JSON 数据库的开源数据库。这种类型的数据库的优点是,它们被设计为在使用动态模式时是敏捷的和可伸缩的,而无需首先定义结构。

另一方面,关系数据库更多的是与标准的一致性和可扩展性相关,因此,在如何存储数据上没有给我们自由。它们使用动态和静态模式,这有助于我们在数据是关系型的时候链接数据。相反,由于非结构化方法,我们不能在 MongoDB 中执行此操作。使用关系数据库的一些其他优点是,我们只需要改变其中一个表中的数据,然后它就会自我更新( 数据完整性 ),并且它们确保没有属性重复( 数据冗余 )。如前所述,关系数据库是以列和行的形式组织的,我们可以通过使用键来链接不同表中的信息,这些键唯一地标识表中的任何数据,并被其他表用来指向它们。

尽管 MongoDB 被设计得很快,对非结构化数据有很好的性能,但 PostgreSQL 等关系数据库在处理 JSON 时有很好的性能。这一事实以及结构化数据给我们带来的可能性导致我们使用关系数据库,特别是PostgreSQL 10(通常只作为 Postgres 提及),因为它是一个免费、可靠和高效的 SQL 数据库,最重要的是,它有一个非常强大和有用的 python API,称为 psycopg2 。为了以更友好的方式管理我们的数据库,我们还将使用 pgadmin 来创建一个带有用户名和密码的数据库,以保护我们的信息。同样,我们将把这些凭证存储在另一个 python 文件中,这样,一旦我们将主文件推送到 git 存储库,我们就可以对它们保密。

我们需要引入分析的最后一个组件是 Tweepy ,一个 python 库,它将成为我们代码中的主要参与者,将帮助我们访问 Twitter API、处理授权请求、捕获和流式传输 tweets 等,以及 json ,它将管理从 API 获得的 json 文件。

因此,我们需要在代码中做的第一件事是导入我们创建的所有库和文件:

之后,我们将定义一个函数,该函数将授权我们的应用程序连接到 Twitter API。OAuth 是一种开放的访问标准,主要由互联网用户用来授权应用程序或网站访问他们在其他网站上的信息,而无需向他们提供密码,而是允许批准的访问令牌访问由资源服务器托管的受保护资源。在 Twitter 的例子中,我们已经请求了令牌和密钥,所以我们将使用 Tweepy,这使得 OAuth 授权很容易用 tweepy 来处理。OAuthHandler 类。因此,首先,我们将consumer keyconsumer secret传递给这个函数,然后,我们将访问令牌设置为我们从 Twitter 获得的access tokenaccess token secret

正如我们以前讨论过的,关系数据库将信息存储在结构化的表中,所以下一步是决定数据库的模式。这里有一个很重要的概念需要我们考虑: 归一化。 规范化数据库需要一个根据某种范式构建关系数据库的过程,这种范式遵循减少数据冗余和提高数据完整性的目标。规范化数据库是这样一种数据库,即表之间的关系与数据之间真实存在的关系相匹配。简而言之,规则规定行中的唯一键和事件应该对此有所说明,与键无关的事实属于不同的表,并且表不应该暗示不存在的关系。

在我们的例子中,我们将创建两个表:第一个将包含关于 Twitter 用户的信息:user id,这将是我们的主键(对于每个记录都是唯一的键),以及user name。另一方面,我们将创建第二个表来存储关于 tweet 的信息:creation datetext(tweet 本身)、user id,这将是我们的外键(唯一标识另一个表的主键的键),将这个表与我们的用户表相关联,还有retweet count

我们将定义一个函数,一旦调用该函数,它将使用凭证连接到我们的数据库(使用命令 pyscopg2.connect ),并创建一个包含我们要搜索的术语名称的表。对于这最后一步,Postgres 为我们提供了设置一个 游标 的可能性,该游标封装查询并一次读取几行结果,而不是一次执行整个查询。因此,我们将利用这一点,创建一个游标(使用 database.cursor() ),然后执行我们的查询来创建用户表和包含 tweets 的表。这里我们需要考虑一些要点:当我们执行对CREATE TABLE的查询时,使用IF NOT EXISTS命令是很重要的,否则,Postgres 可能会出现表已经创建的错误,并会停止代码执行;我们需要澄清每一列包含哪种类型的变量(VARCHAR、TIMESTAMP 等。),哪一列是主键和外键,在这最后一种情况下,哪一列REFERENCES为;在我们执行完查询之后,一定要提交它( database.commit() ),否则,不会保存任何更改,并关闭到游标和数据库的连接。

之后,我们需要定义一个函数来帮助我们存储推文。这个函数将遵循我们用来创建表的相同逻辑(连接到数据库、创建游标、执行查询、提交查询、关闭连接),但是我们将使用[INSERT INTO](https://www.postgresql.org/docs/10/sql-insert.html)命令。当创建用户表时,我们声明user id将是我们的主键。因此,当我们存储推文时,我们需要小心如何将它插入表中。如果同一个用户有两条 tweets,第二次执行这个函数时,它会产生一个错误,因为它检测到特定的user id已经在表中,因为主键必须是惟一的。因此,我们可以在这里使用[ON CONFLICT](https://www.postgresql.org/docs/10/sql-insert.html)命令告诉 postgres,如果user id已经在表中,它就不必再次插入它。相反,tweet 将被插入到 tweets 表中,并被用户表中的那个user id引用。

有两种方法可以用 Tweepy 捕捉推文。第一个是使用 REST 搜索 API, tweepy。API,,搜索过去 7 天内发布的公共 tweets 样本。第二个是通过使用与 REST api 不同的 Twitter 流 api 来流式传输实时推文,这种方式从 Twitter 中提取数据,而流 api 将消息推送到持久会话。

为了在 tweepy 中传输 Tweepy,创建了类 的一个实例。stream建立流式会话,并向stream listener类的实例发送消息。在这个类中,有几个处理 tweets 的方法。根据我们想要获得的信息类型,我们需要覆盖不同的方法:如果我们只想要状态,那么我们将重载 on_status 方法。因为我们想要关于 tweet 的详细信息(创建日期、用户 id、用户名、转发次数),所以我们将重载负责接收所有消息并根据消息类型调用函数的 on_data 方法。

因此,我们将创建类 MyStreamListener ,它将继承自 tweepy。StreamListener 类,我们将覆盖 on_data 方法。我们将获取包含 tweet 的 json 文件( json.load(raw_data) )并解析它以将值存储在不同的变量中(例如:user_id = data['user']['id_str']),然后将它们传递给函数以存储我们之前创建的 tweet。

重要是要小心此时可能发生的错误或异常。为此,我们将用一个 try/except 块将代码括起来,以便在发生异常时,它会被打印出来,这样我们就可以知道发生了什么。此外,连接到流式 API 的尝试次数有限,这将显示错误 420。我们可以通过重载 on_error 方法来处理这个错误,并在出现这个错误时断开 API。

那么,还剩下什么?我们需要创建一个 api ( tweepy。API() )之后,创建我们的流对象( tweepy.stream() ),传递我们已经创建的授权和监听器。我们将使用 过滤器 功能来流式传输所有包含感兴趣的单词( track = ['word'] )并用英语编写的推文( languages = ['en] )

现在,是时候开始发送推文了!!我特别想知道人们对《复仇者联盟》是什么感觉。因此,我将使用“复仇者联盟”作为我的兴趣术语,并开始捕捉实时推文,以创建一个良好的数据库,这将有助于我稍后的情绪分析,您可以在此处阅读,并可视化 Twitter 与 Networkx 的交互,您可以在此处找到。你对什么感兴趣?

如何用 Go 构建一个简单的人工神经网络

原文:https://towardsdatascience.com/how-to-build-a-simple-artificial-neural-network-with-go-ac2e8c49ae37?source=collection_archive---------11-----------------------

从基础数学到用它识别笔迹的一步一步

我在职业生涯中写过很多计算机程序,大部分时间是为了解决各种问题或者执行一些任务(或者有时候只是为了好玩)。在大多数情况下,除了 bug 之外,只要我非常清楚地告诉计算机该做什么(无论我使用哪种编程语言),它就会乖乖地听从我的指令。

这是因为计算机程序非常擅长执行算法——遵循精确且经常重复的既定步骤和模式的指令。在大多数情况下,它们对我们处理数字运算或重复枯燥的工作很有帮助。

The ENIAC was one of the first general-purpose, programmable computers ever made (public domain from https://commons.wikimedia.org/wiki/File:Eniac.jpg)

然而,计算机程序不擅长做的事情是那些没有很好定义的任务,并且不遵循精确的模式。

In the 60s, Marvin Minsky assigned a couple of undergrads to spend the summer programming a computer to use a camera to identify objects in a scene. He figured they’d have the problem solved by the end of the summer. Half a century later, we’re still working on it. (from Explain XKCD — 1425: Tasks)

那么我们如何使用计算机来完成这样的任务呢?想想你如何完成这项任务。你可能在年轻的时候了解过鸟类,你被告知某些动物是鸟类,而某些动物不是,大部分是通过在现实生活中或通过图画书看到的。当你做错的时候,你会被告知并且记住。久而久之,你就有了一个心理模型,知道什么是鸟,什么不是。每次你看到一只鸟的某些部分(有爪的脚,有羽毛的翅膀,锋利的喙)你甚至不需要再看到整个动物,你会通过与你的心理模型进行比较来自动正确地识别它。

那么我们如何用计算机程序做到这一点呢?基本上我们做同样的事情。我们试图创建一个模型,通过试错过程,我们可以用它来比较输入。由于计算机程序都是数学,你可以猜到这将是我们将要谈论的一个数学模型

猜谜游戏

让我们举一个简单的例子,创建一个接受输入并试图预测输出的黑盒。

A simple predictor

我们给它一个输入,然后从这个预测器得到输出。既然我们知道实际输出应该是什么,我们就可以知道预测输出与实际输出有多大的不同。实际输出和预测输出之间的差异成为误差

当然,如果预测器是静态的,不能改变,那就没什么意义了。当我们向预测器提供输入时,会产生一个带有错误的输出,这就是故事的结尾。不是很有用。

为了让我们的预测器更有用,让我们给它一个可配置的参数,我们可以用它来影响输出。因为它只有在没有错误的情况下才能正确预测,所以我们希望更改参数,以便随着我们不断向预测器提供数据,错误会缩小。目的是得到一个预测器,它在大多数情况下预测正确的输出,而实际上不需要给预测器明确的指令。

换句话说,这很像一个数字猜谜游戏。

让我们从更实际的角度来看这个问题。假设我们有一个带有简单数学公式o = i x c的预测器,其中o是输出,i是输入,c是可配置参数。

A simple predictor with a configurable parameter

我们还得到了一个给定输入的确认有效输出,即我们知道i是否为 10,o是否为 26。我们如何使用预测器找到c

首先,我们需要进行随机预测,假设c是 2。让我们输入 10,启动预测器。输出o为 20。由于误差e = t - o其中t是真值(或目标),这意味着e = 26 - 20 = 6。我们的误差e是 6,我们想达到 0,所以我们再试一次。

让我们把c设为 3。然后输出为30并且e现在为-4。哎呀,我们超过了!我们倒回去一点,让c为 2.5。这使得o为 25,而e为 1。最后,我们尝试将c设为 2.6,我们得到的误差e为 0!

一旦我们知道c是什么,我们就可以使用预测器来预测其他输入的输出。假设输入i现在是 20,那么我们可以预测o是 52。

正如你所看到的,这种方法试图迭代地寻找答案,并不断改进自己,直到我们找到最佳答案。这本质上就是机器学习是什么。计算机程序试图迭代地寻找答案,并通过它的错误“学习”,直到它获得一个可以产生最佳答案的模型。一旦它有了正确的模型,我们就可以使用该模型来正确地猜测答案。这非常类似于我们人类所做的(从过去的错误中学习并纠正自己),但我们具体是如何做的呢?

人类是如何做到的

让我们出去一点。我们谈了一点机器如何利用数学函数学习。人类如何做同样的事情(正如多年来的研究表明的那样)是使用一种叫做 神经元 的东西。

Drawing of neurons in the pigeon cerebellum, by Spanish neuroscientist Santiago Ramón y Cajal in 1899 (public domain from https://commons.wikimedia.org/wiki/File:PurkinjeCell.jpg)

神经元或神经细胞是一种接收信息、处理信息并通过电信号和化学信号进行传输的细胞。我们的大脑和脊髓(我们的中枢神经系统的一部分)由神经元组成。

A neuron with dendrites, a cell body and an axon

神经元由细胞体、树突和轴突组成,可以相互连接形成神经网络。在神经网络中,神经元的轴突连接到下一个神经元的树突,突触信号从一个神经元通过其轴突传输,并由下一个神经元通过其树突接收。轴突和树突之间的连接是突触。

Synapses are the connections between neurons

通过树突传入的信号根据突触连接的使用频率而加强或减弱,这些加强或减弱的信号在细胞体中汇集在一起。

如果接收到的汇集信号足够强,它将触发一个新的信号,通过轴突发送到其他神经元。

如你所见,神经元工作方式有点类似于我们之前的预测器。它通过树突处理大量输入,通过轴突输出。每个输入都与突触连接的强度(或权重)配对,而不是一个可配置的参数。

有了这些信息,让我们回到我们的预测器并做一些改变。

人工神经元

我们从建立一个模拟真实生物神经元的人工神经元开始。这个人工神经元是我们升级的预测器。

An artificial neuron mimicking a biological one

我们有一堆输入,而不是单个输入,每个输入都有一个权重(代替一个可配置的参数)。这些修改后的输入被累加并通过触发或激活功能传递,该功能确定是否应该发送输出。

那么,为什么会有激活功能呢(除了生物神经元的行为方式相同这一事实之外)?有几个很好的理由,但最重要的一个是激活函数将非线性引入网络。没有激活函数(或线性激活函数)的神经网络基本上只是一个线性回归模型,不能完成更复杂的任务,如语言翻译和图像分类。稍后您将看到非线性激活函数是如何实现反向传播的。

现在,我们将假设使用一个普通的激活函数, sigmoid 函数。

Sigmoid function

关于这个函数值得注意的有趣的事情是,输出总是在 0 和 1 之间的范围内,但从来没有达到任何一个。

人工神经网络

就像我们有神经元形成神经网络一样,我们也可以将我们的人工神经元连接起来,形成人工神经网络。

Artificial neural network with 3 layers

现在看起来有点复杂了!

然而,我们只是将神经元堆叠在不同的层中。所有输入都通过输入层进入,输入层将其输出发送到隐藏层,隐藏层又将其输出发送到最终输出层。虽然来自每个节点的输出是相同的(只有一个输出),但是到下一层中神经元的连接被不同地加权。例如,隐藏层中第一个节点的输入将是(w11 x i1) + (w21 x i2)

用矩阵简化

如果我们必须一次计算一个,计算这个网络中的最终输出可能会有点乏味,特别是如果我们有很多神经元。幸运的是,有一个更简单的方法。如果我们将输入和权重表示为矩阵,我们可以使用矩阵运算来简化计算。事实上,我们不再需要做单个神经元的输入求和和输出激活,我们只需一层一层地做。

Using matrices

正如您将看到的,这将对代码的后续部分有很大帮助。

我们使用了矩阵点积来处理输入和权重的乘法和求和,但是对于激活函数,我们需要对每个矩阵元素应用 sigmoid 函数。我们将不得不对每个隐藏层和输出层做同样的操作。

调整重量

在这个时候,你可能会意识到,我们的神经网络(在概念上)只是神经元的一个更大的版本,因此非常像我们之前的预测器。就像我们的预测器一样,我们希望训练我们的神经网络,通过向它传递输入和已知输出来从它的错误中学习。然后利用已知和实际输出之间的差异(误差),我们改变权重以最小化误差。

然而,你可能会意识到,神经网络比我们的预测器要复杂得多。首先,我们有多层排列的多个神经元。因此,虽然我们知道最终目标输出,但我们不知道中间不同层的中间目标输出。第二,虽然我们的预测器是线性的,但是我们的神经元通过一个非线性的激活函数,所以输出是非线性的。那么我们如何改变不同连接的权重呢?

Weights and outputs in artificial neuron

我们从前面的预测器中知道,我们希望通过改变连接隐藏层和输出层之间的各种输出权重来最小化最终输出误差Ek

这很好,但是我们如何通过改变输入变量来最小化一个函数的值呢?

让我们从不同的角度来看这个问题。我们知道最后的输出误差Ek是:

然而,仅仅从tk中减去ok并不是一个好主意,因为这通常会导致负数。如果我们试图找出网络的最终输出误差,我们实际上是将所有误差相加,因此如果其中一些误差是负数,就会导致错误的最终输出误差。一种常见的解决方案是使用平方误差,顾名思义就是:

同时我们知道:

因此,我们知道(粗略地说),如果我们将Ekwjk对应起来,我们将得到一系列数值(蓝线)绘制在图表上(实际上这是一个多维图表,但为了保持我们的集体理智,我将使用一个二维图表):

Charting final output error to weights

如你所见,为了达到最小值Ek,我们沿着梯度或负梯度向下。换句话说,我们试图找到负梯度,相应地改变权重,然后再次找到负梯度,直到我们到达最小点Ek。这个算法叫做 梯度下降

Gradient descent

你可能还记得中学微积分,为了找到函数中点的梯度,我们使用微分来得到函数的导数。这让我们能够发现我们需要调整wjk到什么程度。为了找到Ek的最小值,我们从wjk中减去这个量,并重复这样做。

让我们做数学。

为了计算输出权重wjk所需的变化,我们应该计算最终输出误差Ek相对于输出权重wjk的导数。这意味着:

这很好,但是我们如何使用其他变量得到我们的结果呢?为此我们需要使用 链式法则 :

这看起来稍微好一点,但是我们可以更进一步:

我们开始工作吧。首先,我们需要找到Ek相对于最终输出ok的导数。

从前面,我们知道Ek是平方误差:

但是为了更好的区分,我们把它缩小了一半(我知道这有点像作弊,但这让我们的生活更轻松):

它的导数是:

这很简单!让我们看看最终输出ok相对于中间输出和权重sumk的乘积总和的导数。我们知道求和是通过一个 sigmoid 函数sig来得到最终输出ok:

因此,最终输出ok相对于总和sumk的导数为:

这是因为我们知道 sigmoid 的导数是:

我前面提到过,我们使用 sigmoid 函数是有充分理由的——简单微分就是其中之一!这一点的证明可以在这里找到。现在既然:

我们可以将等式进一步简化为:

最后,我们想找到总和sumk相对于输出权重wjk的导数。我们知道总和是输出权重wjk和先前输出oj的乘积之和:

因此,总和sumk相对于输出权重wjk的导数为:

现在我们有了所有的 3 个导数,让我们把它们放在一起。之前,我们说过:

因此:

这样我们就有了改变输出层权重的公式。隐藏层的权重是多少?我们简单地使用相同的等式,但是后退一层。该算法被称为 反向传播 ,因为它从最终输出反向计算权重。

但是等等。我们没有隐藏层的目标输出。那么我们如何得到隐藏层的误差呢?我们必须找到另一种方法。

反向传播误差

仔细想想,输出层的误差是由隐藏层的误差根据前一个隐藏层的连接造成的。换句话说,隐藏层的误差组合形成了输出层的误差。由于权重代表输入的重要性,它也代表误差的贡献。

Contribution of errors

因此,我们可以使用重量的比率来计算每个重量的变化。因为分母是常数,我们可以通过去掉分母来进一步简化。

Back propagating errors

现在,让我们看看如何使用矩阵从输出层反向传播误差。

一旦我们有了隐藏层的误差,我们就可以使用和以前一样的等式,但是用隐藏的输出误差代替最终的输出误差。

学习率

因此,人工神经网络通过使用梯度下降的反向传播进行学习。在梯度下降迭代过程中,经常很容易超调,这导致移动太快并跨过最小值wjk。为了防止这种情况,我们使用一个学习率 l来缩小我们想要为权重改变的量。这导致我们之前等式的改变:

l通常是一个很小的值,因此我们在超过最小值时会更加小心,但也不能太小,否则训练时间会很长。有很多关于设定最佳学习率的研究文献。

偏见

对于我们当前的神经网络,激活函数是在 0.5 处穿过y的 s 形曲线。对权重的任何改变仅仅改变了 s 形的陡度。因此,神经元的触发方式是有限制的。例如,当x为 2 时,让 sigmoid 返回 0.1 的低值是不可能的。

Sigmoid functions without bias

然而,如果我们给x加上一个 偏置 值,事情就完全变了。

Sigmoid functions with bias

我们如何做到这一点是通过在神经网络中添加一个叫做偏置神经元的东西。这个偏置神经元总是输出 1.0,并且被添加到一个层,但是没有任何输入。

Artificial neural network with bias

不是所有的神经网络都需要偏向神经元。在我们稍后要写的简单神经网络中,我们不会使用任何偏向神经元(并且它工作得相当好)。

终于有代码了!

所以我们终于来了!在所有的概念和数学之后,我们现在要开始一些实现!

这篇文章中的代码片段并不完整,所以不要简单地从这里剪切和粘贴来运行它。这里的所有代码都可以在这个 Github 资源库中找到:

https://github.com/sausheong/gonn

与 Python 不同,Go 目前在机器学习的库方面没有太多支持。然而有一个非常有用的库叫做 Gonum ,它提供了我们最需要的东西——矩阵操作。

此外,虽然 Gonum 有非常好的包,但我认为 Gonum 中的一些怪癖使它变得不必要的冗长,所以我创建了自己的助手函数来克服它。

矩阵助手

我们将首先从助手函数开始。Gonum 用于矩阵操作的主包叫做mat。我们将使用的主要是mat.Matrix接口及其实现mat.Dense

mat包有一个怪癖,它要求我们在对矩阵执行操作之前,先创建一个包含正确行和列的新矩阵。对多个操作这样做相当烦人,所以我用自己的函数包装了每个函数。

例如,Gonum Product函数允许我们对两个矩阵执行点积运算,我创建了一个助手函数,它找出矩阵的大小,创建它并在返回结果矩阵之前执行运算。

这有助于节省大约 1-3 行代码,具体取决于操作。

func dot(m, n mat.Matrix) mat.Matrix {
	r, _ := m.Dims()
	_, c := n.Dims()
	o := mat.NewDense(r, c, nil)
	o.Product(m, n)
	return o
}

apply功能允许我们对矩阵应用函数。

func apply(fn func(i, j int, v float64) float64, m mat.Matrix) mat.Matrix {
	r, c := m.Dims()
	o := mat.NewDense(r, c, nil)
	o.Apply(fn, m)
	return o
}

scale功能允许我们缩放矩阵,即将矩阵乘以标量。

func scale(s float64, m mat.Matrix) mat.Matrix {
	r, c := m.Dims()
	o := mat.NewDense(r, c, nil)
	o.Scale(s, m)
	return o
}

multiply函数将 2 个函数相乘(这不同于点积`)。

func multiply(m, n mat.Matrix) mat.Matrix {
	r, c := m.Dims()
	o := mat.NewDense(r, c, nil)
	o.MulElem(m, n)
	return o
}

addsubtract功能允许增加或减少一个功能。

func add(m, n mat.Matrix) mat.Matrix {
	r, c := m.Dims()
	o := mat.NewDense(r, c, nil)
	o.Add(m, n)
	return o
}func subtract(m, n mat.Matrix) mat.Matrix {
	r, c := m.Dims()
	o := mat.NewDense(r, c, nil)
	o.Sub(m, n)
	return o
}

最后,addScalar函数允许我们向矩阵中的每个元素添加一个标量值。

func addScalar(i float64, m mat.Matrix) mat.Matrix {
	r, c := m.Dims()
	a := make([]float64, r*c)
	for x := 0; x < r*c; x++ {
		a[x] = i
	}
	n := mat.NewDense(r, c, a)
	return add(m, n)
}

神经网络

开始了。

我们将创建一个非常简单的 3 层前馈神经网络(也称为多层感知器)。我们从定义网络开始:

type Network struct {
	inputs        int
	hiddens       int
	outputs       int
	hiddenWeights *mat.Dense
	outputWeights *mat.Dense
	learningRate  float64
}

字段inputshiddensoutput定义了每个输入、隐藏和输出层中的神经元数量(记住,这是一个 3 层网络)。hiddenWeightsoutputWeights字段是矩阵,分别表示从输入层到隐藏层以及从隐藏层到输出层的权重。最后,学习率是网络的学习率。

接下来,我们有一个简单的方法来创建神经网络。

func CreateNetwork(input, hidden, output int, rate float64) (net Network) {
	net = Network{
		inputs:       input,
		hiddens:      hidden,
		outputs:      output,
		learningRate: rate,
	}
	net.hiddenWeights = mat.NewDense(net.hiddens, net.inputs, randomArray(net.inputs*net.hiddens, float64(net.inputs)))
	net.outputWeights = mat.NewDense(net.outputs, net.hiddens, randomArray(net.hiddens*net.outputs, float64(net.hiddens)))
	return
}

输入、隐藏和输出神经元的数量以及学习速率从调用者传入以创建网络。然而,隐藏和输出权重是随机创建的。

如果您还记得上面的内容,我们创建的权重是一个矩阵,其列数由来自层的表示,行数由层表示。这是因为权重中的行数必须与层中的神经元数量相同,列数必须与层中的的神经元数量相同(以便与层中的的输出相乘)。花点时间再看看下面的图表——它会更有意义。

Neural network and matrices

用一组随机数字初始化权重是一个重要的参数。为此,我们将使用函数randomArray来创建 float64 的随机数组。

func randomArray(size int, v float64) (data []float64) {
	dist := distuv.Uniform{
		Min: -1 / math.Sqrt(v),
		Max: 1 / math.Sqrt(v),
	} data = make([]float64, size)
	for i := 0; i < size; i++ {
		data[i] = dist.Rand()
	}
	return
}

randomArray函数使用 Gonum 中的distuv包在-1/sqrt(v)1/sqrt(v)之间创建一组均匀分布的值,其中v是来自层的的大小。这是一个相当常用的分布。

现在我们有了神经网络,我们可以要求它做的两个主要功能是用一组训练数据训练自己,或者根据一组测试数据预测值。

从我们之前的努力工作中,我们知道预测意味着通过网络的前向传播,而训练意味着首先是前向传播,然后是后向传播,以使用一些训练数据来改变权重。

因为训练和预测都需要前向传播,所以让我们先从它开始。我们定义了一个名为Predict的函数,使用训练好的神经网络来预测这些值。

func (net Network) Predict(inputData []float64) mat.Matrix {
	// forward propagation
	inputs := mat.NewDense(len(inputData), 1, inputData)
	hiddenInputs := dot(net.hiddenWeights, inputs)
	hiddenOutputs := apply(sigmoid, hiddenInputs)
	finalInputs := dot(net.outputWeights, hiddenOutputs)
	finalOutputs := apply(sigmoid, finalInputs)
	return finalOutputs
}

我们首先从输入开始,通过创建一个名为inputs的矩阵来表示输入值。接下来,我们通过应用隐藏权重和输入之间的点积来找到隐藏层的输入,创建一个名为hiddenInputs的矩阵。换句话说,给定一个 2 神经元输入层和一个 3 神经元隐藏层,我们得到的是:

接下来,我们将激活函数sigmoid应用于隐藏输入,以产生hiddenOutputs

func sigmoid(r, c int, z float64) float64 {
	return 1.0 / (1 + math.Exp(-1*z))
}

我们对最终输入和最终输出重复这两个动作,分别产生finalInputsfinalOutputs,预测就是最终输出。

这就是我们如何使用正向传播算法进行预测。让我们看看我们在训练中是如何进行前向和后向传播的。

func (net *Network) Train(inputData []float64, targetData []float64) {
	// forward propagation
	inputs := mat.NewDense(len(inputData), 1, inputData)
	hiddenInputs := dot(net.hiddenWeights, inputs)
	hiddenOutputs := apply(sigmoid, hiddenInputs)
	finalInputs := dot(net.outputWeights, hiddenOutputs)
	finalOutputs := apply(sigmoid, finalInputs) // find errors
	targets := mat.NewDense(len(targetData), 1, targetData)
	outputErrors := subtract(targets, finalOutputs)
	hiddenErrors := dot(net.outputWeights.T(), outputErrors) // backpropagate
	net.outputWeights = add(net.outputWeights,
		scale(net.learningRate,
			dot(multiply(outputErrors, sigmoidPrime(finalOutputs)),
				hiddenOutputs.T()))).(*mat.Dense)

	net.hiddenWeights = add(net.hiddenWeights,
		scale(net.learningRate,
			dot(multiply(hiddenErrors, sigmoidPrime(hiddenOutputs)),
				inputs.T()))).(*mat.Dense)
}

正向传播部分与Predict功能完全相同。我们在这里没有调用Predict,因为我们仍然需要其他的中间值。

获得最终输出后,我们需要做的第一件事是确定输出误差。这相对简单,我们简单地从最终输出中减去我们的目标数据,得到outputErrors:

隐藏层隐藏的错误有点棘手。还记得这个吗?

我们使用反向传播通过在输出权重和输出误差的转置上应用点积来计算隐藏误差。这会给我们hiddenErrors

现在我们有了误差,我们简单地使用我们之前推导的公式(包括学习率)来改变我们需要做的权重:

请记住,我们是从重量中减去这个数字。因为这是一个负数,我们最后把它加到权重上,这就是我们所做的。

为了简化计算,我们使用了一个sigmoidPrime函数,它无非是做sigP = sig(1 - sig):

func sigmoidPrime(m mat.Matrix) mat.Matrix {
	rows, _ := m.Dims()
	o := make([]float64, rows)
	for i := range o {
		o[i] = 1
	}
	ones := mat.NewDense(rows, 1, o)
	return multiply(m, subtract(ones, m)) // m * (1 - m)
}

你可能还会看到,我们正在做前一个输出转置的点积——这是因为我们在跨层相乘。

最后,我们这样做两次,为我们的神经网络获得新的隐藏和输出权重。

这就是对Train函数的总结。

保存培训结果

在我们继续使用神经网络之前,我们将看看如何保存我们的训练结果并加载它以供以后使用。我们当然不希望每次想做预测时都要从头开始训练——训练网络通常需要很长时间。

func save(net Network) {
	h, err := os.Create("data/hweights.model")
	defer h.Close()
	if err == nil {
		net.hiddenWeights.MarshalBinaryTo(h)
	}
	o, err := os.Create("data/oweights.model")
	defer o.Close()
	if err == nil {
		net.outputWeights.MarshalBinaryTo(o)
	}
}// load a neural network from file
func load(net *Network) {
	h, err := os.Open("data/hweights.model")
	defer h.Close()
	if err == nil {
		net.hiddenWeights.Reset()
		net.hiddenWeights.UnmarshalBinaryFrom(h)
	}
	o, err := os.Open("data/oweights.model")
	defer o.Close()
	if err == nil {
		net.outputWeights.Reset()
		net.outputWeights.UnmarshalBinaryFrom(o)
	}
	return
}

saveload函数是彼此的镜像,我们使用 Gonum mat包中的一个方便的函数将权重矩阵编组为二进制形式,并将相同的形式解组回矩阵。这很普通——唯一值得注意的是,当我们从二进制数据解组回权重矩阵时,我们需要首先将矩阵重置为零值,以便可以重用。

使用我们的神经网络

我们终于来了——使用神经网络!

MNIST 手写识别

让我们从机器学习的“hello world”开始——使用 MNIST 数据集来识别手写数字。MNIST 数据集是一组用于训练的 60,000 个扫描的手写数字图像和用于测试的 10,000 个类似图像。它是 NIST(国家标准与技术研究所)的一个更大的集合的子集,已经过大小标准化和居中。这些图像是黑白的,28 x 28 像素。原始数据集以一种更难处理格式存储,所以人们想出了更简单的 CSV 格式的数据集,这就是我们正在使用的。

MNIST dataset

在 CSV 格式中,每一行都是一幅图像,除了第一列以外的每一列都代表一个像素。第一列是标签,这是图像应该表示的实际数字。换句话说,这就是目标输出。由于有 28 x 28 个像素,这意味着每行有 785 列。

让我们从培训开始。我们创建一个名为mnistTrain的函数,它接收一个神经网络,并使用它来训练 MNIST 数据集:

func mnistTrain(net *Network) {
	rand.Seed(time.Now().UTC().UnixNano())
	t1 := time.Now() for epochs := 0; epochs < 5; epochs++ {
		testFile, _ := os.Open("mnist_dataset/mnist_train.csv")
		r := csv.NewReader(bufio.NewReader(testFile))
		for {
			record, err := r.Read()
			if err == io.EOF {
				break
			} inputs := make([]float64, net.inputs)
			for i := range inputs {
				x, _ := strconv.ParseFloat(record[i], 64)
				inputs[i] = (x / 255.0 * 0.99) + 0.01
			} targets := make([]float64, 10)
			for i := range targets {
				targets[i] = 0.01
			}
			x, _ := strconv.Atoi(record[0])
			targets[x] = 0.99 net.Train(inputs, targets)
		}
		testFile.Close()
	}
	elapsed := time.Since(t1)
	fmt.Printf("\nTime taken to train: %s\n", elapsed)
}

我们打开 CSV 文件并读取每条记录,然后处理每条记录。对于我们读入的每条记录,我们创建一个表示输入的数组和一个表示目标的数组。

对于inputs数组,我们从记录中取出每个像素,并将其转换为 0.0 到 1.0 之间的值,0.0 表示没有值的像素,1.0 表示完整的像素。

对于targets数组,数组的每个元素代表索引成为目标数字的概率。例如,如果目标数字是 3,那么第 4 个元素targets[3]将具有 0.99 的概率,而其余的将具有 0.01 的概率。

一旦我们有了输入和目标,我们就调用网络的Train函数,并将输入和目标传递给它。

你可能会注意到我们在“时代”中运行这个。基本上,我们所做的是运行多次,因为我们运行训练的次数越多,神经网络的训练就越好。然而,如果我们过度训练它,网络将过度适应,这意味着它将很好地适应训练数据,最终将在处理它以前从未见过的数据时表现不佳。

预测手写图像基本上是同样的事情,除了我们只使用输入来调用Predict函数。

func mnistPredict(net *Network) {
	t1 := time.Now()
	checkFile, _ := os.Open("mnist_dataset/mnist_test.csv")
	defer checkFile.Close() score := 0
	r := csv.NewReader(bufio.NewReader(checkFile))
	for {
		record, err := r.Read()
		if err == io.EOF {
			break
		}
		inputs := make([]float64, net.inputs)
		for i := range inputs {
			if i == 0 {
				inputs[i] = 1.0
			}
			x, _ := strconv.ParseFloat(record[i], 64)
			inputs[i] = (x / 255.0 * 0.99) + 0.01
		}
		outputs := net.Predict(inputs)
		best := 0
		highest := 0.0
		for i := 0; i < net.outputs; i++ {
			if outputs.At(i, 0) > highest {
				best = i
				highest = outputs.At(i, 0)
			}
		}
		target, _ := strconv.Atoi(record[0])
		if best == target {
			score++
		}
	} elapsed := time.Since(t1)
	fmt.Printf("Time taken to check: %s\n", elapsed)
	fmt.Println("score:", score)
}

我们得到的结果是一组概率。我们找出概率最高的元素,该数字应该是该元素的索引。如果是的话,我们就认为这是一场胜利。胜利的最终计数是我们的最终得分。

因为我们有 10,000 张测试图像,如果我们能够准确地检测到所有这些图像,那么我们将拥有 100%的准确性。我们来看一下main函数:

func main() {
	// 784 inputs - 28 x 28 pixels, each pixel is an input
	// 200 hidden neurons - an arbitrary number
	// 10 outputs - digits 0 to 9
	// 0.1 is the learning rate
	net := CreateNetwork(784, 200, 10, 0.1) mnist := flag.String("mnist", "", "Either train or predict to evaluate neural network")
	flag.Parse() // train or mass predict to determine the effectiveness of the trained network
	switch *mnist {
	case "train":
		mnistTrain(&net)
		save(net)
	case "predict":
		load(&net)
		mnistPredict(&net)
	default:
		// don't do anything
	}
}

这非常简单,我们首先创建一个神经网络,在输入层有 784 个神经元(每个像素是一个输入),在隐藏层有 200 个神经元,在输出层有 10 个神经元,每个神经元对应一个数字。

然后用 MNIST 训练集训练网络,用测试集预测图像。这是我测试时得到的结果:

用 60,000 幅图像和 5 个时期训练网络需要 8 分钟,用 10,000 幅图像测试需要 4.4 秒。结果是 9772 幅图像被正确预测,准确率为 97.72%!

预测单个文件

现在,我们已经测试了我们的网络,让我们看看如何使用它对个别图像。

首先,我们从 PNG 文件中获取数据。为此,我们创建了一个dataFromImage函数。

func dataFromImage(filePath string) (pixels []float64) {
	// read the file
	imgFile, err := os.Open(filePath)
	defer imgFile.Close()
	if err != nil {
		fmt.Println("Cannot read file:", err)
	}
	img, err := png.Decode(imgFile)
	if err != nil {
		fmt.Println("Cannot decode file:", err)
	} // create a grayscale image
	bounds := img.Bounds()
	gray := image.NewGray(bounds) for x := 0; x < bounds.Max.X; x++ {
		for y := 0; y < bounds.Max.Y; y++ {
			var rgba = img.At(x, y)
			gray.Set(x, y, rgba)
		}
	}
	// make a pixel array
	pixels = make([]float64, len(gray.Pix))
	// populate the pixel array subtract Pix from 255 because 
	// that's how the MNIST database was trained (in reverse)
	for i := 0; i < len(gray.Pix); i++ {
		pixels[i] = (float64(255-gray.Pix[i]) / 255.0 * 0.99) + 0.01
	}
	return
}

图像中的每个像素代表一个值,但我们不能使用普通的 RGBA,而是需要一个image.Gray。从image.Gray结构中,我们得到了Pix值,并将其转换为float64值。MNIST 图像是黑底白字,所以我们需要从 255 减去每个像素值。

一旦我们有了像素阵列,事情就很简单了。我们使用一个predictFromImage函数,它接收神经网络并从图像文件中预测数字。结果是一个概率数组,其中索引是数字。我们需要做的是找到索引并返回它。

func predictFromImage(net Network, path string) int {
	input := dataFromImage(path)
	output := net.Predict(input)
	matrixPrint(output)
	best := 0
	highest := 0.0
	for i := 0; i < net.outputs; i++ {
		if output.At(i, 0) > highest {
			best = i
			highest = output.At(i, 0)
		}
	}
	return best
}

最后,通过main函数,我们打印图像并从图像中预测数字。

func main() {
	// 784 inputs - 28 x 28 pixels, each pixel is an input
	// 100 hidden nodes - an arbitrary number
	// 10 outputs - digits 0 to 9
	// 0.1 is the learning rate
	net := CreateNetwork(784, 200, 10, 0.1) mnist := flag.String("mnist", "", "Either train or predict to evaluate neural network")
	file := flag.String("file", "", "File name of 28 x 28 PNG file to evaluate")
	flag.Parse() // train or mass predict to determine the effectiveness of the trained network
	switch *mnist {
	case "train":
		mnistTrain(&net)
		save(net)
	case "predict":
		load(&net)
		mnistPredict(&net)
	default:
		// don't do anything
	} // predict individual digit images
	if *file != "" {
		// print the image out nicely on the terminal
		printImage(getImage(*file))
		// load the neural network from file
		load(&net)
		// predict which number it is
		fmt.Println("prediction:", predictFromImage(net, *file))
	}
}

假设网络已经被训练过,这就是我们得到的。

就这样,我们用 Go 从头开始编写了一个简单的 3 层前馈神经网络!

参考

这里是我写这篇文章和代码时参考的一些资料。

  • 塔里克·拉希德的制作你自己的神经网络是一本学习神经网络基础知识的好书,其简单的解释风格
  • 迈克尔·尼尔森的神经网络和深度学习免费在线书籍是学习构建神经网络复杂性的另一个惊人资源
  • 丹尼尔·怀特纳克写了一本关于用围棋进行机器学习的书,他关于 T2 在围棋中从头开始构建神经网络的帖子很有教育意义
  • Ujjwal Karn 的数据科学博客有一篇关于神经网络的很好的介绍文章

如何建立一个简单的歌曲推荐系统

原文:https://towardsdatascience.com/how-to-build-a-simple-song-recommender-296fcbc8c85?source=collection_archive---------0-----------------------

这篇博客的灵感来自 Siraj Raval 在 Udacity 的深度学习基金会纳米学位。那么回购这种做法可以在这里找到。

建立推荐系统是亚马逊、网飞、Spotify 和谷歌面临的共同任务。推荐系统的基本目标是为我们的观众个性化内容和识别相关数据。这些内容可以是文章、电影、游戏等

有 3 种类型的推荐系统:基于内容的、协作的和流行的。

在本练习中,我们将学习如何使用真实数据构建音乐推荐系统。我们的百万首歌曲数据集包含两个文件:三元组 _ 文件和元数据 _ 文件。三元组文件包含用户 id、歌曲 id 和收听时间。元数据文件包含歌曲 id、标题、发行人和艺术家姓名。百万歌曲数据集是来自不同网站的歌曲的混合,用户在听完歌曲后给出评级。例如 Last.fm 、 thisismyjam 、 musixmatch 等

我们的第一项工作是整合我们的数据集,这在每次我们想要构建数据处理管道时都非常重要。为了集成三元组文件和元数据文件,我们将使用一个流行的 Python 库,名为 pandas

我们首先定义将要使用的两个文件:

triplets_file = 'https://static.turi.com/datasets/millionsong/10000.txt'songs_metadata_file = 'https://static.turi.com/datasets/millionsong/song_data.csv'

然后,我们使用 pandas 读取三元组文件表,并将这 3 列定义为 user_id、song_id 和 listen_count ( df 在这里表示数据帧)

song_df_1 = pandas.read_table(triplets_file,header=**None**)
song_df_1.columns = ['user_id', 'song_id', 'listen_count']

我们还读取了 metadat_file,并打算将 metadat _ file 与 triplets_file 合并。每当组合两个或更多数据集时,都会有重复的列。这里,我们使用 song_id 删除两个数据集之间的重复项

 song_df_2 =  pandas.read_csv(songs_metadata_file)

song_df = pandas.merge(song_df_1, song_df_2.drop_duplicates(['song_id']), on="song_id", how="left")

使用命令song_df.head()允许我们可视化组合数据集:

这里有歌曲索引、用户标识、歌曲标识、收听次数、标题、发行版本和艺术家名称。运行len(song_df)返回这个数据集按歌曲索引的总长度是 2,000,000。

本练习的第二步是数据转换,我们将选择该数据的一个子集(前 10,000 首歌曲)。然后,我们将歌曲和 artist_name 合并到一个列中,按照特定歌曲被所有用户收听的次数进行汇总。下面代码中的第一行按照 listen_count 的升序对 song_df 进行分组。第二行通过对每首歌曲的 listen_count 求和来计算 group_sum。第三行添加了一个名为percentage的新列,通过将 listen_count 除以所有歌曲的 listen_count 之和然后乘以 100 来计算这个百分比。最后一行按给定歌曲流行度的升序列出歌曲

song_grouped = song_df.groupby(['song']).agg({'listen_count': 'count'}).reset_index()
grouped_sum = song_grouped['listen_count'].sum()
song_grouped['percentage']  = song_grouped['listen_count'].div(grouped_sum)*100
song_grouped.sort_values(['listen_count', 'song'], ascending = [0,1])

以下是转换步骤后数据集的示例:

进行数据转换使我们能够进一步简化数据集,并使其易于理解。

下一步,在构建推荐系统时,我们将遵循一种简单的方法。我们将统计数据子集中独立用户和歌曲的数量

users = song_df['user_id'].unique()
len(users) ## return 365 unique userssongs = song_df['song'].unique()
len(songs) ## return 5151 unique songs

然后,我们通过将数据集分成训练和测试数据来创建歌曲推荐器。我们使用scikit-learn库的train_test_split功能。值得注意的是,每当我们构建机器学习系统时,在训练我们的模型之前,我们总是希望将我们的数据分成训练和测试数据集

train_data, test_data = train_test_split(song_df, test_size = 0.20, random_state=0)

我们任意选择 20%作为我们的测试规模。然后,我们使用基于流行度的推荐器类作为黑盒来训练我们的模型。我们创建了一个基于流行度的推荐类的实例,并用我们的训练数据来填充它。下面的代码实现了以下目标:基于每首歌曲的流行度,创建一个推荐器,它接受一个user_id作为输入,并输出该用户的推荐歌曲列表

pm = Recommenders.popularity_recommender_py()
pm.create(train_data, 'user_id', 'song')#user the popularity model to make some prediction
user_id = users[5]
pm.recommend(user_id)

推荐系统模型的代码如下。这个系统是一个幼稚的方法,没有个性化。它首先获得每首歌曲的 user_id 的唯一计数(即该歌曲通常被所有用户收听的次数),并将其标记为推荐分数。然后,recommend函数接受一个 user_id,并为任何给定用户输出前十首推荐歌曲。因为这是幼稚的方法,所以推荐不是个性化的,对所有用户都是一样的。

#Class for Popularity based Recommender System modelclass popularity_recommender_py():    
    def __init__(self):        
    self.train_data = None        
    self.user_id = None        
    self.item_id = None        
    self.popularity_recommendations = None                #Create the popularity based recommender system model    
    def create(self, train_data, user_id, item_id): 
        self.train_data = train_data
        self.user_id = user_id        
        self.item_id = item_id         

        #Get a count of user_ids for each unique song as   recommendation score
        train_data_grouped = train_data.groupby([self.item_id]).agg({self.user_id: 'count'}).reset_index()        
        train_data_grouped.rename(columns = {'user_id': 'score'},inplace=True)                    #Sort the songs based upon recommendation score
        train_data_sort = train_data_grouped.sort_values(['score', self.item_id], ascending = [0,1])                    #Generate a recommendation rank based upon score
        train_data_sort['Rank'] = train_data_sort['score'].rank(ascending=0, method='first') #Get the top 10 recommendations
        self.popularity_recommendations = train_data_sort.head(10)        #Use the popularity based recommender system model to    
        #make recommendations        def recommend(self, user_id):                    user_recommendations = self.popularity_recommendations                         #Add user_id column for which the recommendations are being generated                user_recommendations['user_id'] = user_id                    #Bring user_id column to the front        
        cols = user_recommendations.columns.tolist()        
        cols = cols[-1:] + cols[:-1]        
        user_recommendations = user_recommendations[cols]
        return user_recommendations

本练习的第二部分是通过利用基于 相似性的协同过滤模型来创建一个 ML 个性化歌曲推荐系统。回想一下,推荐系统分为两种类型:基于内容的基于协作的。基于内容的系统根据用户过去喜欢什么来预测用户喜欢什么。基于协作的系统基于其他相似用户的喜好来预测特定用户的喜好。像网飞和 Hulu 这样的大多数公司都使用混合方法,根据用户过去喜欢的内容以及其他类似用户喜欢的内容来提供推荐。

根据剑桥编码学院的 Agnes jóhannsdóttir(Twitter:@ agnesjohanns)的说法,基于记忆的协同过滤可以分为两种主要方法:用户-项目过滤和项目-项目过滤。

项目-项目过滤方法包括基于用户喜欢的歌曲定义一个共现矩阵。我们试图回答一个问题,对于每首歌曲,已经听过该歌曲的用户还会听另一组其他歌曲多少次。为了进一步简化这一点,根据你过去喜欢什么,根据其他类似用户喜欢什么,你会喜欢什么其他类似的歌曲。让我们将它应用到我们的代码中。首先,我们创建一个基于实例项目相似性的推荐器类,并向它提供我们的训练数据。

is_model = Recommenders.item_similarity_recommender_py()
is_model.create(train_data, 'user_id', 'song')

请注意,在推荐系统的源代码中,generate_top_recommendations 函数计算了所有用户歌曲在同现矩阵中得分的加权平均值。这个共现矩阵将趋向于稀疏矩阵,因为不可能预测用户是否喜欢特定歌曲,他/她是否会喜欢一百万首其他歌曲。可能性是如此之大。使用我们的模型,我们将能够预测用户喜欢的歌曲列表

*#Print the songs for the user in training data*
user_id = users[5]
user_items = is_model.get_user_items(user_id)
*#*
print("------------------------------------------------------------------------------------")
print("Training data songs for the user userid: **%s**:" % user_id)
print("------------------------------------------------------------------------------------")

**for** user_item **in** user_items:
    print(user_item)

print("----------------------------------------------------------------------")
print("Recommendation process going on:")
print("----------------------------------------------------------------------")

*#Recommend songs for the user using personalized model*
is_model.recommend(user_id)

输出:

------------------------------------------------------------------------------------
Training data songs for the user userid: 4bd88bfb25263a75bbdd467e74018f4ae570e5df:
------------------------------------------------------------------------------------
Just Lose It - Eminem
Without Me - Eminem
16 Candles - The Crests
Speechless - Lady GaGa
Push It - Salt-N-Pepa
Ghosts 'n' Stuff (Original Instrumental Mix) - Deadmau5
Say My Name - Destiny's Child
My Dad's Gone Crazy - Eminem / Hailie Jade
The Real Slim Shady - Eminem
Somebody To Love - Justin Bieber
Forgive Me - Leona Lewis
Missing You - John Waite
Ya Nada Queda - Kudai
----------------------------------------------------------------------
Recommendation process going on:
----------------------------------------------------------------------
No. of unique songs for the user: 13
no. of unique songs in the training set: 4483
Non zero values in cooccurence_matrix :2097

我们还可以使用我们的基于项目相似性的协作过滤模型来查找与我们数据集中的任何歌曲相似的歌曲:

is_model.get_similar_items(['U Smile - Justin Bieber'])

这个输出

no. of unique songs in the training set: 4483
Non zero values in cooccurence_matrix :271

值得注意的是,这种方法不是深度学习,而是纯粹基于线性代数。

概括地说,在本练习中,我们讨论了两种模型。第一种模型是基于流行度的推荐器,这意味着它不会针对任何用户进行个性化,并且会输出相同的推荐歌曲列表。第二个模型是个性化推荐器,利用基于 相似性的协同过滤模型(即共现矩阵)来基于其他相似用户已经喜欢的歌曲找到用户可能喜欢的歌曲的个性化列表。

接下来我们将讨论如何使用精确召回曲线来量化比较基于流行度的模型和个性化协同过滤模型,从而衡量这两个模型的性能。

为了定量地衡量推荐系统的性能,我们使用了三种不同的指标:精确度、召回率和 F-1 分数

Source: http://aimotion.blogspot.com/2011/05/evaluating-recommender-systems.html

根据 Marcel Caraciolo 的说法, Precision 是“相关的顶级结果的比例,考虑到与您的问题领域相关的一些定义”。在我们的案例中,对于我们问题领域相关的定义是一首歌被听的时长,若干用户都喜欢过这首歌。回忆将“测量所有相关结果在顶部结果中所占的比例”。在我们的例子中,这意味着 precision 试图衡量歌曲与推荐歌曲前十名结果的相关性,而 recall 试图衡量歌曲与所有歌曲的相关性

观察我们的基于流行度的模型和个性化项目相似性模型的精确召回曲线,项目相似性模型在精确召回曲线的某个点上表现更好(即具有更高的召回数和精确度)。

最后一类推荐系统是基于矩阵分解的推荐系统。这种类型的推荐系统使用原始相似矩阵的所谓奇异值分解(SVD)分解矩阵来构建推荐系统。

为了计算 SVD 和建议,我们使用以下代码:

*#constants defining the dimensions of our User Rating Matrix (URM)* MAX_PID = 4 
MAX_UID = 5 *#Compute SVD of the user ratings matrix* **def** computeSVD(urm, K):     
    U, s, Vt = sparsesvd(urm, K)      
    dim = (len(s), len(s))     
    S = np.zeros(dim, dtype=np.float32)     
    **for** i **in** range(0, len(s)):         
        S[i,i] = mt.sqrt(s[i])      
        U = csc_matrix(np.transpose(U), dtype=np.float32)     
        S = csc_matrix(S, dtype=np.float32)     
        Vt = csc_matrix(Vt, dtype=np.float32)          
        **return** U, S, Vt

在这段代码中,U 代表用户向量,S 代表项目向量。Vt 将这两个向量的结合点表示为 2 维空间中的点的集合(即向量)。我们将使用这些向量来衡量一个用户的偏好与另一个用户的偏好之间的距离。

换句话说,我们对矩阵进行矢量化,以计算矩阵之间的距离。为了进一步阐明这一点,我们将通过一个例子来说明。假设我们有一个用户歌曲矩阵如下:

 Song0   Song1   Song2   Song3 
User0   3       1       2       3
User1   4       3       4       3
User2   3       2       1       5
User3   1       6       5       2
User4   0       0       5       0

一旦我们执行 SVD,输出将是向量,测量向量之间的距离给我们建议

#Compute estimated rating for the test user
def computeEstimatedRatings(urm, U, S, Vt, uTest, K, test):
    rightTerm = S*Vt estimatedRatings = np.zeros(shape=(MAX_UID, MAX_PID), dtype=np.float16)
    for userTest in uTest:
        prod = U[userTest, :]*rightTerm
        #we convert the vector to dense format in order to get the     #indices
        #of the movies with the best estimated ratings 
        estimatedRatings[userTest, :] = prod.todense()
        recom = (-estimatedRatings[userTest, :]).argsort()[:250]
    return recom #Used in SVD calculation (number of latent factors)
K=2#Initialize a sample user rating matrix
urm = np.array([[3, 1, 2, 3],[4, 3, 4, 3],[3, 2, 1, 5], [1, 6, 5, 2], [5, 0,0 , 0]])
urm = csc_matrix(urm, dtype=np.float32)#Compute SVD of the input user ratings matrix
U, S, Vt = computeSVD(urm, K)#Test user set as user_id 4 with ratings [0, 0, 5, 0]
uTest = [4]
print("User id for whom recommendations are needed: %d" % uTest[0])#Get estimated rating for test user
print("Predictied ratings:")
uTest_recommended_items = computeEstimatedRatings(urm, U, S, Vt, uTest, K, True)
print(uTest_recommended_items)

将输出:

User id for whom recommendations are needed: 4
Predictied ratings:
[0 3 2 1]

接下来,我们讨论真实世界的例子,Hulu 如何将深度学习应用于协同过滤,以建立其行业领先的推荐系统。在 Hulu,像个性化报头、观察列表和最佳选择等功能都是由协同过滤提供支持的。

Hulu 使用的方法是 CF-NADE。我们举个例子。假设我们有 4 部电影:《变形金刚》、《海绵宝宝》、《忍者神龟》、《星际穿越》,评分分别为 4、2、3、5。在 CF-NADE 中,向量(4,2,3,5)的联合概率通过链规则分解为条件的乘积,条件如下:

1/ The probability that the user gives “Transformers” 4-star conditioned on nothing;2/ The probability that the user gives “SpongeBob” 2-star conditioned on giving “Transformers” 4-star;3/ The probability that the user gives “Teenage Mutant Ninja Turtles” a 3-star conditioned on giving 4-star and 2-star to “Transformers” and “SpongeBob”, respectively;4/ The probability that the user gives “Interstellar” a 5-star conditioned on giving 4-star, 2-star and 3-star to “Transformers”, “SpongeBob” and “Teenage Mutant Ninja Turtles”, respectively;

总而言之,这是基于先前发生的事情的概率链。每个条件由其自己的神经网络建模,并且所有这些神经网络的参数在所有模型之间共享。

来源:

1/Siraj Raval 的深度学习基金会 nano degree(https://www . uda city . com/course/Deep-Learning-nano degree-Foundation-nd 101)

2/【https://www.youtube.com/watch?v=18adykNGhHU

3/https://github.com/llSourcell/recommender_live

4/将深度学习应用于协同过滤:Hulu 如何建立其行业领先地位(http://tech.hulu.com/blog/2016/08/01/cfnade.html)

5/用 Python 实现自己的推荐系统(http://online-dev . Cambridge coding . com/notebooks/eWReNYcAfB/Implementing-your-own-recommender-systems-in-Python-2)

如何在组织中建立影响分析团队

原文:https://towardsdatascience.com/how-to-build-an-analytics-team-for-impact-in-an-organization-21bb05925587?source=collection_archive---------2-----------------------

分析价值生命周期是一个框架,可以帮助分析团队的设计和结构

他们说智慧来自经验,我不得不同意这一点。我花了两年时间建立了一个分析团队,主要目标是对业务产生影响,只是现在我觉得我可以谈谈如何做到这一点。

我花了一些时间来形成一个观点的原因之一是,我们已经试验了一些不同的模型和结构,以便找出哪些最有效。另一个原因是,没有一个人有答案,我们的模型需要时间通过与团队的关键成员和业务中重要的利益相关者进行协商来开发。

也就是说,分析团队在企业或组织中的运作模式现在在我的脑海中已经更加清晰了。它有六个步骤,围绕业务决策形成了一个“生命周期”。这六个步骤告知团队应该如何运作,需要什么技能,团队应该如何构建,以及团队应该具有什么类型的特征和技能。我意识到,许多阅读这篇文章的人不一定能够获得完全遵循这种模型所需的资源,这通常是因为他们所服务的组织太小,不值得这样做,但尽管如此,我相信总体情况仍然是令人感兴趣的。

Diagram of the analytics value lifecycle

步骤 1:了解企业的决策需求

为什么?分析团队无法发挥最佳功能的一个常见原因是缺乏对他们所服务的业务中发生的决策的理解。如果一个分析团队配备了过多的技术或学术人才,这种“概念差距”很可能会影响团队的潜在影响,因为分析通常是由团队成员的个人利益驱动的,而不是违背关键内部客户的要求。

如何?分析团队中至少有一名高级成员应与企业的决策机构保持密切联系,无论是首席财务官、CHRO 还是其他负责做出关键业务决策的委员会或小组。应建立定期论坛,在论坛上交流业务的主要优先事项,并就分析情报的不足之处提供反馈。这将允许形成一个分析议程,并建立最能满足关键内部客户未来需求的数据结构和工具。负责此事的个人最好来自业务本身,具有分析和战略头脑(尽管不一定技术熟练),并有热情和动力在业务内开发分析和分析能力。

步骤 2:构建支持业务决策的方法

为什么?我的老读者可能会厌倦听我说这些,但分析的成功取决于有效的衡量。如今,许多分析团队举步维艰,因为他们无法获得准确的测量数据。在了解业务的决策需求后,要问的第一个问题应该是“我们需要衡量什么才能理解这一点?”。测量可能是一个极其困难的问题。确定适当的衡量标准是数学和统计原则的微妙平衡,同时还要考虑数据系统和数据捕获流程以及人类行为。这通常是一种妥协,但需要有很强的专业知识和判断力才能做好。

如何?确定解决特定业务问题的衡量方法需要分析团队中多种技能的参与。一个测量专家是绝对必要的。例如,如果是人员和技能问题,这可能是一个心理计量学专家;如果是销售或营销问题,这可能是一个营销计量学专家。除了度量专家之外,还需要数据专家的输入,通常是了解交易系统和数据流的工程师、了解如何在进行分析时处理数据的分析专家(如数据科学家),以及第 1 步中能够向技术专家正确解释和解释业务决策需求的人员。

步骤 3:在事务系统中捕获数据,以便跟踪度量

为什么?如果第二步产生的度量是新的,那么通常需要在组织内的原子级别输入新类型的数据。这将需要在系统级别实现,还需要理解所需的规则和逻辑,以及对人工流程所需的调整,以确保准确捕获数据。

如何?数据工程师在任何分析团队中都是一个基础角色。他们将充当与系统管理员和专家的主要联系人,并且他们需要对如何在事务系统中构造字段和输入规则以允许准确和可靠的数据流有重要的发言权。这不是他们唯一的关键角色(见下一步)。

步骤 4:为定期报告和度量分析设计数据

为什么?将交易业务数据转化为对分析和决策有用的衡量标准的过程可能会很费力。围绕这一点的一些仔细思考可以对分析操作的效率和可靠性产生巨大的影响。能否定期(每小时、每天、每周、每月)对事务性数据进行预处理,以创建表或视图,这些表或视图在一定级别上进行聚合,从而实现更快速的分析和洞察?这些视图应该如何设计?应该提供什么样的人口统计或削减?

如何?一个有能力的数据工程师可以在理解数据预处理需求以及实际创建和设计所需的聚合数据源方面创造奇迹。

步骤 5:进行分析以解决业务问题

为什么?这部分显而易见。

如何?这值得更全面的讨论,我将在以后的文章中重点讨论。需要划清界限

  • 定期标准化报告,这需要数据科学、数据工程、可视化、UX 和数据自动化和供应方面的软件开发技能。理想情况下,几乎没有团队时间应该花费在手工交付定期报告上。外部供应商的产品可能有助于填补这方面的空白,但我的经验是,没有一个供应商的工具能够满足这里的全部需求。最好的团队会为自己设计这个。
  • 即席分析,要求商业智能专业人员了解组织的数据系统,并能够使用它们来满足来自商业客户的特定的、非标准的问题。
  • 高级分析,要求深入了解高级统计方法,熟练掌握高级数据科学工具,以便使用这些高级方法分析和处理数据。

步骤 6:为企业消费者翻译分析

为什么?分析在业务和组织中没有影响的主要原因之一是结果没有被很好地理解,并且由于缺乏对结果的有效沟通,经常得出明显错误的结论。为了在组织中产生影响,分析团队需要能够利用有助于以业务领导者可以理解的方式清晰地翻译结果的技能,其中许多人可能不具备为自己翻译的知识或技能。当采用先进的分析方法时,这一点尤为重要。

如何?**翻译是高效分析团队中的关键角色。翻译人员了解组织战略和决策,有很强的解决问题的能力,对分析有热情和兴趣,并有客户服务的心态。分析翻译是目前最难找到的职位,因为这个角色太新了,还没有被很好地理解。根据我的经验,最有效和最有能力的翻译都来自于业务本身。翻译人员提供全面的领导和指导,并与技术人员(数据科学、测量、工程、可视化和设计)合作,找到满足客户需求的最佳解决方案。翻译人员在业务中保持长期的客户关系,以便根据需求的变化调整分析方法。

这是我第一次阐述分析价值生命周期,毫无疑问,它将进一步发展,所以请将它视为一项正在进行的工作。在接下来的几周和几个月里,我还打算花更多的时间来充实生命周期某些部分的细节,以及有效地为这样的行动配备人员所需的角色和个人简介。

最初我是一名纯粹的数学家,后来我成为了一名心理计量学家和数据科学家。我热衷于将所有这些学科的严谨性应用到复杂的人的问题上。我也是一个编码极客和日本 RPG 的超级粉丝。在LinkedInTwitter上找我。

如何用你自己的短信建立一个简单、快速、基本上无用的聊天机器人

原文:https://towardsdatascience.com/how-to-build-an-easy-quick-and-essentially-useless-chatbot-using-your-own-text-messages-f2cb8b84c11d?source=collection_archive---------7-----------------------

使用 elasticsearch 或 python 中的 Doc2Vec 模型来构建一个简单的、愚蠢的聊天机器人,你可以使用你的文本消息与之交谈(iPhone/macOS)

Source

*目前特定于 iPhone 和 macOS

对于那些熟悉数据科学的人来说,该领域最大的挑战之一是获取不差的训练数据。拥有可靠的“基础事实”例子是好的机器学习的燃料。特别是对于像自然语言处理(NLP)这样的任务,机器需要大量数据来学习良好的单词上下文、标签或一般的“理解”。

嗯,作为人类,我们一直在生成训练数据——对于一个对话机器人来说,还有什么比你自己的短信更好的训练数据呢?在这篇文章中,我将向你展示如何使用 python 和你自己的文本消息来构建一个非常简单、容易并且不太成功的聊天机器人。

更复杂和先进的聊天机器人可能有一个架构,涉及实体识别,意图识别,某种定制的响应数据库,一些 LSTMs 撒在那里等等…但我不会去任何一个。如果你想从头开始构建一个面向商业的聊天机器人来提供好的信息和回答问题,试试类似拉莎·NLU的东西。如果你只是想找点乐子,那就继续读吧!

重要——对你的文本进行分析很有趣,但要注意其中的信息。我们将使用的模型将永远可以访问来自您的朋友、醉酒之夜、爱人、杀手、父母、毒贩等的信息。不要将您的模型、数据或敏感结果发布到任何地方,以便有人可以访问您的信息。这不安全,而且对你的朋友来说这是一个愚蠢的举动。记住这一点,让我们开始深入研究。

这篇文章有两条途径

因此,有很多简单的方法来制作一个无用的聊天机器人,但你应该用哪种方法取决于你的数据。我将概述两种方法,并随时尝试这两种方法;然而,你选择哪一个取决于你拥有的短信数据的。在一般的准备步骤之后,帖子将会被拆分。

  1. Elasticsearch(基本上是 TF-IDF)——如果你没有太多数据就选择这个选项。这种方法更加基于关键字,并且不需要机器学习上下文
  2. Doc2Vec —如果您有很多数据,请选择此选项。这个模型需要大量的数据来学习单词,所以如果没有很多文本,它就不能很好地工作。

作为参考,我有大约 100k 的短信,第二个选项仍然不起作用太好了,但请随意查看哪个最适合您。他们都很有趣,看看你能得到什么。

一般准备

首先,你应该已经安装了 python(并且肯定有一些使用它的经验)。如果你没有安装 anaconda ,我推荐你安装,但是我不会介绍任何基础知识。我将在一个 jupyter 笔记本(一个让你运行代码块的 python 笔记本)中工作,但是你可以做任何你喜欢的事情。我将在 Python 2 中工作(但在 3 中应该也可以)。

在这篇文章的相应部分,我将详细介绍每个选项的包。您的 python 版本应该已经安装了我们一开始需要的sqlite3pandas包。

在我们获取数据之前,只需将你的 iPhone 插入你的 Mac,这样就可以备份到最新的数据。你需要尽可能多的数据来改进机器人。完成所有这些后,让我们开始编码。首先让我们创建一个项目目录。我是这样做的:

mkdir -p ~/Documents/textbot

然后,我们接下来需要将数据放在一个更容易的地方。你电脑上的位置应该和我的一样。你所有备份的 iPhone 数据都应该在~/Library/Application Support/MobileSync/Backup。知道了这一点,让我们将数据库文件和我们的文本复制到一个不那么荒谬的位置,而不是你在下面看到的那条可怕的路径。在您的终端中键入:

cp ~/Library/Application\ Support/MobileSync/Backup/feda86be0cbd2b3150fc151e8b03289e3c117213/3d/3d0d7e5fb2ce288813306e4d4636395e047a3d28 ~/Documents/textbot

最后但同样重要的是,让我们进入我们的项目目录并启动 jupyter(或者 python shell,如果您愿意的话)。一旦 jupyter 出现,创建一个新的笔记本。

cd ~/Documents/textbot
jupyter notebook

准备数据

好极了,现在我们要开始学习 python 中有趣的部分了。让我们导入前两个包。sqlite3将让我们从数据库文件中读取数据,而pandas将让我们将其加载到一个数据帧中,以便于操作。

import pandas as pd
import sqlite3

这里是我们读入数据的地方。你必须指定绝对路径否则无法工作,所以不能使用~。在下面的代码中,将kylegallatin改为您的主目录的名称。如果你不知道它是什么,打开一个终端,输入~

#replace kylegallatin with your home directory
path = '''/Users/kylegallatin/Documents/textbot/3d0d7e5fb2ce288813306e4d4636395e047a3d28'''db = sqlite3.connect(path)

现在,我们可以使用一些基本的 SQL 命令来获取我们需要的数据,并将其加载到 pandas 中进行处理。我们只需要几列,所以我已经指定了它们是什么。text是信息本身,handle_id是你用整数格式发短信的人,is_from_me是一个二进制标志——当它是 1 时,你发送了文本,如果是 0,那么那一行的handle_id发送了文本,最后date是文本发送的日期。如果你想对你的社交生活方式做更深入的分析,请查看你现有的其他专栏。

cursor = db.cursor()
result = cursor.execute('''SELECT text, handle_id, is_from_me, date FROM message''')#load results into a df
df = pd.DataFrame(result.fetchall())
df.columns = ['text','handle_id','is_from_me','date']

并检查您是否有:

您应该会看到已备份的最早文本。它应该已经按时间顺序排列了,这是下一部分所必需的。如果你不相信,只需运行df = df.sort_values(by='date')来确定。要查看您有多少条消息,您可以运行len(df)

接下来,我们需要开始考虑训练数据。我们这里有大量的消息,但没有真正以对话训练数据的形式出现——它们只是按时间顺序排列的。我们这篇文章的目标是获得一个由两列组成的数据帧:textresponse,这样我们的聊天机器人就有了可以“学习”的例子。

我们不仅需要按人(或handle_id)对对话进行分组,更仔细地观察数据会发现,我们可以连续收到同一个人的多条短信,这使得我们很难区分哪些应该是短信,哪些应该是回复。我们需要连接所有同时发生的文本,然后将每个df['text'][i]text分配给它的responsedf['text'][i+1]

下面不是我写过的最晦涩的东西,但是它运行得够快了。请随时提出改进意见。

##remove the nulls
df.dropna(subset = ['text'], inplace=True)##helper function
def make_sentences(series):
    return '. '.join(series)##initiliaze empty df
train_data = pd.DataFrame(columns = ['text','response'])##iterate through each convo
for person in pd.unique(df['handle_id']):
    conversation = df[df['handle_id'] == person]
    grouped = (conversation.groupby(conversation.is_from_me.diff()
               .ne(0).cumsum(), as_index=False)
               .agg({'text':make_sentences,'is_from_me':'first',
               'handle_id':'first', 'date':'first'}))

    ##match up texts with responses
    tmp = pd.DataFrame({'text':list(conversation['text'][0:-1]),
                  'response':list(conversation['text'][1:])})

    ##append to our training df
    train_data = train_data.append(tmp[['text','response']], 
                                   ignore_index=True)

最后添加最简单的预处理:

train_data['text'] = train_data['text'].apply(lambda x: x.lower())
train_data['response'] = train_data['response'].apply(lambda x: x.lower())

现在你可能在想“伙计,你忽略了一大堆不同的情况”——你可能是对的。群聊呢?你如何定义一次谈话的开始和结束?这里有很多事情需要考虑,在本教程中我将忽略所有这些。这是一个快速而肮脏的聊天机器人教程,而不是“我必须编写 100 万条 if 语句来创建完美的训练数据”。如果有人想更深入地研究这个问题,我就不必说了,请说吧。

撇开这个障碍不谈,我们现在有了类似训练数据的东西。对于每个handle_id,我们现在将每个text映射到一个response,然后每个response成为下一个text。有了这种格式的数据,我们现在可以建立一种方法,将我们要对机器人说的话映射回半适当的响应。

选项 1:让 Elasticsearch 为您做所有事情

选项 1 在我们的text列中使用基于关键字的搜索,使用我们“发送”给机器人的任何内容。通过将我们的文本与其他文本进行比较,我们可以尝试发送适当的响应。

弹性搜索和 TF-IDF 只需…3 秒钟

Elasticsearch 是一个可扩展的搜索平台,它使用类似于 TF-IDF 的算法,该算法是词频逆文档频率的标准。

Source

本质上,它是一个简单的函数,经常在搜索/相似性空间中使用,根据关键字定位文档。它也不太强调频繁出现的单词。例如,因为单词“the”出现在如此多的文本中,我们不希望它被认为是我们搜索查询的重要部分。TF-IDF 在将您的查询与文档进行比较时会考虑这一点。对于它的基本概述,只需查看维基百科。

[Source](https://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&cad=rja&uact=8&ved=2ahUKEwic6L3k0vTbAhVOwFkKHZZKD7YQjRx6BAgBEAU&url=https%3A%2F%2Fdeeplearning4j.org%2Fbagofwords-tf-idf&psig=AOvVaw3AB8Lk_MHOxMWKOwoYSbRH&ust=1530216484519950)

我们运行的实际比较将基于余弦相似性。由于 TF-IDF 将对我们的文本进行矢量化,因此我们将它与数据中的“最相似”text进行匹配的方式需要基于这一指标。它帮助我们找到在任何大小的向量空间中最接近的向量来表示我们的文档。

选项 1 准备

我们也可以使用类似于sklearn的包来实现 TF-IDF,但是对于我们的目的来说,elastic 在设置、使用和扩展方面更快/更容易。我们需要两样东西 elasticsearch 本身和它的客户。要安装前者,我们将使用软件包管理器自制软件。如果你还没有,从这里的安装。

然后打开一个终端:

brew install elasticsearch
pip install elasticsearch

现在你已经安装了 elasticsearch,你只需要启动它。自制软件应该已经把它添加到你的路径中了。这个终端命令应该在端口 9200 上启动 elastic。

elasticsearch

应该就是这样!现在我们可以回到 python 笔记本了。

索引和搜索

为了索引并使我们的数据具有弹性,我们可以使用下面的代码。我们首先导入我们的包,然后创建我们的 python 客户机的一个实例。最后,我们用来将数据上传到 elastic 的函数需要字典格式,所以我们将数据帧转换成字典。

我不会深入讨论这个代码/客户端和 elasticsearch,但是在这里我们所做的只是对我们的数据进行了一点处理,并在我们的 elasticsearch 实例上创建了一个名为textbot的索引,我们现在可以查询它的信息。

from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulkes = Elasticsearch(['localhost:9200'])texts_dict = train_data.to_dict(orient='records')
bulk(es, texts_dict, index='textbot', doc_type='clue', raise_on_error=True)

和 dddd 基本就是这样!现在唯一要做的就是创建一个函数来查询我们的数据。

选项 1 聊天机器人

下面就是了。我有一个简单的函数,运行一个连续的循环。每次,它都提示用户输入,在我们的数据中搜索最相关的text信息,然后从同一行返回response。如果响应为quit(),程序停止。我们从搜索中得到的response变量是由被称为查询 DSL 的语言生成的。你可以用它做很多可笑的事情,但是我还是会根据我们的需要坚持做最基本的事情。

response将是一个 json,包含一堆信息,但我们只想要一个值,所以我们只需要获取并打印它!我还引入了一个可以切换的randomness变量。这样做的目的是,你不必每次给你的机器人发送“文本”都得到相同的结果,因为结果是按顺序返回的。如果在索引itext记录中没有与您发送的查询相匹配的相关内容,那么您将只得到“idk”。

from random import randint
randomness = 1def chatbot():
    quit=False
    while quit== False:
        text = str(raw_input('Me: '))
        ##an optional quit command
        if text == 'quit()':
            quit=True
        else:
            response = es.search(index='textbot', doc_type='clue', body={ "query": {
                "match": {
                    "text":text
                }
            }})
            try:
                ##introduce a bit of randomness into the response 
                i = randint(0,randomness)
                print("Chabot: %s" % response['hits']['hits'][i]['_source']['response'])
            except:
                print("Chatbot: idk")

Lit,现在你可以试一试了。

chatbot()

下面是我在我的机器人上输入一些东西的例子,所以你可以得到我所得到的东西,可以随意使用代码的随机性或其他部分来改进你的查询。

选项 2:训练您自己的上下文 Doc2Vec 模型

更有趣但不太可靠的选择基本上基于两种模型:word2vec 和 doc2vec。

word2vec 和 doc2vec 只需…5 秒钟

要理解 doc2vec,首先需要看一下 word2vec。最初由谷歌的托马斯·米科洛夫领导的研究团队创建,这是一个试图学习单词上下文的模型。对于那些熟悉神经网络的人来说,其架构如下所示。

Source

它是一个浅层神经网络,以文本作为训练数据。本质上,它通过迭代试图预测一个单词子集出现在给定单词附近的概率,或者一个单词出现在给定的一个相邻单词窗口中的概率(取决于您使用的架构)。每一次尝试,你都要更新隐藏层中每个单词的权重。最后,你丢弃预测,但保留隐藏层的权重。给定足够的文本输入,这些权重应该在某种程度上代表单词的上下文。相似的单词应该具有相似的权重向量,然后可以通过余弦相似度进行比较。想了解更多关于 word2vec 的信息,这位老兄有一篇很棒的文章。

Doc2vec 非常类似,你只是有另一个输入,即句子或完整的文本块,而不是单词。此外,不像 word2vec 那样丢弃谓词,这里我们可以选择评估标签。在 word2vec 中,每个单词都已经是它自己的实体,所以不需要这样做。在 doc2vec 中,我们有包含多个实体的句子或段落,所以我们可以给这些组贴上标签进行分类。

就像选项 1 一样,我们这样做的方式是余弦相似性。由于 doc2vec 将为我们发送的 bot 文本提供权重,并对其进行矢量化,因此我们将它与数据中的“最相似”text进行匹配的方式需要基于这一度量。它帮助我们找到在任何大小的向量空间中最接近的向量来表示我们的文档。下图应该完美地解释了所有技术上的东西。

Source

要阅读更多关于 doc2vec 的内容,请查看本文。

选项 2 准备

让数学和理论见鬼去吧!让我们编码这个东西。

我们将使用gensim,这是一个很容易使用最初由 google 发布的 word2vec 和 doc2vec 包的包。它很容易通过命令行上的pip安装。

pip install gensim

训练你自己的 Doc2Vec 模型

首先,我们需要定义如何将数据输入到模型中。到目前为止,我甚至还没有意识到我正在使用的内存,因为我只有 10 万条文本,而且真的没有那么多数据。然而,在这里,通过迭代器一次一句地将数据输入模型是一种很好的做法。

import gensim
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
from gensim.utils import simple_preprocess
import multiprocessing
import osclass MyTexts(object):
    def __iter__(self):
        for i in range(len(train_data)):
            yield TaggedDocument(words=simple_preprocess(train_data['text'][i]), tags=[i])

simple_preprocess函数只是做一些简单的事情,比如将文本小写以使其标准化。这里最关键的是标签——我将其设置为[i],而不是实际的response。虽然你可以做后者,这也是更友好的内存,所以我们将继续这样做,并在稍后处理响应。

该训练模型了!

%%timeassert gensim.models.doc2vec.FAST_VERSION > -1print('Doin cool math stuff...')
cores = multiprocessing.cpu_count()texts = MyTexts()
doc2vec_model = Doc2Vec(size=200, workers=cores)
doc2vec_model.build_vocab(texts)
doc2vec_model.train(texts, total_examples=doc2vec_model.corpus_count, epochs=15)if not os.path.exists('models'):
    os.makedirs('models')
    doc2vec_model.save('models/doc2vec.model')
else:
    doc2vec_model.save('models/doc2vec.model')
print('And we did it!')

%%timejupyter 细胞只是时间,所以如果你在壳或其他东西里,就把它取出来。断言语句确保我们有 c 编译器,以便它快速训练,并且设置模型在所有内核上训练确保它甚至更快。然后,我们用大多数默认参数初始化我们的模型。200 只是我们将得到的单词向量的大小——您可以随意更改所有其他调优参数!我们用build_vocab函数让 doc2vec 访问我们的单词库,然后在我们的texts上训练模型 15 个时期或迭代。os包只是让我们创建一个目录来保存我们的模型供以后使用。

就是这样!鉴于我的数据/计算机的大小,我的只花了 2 分钟,我想你的也差不多。但是——我们怎么知道 doc2vec 做了它应该做的事情?

健全性检查

word2vec 和 doc2vec 都带有一个方便的余弦相似度函数,用于检查我们的 200 维空间中单词之间的“距离”。让我们检查一两个词。

doc2vec_model.most_similar(['hey'])[0:2]

我从我的短信中得到什么?

[(u'hi', 0.588394045829773), (u'yo', 0.5450516939163208)]

毒品。如果你的结果看起来不一样,不要气馁——没有足够的训练数据,你一定会看到一些奇怪的结果。老实说,看看你的模型从你和你朋友的对话中学到了什么,这很有趣。

doc2vec_model.most_similar(['drinks'])[0:2]

给了我:

[(u'beers', 0.8393490314483643), (u'lunch', 0.736896276473999)]

看起来我有在工作时间喝酒的倾向。更准确地说,看起来“饮料”、“啤酒”和“午餐”在我的对话中都是类似的用法。这是有道理的,考虑到我可能会说“让我们去喝杯啤酒”,就像我说“让我们去吃顿午饭”一样。你拥有的数据越多,这些词向量就越有可能彼此远离,更多的同义词就会取代它们的位置。

选项 2 聊天机器人

在这一点上,我们是在容易的部分。我们只需要创建一个简单的函数,它接受一个输入,将其标记化,得到最相似的text,并返回适当的response。由于我们的模型可能还没有看到我们可能扔给它的所有输入,我们将使用infer_vector函数向我们的聊天机器人矢量化我们的文本。

##quick and dirty chatbot function
def chatbot():
    quit=False
    while quit == False:
        text = str(raw_input('Me: '))
        ##an optional quit command
        if text == 'quit()':
            quit=True
        else:
            tokens = text.split()
            ##infer vector for text the model may not have seen
            new_vector = doc2vec_model.infer_vector(tokens)
            ##find the most similar [i] tags
            index = doc2vec_model.docvecs.most_similar([new_vector], topn = 10)
            print('Chatbot: ' + train_data.iloc[index[0][0],1])
            print('\n')

现在运行你的聊天机器人,和它说话!根据你的对话,看看你得到的所有奇怪的回答。

chatbot()

仅此而已!如果我错过了什么,或者你有什么意见,尽管讨厌。这是我的第一个帖子,还在琢磨。希望你喜欢。

对 Reddit 帖子内容进行分类的引擎:自然语言处理的应用

原文:https://towardsdatascience.com/how-to-build-an-engine-that-classifies-the-content-of-a-reddit-post-an-application-of-natural-6306cfe94742?source=collection_archive---------9-----------------------

“white text on black background” by Lauren Peng on Unsplash

在我发表了关于自然语言处理和决策树的博文之后,我认为谈论 NLP 和随机森林的具体应用是个好主意,特别是关于我最近参与的一个项目。

1.定义问题

本主题的目的是从两个不同的子编辑中收集帖子,并且仅通过分析帖子的文本,建立一个能够对哪些帖子属于哪个子编辑进行分类的模型。我决定挑战自己,挑选两个彼此没有太大区别(但也很搞笑)的子主题:淋浴思想和深刻的哲学。想想看:如果你分析科学与艺术,这两个子主题的关键词可能会非常不同,模型将很容易识别哪个帖子属于哪个页面。然而,淋浴的想法和深刻的哲学之间有很多重叠。为了让你有个概念,这里有两个这样的帖子的例子:

“你永远不会意识到你咀嚼食物用了多大的力量,直到你咬下嘴唇。”

“如果我克隆自己,它杀了我,这是谋杀还是自杀?我需要在周二之前知道。”

你能猜出哪个帖子属于哪个子编辑吗?

除了算法本身,这个项目还包含另一个对数据科学家来说常见的巨大挑战:收集数据!没错,这次没有。csv 文件与一起工作。

2.收集数据

定义问题后,我们数据科学流程的下一步是收集数据!足够幸运的是,一旦我们有了想要抓取的 Reddit 页面的 url,如果我们添加。json 在 url 的末尾,我们将可以访问到 json 格式下的页面内容。对于那些不熟悉这种格式的人来说,它类似于 Python 字典。开始的时候可能会有点乱,但是经过一些尝试和错误,你可以找出关键,提取你需要的数据是相当容易的!

每次我们 ping Reddit 服务器,我们将可以访问 25 个帖子,但这当然远远不足以解决我们的问题,这意味着我们必须 ping 服务器几次,以便收集相关数量的帖子。我们还必须对代码进行一些更改,以便正确地执行此操作。我们必须改变我们的User-agent并改变一个名为after的参数,这样我们就不会每次尝试都刮到相同的 25 个帖子!这样,我们就可以在每次获取新数据时,向下移动页面,收集不同的 Reddit 帖子。的。Reddit 给我们的 json 文件包含了很多关于页面的信息,经过初步探索,我注意到实际的帖子包含在[data][children]键下,如下面代码的第 41 行所示。

上面的代码从 Reddit 页面返回一个子对象列表。然而,为了找到它,必须进行一些数据探索和清理,然后确保每个帖子的内容不会分成两个字段。下面的 Python 代码将查找并清理数据。

这是淋浴思想 subreddit 的前几行。

现在,我们将不得不对第二个子编辑页重新做一遍,并将这些观察结果附加到我们的数据帧中。一旦我们收集了足够的数据(就我而言,超过 2000 篇帖子),就该进行下一步了!

3.清理和准备数据

幸运的是,我提取的数据非常干净。然而,我想最终将自然语言处理(NLP)技术应用于这些数据。在此之前,我通过删除标点符号、停用词和最有可能是网页中 unicode 残余的字符来清理数据。我利用 scikit-learn 的feature_extraction模块来帮助清理这些数据。还得定义我的 Y 变量,建模时要预测的变量。我选择“淋浴思想”的值为 1,选择“深层哲学”的值为 0。

当把文本转换成计算机可以解释的变量时,我们通常会做一些叫做“矢量化”的事情。一种简单的矢量器称为“计数矢量器”。这是一个频率计数器,计算一个单词在帖子中出现的次数。例如,如果一篇文章包含单词“thinking”三次,那么我的 CountVectorizer 将创建一个名为“thinking”的变量,这篇文章在该列中的值为 3。对于每一篇帖子,该算法会计算单词“thinking”被看到的次数,并将该数字放入该列。因此,“思考”列将是一个大的数字列表,它计算每个帖子中出现“思考”的次数。对于我的项目,我使用了一个不同的矢量器,叫做“TFIDFVectorizer”它以稍微复杂一点的方式统计我们的单词:在这种情况下,矢量器不仅统计一个单词在每个帖子中出现的次数,还考虑该单词在整个语料库(即帖子集合)中的重要性。实际上,我尝试了这两种方法,发现我的模型在 TFIDFVectorizer 和 CountVectorizer 上的表现大致相同。

现在我们有了训练和测试数据,是时候建模了!

4.建模

当完成一个二元分类问题时,有许多方法可以衡量它的表现。可视化这个模型性能的一种方法是通过混淆矩阵,它将显示我的模型生成了多少真阳性、真阴性、假阳性和假阴性。

在我的模型中:

  • 一个真正的肯定是一个预测来自淋浴思想子编辑的帖子,并且确实来自淋浴思想子编辑。
  • 一个真正的否定是一个预测来自深层哲学子编辑的帖子,并且确实来自深层哲学子编辑。
  • 误报是一个预测来自我的淋浴思想子编辑的帖子,但实际上来自深层哲学子编辑。
  • 假阴性是一个预测来自深层哲学子编辑的帖子,但实际上来自淋浴思想子编辑。

在这种情况下,假阳性和假阴性一样糟糕。因为它们同样糟糕,所以我想建立一个模型,使我的准确率尽可能高。

在训练和测试不同的模型之前,我定义了一个函数来打印我的测试集的分类矩阵,并将真/假阳性/阴性分配给变量。由于我计划尝试几个不同的模型,这个函数在评估每个模型的表现时就派上了用场!

我测试了逻辑回归模型、高斯朴素贝叶斯模型、多项式朴素贝叶斯模型和随机森林模型。当根据我的测试集进行测量时,随机森林模型显示出最少的过度拟合和最好的整体性能。然后,我决定在各种超参数上实现 GridSearch,看看能否提高基本随机森林模型的性能。

。有了这两个非常密切相关的子数据集,我的最佳随机森林模型在测试集上有 84%的准确率。(对于一个刚学了六周的人来说,这已经不错了!).是的,它花了很多的调整,这个模型仍然稍微超出了我的训练数据,但这与我开始的地方相比绝对是一个进步。

下面,您将看到一个功能重要性图。这个图直观地显示了每个术语在分类一篇文章所属的子主题中的重要性。“深刻的”和“深刻的思考”是两个最重要的术语,但是“可能”和“意思”在预测某件事是哲学的还是只是一个随机的想法方面出奇的好!

Top 20 most important features of the Random Forest Classifier

注意:作为一个随机森林分类器,Importance被定义为集合中所有树的平均节点杂质(通过到达该节点的概率加权)的总减少量。如果你想了解更多关于节点杂质的知识,可以看看我关于决策树的博文。

5.回答问题

任务完成了!我不确定为什么一家公司想要实现这种预测子数据集的特定模型,但是这种类型的模型在现实世界中有很多应用。例如,电子邮件服务想要检测垃圾邮件,或者公司可能想要尝试检测垃圾评论。这个问题可以用这种方法解决。如果我在一家试图检测垃圾邮件和合法评论的公司工作,我会和一个团队一起将这个模型投入生产并自动过滤评论。

请随意查看:

我的其他中帖。

我的 LinkedIn 个人资料。

如何用 API 构建 FAQ 聊天机器人?使用 Node.js 和 PHP 的人工智能

原文:https://towardsdatascience.com/how-to-build-an-faq-chatbot-with-api-ai-using-node-js-a802aff53e6a?source=collection_archive---------1-----------------------

在通用聊天中,我们实现了一个聊天机器人,任何人都可以毫不费力地训练它。逻辑很简单;只要给它你的问题和答案,机器人就会回复任何提出类似问题的顾客。

在本文中,我将向您展示我们是如何做到这一点的,这样您也可以这样做。

框架的选择

首先,我测试了许多不同的机器学习框架——Wit。AI,微软认知服务,我瞄了一眼 Luis……对我来说,原来是 API。AI 是正确的选择。它是完全免费的,有很好的响应率,它有一个很好的开发用户界面,并且很容易设置、开始使用和扩展。

我不打算进行 Api.ai 开发,因为那里的文档已经很棒了。Node.js SDK 只有一个缺点;涉及开发人员令牌的方法都没有实现。所以,我创造了我自己的叉子来解决这个问题。随意克隆和使用它。

独特的问题和解决方案

当您构建一个将被许多用户使用的服务时,您希望确保信息不会重叠。例如,一个用户可能会提出一个问题,比如“哪个 ML 框架是最好的?”并将答案设置为“Api.ai ”,而另一个用户可能会将“Wit.ai”作为答案。机器人应该理解哪个用户正在被询问,并返回相应的答案。

为了解决这个问题,我们使用了上下文变量——通过定义上下文,我们可以在一个单独的线程上为每个用户和她的客户端分离答案。

让用户创建他们自己的常见问题

Api.ai 非常聪明——将它变成一个对话代理只是添加新的意图并定义机器人的响应。您还可以通过从 Api.ai 库中导入现成的模板来丰富体验,这会让您在自己的领域中占得先机。

要创建新的意图,你需要我之前提到的 github fork 。

在我们开始之前还有一个问题。聊天机器人不会一直准确无误。当这种情况发生时,我们需要一种后退的方法。

在通用聊天中,我们用两种方式来处理这个问题:

  1. 对于每个回答,我们允许访问者升级到一个实时操作员。当访问者这样做时,我们也会记录他们提出的问题,以便以后可以将正确答案添加到数据库中
  2. 有时 Api.ai 找不到答案,在这种情况下,它会返回“input.unknown”结果。这是另一个需要注意和创造问题的地方

所以,现在我们有了所有的原料;

  • Api.ai 作为机器学习框架
  • 可以正确创建新意图的 Node.js 分支
  • 如何构建它的路线图

让我们开始吧。我不会详细讨论你在网上其他地方可以找到的问题,但是我会向你展示我们上面讨论的两个主要问题:使用上下文调用和创建意图。

在上下文中调用

我们将创建这个方法来查询 Api.ai:

函数 ask(text,options){
let apiaiRequest = apiai . text request(text,options);

apiaiRequest.on('response ',(response)= > { console . log(response);})

apiaiRequest.on('error ',(error)= > { console . log(error);});

apiairequest . end();
}

然后,您可以这样查询它:

询问('某个问题',{
sessionId:'某个会话的某个唯一 Id ',
上下文:[{名称:'用户 1' }]
}

仅此而已。用更有用的代码替换 console.log 代码。在 github 中,我展示了如何使用 promises 来重写上述内容,以获得更干净的替代方案。

创造新的意图

要创建新的意图,请使用 POST 方法。同样,所有这些都是有据可查的,所以我们只讨论新的内容:

函数 create intent(options){
return new Promise((resolve,reject)=>{
let request = app . intentpostrequest(options);

request.on('response ',(response)= > { return resolve(response);});

request.on('error ',(error)= > { return reject(error);});

request . end();
})
}

现在,像这样调用它:

var opts = {"name": " ",
"auto": true,
"templates": [" <新问题> " ],
"contexts": [' <上下文> ' ],
" user says ":[
{ " data ":[{ " text ":<新问题> "} ]," isTemplate": false," count": 0 }],

创建意图(opts)

需要注意的重要事项:

  • 不要忘记auto:true——否则你将无法从机器学习的魔力中获益
  • 你可能已经注意到我用了几次“新问题”——没关系,它很有效
  • 您还注意到,我们在这里包含了上下文—保证问题和答案被保存起来,并分别提供给每个客户

奖金;用 PHP SDK 创建意图

如果你已经建立了一个网站来管理这些东西,你可以使用 PHP SDK。同样,最初的那个也不支持创建意图,所以我们在这个分支中添加了它。Readme.md 中有一个不言自明的例子,所以我不会在这里打扰你。

结论

现代机器学习框架使得建立对话代理变得非常容易——你刚刚在不到 4 分钟的时间里见证了一个对话代理。只是一定要引入适当的回退,以便在遇到更难的查询时拯救机器人的皮肤。

如何为数据集构建图像重复查找器

原文:https://towardsdatascience.com/how-to-build-an-image-duplicate-finder-f8714ddca9d2?source=collection_archive---------12-----------------------

借助神经网络隐藏层执行图像相似性分析

This is a duplicate found by the algorithm

当你从网上下载图片时,你通常会发现有噪音的数据。此外,流行的图片到处都是。一个接一个地查看它们并试图找到重复项来清理数据集是很乏味的。

考虑到这个问题,我构建了一个重复查找器来为您查找重复项,因此您只需选择是否要删除它们。你可以在 fastai 库中找到代码。在这篇文章中,我将解释我是如何构建这个工具的。

步骤 1:获取激活

我们通常使用 CNN 对图像进行分类,我们只对网络末端 softmax 的输出感兴趣,它会告诉我们网络认为我们图像的标签是什么。在这种情况下,我们将比较网络的内层,希望网络学习的一些特征有助于找到相似的图像。为了实现这一点,我利用了 fastai 库中强大的 钩子 功能,它允许我们保存网络中任何子层的激活。

hook = hook_output(learn.model[0][7][2])

我使用的激活是 Resnet 架构的最后一个卷积块的输出,因为我注意到它们在经验上工作得更好。

第二步:合并

您可能知道,CNN 中的隐藏层有四个维度:批量大小、特征数量、高度和宽度。让我们假设我们正在谈论一个特定的图像,或者 bs=1。例如,在 Resnet 50 的情况下,最后一层的输出将具有维度( 1,512,7,7)。由于这里的维数非常高,计算相似度将非常耗时,这对用户来说是一种痛苦。这个问题的答案是用池。我们将汇集每一个 7x7 矩阵,从而得到一个维度为的张量(1,512,pool_dim,pool_dim)。

我使用的池函数是 AdaptiveConcatPooling(自适应平均池和自适应最大池连接在一起),我使用的池维数是 4,因为我发现它是速度和性能的良好组合。

第三步:展平

我们用一个四维张量结束了最后一步。然而,为了计算不同例子之间的相似性,我们需要一维张量(向量)。我们将展平每个图像的激活,以获得大小为 pool_dim x pool_dim x 512 的向量,并将每个图像的向量连接成一个具有维度的矩阵( n_exs,vector_dim )。现在我们有了每个 n_exs 图像的特征向量。是时候计算相似度了!

def get_actns(learn:Learner, dl:DataLoader, hook:Hook, pool=AdaptiveConcatPool2d, pool_dim:int=4, train:bool=True):
"""Gets the activations at the layer specified by `hook`, 
   applies `pool` of dim `pool_dim` and concatenates.""" pool = pool(pool_dim) 

    actns = []
    learn.model.eval()
    with torch.no_grad():
        for i,(xb,yb) in enumerate(dl):
            learn.model(xb)
            actns.append((hook.stored).cpu())

    return pool(torch.cat(actns)).view(len(dl.x), -1)

第四步:计算相似度

为了计算每个特征向量之间的相似度,我们将使用余弦相似度函数。请注意,如果我们将每个向量与其他向量相结合,所有的相似性都会被计算两次。还要注意,如果我们计算一个向量与其自身的相似性,相似性的度量显然是最高的。因此,对于我们的相似性矩阵,我们将用零替换对角线和右上部分。

def comb_similarity(t1: torch.Tensor, t2: torch.Tensor, sim_func=nn.CosineSimilarity(dim=0)):
    """Computes the similarity function `sim_func` between each embedding
       of `t1` and `t2` matrices.
       t1` and `t2` should have dimensions [n_embeddings, n_features]."""

    self_sim = False
    if torch.equal(t1, t2): self_sim = True

    sims = np.zeros((t1.shape[0], t2.shape[0]))
    for idx1 in range(t1.shape[0]):
        for idx2 in range(t2.shape[0]):
            if not self_sim or idx1>idx2:
                ex1 = t1[idx1,:]
                ex2 = t2[idx2,:]
                sims[idx1][idx2] = sim_func(ex1,ex2)

    return sims

第五步:结果

看看我们的方法行不行!让我们看看我们数据集中最相似的图像,看看我们是否能找出一些重复的(我在这里贴了一些截图,更多请访问我的 repo )。我用来测试算法的数据集是牛津-IIIT 宠物数据集,有 37 种狗和猫。

Perfect duplicates. This image was included 5 times in the dataset.

Duplicates (one has a signature)

Similar but not duplicates

我还用 CIFAR10 测试了该算法,cifar 10 是计算机视觉中一个著名的数据集,看我能否找到一些重复的数据。这些是我发现的一些例子:

Perfect duplicate

Nearly a duplicate truck but with different logos

Not a duplicate, more like data augmentation

我还运行了 relabeler 小部件,这里有一个额外的有趣发现:

Not a truck

一旦我们有了网络对复制品的建议,我们该怎么处理它们呢?嗯,我们应该选择那些实际上是重复的,并从我们的数据集中删除它们,因为有重复会导致网络对这些图像给予太多的重视。怎样才能轻松删除重复?有了 fastai 的互动小工具就非常容易了!您可以通过运行以下命令来尝试一下:

from fastai.widgets import *ds, fns_idxs = DatasetFormatter.from_similars('learner')
ImageCleaner(ds, fns_idxs, path, duplicates=True)

想用吗?用 CIFAR 查看我的教程笔记本。

如何构建和部署歌词生成模型——与框架无关

原文:https://towardsdatascience.com/how-to-build-and-deploy-a-lyrics-generation-model-framework-agnostic-589f3026fd53?source=collection_archive---------7-----------------------

你会发现大量关于如何建立机器学习模型的文章。你会发现关于如何明智地消费它的文章比较少。而且你会发现几乎没有关于如何从零开始服务它的文章。

我将详细说明我们到上面可以看到的产品的步骤:rap lytics . eu所有代码都是开源的,可以在 GitHub 上获得。

  • 填词-刮刀
  • 填词-背面
  • 填词-正面

更新:在这篇帖子中,我们提出了一种更具成本效益、更直接的方式来为你的机器学习项目服务。

什么?

和我的一个好朋友一起,我们真的很喜欢听说唱音乐。说唱音乐是强大的,因为它有能力只用几个词就创造出野蛮的笑点。
由于仍然很难用 RNN 生成长文本,我们认为说唱音乐是一个很好的候选。

The final product

怎么会?

大局

Project’s architecture

我不会在帖子中过多描述实现,因为我们试图在代码库中做到详尽,见READMEs。我将坚持对我们具有挑战性的转折点。

基本的系统管理员知识和 unix 熟练程度会有所帮助。

1-数据提取和处理

GitHub 库: RapLyrics-Scraper

—刮削

首先,我们需要一个数据集来训练我们的神经网络。

足够幸运的是,Genius.com有大量的在线歌词,甚至还有一个不错的 API 。

它可能不是为废弃歌词而设计的,但通过一些变通方法,我们设法在它上面建立了一个歌词刮刀。

如果您需要技术细节,请查看源代码或在评论中寻求帮助。
经过多次拍摄,我们意识到专注于高质量的自然语言处理数据集非常重要。我们决定关注 40 位美国艺术家的 60 首最受欢迎的歌曲。

✔:报废了。

预处理

抓取部分为我们提供了一个.txt数据集。我们现在必须清理它— 删除非抒情内容:、演职员表、错别字和同一单词的各种拼写。想想gettin'getting之类的东西。

我们遵循的方法:
1。识别模式以消除
2。手工正则表达式捕捉那些模式— 正则表达式测试资源:pythex.org
3 .使用文本编辑器直接在数据集上执行这些正则表达式

如果你想自动清理正则表达式,要知道这是有风险的。您必须彻底考虑执行正则表达式的顺序。

扩充数据集 【可选】

我们只选择了歌词真正有意义的艺术家,我们选择了他们最受欢迎的歌曲。这并不构成一个庞大的语料库。因此,我们决定执行一个数据扩充步骤,以便实际上增加我们数据集的大小。

📖数据扩充意味着增加数据点的数量。在我们的上下文中,它意味着增加句子的数量。

我们复制了我们的数据集,打乱了所有的诗句,然后把它粘贴到原始数据集的末尾。

你可以在这里找到一个关于如何打乱段落的片段。

使用这个技巧,我们将数据集的大小加倍。这将对神经网络的训练产生积极的影响。实际上,由于洗牌,每个新批次都是不同的,所以网络权重用不同的输入来更新。

✔:数据扩充到此结束。

2-建立歌词生成模型

  • GitHub 资源库: RapLyrics-Back

标注文本创成式模型

许多神经网络实现可在线获得。我们选择了一个并对其进行了微调以满足我们的需求: textgenrnn — 一个使用神经网络生成文本的 python 项目

您可以在我们的代码库中找到模型超参数和训练设置的基本描述READMEs

本文的目的不是深入研究神经网络设计。实现就不细说了。您可以查看源代码或在评论中 ping 我们。

训练文本生成模型

根据您的数据集和配置,您可以考虑使用云计算来加速训练。我们使用 AWS——亚马逊网络服务。

如果您在本地培训您的模型,您可以跳过这一部分。否则,考虑到下面的部分会变得有点技术性。

我会更详细地介绍我们的训练设置,因为这需要我们花时间去适应。

我们启动了 aws ec2 spot 实例来降低成本。我们需要至少 3gb 的内存和 8gb 的默认固态硬盘足够了。训练不是 GPU 加速的(一个改进点)。

83% savings on a spot instance comparing to a classic ec2 instance

ec2 spot 实例与传统 ec2 实例有何不同?

您出价购买一个具有特定规格的 ec2 实例,只要您的出价高于平均市场价格,您就拥有了一个行为类似经典 ec2 的实例。

如果你的出价低于市场价格,你的实例在一个短时间通知后被终止。关于聚光灯实例的更多信息。

我们提出了一个现场请求,很快就完成了,然后我们克隆了我们的 repo 并安装了一个包含所有项目需求的 python3 虚拟环境。

注意:如果您想要保存您的模型检查点,您需要使您的实例能够在 s3 存储桶上写入(如图所示👇)

texgenrnn 在每个时期保存一个模型检查点。

  • 为了应对实例终止的风险并在安全的地方保存我们的检查点,我们使用aws cli在 aws s3 桶中复制检查点。cd到您的检查点文件,并将它们复制到您的 s3 存储桶。
# run `pip install awscli` beforehand
aws s3 cp my-checkpoint-file.ckpt s3:*//my-s3-bucket/model-saves/*

注意:要做到这一点,您需要向实例授予对 ec2 的写权限。为此,向您的 ec2 实例添加一个角色,使用 s3 完全访问和 ec2 完全访问策略,如下图所示。

Attach those 2 policies to the IAM role attached to your ec2 instance.

政策处理中有许多偷偷摸摸的细节,不要犹豫,在评论中问我们。

——————测试文本生成——

一旦你训练好了你的模型,你就可以使用 Jupyter 笔记本[RapLyrics-Back/exploration/sample_explorator.ipynb](https://github.com/cyrilou242/RapLyrics-Back/blob/master/exploration/sample_explorator.ipynb)来生成你的第一首人工智能歌词。

3。服务于文本生成模型

为了给用户提供更好的歌词,我们使用了一个自定义生成函数。

我们使用 gunicorn 在烧瓶上提供应用程序。这个想法是不要在每次 API 调用时重新加载模型——这会导致很长的响应时间。
我们只在应用程序初始化时恢复一次会话,它在 API 调用之间持续存在。

API 调用及其响应的演示。

curl on back-end

如果您还没有实现该模型,请随时调用我们的 API:

curl '[https://raplyrics.eu/apiUS'](https://raplyrics.eu/apiUS') -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "input=struggle"

参见上api/serve_us.py中的get_model_api_us函数,了解我们如何建立一个持久的张量流会话。只需从 shell 中运行gunicorn app:app来启动应用程序。模型默认在127.0.0.1:8000端上。

你现在可以在将被用作网络服务器的机器上克隆 RapLyrics-Back 。

4-插入前端

GitHub 资源库: RapLyrics-Front

本文描述了 apache web 服务器的必要步骤。如果没有它sudo apt-get install apache

将所有要提供的文件从 RapLyrics-Front 移动到/var/www/html/
记住在index.html 中更新你的端点的"url"设置就这样,你就大功告成了(差不多)。现在,您可以通过网络浏览器访问您的服务器ip来访问网站。

生产设置 【可选】

如果您想让前端和后端在同一台机器上使用 https 连接,下面是几个步骤。

1.让我们加密我们的网站🔒→按照如何用加密来保护 Apache 的步骤进行(数字海洋有非常棒的教程)

2.当用户提交输入时,apache 服务的index.html调用raplyrics.eu/apiUS。事实上,阿帕奇上没有/apiUS航线。我们需要将这个调用重定向到运行在同一台机器上的gunicorn服务器。这就是所谓的反向代理。

让我们来处理这两个步骤。
由于代码与 apache 配置相关,因此不受版本控制。

  • /etc/apache2/sites-available

您应该会看到一个000-default.conf和一个000-default-le-ssl.conf文件。它们是模板文件,处理 apache 如何服务于 http 和 https ( le-ssl)网站的配置。

我们为我们的网站复制了一份。(用您的域名替换raplyrics.eu👇)

sudo cp 000-default.conf raplyrics.eu.conf
sudo cp 000-default-le-ssl.conf raplyrics.eu-le-ssl.conf

1。将流量从 **http** 重定向到 **https**

编辑raplyrics.eu.conf以包括以下重写条件:

Rewrite rules to redirect traffic from http to https. Remember to replace raplyrics.eu by your site name.

2。反向代理 API 调用

编辑raplyrics.eu-le-ssl.conf以包含代理反向指令。

Reverse proxy to redirect the API call to the gunicorn app

在这里,我们处理从raplyrics.eu/apiUS127.0.0.1:8000的本地 gunicorn 服务器的代理传递

现在我们告诉 apache 更新网站配置:

sudo a2ensite raplyrics.eu.conf
sudo a2ensite raplyrics.eu-le-ssl.conf

最后,sudo systemctl restart apache2要把变化考虑进去。

就这样,你在制作中。🚀
你可以在 raplyrics.eu 上查看我们的

参考📚

关于在 heroku 上提供 python 应用的有趣博客文章(Heroku dynos 无法处理我们的应用——没有足够的 ram)很好地描述了步骤。

Apache 2 上的反向代理

数字海洋在 apache 上的反向代理,数字海洋再次做了一个非常值得赞赏的文档工作,非常详细。

非常有趣,所以在上发布如何用 GitLab 和 AWS 构建 CI / CD 管道

神经网络参数微调的启示

有趣的关于微调批量训练参数的交叉验证帖子。

谷歌大脑论文提出了一组文本生成 LSTM 的超级参数(尤其是 4。我们用例的实验和 4.1 语言建模。)

如何像汉斯·罗斯林一样制作动画图表——全部用 R 语言完成

原文:https://towardsdatascience.com/how-to-build-animated-charts-like-hans-rosling-doing-it-all-in-r-570efc6ba382?source=collection_archive---------3-----------------------

一个学习数据可视化技能的小型教育项目,利用了两个库(gganimate 和 plot . ly)——更新了新的 gganimate 版本

汉斯·罗斯林是统计学大师。他毕生致力于推动使用数据和动画图表来探索发展问题,并分享基于事实的世界观。他最受欢迎的 TED 演讲:“你见过的最好的统计数据”点击量超过 1200 万次。这也是世界上 100 个最受欢迎的 TED 演讲之一。

你曾经梦想过像他的 最受欢迎的一张 一样免费制作动画图表吗,从零开始,不到 5 分钟,并且可以以不同的格式(gif,html 用于你的网站等)共享。)?

What we will be building with gganimate 😉

本文将向您展示如何使用两种方法用 R 构建动画图表:

  • 将创建 GIF 文件的 R + gganimate 库
  • R + plot.ly 将生成一个 HTML 文件,您可以将它嵌入到您的网站中(参见下面的 plot.ly 版本)

What we will be building with plot.ly 😉

假设您已经安装了 Rstudio,并且了解一些基础知识,因为本文将只介绍生成视觉效果的步骤和代码。完整代码可从 Github 上获得,用于教育目的。

第一步:搜索并下载你需要的数据集

第一站是在gapminder.com下载所需的 3 个数据集。这个基金会是罗斯林家族创立的。它有奇妙的可视化和数据集,每个人都应该检查“用每个人都能理解的基于事实的世界观来战胜无知”。

我们将下载 3 个 excel 文件(xlsx):

  1. 每名妇女的子女数(总生育率)
  2. 人口总数
  3. 预期寿命(年)

一旦文件被下载并保存在你的工作文件夹中,就该清理并合并数据集了。

第二步:清理并合并数据

a1)用 xlsx 库加载数据(替换'..'您的文件夹旁)

# Please note that loading xlsx in R is really slow compared to csvlibrary(xlsx)population_xls <- read.xlsx("indicator gapminder population.xlsx", encoding = "UTF-8",stringsAsFactors= F, sheetIndex = 1, as.data.frame = TRUE, header=TRUE)fertility_xls <- read.xlsx("indicator undata total_fertility.xlsx", encoding = "UTF-8",stringsAsFactors= F, sheetIndex = 1, as.data.frame = TRUE, header=TRUE)lifeexp_xls <- read.xlsx("indicator life_expectancy_at_birth.xlsx", encoding = "UTF-8", stringsAsFactors= F, sheetIndex = 1, as.data.frame = TRUE, header=TRUE)

a2)更新—在 R 版本 5.3+上安装 gganimate 新版本

library(devtools)
library(RCurl)
library(httr)
set_config( config( ssl_verifypeer = 0L ) )
devtools::install_github("RcppCore/Rcpp")
devtools::install_github("thomasp85/gganimate", force = TRUE)

b)使用 reshape 和 dplyr 库清理和合并数据

# Load libraries
library(reshape)
library(gapminder)
library(dplyr)
library(ggplot2)# Create a variable to keep only years 1962 to 2015
myvars <- paste("X", 1962:2015, sep="")# Create 3 data frame with only years 1962 to 2015
population <- population_xls[c('Total.population',myvars)]
fertility <- fertility_xls[c('Total.fertility.rate',myvars)]
lifeexp <- lifeexp_xls[c('Life.expectancy',myvars)]# Rename the first column as "Country"
colnames(population)[1] <- "Country"
colnames(fertility)[1] <- "Country"
colnames(lifeexp)[1] <- "Country"# Remove empty lines that were created keeping only 275 countries
lifeexp <- lifeexp[1:275,]
population <- population[1:275,]# Use reshape library to move the year dimension as a column
population_m <- melt(population, id=c("Country")) 
lifeexp_m <- melt(lifeexp, id=c("Country")) 
fertility_m <- melt(fertility, id=c("Country"))# Give a different name to each KPI (e.g. pop, life, fert)
colnames(population_m)[3] <- "pop"
colnames(lifeexp_m)[3] <- "life"
colnames(fertility_m)[3] <- "fert"# Merge the 3 data frames into one
mydf <- merge(lifeexp_m, fertility_m, by=c("Country","variable"), header =T)
mydf <- merge(mydf, population_m, by=c("Country","variable"), header =T)# The only piece of the puzzle missing is the continent name for each country for the color - use gapminder library to bring it
continent <- gapminder %>% group_by(continent, country) %>% distinct(country, continent)
continent <- data.frame(lapply(continent, as.character), stringsAsFactors=FALSE)
colnames(continent)[1] <- "Country"# Filter out all countries that do not exist in the continent table
mydf_filter <- mydf %>% filter(Country %in% unique(continent$Country))# Add the continent column to finalize the data set
mydf_filter <- merge(mydf_filter, continent, by=c("Country"), header =T)# Do some extra cleaning (e.g. remove N/A lines, remove factors, and convert KPIs into numerical values)
mydf_filter[is.na(mydf_filter)] <- 0
mydf_filter <- data.frame(lapply(mydf_filter, as.character), stringsAsFactors=FALSE)
mydf_filter$variable <- as.integer(as.character(gsub("X","",mydf_filter$variable)))
colnames(mydf_filter)[colnames(mydf_filter)=="variable"] <- "year"
mydf_filter$pop <- round(as.numeric(as.character(mydf_filter$pop))/1000000,1)
mydf_filter$fert <- as.numeric(as.character(mydf_filter$fert))
mydf_filter$life <- as.numeric(as.character(mydf_filter$life))

第三步——升级到新版 gganimate:用 gganimate 构建图表并生成 GIF 文件与你的朋友分享

现在我们有了一个包含 3 个 KPI(人口、生育率和预期寿命)和 3 个维度(国家、年份、洲)的清晰数据集,我们可以用 gganimate 生成可视化效果。

# Load libraries
library(ggplot2)
library(gganimate)
#library(gifski)
#library(png)# Add a global theme
theme_set(theme_grey()+ theme(legend.box.background = element_rect(),legend.box.margin = margin(6, 6, 6, 6)) )# OLD VERSION
# Create the plot with years as frame, limiting y axis from 30 years to 100
# p <- ggplot(mydf_filter, aes(fert, life, size = pop, color = continent, frame = variable)) +
#  geom_point()+ ylim(30,100)  + labs(x="Fertility Rate", y = "Life expectancy at birth (years)", caption = "(Based on data from Hans Rosling - gapminder.com)", color = 'Continent',size = "Population (millions)") + 
#  scale_color_brewer(type = 'div', palette = 'Spectral') 
# gganimate(p, interval = .2, "output.gif")# NEW VERSION# Create the plot with years as frame, limiting y axis from 30 years to 100
p <- ggplot(mydf_filter, aes(fert, life, size = pop, color = continent, frame = year)) +
  labs(x="Fertility Rate", y = "Life expectancy at birth (years)", caption = "(Based on data from Hans Rosling - gapminder.com)", color = 'Continent',size = "Population (millions)") + 
  ylim(30,100) +
  geom_point() +
  scale_color_brewer(type = 'div', palette = 'Spectral') + 
  # gganimate code
  ggtitle("Year: {frame_time}") +
  transition_time(year) +
  ease_aes("linear") +
  enter_fade() +
  exit_fade()# animate
animate(p, width = 450, height = 450)# save as a GIF
anim_save("output.gif")

现在你可以享受你当之无愧的 GIF 动画,并与你的朋友分享。

第四步:用 plot.ly 构建图表并生成一个 HTML 文件嵌入你的网站

# Load libraries
library(plotly)
library(ggplot2)# Create the plot
p <- ggplot(mydf_filter, aes(fert, life, size = pop, color = continent, frame = year)) +
  geom_point()+ ylim(30,100)  + labs(x="Fertility Rate", y = "Life expectancy at birth (years)", color = 'Continent',size = "Population (millions)") + 
  scale_color_brewer(type = 'div', palette = 'Spectral')# Generate the Visual and a HTML output
ggp <- ggplotly(p, height = 900, width = 900) %>%
  animation_opts(frame = 100,
                 easing = "linear",
                 redraw = FALSE)
ggp
htmlwidgets::saveWidget(ggp, "index.html")

代码可在 Github 上获得。感谢你阅读我的帖子,如果你喜欢,请鼓掌。如果你想在你的组织内制作动画图表,请随时联系我。

其他有趣的链接,了解有关 R 动画图表的更多信息:

[## 了解关于 Gapminder 的更多信息

Gapminder 是一个独立的瑞典基金会,没有任何政治、宗教或经济背景。Gapminder 是一个…

www.gapminder.org](https://www.gapminder.org/about-gapminder/) [## dgrtwo/gganimate

用 ggplot2 创建简单的动画

github.com](https://github.com/dgrtwo/gganimate/blob/master/README.md)

我如何建立一个数据科学实验室并休假

原文:https://towardsdatascience.com/how-to-build-data-science-unit-f84ee3de63f5?source=collection_archive---------9-----------------------

毫无疑问,对数据分析的需求巨大,几乎每家公司都希望被视为数据驱动型,能够提取有用的见解,最终使其在竞争中处于领先地位。以人工智能和机器学习为实现目标,数据科学部门正在发展,将继续在各种规模和行业的组织内传播

尽管如此,建立这样一个单位肯定是一个挑战,因为它的研究&创新性质及其所有后果和所需的资本投资。所需的技能目前很难在市场上找到,但通过获得支持,组建和组织合适的团队,你可以保证成功和盈利。

JLL ,作为一家企业房地产公司(财富 500 强),为我们的客户管理着大量的建筑组合,因此产生了大量的数据。在过去,这些数据主要用于可视化和报告,但问题是,我们能否通过应用数据科学做一些更高级的事情,并提取更多有意义的有用信息,以造福于我们的客户?带着这个目标,我们开始了我们的旅程,这使我们得以开发一个数据科学实验室,到目前为止,这是一个由六名数据科学家和工程师组成的团队,他们在工作场所、能源&可持续发展和设施管理领域提供创新的高级分析解决方案。

许多这样的单元在早期阶段失败或经历巨大困难,我们的开始也不例外。这是一条崎岖不平的道路,但在几个月内,我们的团队设法建立了一个平稳运行的实验室。下面你会发现我的一些最重要的非技术性提示,你可能希望遵循它们来节省时间和金钱,抄近路,避免可避免的错误。它们展示了新团队遇到的最常见问题和解决方案,可以帮助任何数据科学团队取得更大的成功。

1。 从你的上级和下级那里获得支持

没有适当的支持,你的项目将一事无成。首先,你的赞助商需要明白,组建一个数据科学部门很像为一家初创企业融资,它需要投资和时间来获得盈利。所需的时间取决于许多变量和限制因素,但应该在您的项目计划中明确定义,因为通常需要9-18 个月才能开始显示积极的结果。

虽然非常重要,盈利能力不应该是一个单位的唯一目标,因为建立正确的团队会带来其他切实的利益,包括为您的公司提供数据驱动的&创新形象,这可能在其他业务部门产生收入,并帮助公司在竞争中处于领先地位。并非每个客户都准备好了成熟的数据科学解决方案,但总有空间开发更简单的产品,如数据管理、报告或可视化。

发展一个数据科学部门就像坐过山车一样,这是大多数初创企业的经历。因此,要取得成功,你需要获得赞助商的信任和自由,以及在你进步和适应不断变化的环境的过程中做出自己决定的灵活性。

此外,该部门应在组织内尽可能靠近首席信息官/CDO** 进行**定位,以确保其他部门有足够的资金、影响力和支持。建立数据科学团队不是一个人的工作,而是需要利益相关者的积极参与,尤其是那些将直接或间接受益于您所在单位的利益相关者。

2。 发现人才,组织好他们

建立一个团队可能是棘手的,往往需要许多权衡,例如在预算和薪水、硬技能和软技能、专业化和普遍化、个性或数据能力和职位之间找到正确的平衡。最好和一个新的团队一起开始新的生活,这个团队将致力于这个单位和你的目标。在从市场人才库中招聘新员工之前,先从你的组织内部寻找可用的人才,然后从外部寻找最优秀的人才,这些人才将带来打破常规的思维,不会受到组织文化的偏见或威胁。

由于高需求,招募优秀的数据科学家可能是一个相当大的挑战。为了获得外部帮助,不要犹豫使用你自己和其他团队成员的专业网络、数据科学聚会和会议,因为这些可能是最有效的招聘手段。

运行一个单元需要多少数据科学家和工程师?从小处着手,按需增长。根据您组织的规模,通常您可以从 3 到 4 名数据科学家开始,并随着新业务的出现而扩展。

人工智能和数据科学炒作的一个不利方面是,可用的熟练数据科学家短缺。不要指望找到一个完全符合你的具体工作规格。科技技能差别很大,公司对数据科学家必备能力的认知也不尽相同,他们会根据自己的需要进行培训,但总会有灵活、愿意学习并随时准备迎接新挑战的能干的候选人。

硬技能是非常重要的,但要记住,如果一个潜在的候选人是缺乏某些领域,他们总是可以培训,以满足你的期望。招聘时,要专注于最基本的技能,比如机器学习、用 R/Python 编程以及在 sharing 或 Tableau 中创建可视化效果。然而,你的关注点应该是软技能,个性以及候选人与你的团队保持一致的能力。最好是组建一个性格各异的团队,由谁来平衡团队的情绪——根据我的个人经验,我建议你也加入一个“T10”叛逆!他们经常帮助刺激必要的改变,不害怕风险,愿意在需要的时候努力工作。

无论你的组织的文化,创造力是任何创新单位的基本要素。重要的是要推广由有着共同目标的专家组成的临时启动机构。这将有助于支持团队敏捷性、开箱即用的思维、协作、文化共享、开放性和完整性。不要忘记使用个人培训方式培养你的团队,其中应包括在线课程和参加会议。

3 . 着力打造有形效益

由于过度设计交付的解决方案,大量数据科学、通用研究和创新部门在某个时候出现了故障。始终记住必要的开发工作、时间和成本,因为在大多数情况下,解决方案甚至是基于规则引擎的解决方案通常满足客户期望,并且可能不需要到处部署深入学习。瞄准最简单的那些可以快速部署并且易于维护的。

由于数据科学是一个相对较新的概念(由来已久),许多客户可能没有特定的需求,只是依赖您来提供有用的解决方案。做你的学术和工业研究,和你的团队一起头脑风暴用例,咨询专家和你的客户,为了概念证明,只选择那些给你的客户带来切实利益的用例(速赢)。当然,我的意思是…钱!因此,专注于能够节约成本、提高运营绩效、增加收入或带来竞争优势的解决方案。

运行数据科学计划时,无论您的起点是研究、概念验证还是试点,都要利用项目管理和软件开发方法。为了完成这类项目的研究性质,调整和定制敏捷方法,包括 scrum、快速原型和连续交付,这将确保成功完成。

从项目的角度看待你单位的发展没有结束日期的限制。您的最终产品应该按照您在路线图中定义的中间步骤交付。这应作为至少 2-3 年的总体规划,并与您的使命和愿景(或同等目标)一起尽早确定(随着您的发展,在必要时进行更改)。

4。 培养研究和创造力

这说起来容易,但是如何在团队中激发好奇心、学习和创造力呢?这些是每个数据科学部门取得成功的基本因素。你会经常发现自己在未知的水域航行,研究新方法,并首次将它们应用到主题中。因此,你需要一个能够一起工作、分享想法、集思广益并提出解决方案的团队——但这是如何做到的呢?

重要的是不要让你的团队承担过多的项目,给他们留一些研究和自我发展的空间。你甚至可以批准一些特殊的时间,比如每周五举行创意会议,学习新技术,研究选定的主题等等。

多元化是与团队及其项目/职责相关的另一个关键因素。在一个单位里,不同个性的人结合在一起,肯定能引发建设性的讨论。

通过促进开放、非正式文化,知识共享和引入创意会议或实践社区来加强沟通,这可能会拓宽每个成员和团队的界限。此外,通过混合项目团队,转移重点和责任领域,团队将获得更广阔的业务视角,并将能够从不同角度理解主题。

领导者的角色还包括提供愿景并定义所采取措施的目的。给团队成员一个关于组织目标的更广阔的视角,向团队灌输他们是更大项目不可或缺的一部分,并帮助他们理解他们的个人工作如何适应整体战略。

团队成员也应该有自主权和信任来进行项目并做出自己的决定。给失败留有余地必要时提供辅导。因此,您应该拥有自我驱动和富有创造力的数据科学家,他们可以研究某个主题,定义 PoC 所需的方法,并端到端地实施项目。

5。 营销和 UX

在房地产领域,我们喜欢说——位置,位置,位置。在确保一个萌芽的数据科学部门成功起步的情况下,我认为关键词是——营销、营销、营销。如果没有适当的营销,即使是最先进的解决方案,也可能会产生巨大的成本节约。因此,投入巨资将您的解决方案包装成带有营销材料的产品,包括网站、社交媒体和其他可用渠道。因为你不可能在每个领域都是专家,向你公司的市场营销和销售人员寻求支持

然而,任何数据科学解决方案成功的关键因素如何将见解交付给最终用户,以及他如何与解决方案互动。因此,不要只局限于 Tableau、Shiny 或其他类似产品中的数据可视化,而是要投资于适当的 UI 和 java script web 应用程序开发。

雇佣专家或顾问和培训你剩下的数据科学家进行现代 UI/UX 设计,因为它是你的前端,反映客户的需求,提供可用性并提供愉快的体验,这将增加你的客户对更多的胃口,并显著促进你的销售。毕竟视知觉才是关键。

那休假呢?

当我写这篇文章时,我正在夏洛茨维尔,这是许多美国总统的绿色家园,也是许多矛盾的地方。在过去的几个月里,我们的家庭扩大了,我的妻子在弗吉尼亚大学获得了一笔有声望的研究基金,我们决定我们三个人在美国呆 4 个月。因此,我现在正在休公休假/育儿假,专注于我最近忽视的家庭和研究——写一篇学术论文,与研究人员会面,开阔我的视野。

在扩大规模阶段离开我的团队绝对不是一个容易的决定,但我花了几周时间为他们做准备。我的团队中的大多数人都是经验丰富、自我驱动的数据科学家,他们可以独自忽略他们的项目,并继续创造新的业务。然而,我考虑到,由于缺乏明确的领导和研究指导,团队的创造力可能会受到影响。因此,该股目前的重点是向新客户宣传现有产品,而不是确定新的解决方案。然而,在短期内,我缺席的影响应该是有限的,而是有助于团队的成熟。

最后一条建议是,坚持建立自己的数据科学部门。你会遇到许多障碍,但请记住——如果你不成功,没人会成功。像我们大多数人一样,你也可能不是每个主题的专家,所以尽管这可能很难,但试着让你周围的人填补你的知识或专业知识的空白——最好是在某些领域比你更有成就的人。

坚持不懈,你就会成功——祝你好运!

当然,这篇文章只是触及了表面。因此,请随时在 LinkedIn 上留下您对该主题的经验或看法或联系方式。

## Przemyslaw Pospieszny 博士| LinkedIn

如何用自然语言处理构建基于内容的电影推荐系统

原文:https://towardsdatascience.com/how-to-build-from-scratch-a-content-based-movie-recommender-with-natural-language-processing-25ad400eb243?source=collection_archive---------0-----------------------

“empty brown theater chairs” by Tyler Callahan on Unsplash

在某种程度上,我们每个人肯定都想知道网飞、亚马逊、谷歌给我们的所有推荐来自哪里。我们经常在互联网上对产品进行评级,我们表达的所有偏好和分享的数据(明确地或不明确地)都被推荐系统用来产生实际上的推荐。推荐系统的两种主要类型要么是协作式的,要么是基于内容的过滤器:这两个名称都是不言自明的,但是让我们看几个例子来更好地理解它们之间的区别。我将使用电影作为例子(因为如果可以的话,我会一直看电影/电视节目),但是请记住,这种类型的过程可以应用于您观看、收听、购买的任何类型的产品,等等。

协同过滤器

这种类型的过滤器是基于用户的比率,它会向我们推荐我们尚未观看过,但与我们相似的用户已经观看过,并且喜欢的电影。为了确定两个用户是否相似,该过滤器考虑他们观看的电影以及他们对电影的评价。通过查看共同的项目,这种类型的算法将根据相似用户的评价,基本上预测尚未观看该电影的用户的评价。

Collaborative-based filter.

为了准确地工作,这种类型的过滤器需要评级,并且不是所有用户都不断地对产品进行评级。他们中的一些人几乎从不评价任何东西!这种方法的另一个特点是建议的多样性,这可能是好的或坏的,取决于具体情况。比如说用户 A 非常喜欢反乌托邦电影和黑色喜剧。用户 B 也喜欢反乌托邦电影,但从未看过黑色喜剧。协作过滤器将基于两个用户对反乌托邦电影的共同品味,向用户 B 推荐黑色喜剧表演。这种情况可能有两种方式:要么用户 B 发现他/她非常喜欢黑色喜剧,在这种情况下,很好,他/她的列表上有很多新的东西可以看!或者,用户 B 确实喜欢较轻的喜剧风格,在这种情况下,推荐没有成功。

基于内容的过滤器

Content-based filter.

这种类型的过滤器不涉及其他用户,如果不是我们自己。基于我们喜欢的东西,该算法将简单地挑选内容相似的项目来推荐给我们。

在这种情况下,推荐的多样性将会减少,但是这将会影响用户对事物的评价。如果我们将此与上面的示例进行比较,可能用户 B 潜在地喜欢黑色喜剧,但他/她永远不会知道,除非他/她决定自主尝试,因为该过滤器只会继续推荐反乌托邦电影或类似的电影。当然,我们可以计算许多类别的相似性:在电影的情况下,我们可以决定只基于类型建立自己的推荐系统,或者我们可能希望包括导演、主要演员等等。

当然,现有的过滤器并不只有这两种。还有基于集群或行为的,仅举几个例子。

到目前为止,我已经多次提到这个词相似性,但是它到底是什么呢?这似乎不是我们可以量化的东西,但令人惊讶的是它是可以测量的!在进入如何构建基于内容的系统的实际例子之前,让我们简单回顾一下余弦相似性的概念。这是我们在计算用户或内容之间的相似性时可以使用的指标之一。

余弦相似性

我们都很熟悉向量:它们可以是 2D、3D 或其他什么-D。让我们在 2D 想一会儿,因为它更容易在我们的脑海中描绘出来,让我们首先刷新一下点积的概念。两个向量之间的点积等于其中一个向量在另一个向量上的投影。因此,两个相同向量(即具有相同分量的向量)之间的点积等于它们的平方模,而如果这两个向量垂直(即它们不共享任何方向),则点积为零。一般来说,对于 n 维向量,点积可以计算如下。

Dot product.

点积在定义相似性时很重要,因为它与相似性直接相关。两个向量 uv 之间的相似性的定义实际上是它们的点积和它们的大小的乘积之间的比率。

Similarity.

通过应用相似性的定义,如果两个向量相同,这实际上等于 1,如果两个向量正交,则等于 0。换句话说,相似性是一个介于 0 和 1 之间的数字,它告诉我们两个向量有多相似。相当简单!

现在是编码的时候了!

1.收集数据

对于这个问题,我决定使用包含 IMDB 中排名前 250 的电影的数据集。事实上,这个表收集了 250 个观察值(电影)和 38 列。然而,我希望我的推荐者只基于电影导演、主要演员、流派和情节,所以这些是我在建模中考虑的唯一列。

这是数据帧头部的样子。

我的目标是为包含上述所有特征的每部电影只获取一列,以便执行矢量化。没错,我们需要使用 NLP,因为我们需要数字来计算余弦相似度,而我们还没有…还没有!当然,首先要做一些清洁工作。

2.数据清理

我在nltk包中发现了一个很好的特性,允许我们从文本中提取关键词,它甚至给每个词打分。我没有真正考虑这个基本推荐者的分数,但是我使用这个Rake函数从Plot列中提取关键词,所以我没有使用描述情节的整个句子,而是只考虑描述中最相关的词。为了做到这一点,我将这个函数应用于Plot列下的每一行,并将关键字列表分配给一个名为Key_words的新列

Extracting key words from movie plots.

其他的柱子也需要清洗。一切都需要小写以避免重复,我还决定将所有的名和姓合并成一个唯一的单词。因为,想想看:如果我们有导演是丹尼·鲍伊尔的电影 A,和主要演员之一是丹尼·德维托的电影 B,推荐者会因为他们的名字而发现相似性,而这是我们不想要的。我希望推荐器只在与不同电影相关联的人完全相同时才检测相似性。

在所有的清理和合并之后,我将索引重新分配给电影标题列(这不是我的功能之一),这就是准备进行矢量化的数据帧。

3.建模

为了检测电影之间的相似性,我需要向量化,正如我上面提到的。我决定使用CountVectorizer而不是TfIdfVectorizer,原因很简单:我需要为我的bag_of_words列中的每个单词设置一个简单的频率计数器。Tf-Idf 倾向于对出现在整个语料库(在本例中是我们的整个专栏)中的单词不太重视,这不是我们在这个应用程序中想要的,因为每个单词对检测相似性都很重要!一旦我有了包含每个单词计数的矩阵,我们就可以应用cosine_similarity函数了

相似矩阵是这样的。

Similarity matrix.

让我们简单看一下:对角线上的所有数字都是 1,因为,当然,每部电影都和它自己一模一样。矩阵也是对称的,因为 A 和 B 之间的相似性与 B 和 A 之间的相似性相同。

此时,我可以编写实际的函数,该函数以电影标题作为输入,并返回前 10 部类似的电影。为了做到这一点,我还创建了一个简单的带有数字索引的电影标题系列,以便将相似性矩阵中的索引与实际的电影标题相匹配。事实上,我的函数一旦接收到输入,就检测与输入的电影对应的行中的 10 个最高数字,获取相应的索引并将它们与电影标题系列进行匹配,以返回推荐的电影列表。当我说该函数考虑 10 个最高的相似性值时,我是在丢弃单元值(很容易是最高的),以便该函数不会返回我输入的相同电影标题。

4.测试推荐器

任务完成了!当然,这是一个非常有限的推荐系统,因为我只使用了一个包含 250 部电影的数据集,但它一点也不差!遵循相同的程序,但使用更多的数据,并实现关键字的分数,例如,这个系统可以很容易地完善。但是让我们通过输入 Fargo: 来测试一下,这是(250 部电影中)最值得推荐的 10 部电影。

Movies recommended because I like Fargo.

我看这个不错!主要是基于导演和剧情我能看出一些相似之处。我喜欢上面列表中我已经看过的电影,就像我喜欢《法戈》一样,所以我想我会去看我仍然错过的几部电影!

请随意查看:

我的其他中等岗位。

我的 LinkedIn 个人资料。

我的这个项目的 GitHub 资源库。

感谢您的阅读!

如何构建能够自我更新的闪亮应用

原文:https://towardsdatascience.com/how-to-build-r-shiny-apps-that-update-themselves-6ce2d9606e90?source=collection_archive---------9-----------------------

R 生态系统现在是一个非常好的地方。特别是,R 中的基础设施允许人们通过闪亮的应用程序与数据进行交互,这为减少数据分析师的工作量提供了不可思议的潜力。

现在有可能构建闪亮的应用程序,可以定期更新自己,引入更新的数据,以便人们总是看到最新的分析。因此,通过一个预先开发 sprint,分析师可以将特定主题的持续分析工作量减少近 100%。

你需要什么

  1. 一个项目,在该项目中,您定期以相同的格式交付报表,并且数据库中的所有数据都可用。
  2. R,R 降价和 R 闪亮技能
  3. 访问包含闪亮服务器的运行 R 的 Linux 服务器,或者如果你真的幸运,访问 RStudio Connect 发布平台,这使得整个过程变得更加容易。

第一步:根据本地数据源构建你的应用

使用本地数据源,以.csv.feather文件、.RData文件甚至是SQLLite本地数据库的形式,编写一个闪亮的应用程序,使其成功部署在您的本地机器上。确保它按预期运行。

步骤 2:编写一个可以在服务器上运行的 ETL 脚本或文档

用 R 编写一个脚本,从远程数据库中提取原始数据,将其转换成您闪亮的应用程序所需的形式。然后,您需要将这些数据写入某个地方,以便您的闪亮应用程序可以远程访问这些数据。选项包括:

  • 在新表中写回源数据库(如果您有权限这样做)
  • 写入托管您的闪亮服务器的 Linux 服务器的文件系统
  • 如果你使用 RStudio Connect,在/var/cache/data写入它的缓存。

步骤 3:将您的脚本部署到您的 Linux 服务器或 RStudio Connect 上

您需要在 Linux 服务器上的 R 中设置数据库连接。这里的是一个很好的指南。然后,您需要编辑您的脚本来指向这些连接。

如果您将输出写入 Linux 文件系统,您将需要确保它位于 Shiny 服务器可以访问的目录中。

如果您在 RStudio Connect 中操作,您可以将您的脚本包装到一个 R Markdown 文档中,并发布它,包括源代码,这样每当文档被刷新时,代码就会执行,从而执行一个新的 ETL。

步骤 4:将你的闪亮应用部署到闪亮服务器或 RStudio Connect

您需要编辑您的应用程序代码,以指向远程数据源,无论它是数据库还是文件系统中的某个地方。然后,您可以将应用程序文件加载到 Linux 服务器上的子目录shiny-server中。应用的 URL 将是 shiny 服务器的 URL,后跟子目录名称,例如[https://my.shiny.server/myappname](https://my.shiny.server/myappname.)

如果在 RStudio Connect 中工作,您只需正常发布并在 RStudio Connect 中自定义 URL。

第五步:设置数据自动刷新

如果您的脚本位于您的 linux 服务器上,您可以使用各种调度工具来设置脚本在期望的时间间隔自动运行。cron是一种简单的方法。在您的 Linux 用户文件夹中找到您的crontab文件,并适当地编辑它。例如,要设置您的脚本在每个星期天的凌晨 2 点运行,编辑您的crontab文件,如下所示:

0 2 * * 0 Rscript /mypath/myscript

这将自动以所需的频率运行您的脚本,提取原始数据并用新数据覆盖您的应用程序访问的文件。

如果您使用的是 RStudio Connect,您可以为包含脚本的 R Markdown 文档设置,以便使用文档的“设置”菜单刷新到计划。

所以你有它。一个完全自动化的应用程序,可以自我刷新。想想如果你能设置好这个,你能节省多少时间。不客气

你可以在这里 了解更多关于 Shiny Server 和 RStudio Connect

最初我是一名纯粹的数学家,后来我成为了一名心理计量学家和数据科学家。我热衷于将所有这些学科的严谨性应用到复杂的人的问题上。我也是一个编码极客和日本 RPG 的超级粉丝。在LinkedInTwitter上找我。

如何使用 Scrapy,ScrapingHub 和亚马逊 S3 建立重复的网络蜘蛛工作

原文:https://towardsdatascience.com/how-to-build-recurring-web-spider-jobs-using-scrapy-scrapinghub-and-amazon-s3-43dbe3c73b69?source=collection_archive---------3-----------------------

最近我和一个好朋友一直在尝试自学机器学习。根据许多行业专家的说法,在未来 10-15 年内保持有收入的工作是编程世界的必要的下一步。

注:如果你听说过同样的事情,但不确定从哪里开始,我会给你指出这个不可思议的 中帖 和这个 Coursera 课程 来开始。

我们很快遇到的一个问题是需要一个数据集。虽然世界上有很多令人难以置信的有趣的数据集可以免费下载,但我们有特定的兴趣(火箭发射,太空探索,火星等等。)并认为通过刮刮来建造我们自己的会很有趣。

就我个人而言,我从来没有构建过一个 scraper(或者使用 Python),但是我认为这不会太难。我们花了大约一天半的时间来构建我们的蜘蛛,让它们按照每天的时间表运行,并将数据放入 S3 桶中。

很难找到任何关于这个过程的指南,所以我想我应该写下我们是如何做的,并在互联网上公开我们的过程。如果您看到我们做错了什么,请随时告诉我们如何才能做得更好。我们正在学习。

建造蜘蛛

  1. 安装Scrapy——他们的文档是令人敬畏的。如果您遵循安装指南,应该没有问题
  2. 安装依赖项: boto (可能已经安装,这取决于你如何安装 Scrapy) & dotenv (这是为了不检查 AWS 的秘密到我们的 VCS)
  3. scrapy startproject directoryname建立一个新的 Scrapy 项目

您应该有一个scrapy.cfg文件和一个目录(在上面的步骤中命名。)在目录内部,您将看到 Scrapy 的工作原理。首先,我们将使用settings.py/spiders目录。

让我们开始建造蜘蛛。进入您的/spiders目录并创建一个新的spidername.py文件。这里有一个使用 CSS 和 XPath 选择器的蜘蛛示例。

这是一个难以置信的简化版本,但让我们现实一点。你的需求会有所不同,Scrapy 的文档比我在这篇文章中写的要好 100 倍。重要的是要认识到,你可以创建多个spider.py文件,并为不同的网站有不同的蜘蛛。

一旦你的蜘蛛启动并运行,下一步就是正确设置你的settings.py文件。

Scrapy 为您提供了大量样板代码。我只包括我修改过的相关部分。您会注意到几件重要的事情:

  1. 通过遵守robots.txt并在抓取之前手动检查每个网站的服务条款,我们成为了互联网的好公民。我们不刮那些要求不被刮的网站。
  2. 我们使用dotenv来保护我们的 AWS 访问密钥 id 和秘密访问密钥。这意味着您将在与settings.py相同的目录中拥有一个.env文件。您会希望将.env包含在您的.gitignore中。
  3. Scrapy 的超级合法部分是,你需要的只是为它设置的几个选项,以处理向 S3 的推送。

酷毙了。我们已经准备好了。一旦我们给了它正确的凭证,蜘蛛就被构建好了,并且settings.py已经准备好将数据推送到 S3。

设置 AWS

如果你不熟悉 AWS,它可能会相当吓人。我们需要做两件事:

  1. 创建一个 IAM 用户,并获取访问密钥 id 和秘密访问密钥
  2. 设置一个存储桶并添加正确的权限

IAM 用户可能有点棘手,所以我建议阅读 AWS 的文档。实际上,您需要登录 AWS 控制台,进入 IAM 部分,创建一个新用户,然后生成一个访问密钥。我建议创建这个用户仅仅是为了对您的 bucket 进行 API 调用。您将需要来自您创建的用户的三个字符串。把它们保存在安全的地方。

  • 用户 ARN
  • 访问密钥 ID
  • 秘密访问密钥

现在,让我们设置一个新的铲斗。这很简单。创建您的存储桶,然后导航至“权限”选项卡。您需要设置一个 bucket 策略,允许您刚刚创建的 IAM 用户将数据推送到这个 bucket。这是我们的样子:

必要时,交换[your-user-id][your-bucket-name]部件。这可能不言而喻,但不包括[]。

最后,将访问 id 和密钥添加到 Scrapy 项目中的.env文件中。

部署到报废网络

ScrapingHub 是由支持 Scrapy 和十几个其他开源项目的了不起的人运营的一个漂亮的服务。手动触发蜘蛛抓取是免费的,但它有一个非常合理的价格 $9 /月计划,允许单个蜘蛛在任何给定时间并发运行。对于我们的需求,它允许我们每 5 分钟调度不同的蜘蛛,即 280+独特的蜘蛛,只要它们的运行时间是< 5 分钟。

我们在最后冲刺阶段。这部分很简单。您将创建一个 ScrapingHub 帐户,登录并生成一个 API 密钥。你将安装 shub,清除掉 Hub 的命令行界面,并按照指示添加你的密钥和项目 ID。

注意:如果你已经用.env混淆了你的 AWS id &密钥,那么在部署到 ScrapingHub 之前,你需要在你的settings.py中注释掉几行。即上面要点中的第 5-7 行和第 14-18 行。

一旦一切就绪,你就可以使用shub deploy将你的项目推向报废。

您需要做的最后一件事是进入蜘蛛设置区域,手动添加 AWS 凭证。您会注意到,我们还添加了一个超时,以确保如果出现任何错误,我们会正常失败。

你完了!嗯,差不多了。

我建议首先至少手动运行一次蜘蛛,检查 S3 桶中生成的文件,并确保您对所有结果都满意。一旦你对此感到满意,转到你的项目的定期作业部分,设置你的蜘蛛在你需要的任何时间间隔运行。例如,世界协调时每天 04:30。

摘要

我意识到这并不是对每一行代码或点击的每一个按钮的完全详尽的指导,但希望它能让你步入正轨。接下来,我们将获取生成的 CSV 文件,规范化数据,并将其插入 Postgres 数据库。

请关注我的最新消息!

如何打造值得信赖的 AI 产品

原文:https://towardsdatascience.com/how-to-build-trustworthy-ai-products-3f49de63209a?source=collection_archive---------7-----------------------

Photo by Andy Kelly on Unsplash

你不能只是在一个项目中添加人工智能,然后指望它能工作。它不是可以洒在产品上的魔法粉。

建立融入人们生活的系统的关键是信任。如果你没有足够的信任,你就会让这个系统被废弃和滥用。

这篇文章(以及下面的这个对应的对话)最初是为 5 月 30 日作为产品学校的一部分,开始接触数据科学、机器学习和人工智能的产品人员创建的。虽然对 AI/ML 有一个简单的介绍,但是更有经验的从业者可以学习很多关于 AI 中信任的东西。

信任 101

信任之所以重要,是因为它有助于促进合作行为。这是我们创造复杂社会的基石。

归结起来有几个关键点:

  • 合同——书面或非书面
  • 关注对未来的期望
  • 基于过去的绩效、问责制和透明度
  • 构建缓慢,但可能很快丢失

信任和机器有什么关系?

当我在一家名为 Complete Seating 的餐厅初创公司工作时,我们开发了许多功能来帮助主人管理他们的餐厅地板。我们包括了智能等候名单时间和自动餐桌推荐。

我们当时称之为分析、商业智能、预测和约束编程,但如果我们今天筹集资金,它应该被称为“人工智能餐厅管理”。

不幸的是,我们没有获得他们的信任,因为我们缺乏信任的三个关键方面中的两个:性能和透明度。

  • 性能——这是一个测试版产品,起初它没有达到预期。一旦服务开始发挥应有的作用,我们就有一座大山要爬上去重建信任。
  • 责任——当出现问题时,我们总是会接听他们的电话,或者出现在现场提供帮助。他们知道我们在尽力帮忙,但还是没有解决另外两个问题。
  • 透明性——我们没有给他们很好的抽象概念,所以他们可以理解幕后发生的事情。他们想应用他们的专业知识,但他们不知道我们涵盖了什么。

我们最初试图通过向主机提供更多的上下文来解决这些问题。

回顾过去,我们应该从指出主持人可能犯的错误开始,而不是混淆整个座位引擎。

机器如何与人类建立信任?

当我们考虑与他们建立信任时,我们需要以人为中心。这是我认为未来几年人工智能面临的最大危险之一。

使用相同的框架,我们可以如下考虑机器构建信任:

  • 性能——这不像传统的准确度、精确度和召回那么简单。我们需要担心对人类目的来说什么是正确的度量标准。
  • 责任——关于系统的设计者在他们的操作中需要承担什么责任,有许多道德和法律问题需要回答。
  • 透明度——我们如何构建可解释的系统,提供适应性的行动,提供控制感,允许人类干预,并获得反馈以改进系统。

查看演讲深入了解这些关键方面。

对于机器来说,什么是正确的信任级别?

在《人类与自动化:使用、误用、废弃、滥用》一书中,他们讨论了人们基于信任使用自动化的各种方式:

  • 使用—“[自动]由操作员激活或解除自动化。”这是信任达到“正确”程度的时候。
  • 误用—“[过度]依赖自动化,这可能导致监控失败或决策偏差。”这是人类过于信任系统的时候。
  • 当人类对自动化不够信任时,就会出现弃用——“[忽视]或未充分利用自动化……”。
  • 滥用—“[自动化]功能…没有适当考虑对人的表现的后果…”当设计自动化时没有考虑操作者(或那些受影响的人)时,就会发生这种情况。从我的角度来看,这是我认为未来几年人工智能面临的最大危险之一。

我们怎样才能了解对机器的信任?

我们可以通过原型和研究来了解对信任的期望和需求。

在构建原型时,您不需要实际构建和训练模型。你只需要考虑几种不同的情况,然后假装:

  • 正确操作或“快乐路径”
  • 不正确的操作—自动化的误报/漏报
  • 理解“正确”信任级别的误用/废弃边界的两边
  • 从人到机器的反馈的适当场景
  • 为你的抽象陈述从机器到人类的交流

我还发现,当开始构建时,使用“绿野仙踪”或“门房”方法来开发人工智能的 MVPs】可以帮助你专注于你真正需要学习的东西。

最后

请记住:

  • 使用人工智能就像任何其他有权衡的技术一样…你应该意识到其中的细微差别。
  • 建立适量的信任——不多也不少。
  • 信任基于绩效、责任和对人类的透明性。

请观看视频了解完整的演讲以及每一点的更多细节。

关于克里斯·巴特勒

我帮助团队理解他们应该用以人工智能为中心的解决方案解决的真正的商业问题。我们工作的团队通常被要求用他们拥有的数据做一些有趣的事情(T2)。我们通过偶发事件相关性帮助他们避免局部极值,并专注于解决巨大的业务问题。我的背景包括在微软、KAYAK 和 Waze 等公司超过 18 年的产品和业务开发经验。在 Philosophie,我创造了像机器移情映射和混淆映射这样的技术,以在构建人工智能产品时创建跨团队对齐。如果你想了解更多或者通过邮箱、 LinkedIn 联系,或者访问http://philosophie.is/human-centered-ai。

幻灯片:

[## 克里斯·巴特勒- PS 演示

旧金山、硅谷、洛杉矶、纽约、奥斯汀、波士顿、西雅图的兼职产品管理课程…

docs.google.com](https://docs.google.com/presentation/d/e/2PACX-1vQt1aD_sq_zvVC9ulRgEWBUpasLb07gjss6VVTHQHu5Rsw6yJq8_XuBruyIJhsHJPx8an4lI5e1d-LB/pub?start=false&loop=false&delayms=3000)

参考资料:

  • 数据科学、机器学习、人工智能有什么区别?
  • 回路中的机器接近
  • 星球大战社交网络
  • 以人为中心的机器学习
  • 机器的移情映射
  • 混淆映射
  • 你的顾客应该被人类还是人工智能欺骗?
    “礼宾”vs“绿野仙踪”MVP
  • WoZ 方式:实现实时远程交互原型&在路上车辆中观察
  • 康奈尔大学的温迪·朱
  • TWiML & AI 播客#110 与 Ayanna Howard
  • 急救机器人视频
  • 安慰剂按钮(假恒温器)
  • 控制偏差错觉
  • 那是我们的出口!
  • 道德崩溃区
  • 计算机化社会中的问责制
  • 在用户研究中测试人工智能概念
  • 对心智模型的一些观察(1987)
  • 人类与自动化:使用、误用、废弃、滥用 (1997)
  • 紧急疏散场景下机器人的过度信任 (2016)
  • 自动化中的信任:整合影响信任因素的经验证据 (2015)
  • 零、一或无穷大规则
  • 中数定律
  • 谢恩·勒温,精益人工智能产品开发
  • NYT MTA 地铁危机篇

如何用 Python 从零开始构建自己的神经网络

原文:https://towardsdatascience.com/how-to-build-your-own-neural-network-from-scratch-in-python-68998a08e4f6?source=collection_archive---------0-----------------------

理解深度学习内部运作的初学者指南

更新:当我一年前写这篇文章的时候,我没有想到它会受到这个的欢迎。从那以后,这篇文章被观看了超过 45 万次,有超过 3 万次鼓掌。它还登上了谷歌的首页,并且是“神经网络”的前几个搜索结果之一。你们中的许多人都联系过我,这篇文章对你们学习之旅的影响让我深感谦卑。

这篇文章也引起了 Packt 出版社编辑的注意。这篇文章发表后不久,我就被提出作为《用 Python 做 神经网络项目》一书的唯一作者。今天,很高兴和大家分享我的书出版了!

这本书是这篇文章的延续,它涵盖了神经网络项目在人脸识别、情感分析、噪声消除等领域的端到端实现。每章都有一个独特的神经网络结构,包括卷积神经网络,长期短期记忆网络和暹罗神经网络。如果你正在寻找用深度学习项目创建一个强大的机器学习组合,请考虑购买这本书!

你可以从亚马逊得到这本书: 用 Python 做的神经网络项目

动机:作为我个人更好地理解深度学习之旅的一部分,我已经决定从零开始建立一个神经网络,而不需要像 TensorFlow 这样的深度学习库。我认为,理解神经网络的内部工作对任何有抱负的数据科学家都很重要。

这篇文章包含了我所学到的东西,希望对你也有用!

什么是神经网络?

大多数介绍神经网络的文章在描述它们时都会提到大脑类比。在不深究大脑类比的情况下,我发现简单地将神经网络描述为将给定输入映射到期望输出的数学函数更容易。

神经网络由以下组件组成

  • 一个输入层x
  • 任意数量的隐藏层
  • 一个输出层
  • 一组权重在各层之间偏置W 和 b
  • 选择激活功能用于每个隐藏层,。在本教程中,我们将使用一个 Sigmoid 激活函数。

下图显示了 2 层神经网络的架构(注意,在计算神经网络的层数时,输入层通常被排除在外**

Architecture of a 2-layer Neural Network

用 Python 创建神经网络类很容易。

训练神经网络

简单 2 层神经网络的输出 ŷ 为:

您可能会注意到,在上面的等式中,权重 W 和偏差 b 是影响输出 ŷ.的唯一变量

自然,权重和偏差的正确值决定了预测的强度。从输入数据中微调权重和偏差的过程称为训练神经网络。

训练过程的每次迭代包括以下步骤:

  • 计算预测输出 ŷ ,称为前馈
  • 更新权重和偏差,称为反向传播

下面的序列图说明了这个过程。

前馈

正如我们在上面的序列图中看到的,前馈只是简单的微积分,对于一个基本的 2 层神经网络,神经网络的输出是:

让我们在 python 代码中添加一个前馈函数来做到这一点。注意,为了简单起见,我们假设偏差为 0。

然而,我们仍然需要一种方法来评估我们预测的“好性”(即我们的预测有多远)?损失函数允许我们这样做。

损失函数

有许多可用的损失函数,我们问题的性质决定了我们对损失函数的选择。在本教程中,我们将使用简单的平方和误差作为我们的损失函数。

也就是说,平方和误差就是每个预测值和实际值之间的差值之和。差值是平方的,因此我们可以测量差值的绝对值。

我们训练的目标是找到使损失函数最小化的最佳权重和偏差集。

反向传播

既然我们已经测量了预测的误差(损失),我们需要找到一种方法来传播误差回来,并更新我们的权重和偏差。

为了知道调整权重和偏差的合适量,我们需要知道损失函数相对于权重和偏差的导数。

回想一下微积分,函数的导数就是函数的斜率。

Gradient descent algorithm

如果我们有导数,我们可以简单地通过增加/减少来更新权重和偏差(参考上图)。这就是所谓的梯度下降

然而,我们不能直接计算损失函数关于权重和偏差的导数,因为损失函数的方程不包含权重和偏差。因此,我们需要链式法则来帮助我们计算它。

Chain rule for calculating derivative of the loss function with respect to the weights. Note that for simplicity, we have only displayed the partial derivative assuming a 1-layer Neural Network.

唷!这很难看,但它让我们得到了我们需要的东西——损失函数相对于权重的导数(斜率),这样我们就可以相应地调整权重。

现在我们有了这个,让我们把反向传播函数添加到我们的 python 代码中。

为了更深入的了解微积分的应用和反向传播中的链式法则,我强烈推荐 3Blue1Brown 的这个教程。

把所有的放在一起

现在我们已经有了完整的 python 代码来进行前馈和反向传播,让我们将我们的神经网络应用于一个例子,看看它做得有多好。

我们的神经网络应该学习一组理想的权重来表示这个函数。请注意,仅仅通过检查来计算重量对我们来说并不简单。

让我们训练神经网络 1500 次迭代,看看会发生什么。查看下面的每次迭代损失图,我们可以清楚地看到损失朝着最小值单调递减。这与我们之前讨论过的梯度下降算法是一致的。

让我们看看神经网络经过 1500 次迭代后的最终预测(输出)。

Predictions after 1500 training iterations

我们做到了!我们的前馈和反向传播算法成功地训练了神经网络,并且预测收敛于真实值。

请注意,预测值和实际值之间略有不同。这是可取的,因为它防止过度拟合,并允许神经网络更好地将推广到看不见的数据。

下一步是什么?

幸运的是,我们的旅程还没有结束。关于神经网络和深度学习,还有很多东西需要学习。例如:

  • 除了 Sigmoid 函数之外,我们还可以使用什么其他的激活函数
  • 训练神经网络时使用学习率
  • 使用卷积进行图像分类任务

我很快会写更多关于这些话题的文章,所以请在 Medium 上关注我,留意它们!

最后的想法

从零开始编写自己的神经网络,我确实学到了很多。

尽管 TensorFlow 和 Keras 等深度学习库可以在不完全了解神经网络内部工作原理的情况下轻松构建深度网络,但我发现,对有抱负的数据科学家来说,更深入地了解神经网络是有益的。

这个练习花费了我大量的时间,我希望它对你也有用!

如何计算各行业的流失率

原文:https://towardsdatascience.com/how-to-calculate-churn-rates-across-industries-68c692b64605?source=collection_archive---------0-----------------------

一个可悲的商业事实是,你不可能永远留住客户。随着时间的推移,你会失去客户,因为他们的需求不断变化,竞争加剧,或者只是因为他们离开(如果你是一个实体零售商)。

你在一段时间内失去的客户百分比被称为你的流失率,或者简称为流失率。了解你的客户流失对于控制你的客户获取成本和确保你的业务增长至关重要。你要确保增加客户的速度快于失去客户的速度!

计算你的客户流失看起来很难。事实上,客户流失可能是你在业务中使用的最复杂的指标,因为很难可靠地定义和计算。在这篇文章中,我们将涵盖许多不同的方法来计算客户流失,即使我们不强调一种方法适合你的业务,给你的想法,就如何计算自己的客户流失。

具体来说,我们将涵盖:

  • 第一部分 —定义流失
  • 第二部分 —收入流失
  • 第三部分 —交易型流失
  • 第四部分 —合作

异常值 监控您的业务数据,并在发生意外变化时通知您。 我们帮助营销/增长&产品团队从他们的业务数据中获取更多价值。 今天安排一个演示

让我们从定义客户流失的确切含义开始,并理解为什么说起来容易做起来难。

第一部分。什么是流失?

在我们开始分析我们的客户流失之前,我们需要就一个定义达成一致。流失率通常被定义为你失去现有客户的比率。在这种情况下,通过以下方式计算客户流失应该很容易:

A typical churn calculation that disregards time

然而,这并不完全清楚!我们什么时候衡量客户流失?我们从哪一点开始计算我们的客户总数?为了做到这一点,我们需要测量特定时间窗口内的客户流失。因此,客户流失率通常是按月来衡量的:

Typical churn calculation by month

这更有道理,但仍有一个大问题。我们如何定义客户总数?如果当月增加客户,要不要统计?他们在第一个月没有机会流失,所以这可能会扭曲我们的指标。为了解决这一问题,仅对当月开始的客户计算流失率:

Churn calculation for customers at start of month

这更好,因为现在我们可以了解有多少开始这个月的客户在这个月流失了。这仍然不能捕捉到在第一个月开始并流失的客户,但至少他们不会扭曲我们的计算。

即使在三次迭代之后,该解决方案仍然存在许多问题:

  • 延迟洞察。在任何给定的时间,你最近的客户流失指标至少是一个月前的。三月份,您将获得的最新客户流失指标来自二月份!这使得实时解决客户流失问题变得困难。
  • 顾客交融。这一指标无法区分与您合作多年并流失的客户和最近成为客户并在下个月离开的客户。将这些价值观融合在一起,就无法判断你是在失去长期客户还是短期客户!

我们可以继续完善我们的等式[1],但是,最终,您使用的流失计算将取决于您希望它包含的内容。你想每周都进行客户流失测量吗?你想用不同的方式衡量你的顾客吗?没有神奇的、单一的客户流失方程式,因为每个公司对客户流失的看法都不一样。

要创建你的客户流失公式,就像我们上面做的那样,列出它需要包含的重要特性,并对其进行提炼。注意不要把它弄得太复杂,因为它变得越复杂,就越有可能有人在某个时候计算错误,你就会有一个误导性的指标。

第二部分。收入流失

到目前为止,我们已经介绍了如何根据一段时间内获得和失去的客户来计算客户流失率。然而,并不是所有的顾客都是平等的!如果一个每月付给你 10 美元的客户流失了,那也没有失去一个每月付给你 1000 美元的客户重要!事实上,低价客户留存率高,高价客户留存率低是很常见的。这将被我们昨天讨论的流失计算所隐藏。

收入流失是另一种思考流失的方式,它关注的是你如何从客户那里保持收入。如果您的客户有各种各样的定价,这可能是一种更有用的思考客户流失的方式。

在计算收入流失时,您的第一反应可能是像我们的客户流失公式一样处理它:

Calculating churn for revenue.

然而,计算收入不同于计算客户,因为任何给定的客户都可能在给定的一个月内开始多付或少付你钱。我们需要更具体地了解“收入损失”的含义:

A better way to calculate churn for revenue, this time accounting for upgrades

我们已经用一个简单的等式代替了“收入损失”,该等式从每月第一天的总收入开始,减去该月最后一天来自这些客户的收入(从而得出损失的收入),然后减去升级的价值。我们需要减去升级,因为如果您的客户向上销售非常有效,它们可能会隐藏客户的流失。

这个等式的一个有趣的副作用是,如果你的客户升级率高于客户流失率,你的收入流失率可能是负数!这被认为是非常好的,因为负收入流失率是建立高增长业务的关键因素[1]。

第三部分。事务性流失

大多数交易业务,如电子商务,使用重复购买率等指标来评估客户保持率。这是因为客户流失指标要求您知道何时会失去客户,这对于交易型企业来说非常困难。在订阅业务中,你知道他们何时会取消订阅,但如果是一个网站,客户可以随心所欲地来来去去,那该怎么办?但是,难不代表不值得做!

确定何时失去交易型客户的一个常用方法是使用活动时间窗口。每当顾客购物时,你就启动一个计时器。如果同一个客户在一段时间内没有回来,你就认为他们被解雇了。我在下面举例说明了这一点:

Using a purchase history window to measure customer churn

这很有道理,但是如果同一用户在你把他们标记为“搅动”的第二天又回来购买,你会怎么做呢?

Options to handle a use-case where the customer has churned: treat them as a new customer or re-calculate churn rates.

对于如何处理这些情况,您有几个选择:

  • 把他们当成新客户。将回头客视为新客户似乎是欺骗,但如果你的时间足够长,这可能是最好的。如果你的网站和产品在客户上次购买你的产品后的 6 个月内发生了显著的变化,他们的体验将是全新的,他们在大多数方面都将是一个新客户。
  • 重新计算你的流失率。每个月,你可以重新计算过去一年的流失率,因为你可以识别那些被认为已经流失但后来又回来购买的客户。这是最准确的方法,但在实践中最难使用,因为您过去的指标会不断变化!

这似乎很容易,尽管选择你的时间窗口是至关重要的。你是用一周,一个月,还是几个月?如果你选择的窗口太短,你会显示一个人为的高流失率。如果你选择的时间太长,那么你不会知道你什么时候失去了顾客,直到他们离开很久以后。您将需要利用您对业务和典型使用模式的了解来做出明智的选择,如果您觉得客户流失指标不能反映真实的客户流失,请重新进行评估。

第四部分。合作

不管你用什么方法来衡量客户流失,所有的方法都很大程度上依赖于使用预先确定的时间间隔(比如几个月)。这种方法的一个挑战是,它可以通过混合许多不同类型的客户来隐藏长期趋势。例如,在一个特定的月份里,你可能会失去三个和你在一起超过一年的客户,和 10 个只和你在一起一个月的客户。你可能想知道为什么你会失去这三个长期客户,但是他们可能会被你的流失指标所淹没。

出于这个原因,客户流失几乎总是根据客户群来衡量和可视化。这种协作可以让你看到,随着你改进产品、调整定价和对业务做出其他改变,客户流失是如何随着时间的推移而变化的。例如,群组可以是客户开始使用你的产品的月份。

让我们来看一个数字示例,说明客户是如何通过每月的购买群体流失的。在这个例子中,我将使用保留率(这是流失率的倒数),因为它可以更直观地看到保留率随着时间的推移而下降,而不是流失率增加。你觉得哪个更容易理解取决于你:

对于每个月(3 月至 9 月),该图表显示了客户首次成为客户后每个月的流失情况。第一行表示,对于 3 月份开始的客户,此后每个月的保留率。第 0 个月将始终是 100%,因为该月是客户成为客户的第一个月,因此他们不会有变动。在这一行中,每个群组的保留率始终小于或等于前一列中的值,因为群组无法增加久而久之。

请注意,并非所有行都有 7 个月之后的值,因为这些月份可能还没有发生!这张图表是在假设现在是 10 月份的情况下查看您的数据,因此 9 月份获得的客户只有一个月的时间来衡量他们的保留率。

按群组考虑人员流动会很容易发现模式。从第 1 个月开始,从 3 月份开始,我们的客户保持率约为 2%,直到 7 月份开始下降,9 月份获得的客户一直下降到 1.21%。很明显,我们在业务中所做的一些改变导致了第 1 个月更高的流失率,我们需要解决这个问题!

回顾:流失率可能很难计算,但随着时间的推移,它是了解和提高客户保持率的非常有价值的工具。无论你从事哪种业务,你都可以也应该把流失率作为一个关键的绩效指标来衡量。

离群值 监控您的业务数据,并在发生意外变化时通知您。 我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。 今天安排一个试玩

[1]为了更好地了解负收入流失及其如何创造高增长,我推荐 Tomasz Tunguz 的帖子。

[2]重复购买率是再次购买的顾客的百分比。它为您提供了一个简写方式,让您知道在给定的时间范围内,新客户或现有客户购买了多少商品。理想情况下,随着你积累更多的忠实客户,这个比率会随着时间的推移而增加。

如何计算你的荟萃分析的统计功效

原文:https://towardsdatascience.com/how-to-calculate-statistical-power-for-your-meta-analysis-e108ee586ae8?source=collection_archive---------3-----------------------

生物行为科学领域的大多数研究在统计上不够有力,这降低了具有统计显著性的发现反映真实效果的可能性。

元分析是一种流行的方法,用来综合解决特定研究问题的大量研究。然而,在规划或解释荟萃分析时,很少考虑统计能力。这可能是因为没有可访问的软件或 R 脚本来计算元分析功效,像 G*Power 或“PWR”R package,它们是计算主要研究的统计功效的伟大选项。

多亏了这篇论文中的公式,我写了自己的脚本来计算随机效应元分析的功效。只需在下面的脚本中输入您预期的汇总效应大小、每组参与者的平均人数、效应大小的总数以及研究异质性。

下面是一系列异质性水平、汇总效应大小、分组样本大小和包含样本大小总数的统计功效。

Effect sizes of d = 0.2, d = 0.5, and d = 0.8 are considered small, medium, and large effect sizes. As per convention, 80% statistical power is considered sufficient.

有趣的是,在大多数情况下,荟萃分析足以检测大的汇总效应大小(底部一行)。然而,在大多数情况下,它们很难有足够的能力来检测微小的影响(顶行)。检测中等效应的能力(中间一行)是一个大杂烩,似乎很大程度上取决于研究的异质性。

更新:感谢 Jakob Tiebel ,他组装了一个 Excel 计算器来使用相同的公式计算您的元分析的统计功效。对于不熟悉 r 的人来说是一个很好的选择。

想要一步一步的指导来执行你自己的相关性元分析吗?看看我的论文和相关的视频。如果你已经在度过了这个,你可能会喜欢万物赫兹,这是我共同主持的元科学播客。这是我们关于元分析的集。

如何计算你公司的增长率

原文:https://towardsdatascience.com/how-to-calculate-your-companys-growth-rate-63b6852638c6?source=collection_archive---------0-----------------------

你的业务是否在增长是一个重要的事实,但了解它的增长速度可能很难确定。正如我们在客户流失调查中看到的那样,甚至很难定义一个像增长这样的简单指标,甚至更难计算它。那么你的业务增长有多快呢?

你的增长率是未来分配资源的一个重要指标。如果你的业务增长速度超过了你的承受能力,你可能会发现自己的负担太重了。如果增长太慢,你的企业可能无法生存。增长对你意味着什么将影响你如何计算你的增长率,以及你如何使用这个指标。

误导性的正增长率可能代表数据的阴暗面,使人们认为你的业务比实际增长得更快。有时这是有目的欺骗的结果,有时是基于计算增长的复杂性的诚实错误。赌注很高,因为大多数企业的增长率与其整体盈利能力一样重要。

在这里,我们将深入探讨是什么让增长率难以定义,以及如何确保增长率指标的可靠性。具体来说,我们将涵盖:

  • 第一部分 —定义增长
  • 第二部分 —复合增长率
  • 第三部分 —季节性增长
  • 第四部分 —预测增长

让我们从定义增长开始…

离群值 监控您的业务数据,并在发生意外变化时通知您。我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。今天安排一次演示。

直觉上,定义增长似乎应该很简单。给定一个像收入这样的指标,计算今天的收入比过去高多少应该很容易:

用这个简单的方法,增长率就是一个月到下一个月收入的百分比变化。如果我们要绘制一段时间内的收入图表,增长率就是每个数据点之间的变化率。以下面一家样本公司的收入随时间变化的图表为例:

Chart of simple growth rate: revenue over time

根据我们的简单公式,这家公司的增长率将是每月 10%的直线。

然而,如果我们透过表面看,上面简单的图表可以告诉我们许多不同的故事,因为这样一个简单的增长率可以隐藏许多事情。如果你的价格改变了呢?这一个月你获得和失去的客户呢?例如,考虑下面的两个图表,其中旧客户收入反映了每个月初之前的所有客户的收入,新客户收入反映了该月的新收入。

示例 A:

Segmented growth rate of revenue over time: new vs. old customers where old customers drive most growth

示例 B:

Segmented growth rate of revenue over time: new vs. old customers where new customers drive most growth

在示例 A 中,除了现有客户之外,业务还在稳步增长,新客户也在健康增长。在示例 B 中,企业正在快速流失客户,但却隐藏在新客户快速增加的背后!使用我们的简单公式,这两个示例将导致相同的增长率(两个示例中的面积图顶部)。

新老客户之间的这种混淆是增长率的一个重要问题,需要解决。零售店普遍存在这个问题,因为开设新店可以很容易地抵消老店销售额下降的影响。因此,零售商店的增长率是用一种叫做“同店销售额的指标来衡量的,这种指标只衡量开业至少一年的商店的增长率。这将真正的销售增长与新开业率区分开来。

你可以类似地修改你的增长率计算,并通过考虑你的流失率来隔离现有业务和新业务的增长。你需要做的就是从上面我们的增长率公式中减去它:

Growth rate calculation, including churn

正如我们上周讨论的,你的流失率实际上可能是负数,在这种情况下,它会增加你的增长率!

这种新的增长率公式可能是对我们业务的更好衡量,因为它清楚地告诉我们,在保留客户价值方面,我们的增长情况如何。然而,这种方法仍然存在挑战:

  • 短月。有些月份的天数(31)比其他月份(28 或 30)多,这意味着产生收入的时间更长。因此,二月看起来总是像一个缓慢增长的月份!由于假期的原因,几周的时间可能会变短,这使得我们的增长率超出了应有的范围。
  • 公制组件。理解增长的驱动因素和增长率本身一样重要。你将增长率分解成几个部分的能力与你如何计算增长率直接相关。

就像客户流失一样,增长率没有神奇的公式,你需要自己决定如何最好地衡量你的业务增长。到目前为止,我们所介绍的内容应该足以让您开始定义业务增长,并找到相应的计算方法。

第二部分。复合增长率

很容易想到一个月到下一个月(或几天或几周)的增长率。然而,增长率通常会被考虑更长的时间,因为在你的增长中可能会有很多变化。

为了说明这一点的重要性,让我们以一家公司为例,这家公司每月收入稳定增长 1,000 美元(每月流失率为 0)。他们的总收入图表是一条简单的直线,显示了持续增长的业务:

linear growth over time — a straight line

然而,如下图所示,这个线性增长率正在随着时间的推移而降低!

linear growth over time means a decreasing growth RATE!

这是因为随着公司的发展,1000 美元在总收入中所占的比例越来越小。最终,如果公司每月收入达到 100 万美元,他们每月增加的 1000 美元将只有 0.1%的增长!

每月 10%的持续增长率意味着你实际上在产生复合增长,也就是说你每个月都在更快地增长。同一家公司,从 1,000 美元的初始收入开始,以 50%的增长率持续增长,其总收入将增长如下:

Revenue growth on $1,000, with a consistent 50% monthly growth rate.

为了在一段时间内保持一个增长率,你的规模越大,你的增长速度就越快。对于那些设定未来增长率目标的公司来说,这是一个隐藏的陷阱——随着时间的推移,你设定的具体增长率目标越往后,就越难保持。

第三部分。季节性增长

到目前为止,在我们对增长率的探索中,我们做了一个隐含的假设,即您的业务全年将以大致相同的速度增长。大部分商家都不是这样!有些业务会在某些月份快速增长,而在其他月份收缩。以一辆冰淇淋车为例:在夏季的几个月里,生意会很兴隆,增长很快,只是在秋季和冬季,随着室外天气变冷,生意会萎缩。

在季节性很强的企业中,理解增长更难,但也更重要。从你的图表上看不出你是否在增长,以下连续两年季节性业务的收入图表就证明了这一点:

Growth in seasonal business becomes more complex to understand

我们需要重新思考我们最初关于增长的假设,因为在这些业务中,通过比较一个月与前一个月来计算增长并不是一个很好的增长衡量标准。如果你不相信我,这是上例中的业务在第二年的天真增长率:

Understanding growth becomes more complex with ups and downs!

很难从这张图表中获得太多,因为它从正增长率跳到负增长率,然后再跳回来。我们所能看到的是,夏季的几个月对生意不利,但我们在增长吗?

我们可以做得更好!让我们将每个月与前一年的同一个月进行比较,前一年是一年中的同一时间(季节)。你可以在下面看到:

For seasonal businesses consider modeling growth year over year to adjust for seasonality

我们的增长率稳定在 20%到 30%之间,直到 12 月份出现大幅增长。

这非常有用,我们可以利用它来了解我们的决策是如何影响业务的。

如果你的业务是季节性的,你可能想使用类似的方法,因为它使增长更容易理解,与你的业务更相关。

第四部分。预测增长

几乎在你定义了你的成长指标之后,你会想把它投射到未来。今年你会长得更快吗?你目前的增长速度会持续多久?你越能预测你未来的成长,你就能越准确地分配你的资源和提前计划。

不幸的是,真实世界的增长很难预测。例如,给定以下每日收入数据,让我们尝试预测下周每天的收入:

Forecasting growth can be difficult when looking at daily numbers.

像大多数真实世界的数据一样,这些数据中隐藏着模式和趋势,这使得外推变得困难。幸运的是,有一个简单的方法来模拟周期性周数据的增长。我们可以观察到,重复的循环意味着我们可以独立地关注一周中的每一天,而不是试图从整体上理解数据。这样一来,way 就可以使用像线性回归这样的技术来给我们一个下周每天的预测(阅读更多关于这个)。

例如,如果我们只分析周一,趋势实际上是一条直线!

consider forecasting trends by day of week to smooth out the noise from day of week fluctuations

通过为一周中的每一天创建单独的趋势,我们可以以相当高的准确度为我们认为下周每天的收入建立一个模型(我们可以使用更高级的技术,如双指数平滑来平滑单个估计值):

Aggregate your day of week trends into a single model to smooth out the noise from day of week fluctuations

有了这个预测,我们就可以像本周前几章那样计算未来的增长率了!

回顾:你的业务是否在增长是一个重要的事实,但是增长速度有多快却很难确定。您计算和预测增长的方式将取决于您对业务增长的定义,最好尽早做出决定。

离群值 监控您的业务数据,并在发生意外变化时通知您。我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。安排今天的演示。

  • Outlier 是 Strata+Hadoop World 2017 观众奖得主。

如何用 Apache Spark 和 Apache Kafka 实时捕捉和存储推文?使用云平台,比如 Databricks 和 GCP(第 1 部分)

原文:https://towardsdatascience.com/how-to-capture-and-store-tweets-in-real-time-with-apache-spark-and-apache-kafka-e5ccd17afb32?source=collection_archive---------8-----------------------

包含代码和教程的可重复的端到端解决方案

大家好,借此机会我想分享一个关于如何使用云平台如 Databricks谷歌云平台实时捕获和存储 Twitter 信息的例子 Spark StreamingApache Kafka 作为开源工具。

这次我们将使用 Spark 与 Twitter 进行交互,并通过 Producer 的 API 将数据带到 Kafka 主题。

在开始开发之前,必须理解一些基本概念:

Spark Streaming: 它是 Apache Spark core API 的扩展,以可扩展的方式响应近实时(微批处理)的数据处理。Spark Streaming 可以连接不同的工具,如 Apache Kafka、Apache Flume、Amazon Kinesis、Twitter 和 IOT 传感器。

Apache Kafka: 这是一个快速、可伸缩、持久、容错的发布订阅消息系统。Kafka 通常用于使用流数据提供实时分析的实时架构中。

我们开始吧!

  1. Twitter 应用:要获取推文,我们必须在Twitter devs注册并创建一个应用。Twitter 会给我们 4 个重要的价值观,让我们能够消费信息:
  • 消费者密钥(API 密钥)
  • 消费者秘密(API 秘密)
  • 访问令牌
  • 访问令牌秘密

2.Spark data bricks:data bricks 平台允许我们创建一个免费的 Spark-Scala 集群。我们必须注册 Databricks ,然后创建一个 scala 笔记本,我们将在其中编写代码。

在编写代码之前,我们必须创建一个集群并导入两个库,Twitter library将允许我们将 Twitter API 与 Spark 和 KafkaLibrary 一起使用,这有助于我们连接 Apache Kafka。****

这里是如何使用 Maven 导入库的文档:https://docs.databricks.com/user-guide/libraries.html

创建集群:

然后,我们必须选择选项:导入库

然后,我们选取漫威坐标为源,写出库名:spark-streaming-Kafka-0–10 _ 2.11。

之后,我们对spark-streaming-Twitter _ 2.11做同样的事情

现在,我们只需要让我们的 Kafka 集群开始执行我们的开发。

3.Google 云平台中的 Apache Kafka:要创建集群,我们必须遵循以下步骤

a)在 GCP 创建一个实例并安装 Kafka,遵循下一个Kafka-Cloud教程。

b)启用并创建规则以公开端口 2181(zookeeper)和 9092(kafka)。从我们虚拟机的 ssh 控制台输入以下命令:(记住要更改变量 NAME_VM

***gcloud compute firewall-rules create rule-allow-tcp-9092 --source-ranges 0.0.0.0/0 --target-tags allow-tcp-9092 --allow tcp:9092**gcloud compute firewall-rules create rule-allow-tcp-2181 --source-ranges 0.0.0.0/0 --target-tags allow-tcp-2181 --allow tcp:2181**gcloud compute instances add-tags NAME_VM --tags allow-tcp-2181
gcloud compute instances add-tags NAME_VM --tags allow-tcp-9092***

c)配置 Kafka 属性文件以公开其服务,在 SSH 的下一个配置文件 server.properties 中添加以下参数。

***vi /usr/local/kafka/config/server.properties**listeners=PLAINTEXT://your_internal_ip_vm:9092
advertised.listeners=PLAINTEXT://your_external_ip_vm:9092***

d)最后,重新启动 Kafka 服务以使所做的更改生效。

***sudo /usr/local/kafka/bin/kafka-server-stop.sh**sudo /usr/local/kafka/bin/kafka-server-start.sh -daemon /usr/local/kafka/config/server.properties***

现在我们准备消费来自 Twitter 的数据,并将其存储在 Apache Kafka 的一个主题中,走吧!

在我们的笔记本中,我们输入以下代码:

你可以从 jmgcode 下载完整的笔记本

要查看 Kafka 中的消息,您可以在 GCP 环境中启动以下命令:By SSH

**sudo /usr/local/kafka/bin/kafka-console-consumer.sh --bootstrap-server your_internal_ip_vm:9092 --topic llamada**

working 😃

在 Databricks 中,我们可以跟踪我们处理的推文:

number of tweets per second

这就是目前的全部内容,在第二部分中,我们将看到如何在 rt 中对这些信息进行一些转换,并将结果存储在 Apache Hbase、Cassandra 或 Apache Kudu 等数据库中。

下期帖子再见:)…

**** [## jmendezgal/卡夫卡-twitter-spark-streaming-cloud

通过在 GitHub 上创建帐户,为 jmendezgal/Kafka-Twitter-spark-streaming-cloud 开发做出贡献。

github.com](https://github.com/jmendezgal/kafka-twitter-spark-streaming-cloud/blob/master/KafkaTwitterSparkStreaming.scala)****

如何使用 R 和 ggplot2 更改日期时间轴上的中断数

原文:https://towardsdatascience.com/how-to-change-the-number-of-breaks-on-a-datetime-axis-with-r-and-ggplot2-douglas-watson-338f0d353f05?source=collection_archive---------5-----------------------

我花了惊人的时间才找到如何在 ggplot2 日期时间轴上更改刻度间隔,而无需手动指定每个位置的日期。一旦你知道了语法,解决方案就出奇的简单明了:

scale_x_datetime(breaks = date_breaks("12 hours"))

这意味着每 12 小时休息一次。间隔可以是scales包接受的任何值:“秒”、“分”、“小时”、“天”、“周”、“月”或“年”。尾部的s被忽略。请阅读如何旋转标签文本的示例和说明。

例子

我们用一些假数据来说明。我重用了我的闪亮教程中的 CSV 数据。你可以在这里下载文件。格式如下所示:

"timestamp","date","origin","variable","value" 
1448315085.07,2015-11-23 21:44:45,"kitchen","temperature",24.4 
1448315085.07,2015-11-23 21:44:45,"kitchen","humidity",44.9 
1448315085.07,2015-11-23 21:44:45,"bedroom","temperature",24.8 
1448315085.07,2015-11-23 21:44:45,"bedroom","humidity",46.1 
1448318685.07,2015-11-23 22:44:45,"kitchen","temperature",23 
1448318685.07,2015-11-23 22:44:45,"kitchen","humidity",41.1 
1448318685.07,2015-11-23 22:44:45,"bedroom","temperature",23.6 
1448318685.07,2015-11-23 22:44:45,"bedroom","humidity",45.7 
1448322285.07,2015-11-23 23:44:45,"kitchen","temperature",23.4 
...

让我们将它加载到 R dataframe 中,确保将 date 列转换为 R datetime 对象(参见我的上一篇关于这个主题的文章,然后创建一个简单的温度-时间图:

library(ggplot2) 
library(dplyr) data <- read.csv("data.csv") 
data$date <- as.POSIXct(data$date) 
temperatures <- filter(data, variable == "temperature", 
                       origin == "kitchen") qplot(date, value, data = temperatures, geom="line", 
      ylab = "Temperature [C]")

默认的休息时间很合理,但是为了便于说明,让我们将它们改为每两天休息一次。标签格式遵循 strftime 语法(见http://www.foragoodstrftime.com/帮助构建它们):

qplot(date, value, data = temperatures, 
      geom="line", ylab = "Temperature [C]") + 
    scale_x_datetime(breaks = date_breaks("2 day"), 
                     labels = date_format("%b %d"))

你可以看到休息的次数已经改变了。很多时候,我更感兴趣的是增加它们的密度。让我们切换到以小时为单位的时间间隔,并在标签中包括时间:

qplot(date, value, data = temperatures, 
      geom="line", ylab = "Temperature [C]") + 
    scale_x_datetime(breaks = date_breaks("12 hour"), 
                     labels = date_format("%b %d - %H:%M"))

哎哟!标签不可读。幸运的是,我们可以旋转文本以防止它们重叠:

qplot(date, value, data = temperatures, 
      geom="line", ylab = "Temperature [C]") + 
    scale_x_datetime(breaks = date_breaks("12 hour"), 
                     labels = date_format("%b %d - %H:%M")) +
    theme(axis.text.x = element_text(angle = 25, 
                                     vjust = 1.0, hjust = 1.0))

那好多了!如果您将角度设置为 90 度,或者如果您有一个旧版本的 R,您将需要调整vjusthjust值,直到标签正确排列。尝试将debug = TRUE添加到element_text来显示文本锚点。

包括图书馆里的这些

我发现自己在许多 R 笔记本上加载相同的数据格式并制作类似的图形,所以我编写了一个小型函数库,可以在我的所有分析中重用。希拉里·帕克的指南解释了你自己写作所需要的一切。我的函数类似于下面的代码,我可以选择指定一个刻度间隔。如果我以小时为单位指定时间间隔,标签会自动包含时间。如果我将参数留空,ggplot 将保持其默认值:

plot_temperature <- function(data, title = "", breaks = "", angle = 25) {
    p <- ggplot2::qplot(date, value, data = data, 
                        ylab="Temperature [C]") 

    if (title != '') {
      p <- p + ggplot2::ggtitle(title)
    }

    if ( breaks != '' ) {
      if ( grepl("hour", breaks) ) {
        fmt <- "%b %d - %H:%M"
      } else {
        fmt <- "%b %d"
      }
      p <- p + ggplot2::scale_x_datetime(date_breaks = breaks, 
                                         date_labels = fmt) +
        ggplot2::theme(axis.text.x = ggplot2::element_text(
          angle = angle, vjust = 1.0, hjust = 1.0
        ))
    }
    return(p)
}

当您将函数移动到外部库时,指定您调用的每个函数的名称空间非常重要。于是ggplot2::分散各处。

原载于Douglas-Watson . github . io

如何选择数据科学工作?

原文:https://towardsdatascience.com/how-to-choose-a-data-science-job-53007d7f195f?source=collection_archive---------2-----------------------

这是数据科学的全盛时期…

Yes! Yes!Yes!

1。世界各地大学最热门的新课程都在这个领域。

2。数据科学家毕业生的起薪中值为 93,000 美元,令人印象深刻。

3。六位数数据科学工作的广告很常见。

数据科学似乎无愧于 21 世纪最性感工作的称号。”

但是随着这个领域的所有这些骚动,许多人想知道数据科学职业的趋势是否只是一种时尚。为什么要拿你的教育、职业和未来做赌注呢?

有这些犹豫是合理的。所有称职的数据科学家都应该知道用事实而不是直觉工作的重要性。

这就是为什么在下面的文章中,我们将揭示五种新兴角色如何产生公司不能忽视的已被证明的价值。

此外,我们将解释每个职位的共同期望和责任,以帮助你专注于获得你真正想要的工作。

在我们详细研究这五个角色之前,让我们先明确一下为什么数据科学工作如此有前途。

为什么从事数据科学职业是值得的?

数据科学角色将呈指数级增长

在我们热爱的领域里,工作是时尚的,但是不要让这种认为趋势是短暂的想法阻止你去学习更多关于这个主题的知识。

So far — So good (source: Indeed.com)

我们生活在数字时代,随着技术的进步,获取、存储和处理数据的能力也会提高。

公司需要人来管理和控制这些阶段。因此,随着工作领域的技术义务变得更加苛刻,对数据科学家的需求只会增加,这是合乎逻辑的一步。

但不要相信我的话:专家预测,未来三年内,新的数据和分析工作将增加 364,000 个。这不是一个可以掉以轻心的数字。

数据科学工作的竞争较少

预计的 364,000,000 个新工作岗位将需要人员来填补。

尽管在线和传统机构的数据科学课程数量惊人增长,但由于其快速增长,未来十年该领域不太可能出现员工过剩。

公司正在努力填补职位空缺。数据科学职位的开放时间比更传统的职位发布时间更长,例如,专业服务行业的分析经理职位平均需要 53 天,比该领域的平均时间多 8 天。

因此,众所周知,确实缺乏合适的候选人,现在是在就业市场上利用这一需求的时候了。

各行各业都感受到了数据工作爆炸的余震,包括:

休闲&旅游: Airbnb 建立了一所内部大学,专门研究数据科学。
金融:人工智能将被会计师用于减轻审计负担。
医学: IBM 计划在其大获成功的沃森人工智能的基础上,创建一个跨学科的数据科学网络。

除此之外,在这些领域和许多其他领域,公司需要熟练的工人来带领他们穿越数据科学的波涛汹涌的水域。

数据科学可能是你未来工作保障的最佳选择

机器人有一天将取代许多目前由人类完成的工作,这种想法不再是科幻小说中的东西,对于任何开始职业生涯的人来说,这都应该是一个值得关注的问题。

德意志银行首席执行官 John Cryan 在接受美国消费者新闻与商业频道采访时表示,在通过技术简化工作流程的过程中,金融领域的非技术性工作将不可避免地受到影响。

《卫报》最近报道称,在未来 10 年内,英国私营部门的 400 万份工作可能会被机器人取代。

虽然很少有工作不存在未来自动化的风险,但数据科学的吸引力在于它直接分析、管理和改变工作流程和公司信息的数字后端。

对于那些在未来不确定时期寻找工作保障的人来说,这是一个合理的——如果不是完全可靠的——计划。

我很高兴给你一个数据科学工作的顶级概述。为了更深入地了解这一领域,请参加 2018 年 10 月 12 日至 14 日在圣地亚哥举办的数据科学大会。

在本次会议上,您将从该领域的专家那里获得有价值的信息,帮助您开启数据科学职业生涯。

开启您的数据科学职业生涯

这三个原因应该会激起你对这个领域的兴趣…

但是数据科学家实际上是做什么的呢?什么是数据分析师与数据科学家?

不喜欢数据科学技术方面的人有什么选择?

查看以下五个关键角色及其职权范围,以表明该领域不仅对公司越来越重要,而且数据科学是 21 世纪最令人振奋的工作领域。

选择适合您的数据科学工作:

有许多职业道路可供选择,并且很难驾驭。为了帮助你找到理想的角色,以下是大多数广告中常见的五个头衔,以及对他们可能承担的职责的描述。

商业分析师:
这些类型的角色对许多公司来说都是舒适的领域,因为商业智能的概念在数据繁荣之前已经存在了很长时间。

因此,它们可能比更具分析性或需要编程知识的职位更具竞争力。

商业分析师不太可能自己分析数据。相反,他们应该将准备好的数据转化为公司未来运营的引人注目的视觉效果。

无论你的职责是什么,如果你有兴趣成为一名商业分析师,强大的表达能力是很重要的。

数据分析师(数据准备):
数据准备方面的专家才是真正的数据科学项目的中坚力量。数据准备不是一件容易的事情,在项目的这个阶段出现失误会导致失败。

在这些职位上,工作人员必须手动在无尽的数据行中搜寻,根据需要进行清理和结构化。这使得它成为一个繁琐而困难的过程,需要一些技术知识,更重要的是,相当注意细节。尽管有这些职责,这些角色通常被称为入门级职位。

这些工作对于那些可能已经上过数据科学课程并希望实践他们新获得的技能的人来说可能是理想的“实习”,以在承担其他责任之前增加他们在该领域的信心。在这个职位上证明你自己,你将比其他寻求立足之地的候选人更有竞争力。

数据分析师(建模)/数据建模师:
虽然名字相似,但数据分析师在建模方面实际上要比他们的数据分析师(数据准备)同行负责更多。

数据建模师的任务是开发能够管理和处理公司数据库的系统。编程专业知识对于这些角色来说是必不可少的。

虽然数据准备可能不是工作描述中的要求,但如果你准备数据集的技能不稳定,请谨慎从事:较小的公司可能会整合数据分析师的角色,这意味着除了数据建模员之外,你还可能被赋予数据准备员的职责。

数据科学家/高级分析师/机器学习(ML)从业者/高级数据科学家:
这些角色是数据科学跳动的心脏。任何想要解决这些问题的人都必须是一个多面手…并且是所有人的主人!对于这些职位,你必须精通数据科学项目的所有阶段。

对于普通读者来说,我们对这些迷人的角色垂涎三尺并不奇怪。这些工作需要人们跳出框框思考问题,然后为公司未来的健康发展创造可行的解决方案。

说了这么多,这些职位只适合喜欢主动的人。如果你想遵循一套严格的规则,在 5 点钟结束一天的工作,这些规则不适合你。

如果你喜欢挑战,如果你有创造力,如果你在工作中渴望编程和分析任务,立即申请吧!

数据科学经理/分析经理:
这些角色为回避更多技术职位的人开了绿灯。他们只是浏览了数据科学的表面——重点是客户和团队的一般管理。

管理职位自然最适合喜欢跨团队交流和与客户交流的人。由于它们不直接处理数据科学的技术方面,它们可能不适合希望成为“严肃”数据科学家的人。

这是因为经理们将忙于员工和预算控制,因此没有时间参与编程或分析。

然而,由于他们的管理职责,这些职位可能是那些已经在另一个领域进入职业生涯并计划转向数据科学的人的合理解决方案。

最终外卖

当你在寻找一份利润丰厚的数据科学职业时,把这些细目分类放在身边作为工作备忘单——它将帮助你快速剔除不太适合的职位。

请记住,虽然我们尽了最大努力来强调对每个角色的总体期望,但每个角色的实际工作规范会因公司而异。

和其他职位一样,在申请之前一定要通读说明书。数据科学家注重细节——确保你在应用中证明了这一点!

有关如何改善您的数据科学职业生涯的更多信息,点击此处参加我们 2018 年 10 月 12 日至 14 日的直播。

Click here to reserve your seat!

参考资料:

以下是领英 2017 届毕业生的前 15 份工作-https://tech.co/linkedin-jobs-grads-2017-05

数据科学家:21 世纪最性感的工作——https://HBR . org/2012/10/Data-Scientist-21 世纪最性感的工作

量子危机:对数据科学技能的需求正在扰乱就业市场—https://www . IBM . com/analytics/us/en/technology/data-science/Quant-Crunch . html

IBM 预测到 2020 年对数据科学家的需求将飙升 28%—https://www . Forbes . com/sites/louiscumbus/2017/05/13/IBM-Predicts-Demand-For-Data-Scientists-Will-Soar-28-By-2020/# 4 e5d 9 a 9 e 7 e 3 b

Airbnb 正在运营自己的内部大学,教授数据科学—https://TechCrunch . com/2017/05/24/Airbnb-is-running-its-own-internal-university-to-teach-data-science/

IBM 的 Watson 数据平台旨在成为数据科学操作系统—http://www . zdnet . com/article/ibms-Watson-Data-Platform-aims-to-be-Data-science-operating-system/

德意志银行首席执行官直言不讳地谈到自动化将对银行业的工作岗位产生什么影响—https://www . CNBC . com/2017/09/17/jobs-and-automation-Deutsche-Bank-CEO-cry an-warns-at-Singapore-summit . html

机器人“可能在 10 年内夺走 400 万份英国私营部门工作岗位”——https://www . the guardian . com/technology/2017/sep/19/Robots-can-take-400 万份私营部门工作岗位——10 年内

如何选择有效的机器学习和数据科学课程

原文:https://towardsdatascience.com/how-to-choose-effective-moocs-for-machine-learning-and-data-science-8681700ed83f?source=collection_archive---------1-----------------------

给希望学习数据科学/机器学习并为之做出贡献的非 CS 领域的年轻专业人士的建议。根据个人经验策划。

动机

比尔·盖茨在最近的毕业典礼上宣称,人工智能(AI)、能源和生物科学是当今年轻的大学毕业生可以选择的三个最令人兴奋和最有回报的职业。

我完全同意。

我坚信,我们这一代人面临的一些最重要的问题——与可持续性、能源生产和分配、交通、获得基本生活设施等有关。取决于我们如何明智地将盖茨先生提到的前两个知识分支结合起来。

换句话说,在物理电子世界(半导体行业构成了这个世界的核心部分),必须做更多的事情来充分享受信息技术的成果以及人工智能或数据科学的新发展。

我想学,但是从哪里开始呢?

我是一名半导体专业人士,在一家顶级科技公司拥有超过 8 年的博士后工作经验。我感到自豪的是,我在物理电子学的交叉领域工作,这直接有助于能源部门。我开发功率半导体器件。它们能够高效可靠地传输电力,从智能手机内部的微型传感器到处理日常消费食品或布料的大型工业电机驱动器,它们都可以供电。

因此,很自然地,我想学习和应用现代数据科学和机器学习的技术来改进这种设备和系统的设计、可靠性和操作。

但我不是计算机科学毕业生。我分不清链表和堆。支持向量机听起来像(几个月前)一些残疾人专用设备。我记得的人工智能的唯一关键词(来自我大三的选修课)是' 一阶谓词演算 ',这是所谓的'旧人工智能知识工程方法的残余,与较新的基于机器学习的方法相对。

我必须从某个地方开始学习基础知识,然后深入学习。显而易见的选择是 MOOC ( 大规模开放在线课程)。我仍然处于学习阶段,但我相信我至少已经积累了一些选择适合这条道路的 MOOC 的好经验。在这篇文章中,我想分享我在这方面的见解。

了解你的“气”和你的“敌人”

这是 Netlfix 最新的超级英雄系列剧——《守卫者》。

但确实,在开始通过 MOOC 学习之前,你应该非常清楚自己的优势、劣势和技术倾向。

因为,让我们面对现实吧,时间和精力是有限的,你不能把你宝贵的资源浪费在你在当前工作或未来工作中不太可能实践的事情上。这是假设你想走 (几乎)免费的学习道路,即旁听 MOOCs 而不是花钱买证书 。我有一个“差不多”在这里,因为在本文的最后,我想列出几个我认为你应该付费来展示证书的 MOOCs。就我个人而言,我不得不为我参加的几门 Udemy 课程付费,因为它们从来都不是免费的,但你可以在促销时以一份美味午餐三明治的价格购买它们。

What you can and cannot learn from MOOCs

在这幅图中,我只是想展示这个过程的可能性和不可能,即你希望通过自学和实践学到什么,以及无论你的职业是什么,在工作中必须学到什么或必须培养什么样的心态。然而,话虽如此,这些圈子广泛包含了一个人可以学习的核心技能,以便从非 CS 背景进入数据科学/机器学习领域。请注意,即使你在信息技术(IT)领域,你可能会有一个陡峭的学习曲线,因为传统的 IT 正在被这些新领域所破坏,核心技能和良好的实践往往是不同的。

就我而言,我认为数据科学领域比许多其他专业领域(例如我自己的工作领域半导体技术)更民主,在那里进入门槛低,只要足够努力和热情,任何人都可以获得有意义的技能。就我个人而言,我并没有“闯入”这个领域的强烈愿望,相反,我只是有一种热情,想借用这些成果来应用到我自己的专业领域。然而,这个最终目标并不影响人们必须经历的初始学习曲线。因此,你可以瞄准成为数据工程师、商业分析师、机器学习科学家或可视化专家——领域和选择都是敞开的。如果你的目标和我一样——停留在当前的专业领域,应用新学到的技术——你也很好。

你可以从真正的基础开始,这没什么不好意思的:)

我从真正的基础开始— 在 Codeacademy 上学习 Python。十有八九,你不能比这更基本:-)。但它成功了。我讨厌编码,但 Codeacademy 免费课程简单有趣的界面和正确的节奏足以让我继续下去。我本可以在 Coursera 或 Datacamp 或 Udacity 上选择 Java 或 C++课程,但一些阅读和研究告诉我,Python 是平衡学习复杂性和实用性(特别是对于数据科学)的最佳选择,我决定相信这种洞察力。

过了一段时间,你渴望更深层次的知识(但速度很慢)

odeacademy 的推出是一个良好的开端。我可以从这么多在线 MOOC 平台上选择,不出所料,我同时注册了多门课程。然而,在涉猎了几天 Coursera 课程后,我意识到我还没有准备好向教授学习 Python!我一直在寻找一门由一些热情的讲师讲授的课程,他们会花时间详细讲解概念,教我其他基本工具,如 Git 和 Jupyter notebook system,并在课程的基本概念和高级主题之间保持适当的平衡。我找到了这份工作的合适人选:何塞·马西亚尔·波尔蒂利亚。他在 Udemy 上为提供多门课程,并且是该平台上最受欢迎和最受好评的讲师之一。我报名完成了他的Python boot camp课程。这是对这门语言的惊人介绍,速度、深度和严谨都恰到好处。我向新学员强烈推荐这门课程,即使你不得不支付 10 美元( Udemy 课程通常不是免费的,它们的正常价格是 190 美元或 200 美元,但你总是可以等待几天,以获得经常性的推广周期,并注册 10 美元或 15 美元)。

保持对数据科学的关注非常重要

下一步对我来说至关重要。我可能会误入歧途,尝试学习 Python 上的任何东西。尤其是面向对象和类定义部分,很容易就能让你陷入漫长而艰难的旅程。现在,没有从 Python 世界的关键领域带走任何东西,可以有把握地说,您可以在不能够在 Python 中定义自己的类和方法的情况下实践深度学习和良好的数据科学。 Python 作为数据科学的首选语言越来越受欢迎的一个根本原因是,大量高质量、经过同行评审、由专家编写的库、类和方法的可用性,正等待着以一种良好的打包形式下载,并展开以无缝集成到您的代码中。

因此,对我来说,快速进入数据科学最广泛使用的包和方法非常重要——NumPy、 Pandas 和 Matplotlib 。

我是通过 edX 的一个简洁的小课程被介绍给这些人的。虽然 edX 上的大部分课程都是来自大学,性质严谨(而且长ish】,但是像微软这样的科技公司提供的短而多动手/少理论的课程很少。其中之一就是 微软数据科学专业计划 。你可以在这个项目下注册任意多的课程。然而,我只学了以下课程(我打算以后再来学其他课程)

  • 数据科学方向 :讨论典型的数据科学家的日常生活,并触及一个人在这个角色中应该具备的核心技能,以及对构成主题的基本介绍。
  • 数据科学 Python 入门 :讲授 Python 基础知识——数据结构、循环、函数,然后介绍 NumPyMatplotlibPandas
  • Excel数据分析入门:教授 Excel 的基本和少量高级数据分析函数、绘图和工具(例如透视表power pivot求解器插件)。
  • 数据科学用 R 简介 :用 ggplot2 介绍 R 语法、数据类型、向量和矩阵运算、因子、函数、数据帧、图形。

虽然这些课程以一种基本的方式呈现材料,并且只涵盖最基本的例子,但它们足以激发灵感!好家伙,我被迷住了!

我转而详细学习 R——有一段时间了

最后一门课程让我意识到几件重要的事情:(a)统计学和线性代数是数据科学过程的核心,(b)我不知道/已经忘得够多了,以及(c) R 自然适合于我想用我的数据集做的那种工作——由受控晶圆厂实验或 TCAD 模拟生成的几 MB 大小的数据,为基本的推理分析做好准备。

这促使我寻找一个坚实的 R 语言入门课程,还有谁比何塞·波尔蒂利亚更好呢!我报名参加了他的“ 数据科学和机器学习训练营与 R ”班。这是一笔“买一送一”的交易,因为课程在前半部分涵盖了 R 语言的基础知识,并转向教授基本的机器学习概念(入门课程中预期的所有重要概念都得到了足够的关注)。与使用基于服务器的动手实验室环境的 edX 微软课程不同,本课程涵盖了 R Studio 和必要软件包的安装和设置,向我介绍了 kaggle ,并为我从被动学习者(也称为 MOOC 视频观察者)转变为不怕玩数据的人提供了必要的推动力。它还遵循了加雷斯·詹姆斯、丹妮拉·威滕、特雷弗·哈斯蒂和罗伯特·蒂布拉尼所著的《》(ISLR)中的《统计学习导论》一章一章地讲述。

如果让你一生只看一本书学习机器学习,别的什么都不看,那就挑这本书,看完所有章节,无一例外。对了,这本书里没有神经网络或者深度学习的材料,所以有那个…

有了课程材料、ISLR 的书、从 kaggle 下载的随机数据集的练习,甚至是从 PG&E 下载的我自己的用电数据,我不再害怕编写小字节的代码,这些代码实际上可以模拟一些有趣或有用的东西。我分析了一些美国县级犯罪数据,为什么一个大型实验设计会导致虚假关联,甚至我公寓过去 3 个月的用电量。我还成功地使用 R 建立了基于我工作中的一些真实数据集的预测模型。语言的统计/功能性质和各种模型(回归或分类)的置信区间(p 值或 z 值)的现成估计确实有助于新手在统计建模领域轻松立足。

尽可能多学习数学基础知识

这方面的学习怎么强调都不为过——特别是对于非计算机专业的毕业生和 IT 工程师来说,他们在职业生涯中几年都没有接触过严谨的数学。我甚至写过一篇关于机器学习和数据科学需要具备哪些数学知识的中等文章。

Mathematics necessary to learn/refresh for gaining foothold in data science/machine learning

为此,我从 Cousera 和 edX 选择了几门课程。很少有作品在深度和严谨性上脱颖而出。那些是,

  • 数据科学和分析的统计思维 (哥伦比亚大学):哥伦比亚大学 edX 上的数据科学高管证书课程的基础统计课程。严谨,但以结构化的方式很好地深化了概念。
  • 计算概率与推理 (麻省理工):这是麻省理工出的硬题,要注意!它以无与伦比的深度涵盖了贝叶斯模型和图形模型等高级主题。
  • [统计学与 R 专业化](http://Statistics with R Specialization) ( 杜克大学):这是杜克大学的 5 门课程(最后一门是顶点项目,你可以忽略它)专业化,通过动手编程练习来增强你的统计学基础。推荐平衡难度和严格程度。
  • LAFF:线性代数——前沿基础(UT Austin):这是一门令人惊叹的线性代数基础课程(以及关于线性代数例程高性能计算的深入讨论),你必须尝试一下。由德克萨斯大学奥斯汀分校在 edX 平台上提供。相信我,在学完这门课程后,你将永远不会想求矩阵的逆来解一个线性方程组,即使这很诱人也很容易理解,但你会试图找到一种 QR 分解或乔莱斯基分解来降低计算复杂度。****
  • 商业分析中的优化方法 ( 麻省理工):这是麻省理工的一门商业分析优化/运筹学方法的课程。我报名是因为这是我能找到的关于线性和动态编程技术的唯一一门在 good platform (edX)上评价很高的课程。我相信学习这些技术会非常有帮助,因为优化问题会出现在几乎所有的机器学习算法中。

请注意,我没有搜索和注册任何微积分课程,因为我对我能记得的知识水平(从大学时代)和我期望对任何机器学习或数据科学研究和实践有用的知识感到满意。如果你在这方面生疏,请寻找一个好的。

更新:这是我写的一篇专门关注数据科学数学的文章。这篇文章被放在 KDNuggets 和 Medium editorial choice 的显著位置。所以,试试吧…

机器学习——各种各样的个性让它变得丰富多彩

在所有这些业余学习中,我设法完成了被认为是所有 MOOCs 先驱之一的课程——吴恩达在 Coursera 上的机器学习课程。我猜已经有很多关于它的文章了,因此,我不会再浪费你的时间来描述这个课程了。拿着它,做所有的家庭作业和编程作业,学会用你知道的所有主要机器学习算法的矢量化代码来思考,并保存笔记以备将来工作时参考。

哦,对了,如果你想温习/从头学习 MATLAB(这门课你会需要写 MATLAB 代码,不是 R 或者 Python),那么你可以看看这门课:MATLAB 编程入门

现在,我想谈谈个性。

我参加了多门机器学习课程,我最喜欢的方面是意识到对同一基础学科的处理如何成为不同讲师的个性和世界观的函数:)这是一次迷人的经历。

我列出了我注册并参与的各种机器学习 MOOCs

  • 【机器学习(斯坦福大学)】 :吴恩达广为人知的课程。上一段讲到了。
  • 【机器学习专业化(华盛顿大学) :这和 ng 的味道不一样。Emily Fox 和 Carlos Guestrin 分别从统计学家和从业者的角度介绍了这些概念。我不能安装 Carlos 的公司提供的免费许可 Python 包,但是这个专门化对于它的理论讲座来说是值得完成的。一些基本概念的证明和讨论,如偏差-方差权衡、成本计算以及成本函数最小化的解析方法与数值方法的比较,甚至比 ng 教授的课程更直观、更仔细(鉴于 Ng 教授的教学质量非常高,这也说明了一些问题)。
  • 【哥伦比亚大学】 :这门课程的教学大纲与一般的机器学习课程有些不同,它将整个前半部分都用于传统算法讲座。它涵盖了基本的排序、搜索、图遍历和调度算法。关于这些算法如何准确地用于机器学习问题,没有太多一对一的讨论,但研究它们会让你了解传统的计算机科学知识,这是理解如何解决大规模数据科学问题所必需的。当你要乘矩阵时,想想【o(n^3】)当你要对一个列表排序时,想想 O(nlog(n))。你可能不会在日常工作中专门使用这些知识,但是了解这些计算过程的具体细节肯定会拓宽你对手头问题的世界观。
  • 数据科学:Data to Insights (MIT xPro 6 周在线课程) :这是我上过的为数不多的付费课程之一(MOOCs 我一般走审计路线)。这在公共 edX 网站上不可用,尽管它使用 edX 平台来传送内容。为期 6 周的课程结构合理,充满有趣的内容,为门外汉打开了数据科学和机器学习的广阔世界。案例研究非常有趣,但编纂起来相当困难和耗时。讲座非常引人入胜,展示了这些案例研究。我特别喜欢的模块是关于推荐系统的。上完这门课后,我真的开始在我的笔记本电脑上用邻接矩阵查看 网飞屏幕了
  • 【T2 大学】用于机器学习的神经网络:这是 Coursera 上一门有些被低估的课程,即使有神经网络先驱 Jeff Hinton 作为指导老师。我意识到吴恩达新的深度学习专业将直接与这门课程竞争,如果 Coursera 在不久的将来删除它,我不会感到惊讶。然而,当它还在的时候,一个深度学习的热心人应该耐着性子看完这一关,即使只是为了揣摩深度网络的历史发展模式。
  • 【Deep Learning . ai】:这是最新的一个孩子,但它站在吴恩达的肩膀上,因此拥有非常强壮的腿:)我已经完成了第二个课程,现在正在进行第三个课程。陪审团仍然存在,但如果你想重温深度学习的最新趋势,你肯定应该考虑完成这个系列。即使编程任务看起来很难,并且你不想手工编程一个深度网络(你可以争辩说总有优秀的开源包,如 TensorFlow、Keras、Theranos,它们可以解决实际问题),深入理解正则化、爆炸梯度、超参数调整、批处理规范化等基本概念是必不可少的。来有效地使用那些高级的深度学习框架。

两个伞式数据科学 MOOCs,包含 R 和 Python

随着这篇长文的结尾越来越近,我想列出两个我觉得有趣和有用的多课程 MOOCs,以配合上面提到的特定主题领域。

  • 【约翰·霍普斯金大学】 :这是 Coursera 上提供的一个知名的 10 门课程的专业。不是每门课程都会吸引每个学习者。我个人只完成了 10 个中的 5 个。关键是时机,即何时开始这种专业化。当人们研究数据科学的 MOOC 时,这经常出现在谷歌搜索结果的顶部,因此这成为许多新学习者的第一个 MOOC。就我个人而言,如果我那样做了,我将很难从这门课程中获得全部价值。微软和 Udemy 关于 R 的入门课程,以及在此之前的一些统计学和线性代数课程极大地帮助了我从这些课程中获得最大的收益。由于专业化是由 JHU 生物统计系的教授指导的,人们在数据科学的两个方面得到了很好的处理,这两个方面在许多课程中往往是不足的——研究性学习和实验设计。
  • 【数据科学微硕士证书课程(加州大学圣地亚哥分校) :我刚刚注册并开始了这个系列/证书课程 4 门课程中的第 1 门。我喜欢这一事实,即它在广度和目标上与约翰·霍普斯金专业化相似,只是它选择 Python 作为动手部分的工作语言。结构和内容似乎经过深思熟虑,涵盖了 Python、Git、Jupyter 的基础知识,一直到 Apache Spark framework 的大数据处理(中间是统计学和机器学习课程)。案例研究和实践示例来自数据科学的现实应用,如野火建模、霍乱爆发或世界发展指标分析。首席讲师之一是 Ilkay Altintas,他创建了一个帮助野火动态预测的惊人平台,并将数据科学研究的成果用于追求社会公益。我确信我的专业化之旅将会是一次令人兴奋和有益的经历。欢迎你来参加聚会!
  • 数据科学顶点项目(Simplilearn) :通过专门的辅导课程,您将学习如何解决现实世界中与行业一致的数据科学问题,从数据处理和模型构建到报告您的业务成果和见解。

混合机器学习和大数据

随着大数据(Pb 级)的使用在商业和分析的每个方面都在增长,那些能够有效混合大数据和机器学习技能的工程师将会非常受欢迎。因此,关注围绕这一组合的几门课程是有意义的。

Simplilearn 的机器学习认证课程 :该课程通过动手实践的方式帮助你掌握有监督和无监督学习、推荐引擎和时间序列建模的概念,包括从事四个主要的端到端项目和 25 个以上的动手练习。优步和梅赛德斯-奔驰等主要行业合作伙伴对他们的课程提出建议。

谷歌基于云的 TensorFlow 专业化(Coursera) :这一 5 门课程的专业化专注于使用谷歌云平台的高级机器学习主题,在实践实验室中,您将获得优化、部署和扩展各种类型的生产 ML 模型的实践经验。

学习是相当大众化的——好好利用它

随着 MOOCs、开源编程平台、协作工具和几乎无限的免费云端存储的出现,学习变得越来越民主化、无处不在和普遍可用。如果你不是数据科学/机器学习方面的专家,但想学习这门学科,编写一些代码以提高工作效率,争取职业发展,或者只是寻找一些乐趣,现在是开始学习的时候了。几句离别的话,

  • 你是一名数据科学家 :不要让任何所谓的专家说“mooc 是给孩子们的,你不会像那样学到真正的数据科学”之类的话来打击你的士气。你试图通过参加 MOOC 学习数据科学,这一事实意味着两件事:(a)你已经在职业生涯中处理过数据;( b)你想学习从数据中提取最大价值的科学、结构化的方式,并围绕这些数据提出智能问题。这意味着你,我的朋友,已经是一个数据科学家了。如果仍然不相信,请阅读布兰登·罗勒 的博客,他是我所知道的最受尊敬和鼓舞人心的数据科学家之一。**
  • 你不必花一大笔钱来学习 :我知道我列了很多课程,对你来说它们可能看起来很贵。但是,幸运的是,大多数(如果不是全部的话)可以免费注册。edX 课程总是免费注册的,它们通常在课程内容方面没有任何限制,即你可以查看、执行、提交所有评分作业(不像 Coursera,它让你观看所有视频,但隐藏评分材料)。如果你认为某个证书值得在你的简历上展示,你可以在完成一些视频并判断其价值和效用后,在课程中途支付费用。
  • 练习、编码、构建东西来补充你的在线学习 :在机器学习的背景下有一种真正的算法叫做‘在线学习’。在这种技术中,该算法不是处理数百万个数据点的完整矩阵,而是处理最近的几个数据点并更新预测。你也可以在这种模式下工作。停顿问题/停车问题总是一个迷人的问题,它也适用于学习。我们总是想知道在构建东西之前要学习和吸收多少东西,即在哪里停止学习并开始实施。不要犹豫,不要拖延。学习一个概念,通过简单的编码来测试它。使用你看过的视频中最新的技巧或技术,不要等到掌握了整个主题。你会惊讶地发现,简单的 20 行代码可以让你在观看视频时学到的最复杂的概念上进行扎实的练习(并让你流汗)。

  • 那里有大量的数据 :你也会惊讶于网络上有多少丰富的免费数据来源。不要去 Kaggle,尝试不同的乐趣。试试data.gov或者 联合国数据门户 。前往 UCI 机器学习资源库 。感觉更冒险?那么 从 CIA 下载各个国家的数据,并尝试所有你在最新的 Matplotlib 或 ggplot2 讲座中学到的很酷的可视化效果呢?如果没有别的,从你的能源供应商那里下载你自己的用电数据,分析如果你在不同的时间打开空调或洗碗机,你是否可以节省一些钱。

本文中关于各种课程/讲师的观点完全是作者本人的观点。如果您有任何问题或想法要分享,请通过tirthajyoti【AT】Gmail[DOT]com联系作者。你可以查看作者的 GitHub 资源库 中其他有趣的 Python、R 或 MATLAB 代码片段和机器学习资源。此外,如果你像我一样对机器学习/数据科学/半导体充满热情,请随时在 LinkedIn 上添加我或在 Twitter 上关注我。

如何选择统计软件工具

原文:https://towardsdatascience.com/how-to-choose-statistical-software-tools-4870dd3c92a0?source=collection_archive---------4-----------------------

数据科学项目的好、坏和有帮助的方面

The book — now in print — has an awesome picture on the cover.

摘自像数据科学家一样思考 —为您的数据科学项目选择软件时需要寻找什么。

节省 37 折 像数据科学家 用代码fccgodsey

广泛的工具可用于实施统计方法。您可以将方法或模型与可用于实现它们的软件选项进行比较,并得出一两个好的选项。在选择软件工具时,有各种各样的事情要考虑,也有一些我遵循的一般规则。

工具有方法的实现吗?

您可以自己编写方法,但是如果您使用的是通用方法,有许多工具已经有了实现,使用其中一个可能更好。与你在一天内编写的、只使用一两次的代码相比,被许多人使用过的代码通常是相对无错误的。

根据您的编程能力和对各种统计工具的熟悉程度,在您最喜欢的工具中可能有一个现成的实现,您可以快速使用。如果 Excel 有,那么很可能其他工具也有。如果 Excel 不支持,那么中级工具可能支持,如果不支持,您可能需要编写一个程序。否则,您将选择不同的统计方法。

如果你决定使用一种编程语言,记住不是所有的包或库都是一样的。确保编程语言和软件包能够完全按照您的意图工作。阅读文档或一些与您想要做的分析类似的示例可能会有所帮助。

柔韧性好

除了能够执行主要的统计分析之外,如果一个统计工具能够执行一些相关的方法,通常也会很有帮助。通常,你会发现你选择的方法并不像你希望的那样有效,你在这个过程中学到的东西让你相信不同的方法可能更有效。如果你的软件工具没有任何选择,那么你要么坚持第一个选择,要么你将不得不切换到另一个工具。

例如,如果您有一个统计模型,并且想要找到最佳的参数值,您将使用似然函数和优化技术。有几种方法可以从似然函数中找到最佳参数,包括最大似然(ML)最大后验概率 (MAP)、期望最大化(EM)和变分贝叶斯 (VB)。Excel 有一些不同的具体优化算法,(它们都是 ML 方法),如果你认为你可以摆脱 ML,但你不确定,你可能想升级到一个更复杂的统计工具,有更多的优化选项。

有多种类型的回归、聚类、组件分析和机器学习,一些工具可能提供一种或多种这些方法。我倾向于支持统计工具,这些工具提供了这些方法类别中的一些,以防我发现需要切换或尝试另一种方法。

信息丰富就好

面对不确定性的意识是数据科学的主要方面;这涉及到统计软件工具的选择。一些工具可能会给出好的结果,但是没有提供如何以及为什么达到这些结果的洞察力。一方面,能够去构造方法和模型,以便更好地理解模型和系统,这是很好的。另一方面,如果您的方法在某种程度上犯了“错误”,并且您发现自己看到了一个奇怪的、意想不到的结果,那么有关该方法及其对数据的应用的更多信息可以帮助您诊断具体的问题。

一些统计工具,特别是像统计编程语言这样的高级工具,提供了查看几乎每种统计方法和结果内部的能力——甚至像机器学习这样的“黑盒”方法。这些内幕并不总是用户友好的,但至少他们是可用的。根据我的经验,像 Excel 这样的电子表格不能提供对其方法的深入了解,并且很难对比线性回归更复杂的统计模型进行解构或诊断。

普通就是好

对于生活中的许多事物——音乐、电视、电影和新闻文章——受欢迎并不总是意味着高质量;往往相反。有了软件,越来越多的人使用一个工具意味着有越来越多的人尝试它,得到结果,检查结果,并且可能报告问题,如果有的话。这样,软件就像开源软件一样,有一个反馈环,可以及时修复错误和问题。越多的人参与到这个反馈循环中,一个软件就越有可能相对来说没有错误或者健壮。

data = data.frame(X1 = c( 1.01, 1.99, 2.99, 4.01 ),
                  X2 = c( 0.0, -2.0, 2.0, -1.0 ),
                   y = c( 3.0, 5.0, 7.0, 9.0 ))linearModel <- lm(y ~ X1 + X2, data)
summary(linearModel)predict(linearModel,data)

文本 1:线性回归的 R 代码。

这并不是说现在最流行的东西是最好的。像其他事物一样,软件也有趋势和时尚。我倾向于查看过去几年中与我情况相似的人的使用情况。在统计工具的普及竞赛中,Excel 显然会胜出。但是,如果我们只考虑数据科学家,也许只考虑特定领域的数据科学家——不包括会计师、金融专业人士和其他半统计用户——我们可能会看到它的受欢迎程度下降,转而青睐更严肃的统计工具。

对我来说,工具必须满足的标准是:

  • 该工具必须至少有几年的历史;
  • 该工具必须由声誉良好的组织维护;
  • 论坛、博客和文献必须表明许多人已经使用这个工具很长时间了,而且最近没有太多重大问题。

请战好

除了被普遍使用之外,统计软件工具应该包括全面和有用的文档。当我试图使用一个软件时,我有一个应该有直接答案的问题,但我在任何地方都找不到答案,这很令人沮丧。

如果您找不到一些大问题的答案,例如如何配置进行线性回归的输入,或者如何格式化机器学习的特征,这是一个不好的迹象。如果大问题的答案不在文档中,那么就更难找到你不可避免会遇到的特定问题的答案。

文档通常是软件的年龄和流行程度的函数。该工具的官方文档应该放在维护组织的网页上,并且应该包含简单易懂的信息说明和规范。有趣的是,许多软件组织在他们的文档中不使用简单的语言,或者使他们的例子过于复杂。也许这是我对不必要的术语的厌恶,但是我避免使用我不容易理解其文档的软件。

> summary(linearModel)Call:
lm(formula = y ~ X1 + X2, data = data)Residuals:
       1        2        3        4
-0.02115  0.02384  0.01500 -0.01769Coefficients:
            Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.001542   0.048723  20.556  0.03095 *
X1          1.999614   0.017675 113.134  0.00563 **
X2          0.002307   0.013361   0.173  0.89114
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1Residual standard error: 0.03942 on 1 degrees of freedom
Multiple R-squared:  0.9999, Adjusted R-squared:  0.9998
F-statistic:  6436 on 2 and 1 DF,  p-value: 0.008813

Text 2:汇总的打印输出(linearModel)。

就像确定一个工具是否足够常用一样,我还会查看论坛和博客帖子,以确定是否有足够的示例和问题以及支持官方文档的答案。无论文档有多好,都有可能存在漏洞和歧义,有非正式文档作为备份是很有帮助的。

特制好的

一些软件工具或软件包是为特定目的而构建的,其他功能是后来添加的。例如,MATLAB 和 R 中的矩阵代数例程是构建这些语言时主要关心的问题,可以肯定地认为它们是全面而健壮的。相比之下,在 Python 和 Java 的最初版本中,矩阵代数并不是主要关注的问题,这些功能是后来以包和库的形式添加的。这不一定是坏事;Python 和 Java 现在都有健壮的矩阵功能,但是并不是每一种声称能够有效处理矩阵的语言都有这样的功能。

如果我想要的统计方法是一个包、库或软件工具的附件,那么我会像审查工具本身一样审查这个包:它是灵活的、信息丰富的、通用的、文档完善的,还是健壮的?

互通性好

互操作性是专门构建的一种逆过程,但它们并不相互排斥。一些软件工具与其他工具配合得很好,在这些工具中,您可以期望能够以普遍接受的格式集成功能、导入数据和导出结果。这当然有助于使用其他软件完成相关任务的项目。

如果您正在使用数据库,使用与数据库直接交互的工具会很有帮助。如果您打算基于您的结果构建一个 web 应用程序,请选择一个支持 web 框架的工具,或者至少选择一个能够以 JSON 或其他 web 友好格式导出数据的工具。或者,如果您的统计工具将在各种类型的计算机上使用,请确保该软件能够在各种操作系统上运行。将统计软件方法集成到完全不同的语言或工具中并不罕见。如果是这种情况,最好检查一下,例如,是否可以从 Java 调用 Python 函数(只要稍加努力,就可以)。

r 是专门为统计而构建的,互操作性在某种程度上是事后才想到的,尽管有一个庞大的软件包生态系统支持与其他软件的集成。Python 是作为一种通用编程语言而构建的,统计是后来才想到的,但是正如我所说的,Python 的统计包是最好的。在它们和其他软件之间进行选择是一个审查你打算使用的所有语言、应用程序和软件包的问题。

许可许可良好

大多数软件都有一个许可证,无论是明示的还是暗示的,说明了软件的使用存在哪些限制或许可。专有软件许可通常是显而易见的,但开源许可通常不那么清晰。

如果您将商业软件用于商业目的,这没问题,但是用“学术”或“学生”许可证做同样的事情可能会有法律风险。在没有确认许可不禁止的情况下,向他人出售商业软件,无论修改与否,也是很危险的。

当我使用开源工具进行数据科学研究时,我的主要问题是,我是否可以使用该工具创建软件,并在不泄露源代码的情况下将其出售给某人?有些开源许可允许这样做,有些不允许。我的理解是(尽管我不是律师),我不能在不提供源代码的情况下出售我用 R 编写的应用程序;在 Python 和 Java 中,这通常是允许的,这也是为什么生产应用程序通常不用 R 和其他语言构建,并有类似许可的一个原因。当然,通常有合法的途径解决这个问题,比如自己托管 R 代码,并以 web 服务或类似方式提供其功能。无论如何,如果你怀疑你可能违反了软件许可,最好检查许可并咨询法律专家。

import statsmodels.regression.linear_model as lmX = [ [ 1.01,  0.0, 1 ],
      [ 1.99, -2.0, 1 ],
      [ 2.99,  2.0, 1 ],
      [ 4.01, -1.0, 1 ] ]
y = [ 3.0, 5.0, 7.0, 9.0 ]linearModel = lm.OLS(y,X)
results = linearModel.fit()
results.summary()results.predict(X)

文本 3:线性回归的 Python 代码。

知识和熟悉度都不错

我把这条一般规则放在最后,尽管我怀疑大多数人,包括我自己,会首先考虑它。我承认:我倾向于使用我所知道的。使用你最熟悉的工具可能没什么问题,如果它在前面的规则中表现得相当好的话。例如,Python 和 R 在数据科学的几乎所有方面都很擅长,如果你知道其中一个比另一个好,就用那个。

另一方面,有许多工具并不适合这项工作。例如,尝试使用 Excel 进行机器学习通常不是最好的主意,尽管我听说随着微软扩大其产品,这种情况正在改变。在这种情况下,你可能能够使用你知道的工具,值得考虑学习一种更适合你的项目的工具。

最后,这是一个平衡的问题:使用你熟悉的工具可以节省时间,而使用不合适的工具会损失时间和质量。项目的时间限制和要求通常是决定性因素。

要了解更多信息,请下载免费的第一章 像数据科学家一样思考 并查看此 幻灯片演示文稿 了解更多信息和折扣代码。

Brian Godsey 博士是一名数学家、企业家、投资者和数据科学家,他的著作 像数据科学家一样思考 现已有印刷版和电子书。——briangodsey.com

如果您喜欢,请点击💚下面。

[## (我喜欢你)叫我大数据

恶名昭彰的 IDE 人群的滑稽嘻哈联合

medium.com](https://medium.com/@briangodsey/i-love-it-when-you-call-me-big-data-2e4b89e84740) [## 检查您对数据的假设

没有人喜欢糟糕的假设

medium.com](https://medium.com/towards-data-science/check-your-assumptions-about-your-data-20be250c143)

如何对您的客户数据进行聚类——使用 R 代码示例

原文:https://towardsdatascience.com/how-to-cluster-your-customer-data-with-r-code-examples-6c7e4aa6c5b1?source=collection_archive---------2-----------------------

聚类客户数据通过为你分组相似的东西,帮助你发现数据中隐藏的模式。例如,您可以根据活动创建客户角色,并为这些群体定制产品。

在另一篇文章中,我们讨论了如何利用你所了解的客户特征,通过手动标记客户群来建立人物角色。另一种方法是让计算机创建人物角色集群。这被称为无监督分类,因为您让计算机决定如何使用您的数据的值和特征。

无监督分类的另一个名称是“聚类”。有许多不同的聚类技术,根据它们解决问题的方法来区分。最常见的区别之一是由算法确定的聚类是否可以嵌套。嵌套的聚类算法被称为“分层的”,而非嵌套的被称为“分区的”。

在这里,我们将深入研究每种算法的示例,并在实践中观察它:

  • K-means 聚类,理论上
  • K-均值聚类,实际上
  • 理论上的凝聚层次聚类
  • 凝聚式层次聚类,实际上

离群值 监控您的业务数据,并在发生意外变化时通知您。我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。 注册每日数据驱动 获取工作中更多数据驱动的每日提示。

  • Outlier 是 Strata+Hadoop World 2017 观众奖得主。

也许从 k-means 聚类算法开始的最好地方是分解它的名字,因为它有助于理解算法在做什么。让我们从头开始;“k”是指该算法将创建的聚类数。因此,尽管该算法在如何创建聚类方面是无人监督的,但它确实将您想要创建的聚类的数量(k)作为输入。k-means 中的术语“均值”指的是如何将每个数据点加入到一个聚类中,即将每个数据点分配到具有最接近均值的聚类中。综上所述,k-means 聚类为您提供了“k”个数据点聚类,其中每个数据点都被分配到其最接近的聚类中。

该算法首先选择“k”个点作为初始中心值(通常称为质心)[1]。接下来,数据中的每个点都被分配到它最接近的中心值。现在每个点都被分配了一个聚类,但是我们需要检查中心值的初始猜测是否是最好的(不太可能!).检查的方法是计算每个聚类的新中心值-如果所有重新计算的中心值都与原始值相同,则您处于最佳解,算法可以停止。否则,该算法通过将点重新分配给新计算的中心值来再次尝试。这将持续到重新计算的中心值不变。

k-means 聚类为您提供了“k”个数据点聚类,其中每个数据点都被分配到与其最接近的聚类中。

该算法的结果是“k”个聚类,其中您拥有的每个数据点都被唯一地分配给一个且仅一个聚类。这就是为什么这种算法被称为“分区”或“非嵌套”算法——每个点只在一个簇中。

以上都是理论——接下来,让我们看看实践中的 k-means。

实际上,k-均值聚类

昨天,我谈到了 k-means 理论,但让我们将它付诸实践,使用一些样本客户销售数据为我们之前谈到的理论上的在线表格公司构建。假设我们收集了关于最近销售的数据,我们试图将这些数据分组为客户角色:年龄(年)、平均餐桌尺寸购买量(平方英寸)、每年购买的数量以及每次购买的金额(美元)。绘制数据,我们看到我们的客户可能有一些有趣的分组。

An example exploratory grouping using purchase attributes vs. purchase frequency

在这种情况下,看起来最年轻和最年长的顾客通常购买较小、较便宜的桌子,购买量低于中年顾客购买较大型号的数量,有时购买量更大。

现在,让我们针对 k、2、3 和 4 的几个不同值对这些数据运行 k-means 算法,看看该算法会产生什么结果。

An example running k-means with several different k values

在所有情况下,2160 cm 餐桌的购买者都属于自己的顾客群,但其他顾客则根据各自的特点更加混杂。当 k 等于 2 时,集群看起来是合理的,但是对于购买较小表的客户来说,可能有更多的粒度可以区分。当 k 等于 3 和 4 时,这些客户被分成更小的部分。

那么,选择什么样的 k 数比较合适呢?没有很好的算法方法来回答这个问题,但通常的做法是对不同的 k 值运行 k-means 算法,并测量通过添加更多的聚类而减少的误差量[2]——权衡的结果是,随着添加更多的聚类,你减少了误差,但随着添加更多的聚类,你有过度拟合数据的风险(在极端情况下,最终每个数据点都有自己的聚类!).

在我们的例子中,k 等于 2 和 3 之间的误差大幅下降,因此我们应该非常有信心至少有 3 个集群。在 3 和 4 个簇之间有另一个下降,但是比第一个下降小得多。随后的下降似乎没有太大的改善,所以在这种情况下,我会考虑创建 3 或 4 个客户角色。

如果你有兴趣看我用来运行 k-means 算法和创建这些图的 R 代码,一切都可以在我们的数据驱动每日 GitHub 页面上找到。

接下来,我们将回到理论,讨论一种不同类型的聚类算法,凝聚层次聚类。

理论上,凝聚层次聚类

我们刚刚在讨论一种分割聚类算法,k-means。现在,我将谈论凝聚层次聚类算法。像 k-means 一样,让我们分解算法的名称,以便更好地了解它的作用。先说“层级”这个词。这是指聚类分析算法的总体类型,在这种情况下,这意味着该算法通过不断嵌套数据点来创建聚类。“凝聚”这个词描述了我们正在做的层次聚类的类型。层次聚类有两种基本方法,凝聚法和分裂法。更常见的方法是聚集聚类,这意味着该算法通过自下而上的构建来嵌套数据点。换句话说,每个数据点都是它自己的聚类,然后它们被连接在一起以创建更大的聚类。分裂聚类意味着该算法通过自顶向下构建来嵌套数据点。换句话说,所有的数据点都从一个簇开始,然后被分解成更小的簇。

该算法通过合并两个最接近的聚类并重复直到只剩下一个聚类来工作。凝聚层次聚类的结果是每个聚类如何在每一步中合并在一起的映射。

k-means 和凝聚层次聚类之间的最大差异是由于它们解决问题的核心方法。特别是,在 k-means 聚类中,随着算法在每次迭代中提高其中心值,数据点可以在聚类之间移动。凝聚层次聚类算法不允许撤消任何以前的合并。这两种算法之间的另一个区别是,使用 k-means 时,因为它对其初始中心值使用猜测,所以每次使用相同的 k 值运行该算法时,您都可以得到不同的答案。另一方面,凝聚层次聚类将始终产生相同的结果,因为数据点之间的距离不会改变。

接下来,我将向您展示一个凝聚层次聚类的实际例子!

实际上,凝聚层次聚类

现在我们已经了解了凝聚层次聚类,让我们使用我们用于 k-means 的相同数据来实践它:年龄(年)、平均表大小购买(平方英寸)、每年购买的次数和每次购买的金额(美元)。绘制层次聚类结果的最常见方法之一是通过树形图或树状图。

Clustering customer data using adendogram (tree diagram)

左侧的值是指原始数据集的行号(底部的值是指距离[3]的测量值)。从左向右阅读时,您可以看到群集合并在一起以创建更大群集的顺序。将该算法与 k-means 聚类进行比较,我们发现结果是相似的。例如,树状图底部的值 19、22、21、20 和 27 被分组在一起,这些都是购买了 2160 cm 表的客户,这些表在 k-means 算法中被类似地分组。

将这种聚类算法的结果显示为树状图加强了这种算法和 k-means 之间的结构差异-每个数据点都嵌套在一起以创建更大的聚类,这与 k-means 不同,k-means 每次迭代都创建新的非重叠聚类。

如果你有兴趣看我用来运行凝聚层次聚类算法和创建这些图的 R 代码,一切都可以在我们的 数据驱动每日 GitHub 页面 上找到。

我希望这篇关于聚类算法的综述对您有所帮助。正如您所知,即使这些是无监督的分类技术,仍然需要一些人工监督和解释,例如,决定应该使用多少个聚类(以及许多其他决定,如如何初始化 k-means 或距离的度量,我鼓励您阅读更多信息)。虽然聚类算法通常不能用来告诉你“正确”的答案,只要按一下按钮,他们是一个伟大的方式来探索和理解您的数据!

离群值 监控您的业务数据,并在发生意外变化时通知您。我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。 今天安排试玩。

  • Outlier 是 Strata+Hadoop World 2017 观众奖得主。在下面的 39 秒中了解更多关于离群值的信息。

[1]k 均值的挑战之一是确定从哪里开始。有许多不同的算法可以单独解决这个问题,例如,选择一个随机的值子集并取这些值的平均值。计算 k-means 的计算机程序应该可以帮你做这个初始化。

[2]对于此处所示的数字数据,通常以每个点与其聚类中心值之间距离的平方误差之和来衡量。

[3]有许多方法可以测量两个集群之间的距离。例如,它可以是不同聚类中任意两点之间的最小距离,不同聚类中任意两点之间的最大距离,或者不同聚类中所有点对的平均距离。

如何在 Pytorch 中编写变压器代码

原文:https://towardsdatascience.com/how-to-code-the-transformer-in-pytorch-24db27c8f9ec?source=collection_archive---------1-----------------------

变压器会不会是 RNNs 棺材上的另一颗钉子?

去掉了笨重的 for 循环,它找到了一种方法,允许整个句子同时成批地进入网络。奇迹;NLP 现在重新利用了 python 高效的线性代数库的优势。节省下来的时间可以用于在模型中部署更多的层。

到目前为止,结果似乎是更快的收敛和更好的结果。有什么不喜欢的?

我个人的经历非常有希望。它对 200 万个法语-英语句子对进行训练,仅用三天时间就能创造出一个复杂的翻译器。

如果你去我在 Github 这里的实现,你可以在语言翻译任务中自己玩这个模型。也请查看我的下一篇文章,在那里我将分享我构建翻译器的旅程和结果。

或者最后,你可以自己造一个。这是如何做的指南,以及它是如何工作的。

本指南仅解释如何对模型进行编码和运行,有关如何获取数据并为 seq2seq 处理数据的信息,请参见我的指南 此处

变形金刚

上图显示了变压器模型的概况。编码器的输入将是英语句子,进入解码器的“输出”将是法语句子。

实际上,我们需要了解五个流程来实施这一模型:

  • 嵌入输入
  • 位置编码
  • 创建遮罩
  • 多头关注层
  • 前馈层

把...嵌入

嵌入单词已经成为 NMT 的标准做法,给网络提供了比一个热门编码更多的单词信息。关于这方面的更多信息,请看我的帖子这里。

pytorch 中的嵌入操作非常简单:

class Embedder(nn.Module):
    def __init__(self, vocab_size, d_model):
        super().__init__()
        self.embed = nn.Embedding(vocab_size, d_model)
    def forward(self, x):
        return self.embed(x)

当每个单词被输入到网络中时,这个代码将执行一个查找并检索它的嵌入向量。然后,这些向量将被模型学习为参数,并随着梯度下降的每次迭代进行调整。

给我们的话语语境:位置编码

为了让模型理解一个句子,它需要知道每个单词的两件事:这个单词是什么意思?它在句子中的位置是什么?

每个单词的嵌入向量将学习意思,所以现在我们需要输入一些东西来告诉网络这个单词的位置。

Vasmari 等人通过使用这些函数创建一个特定于位置的常量值来解决这个问题:

这个常数是一个二维矩阵。 Pos 是指句子中的顺序, i 是指沿着嵌入向量维的位置。pos/i 矩阵中的每个值随后使用上述等式计算出来。

The positional encoding matrix is a constant whose values are defined by the above equations. When added to the embedding matrix, each word embedding is altered in a way specific to its position.

位置编码器的直观编码方式如下:

class PositionalEncoder(nn.Module):
    def __init__(self, d_model, max_seq_len = 80):
        super().__init__()
        self.d_model = d_model

        # create constant 'pe' matrix with values dependant on 
        # pos and i
        pe = torch.zeros(max_seq_len, d_model)
        for pos in range(max_seq_len):
            for i in range(0, d_model, 2):
                pe[pos, i] = \
                math.sin(pos / (10000 ** ((2 * i)/d_model)))
                pe[pos, i + 1] = \
                math.cos(pos / (10000 ** ((2 * (i + 1))/d_model)))

        pe = pe.unsqueeze(0)
        self.register_buffer('pe', pe)

    def forward(self, x):
        # make embeddings relatively larger
        x = x * math.sqrt(self.d_model)
        #add constant to embedding
        seq_len = x.size(1)
        x = x + Variable(self.pe[:,:seq_len], \
        requires_grad=False).cuda()
        return x

上面的模块让我们将位置编码添加到嵌入向量中,为模型提供关于结构的信息。

我们在加法之前增加嵌入值的原因是为了使位置编码相对较小。这意味着当我们将它们加在一起时,嵌入向量中的原始含义不会丢失。

创造我们的面具

屏蔽在变压器中起着重要的作用。它有两个目的:

  • 在编码器和解码器中:只要输入句子中有填充,就把注意力输出归零。
  • 在解码器中:防止解码器在预测下一个单词时在翻译句子的剩余部分提前“到达峰值”。

为输入创建掩码很简单:

batch = next(iter(train_iter))
input_seq = batch.English.transpose(0,1)
input_pad = EN_TEXT.vocab.stoi['<pad>']# creates mask with 0s wherever there is padding in the input
input_msk = (input_seq != input_pad).unsqueeze(1)

对于 target_seq,我们做了同样的事情,但是创建了一个额外的步骤:

# create mask as beforetarget_seq = batch.French.transpose(0,1)
target_pad = FR_TEXT.vocab.stoi['<pad>']
target_msk = (target_seq != target_pad).unsqueeze(1)size = target_seq.size(1) # get seq_len for matrixnopeak_mask **=** np**.**triu(np**.**ones(1, size, size),
k**=**1)**.**astype('uint8')
nopeak_mask = Variable(torch**.**from_numpy(nopeak_mask) **==** 0)target_msk = target_msk & nopeak_mask

解码器的初始输入将是目标序列(法语翻译)。解码器预测每个输出单词的方式是利用所有编码器输出和法语句子,直到每个单词的预测点。

因此,我们需要防止第一个输出预测能够看到后面的句子。为此,我们使用 nopeak_mask:

When the mask is applied in our attention function, each prediction will only be able to make use of the sentence up until the word it is predicting.

如果我们稍后将这个掩码应用于注意力分数,那么在计算输出时,输入前面的值将不能起作用。

多头注意力

一旦我们有了嵌入值(带位置编码)和掩码,我们就可以开始构建模型的层了。

以下是多头注意力层的概述:

Multi-headed attention layer, each input is split into multiple heads which allows the network to simultaneously attend to different subsections of each embedding.

v、K、Q 分别代表“键”、“值”和“查询”。这些是在注意力函数中使用的术语,但老实说,我不认为解释这些术语对理解模型特别重要。

在编码器的情况下, V,KG 将只是嵌入向量的相同副本(加上位置编码)。它们的尺寸为 Batch_size * seq_len * d_model。

在多头注意力中,我们将嵌入向量分成 N 个头,因此它们将具有尺寸 batch _ size * N * seq _ len *(d _ model/N)。

这个最后的维度(d_model / N)我们称之为 d_k。

让我们看看解码器模块的代码:

class MultiHeadAttention(nn.Module):
    def __init__(self, heads, d_model, dropout = 0.1):
        super().__init__()

        self.d_model = d_model
        self.d_k = d_model // heads
        self.h = heads

        self.q_linear = nn.Linear(d_model, d_model)
        self.v_linear = nn.Linear(d_model, d_model)
        self.k_linear = nn.Linear(d_model, d_model)
        self.dropout = nn.Dropout(dropout)
        self.out = nn.Linear(d_model, d_model)

    def forward(self, q, k, v, mask=None):

        bs = q.size(0)

        # perform linear operation and split into h heads

        k = self.k_linear(k).view(bs, -1, self.h, self.d_k)
        q = self.q_linear(q).view(bs, -1, self.h, self.d_k)
        v = self.v_linear(v).view(bs, -1, self.h, self.d_k)

        # transpose to get dimensions bs * h * sl * d_model

        k = k.transpose(1,2)
        q = q.transpose(1,2)
        v = v.transpose(1,2)# calculate attention using function we will define next
        scores = attention(q, k, v, self.d_k, mask, self.dropout)

        # concatenate heads and put through final linear layer
        concat = scores.transpose(1,2).contiguous()\
        .view(bs, -1, self.d_model)

        output = self.out(concat)

        return output

计算注意力

Equation for calculating attention

Diagram from paper illustrating equation steps

这是我们今天要考虑的唯一一个等式,这张来自论文的图表很好地解释了每一步。

图中的每个箭头反映了等式的一部分。

最初,我们必须将 Q 乘以 k 的转置,然后通过将输出除以 d_k 的平方根来“缩放”。

等式中没有显示的一个步骤是屏蔽操作。在执行 Softmax 之前,我们应用掩码,从而减少输入填充的值(或者在解码器中,输入在当前字之前的值)。

另一个未显示的步骤是 dropout,我们将在 Softmax 之后应用。

最后,最后一步是在目前为止的结果和 v 之间做点积。

下面是注意力功能的代码:

def attention(q, k, v, d_k, mask=None, dropout=None):

    scores = torch.matmul(q, k.transpose(-2, -1)) /  math.sqrt(d_k)if mask is not None:
        mask = mask.unsqueeze(1)
        scores = scores.masked_fill(mask == 0, -1e9)scores = F.softmax(scores, dim=-1)

    if dropout is not None:
        scores = dropout(scores)

    output = torch.matmul(scores, v)
    return output

前馈网络

好了,如果你已经理解了,给自己一个大大的鼓励,因为我们已经完成了最后一层,从这里开始一切都很简单了!

这一层仅由两个线性操作组成,其间有一个 relu 和 dropout 操作。

class FeedForward(nn.Module):
    def __init__(self, d_model, d_ff=2048, dropout = 0.1):
        super().__init__() 
        # We set d_ff as a default to 2048
        self.linear_1 = nn.Linear(d_model, d_ff)
        self.dropout = nn.Dropout(dropout)
        self.linear_2 = nn.Linear(d_ff, d_model)
    def forward(self, x):
        x = self.dropout(F.relu(self.linear_1(x)))
        x = self.linear_2(x)
        return x

前馈层只是深化我们的网络,使用线性层来分析注意力层输出的模式。

最后一件事:正常化

规范化在深度神经网络中非常重要。它可以防止层中值的范围变化太大,这意味着模型训练速度更快,泛化能力更强。

我们将对编码器/解码器中各层之间的结果进行归一化,因此在构建模型之前,让我们定义该函数:

class Norm(nn.Module):
    def __init__(self, d_model, eps = 1e-6):
        super().__init__()

        self.size = d_model
        # create two learnable parameters to calibrate normalisation
        self.alpha = nn.Parameter(torch.ones(self.size))
        self.bias = nn.Parameter(torch.zeros(self.size))
        self.eps = eps
    def forward(self, x):
        norm = self.alpha * (x - x.mean(dim=-1, keepdim=True)) \
        / (x.std(dim=-1, keepdim=True) + self.eps) + self.bias
        return norm

把所有的东西放在一起!

如果你理解了上面的细节,你现在就理解了这个模型。剩下的就是简单地把所有东西放回原位。

让我们再看一看整体架构,然后开始建造:

最后一个变量:如果您仔细观察图表,您会发现编码器和解码器架构旁边有一个“Nx”。实际上,上图中的编码器和解码器代表编码器的一层和解码器的一层。n 是层数的变量。例如,如果 N=6,数据通过六个编码器层(具有上述架构),然后这些输出被传递到解码器,该解码器也由六个重复的解码器层组成。

我们现在将使用上面模型中所示的架构构建 EncoderLayer 和 DecoderLayer 模块。然后,当我们构建编码器和解码器时,我们可以定义有多少层。

# build an encoder layer with one multi-head attention layer and one # feed-forward layerclass EncoderLayer(nn.Module):
    def __init__(self, d_model, heads, dropout = 0.1):
        super().__init__()
        self.norm_1 = Norm(d_model)
        self.norm_2 = Norm(d_model)
        self.attn = MultiHeadAttention(heads, d_model)
        self.ff = FeedForward(d_model)
        self.dropout_1 = nn.Dropout(dropout)
        self.dropout_2 = nn.Dropout(dropout)

    def forward(self, x, mask):
        x2 = self.norm_1(x)
        x = x + self.dropout_1(self.attn(x2,x2,x2,mask))
        x2 = self.norm_2(x)
        x = x + self.dropout_2(self.ff(x2))
        return x

# build a decoder layer with two multi-head attention layers and
# one feed-forward layerclass DecoderLayer(nn.Module):
    def __init__(self, d_model, heads, dropout=0.1):
        super().__init__()
        self.norm_1 = Norm(d_model)
        self.norm_2 = Norm(d_model)
        self.norm_3 = Norm(d_model)

        self.dropout_1 = nn.Dropout(dropout)
        self.dropout_2 = nn.Dropout(dropout)
        self.dropout_3 = nn.Dropout(dropout)

        self.attn_1 = MultiHeadAttention(heads, d_model)
        self.attn_2 = MultiHeadAttention(heads, d_model)
        self.ff = FeedForward(d_model).cuda()def forward(self, x, e_outputs, src_mask, trg_mask):
        x2 = self.norm_1(x)
        x = x + self.dropout_1(self.attn_1(x2, x2, x2, trg_mask))
        x2 = self.norm_2(x)
        x = x + self.dropout_2(self.attn_2(x2, e_outputs, e_outputs,
        src_mask))
        x2 = self.norm_3(x)
        x = x + self.dropout_3(self.ff(x2))
        return x# We can then build a convenient cloning function that can generate multiple layers:def get_clones(module, N):
    return nn.ModuleList([copy.deepcopy(module) for i in range(N)])

我们现在准备构建编码器和解码器:

class Encoder(nn.Module):
    def __init__(self, vocab_size, d_model, N, heads):
        super().__init__()
        self.N = N
        self.embed = Embedder(vocab_size, d_model)
        self.pe = PositionalEncoder(d_model)
        self.layers = get_clones(EncoderLayer(d_model, heads), N)
        self.norm = Norm(d_model)
    def forward(self, src, mask):
        x = self.embed(src)
        x = self.pe(x)
        for i in range(N):
            x = self.layers[i](x, mask)
        return self.norm(x)

class Decoder(nn.Module):
    def __init__(self, vocab_size, d_model, N, heads):
        super().__init__()
        self.N = N
        self.embed = Embedder(vocab_size, d_model)
        self.pe = PositionalEncoder(d_model)
        self.layers = get_clones(DecoderLayer(d_model, heads), N)
        self.norm = Norm(d_model)
    def forward(self, trg, e_outputs, src_mask, trg_mask):
        x = self.embed(trg)
        x = self.pe(x)
        for i in range(self.N):
            x = self.layers[i](x, e_outputs, src_mask, trg_mask)
        return self.norm(x)

最后…变形金刚!

class Transformer(nn.Module):
    def __init__(self, src_vocab, trg_vocab, d_model, N, heads):
        super().__init__()
        self.encoder = Encoder(src_vocab, d_model, N, heads)
        self.decoder = Decoder(trg_vocab, d_model, N, heads)
        self.out = nn.Linear(d_model, trg_vocab)
    def forward(self, src, trg, src_mask, trg_mask):
        e_outputs = self.encoder(src, src_mask)
        d_output = self.decoder(trg, e_outputs, src_mask, trg_mask)
        output = self.out(d_output)
        return output# we don't perform softmax on the output as this will be handled 
# automatically by our loss function

训练模型

随着变压器的建立,剩下的就是在 EuroParl 数据集上训练这个傻瓜。编码部分相当容易,但是要准备好等待大约 2 天,这个模型才开始收敛!

让我们先定义一些参数:

d_model = 512
heads = 8
N = 6
src_vocab = len(EN_TEXT.vocab)
trg_vocab = len(FR_TEXT.vocab)model = Transformer(src_vocab, trg_vocab, d_model, N, heads)for p in model.parameters():
    if p.dim() > 1:
        nn.init.xavier_uniform_(p)# this code is very important! It initialises the parameters with a
# range of values that stops the signal fading or getting too big.
# See [this blog](http://andyljones.tumblr.com/post/110998971763/an-explanation-of-xavier-initialization) for a mathematical explanation.optim = torch.optim.Adam(model.parameters(), lr=0.0001, betas=(0.9, 0.98), eps=1e-9)

现在我们可以开始训练了:

def train_model(epochs, print_every=100):

    model.train()

    start = time.time()
    temp = start

    total_loss = 0

    for epoch in range(epochs):

        for i, batch in enumerate(train_iter): src = batch.English.transpose(0,1)
            trg = batch.French.transpose(0,1) # the French sentence we input has all words except
            # the last, as it is using each word to predict the next

            trg_input = trg[:, :-1]

            # the words we are trying to predict

            targets = trg[:, 1:].contiguous().view(-1)

            # create function to make masks using mask code above

            src_mask, trg_mask = create_masks(src, trg_input)

            preds = model(src, trg_input, src_mask, trg_mask)

            optim.zero_grad()

            loss = F.cross_entropy(preds.view(-1, preds.size(-1)),
            results, ignore_index=target_pad) loss.backward()
            optim.step()

            total_loss += loss.data[0]
            if (i + 1) % print_every == 0:
                loss_avg = total_loss / print_every
                print("time = %dm, epoch %d, iter = %d, loss = %.3f,
                %ds per %d iters" % ((time.time() - start) // 60,
                epoch + 1, i + 1, loss_avg, time.time() - temp,
                print_every))
                total_loss = 0
                temp = time.time()

Example training output: After a few days of training I seemed to converge around a loss of around 1.3

测试模型

我们可以使用下面的功能来翻译句子。我们可以直接从我们的批处理中输入句子,或者输入自定义字符串。

翻译器通过运行一个循环来工作。我们从对英语句子进行编码开始。然后,我们向解码器提供令牌索引和编码器输出。解码器对第一个字进行预测,我们用 sos 标记将其添加到解码器输入中。我们重新运行循环,获得下一个预测,并将其添加到解码器输入,直到我们到达标记,让我们知道它已经完成翻译。

def translate(model, src, max_len = 80, custom_string=False):

    model.eval()if custom_sentence == True:
        src = tokenize_en(src)
        sentence=\
        Variable(torch.LongTensor([[EN_TEXT.vocab.stoi[tok] for tok
        in sentence]])).cuda()src_mask = (src != input_pad).unsqueeze(-2)
    e_outputs = model.encoder(src, src_mask)

    outputs = torch.zeros(max_len).type_as(src.data)
    outputs[0] = torch.LongTensor([FR_TEXT.vocab.stoi['<sos>']])for i in range(1, max_len):    

        trg_mask = np.triu(np.ones((1, i, i),
        k=1).astype('uint8')
        trg_mask= Variable(torch.from_numpy(trg_mask) == 0).cuda()

        out = model.out(model.decoder(outputs[:i].unsqueeze(0),
        e_outputs, src_mask, trg_mask))
        out = F.softmax(out, dim=-1)
        val, ix = out[:, -1].data.topk(1)

        outputs[i] = ix[0][0]
        if ix[0][0] == FR_TEXT.vocab.stoi['<eos>']:
            breakreturn ' '.join(
    [FR_TEXT.vocab.itos[ix] for ix in outputs[:i]]
    )

仅此而已。看我的 Github 这里我已经写了这个代码作为一个程序,它将接受两个平行文本作为参数,并在它们上面训练这个模型。或者把知识实践出来,自己去实施!

如何收集你的深度学习数据集

原文:https://towardsdatascience.com/how-to-collect-your-deep-learning-dataset-2e0eefc0ba24?source=collection_archive---------7-----------------------

想获得灵感?快来加入我的 超级行情快讯 。😎

深度学习已经成为解决许多具有挑战性的现实世界问题的首选方法。这绝对是迄今为止执行计算机视觉任务的最佳方法。上图展示了深度学习对计算机视觉的强大作用。通过足够的训练,深度网络可以分割和识别图像中每个人的“关键点”。

这些一直运行良好的深度学习机器需要燃料——大量的燃料;这种燃料就是数据。我们拥有的标签 数据越多,我们的模型表现就越好。更多的数据导致更好的性能的想法甚至已经被谷歌用 3 亿张图像的数据集进行了大规模的探索!

重新审视深度学习时代数据的不合理有效性

当在现实世界的应用中部署你的深度学习模型时,你真的应该不断地给它提供更多的数据以继续提高它的性能。喂野兽:如果你想提高你的模型的性能,获得更多的数据!

但是我们从哪里得到这些数据呢?获得良好注释的数据既昂贵又耗时。雇人手动收集图像并贴上标签根本没有效率。而且,在深度学习时代,数据无疑是你最有价值的资源。

在这里,我将向您展示获取标签数据的 3 种方法。这将比手动下载和标记图片更有效,让你节省时间和金钱。一旦你有了你的基本数据集,就很容易滚雪球,建立一个大规模的数据集,以创建一个高性能和强大的深度学习模型。

我们开始吧!

从网上抓取

手动查找和下载图像需要很长时间,这仅仅是因为涉及到大量的人工工作。那么,作为给计算机编程的人,当一项任务需要大量手工工作时,我们该怎么办呢?…当然是我们编程的!我们编写代码来自动完成任务!

我们将使用为计算机视觉任务收集某种数据的示例,例如对象检测或分割。嗯,我们的任务可能有某种我们想要检测的公共对象。所以这就成了我们抓取网页的关键词。它也成为该对象的类名。

从声音上看,这对于图像分类这样的图像注释非常粗糙的任务来说当然是非常容易的。但是如果我们想做类似实例分割的事情呢?我们需要图像中每个像素的标签!为了得到这些,最好使用一些已经存在的非常棒的图像注释工具!

Polygon-RNN++ 论文展示了如何创建一个模型,给定一个对象周围的多边形点的粗略集合,就可以生成用于分割的像素标签。深度极限切割也很相似,除了他们只使用物体周围的四个极限点。这将给你一些漂亮的包围盒和分割标签!他们在 GitHub 上的代码也非常好用。

另一种选择是使用现有的图像注释 GUI。LabelMe 是一个非常受欢迎的工具,你可以在其中绘制边界框并为分割图设置多边形点。如果你不想自己动手,亚马逊土耳其机器人也是一个便宜的选择!

第三方

由于数据在深度学习时代已经成为如此宝贵的商品,许多初创公司已经开始提供自己的图像标注服务:他们将为你收集和标记数据!你所要做的就是告诉他们你需要什么样的数据和注释。

Mighty AI 是一个一直在做自动驾驶汽车图像标注,在空间上已经变得蛮大的;他们也在 2018 年 CVPR 奥运会上。 Playment AI 没有 Mighty AI 专业,提供任何领域的图像标注。他们还提供了更多的工具,如视频和地标注释。

预训练网络

许多人已经知道迁移学习的概念:从一个在大型数据集上预先训练好的网络开始,然后我们自己进行微调。我们可以用同样的想法来收集我们的新数据集!

这些预训练网络被训练的数据集是巨大的。只需查看开放图像数据集,该数据集包含超过 1500 万张图像,并标有来自 600 个类别的边界框!在这个数据集上训练的网络已经非常擅长检测物体了。所以我们可以用它在图像中的物体周围画一些边界框。这使我们的工作减半,因为我们接下来要做的就是将盒子里的物品分类。此外,由于有 600 个类别,你想要检测和分类的一些对象可能已经通过这个预先训练的网络以高精度被挑选出来。 TensorFlow 对象检测 API 实际上已经有了一个对开放图像进行预训练的网络,如果你想试试的话!

雪球效应

现在你已经收集了一个初始数据集。你用它来训练你的网络,并把它应用到你的产品中。它的性能足以满足您的需求,但它并不像您希望的那样精确。现在您已经有了一个运行中的基线网络,您可以使用该网络来收集更多的数据!这个网络将比一般的预先训练的网络更好地完成你的任务,因为你已经针对你的具体问题对它进行了微调。因此,你可以用它来收集越来越多的数据甚至更快,使您的网络更好;一个漂亮的雪球效应!

喜欢学习?

在推特上关注我,我会在这里发布所有最新最棒的人工智能、技术和科学!也请在 LinkedIn上与我联系!

如何在 Kaggle 竞争 Zillow 奖

原文:https://towardsdatascience.com/how-to-compete-for-zillow-prize-at-kaggle-535852243906?source=collection_archive---------2-----------------------

Kaggle 是数据科学家的 AirBnB 这是他们度过夜晚和周末的地方。这是一个众包平台,旨在吸引、培养、培训和挑战来自世界各地的数据科学家,通过机器学习解决数据科学和预测分析问题。它拥有来自 194 个国家的 536,000 多名活跃成员,每月收到近 150,000 份申请。从墨尔本开始,卡格尔于 2011 年搬到硅谷,从哈尔·瓦里安(谷歌首席经济学家)、麦克斯·拉夫琴(Paypal)、Index 和科斯拉风险投资公司等公司筹集了约 1100 万美元,最终在 2017 年 3 月被谷歌收购。Kaggle 是全球数据科学爱好者争夺奖项和提升 Kaggle 排名的第一站。迄今为止,世界上只有 94 位卡格勒大师。有关 Kaggle Progression 系统的详细信息,请查看此链接和此链接。下面是 Anthony Goldbloom (Kaggle 创始人)关于如何赢得 Kaggle 比赛的精彩文章和视频。我也会看 Marios Michailidis 从预测赛马到成为 Kaggle 第一的旅程,以及模型赌注是如何帮助的。

Zillion Pillows (Zillow)是世界上最大的美国家庭数字库存和估计。美国住房存量超过 27.5 万亿美元。Zillow 覆盖了美国 1.1 亿个家庭,每个家庭有 103 个变量。每月有 7300 万独立访客,20 TBs 的数据和 120 万个每天晚上运行的统计和机器学习模型来预测下一个 Zestimates ,这无疑是天底下最好的房地产机器学习案例研究。Zillow 在预测房屋销售价值(Zestimate)时的平均误差从 14%降至 5%,但考虑到不可预测的异常值和看不见的金融衰退,这仍有很长的路要走。Zillow 最近因其误差幅度和给潜在卖家或买家带来的麻烦而受到批评,据估计,一栋典型房屋的价格误差高达 14,000 美元。

Zillow 于 2017 年 5 月 24 日在 Kaggle 上推出了其 Zillow Prize 竞赛。它分为两个阶段,将持续八个月。虽然百万美元似乎是一个很大的奖项,但它是 10 名数据科学工程师在硅谷工作 8 个月的成本,每人 10 万美元,而迄今为止,世界各地有 2900 个团队参与并竞争这一奖项,通常每个团队有 3 名成员,8700 人,每个工程师只有 114 美元,相当于每个数据科学家每月 14 美元或每小时 1.7 美元。这就是众包和 Kaggle 的魅力和力量。

要开始比赛,请浏览温迪·坎的欢迎信息和常见问题和任意提问线程。他是 Zillow 的研究主管。这是他的另一个不错的博客(训练、得分和重复),其中包含一些关于如何在竞争中排名的提示。这是 Zillow 创始人兼首席经济学家关于 Zillow 创新和竞争的一个炉边聊天视频。

在 Kaggle 上创建您的帐户,加入竞赛并接受规则。提交你的第一个内核,可以分叉我的公共内核— 如何争夺 Zillow prize —第一个内核运行。一旦你得到结果,请将文件提交给 Zillow。欢迎来到齐洛奖挑战赛。我不知道谁会赢,但我肯定会通过特征选择、集成和外部数据集的结合。

为了让第一次提交对你来说超级简单,这里有所有的步骤和完整的源代码

第一步:在 Kaggle 上创建你的账户,加入竞赛

第二步:进入内核标签,点击新内核

第三步:选择笔记本

步骤 4:在代码窗口中复制粘贴以下代码(XGB)

### Importing Libraries or Packages that are needed throughout the Program ###import numpy as npimport pandas as pdimport xgboost as xgbimport randomimport datetime as dtimport gcimport seaborn as sns #python visualization librarycolor = sns.color_palette()#%matplotlib inlinenp.random.seed(1)###Load the Datasets #### We need to load the datasets that will be needed to train our machine learning algorithms, handle our data and make predictions. Note that these datasets are the ones that are already provided once you enter the competition by accepting terms and conditions #train = pd.read_csv(‘../input/train_2016_v2.csv’ , parse_dates=[“transactiondate”])properties = pd.read_csv(‘../input/properties_2016.csv’)test = pd.read_csv(‘../input/sample_submission.csv’)test= test.rename(columns={‘ParcelId’: ‘parcelid’}) #To make it easier for merging datasets on same column_id later### Analyse the Dimensions of our Datasets.print(“Training Size:” + str(train.shape))print(“Property Size:” + str(properties.shape))print(“Sample Size:” + str(test.shape))### Type Converting the DataSet #### The processing of some of the algorithms can be made quick if data representation is made in int/float32 instead of int/float64\. Therefore, in order to make sure that all of our columns types are in float32, we are implementing the following lines of code #for c, dtype in zip(properties.columns, properties.dtypes):if dtype == np.float64:properties[c] = properties[c].astype(np.float32)if dtype == np.int64:properties[c] = properties[c].astype(np.int32)for column in test.columns:if test[column].dtype == int:test[column] = test[column].astype(np.int32)if test[column].dtype == float:test[column] = test[column].astype(np.float32)### Let’s do some feature engineering#living area proportionsproperties[‘living_area_prop’] = properties[‘calculatedfinishedsquarefeet’] / properties[‘lotsizesquarefeet’]#tax value ratioproperties[‘value_ratio’] = properties[‘taxvaluedollarcnt’] / properties[‘taxamount’]#tax value proportionsproperties[‘value_prop’] = properties[‘structuretaxvaluedollarcnt’] / properties[‘landtaxvaluedollarcnt’]###Merging the Datasets #### We are merging the properties dataset with training and testing dataset for model building and testing prediction #df_train = train.merge(properties, how=’left’, on=’parcelid’)df_test = test.merge(properties, how=’left’, on=’parcelid’)### Remove previos variables to keep some memorydel properties, traingc.collect();print(‘Memory usage reduction…’)df_train[[‘latitude’, ‘longitude’]] /= 1e6df_test[[‘latitude’, ‘longitude’]] /= 1e6df_train[‘censustractandblock’] /= 1e12df_test[‘censustractandblock’] /= 1e12### Let’s do some pre-exploratory analysis to identify how much missing values do we have in our datasets.### Thanks to Nikunj-Carefully dealing with missing values. Ref. [https://www.kaggle.com/nikunjm88/carefully-dealing-with-missing-values](https://www.kaggle.com/nikunjm88/carefully-dealing-with-missing-values)### Label Encoding For Machine Learning & Filling Missing Values #### We are now label encoding our datasets. All of the machine learning algorithms employed in scikit learn assume that the data being fed to them is in numerical form. LabelEncoding ensures that all of our categorical variables are in numerical representation. Also note that we are filling the missing values in our dataset with a zero before label encoding them. This is to ensure that label encoder function does not experience any problems while carrying out its operation #from sklearn.preprocessing import LabelEncoderlbl = LabelEncoder()for c in df_train.columns:df_train[c]=df_train[c].fillna(0)if df_train[c].dtype == ‘object’:lbl.fit(list(df_train[c].values))df_train[c] = lbl.transform(list(df_train[c].values))for c in df_test.columns:df_test[c]=df_test[c].fillna(0)if df_test[c].dtype == ‘object’:lbl.fit(list(df_test[c].values))df_test[c] = lbl.transform(list(df_test[c].values))### Rearranging the DataSets #### We will now drop the features that serve no useful purpose. We will also split our data and divide it into the representation to make it clear which features are to be treated as determinants in predicting the outcome for our target feature. Make sure to include the same features in the test set as were included in the training set #x_train = df_train.drop([‘parcelid’, ‘logerror’, ‘transactiondate’, ‘propertyzoningdesc’,‘propertycountylandusecode’, ], axis=1)x_test = df_test.drop([‘parcelid’, ‘propertyzoningdesc’,‘propertycountylandusecode’, ‘201610’, ‘201611’,‘201612’, ‘201710’, ‘201711’, ‘201712’], axis = 1)x_train = x_train.valuesy_train = df_train[‘logerror’].values### Cross Validation #### We are dividing our datasets into the training and validation sets so that we could monitor and the test the progress of our machine learning algorithm. This would let us know when our model might be over or under fitting on the dataset that we have employed. #from sklearn.model_selection import train_test_splitX = x_trainy = y_trainXtrain, Xvalid, ytrain, yvalid = train_test_split(X, y, test_size=0.2, random_state=42)###Implement the Xgboost#### We can now select the parameters for Xgboost and monitor the progress of results on our validation set. The explanation of the xgboost parameters and what they do can be found on the following link [http://xgboost.readthedocs.io/en/latest/parameter.html](http://xgboost.readthedocs.io/en/latest/parameter.html) #dtrain = xgb.DMatrix(Xtrain, label=ytrain)dvalid = xgb.DMatrix(Xvalid, label=yvalid)dtest = xgb.DMatrix(x_test.values)# Try different parameters!xgb_params = {‘min_child_weight’: 5, ‘eta’: 0.035, ‘colsample_bytree’: 0.5, ‘max_depth’: 4,‘subsample’: 0.85, ‘lambda’: 0.8, ‘nthread’: -1, ‘booster’ : ‘gbtree’, ‘silent’: 1, ‘gamma’ : 0,‘eval_metric’: ‘mae’, ‘objective’: ‘reg:linear’ }watchlist = [(dtrain, ‘train’), (dvalid, ‘valid’)]model_xgb = xgb.train(xgb_params, dtrain, 1000, watchlist, early_stopping_rounds=100,maximize=False, verbose_eval=10)###Predicting the results#### Let us now predict the target variable for our test dataset. All we have to do now is just fit the already trained model on the test set that we had made merging the sample file with properties dataset #Predicted_test_xgb = model_xgb.predict(dtest)### Submitting the Results #### Once again load the file and start submitting the results in each column #sample_file = pd.read_csv(‘../input/sample_submission.csv’)for c in sample_file.columns[sample_file.columns != ‘ParcelId’]:sample_file[c] = Predicted_test_xgbprint(‘Preparing the csv file …’)sample_file.to_csv(‘xgb_predicted_results.csv’, index=False, float_format=’%.4f’)print(“Finished writing the file”)

第五步:发布内核。Kaggle 服务器需要一些时间来渲染内核。在内核的 output 选项卡中完成后,提交文件就准备好了。下载并提交

一旦你完成了这个,祝贺你自己提交了你的第一个内核,并开始成为一个骄傲的 Kaggler。现在,是时候进行一些繁重的工作和考虑来改进您的模型了。这是 Zillow 数据科学的一个精彩的幻灯片演示,详细介绍了 Zestimate 模型。这篇评估期刊文章应该是你的下一站,以获得一些关于这个问题的外部观点。这是 Zillow 自己的 Zestimates 的作品,这是 Lynda 的一个关于预测房屋价值的很棒的入门课程。点击链接了解 Zillow 的房屋价值指数和房屋价值预测方法。

为最后一个月的比赛做准备,并进入第二阶段,我强烈推荐阅读 Zillow 创始人兼首席经济学家写的书 Zillow 的谈话——房地产的新规则。

美国的住房发生了很大的变化——1950 年,人均住宅面积为 300 平方英尺,到 2000 年已经增加到 900 平方英尺。有趣的是,人均办公室面积从 1970 年的 600 平方英尺减少到 100 平方英尺。制成 2000 年。美国家庭不仅更大,还拥有一个办公空间(远程办公),一个健身房和游戏室(买家找房子时的首选之一)。)

我们需要记住,房价和购买不仅仅是统计数据,它是一个人生活进步的象征,因此它与情绪和其他任何事情一样重要,我们需要找到一种方法来挖掘这些情绪,以便能够预测房子的正确价值。

Zillow talk 提供了更多的线索,然后你可以在你的模型中处理:例如,靠近市中心的邻近社区的房子比城市中的任何其他社区升值更多(我在这里想到了 Kim Rossmo 的等式),星巴克四分之一英里内的房子比远离咖啡店的房子平均溢价高达 37,000 美元,名校排名可以影响房价, 与地下室的重新建模相比,浴室的重新建模是房屋销售价格的一个积极指标,地下室的重新建模产生了改造投资的一半资金,作为销售价格的一个附加部分,而且名称——命名街道上的房屋比编号街道上的房屋平均多卖 2%,“湖泊”和“日落”是比“主街道”或“杰斐逊”更有价值的街道名称。 下面是书中的一些图表,用来强调外部数据集的价值。

我希望你喜欢这个博客,请继续关注更多更新和更好的代码。做 UpVote 如果有用的话。

如何进行正确的根本原因分析

原文:https://towardsdatascience.com/how-to-conduct-a-proper-root-cause-analysis-789b9847f84b?source=collection_archive---------0-----------------------

我们所有人都害怕那种老板会问“为什么收入下降了?”唯一比这个问题更糟糕的是没有任何答案!您的业务每天都在发生许多变化,通常您会希望确切地了解是什么推动了给定的变化,尤其是在变化出乎意料的情况下。

理解变化的根本原因被称为根本原因分析。根本原因是最终导致变化的行动或事件。请注意,根本原因本身可能不会导致变更,它可能会引发一系列其他事件,最终导致变更。当然,给定变化的根本原因可能不止一个。

例如,假设我们经营一家名为 Sean's Snowshoes 的大型连锁零售店。如果我们的收入下降,可能是由于以下原因之一:

  • 竞争降低了他们的价格,导致我们的销售额减少。
  • 一场大规模的暴风雪使我们的顾客呆在家里,而不是在我们的商店里。
  • 我们的一个主要营销活动结束了。
  • 我们改变了让顾客困惑的优惠券策略。

….或者其他几十个潜在原因中的一个!

正如你所想象的,根本原因分析可能是复杂和具有挑战性的。本周,我们将介绍一系列技术和工具,帮助你在这些困难的水域中航行。具体来说,我们将涵盖:

  • 第 1 部分 —确定影响因素
  • 第二部分 —排序因素
  • 第三部分 —分类因素
  • 第 4 部分 —根本原因分析设计

让我们开始帮助 Sean 的雪地靴进行根本原因分析,确定我们需要考虑的所有影响因素。

异常值 监控您的业务数据,并在发生意外变化时通知您。 我们帮助营销/增长&产品团队从他们的业务数据中获取更多价值。 今天安排一个试玩

第一部分。确定影响因素

根本原因分析的第一步是识别所有促成问题变化的因素。业务变化有两种主要的促成因素:

  • 内部。这些都是你所采取的行动,这些行动导致了你的企业发生了变化。示例包括新产品发布、产品更新和营销活动变更。
  • 外部。不管你愿不愿意,这些事情都会发生在你身上。例子包括竞争性价格变化、用户行为转变和自然灾害。

我们的目标是列举每一个可能的因素,这两种类型,可能有助于我们正在分析的变化。我们在这个阶段越全面,就越有可能找到根本原因。

让我们回到 Sean's Snowshoes 的例子,这是一家零售连锁店,在 1 月 21 日收入有所下降。我们希望找到这种下降的根本原因,因此首先我们将汇集一份可能导致这种下降的所有内部和外部因素的列表:

  • 1 月 21 日:我们开始了新的营销活动。(内部
  • 1 月 20 日:我们一些最大的商场开始施工。(外挂)
  • 1 月 20 日:我们的一项主要营销活动结束了。(内部)
  • 1 月 19 日:我们开始了新的在线优惠券促销活动。(内部)
  • 1 月 18 日:一场大规模的暴风雪袭击了我们所有的工作地点。(外部)
  • 1 月 17 日:421 号店、439 号店和 456 号店新聘经理。(内部)
  • 1 月 10 日:竞争对手在选定的地点降低了价格。(外部)

要避免的一个重要陷阱是假设促成因素必须与变化同时发生。例如,由于收入在 1 月 21 日下降,我们的第一直觉可能是识别 1 月 21 日发生的所有事情。然而,真正的因素(以及根本原因本身)很可能发生在收入下降之前。根据它们触发的事件链,起作用的因素可能发生在问题变化的几天、几周甚至几个月之前。

请注意,每个因素都有一个与之相关联的日期(或时间),这样我们就可以构建一个导致(和跟随)变更事件的时间表。事实上,如果你的潜在因素列表足够短,你应该现在就做!不幸的是,在现实世界中,这个列表可能会太长,你首先需要缩小范围。

第二部分。分类因素

有了你的潜在因素清单,是时候开始将它们削减到最有可能导致变化的原因了。评估数百个潜在因素可能是不可能的,但如果我们能把它减少到几十个,这就成了一个可管理的问题。最好从一开始就指出变化的指标和组成变化的部分开始。

让我们回到 Sean's Snowshoes 的例子,一家零售连锁店的收入下降了。收入本身很容易理解,因为它是我们从销售中获得的现金总额。但是,收入可以由许多不同的因素分解:

  • 存储位置
  • 客户位置
  • 产品
  • 星期几

通过查看每个维度(以及所有维度的组合)的收入,应该会清楚哪些细分市场导致了收入下降。是一家特别的商店吗?一些具体的产品?特定的日期或时间?您希望确定哪些部分在总体变化的同时发生了变化,以及哪些部分的数量最多。

以下是肖恩雪地鞋收入的一些精选维度的图表:加州的收入、销售围巾的收入和 456 号店的收入。

该图帮助我们确定哪些方面是变化的驱动因素,哪些方面可能是副作用:

  • 右边的总收入(蓝色)大幅下降。我们的目标是找到这种变化的根本原因。
  • 加州(黄色)的收入显然是总收入的重要组成部分,它确实与总收入同时下降。然而,它没有总收入下降那么多,而且恢复得很快,所以看起来不像是下降的原因。
  • 围巾(紫色)的收入与总收入同时大幅下降,但这只是总收入的一小部分。总收入中如此小的一部分更可能是副作用,而不是根本原因。
  • 456 号店(绿色)的收入是总收入的重要组成部分,当总收入下降时,其收入也大幅下降。这是一个明显的落点来源。

一旦您有了看起来与变更相关的最重要的部分,您就可以使用它来选择最有可能影响这些部分的因素。如果我们重温昨天的潜在因素列表,我们可以排除那些不会影响 456 号店的因素。具体来说,任何影响所有商店的变化都不太可能比可能影响该商店的因素起作用:

  • 1 月 21 日:我们开始了新的营销活动。(内部)
  • 1 月 20 日:我们一些最大的商场开始施工。(外部)
  • 1 月 20 日:我们的一项主要营销活动结束了。(内部)
  • 1 月 19 日:我们开始了新的在线优惠券促销活动。(内部)
  • 1 月 18 日:一场大规模的暴风雪袭击了我们所有的工作地点。(外部)
  • 1 月 17 日:421 号店、439 号店和 456 号店新聘经理。(内部)
  • 1 月 10 日:竞争对手在选定的地点降低了价格。(外部)

当然,在你的分析中,你会有成百上千个不同的维度和组合需要检查。像我在这里所做的那样绘制它们是不可行的,因为与每个指标相关的维数太大了。为了帮助简化这个问题,您可以使用我们的系列中关于集群的技术,称为层次集群。层次聚类的目标是以层次结构中最重要的聚类形式汇总数据,这是突出显示哪些维度可能与更改相关的好方法。只要你按照总的百分比和变化幅度的组合进行分类,这个层次结构应该能够完成我们通过上面的观察所做的事情。[1]

第三部分。分类因素

现在我们有了一个较短的潜在原因(因素)列表,按影响的可能性排序,我们需要确定哪一个是根本原因。每个因素可分为四组:

  • 关联结果。这些因素是同一根源的其他症状。例如,如果收入下降,我们的销售税征收减少,销售税的减少不是收入减少的原因,而是根本原因的另一个副作用(导致收入下降的原因)。
  • 无关因素。这些因素看起来可疑,但实际上与所讨论的变化无关。
  • 促成因素。这些因素虽然是导致连锁反应的事件链的一部分,但不是根本原因。例如,如果收入下降,购买总数下降,购买总数的减少可能是收入下降的原因,但不是购买本身下降的原因。
  • 根本原因。这是引发导致变化的一连串事件的因素。记住,可能不止一个!

我们的第一步是将所有高可能性因素排列成一个时间表。在你的时间线上确定因素发生的顺序并不总是像检查它们发生的时间一样容易,有时你需要依靠你对业务和内部流程的了解。

如果你还记得 Sean 滑雪板的例子,很明显,456 号店是我们 1 月 21 日收入下降的核心原因。以下是我们确定的与 456 号店相关的因素的时间表。

按照时间来组织这些因素,当它们开始向我们讲述一个故事时,更容易对这些因素进行分类。

  • 1 月 10 日:竞争降低了附近商店的价格。这几乎是下降前的两周,不太可能是根本原因,因为我们会在更早的时候看到收入变化。判决:无关
  • 1 月 18 日:助理经理辞职。这可能是 1 月 17 日招聘新经理的结果。充其量这只是一个促成因素,但更有可能是出了什么问题的另一个症状。判定:相关因素
  • 1 月 20 日:停车场开工。这可能是罪魁祸首,因为如果顾客不能停车,他们可能无法到达商店。然而,像这样的施工是另一个决定的结果,因为施工人员不会自己出现。这是导致变化的事件链的一部分,但不是根本原因。裁决:促成因素
  • 1 月 17 日:新经理入职。这是我们最有可能的罪魁祸首,因为它发生在下降之前不久,新经理将不得不批准停车场的建设开始。判决:根本原因

很明显,这是一个简单的例子,但是我希望它能给你一个重新创建时间线和对因素进行分类的过程是如何为你工作的感觉。

你可能已经注意到,根本原因分析很像侦探工作。你从一些证据开始,排除可能的嫌疑,希望重建事件的时间线。就像侦探工作一样,有些事情你今天就可以开始做,这将有助于你在未来更好地进行根本原因分析。

第四部分。为根本原因分析而设计

正如您所看到的,确定根本原因具有挑战性。确保您能够可靠地识别根本原因的最佳方法是设计您的业务流程,使其更容易。关键是要确保你已经记录了所有你需要的数据,并且很容易获取,以便找到根本原因。

以下是一些最佳实践:

  • 记录你的动作。在共享日历上跟踪重要的业务决策和行动。这将让你很容易地识别出所有可能导致变化的内部因素。
  • 追踪外力。监控所有可能影响你业务的外部力量,包括竞争、经济和政府政策。有许多服务将为你做这件事,但是你的任务是识别最重要的,因为你不能监控整个世界。
  • 对您的数据进行分段。确保您的度量是分段的,以便您可以有效地评估任何给定分段促成变更的可能性。如果你不能对你的指标进行细分,你将不得不花费大量的时间通过其他方式来消除潜在的因素。
  • 绘制您的流程图。你的业务流程应该被写下来,这样你就可以找出促成因素和根本原因之间的区别。

你能做的越多,将来你就能越快、越容易地找到问题的根源。

一句提醒的话:在你做了许多根本原因分析之后,当一个新的变化事件发生时,很容易依赖你的直觉。它可能看起来和感觉起来像你过去分析过的其他人,这使你很容易根据你以前的经验得出结论。这是危险的,因为你假设未来和过去一样,而许多其他事情可能已经改变了。即使你认为你知道根本原因,也要仔细分析,确保你没有遗漏任何东西。

在回顾

确定业务变化的根本原因包括三个步骤。首先,找出所有可能导致变化的因素。第二,使用您的指标分段从该集合中选择最可能的因素。最后,重新创建变化的时间表,并使用它对因素进行分类,确定其中的根本原因。

根本原因分析也是找到问题根源的有力工具。祝你好运!

[1]如果您有兴趣了解这方面的更多信息,宝洁公司发表了一篇有趣的论文,介绍了聚类在根本原因分析中的应用。

异常值 监控您的业务数据,并在发生意外变化时通知您。 我们帮助营销/增长&产品团队从他们的业务数据中获取更多价值。 今天安排一个试玩

使用 TensorFlow Estimator API 时如何定制分布式培训

原文:https://towardsdatascience.com/how-to-configure-the-train-and-evaluate-loop-of-the-tensorflow-estimator-api-45c470f6f8d?source=collection_archive---------6-----------------------

TensorFlow 的 Estimator API 提供了一个简单的高级 API 来训练机器学习模型。您可以在估计器上使用 train()、evaluate()或 predict()方法。然而,大多数情况下,培训是在一个循环中以分布式的方式进行的,在培训过程中定期进行评估。为此,您将使用 train_and_evaluate 循环:

tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)

在本文中,我将讨论您可能希望在 train_spec 和 eval_spec 中指定哪些内容。总之,这些选项允许 train_and_evaluate 提供一种强大的、可定制的方法来进行分布式培训。

这里有一个完整的 train_and_evaluate(完整代码在 GitHub 上)。我将挑选出不同的部分来讨论:

def train_and_evaluate(output_dir):
    EVAL_INTERVAL = 300 # seconds run_config = tf.estimator.RunConfig(save_checkpoints_secs = EVAL_INTERVAL,
                                        keep_checkpoint_max = 3)
    estimator = tf.estimator.DNNLinearCombinedRegressor(
        model_dir = output_dir,
        ...
        config = run_config)

    estimator = tf.contrib.estimator.add_metrics(estimator, my_rmse) train_spec = tf.estimator.TrainSpec(
        input_fn = read_dataset('train', tf.estimator.ModeKeys.TRAIN, BATCH_SIZE),
        max_steps = TRAIN_STEPS) exporter = tf.estimator.LatestExporter('exporter', serving_input_fn, exports_to_keep=None) eval_spec = tf.estimator.EvalSpec(
        input_fn = read_dataset('eval', tf.estimator.ModeKeys.EVAL, 2**15),  # no need to batch in eval
        steps = None,
        start_delay_secs = 60, # start evaluating after N seconds
        throttle_secs = EVAL_INTERVAL,  # evaluate every N seconds
        exporters = exporter) tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)

train_and_evaluate() is highly customizable

运行配置

RunConfig 允许您控制检查点被写出的频率。检查点是 Estimator 支持容错的方式。如果训练群集的主要(或主节点)失败,训练将从检查点恢复。检查次数越多,机器故障造成的损失就越少。当然,检查点本身会消耗 CPU 和存储,所以这是一个权衡。在我的示例中,我要求每 300 秒执行一次检查点操作(以限制 CPU 开销),并且只保存最后 3 个检查点(以限制存储开销):

run_config = tf.estimator.RunConfig(save_checkpoints_secs = 300, 
                                    keep_checkpoint_max = 3)

您还可以根据训练步骤的数量来指定检查点间隔——最初,这看起来更简单,也更有吸引力。然而,如果您认识到检查点是关于故障恢复的,您将很快认识到按时间指定这是一个更好的选择。Estimator 足够聪明,不会编写检查点,除非训练工作实际上已经取得了进展。

请注意,run_config 是作为参数传递给估计器的:

estimator = tf.estimator.DNNLinearCombinedRegressor(
        model_dir = output_dir,
        ...
        config = run_config)

评估指标

默认情况下,预构建的估计器(如 LinearRegressor 和 DNNClassifier)会预先指定它们将评估的指标。例如,对于 LinearRegressor,这是 average_loss,即均方误差。一个常见的需求是评估其他指标。您可以通过 add_metrics 来实现:

estimator = tf.contrib.estimator.add_metrics(estimator, my_rmse)

这是一种常见的模式——扩展 Estimator 的方法是对其进行包装并添加额外的功能。在这种情况下,有一个贡献函数能够添加指标。my_rmse 是一个函数,它返回此类指标的字典:

def my_rmse(labels, predictions):
    pred_values = predictions['predictions']
    return {
      'rmse': tf.metrics.root_mean_squared_error(labels, pred_values)
    }

训练批量

梯度是一次对一批训练样本进行计算的。该批次的大小由训练输入函数控制:

train_spec = tf.estimator.TrainSpec(
  input_fn = read_dataset('train', ModeKeys.TRAIN, 40),
  max_steps = TRAIN_STEPS)

您的输入函数可能使用 TensorFlow 数据集 API,其中批处理只是对数据集的一个调用:

dataset = dataset.repeat(num_epochs).batch(batch_size)

但是,请注意,num_epochs 在分布式训练中的表现不同。训练时间由训练步数控制,而不是由重复输入数据控制。因此,将模式传递给输入函数是很重要的,因为您可能希望随机排列训练示例并无限期地读取训练数据:

if mode == tf.estimator.ModeKeys.TRAIN:
   num_epochs = None # indefinitely
   dataset = dataset.shuffle(buffer_size = NWORKERS * batch_size)

为什么洗牌?这是因为,在分布式训练中,每个工人在一批上计算梯度,然后梯度更新在所有工人中平均。显然,如果你的所有员工都在处理相同的数据,那就没有意义了。因此,您要求数据集打乱数据,以便每个工人看到不同的批次。

在评估期间,num_epochs 将为 1,但是您可以通过适当地设置评估步骤的数量来评估数据集的一部分(这将在下面介绍)。

火车步骤

TrainSpec 的第二个参数表示要训练多少步:

train_spec = tf.estimator.TrainSpec(
  input_fn = read_dataset('train', ModeKeys.TRAIN, BATCH_SIZE),
  max_steps = TRAIN_STEPS)

记住,训练步骤包括对一批训练样本进行梯度计算。 TrainSpec 需要训练模型的最大步数。注意,这是 max_steps,而不是 steps。如果您有一个对应于步骤#1800 的检查点,并且您指定 max_steps=2000,那么训练将在 1800 恢复,并且只进行 200 步!恢复训练的能力是一个重要的属性,但是请确保您完全理解这意味着什么:要从头开始训练,您需要清除输出目录,以便没有预先存在的检查点。

还要注意,这是控制你训练时间的因素——它实际上覆盖了输入函数中的 num_epochs。

出口商

检查点不同于导出。检查点是关于故障恢复的,并且包括保存完整的训练状态(权重、全局步数等。).导出是关于创建服务签名。最常见的情况是,您将导出神经网络的预测头或输出节点,但有时,您也会想要导出嵌入节点。

在我的例子中,我在培训结束时导出:

exporter = tf.estimator.LatestExporter('exporter', serving_input_fn, exports_to_keep=None)

导出的模型将被写入名为“exporter”的目录,并且服务输入函数指定最终用户将被期望向预测服务提供什么。如果要保留与最后 5 个检查点对应的导出,可以指定 exports_to_keep=5。

评估批量

训练批次大小大约是计算梯度的样本数。然而,在评估期间,没有计算梯度。在评估期间,成批读取数据以避免过度分配内存缓冲区的唯一原因。因此,请指定一个更大的批量:

input_fn = read_dataset('eval', tf.estimator.ModeKeys.EVAL, 2**15)

训练批次大小约为 100,而评估批次大小可以设置为一个批次的总内存使用量约为 32MB,显然,确切的数量取决于训练数据在内存中占用的空间。

评估步骤

评估时,可以通过在 EvalSpec 中指定 steps=None 对整个数据集进行评估:

eval_spec = tf.estimator.EvalSpec(
        input_fn = ...,
        steps = None

但是,如果数据集很大,这可能会带来相当大的开销。在培训期间进行评估的唯一原因是为了监控,并且您希望监控在某种程度上是轻量级的。因此,一个好的折衷办法是指定足够大的步骤数,使评估在统计上是稳健的。这取决于您的数据,但 100 往往是一个常见的选择:

eval_spec = tf.estimator.EvalSpec(
        input_fn = ...,
        steps = 100

因为我们的 batch_size 是 2 * 15(或 32k),所以 100 个步骤对应于大约 320 万个示例,我们的想法是对这个大数字进行评估已经足够稳定了。

评估油门

默认情况下,Estimator 将在每次检查点时进行评估。您可以在评估上指定一个限制,以便更频繁地进行检查点操作(用于故障恢复),但减少评估次数(用于监控)。这样做的原因是检查点相对较快,但评估可能较慢,尤其是在评估整个数据集时:

eval_spec = tf.estimator.EvalSpec(
        input_fn = ...,
        steps = EVAL_STEPS,
        start_delay_secs = 60, # start evaluating after N seconds
        throttle_secs = 600,  # evaluate every N seconds
        exporters = exporter)

如您所见,train_and_evaluate 提供了一种强大的、可定制的方法来进行分布式培训。

如何用 Pythonic 方式将不同情况下的对象相互连接

原文:https://towardsdatascience.com/how-to-connect-objects-with-each-other-in-different-situations-with-pythonic-ways-d3aaf4c89553?source=collection_archive---------2-----------------------

Credits — author : Joanna Malinowska; illustrator : Tatuna Gverdtsiteli

你知道什么是“地理课的效果”吗?!我想,你没有。因为这种效应是由我的朋友命名的,它描述了一种感觉,当你完全准备好某事时,例如为上课,当你被问到某事时,在你回答完之后,你有一种感觉,你可以做得更好,这不是你的最佳答案。很常见吧?有很多原因可以解释为什么它在每个人的生活中至少发生过一次,但这超出了我们的范围。我只是想说,这种感觉对于音箱来说是很常见的(行业无所谓)。每次他们中的大多数人都认为这次经历没有最大限度地发挥他们的潜力,当他们试图在另一个会议上或更好的情况下做同样的演讲时,他们会把他们的演讲写成一篇文章,因为写博客要容易得多。你没有严格的日程安排和时间限制或其他类似的尴尬因素。

老实说,我可以说我没有受到这种影响。我喜欢每次都尽力而为,我也喜欢这种做法,这一点我在上面已经提到过了(在另一场会议中不是同样的谈话)😀 ).所以我决定写一篇关于这个话题的文章,我认为这真的很重要,并且引用了我大约参加过的 Pycon 会议。两个月前。

演讲的视频还没有上传。这对于会议来说很常见,尤其是对于 Pycons 来说,他们需要 2 个多月的时间才能在 Youtube 上上传所有的演讲。当然,这不是一个很长的时间,当你应该剪辑 50-100 个演讲时,主要持续时间是 30 分钟,但我只有一个问题-为什么不做一个视频编辑的人工智能工具,在那里你可以学习人工智能你已经得到的(幻灯片,演讲)和你想要的结果(用幻灯片演讲),它会自动执行这些,而没有任何不必要的努力?无论如何,如果你喜欢这个想法,并决定写这个项目-添加我的学分🙂

现在,如何用 pythonic 方式连接对象,何时使用关联、聚合、继承等等..

不难看出并记住对象之间这种关系的区别,但是,例如,当我向某人询问这些话题时,几乎每个人都说他们有相当模糊的知识,例如聚合和组合之间的区别,或者组合和复合设计模式之间的区别,或者如果他们有知识,他们只知道抽象的概念。

诚然,面向对象的设计原则并不是特定于语言的,但是不同语言在实现细节上有所不同,并且有一些技术并不适合所有语言。

例如,当我们谈论多重继承时——我们应该考虑到这对于面向对象的范例来说是一个非常敏感的话题,存在类似“钻石问题”的情况

对于一些语言来说,这是一个非常严重的问题,它们不允许多重继承。也有语言不允许类多重继承,只允许接口多重继承。

因此,对于许多只实现单一继承的语言来说,使用接口、协议、混合、特征和其他架构解决方案来提供真正多重继承的一些功能是非常常见的。

与 DI( 依赖注入)相关的题目,也是很重要很痛苦的。

在这种情况下,已经了解 oop 概念的程序员不会再问一些愚蠢的问题,比如“我们到底为什么需要对象?我们可以使用函数编写任何东西。”我觉得这句话用 Python 来说很讽刺,有其他编程语言背景的人还是没有考虑到我们一定要用 Python 的方式写 Python 代码。

例如,他们没有考虑如何使用 super 来制作 di。我不想写这些话题,因为这里有一个最流行的话题。雷蒙德·赫廷格认为超级就是超级。

因此,在开始讨论如何用 python 的方式将对象相互连接之前,我们必须深刻理解 MRO 是如何在 python 中处理新旧样式类的。

众所周知,Python 支持多重继承,也就是说,在 Python 中,一个类可以继承多个类的特性和属性。

MRO 或方法解析顺序是在父类中查找方法时搜索基类的层次结构。python 中有两种类型的类。

直到 Python 2.1,旧式的类是用户可以使用的唯一风格。—docs.python.org

Python 2.2 引入了新样式的类来统一类和类型的概念。—docs.python.org

Python 3 只有新型类。不管你是否继承了object的子类,类在 Python 3 中都是新的样式。—docs.python.org

它们之间有很大的区别(新样式类和旧样式类),例如,在新样式类中添加了

  • 描述符
  • 时间
  • 静态方法
  • 类方法
  • 低级构造函数

但是最重要的事情之一是在新的风格类别中,我们有了新的 MRO。

旧类 MRO 算法非常简单易懂,它是这样工作的:“深度优先,从左到右”。
这意味着当我们实现多重继承时——Python 构建了一个要搜索的类列表,因为它需要解析当实例调用一个方法时必须调用哪个方法。

该算法首先在实例类中查找被调用的方法。

如果它不存在于实例类中,那么它会查找第一个父类。如果没有出现,则检查父类的父类,这一直持续到类深度的末尾,最后,直到继承类的末尾。

根据该算法,方法分辨率应为:

D>B>A>c

但是对于新的类型类——Python 使用 c3 线性化算法,也称为 c3 超类线性化。

这意味着,如果我们在新的类型类中有相同的结构,方法解析应该是 D > B > C > A。

让我们继续 Mixins。

混合和特性

Mixin 是一个包含供其他类使用的方法的类,而不必是那些其他类的父类。

-维基百科

当我们开始讨论多重继承时,我们说过在一些面向对象的语言中存在混合的概念,它主要是一个包含其他类可以使用的方法的类。

我们也可以说它是一个类的语言结构,用于向另一个类添加功能。

它们并不意味着要独立存在——只有当它们与其他阶级混在一起时才有意义。还有一个关于混合蛋白的非常流行的短语,它帮助我们更好地理解混合蛋白的本质——混合蛋白是“包含的”而不是“继承的”。

Ruby 使用模块支持 mixin,所以我们可以看到在 ruby 中实现 mixin 的最简单的例子:

PHP 使用 traits 类来继承特定的方法实现。

Trait 是面向对象编程中使用的一个概念,它表示一组可用于扩展类功能的方法。

-维基百科

可以这样做:

这些方法之间几乎没有区别,但是在这种情况下,我们只对这种关系的结构感兴趣。
现在让我们从 Python 的角度来探索 Mixins。

Python 语言并没有混合的概念,但是它提供了多重继承。尽管 mixins 和多重继承的技术实现是相似的,并且可以类似地使用,但是在很多方面有一些非常重要的区别。

通常 mixins 是扩展某些类的可选定制;它们不同于抽象类,因为当 mixin 提供功能但不能直接使用它时,抽象类只提供接口,没有可用的功能,所以定义了一组函数。但是就它们自己而言,这些类是没有用的,你不能单独实例化它们。

如果你知道这个词的来源,这是很符合逻辑的。
马萨诸塞州一家冰淇淋店的老板第一次使用了“混合”这个名称,他将冰淇淋的基本口味与坚果、饼干等其他配料混合在一起。

Credits : Tatuna Gverdtsiteli

因此,当我们实现具有多重继承的混合时——通常它被用作二级基类,但是因为我们在 Python 中有 MRO,所以不强制将其用作二级基类。

为了更好地理解,我们可以看到字典对象最简单的混合示例:

首先,我们编写 mixin 类并试图覆盖 setitem 函数,当我们有了字典并设置了新的 key:value 对时,就会调用这个函数。接下来我们创建 dictionary 类,它将是 mixin 类的子类,也是 dictionary 对象的子类。
最后,我们可以从我的字典类创建新的实例,当我们在字典中设置一个键值时,MRO 调用我们的 mixins setitem()来打印这些文本,并为超类调用 setitem()在本例中是字典。

因此,我们可以看到 MRO 在使用 mixin 方面发挥了重要作用,因为 Python 本身并没有 mixin 的具体实现。

正确使用 mixins 的最好例子——我们可以在 Sqlalchemy 中看到,它是 Python 中最流行的对象关系映射器和 sql 工具包之一。

例如,当我们想要创建模型,该模型将与具有相似名称的表相连接,并且我们想要为每个表 id 创建一个 pk 时,我们可以编写我们的 mixin,然后,我们创建 MyModel 类,它将是基类的子类,也是 mymixin 的子类,我们得到如下的类:

如果我们知道基类没有定义 mymixin 定义的任何变量,我们可以使用这两个代码并得到相似的结果。但是如果我们在两个类中都有 tablename attr,我们会得到不同的结果,因为 mro 在那里的工作方式不同。

在关系中使用 mixins 也很常见——当我们想要创建表之间的关系时,例如当我们有类 foo 和类 bar,并且我们想要在它们和类 target 之间进行引用时。

这是我们的班级结构:

接下来我们创建 mixin RefTargetMixin,我们可以将这个 mixin 添加为 foo 和 bar 类的父类。最终结果将是这样的:

当 sqlalchemy 使用 mixins 时,还有更高级的情况,您可以阅读文档查看其他示例。

所以总的来说,当我们想为一个类提供不同的可选特性时,mixins 是最好的。

这也是一个非常灵活的解决方案,当你想在不同的类中拥有相同的特性,又不想打破一成不变的规则时。

所以,通常 mixins 经常在框架中和流行的工具包中使用。

联合

那么联想呢?

当语言支持多重继承时,这是非常灵活的,但当我们想要将对象相互连接时,每次都使用继承并不完美。

举个例子,因为在 oop 中有一个很流行的情况,当你想要一个香蕉,但是你得到的是一个拿着香蕉的大猩猩。

你想要一个香蕉,但你得到的是一只大猩猩拿着香蕉和整个丛林。

—乔·阿姆斯特朗

除此之外,还有类似于《Python 掌握设计模式的艺术》一书中的经验法则:

如果你认为你需要多重继承,你可能是错的,但是如果你知道你需要它,你可能是对的。

如果我们使用多重继承,并且没有正确地定义某些东西,将来可能会导致更多的问题。

这正是我们需要联想概念的地方。

在面向对象编程中,关联定义了对象类之间的关系,允许一个对象实例引起另一个对象实例代表它执行一个动作。

-维基百科

它通过对象在两个独立的类之间建立关系。

当我们使用继承时——通常类之间存在“是-是”关系。例如,如果我们有一个 conference 类,并且我们想从它实例化 python conference 类,我们将执行以下操作。

这是一个经典继承的例子,我们看到,它们之间确实存在“是-a”关系,因为在现实中——python 大会— 也是一个大会。

在 associacion 的情况下,我们通常使用' has-a '和' uses-a 关系。

第一个词的名字是 composition,从逻辑上我们可以看到——“has-a”比“uses-a”联想更强。

我们也可以说,组合是将几个对象收集在一起创建一个新对象的行为,当一个对象是另一个对象的一部分时,这通常是一个好的选择。

组合是一种受限的聚合形式,其中两个类高度依赖于彼此。

例如人类和身体部分,我们需要身体部分来生存,身体部分需要我们的身体来生存。所以我们可以说,这些物体的寿命和类是一样的,或者说,如果人类类不存在,心就没有意义。人和大脑以及人和心脏是非常常见的例子,它们对于更好地理解非常有用,但是在所有情况下使用相同的例子会使记忆非常困难,因为每个人在谈论 oop 时都会使用这些例子,所以我们可以使用“演讲者”和“幻灯片放映”的例子,当演讲者是对象时,它会创建自己的幻灯片放映并使用它,所以如果没有演讲者,就不会有幻灯片放映。我们可以看到实现是什么样子的:

关联的第二种形式是聚合,它表示 has-a 关系,而且在聚合中,两个条目可以单独存在,这意味着结束一个对象不会影响另一个对象。

聚合的典型例子是组织和个人,或者聚合的另一个例子是学校班级中的学生,当学校关闭时,该学生仍然存在,然后可以加入另一所学校。这里我们也可以使用更具体的情况,例如扬声器和麦克风,因为麦克风的存在不依赖于扬声器的存在。我们可以看到代码示例:

因此,作为结论,我们可以说组合和聚集都是两个对象之间的关联形式,但是组合和聚集之间有细微的区别,

当一个类拥有另一个类,而当另一个类的所有者被破坏时,另一个类无法有意义地存在时,我们将两个对象之间的关联称为复合。但是如果 A 和 B 相互关联,使得 B 可以不与 A 关联而存在,那么这种关联被称为聚合。

还有,记住这一点很重要,那就是组合是聚合;聚合只是一种更一般的组合形式。正如我们已经说过的——“组合是聚合的一种受限形式”,任何复合关系也是聚合关系,但不是相反。我们可以看到图像,以便更好地理解。

复合设计模式

再举一个例子——当我们谈到关联、它的用法和对象之间的强关系时——我们必须紧急承认一个最常用的基于这种范式的设计模式。

credits: Wikipedia

复合模式为我们提供了从简单组件构建树状结构的可能性。这些组件被称为复合对象和叶对象。

如果它们有子组件——它们的行为就像一个容器,或者如果它们没有子组件——它们的行为就像变量。复合对象是容器对象,其中的内容实际上可能是另一个复合对象。

关键是复合节点和叶节点可以有相同的接口。我认为 UML 图非常简单:

book: Python Master the Art of Design Patterns

文件夹的结构是使用复合模式的最好例子。我们可以在文件夹中创建文件,也可以在这些文件夹中创建其他文件夹。

现在我们可以看到一些代码示例来更好地理解复合设计模式,并再次看到关联的实现。

首先,我们声明一个抽象类,并在其中创建一个抽象方法,之后,每个复合对象和每个叶对象都必须实现这个抽象类的行为,这是强制性的,因为如果我们再次谈论文件夹和文件,我们也可以对它们进行相同的操作,例如复制、粘贴、删除、重命名等。

在复合类的初始化方法中,我们为子类创建了“set”集合。接下来,创建一个添加子节点的方法和操作方法,为每个子节点调用相同的方法。

还有一个 leaf 类,它表示一个 leaf 对象,leaf 是一个没有子对象的对象,所以我们在 leaf 类中定义了 operation method,因为我们已经说过它也继承了组件。

因此,最后我们可以创建一些叶对象,复合对象,将叶对象添加到复合对象,然后调用复合对象上的操作方法,如果我们运行代码,我们会看到操作方法将执行三次,因为我们总共有 3 个叶对象。

我真的很喜欢 Python,并且仍然在尝试语言概念,试图找到每种情况下的最佳实践,所以如果您有任何问题或想法,请不要犹豫,留下您的评论。

谢谢你,祝你愉快!

如何在 Python 中运用现代投资组合理论构建高效的投资组合?

原文:https://towardsdatascience.com/how-to-construct-an-efficient-portfolio-using-the-modern-portfolio-theory-in-python-5c5ba2b0cff4?source=collection_archive---------8-----------------------

在我的上一篇文章中,我们讨论了使用 Harry Markowitz 均值-方差分析构建一个最优的股票投资组合。在这篇文章中,我们将通过为五只股票的组合生成随机投资组合来构建一个有效边界。

那么什么是有效前沿

简而言之,在给定风险水平下,提供最佳投资组合回报的权重组合(财富份额)。

例如,请看下图,它描绘了使用随机权重生成的数千个随机投资组合回报和波动性。注意到黑色的痕迹了吗?回报较高的是曲线有效的一边,因为在同样的风险水平下,它能提供更多的回报。

Random Portfolios

所以现在我们知道什么是有效边界,因此我们将开始用 Python 来编码它。这篇博文使用的数据可以在这里找到。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# loading the returns datadaily_returns = pd.read_csv("Returns.csv", index_col ="Date")
mean_ret = daily_returns.mean().reshape(4,1)#Generating a random matrix of 1000 rows and 4 Columns
matrix = np.random.rand(1000,4)#Converting to a data frame
matrix_df = pd.DataFrame(matrix, columns = daily_returns.columns)matrix_sum = matrix_df.sum(axis = 1)#Calculating portfolio weights
weights  = matrix_df.divide(matrix_sum , axis ="rows")#transpose
weights_t= np.transpose(weights)#Using the portfolio return formula
portfolio_return = np.dot(weights, mean_ret)

为了生成有效边界,我们需要随机投资组合,对于随机投资组合,我们需要随机权重分别乘以它们的平均回报率,以获得投资组合回报。上面的代码块做了需要做的事情。

我们还需要有效边界的投资组合风险,它是从下面的代码中计算出来的。

#Variance covariance
cov_mat = daily_returns.cov()portfolio_risk = []
for one_port in range(weights.shape[0]):

    risk = np.sqrt(np.dot(weights.iloc[one_port,:],np.dot(cov_mat,weights_t.iloc[:,one_port])))

    portfolio_risk.append(risk)

现在我们已经做好了规划投资组合的一切准备。下面的代码绘制了一个简单的投资组合回报与投资组合风险的散点图。

plt.figure(figsize = (10,8))
plt.scatter(portfolio_risk, portfolio_return)plt.xlabel("Portfolio Risk - Standard Deviation")
plt.ylabel("Portfolio Return")plt.show()

就这么简单。因为我不习惯用 Python 绘图,所以我决定也用 Tableau 绘图,以获得更好的交互式可视化效果。

#converting to a csv file
portfolio_risk = pd.DataFrame(portfolio_risk, columns = ["portfolio risk"])portfolio_return = pd.DataFrame(portfolio_return, columns = ["portfolio return"])random_portfolio = pd.concat([portfolio_return, portfolio_risk, weights], axis =1)random_portfolio.to_csv("Random_Portfolios.csv")

[## 效率限界

效率限界

高效 Frontierpublic.tableau.com](https://public.tableau.com/views/EfficientFrontier/Sheet2?:embed=y&:display_count=yes&publish=yes)

接下来,我将讲述我们如何在投资组合优化以及其他金融领域应用不同的机器学习,而不是仅仅进行价格预测,这在现实中几乎没有实际重要性。

参考资料:

https://towards data science . com/efficient-frontier-portfolio-optimization-in-python-e 7844051 e7f

[## 用 Python 实现高效前沿和投资组合优化[第 2/2 部分]

在这个系列的第一部分,我们看了现代投资组合理论的基础,并产生了一个有效的…

medium.com](https://medium.com/python-data/efficient-frontier-portfolio-optimization-with-python-part-2-2-2fe23413ad94)

https://medium . com/python-data/efficent-frontier-in-python-34 b0c 3043314

如何在现实世界中构建有价值的数据科学项目

原文:https://towardsdatascience.com/how-to-construct-valuable-data-science-projects-in-the-real-world-203a4f520d54?source=collection_archive---------5-----------------------

从几次错误中吸取的教训

介绍

大多数关于如何“完成”一个数据科学任务的文章通常讨论如何编写一个算法来解决一个问题。例如,如何分类文本文档或预测财务数据。如果属于数据科学家的职权范围,学习如何做这些事情对他们来说可能是至关重要的知识。然而,任务只是在现实世界中完成数据科学项目过程的一小部分。即使你能编码出一个多类文本分类问题的完美解决方案,它对商业有价值吗?这个问题目前的解决方案是什么?你必须超越什么样的基准才能让用户相信它的输出?当算法在生产中启动并运行时,您是否得到反馈以了解输出是否持续产生可用的结果?

在这篇文章中,我想列出一些关于开发和实施有效和可持续的数据科学项目的指导方针。这个指南是我在自己的数据科学项目中犯了几个错误,并看到其他人也犯了自己的错误后得出的。其中一些不适用于所有数据科学家,因为并非所有这些都属于他们的职权范围。然而,在我所在的团队中,我们没有专门的业务分析师、产品经理甚至数据科学经理。这意味着我不得不自己承担这些角色的一些责任,而且经常做得不好。但这是一次宝贵的学习经历,以下是我学到的一些东西。

  • 特别提及:不管你是否同意我的胡言乱语,你都应该看看这篇文章中的视频,关于如何进行利益相关者驱动的数据科学,作者是 Max Shron,Warby Parker 的数据科学主管。这太棒了,为在现实世界中做好数据科学项目树立了一个伟大的标杆。

一个项目需要解决哪些问题才能被认为是成功的?

当想出一个问题的解决方案时,我发现描绘成功是什么样子是很有用的(这里我们假设我们已经知道问题是什么,但是不要低估找出一个你的团队目前能够解决的问题有多难)。这有助于我制定达到最终目标的策略。在这种情况下,我想写下一组问题,如果项目成功,我可以立即回答。他们在这里:

  1. 你为什么要做这个项目?即项目带来了什么价值,它如何为更广泛的数据科学团队目标做出贡献?
  2. 谁是项目的主要利益相关者?
  3. 目前解决问题的方法是什么?
  4. 有没有简单有效的可以快速执行的解决问题的方法?
  5. 你是否努力让合适的人参与进来,并提供足够的通知和信息?
  6. 你和其他人一起对你的解决方案进行过感官检查吗?
  7. 你努力确保代码是健壮的了吗?
  8. 你有没有努力确保这个项目能被别人轻松理解并交给别人?
  9. 你如何在生产中验证你的模型?
  10. 您如何从解决方案中收集反馈?

根据我的经验,如果这些问题能够得到充分的回答,那么这个项目很可能会成功。情况可能并不总是这样,根据项目的不同,这个列表可能远非详尽,但它至少是一个好的起点。

Kate Strachnyi 在开始数据分析之前有一组 20 个问题要问在一篇很短的文章中,如果你决定不通过我庞大的大脑放屁(我不会怪你)。

以下步骤有助于解决这些问题。

数据科学项目的 5 步指南

步骤 1:获得项目潜在价值的初步评估

  • 为什么这么做?它帮助你区分项目的优先次序。你应该能够充分解释为什么一个项目应该在另一个之前完成。它还允许我们理解项目如何与团队和公司的目标保持一致。此外,这还将为我们应该为模型优化什么指标提供一些指导。
  • 这涉及到什么?收益的粗略量化,例如节省的资金、增加的收入、减少花费在体力劳动上的时间。反对这种观点的理由是,这很难做到,而且不总是可以量化的。我的回答是:如果你或你的利益相关者不能算出项目的价值,那么你为什么允许你自己或你的利益相关者 浪费 你的时间呢? 数值不一定要完美,只是一个大概的估计。这一步还包括确定谁是主要的利益相关者?
  • 如果没做到会怎么样? 我们可能会花很长时间做一个对谁都没有好处的项目。我认为可以更好地确定范围的一个项目示例是,数据科学团队的任务是确定最有可能从我们的营销团队联系中受益的人员列表。模型已经建成,但我们决定花几个月的时间来改进它。尽管新模型提供了更好的结果,但团队不得不调整他们的阈值,因为企业并不关心为每个客户生成的分数,相反,他们希望确保他们联系固定数量的人。因此,花费在改进模型上的时间是没有意义的,这是有争议的,如果我们与利益相关者一起更好地确定项目的范围,我们就会知道这一点。(有一种观点认为,由于模型更好,联系的固定人数实际上是一个更好的细分群体,但这没有进行测量,因此我们不知道情况是否如此)。
  • 这一步的结果是什么?对项目价值的粗略量化估计,并附有一段简短的段落,提供更多的背景信息(项目的执行摘要)。需要注意的是,根据公司和项目的不同,仅仅是拥有数据模型的感知价值收益就足以让企业认为项目是成功的。在这种情况下,没有必要进行定量评估。但这更多的是关于公司政治,在你需要确凿的数字来展示你团队的价值之前,这种情况只会持续很久。
  • 有用的资源:这篇题为“一种对任何新特性的投资回报率进行建模的简单方法很有帮助。给个简单的公式:预期 ROI =(用户触达量新增或增量使用量对业务的价值)-开发成本。其他有用的阅读材料有"优先考虑数据科学工作"和"产品和优先考虑"

步骤 2: 确定当前方法/创建基线模型

Source: Create a Common-Sense Baseline First

  • 为什么这么做?当前的方法为我们提供了一个目标基准。所有有用的模型都应该胜过当前的方法,如果有的话。如果当前没有解决问题的方法,那么你应该开发一个基线模型。基线模型本质上是没有机器学习的问题的解决方案。很可能一个复杂的解决方案只能提供增量价值,所以你需要评估是否值得构建更复杂的东西。
  • 这涉及到什么?与利益相关者交流,确定他们目前在做什么以及取得了哪些成功。很可能他们没有衡量他们的成功率,所以这是你必须估计/计算的事情。构建基线模型不应该涉及任何复杂的方法。它应该是相当快速和基本的。可能使用计数方法。
  • 这个阶段的结果是什么?对利益相关者来说成功/有用的绩效的基准评估数。对复杂模型是否值得构建的评估。
  • 如果不这样做,会发生什么:你可能会浪费时间构建一个复杂的模型,这在最好的情况下,可能不值得花费时间来获得额外的准确性,或者在最坏的情况下,甚至不如当前的方法。这是我们在构建推荐引擎时所忽略的。我们没有检查算法是否优于合理的基线(推荐最受欢迎的内容)。可能是因为推荐算法没有提供足够的价值来保证我们做这件事。
  • 资源帮助:标题为“首先创建常识基线”和“总是从一个愚蠢的模型开始,没有例外。强调这一点的好文章。

3.进行“团队”讨论

  • 为什么要这么做?此时,您已经得出结论,该项目值得做(步骤 1)并且成功是可行的(步骤 2),因此是时候与参与项目成功的人员交流了,例如工程师和/或其他数据科学家是显而易见的候选人。你应该更清楚你应该写什么代码,你需要什么数据,你应该测试什么,使用什么性能度量,你应该尝试什么模型方法。你很容易认为自己知道自己需要什么,但与他人讨论往往有助于突出你错过的事情或可以改进的事情。不要低估让不同观点的人参与讨论的重要性。
  • 它涉及什么?至少与另一位数据科学家交谈,并向他们展示你迄今为止取得的成果。也许他们知道如何改进你的想法。在开始模型之前做这件事是至关重要的,因为一旦模型写好了,你就不太可能去修改它。此外,与你交谈的数据科学家可能就是你的代码审查者,所以这将有助于他们了解上下文。与将参与生产你的作品的工程师交谈。他们可能需要知道会发生什么,并且可能会有一些使代码生产更容易的建议。
  • 这个阶段的结果是什么?没什么具体的!只是一些确保质量尽可能好的第一轮。确保相关人员了解并参与项目。
  • 如果没有做到会怎样: 最好的情况:你已经设法自己思考并避免了所有的陷阱。然而,更有可能的是,你没有考虑到所有的事情,你会错过一些重要的事情。这里的典型问题包括当模型进入生产时,存储文件的不可管理的传输和处理。模型输出没有达到目标,并且不是最有用的形式。我制作的一个模型就是这种情况。我编写了进行多次 API 调用的代码,其中许多都是不必要的。我在本地运行的小数据集上运行得很好,但是服务器在生产环境中与负载斗争。直到我与一位帮助我诊断问题的工程师交谈后,问题才得以解决。

4.模型开发

  • 为什么这么做?这是我们用来最终解决问题的模型。
  • 它包括什么?区别在于涉及的内容。不仅仅是创造一个模型。关于如何编写机器学习算法来解决特定问题的文章数不胜数,所以我不会在这里解释。相反,重要的是强调一些应该执行的步骤,以产生高质量的产品代码。在开发过程中,你应该定期进行代码审查。记住,你可能不是唯一一个看到代码的人,你也不是唯一一个投资成功项目的人,所以应该有好的代码文档。这对于项目的长久性至关重要。生产中几乎肯定会有错误和意想不到的输入,因此您可以通过执行代码测试来改善代码的健壮性,从而缓解这些问题。这包括单元测试、集成测试、系统测试和用户验收测试(UAT)。如何使您的代码可生产的细节可能因团队而异,但其他有帮助的事情是:在隔离的环境中工作(虚拟环境或 Docker 容器),使用日志记录来写日志文件,使用配置文件使配置独立于主代码。
  • 这一阶段的结果是什么?一个共享的(Github)存储库,包含所需的文件和解决项目中定义的问题的工作模型。
  • 如果没有完成会发生什么:模型必须完成,否则问题将无法解决。如果你的代码没有经过测试,就会出现逻辑上的错误,直到生产出来才会被发现。如果代码没有被其他人审查或者没有被记录,当你不可避免地离开公司或者休年假时,其他人将很难接手。这些问题中的一些会在我以前做过的不健壮的项目中不断出现。在我参与的一个项目“完成”9 个月后,我仍然在修复它的错误,因为代码不够健壮。这会消耗掉你本可以用来做其他有价值的事情的时间,并且会给相关的每个人带来很多挫败感。确保在开发期间花费额外的时间使代码健壮,因为从长远来看这将节省您的时间。
  • 资源有很多,但这些是我读过的一些我非常喜欢的:
  • 在列表的最顶端有一篇名为“如何在数据科学中编写生产级代码?“它涵盖了我能想到的几乎所有东西。如果你是一个构建生产级代码的数据科学家,那么你应该读一读。
  • 代码评审:代码评审数据科学工作和一篇关于如何“自己进行代码评审”的文章,即以一种被评审的方式编写代码(这不能代替实际的代码评审,它只是帮助你思考如何写出好的代码)
  • 代码文档:关于如何正确编写代码文档的好指南。我也很喜欢 numpy 风格的文档串
  • 代码测试:如何为机器学习代码编写单元测试的指南。这是使用 Python 的 Pytest 库编写单元测试的好指南。我用它来帮助我为我的一个项目编写我的第一组测试。同一家公司也有一篇关于模拟测试数据的文章。这是另一个关于 Pytest 和嘲讽的指南

5.模型监控和反馈

  • 为什么这么做?这是为了确保我们的产品在生产中按预期运行。解决方案的输出应该稳定可靠。如果出了问题,我们应该第一个知道。模型性能是否低于预期?数据的格式是否与培训数据不同?数据是否有误?这为我们节省了大量手动检查输出和检查代码以确保事情按预期运行的时间。当利益相关者开始质疑我们的数据时尤其如此。我们的业务是为公司提供价值,因此我们也应该衡量我们的解决方案的影响。有用吗?它需要调整吗?我们赚了多少钱?该解决方案的使用频率。这些是我们可以向高管报告的数字,以展示数据科学为业务带来的价值。
  • 它包括什么?这涉及到模型投入生产后的一段时间(可能是几周),以手动和主动检查一切是否正常。这也包括自动化监控过程。也许创建一个仪表板和自动电子邮件警报和/或异常检测系统。也许利益相关者也需要进行监控,因此监控解决方案可能需要调整,以方便非技术人员使用。出于反馈的目的,这可能包括与利益相关方讨论您将如何接收反馈。会是定性还是定量?你可以在产品中写一些记录使用的东西,这样你就不必明确地询问涉众的使用习惯。
  • 这个阶段的结果是什么?确保模型正常工作的方法和产品,并提供关于解决方案的使用和价值的定性或定量反馈。如果出现问题,它还可能包括某种形式的通知/警报。
  • 如果不这样做,会发生什么:如果我们的产品没有得到适当的监控,当我们的产品出现问题时,我们可能会面临商业利益相关者对我们产品失去信任的风险。这也可能会耗费企业的资金和我们团队的大量时间来解决问题。我遇到的一个例子是,当我们构建的分析工具中的数据开始给出非常不正确的数字。原来原始数据的提供者搞砸了。但重要的是,是我们的利益相关者在我们的数据团队之前发现了这个问题。健壮的测试(如上面模型开发步骤中所述)和自动警报应该已经发现了这一点,但是我们没有做到。当数据最终回来时,涉众认为数据仍然不正确。我们的数据团队花了 2 周的时间检查数据,结果却是没有任何问题!这是我们在为企业提供价值方面损失的两周时间。自动化监控可以将 2 周时间缩短到 2 分钟!此外,如果我们没有得到反馈,那么我们就不知道我们的项目有多有用,或者它们是否还在被使用。一个例子是在与营销团队的会议中,我们不得不提出问题“您正在使用该模型吗?”。我们不应该问这个问题,因为 1)我们应该在步骤 1 和 2 中正确地确定项目的范围,这样我们就知道价值,并且我们确信我们的模型改进了当前的解决方案/基线模型 2)我们应该将监控作为项目的一部分,而不是在不相关的会议中进行。这表明我们没有衡量模型的影响。

明显的遗漏

我的一个好朋友( Michael Barber )提到我错过了重要的一步:评估。模型评估是流程中极其重要的一部分,如果处理不当,可能会导致生产中模型的意外退化。这里有一篇的好文章,作者是 Rachel Thomas 在 Fast.ai 关于使用合适的训练、测试和验证集进行模型评估。

此外,我完全错过了实验。确定您的数据科学解决方案是否产生了预期影响的最佳方式之一是进行实验和 A/B 测试。这里有一篇关于堆栈溢出时的 A/B 的文章,作者是 Julia Silge。

我不打算详细讨论这些,因为这篇文章已经太长了,这些事情应该在与利益相关者讨论项目如何为企业增加价值时提出来(参见步骤 3,在完成项目之前与相关人员进行讨论)😂。也许我第一次会包括这些要点)。

所以我们有它。这是我认为开发一个成功的数据科学项目所需的 5 个高级步骤。我应该注意的是,并非所有这些步骤都需要由数据科学家完全执行,因为一些团队可能会有专门的成员来执行一些任务。例如,业务分析师或产品经理可能是与利益相关者联络以确定项目是否有价值以及需求是什么的人。此外,有些步骤并不是所有项目都需要的。如果一个项目是一次性的分析,那么就没有必要创建一个仪表板来持续监控输出。

实际上,您不需要遵循所有这些步骤来创建一个成功的数据科学项目。在大多数情况下,除了为涉众建立一个监控仪表板,并在出现异常时自动报警之外,编写一整套测试和文档是不实际的。更有可能的是,你必须权衡这些事情中哪些是值得做的,这样你才能在设定的(可能不合理的)最后期限前完成一个项目。我承认我从来没有完成过任何一个特定项目的每一个步骤,但是,我知道我没有做什么,为什么不在这个特定的时间做是一个务实的决定。

我想强调的另一件重要的事情是,这些步骤只是帮助项目成功的指南。但是要成为一名成功的数据科学家,你还必须具备其他的 T2 特质和 T4 技能。

我很清楚,我不是最有经验的数据科学家,我不知道我不知道什么,所以如果有人有任何意见、问题或建议,请随时在评论中提出。感谢您的阅读:)

如何在对 Tensorflow 一无所知的情况下将 Keras 模型带到 Android 上

原文:https://towardsdatascience.com/how-to-convert-from-keras-to-tflite-with-zero-knowledge-of-tensorflow-5448a296ae67?source=collection_archive---------5-----------------------

Photo by Rodion Kutsaev on Unsplash

你刚刚创造了喀拉斯最惊人的神经网络。但是有一个问题。

目前,您的网络只存在于您的计算机上。它不能从那里改变世界。

你首先想到的是把它放到你的手机上。现在手机比人多,这是一个让你的神经网络真正到达需要它的人手中的极好策略。

在 Android 手机上运行神经网络最流行的库之一是 Tensorflow Lite。要使用它,您需要将 Keras .h5 文件转换为 Tensorflow。tflite 文件。对于那些不熟悉 Tensorflow 的 Keras 用户来说,这可能是一项艰巨的任务。在本文中,我将展示如何在几乎不了解 Windows 操作系统上的 Tensorflow 的情况下实现这一点。

第一步,我们要将 Keras .h5 文件转换成张量流。pb 文件。为此,我们将下载 keras_to_tensorflow 工具,可在此处找到。

[## 阿米尔-阿卜迪/喀拉斯 _ 托 _ 滕索福尔

keras _ to _ tensorflow——将训练好的 keras 模型转换成推理 tensor flow 模型的通用代码

github.com](https://github.com/amir-abdi/keras_to_tensorflow)

在您下载了 repo 并将您的模型(我们称之为 model.h5)添加到该文件夹后,使用命令行导航到该文件夹并键入:

python keras_to_tensorflow.py -input_model_file model.h5

您将生成一个 Tensorflow model.pb 文件。请注意,除非指定,否则此。pb 模型将被称为 output_node,这对于下一个转换步骤非常重要。您还应该知道输入节点的名称,在本例中是 input_1。

现在我们需要转换张量流。pb 文件到 Tensorflow Lite。使用 toco 工具创建 tflite 文件。不幸的是,我似乎无法让这个工具在 Windows 上正常工作,我看到许多论坛记录了其他人经历类似的挣扎。为了解决这个问题,我们将使用 Linux。

首先下载 VirtualBox 这里(这是我们的虚拟机)和正确的 Ubuntu 版本(对我来说是 64 位)从这里。

我在这里找到了一篇关于如何用 Ubuntu 安装 VirtualBox 的优秀文章。跟着它走。我遇到的一个问题是 VirtualBox 只允许我安装 32 位版本的 Ubuntu。为了解决这个问题,我需要访问我的 BIOS 并启用虚拟化技术。

一旦你启动并运行了 Ubuntu,右击桌面打开一个终端。

您将需要安装 python,这可以通过使用:

$ sudo apt-get install python3.6
$ sudo apt-get install python3-pip python3-dev

然后安装 Tensorflow。

$ pip3 install tensorflow==1.6.0

我发现 Tensorflow 1.5 无法转换我的模型的一些功能,但这个问题在 Tensorflow 1.6 中消失了。以后的任何事也应该是好的。

现在我们需要将我们的模型引入 Ubuntu。我个人就是用 Dropbox 做到的。在 Windows 中,我把这个模型添加到我的 dropbox 中,在 Ubuntu 中打开这个 dropbox,然后把它添加到我的桌面上。

现在我们准备好进行转换了。假设模型的输入是 299x299 RGB 图像,我们将编写以下命令。请注意这是如何影响我们放入- input_shape 参数中的内容的。此外,整个表彰应写成一行。

/home/ryan/.local/bin/toco --input_file=Desktop/model.pb            --output_file=Desktop/model.tflite                                  --input_format=TENSORFLOW_GRAPHDEF 
--output_format=TFLITE --input_shape=1,299,299,3                    --input_array=input_1 --output_array=output_node                    --inference_type=FLOAT

您的桌面上应该有一个. tflite 文件。只需将它发送回 Windows(我再次使用 Dropbox),瞧,你可以在你的 Android 程序中使用它。

希望这篇文章能有所帮助,如果你有更好的方法将 Keras 神经网络从 Windows 安装到你的 Android 手机上,请在评论中告诉我!

如何创建代号机器人第 1 部分:Word2vec

原文:https://towardsdatascience.com/how-to-create-a-codenames-bot-part-1-word2vec-62701de38e66?source=collection_archive---------1-----------------------

(https://psychedforgames.com/home/2017/7/9/codenames)

作为一名桌游爱好者和程序员,我想到设计一种算法来玩流行游戏 Codenames 会是一件有趣的事情,如果不是值得努力的话。在这一系列的博客文章中,我将分享我在产生基于单词联想的线索方面的各种尝试,这些线索是代号的组成部分。所以!让我们开始吧。

代号解释

玩家被分成两队,红队和蓝队。一块由 25 个随机选择的单词块组成的板,排列成 5×5 的网格,如下所示:

An example board (http://spiralingcadaver.blogspot.com/2017/09/everybody-knows-that-bird-is-word.html)

每支队伍都有一名玩家作为间谍头子,只有间谍头子知道哪些牌属于他们的队伍。每个间谍头子的任务是给她的小组提供线索,让他们猜自己的牌,同时避开其他小组的牌。

对于上面的棋盘,红色间谍首领可能会给出诸如“第二盘”的线索“Dish”是相关的单词,“2”是与之相关的卡片数,在本例中是“plate”和“washer”

“重量 3”可能是一个不好的线索,因为它可能指的是“压力”、“力”或“盘子”,也可能指的是布鲁卡的“秤”如果一个队意外猜中了对手的牌,他们的回合就结束了。

间谍头子们轮流提供线索,直到一个小组猜出了他们所有的单词。

其他一些重要的规则:

  • 以黑色突出显示的“剧院”是刺客,如果猜对了,意味着猜对了的队伍会立即输。所以间谍头子必须不惜一切代价让她的团队远离那张牌。
  • 线索必须是一个单词或专有名词,如名称。
  • 正如猜测的那样,它们被一张相关的牌覆盖——蓝色、红色、黑色(刺客)或白色(中性)。
  • 一条线索不能包含或成为黑板上可见的任何单词的形式。例如,“波浪”和“侍者”是无效的线索。一旦卡被猜中,就可以使用它们。

如果你有 45 分钟的时间来消磨,并且想更好地了解这个游戏,桌面制作了一集关于它的。

创建间谍软件机器人的任务本质上可以归结为自动化单词关联。给定单词 X,最相似的单词有哪些?那么,给定一组单词 X、Y 和 Z,与所有这些单词最相似的单词是什么?同时避免出现与我对手的单词 A、B 和 c 相似的单词,而不是棋盘上任何其他可见单词的一部分。当然也和刺客没有任何关系。

但是,首先,问题的本质是找到单词联想。有许多方法可以做到这一点,我们将在本系列的课程中探讨。其中第一个是 word2vec。

Word2vec:正如它听起来的那样

Word2vec 是表示一个单词的一种方式,比如“猫”作为数字(0,5,1,3,7,1,…)的向量。我不会详细说明这些向量是如何创建的,但是这篇文章很好地解释了它。

一旦创建,向量有一些有趣和有用的属性。对我们来说,最重要的是,相关的单词向量在向量空间中的位置往往很接近。例如,“猫”的向量可能与“小猫”、“宠物”和“狗”等词接近这正是我们要找的。通过寻找最近的向量,我们找到了最相关的单词。

方法学

(以下代码和附加信息都可以在一个 Jupyter 笔记本 中找到,很容易复制和运行。)

我使用了 python3、 gensim 和一个预先构建在谷歌新闻语料库上的 word2vec 模型。首先,我们加载模型,将它限制在 500,000 个最常见的单词中,以过滤掉一些无意义的单词。

import gensim
model = gensim.models.KeyedVectors.load_word2vec_format(
    'GoogleNews-vectors-negative300.bin', binary=True, limit=500000
)

这是我们将要使用的代码板示例。blue是一队的字,red是另一队,assassin是刺客的字。

board = {
    '**blue**': [
        'ambulance', 'hospital', 'spell', 'lock', 
        'charge', 'tail', 'link', 'cook', 'web'
    ],
    '**red**': [
        'cat', 'button', 'pipe', 'pants', 
        'mount', 'sleep', 'stick', 'file', 'worm'
    ],
    '**assassin**': 'doctor'
}

首先,给定一个单词,最相似的单词是什么?获得与“救护车”最相似的 10 个单词:

model.similar_by_word('ambulance', topn=10)

这产生了:

[('paramedics', 0.7590752243995667),
 ('ambulances', 0.7493595480918884),
 ('Ambulance', 0.7236292362213135),
 ('paramedic', 0.662133514881134),
 ('Ambulance_paramedics', 0.6315338611602783),
 ('Ambulances', 0.6211477518081665),
 ('LifeFlight_helicopter', 0.6147335171699524),
 ('hospital', 0.6099206209182739),
 ('Paramedics', 0.6081751585006714),
 ('Ambulance_Service', 0.6080097556114197)]

每一行都是单词,后面跟着这个单词和“救护车”有多相似其中一些单词很有用,例如“护理人员”,但许多只是“救护车”的其他形式

gensim 可以让我们一次直接找到与一整组单词最相似的单词。

model.most_similar(
    positive=board['blue'],
    restrict_vocab=50000,
    topn=20
)

生产

[('For_Restrictions', 0.43488097190856934),
 ('bed', 0.39588358998298645),
 ('links', 0.38411831855773926),
 ('hook', 0.38367366790771484),
 ('paramedics', 0.38072746992111206),
 ('emergency', 0.37950167059898376),
 ('jail', 0.3759669065475464),
 ('log', 0.37062549591064453),
 ('intensive_care', 0.3661930561065674),
 ('call', 0.36543411016464233),
 ('webpage', 0.3649423122406006),
 ('tow_truck', 0.3592333197593689),
 ('click', 0.35906946659088135),
 ('cooked', 0.3552851676940918),
 ('care', 0.3537469208240509),
 ('handcuff', 0.35027384757995605),
 ('then', 0.34921103715896606),
 ('stay', 0.3478427529335022),
 ('turn', 0.34607696533203125),
 ('bookmark', 0.3458564579486847)]

这看起来好多了,并产生了一些像样的线索。

  • “床”、“护理人员”、“紧急情况”都与“救护车”和“医院”有关
  • “监狱”可能与“锁”和“指控”有关
  • 点击“网页”和“链接”

但是“床”也与另一组的单词“睡眠”有关;用“按钮”来“点击”给出可能指向对手底牌的线索是不好的。

gensim 也允许包含负面例子,以帮助避免这种情况。

model.most_similar(
    positive=board['blue'],
    negative=board['red'],
    restrict_vocab=50000
)

生产

[('Hospital', 0.27265793085098267),
 ('ambulances', 0.2605472207069397),
 ('hospitals', 0.24624229967594147),
 ('outpatient', 0.24339225888252258),
 ('inpatient', 0.2404019981622696),
 ('paramedics', 0.23482689261436462),
 ('escort', 0.23161748051643372),
 ('Partnerships', 0.23104971647262573),
 ('Medical_Center', 0.2306305170059204),
 ('telemedicine', 0.22638411819934845)]

我很喜欢“远程医疗”这个线索这并不明显,但与四个词有关:“网络”、“链接”、“救护车”和“医院”这显示了这种方法产生新颖线索的潜力。

假设线索是“远程医疗”,这四个字从黑板上去掉了,那么下一个小组就有机会了。他们的线索可能是什么?

board = {
    '**blue**': ['spell', 'lock', 'charge', 'tail', 'link'],
    '**red**': [
        'cat', 'button', 'pipe', 'pants', 
        'mount', 'sleep', 'stick', 'file', 'worm'
    ],
    '**assassin**': 'doctor'
}model.most_similar(
    positive=board['red'],
    negative=board['blue'],
    restrict_vocab=50000
)

这将返回:

[('pillow', 0.43686941266059875),
 ('bra', 0.3842337727546692),
 ('couch', 0.38342970609664917),
 ('tub', 0.37922778725624084),
 ('closet', 0.36959999799728394),
 ('sofa', 0.36713898181915283),
 ('bathroom', 0.366258829832077),
 ('bed', 0.36348700523376465),
 ('crotch', 0.36245280504226685),
 ('spoon', 0.36179912090301514)]

这似乎不太成功。最热门的词似乎大多只与一个词相关,即使如此,它们也是延伸的:

  • “枕头”与“睡眠”有关
  • “胸罩”可能是“裤子”,因为它们都是衣服?
  • “沙发?”也许是为了“睡觉”或“猫?”

关键要点

这里肯定有潜力。鉴于这一切都是在短短几行代码中完成的,它的表现相当不错。但是目前这种方法存在许多问题:

  • 作为代号间谍大师的目标是让你的团队第一个猜出所有的线索。速度很重要。这意味着,只要有可能,好的线索必须尽可能与你的词汇相关。我们在第一组线索(护理人员、远程医疗)中看到了这一点,但在第二组线索(枕头、胸罩)中看不到。这是因为一个单词与单个单词的关系可能比任何一个单词与一组词的关系都要密切。但是,在代号中,最好是选择一个与你的单词足够相关的单词,这样可以清楚地表明你指的是哪个单词,而不是选择一个与 T4 最相似的单词。在这种幼稚的尝试中,没有偏好最大化字数。
  • 规则需要强制执行——“救护车”不能作为“救护车”的线索,多词短语必须删除(除非是专有名词)。
  • 不清楚有多少单词与给定的单词“相关”。线索必须由一个单词和一个数字组成,如“远程医疗 4”最终的算法也必须有一种方法来指示这个数字。

下一次我们将开始尝试通过建立一个允许单词的主词典来解决无效线索的问题。

感谢 Jonathan Grundy、Robert Hundley、David Leonard 和 Abigail Pope-Brooks 的编辑和反馈。

所有用到的代码和数据都可以在github上找到。杰里米·内曼在他的网站上做着同样毫无意义的事情:http://jeremyneiman.com/

如何使用 CustomVision.ai 创建自定义图像分类器

原文:https://towardsdatascience.com/how-to-create-a-custom-image-classifier-with-customvision-ai-fe3df6fd219b?source=collection_archive---------5-----------------------

去年,当我在为微软菲律宾学生合作伙伴(MSPs)准备关于机器人+认知服务的演讲时,我发现了一个有趣的认知服务,名为 Custom Vision ,我发现它真的很容易使用,因为就像任何其他认知服务一样,Custom Vision 是一个黑盒工具,你可以使用它轻松开始你的人工智能开发,即使你对机器学习知之甚少。

自定义视觉服务是一个用于构建自定义图像分类器的工具。它使得构建、部署和改进图像分类器变得简单而快速。

在本教程中,我们将创建一个图像分类器,它可以从发送到服务的图片中识别某种食物。如果你不想这样,请随意创建一个不同的图像分类器,因为步骤几乎是相同的。

入门指南

这很容易开始,所有你需要使用自定义视觉服务是一个微软帐户。如果你还没有的话,可以去这个链接。完成后,请执行以下操作:

  1. 打开你的浏览器,进入https://www.customvision.ai/
  2. 登录您的 Microsoft 帐户
  3. 点击“新建项目”
  4. 输入项目名称。描述为可选
  5. 从域类别中点击“食物”选项
  6. 点击“创建项目”

如果你想知道这些“域”是做什么用的,它基本上是用来优化一个分类器的,你将在你的图像中使用一个特定类型的对象。以下是一些域的定义:

Screenshot taken from https://docs.microsoft.com/en-us/azure/cognitive-services/custom-vision-service/glossary-of-terms

一旦您创建了项目,您应该能够看到这个页面:

收集数据

下一步我们需要的是,收集与我们将要创建的分类器相关的图像,在我的例子中是与食物相关的图像。现在,你可以去谷歌搜索你需要的特定图片,然后一张一张地下载。

但如果你像我一样,觉得这样做有点麻烦,尤其是如果你打算下载大量的图像,你可以从谷歌 Chrome 下载一个名为fat Kun Batch Download Image的扩展,从名称本身来看,它可以让你从特定页面批量下载图像。多方便啊。

Fatkun Batch Download Image extension from Chrome Web Store

至于在自定义视觉中训练我们的分类器的要求,我们需要至少 2 个标签,每个标签至少 5 个图像。所以我准备下载 10 张图片(图片越多越好!)的图片,然后我们将使用这些图片来训练我们的分类器。

重要提示:定制视觉服务接受训练图像。jpg,。png,还有。bmp 格式,每张图片最多 6 MB。

上传并标记您的图像

第一步:

点按“添加图像”以添加您之前下载的图像

第二步:

为您的图像指定标签(您可以添加多个标签)

第三步:

上传您的图像

成功上传并标记图像后,您应该能够看到图像和标记现在已添加到您的自定义 Vision 项目中。

Images and Tag(s) are now added to your project

现在,添加您为第二个标签下载的另一组图像,然后再次执行步骤 1。

训练你的分类器

上传并标记完图片后,点击“培训”按钮继续培训。

完成培训后,您应该能够看到如下所示的图表:

你可能想知道这个“精确”和“回忆”图表是什么意思,对吗?他们在这里:

  1. 精度:您的分类器能够正确分类您用来训练它的训练图像的百分比。
  2. 回想一下:根据在训练期间分类的图像,您的分类器模型能够正确识别的百分比是多少?

测试您的模型

一旦你完成了训练,下一步就是测试你的模型是否能够正确识别某个图像。要做到这一点,点击“快速测试”,你要么输入一个图像的网址或只是上传一个图像从您的本地机器。

重要提示:测试你的模型时,确保而不是使用你用来训练你的分类器的图像。这是为了防止有偏见的结果,并让您看到您的模型在完全看不见的“真实世界”数据上的表现。

下面是您完成模型测试后的样子:

正如你在这里看到的,它能够正确地识别出我上传的图片确实是一个比萨饼。那么你怎么看待定制视觉认知服务?你觉得它有用并且容易使用吗?请在评论中告诉我。

我将写这篇博客的第 2 部分,向你展示如何使用和消费我们刚刚为你的应用程序创建的分类器模型,特别是在聊天机器人中。

如何在 Azure 中创建用于 AI 开发的预配置虚拟机

原文:https://towardsdatascience.com/how-to-create-a-pre-configured-virtual-machine-for-ai-development-in-azure-484edd7e22a2?source=collection_archive---------2-----------------------

正如我在之前的博客中提到的,过去几个月我一直在练习机器学习和深度学习。我开始实验时需要的一些东西是:

  1. 一台拥有相当计算能力的机器来训练机器学习,特别是深度学习建模的速度要快得多。
  2. 一台拥有所有工具(即 Python、TensorFlow、OpenCV 等)的机器..)我需要开始我的小人工智能实验。

这就是 Azure 数据科学虚拟机或 Azure DSVM 的用武之地。

Image Source: https://blogs.msdn.microsoft.com/uk_faculty_connection/2017/09/29/microsoft-deep-learning-virtual-machine/

数据科学虚拟机 (DSVM)是微软 Azure cloud 上专门为数据科学构建的定制虚拟机映像。它预安装和预配置了许多流行的数据科学和其他工具,可以快速构建用于高级分析的智能应用程序。

Azure DSVM 还提供了 3 个版本:

  1. Windows Server 2016 DSVM
  2. Linux Ubuntu DSVM
  3. 深度学习虚拟机

在这篇博文中,我们将创建一个基于 Linux Ubuntu 的数据科学虚拟机。

先决条件

开始使用的唯一先决条件是拥有有效的 Azure 订阅。如果你还没有 Azure 订阅,你可以点击这里获得免费试用。

创建基于 Linux Ubuntu 的 DSVM

  1. 在你的 Azure 门户中,点击“+新建”
  2. 搜索“Ubuntu 数据科学虚拟机”

3.选择“适用于 Linux (Ubuntu)的 Data Science 虚拟机”

4.点击“创建”

5.填写“基本信息”表格,然后点击“确定”

6.选择您想要的虚拟机大小

7.对于第 3 步“设置”,您可以点击“确定”继续默认设置

8.在第 4 步“总结”中,单击“创建”创建虚拟机

一旦成功创建了 DSVM,您应该能够看到资源组中的资源。

现在,您可以通过 SSH 连接到您的 DSVM,并开始您的 AI 开发。

预装工具列表

包含的预装工具将取决于您用来创建 Azure DSVM 的版本或操作系统。在我们的例子中,因为我们使用了基于 Linux Ubuntu 的 DSVM 版本,所以这里列出了可用的预安装工具:

  1. 咖啡
  2. 咖啡 2
  3. 微软 CNTK
  4. H2O
  5. 克拉斯
  6. MXNet
  7. NVIDIA 数字
  8. 张量流
  9. Theano
  10. 火炬
  11. CUDA、cuDNN 和 NVIDIA 驱动程序
  12. 带有 Microsoft R Open 的 Microsoft R Server 开发人员版
  13. Anaconda Python 发行版(版本 2.7 和 3.5)
  14. 朱丽亚普罗
  15. 独立 Spark 实例和单节点 Hadoop (HDFS、Yarn)
  16. 朱庇特枢纽
  17. Azure 存储浏览器
  18. Azure CLI
  19. Java、Python、node.js、Ruby、PHP 版本的 Azure SDK
  20. 用于 Python 和 R 的 Azure 机器学习库
  21. 文本编辑器和 ide(即 Vim、RStudio、Emacs、PyCharm 和 IntelliJ)

仅此而已。那么你怎么看待 Azure 数据科学虚拟机呢?如果你想了解更多,可以查看他们的官方文件这里。

我还写了一些博客文章,可以帮助你开始使用 Azure DSVM 进行人工智能开发,尤其是使用 Linux 版本时,效率更高。你可以在这里查看:

  • 用远程 VSCode 在你的 Linux 虚拟机上编辑文件变得容易多了
  • 用 Python 和 Azure DSVM 创建 Azure 机器学习 Web 服务

如何在 Keras 中为 R 创建序列模型

原文:https://towardsdatascience.com/how-to-create-a-sequential-model-in-keras-for-r-1437aaf778e2?source=collection_archive---------14-----------------------

TL;dr:本教程将介绍 Keras 的深度学习分类任务。我们将特别关注数组的形状,这是最常见的陷阱之一。

我们将讨论的主题有:

  • 如何进行一键编码
  • 选择层中的输入和输出形状/尺寸
  • 如何训练模型
  • 如何评估模型(培训与测试)

你可以在 Github 上找到这个教程的完整代码👇

创建数据

输入数据将是来自均匀分布的 10000 行和 3 列。

创建数据

输入数据将是来自均匀分布的 10000 行和 3 列。

该模型将识别出这三个数字的总和高于阈值1.5,否则将为 0。

# Input: 10000 rows and 3 columns of uniform distribution
x_data=matrix(data=runif(30000), nrow=10000, ncol=3)# Output
y_data=ifelse(rowSums(x_data) > 1.5, 1, 0)head(x_data)##            [,1]      [,2]      [,3]
## [1,] 0.49224109 0.6096538 0.7855929
## [2,] 0.56710301 0.8707570 0.3428543
## [3,] 0.08246592 0.7504529 0.6979251
## [4,] 0.79197829 0.6330420 0.7307403
## [5,] 0.65170373 0.9052915 0.1395298
## [6,] 0.23479406 0.2611791 0.2780037head(y_data)## [1] 1 1 1 1 1 0

安装/加载 Keras

# install.packages("keras")
library(keras)
library(tidyverse)

Keras 中的一键编码

深度学习的一个关键点是理解模型需要的向量、矩阵和/或数组的维数。我发现这些都是 Keras 支持的类型。

用 Python 的话说,就是数组的形状。

为了完成二进制分类任务,我们将创建一个单热点向量。对于 2 个以上的类,它以相同的方式工作。

例如:

  • 1将是矢量[0,1]
  • 0将是矢量[1,0]

Keras 提供了to_categorical函数来实现这个目标。

y_data_oneh=to_categorical(y_data, num_classes = 2)head(y_data_oneh)##      [,1] [,2]
## [1,]    0    1
## [2,]    0    1
## [3,]    0    1
## [4,]    0    1
## [5,]    0    1
## [6,]    1    0

很容易得到分类变量,如:“是/否”、“CatA、CatB、CatC”等。但是to_categorical不接受非数值作为输入。我们需要首先转换它们。

num_classes是创建矢量长度所必需的。

to_categorical的替代品:

  • CatEncoders, OneHotEncoder (同 Python scikit-learn)。
  • 封装caret,功能 dummyVars 。

注意:我们不需要转换输入变量,因为它们是数值。

在 Keras 中创建顺序模型

Keras 中最简单的模型是序列,它是通过顺序堆叠层而构建的。

在下一个示例中,我们堆叠了三个密集图层,keras 使用 input_shape 参数用您的数据构建了一个隐式输入图层。因此,我们总共有一个输入层和一个输出层。

model = keras_model_sequential() %>%   
  layer_dense(units = 64, activation = "relu", input_shape = ncol(x_data)) %>%
  layer_dense(units = 64, activation = "relu") %>%
  layer_dense(units = ncol(y_data_oneh), activation = "softmax")

目前最重要的参数是:

  • 在第一层中,input_shape代表一个值为 3 ( ncol(x_data))的向量,表示输入变量的数量。在深度学习中,几乎所有东西都是向量(或张量)。
  • 第二层没有input_shape,因为 Keras 是从前一层推断出来的。
  • 第三个layer_dense,代表最终输出,有 2 个(ncol(y_data_oneh))单位代表两种可能的结果。

您可以检查每个图层的模型和形状:

model## Model
## ___________________________________________________________________________
## Layer (type)                     Output Shape                  Param #     
## ===========================================================================
## dense_28 (Dense)                 (None, 64)                    256         
## ___________________________________________________________________________
## dense_29 (Dense)                 (None, 64)                    4160        
## ___________________________________________________________________________
## dense_30 (Dense)                 (None, 2)                     130         
## ===========================================================================
## Total params: 4,546
## Trainable params: 4,546
## Non-trainable params: 0
## ___________________________________________________________________________

现在是时候定义损失和优化器函数,以及要优化的指标了。

虽然它说的是“准确性”,但 keras 识别输出的性质(分类),并在后端使用categorical_accuracy

compile(model, loss = "categorical_crossentropy", optimizer = optimizer_rmsprop(), metrics = "accuracy")

让我们来拟合(训练)模型:

history = fit(model,  x_data, y_data_oneh, epochs = 20, batch_size = 128, validation_split = 0.2)

搞定了。

绘图结果:

plot(history)

Keras results in ggplot2

用看不见的数据验证

创建“看不见的”输入测试数据(1000 行,3 列):

x_data_test=matrix(data=runif(3000), nrow=1000, ncol=3)
dim(x_data_test)## [1] 1000    3

预测新病例:

y_data_pred=predict_classes(model, x_data_test)glimpse(y_data_pred)##  num [1:1000(1d)] 0 0 1 1 1 1 0 1 0 1 ...

请注意,维度是 1000 行和 2 列。predict_classes自动执行一键解码。

相反,predict返回训练时收到的相同维度(n 行,n 类预测)。

y_data_pred_oneh=predict(model, x_data_test)dim(y_data_pred_oneh)## [1] 1000    2head(y_data_pred_oneh)##                     [,1]              [,2]
## [1,] 0.99207872152328491 0.007921278476715
## [2,] 1.00000000000000000 0.000000001157425
## [3,] 0.00000002739444227 1.000000000000000
## [4,] 0.41273152828216553 0.587268412113190
## [5,] 0.03470309823751450 0.965296924114227
## [6,] 0.00000000007147296 1.000000000000000

在分类中,总是建议返回每个类别的概率,就像我们对predict所做的那样(行和为 1)。更多信息请访问: DSLB -得分数据。

softmax 激活

多亏了最后一层的activation = "softmax",我们得到了概率。

对于每个类,softmax 的输出范围从 0 到 1,所有类的总和自然是 1。

评估模型(培训与测试)

创建“真实”y 目标,与预测目标进行比较:

y_data_real=ifelse(rowSums(x_data_test) > 1.5, 1, 0)
y_data_real_oneh=to_categorical(y_data_real)## Training data
evaluate(model, x_data, y_data_oneh, verbose = 0)## $loss
## [1] 0.03008356
## 
## $acc
## [1] 0.9918## Test data (we need the one-hot version)
evaluate(model, x_data_test, y_data_real_oneh, verbose = 0)## $loss
## [1] 0.03146484
## 
## $acc
## [1] 0.991

看不见的数据的精度几乎是完美的:大约在1(以及接近 0 的损失,这比精度更重要)。

神经网络学习了我们一开始定义的模式🎉!

一些问题🤔

需要多少层?我们尝试了 3,但是 4 怎么样?它将学习同样的东西,但是需要更多的时间。但是在其他情况下,性能会提高。这取决于每个案例。

每层需要多少个神经元?和以前一样的推理。我们应该期望用最简单的网络获得最大的精度。倾向于进行良好的标准拟合的一种方法是从具有(即)128 个神经元的层开始。然后加一层 64,另一层 16。模式是减少每层神经元的数量。

你自己试试🙌

阅读只是学习的一个很小的部分,你可以自己尝试,比如改变我们使用的函数(我们尝试了y > 1.5 = 1)并让网络来学习它。

通过编码学习,并暴露你的实践中的错误🙂

进一步阅读

  • 系列车型指南(来自 Rstudio)
  • R 中深度学习入门(来自 Rstudio)
  • 样本大小和类别对模型性能的平衡(底层模型是用 Keras 构建的)

本帖最初发布于:https://blog . datascienceheroes . com/how-to-create-a-sequential-model-in-keras-for-r/

有什么问题吗?把它们留在下面📩

感谢阅读!🚀

📗数据科学 Live Book —学习机器学习的在线书籍

更多数据故事:博客|Linkedin|Twitter

如何创建和部署 Kubeflow 机器学习管道(第 1 部分)

原文:https://towardsdatascience.com/how-to-create-and-deploy-a-kubeflow-machine-learning-pipeline-part-1-efea7a4b650f?source=collection_archive---------3-----------------------

谷歌云最近宣布了一个开源项目,以简化机器学习管道的操作。在本文中,我将带您了解使用 Kubeflow Pipelines (本文中的 KFP)获取现有真实世界 TensorFlow 模型并操作化该模型的培训、评估、部署和再培训的过程。

本文的完整代码在 GitHub 上。

1.创建一个安装了管道的 Kubernetes 集群(一次)

:我写这篇文章的时候,托管管道还没有出现。创建安装了管道的 Kubernetes 集群的一个更简单的方法是遵循这个 自述文件 中的步骤。如果你这样做了,继续从第二步开始读。

KFP 自然需要 Kubernetes 集群来运行。使用此命令启动一个 Google Kubernetes 引擎(GKE)集群,并允许 KFP 管理该集群(repo 中的 create_cluster.sh ):

#!/bin/bash

CLUSTERNAME=mykfp
ZONE=us-central1-bgcloud config set compute/zone $ZONE
gcloud beta container clusters create $CLUSTERNAME \
  --cluster-version 1.11.2-gke.18 --enable-autoupgrade \
  --zone $ZONE \
  --scopes cloud-platform \
  --enable-cloud-logging \
  --enable-cloud-monitoring \
  --machine-type n1-standard-2 \
  --num-nodes 4kubectl create clusterrolebinding ml-pipeline-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)

创建一个 GKE 集群大约需要 3 分钟,因此导航到 GCP 控制台的 GKE 部分,并确保集群已经启动并准备就绪。

一旦集群启动,在 GKE 集群上安装 ML 管道(repo 中的2 _ deploy _ kube flow _ pipelines . sh):

#!/bin/bash
PIPELINE_VERSION=0.1.3
kubectl create -f [https://storage.googleapis.com/ml-pipeline/release/$PIPELINE_VERSION/bootstrapper.yaml](https://storage.googleapis.com/ml-pipeline/release/$PIPELINE_VERSION/bootstrapper.yaml)

在发布页面将上述版本更改为最新版本。部署此包将需要几分钟时间。您可以查看作业的状态,并等待成功运行的次数变为 1。或者,您可以告诉 kubectl 等待创建完成:

#!/bin/bashjobname=$(kubectl get job | tail -1 | awk '{print $1}')
kubectl wait --for=condition=complete --timeout=5m $jobname

在等待软件安装完成时,您可以继续阅读!

Buzzwords all the way down!

2.管道的描述

有几种方法可以创建管道。“dev-ops”的方式是使用 Python3 和 Docker。一种对数据科学家更友好的方式是使用 Jupyter 笔记本。在后面的帖子中,我将向您展示 Jupyter notebook 方法,但在这篇帖子中,我将向您展示 Python3-Docker 机制。理解这一点是有帮助的,这样当你走 Jupyter 路线时,你就知道幕后发生了什么。

我将通过机器学习模型来预测婴儿的体重。该模型有以下步骤:(a)从 BigQuery 中提取数据,对其进行转换,并将转换后的数据写入云存储。(b)训练张量流估计器 API 模型,并对模型进行超参数调整(c)一旦获得最佳学习速率、批量大小等。确定后,使用这些参数对模型进行更长时间的训练,并对更多数据进行训练(d)将训练好的模型部署到云 ML 引擎。

下面是描述上述管道的 Python 代码(repo 中的 mlp_babyweight.py ):

preprocess = dsl.ContainerOp(
  name=**'preprocess'**,image=**'gcr.io/cloud-training-demos/babyweight-pipeline-bqtocsv:latest'**,
  arguments=[
    **'--project'**, project,
    **'--mode'**, **'cloud'**,
    **'--bucket'**, bucket
  ],
  file_outputs={**'bucket'**: **'/output.txt'**}
)hparam_train = dsl.ContainerOp(
  name=**'hypertrain'**,image=**'gcr.io/cloud-training-demos/babyweight-pipeline-hypertrain:latest'**,
  arguments=[
    preprocess.outputs[**'bucket'**]
  ],
  file_outputs={**'jobname'**: **'/output.txt'**}
)train_tuned = dsl.ContainerOp(
  name=**'traintuned'**,image=**'gcr.io/cloud-training-demos/babyweight-pipeline-traintuned-trainer:latest'**,arguments=[
    hparam_train.outputs[**'jobname'**],
    bucket
  ],
  file_outputs={**'train'**: **'/output.txt'**}
)
train_tuned.set_memory_request(**'2G'**)
train_tuned.set_cpu_request(**'1'**)deploy_cmle = dsl.ContainerOp(
  name=**'deploycmle'**,image=**'gcr.io/cloud-training-demos/babyweight-pipeline-deploycmle:latest'**,
  arguments=[
    train_tuned.outputs[**'train'**],  *# modeldir* **'babyweight'**,
    **'mlp'** ],
  file_outputs={
    **'model'**: **'/model.txt'**,
    **'version'**: **'/version.txt'** }
)

上面的每个步骤都是一个 Docker 容器。Docker 容器的输出是另一个后续步骤的输入——它是一个有向无环图,当加载到 pipelines UI 中时,将如下所示:

ML Pipeline

(完整的端到端应用程序还包括第五步,部署 web 应用程序,为模型提供用户界面。)

看一下预处理步骤:

preprocess = dsl.ContainerOp(
  name=**'preprocess'**,image=**'gcr.io/cloud-training-demos/babyweight-pipeline-bqtocsv:latest'**,
  arguments=[
    **'--project'**, project,
    **'--mode'**, **'cloud'**,
    **'--bucket'**, bucket
  ],
  file_outputs={**'bucket'**: **'/output.txt'**}
)

注意,它使用两个输入参数——项目和存储桶——并将其输出(包含预处理数据的存储桶)放在/output.txt 中。

因此,第二步使用 preprocess.outputs['bucket']获取该存储桶名称,并将其输出(性能最高的超参数调优试验的作业名称)作为 hparam _ train . outputs[' job name ']供管道的第三步使用。

相当简单!

当然,这回避了两个问题:第一步如何获得它需要的项目和桶?第二,各个步骤是如何实现的?

项目和桶是通过管道参数得到的:

def train_and_deploy(
    project='cloud-training-demos',
    bucket='cloud-training-demos-ml'
):

本质上,项目和存储桶将由最终用户在管道运行时提供。UI 将预先填充我在上面提供的默认值:

Pipeline parameters are provided by the end-user

本节的其余部分是关于如何实现各个步骤的。再次,正如我提到的,我将解释 Python3-Docker 的实现方式。在以后的文章中,我会解释 Jupyter 的方法。所以,如果你确信你永远不会走码头工人这条路,只需略读这一部分或者直接跳到第三部分。

2a。预处理

在每一步中,您都需要创建一个 Docker 容器。这本质上是一个独立的程序(bash、Python、C++,无论什么),它的所有依赖项都被很好地指定,这样它就可以在集群上由 KFP 运行。

在我的例子中,我的预处理代码是一个独立的 Python 程序,它使用 Apache Beam 并期望在云数据流上运行。所有代码都在一个名为 transform.py 的命令行程序中:

The preprocessing code is all in a single file called transform.py

我的 Dockerfile 文件必须指定所有的依赖项。幸运的是,KFP 有一堆样本容器,其中一个有我需要的所有依赖项。所以,我只是继承了它。因此,我的 Dockerfile 是全部 4 行:

FROM gcr.io/ml-pipeline/ml-pipeline-dataflow-tft:latest
RUN mkdir /babyweight
COPY transform.py /babyweight
ENTRYPOINT ["python", "/babyweight/transform.py"]

本质上,我将 transform.py 复制到 Docker 容器中,并说入口点是执行该文件。

然后,我可以构建我的 Docker 容器,并在我的项目中的 gcr.io 中将其发布在 build.sh 中:

CONTAINER_NAME=babyweight-pipeline-bqtocsvdocker build -t ${CONTAINER_NAME} .
docker tag ${CONTAINER_NAME} gcr.io/${PROJECT_ID}/${CONTAINER_NAME}:${TAG_NAME}
docker push gcr.io/${PROJECT_ID}/${CONTAINER_NAME}:${TAG_NAME}

当然,这是我为预处理步骤指定的 image_name。

2b。CMLE 上的训练和超参数调整

我将使用 bash 在云 ML 引擎上进行训练和超参数调优,以使用 gcloud 提交作业:

gcloud ml-engine jobs submit training $JOBNAME \
  --region=$REGION \
  --module-name=trainer.task \
  --package-path=${CODEDIR}/babyweight/trainer \
  --job-dir=$OUTDIR \
  --staging-bucket=gs://$BUCKET \
  --scale-tier=STANDARD_1 \
  --config=hyperparam.yaml \
  --runtime-version=$TFVERSION \
 **--stream-logs** \
  -- \
  --bucket=${BUCKET} \
  --output_dir=${OUTDIR} \
  --eval_steps=10 \
  --train_examples=20000# write output file for next step in pipeline
echo $JOBNAME > /output.txt

请注意,我使用了 gcloud 命令等待完成的-stream-logs,并注意我写出了 jobname,它是管道代码中以下步骤的契约的一部分。

这一次,我将通过从一个已经安装了 gcloud 的容器继承来创建我的 Dockerfile ,并且 git 克隆包含实际教练代码的存储库:

FROM google/cloud-sdk:latestRUN mkdir -p /babyweight/src && \
    cd /babyweight/src && \
    git clone [https://github.com/GoogleCloudPlatform/training-data-analyst](https://github.com/GoogleCloudPlatform/training-data-analyst)COPY train.sh hyperparam.yaml ./ENTRYPOINT ["bash", "./train.sh"]

2c。在 Kubernetes 上进行本地培训

上面的预处理和超参数调优步骤利用了托管服务。KFP 所做的只是提交作业,并允许托管服务完成它们的工作。在 KFP 运行的 Kubernetes 集群上做点什么怎么样?

为了稍微混淆一下,让我在 GKE 集群上本地执行下一步(培训)。为此,我可以简单地运行一个直接调用 python 的 Docker 容器:

NEMBEDS=$(gcloud ml-engine jobs describe $HYPERJOB --format 'value(trainingOutput.trials.hyperparameters.nembeds.slice(0))')
TRIALID=$(gcloud ml-engine jobs describe $HYPERJOB --format 'value(trainingOutput.trials.trialId.slice(0))')...OUTDIR=gs://${BUCKET}/babyweight/hyperparam/$TRIALID
python3 -m trainer.task \
  --job-dir=$OUTDIR \
  --bucket=${BUCKET} \
  --output_dir=${OUTDIR} \
  --eval_steps=10 \
  --nnsize=$NNSIZE \
  --batch_size=$BATCHSIZE \
  --nembeds=$NEMBEDS \
  --train_examples=200000

在集群本身上执行作业有一个问题。您如何知道集群没有在执行耗尽所有可用内存的任务呢?traintuned 容器操作“保留”了必要数量的内存和 CPU。只有当必要的资源可用时,kubeflow 才会安排作业:

train_tuned.set_memory_request('2G')
train_tuned.set_cpu_request('1')

2d。部署到云 ML 引擎

部署到云 ML 引擎也使用 gcloud,所以那个目录下的 deploy.sh 和 build.sh 应该看起来很熟悉:

gcloud ml-engine versions create ${MODEL_VERSION} \
       --model ${MODEL_NAME} --origin ${MODEL_LOCATION} \
       --runtime-version $TFVERSIONecho $MODEL_NAME > /model.txt
echo $MODEL_VERSION > /version.txt

FROM google/cloud-sdk:latestRUN mkdir -p /babyweight/src && \
    cd /babyweight/src && \
    git clone [https://github.com/GoogleCloudPlatform/training-data-analyst](https://github.com/GoogleCloudPlatform/training-data-analyst)COPY deploy.sh ./ENTRYPOINT ["bash", "./deploy.sh"]

正如我们在 Kubernetes 集群上培训一样,我们也可以在 Kubernetes 本身上部署(参见这个组件中的一个例子)。

2e。编译 DSL

现在,所有步骤的 Docker 容器都已构建完毕,我们可以将管道提交给 KFP 了,只是……KFP 要求我们将管道 Python3 文件编译成特定于领域的语言。我们使用 Python3 SDK 附带的一个名为 dsl-compile 的工具来完成这项工作。所以,先安装那个 SDK ( 3_install_sdk.sh ):

pip3 install python-dateutil [https://storage.googleapis.com/ml-pipeline/release/0.1.2/kfp.tar.gz](https://storage.googleapis.com/ml-pipeline/release/0.1.2/kfp.tar.gz) --upgrade

然后,使用以下代码编译 DSL:

python3 mlp_babyweight.py mlp_babyweight.tar.gz

或者,您可以通过以下方式将包含 dsl-compile 的目录添加到您的路径中

export PATH=”$PATH:`python -m site --user-base`/bin

然后调用编译器:

dsl-compile --py mlp_babyweight.py --output mlp_babyweight.tar.gz

在第 3 节中,您将把这个 tar 文件上传到 ML pipelines UI。

3.上传管道

用户界面服务器在端口 80 的 GKE 集群上运行。进行端口转发,以便您可以通过端口 8085 ( 4_start_ui.sh )从笔记本电脑访问它:

export NAMESPACE=kubeflow
kubectl port-forward -n ${NAMESPACE} $(kubectl get pods -n ${NAMESPACE} --selector=service=ambassador -o jsonpath='{.items[0].metadata.name}') 8085:80

现在,打开浏览器到http://localhost:8085/pipeline,切换到 Pipelines 选项卡。然后,上传在 2e 小节中创建的 tar.gz 文件作为管道。

这只是使图表可用。您可能会使用各种设置组合来运行它。所以,开始一个实验来保持所有这些运行。我将我的实验命名为“博客”,然后创建了一个 run。我将该运行命名为“try1 ”,并使用刚刚上传的管道进行设置:

管道现在开始运行。我可以看到正在执行的每个步骤以及每个步骤的日志:

4.实验、开发、再培训、评估…

完整的源代码包括一些我忽略的东西。显然,完整的代码看起来并不完整,而且第一次也没有成功。我没有每次都从头开始管道,而是设置了管道,这样我就可以从任何一步开始(我正在处理的那一步)。

但是,每一步都依赖于前一步的输出。如何做到这一点?这是我的解决方案:

 **if start_step <= 2:**
    hparam_train = dsl.ContainerOp(
      name='hypertrain',
      # image needs to be a compile-time string
      image='gcr.io/cloud-training-demos/babyweight-pipeline-hypertrain:latest',
      arguments=[
        preprocess.outputs['bucket']
      ],
      file_outputs={'jobname': '/output.txt'}
    )
  **else:
    hparam_train = ObjectDict({
      'outputs': {
        'jobname': 'babyweight_181008_210829'
      }
    })**

本质上,如果 start_step ≤ 2,就会创建容器 op。否则,我只需用上一步的“已知”输出创建一个字典。这样,我可以简单地将 start_step 设置为 4,跳过前面的步骤,从第 4 步开始。然而,后面的步骤将具有它们期望的来自任何先前步骤的输入。

我的实验包括几次运行:

比如 try1 成功运行 3 步后失败,我可以从第 4 步开始。我需要两次尝试才能完成第四步。然后,我添加了步骤 5(部署一个 AppEngine 应用程序到 web 服务的前端)。然后,我回去尝试了阶段 3 的不同变化。

4b。再训练

当然,你不会训练一个模型一次就让它永远消失(是吗?).一旦有了更多的数据,您将需要重新训练模型。在我们的婴儿体重模型中,一旦我们有了一年的数据,我们可以想象重新训练模型。我在管道中处理这种情况的方法是请求一个 startYear 作为输入参数:

def train_and_deploy(
    project=dsl.PipelineParam(name='project', value='cloud-training-demos'),
    bucket=dsl.PipelineParam(name='bucket', value='cloud-training-demos-ml'),
    startYear=dsl.PipelineParam(name='startYear', value='2000')
):

bqtocsv 步骤中的预处理代码仅提取起始年份或之后的行:

WHERE year >= start_year

并命名输出文件,这样它们就不会破坏前面的输出:

os.path.join(OUTPUT_DIR, 'train_{}.csv', start_year)

训练现在在更大的数据集上进行,因为模式匹配是针对 train*。就是这样!

当然,还有其他方法来处理再培训。我们可以采用以前的模型,只根据更新的数据进行训练。像这样的语义并不难合并——使用命名约定来帮助管道做正确的事情。

4c。评价?笔记本?

当然,通常情况下,您不会立即将一个经过训练的模型推向生产。相反,在转换所有流量之前,您将进行一些评估,也许是 A/B 测试。

此外,您倾向于不在 Docker 容器中开发。我在这里很幸运,因为我的 babyweight 模型几乎是一个 Python 包,并且非常方便归档。如果您在 Jupyter 笔记本上完成所有的模型开发,会怎么样?

如何进行评估,以及如何将笔记本转换为管道是另一篇博文的主题。注意这个空间。

5.动手吧!

本文的完整代码在 GitHub 上。克隆 repo 并按照自述文件中的步骤操作。

另外,请阅读 Amy Unruh 关于 Kubeflow 管道入门的博文。

如何用 Python 创建动画图形

原文:https://towardsdatascience.com/how-to-create-animated-graphs-in-python-bb619cc2dec1?source=collection_archive---------1-----------------------

Animation of Heroin Deaths in the USA. Created in Python using Seaborn.

Matplotlib 和 Seaborn 是 Python 中一些很好的库,可以创建很棒的图形。但是这些图都是静态的,很难用一种动态的、令人愉悦的方式来描绘数据值的变化。如果在你的下一个演示文稿、视频或社交媒体帖子中,你可以使用一个简短的视频剪辑来展示数据中的发展,那该有多好?更好的是,你仍然可以继续使用 Matplotlib、Seaborn 或任何其他你喜欢用于绘图的库!

我最近为一部关于美国阿片类药物危机的短纪录片制作了几个动态图,所以我将在这篇文章中使用其中的数据。这些数据由美国国家药物滥用研究所和疾病预防控制中心公开提供,可以在这里下载:https://www . Drug Abuse . gov/sites/default/files/dodoff _ data _ 1999-2015 . xls。

在这篇文章中,我将使用 Matplotlib 和 Seaborn 一起绘图,使用 Numpy 和 Pandas 一起处理数据。对于动画,matplotlib 提供了一些我们可以使用的函数。因此,让我们继续导入所有依赖项。

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.animation as animation

现在,为了准备动画数据,我们只需要加载它,并把它放入一个熊猫数据帧。当绘制关于不同阿片类药物过量的几个图时,还可以方便地编写一个函数,用于从您感兴趣的行加载数据。

overdoses = pd.read_excel('overdose_data_1999-2015.xls',sheetname='Online',skiprows =6)def get_data(table,rownum,title):
    data = pd.DataFrame(table.loc[rownum][2:]).astype(float)
    data.columns = {title}
    return data

现在让我们开始制作动画吧!

首先,如果你像我一样使用 jupyter 笔记本,最好用一个%matplotlib notebook开始这个单元,这样你就可以立即在你的笔记本上看到动画,而不只是在它被保存之后。

在我的例子中,我现在使用get_data函数从表中检索海洛因过量的数字,并将其打包到一个有两列的 Pandas 数据帧中。一个用于年份,另一个用于过量用药的计数。

%matplotlib notebook
title = 'Heroin Overdoses'
d = get_data(overdoses,18,title)
x = np.array(d.index)
y = np.array(d['Heroin Overdoses'])
overdose = pd.DataFrame(y,x)
#XN,YN = augment(x,y,10)
#augmented = pd.DataFrame(YN,XN)
overdose.columns = {title}

接下来,我们初始化一个 writer,它使用 ffmpeg 并以 20 fps 的比特率 1800 进行记录。你当然可以自己挑选这些值。

Writer = animation.writers['ffmpeg']
writer = Writer(fps=20, metadata=dict(artist='Me'), bitrate=1800)

现在让我们用一些标签创建一个图形。确保设置 x 轴和 y 轴的限制,以便动画不会在当前显示的数据范围内跳跃。

fig = plt.figure(figsize=(10,6))
plt.xlim(1999, 2016)
plt.ylim(np.min(overdose)[0], np.max(overdose)[0])
plt.xlabel('Year',fontsize=20)
plt.ylabel(title,fontsize=20)
plt.title('Heroin Overdoses per Year',fontsize=20)

动画的核心部分是动画函数,在该函数中,您可以定义视频的每一帧中发生的事情。这里的i代表动画中帧的索引。使用该索引,您可以选择在该框架中应该可见的数据范围。之后,我使用 seaborn lineplot 来绘制数据选择。最后两行只是为了让剧情看起来更赏心悦目一点。

def animate(i):
    data = overdose.iloc[:int(i+1)] #select data range
    p = sns.lineplot(x=data.index, y=data[title], data=data, color="r")
    p.tick_params(labelsize=17)
    plt.setp(p.lines,linewidth=7)

使用matplotlib.animation.FuncAnimation启动动画,其中链接动画功能并定义动画应包含多少帧。因此,frames定义了animate(i)被调用的频率。

ani = matplotlib.animation.FuncAnimation(fig, animate, frames=17, repeat=True)

要将这个动画保存为 mp4,你可以简单地调用ani.save()。如果你只是想在保存之前看一眼,那就打电话给plt.show()吧。

ani.save('HeroinOverdosesJumpy.mp4', writer=writer)

所以现在动画看起来是这样的:

Heroin Overdose Animation — Jumpy

它有点工作,但仍然很跳动。为了避免跳跃,我们需要更多的数据点在我们已经有的数据点之间。为此我们可以使用另一个函数,我在这里称之为augment

def augment(xold,yold,numsteps):
    xnew = []
    ynew = []
    for i in range(len(xold)-1):
        difX = xold[i+1]-xold[i]
        stepsX = difX/numsteps
        difY = yold[i+1]-yold[i]
        stepsY = difY/numsteps
        for s in range(numsteps):
            xnew = np.append(xnew,xold[i]+s*stepsX)
            ynew = np.append(ynew,yold[i]+s*stepsY)
    return xnew,ynew

现在我们只需要将这个函数应用于我们的数据,并在matplotlib.animation.FuncAnimation函数中增加帧数。这里我用numsteps=10调用 augment,这意味着我将我的训练数据增加到 160 个数据点,并且必须设置frames=160。结果看起来更加平滑,但是在数据值改变的地方仍然有一些尖锐的边缘。

Heroin Overdose Animation — Sharp Edges

为了消除这些问题,我们可以实现一个平滑函数,如下所述:https://www . SW harden . com/WP/2008-11-17-linear-data-smoothing-in-python/

def smoothListGaussian(listin,strippedXs=False,degree=5):  
    window=degree*2-1  
    weight=np.array([1.0]*window)  
    weightGauss=[]  
    for i in range(window):  
        i=i-degree+1  
        frac=i/float(window)  
        gauss=1/(np.exp((4*(frac))**2))  
        weightGauss.append(gauss)
    weight=np.array(weightGauss)*weight  
    smoothed=[0.0]*(len(listin)-window)  
    for i in range(len(smoothed)):        smoothed[i]=sum(np.array(listin[i:i+window])*weight)/sum(weight)  
    return smoothed

此外,我们可以添加一些颜色和风格参数,使情节看起来更有个性。

sns.set(rc={'axes.facecolor':'lightgrey', 'figure.facecolor':'lightgrey','figure.edgecolor':'black','axes.grid':False})

这就是我们如何获得上面显示的最终结果。

这篇文章仅仅展示了 matplotlib 动画函数的一个例子。当然,你可以用它来制作任何你想制作动画的情节。简单调整animate()函数中的参数和绘图类型,可能性是无限的。

我希望你会喜欢 matplotlib 的这个好功能,并能把它用在更好的地方!如果你想看看我为这部纪录片制作的所有图片并从中获得灵感,你可以在这里找到:https://youtu.be/7xrvuSDLHiY

如何使用 rapid miner 创建集合模型

原文:https://towardsdatascience.com/how-to-create-ensemble-models-using-rapid-miner-72a12160fa51?source=collection_archive---------6-----------------------

什么是合奏模型?

在训练阶段,我们可以使用特定的算法,从手头的数据中得到一个模型。但是,对于特定的数据集来说,这不会是最佳的模型,因为这只是一种算法,而且这种算法是一种弱算法。然后,您可能需要尝试不同的算法来获得优化的模型。相反,你可以尝试将几个可能的弱算法结合在一起,或者将同一算法的几个模型用于不同的数据集,并创建一个集成模型。Bagging 和 boosting 使用一种算法,并使用同一数据集的不同样本创建几个模型,而 Voting 对同一数据集使用几个弱算法来创建集成模型。

什么是 RapidMiner?

RapidMiner 是一款数据挖掘工具,可用于数据准备、建模、评估&部署。它提供了用它的操作符创建集合模型的灵活性。RapidMiner 使用 bagging,boosting &投票来创建集合模型。

如何使用 bagging 创建集合模型?

Bagging 是一个集成元算法,从一个算法创建 n 个学习器。数据集被随机采样并替换,以给定的比率创建 n 个数据集,并馈入 n 个分类器。由于完成了替换,相同数据元素可用于其他一些数据集中。一个数据元素出现在不同数据集中的概率对于所有元素都是相同的。对于分类,考虑来自 n 个分类器的多数投票的预测,对于回归,考虑 n 个分类器的预测的平均值。装袋基本上减少了方差和过度拟合。相关的 RapidMiner 流程如下所示。

The Bagging process

在“交叉验证”操作符中,我们在训练阶段使用“装袋”操作符,如下所示。

Inside Cross Validation sub process

在“装袋”中,“决策树”操作员用于培训,如下所示。您可以使用您想要的任何其他分类器。

Inside Bagging sub process

Confusion Matrix of Bagging algorithm

如何使用 boosting 创建集合模型?

Boosting 是一种集成元算法,它从一个算法中依次创建 n 个学习器。数据集被随机抽样替换,并以给定的比例创建 n 个数据集。可能存在被给定学习者错误分类的数据点。所以这是错误的。当训练下一个学习者时,考虑前一个分类器的错误,并且对错误分类的数据元素给予新的权重,使得该数据元素更频繁地出现在新的数据集中。升压用于降低偏置。相关的 RapidMiner 流程被创建为装袋流程。

在“交叉验证”操作符中,我们在训练阶段使用“AdaBoost”操作符,如下所示。还有一些其他的提升算法,比如 RapidMiner 中的贝叶斯提升,你可以试试。

Inside Cross Validation sub process

在“装袋”中,“决策树”操作员用于培训,如下所示。您可以使用我前面提到的任何其他分类器。

Inside AdaBoost sub process

Confusion Matrix of Boosting algorithm

我如何通过投票创建集合模型?

不像在投票中的装袋和助推,几种算法可以结合在一起创建集成模型,正如我在本文开始时提到的。对于分类,所有分类器的多数投票作为预测给出,对于回归,所有分类器的平均值作为预测给出,如在 bagging 算法中。RapidMiner 流程与装袋流程相同。

在“交叉验证”操作符中,我们在训练阶段使用“投票”操作符,如下所示。

The Cross Validation sub process

在“投票”节点中,我使用了 K-NN、决策树和朴素贝叶斯分类器。

Inside Vote operator

Confusion Matrix of Voting process

除了使用一种弱算法,你还可以尝试一种集成算法,它可以做更精确的预测。集成算法的快乐模型训练。

延伸阅读

[1]https://quant dare . com/bagging-and-boosting 之间的区别是什么/

[2]https://www . quora . com/What-is-bias-in-machine-learning-algorithms

如何用 Plotly 创建交互式地图绘图

原文:https://towardsdatascience.com/how-to-create-interactive-map-plots-with-plotly-7b57e889239a?source=collection_archive---------5-----------------------

“brown wooden map board” by Brett Zeck on Unsplash

毫无疑问,我最喜欢处理数据的一部分是创建可视化。图像是传达信息的最佳工具:它们是即时的,事实上大脑处理它们的速度比文字快几千倍。图像也是普遍的,它们会在我们的脑海中停留更久。最后,我们是懒惰的动物,因此我们更注重视觉效果,而不是文字。有多少次你遇见一个新的人,然后你努力记住他们的名字,而他们的脸却清晰地浮现在你的脑海里?

当我在学术界做研究员时,我意识到我是多么喜欢创造视觉效果:尽管我喜欢进行实验和数值模拟,但我真的很期待项目的那一刻,那时我将能够处理我所有的发现,并创建那些漂亮而强大的图表。是的,我还必须写论文来描述所有的过程,工作流程和研究背后的理论推理,但是能够用很少的图像来交流几个月的工作真是不可思议!所有这些介绍都是为了让你相信图像是重要的,如果你还不这么认为的话。尤其是对于一名数据科学家来说,他需要不时高效地向非技术受众传达信息。

在过去的一周左右的时间里,我一直在处理我的关于美国风暴事件的顶点项目,同时处理包含地理空间信息的约 11,000 个观测数据。我的第一个想法是将所有这些数据绘制在地图上,这样我就可以一眼看出哪些区域最容易受到此类事件的影响。由于我使用的是 Python,Geopandas 将是最直接的选择,但是,我想要更具交互性的库。如果我想改变地图的样式怎么办?或者,如果我只想看到雷暴或冰雹呢?我做了一点研究,发现 plotly 正是我所需要的。我找不到任何好的教程来指导我完成这个过程,所以我在网上看了一些例子,试图通过大量的试验和错误来推断性地理解这是如何工作的。这就是我决定写这篇文章的原因,同时我正在为同一个项目训练一批神经网络,当所有这些纪元来来回回时,我有空闲时间。

注意:要做我将要描述的事情,你需要一个与 plotly 以及 mapbox 的账户。特别是因为你需要一个访问令牌,可以在这里创建,还需要一个用户名和 API 密匙,可以在这里生成。这一切都是免费的。我还建议您非常精通 Python 字典,因为正如您将注意到的,它们是创建这样的地图图的基础。

我从国家气候数据中心收集了从 2000 年至今美国风暴事件的数据。像往常一样,我不得不做大量的清理工作,处理丢失的数据,设计一些功能。在这个链接你可以找到。csv 文件用于此目的,并为我的顶点项目一般。这些数据包含了这种现象的纬度和经度信息,这对于我们在地图上绘图是非常重要的。它还显示了是否是雷暴、冰雹、山洪爆发等总共七个不同的类别。风暴事件的强度、所处的状态以及发生的时间

在实际绘制之前,我们需要导入和分配一些东西。这里我们需要来自 Mapbox 的访问令牌,以及来自 Plotly 的用户名和 api 密钥。

import plotly.plotly as py
import plotly.graph_objs as go
import plotly
import pandas as pd# setting user, api key and access token
plotly.tools.set_credentials_file(username='your_username_here', api_key='your_api_key_here')
mapbox_access_token = 'your_access_token_here'

为了生成我们的图,我们将需要两样东西:数据布局。我们的变量数据将是七个字典的列表(每个事件类型一个),其中每个字典包含纬度和经度值,以及风暴类型的名称和绘图的标记特征。变量布局是一个字典,包含了与数据没有直接联系的图像相关的所有内容:下拉菜单、注释、我们想要如何格式化它们以及我们想要将它们放置在哪里。

数据

在读取数据帧并将其分配给一个df变量后,我创建了一个包含七种不同风暴类别名称的列表,并将其命名为event_types。我遍历了这个列表,并使用它来过滤数据帧,为每种事件类型创建一个字典,并将其附加到数据列表。这样我就有了我的字典清单,数据

creating the data variable.

我将标记的不透明度值指定为 0.5 的原因是,最有可能的是,有些区域的点数比其他区域多。赋予这些点某种透明度,将允许我们在地图上看到相同颜色的不同色调,对应于不同地区相同现象的不同频率。

我们已经完成了数据,现在轮到布局,这无疑需要更多的工作。

布局

我们来设置一下地图的基本设置。

Initializing the map layout.

现在我们可以开始在地图上添加一些东西来定制它,并按照我们喜欢的方式进行交互。

布局['批注']

假设我想放一个上面有白色文本的黑框,指定我的点仅代表从 2000 年至今造成超过 50k 美元经济损失的风暴事件。像这样的一些静态提示,将落在布局字典的注释键下:对应于注释的值将需要是一个字典列表,在这个特定的例子中,一个只包含一个字典的列表,因为我想在我的地图上只放置一个注释。文字上看似繁琐,但做起来绝对比解释容易。

Annotation on the map.

现在是下拉菜单的时候了,它需要被分配给布局字典的更新菜单键。

布局['updatemenus']

我想添加两个下拉菜单:一个选择要可视化的风暴事件的类型,以防我们只想查看类型而不是所有类型,而另一个下拉菜单将允许我们更改背景上的地图类型,默认情况下是暗的。可用地图的名称和样式可以在 Mapbox 上找到。

每一个下拉菜单都是通过一个字典重新定义的,所有这些字典都将包含在一个列表中,我们将分配给layout['updatemenus']

Adding drop-down menus to the map.

布局['标题']

如果需要,您可以轻松地为您的地块指定标题。我这样做只是通过做layout['title'] = 'Storm Events'

生成剧情!

一旦我们将数据布局整理好,我们就可以通过运行以下命令来生成图表:

figure = dict(data = data, layout = layout)
py.iplot(figure, filename = 'put_your_name_here')

瞧啊!

您可以放大、缩小,从顶部菜单中选择您想要可视化的内容,并从底部菜单中更改地图类型。相当酷!我期待着像这样的其他一些情节,现在我学会了如何去做。希望您发现这也很有用!

请随意查看:

这个代码的 Github 库

我的其他中帖。

我的 LinkedIn 个人资料。

感谢您的阅读!

如何使用聚类创建新功能!!

原文:https://towardsdatascience.com/how-to-create-new-features-using-clustering-4ae772387290?source=collection_archive---------1-----------------------

介绍

特征是一条可能对预测有用的信息。创造新特征的过程属于特征工程。特征工程..

聚类是一组定位或发生在一起的相似事物,聚类分析本身并不是一种特定的算法。一些例子是:

Formation of clusters by different algorithms

这可以通过各种算法来实现,这些算法在什么构成一个聚类以及如何有效地找到它们的概念上有很大不同。适当的聚类算法和参数设置取决于单个数据集和结果的预期用途。

现在让我们看看我如何在鸢尾数据集中使用 KMeans 聚类来为那些不了解鸢尾数据集的人创建新的功能,这是关于鸢尾花及其物种的数据。

简而言之,数据集由 3 种不同类型的鸢尾(Setosa、Versicolour 和 Virginica)花瓣和萼片长度组成,行是样本,列是:萼片长度、萼片宽度、花瓣长度和花瓣宽度。有关 iris 的更多信息,请使用 Iris_Link1Iris _ link 2

有许多聚类模型和双聚类模型,KMeans 是一种聚类模型,它遵循一种简单而容易的方法将数据集分类为聚类。主要思想是定义 k 个质心,每个聚类一个,并迭代直到找到实际质心。

  1. 将 K 个点放入被聚类的对象所代表的空间中。这些点代表初始组质心。
  2. 将每个对象分配到具有最近质心的组。
  3. 当所有对象都被指定后,重新计算 K 个质心的位置。
  4. 重复步骤 2 和 3,直到质心固定在最终中心。

型号

这里定义了一个类,通过使用 KMeans 聚类生成新的要素,并将其添加到数据集中以计算数据的性能。

结果

我们创建了实例来检查使用和不使用新的集群特性时的变化。

在这次迭代中,我们使用了 LogisticRegression,我们可以清楚地看到步骤 1 的性能比步骤 2 好,在步骤 2 中添加集群的新功能并没有起到什么作用。

步骤 3:如果我们只为我们的训练数据选择标签,这将进一步降低我们的模型性能。

在我们的第二次迭代中,我们使用支持向量机

  • 在这里,考虑到 Kmeans 特性,模型在原始数据集上的表现与我们的 Support_Vector_machine 相同。
  • 即使在这种情况下,如果我们尝试为我们的训练数据使用标签,也会进一步降低我们的模型性能。

结论

当标签用于训练时,它不会给我们的模型增加价值,相反,将它们作为一个特征添加可以在模型的性能方面帮助我们一点。

一定要尝试这种聚类技术,将新特性添加到您的模型中,看看它的表现如何。

如何用机器学习创造价值

原文:https://towardsdatascience.com/how-to-create-value-with-machine-learning-eb09585b332e?source=collection_archive---------7-----------------------

用 3 个步骤定义和解决有意义问题的通用框架

想象以下场景:你的老板要求你建立一个机器学习模型,以预测每个月你的订阅服务的哪些客户将在该月流失,流失定义为超过 31 天没有活跃会员。你通过寻找客户流失的历史例子来煞费苦心地制作标签,通过头脑风暴和手工设计特征,然后训练和手动调整机器学习模型来进行预测。

对抵制测试集的指标感到满意,你带着结果去见你的老板,却被告知现在你必须开发一个不同的解决方案:每两周进行一次预测,流失率定义为 14 天不活动。沮丧的是,你意识到你以前的工作都不能被重用,因为它是为一个单一的预测问题设计的。

您为客户流失的狭义定义编写了一个标签函数,并且管道中的下游步骤(特征工程和建模)也依赖于初始参数,因此必须重做。由于硬编码一组特定的值,你将不得不建立一个完全的新管道来解决问题定义中仅有的一个小的变化。

构建机器学习过程

这种情况表明了目前解决机器学习问题的方法。该过程是特定的,即使使用相同的数据,也需要针对每个参数设置的定制解决方案。结果是公司错过了机器学习的全部好处,因为它们局限于用时间密集型方法解决少量问题。

缺乏 标准化方法 意味着没有可以快速调整和部署为问题变化参数的解决机器学习问题的脚手架。

我们如何改进这一过程?让机器学习变得更容易实现需要一个通用的框架来设置和解决问题。这个框架应该适应现有的工具,快速适应变化的参数适用于不同的行业,并提供足够的结构给数据科学家一条清晰的道路,以规划和解决机器学习的有意义的问题。

在功能实验室,我们对这个问题进行了大量思考,并开发了我们认为解决机器学习有用问题的更好方法。在本系列的接下来三个部分中,我将展示我们如何围绕预测工程特征工程建模的步骤,以结构化、可重复的方式构建机器学习解决方案。

我们将把该方法完整地应用于一个用例——预测客户流失——并看看如果问题的参数发生变化,我们如何调整解决方案。此外,我们将能够利用现有的工具——Pandas、 Scikit-Learn 、feature tools——通常用于机器学习。

通用机器学习框架概述如下:

  1. 预测工程:陈述业务需求,转化为机器学习问题,并从数据集生成带标签的示例
  2. 特征工程:从每个标签的原始数据中提取预测变量——特征
  3. 建模:在特性上训练机器学习模型,针对业务需求进行调整,并在部署到新数据之前验证预测

A general-purpose framework for defining and solving meaningful problems with machine learning

我们将介绍每个步骤的基础知识,以及如何用代码实现它们。完整的项目可以在 GitHub 的 Jupyter 笔记本上获得。(完全披露:我在 Feature Labs 工作,这是一家开发工具的初创公司,包括 Featuretools ,用于解决机器学习的问题。这里记录的所有工作都是用开源工具和数据完成的。)

整套文章是:

  1. 概述:通用机器学习框架(本文)
  2. 预测工程:如何设置你的机器学习问题
  3. 特征工程:机器学习的动力是什么
  4. 建模:教授算法进行预测

虽然这个项目只讨论了一个应用,但同样的过程可以应用于各个行业,以构建有用的机器学习解决方案。最终的交付成果是一个框架,你可以用它来解决任何领域的机器学习问题,以及一个可以直接应用于你自己的客户流失数据集的特定解决方案。

商业动机:确保你解决了正确的问题

最复杂的机器学习管道不会有任何影响,除非它为公司创造价值。因此,构建机器学习任务的第一步是理解业务需求,以便您可以确定要解决的正确问题。在整个系列中,我们将解决解决客户流失的常见问题。

对于基于订阅的商业模式来说,预测哪些客户会流失——在一段特定的时间内停止支付服务费用——是至关重要的。准确预测客户是否会流失以及何时会流失,有助于企业与那些面临退订风险的客户进行接触,或者向他们提供优惠费率,以激励他们继续订购。一个有效的客户流失预测模型可以让一家公司主动发展客户群。

对于客户流失问题,业务需求是:

通过降低客户流失率来增加付费用户的数量。

减少客户流失的传统方法需要使用生存分析技术预测哪些客户会流失,但是,考虑到丰富的历史客户行为数据,这提供了监督机器学习的理想应用。

我们可以通过建立一个监督算法来解决机器学习的业务问题,该算法从过去的数据中学习,以预测客户流失。

陈述业务目标,并用机器学习可解决的任务来表达它,是管道中关键的第一步。一旦我们知道我们希望模型预测什么,我们就可以继续使用可用的数据来开发和解决有监督的机器学习问题。

后续步骤

在接下来的三篇文章中,我们将应用预测工程、特征工程和建模框架来解决来自亚洲最大的订阅音乐流媒体服务 KKBOX 的数据集上的客户流失问题。

寻找以下帖子(或查看 GitHub 库):

  1. 预测工程:如何设置你的机器学习问题
  2. 特征工程:机器学习的动力
  3. 建模:训练算法进行预测(即将推出)

我们将看到如何用现有的数据科学工具填充细节,以及如何在不重写完整管道的情况下改变预测问题。最终,我们将拥有一个预测客户流失的有效模型,该模型经过调整可以满足业务需求。

Precision-recall curve for model tuned to business need.

通过这些文章,我们将看到一种机器学习的方法,这种方法让我们能够快速构建多种预测问题的解决方案。下一次你的老板改变问题参数时,你只需修改几行代码就能有一个新的解决方案。

如果构建有意义的高性能预测模型是您关心的事情,那么请联系我们的功能实验室。虽然这个项目是用开源特性工具完成的,但是商业产品为创建机器学习解决方案提供了额外的工具和支持。

如何利用您的数据科学项目创造价值

原文:https://towardsdatascience.com/how-to-create-value-with-your-data-science-projects-62460db3bb4f?source=collection_archive---------1-----------------------

在我的数据科学之旅中,我遇到了许多关于数据科学的有趣文章和教程,它们旨在提供解决特定业务问题或技术挑战的视角或方法,我从中获得了巨大的价值。我想我应该对现有的文献有所贡献,写一些关于数据科学的过程以及我认为每个人都应该知道的关于最大化其用途的东西。

数据科学可用于了解客户、选择合适的客户、提高产品质量、提高团队效率、在团队成员之间建立协作文化,最重要的是,让员工能够做出更好的决策。要做到这一点,我们需要确保我们回答了正确的问题,但我们也有正确的信息。这些是解决问题时的常见挑战,我们作为数据科学家的职责是克服这些挑战,以便我们的客户能够做出正确的决策。

思考您的数据科学项目的最佳方式之一,是将其视为您为客户或客户制作的产品。为了说明我的想法,我将使用价值主张画布和客户资料,您可以在这里或这里了解更多关于的信息。我发现这是培养个人和团队同理心的有效方法,这样他们就能正确理解客户需求并开发出正确的解决方案。

The Business Value Proposition Canvas (left) and Customer Profile (right)

客户档案将我们的注意力集中在客户需要完成的目标(工作)上。它还让我们专注于与做这些工作相关的挑战(痛苦)和出色完成工作的回报(收获)。我个人喜欢理解“收益”,因为它有助于我们的主张与用户的动机保持一致。

价值主张画布是一张地图,记录了您的产品或服务如何满足我们客户的需求(产品&服务)以及他们选择采用它的原因(收益创造者、止痛者)。缓解疼痛者处理与完成客户感兴趣的工作相关的挑战,并获得创造者,使完成工作所获得的利益价值最大化。

挑战在于确保你所创造的东西能够完美地解决给定的问题。帮助用户完成他们的“工作”应该是你项目的目标。我将在随后的文章中举例说明这实际上是如何工作的。

结论

我当然希望这篇文章是有用的,并希望您在从事数据科学项目时可以考虑另一个有用的视角。一如既往,我感谢您的反馈,并欢迎对文章的建议和改进我迄今为止与您分享的内容的方法。

如果您想进一步了解前面提到的价值主张画布以及如何使用它,请观看下面的视频:

我当然希望这篇文章是有用的,我急切地等待你的反馈。期待我的下一篇文章。

如何创建嵌入 TensorFlow 的单词

原文:https://towardsdatascience.com/how-to-create-word-embedding-in-tensorflow-ed0a61507dd0?source=collection_archive---------8-----------------------

Photo by Vincentiu Solomon on Unsplash

三种不同的方式

你可以在这里 找到这篇文章的 Jupyter 笔记本

今天我们将看到如何使用张量流创建单词嵌入。

更新至 tf 1.9

单词嵌入是通过创建高维向量空间来表示单词的一种方式,在高维向量空间中,相似的单词彼此接近。

长话短说,神经网络和数字一起工作,所以你不能只是把单词扔进去。你可以一次性编码所有的单词,但是你会失去它们之间相似性的概念。

通常,几乎总是,你把你的嵌入层放在神经网络的前面。

预处理

通常,你有一些文本文件,你从文本中提取标记,你建立词汇。类似于下面的代码

然后

这是一个非常简单的例子,你通常需要更多的预处理来并行打开多个文本源,创建令牌和创建 vocab。例如,您可以使用 PySpark 有效地预处理文本。

让我们打印词汇

{'abutere': 0, 'ad': 1, 'audacia': 2, 'catilina': 3, 'effrenata': 4, 'eludet': 5, 'etiam': 6, 'finem': 7, 'furor': 8, 'iactabit': 9, 'iste': 10, 'nos': 11, 'nostra': 12, 'patientia': 13, 'quamdiu': 14, 'quem': 15, 'quo': 16, 'sese': 17, 'tandem': 18, 'tuus': 19, 'usque': 20}

现在我们需要定义嵌入大小,也就是每个向量的维数,在我们的例子中是 50,以及词汇长度

21

我们知道需要定义想要嵌入的单词的 id。举个例子,我们将带着阿布蒂雷巴提尼亚

只是为了确定你在跟踪我。代表词汇表中某些单词的 id。词汇表是单词(令牌)到 id 的映射。

为什么我们必须这么做?神经网络与数字一起工作,所以我们必须将一个数字传递给嵌入层

“本地”方法

为了嵌入,我们可以使用低级 API。我们首先需要定义一个大小为[VOCAL_LEN, EMBED_SIZE] (20,50)的矩阵,然后我们必须使用tf.nn.embedding_lookup告诉 TensorFlow 在哪里寻找我们的单词 id。

tf.nn.embedding_lookup创建一个操作,根据第二个参数的索引检索第一个参数的行。

[[0.2508639 0.6186842 0.04858994 0.5210395 0.46944225 0.93606484 0.31613624 0.37244523 0.8245921 0.7652482 0.05056596 0.82652867 0.637517 0.5321804 0.84733844 0.90017974 0.41220248 0.659974 0.7645968 0.5598999 0.40155995 0.06464231 0.8390876 0.139521 0.23042619 0.04655147 0.32764542 0.80585504 0.01360166 0.9290798 0.25056374 0.9695363 0.5877855 0.9006752 0.49083364 0.5052364 0.56793296 0.50847435 0.89294696 0.4142543 0.70229757 0.56847537 0.8818027 0.8013681 0.12879837 0.75869775 0.40932536 0.04723692 0.61465013 0.97508 ] [0.846097 0.8248534 0.5730028 0.32177114 0.37013817 0.71865106 0.2488327 0.88490605 0.6985643 0.8720304 0.4982674 0.75656927 0.34931898 0.20750809 0.16621685 0.38027227 0.23989546 0.43870246 0.49193907 0.9563453 0.92043686 0.9371239 0.3556149 0.08938527 0.28407085 0.29870117 0.44801772 0.21189022 0.48243213 0.946913 0.40073442 0.71190274 0.59758437 0.70785224 0.09750676 0.27404332 0.4761486 0.64353764 0.2631061 0.19715095 0.6992599 0.72724617 0.27448702 0.3829409 0.15989089 0.09099603 0.43427885 0.78103256 0.30195284 0.888047 ]]

喀拉斯层

我不是 keras 的粉丝,但它可能是有用的。您可以使用独立的层来创建嵌入

[[0.9134803 0.36847484 0.51816785 0.19543898 0.07610226 0.8685185 0.7445053 0.5340642 0.5453609 0.72966635 0.06846464 0.19424069 0.2804587 0.77481234 0.7343868 0.16347027 0.56002617 0.76706755 0.16558647 0.6719606 0.05563295 0.22389805 0.47797906 0.98075724 0.47506428 0.7846818 0.65209556 0.89036727 0.14960134 0.8801923 0.23688185 0.70695686 0.59664845 0.6206044 0.69665396 0.60709286 0.42249918 0.7317171 0.03822994 0.37915635 0.60433483 0.4168439 0.5516542 0.84362316 0.27857065 0.33540523 0.8601098 0.47720838 0.9827635 0.09320438] [0.27832222 0.8259096 0.5726856 0.96932447 0.21936393 0.26346993 0.38576245 0.60339177 0.03083277 0.665465 0.9077859 0.6219367 0.5185654 0.5444832 0.16380131 0.6688931 0.82876015 0.9705752 0.40097427 0.28450823 0.9425919 0.50802815 0.02394092 0.24661314 0.45858765 0.7080616 0.8434526 0.46829247 0.0329994 0.10844195 0.6812979 0.3505745 0.67980576 0.71404254 0.8574227 0.40939808 0.8668809 0.58524954 0.52820635 0.31366992 0.05352783 0.8875419 0.04600751 0.27407455 0.6398467 0.74402344 0.9710648 0.5717342 0.78711486 0.9209585 ]]

张量流层

由于 Tensorflow 很混乱,总是有几种方法来做同样的事情,并且不清楚应该使用哪一种,所以毫不奇怪还有另一个函数来创建嵌入。

[[ 0.11656719 -0.21488819 0.04018757 -0.18151578 -0.12417153 -0.00693065 0.27286723 0.00712651 -0.05931629 -0.20677638 0.14741448 -0.24938995 -0.21667814 0.09805503 0.2690411 0.20826831 0.19904876 0.08541816 0.20128882 0.15323257 -0.0386056 0.03025511 0.11573204 0.2161583 -0.02596462 -0.15845075 -0.26478297 -0.13366173 0.27797714 -0.08158416 -0.25292248 -0.16360758 -0.1846793 0.2444193 0.13292032 0.15807101 0.24052963 -0.0346185 0.02243239 0.2350963 -0.0260604 0.12481615 -0.1984439 0.20924723 -0.00630271 -0.26579106 0.04491454 0.10764262 0.170991 0.21768841] [-0.09142873 -0.25572282 0.2879894 -0.2416141 0.0688259 -0.06163606 0.2885336 -0.19590749 -0.04164416 0.28198788 0.18056017 -0.03718823 -0.09900685 0.14315534 -0.25260317 -0.00199199 -0.08959872 0.23495004 -0.18945126 -0.16665417 0.18416747 0.05468053 -0.23341912 0.02287021 0.27363363 0.07707322 -0.02453846 0.08111072 0.12435484 0.12095574 0.2879583 0.12930956 0.09152126 -0.2874632 -0.26153982 -0.10861655 -0.01751739 0.20820773 0.22776482 -0.17411226 -0.10380474 -0.14888035 0.01492503 0.24255303 -0.10528904 0.19635591 -0.22860856 0.2117649 -0.08887576 0.16184562]]

编写自己的模块

您可以使用经典范例__init__ + __call__来创建您的定制类。

[[0.19501674 0.954353 0.30957866 0.65923584 0.28241146 0.80623126 0.46677458 0.5877205 0.25624812 0.03041542 0.24185908 0.8056189 0.61915445 0.04368758 0.16852558 0.24910712 0.66250837 0.01929498 0.82387006 0.8489572 0.3970251 0.8156922 0.5550339 0.39991164 0.64657426 0.1980362 0.35962176 0.89992213 0.99705064 0.7636745 0.5627477 0.09286976 0.12509382 0.9644747 0.3412783 0.3238287 0.08844066 0.06885219 0.2377944 0.04519224 0.6535493 0.39360797 0.69070065 0.44310153 0.58286166 0.32064807 0.9180571 0.47852004 0.6686201 0.44279683] [0.0843749 0.77335155 0.14301467 0.23359239 0.77076364 0.3579203 0.95124376 0.03154683 0.11837351 0.622192 0.44682932 0.4268434 0.21531689 0.5922301 0.12666893 0.72407126 0.7601874 0.9128723 0.07651949 0.7025702 0.9072187 0.5582067 0.14753926 0.6066953 0.7564144 0.2200278 0.1666696 0.63408077 0.57941747 0.9417999 0.6540415 0.01334655 0.8736309 0.4756062 0.66136014 0.12366748 0.8578756 0.71376395 0.624522 0.22263229 0.35624254 0.00424874 0.1616261 0.43327594 0.83355534 0.51896024 0.53433514 0.47303247 0.7777432 0.4082179 ]]

预训练嵌入

您可以通过使用预训练的单词嵌入来获益,因为它们可以提高模型的性能。他们通常用庞大的数据集来训练,例如维基百科,用跳过语法模型的词袋。

有几个已经训练好的嵌入,最著名的是 word2vec 和 Glove 。

你可以在这篇 tensorflow tutoria l 和这篇文章中读到更多关于训练单词嵌入以及如何从头开始训练它们的内容

在过去,加载到 TensorFlow 预训练的单词嵌入并不容易。你必须从某个地方下载矩阵,加载到你的程序中,并可能再次存储它。现在,我们可以使用 TensorFlow Hub

张量流集线器

您可以通过 TensorFlow hub 轻松使用预训练的单词嵌入:一个预训练模块的集合,您可以在代码中导入它。完整列表在这里

让我们看看它的实际效果。

顺便说一句,TensorFlow Hub 有缺陷,在木星上不能很好地工作。或者至少在我的机器上,你可以试着运行它,看看它是否适合你。在 PyCharm 上我没有任何问题,所以我将复制并粘贴输出。

如果您有同样的问题,请在 TensorFlow 资源库上打开一个问题。

你也可以通过将hub.Module构造器的trainable参数设置为True来重新训练它们。当您有一个特定领域的文本语料库,并且希望您的嵌入专门针对该语料库时,这是非常有用的。

hub.Module("https://tfhub.dev/google/Wiki-words-250-with-normalization/1", trainable=True)

结论

现在,您应该能够在 TensorFlow 中高效地创建单词嵌入层了!

你可能也会觉得下面这篇文章很有趣

** [## 如何在 TensorFlow 中使用数据集

内置的输入管道。再也不用“feed-dict”了

towardsdatascience.com](/how-to-use-dataset-in-tensorflow-c758ef9e4428) [## 强化学习备忘单

声明:这是一个正在进行中的项目,可能会有错误!

towardsdatascience.com](/reinforcement-learning-cheat-sheet-2f9453df7651)

感谢您的阅读,

弗朗西斯科·萨维里奥·祖皮奇尼**

如何使用 Python、Plotly Dash 和 Google Sheets API 创建您的第一个 web 应用程序

原文:https://towardsdatascience.com/how-to-create-your-first-web-app-using-python-plotly-dash-and-google-sheets-api-7a2fe3f5d256?source=collection_archive---------2-----------------------

The final product from this step-by-step guide to developing web dashboards using Plotly Dash, Python and Google Sheets API

更新 09/21/2018: 下面教程第一部分创建的 app 现在在这个 Github 仓库中可用。虽然在功能方面进行了简化,但是将那里的代码与这里的教程结合起来,应该可以让您立即开始使用 Dash。
— — — — — — — —

我最近写了几个简短的教程,讲述如何使用 Plotly 的人提供的令人敬畏的“Dash”Python 库来创建 web 应用程序。该库对于数据科学项目(或任何项目)的快速原型开发的力量是不可低估的。

然而,默认情况下,Dash 应用程序只能在本地机器上运行。显然,任何 web 应用程序的主要好处是能够与受众分享。幸运的是,Dash 库是建立在非常流行的“Flask”库之上的,Dash 应用程序可以部署为以同样的方式提供内容。我们将利用通过使用 Heroku 获得的简单部署过程,而不是从头开始配置服务器。一旦我们有了一些在 Heroku 上运行的示例代码,我们将更新应用程序,通过 Python API 从 Google Docs 电子表格中访问数据。

步骤 1:创建和设置虚拟环境

使用您最喜欢的虚拟环境,创建一个新的环境来存放应用程序。使用 Anaconda,我们只需输入:

$ conda create --name <your env name> python=3.6

创建环境后,在命令提示符下激活它(根据您的操作系统,您可能不需要在前面加上“source”),然后创建一个文件夹,我们将在后续步骤中使用它来存放所有各种应用程序文件。

$ source activate <your env name>
$ mkdir venv
$ cd venv

现在,安装应用程序所需的依赖项。

$ pip install dash
$ pip install dash-renderer
$ pip install dash-core-components
$ pip install dash-html-components
$ pip install plotly
$ pip install dash-table-experiments 
$ pip install numpy
$ pip install pandas
$ pip install gunicorn
$ pip install --upgrade google-api-python-client$ pip install numpy
$ pip install pandas
$ pip install gunicorn

验证您是否在先前为项目创建的“venv”目录中。在此初始化一个空的 git 存储库。

$ git init

步骤 2:创建文件结构和初始 app 文件

与简单地在本地机器上运行相比,在 Heroku 上部署一个网站需要一些额外的文件和文件夹。为了确保事情顺利进行,我们需要根据以下结构创建几个文件:

venv/
   app.py
   .gitignore
   .Procfile
   .requirements.txt
   credentials/
      __init__.py
      Credentials.py

在之前创建的“venv”文件夹中,创建一个名为“app.py”的新文件。我们可以使用这里的代码(链接到原始源代码)进行初始测试。

现在,创建一个“credentials”文件夹,并在该文件夹中创建两个文件,“init”。py”和“Credentials.py”。init 文件只是让 Python 知道我们希望这个文件夹是一个可导入的模块——我们可以将文件本身留空。第二个文件是我们用来存储访问 Google 工作表数据的 Google API 键的地方,但是我们稍后会更新这些键。

*重要提示:在将代码上传到任何公共 Git 存储库之前,请确保更新 gitignore 文件以排除 credentials 文件夹!

在“venv”文件夹中,创建。gitignore 文件(我喜欢用 gitignore.io 作为启动模板)。

# At a minimum, make sure .gitignore file contains these items
*.pyc
.DS_Store
.env

接下来,同样在“venv”文件夹中,创建一个名为“Procfile”的文件,其内容如下:

web: gunicorn app:server

最后,我们需要在“requirements.txt”文件中创建一个项目依赖关系列表。只需在提示符下键入以下命令,即可轻松生成该列表:

$ pip freeze > requirements.txt

第三步:将测试应用部署到 Heroku

对于这一步,您需要在您的机器上安装一个 Heroku 帐户和命令行提示符(参见 Heroku 帐户设置的链接)。

$ heroku create lava-vino # replace "lava-vino" with your-app-name
$ git add . 
$ git commit -m "Initial commit"
$ git push heroku master 
$ heroku ps:scale web=1

验证该应用程序在https://lava-vino.herokuapp.com/(或您的应用程序的等效名称)上可见。

The test app shows up in the browser — Success!

第五步:更新应用程序,从 Google API 中提取数据,并将数据可视化

在之前的教程中,我解释了如何使用 Google 的 Python API 访问 Google 工作表数据。为了可视化该教程中提到的火山葡萄酒数据集,我们需要更新我们的应用程序,并提供适当的 Google API 凭证。稍微修改一下该教程中描述的步骤,将“client_secret.json”文件复制到我们在上一步中创建的“credentials”文件夹中。此外,您需要用您的地图框 ID 令牌更新“Credentials.py”文件。

重要提示:在将代码上传到任何公共 Git 存储库之前,一定要更新 gitignore 文件,以排除 credentials 文件夹!

接下来,用下面的代码更新‘app . py’文件(确保包含您自己的 Mapbox ID 标记,和/或更新 Google 工作表名称、ID 和数据解析方法以适应您自己的数据集)。

我们几乎准备好将更新的应用程序部署到 Heroku,但是首先,我们需要在本地机器上运行应用程序,以便生成 Google API 凭证文件。继续在本地计算机上运行“app.py”文件;您应该会收到一条警告,提示您访问一个链接,以使用您的 Google 帐户验证您的应用程序。单击链接进行身份验证—如果成功,您现在应该在 credentials 文件夹中有一个新的“credentials.json”文件。

After running the app on your local machine, click the link to authenticate access request for the Google API

生成凭证文件后,您就可以使用以下命令将更新后的应用程序部署到 Heroku 了:

$ git status # view the changes
$ git add .  # add all the changes
$ git commit -m "Updated app"
$ git push heroku master

关键时刻……导航到https://lava-vino.herokuapp.com/(或者你的应用程序名称的网址,祈祷成功吧!我们的 web 应用程序已成功部署到世界各地!

如您所见,创建 Dash 应用程序并通过 Heroku 进行部署相对简单,而且所有这些都无需编写任何 HTML、Javascript 或 CSS 代码。显然,这个应用程序还有很多工作要做——交叉引用葡萄酒名称数据、可视化数据、创建友好的用户界面等。我们将在以后的教程中讨论这些内容。我还将尝试上传一个项目的精简版本到它自己的 Git 存储库中,这样它就可以很容易地被克隆为一个模板。与此同时,希望这能让你开始运行自己的 Dash 应用程序!

如何为您的业务数据集策划一个基本事实

原文:https://towardsdatascience.com/how-to-curate-a-ground-truth-for-your-business-dataset-76be7b1549a3?source=collection_archive---------11-----------------------

如果你是一名实践数据科学家,总是给你一个精确标记的数据集来应用先进的机器学习算法,这篇文章不适合你。这是为我们公司世界中的其他人准备的,他们必须争取有用的数据集来解决我们团队面临的业务问题!

Iris Dataset

很有可能你已经在虹膜数据集上运行了实验,用于演示基本的机器学习模型。对于教育目的来说,这是一个很好的数据集,但我经常看到有抱负的数据科学家在试图将这些技能应用于现实世界的问题时感到沮丧。为什么学术界的项目与现实世界中的项目如此不同?

你也可以将同样的故事情节扩展到“Kaggle Cowboys”,他们非常擅长在精心策划的问题陈述和数据集上优化机器学习算法,但在处理现实世界的商业问题时,往往很难捕捉到同样的吸引力。同样,在比赛中运用你的技能和在公司项目中运用你的技能有什么区别?

Adding labels to your dataset

我对这种差异的观察集中在数据注释的艺术/科学上,或者简单地给你的观察加上一个标签!业务问题通常会提交给数据科学团队,他们的意图是好的,但缺乏关键数据点,这使得训练任何有监督的机器学习算法都不可能。对于那些不在业务领域的人,回想一下 Iris 数据集。它类似于只包含原始属性的数据集,没有最终的类来识别正在测量的虹膜类型。或者与此相反,只捕获最终的类,而不捕获有助于做出最终分类决策的属性。

不幸的是,对于一些遗留的业务流程来说,制定决策的决策因素没有被数字化地捕获。解决这些差异的正确方法是与流程工程师和应用程序开发人员合作,告诉他们我们需要收集的数据点,以便在未来应用机器学习算法。然后提出变更请求,以在生产系统上实现这些特性,并可能在流程中重新培训工人。然后我们可以开始考虑在未来的某一天应用机器学习。然而,您的业务发展速度可能会要求您还需要找到一个针对所有历史数据的解决方案,并在本财政季度内展示一个机器学习概念验证!

当数据缺少关键信息时,我们如何弥合这一差距,以利用可用的历史数据来展示机器学习的潜力?

答案出人意料地简单,却很难掌握。利用调查设计中的原则,用人类智慧简单地增加你的历史数据。注释原始数据集的学科通常不与机器学习算法一起教授,但应该这样。如果你看看发表在知名期刊和学术界的文章,就会发现有一整套关于他们如何从主题专家(SME)那里获取实验数据的实践。让我们花点时间来探索这一规律,以及如何将它引入我们的业务数据集。

Google’s reCAPTCHA

谷歌巧妙地将数据注释实践掌握到一项名为 reCAPTCHA 的“免费”服务中。reCAPTCHA 可用于任何网站,并为他们提供抵御机器人的高级安全性,同时引导人类访问者的精神能量解决数字化文本或注释图像的低技能“验证码”。他们利用多人的智慧来构建这个带注释的数据集。这有助于解释任何单个人的偏见,并开发一个“真理”数据集,该数据集是关于被标记的观察结果的普遍接受的“真理”。当然,这里的问题是,任何利用 reCAPTCHA 的网站都在将数据注释任务反馈给 Google 的专有数据集!

整个流程是平滑无缝的,允许一大群人用标签来增加先前未标注的数据集。这为先进的机器学习算法打开了闸门,以解决有趣的商业问题!随着数十亿人访问数十亿个网站,其中一些参与了 reCAPTCHA,谷歌成为人工智能行业的领先公司有什么好奇怪的?企业应该如何利用这群互联网工作者来注释他们自己的专有数据集?我们能为我们的业务数据集复制这个工作流吗?

Mechanical Turk

亚马逊也看到了这一潜力,但他们没有让一群匿名的互联网工作者注释自己的专有数据集,而是将其作为一个名为 Mechanical Turk 的 API 服务公开。这项服务提供了一个惊人的平台,将任何拥有未注释数据集的人与一群愿意以最低报酬注释数据集的工作者联系起来。就数据注释而言,我认为 MTurk 是每个数据注释平台都应该追求的“黄金标准”,这主要是因为可用劳动力的规模可以转化为对数据集进行注释的速度。在实践中,当员工完成交给他们的任务时,你通常会给他们每分钟 0.12 到 0.25 美元的报酬(大约每小时 8 到 15 美元)。

就我们所处理的商业问题的规模而言,你可以在 MTurk 上以非常便宜的价格获得你的数据集注释!对于给定数据集中的数万个观测值,您通常可以期望 MTurk 上的一大群工作人员在几个小时内完成任务,而费用仅为几百美元!但是这里有一个大陷阱…

一般来说,任何互联网用户一般都有资格完成低技能的注释任务,如数字化文本或注释图像。然而,当手头的注记任务需要具有专业知识的高素质工人时,愿意为低工资的数据集进行注记的人数开始显著下降。对于这些类型的数据集,目前的策略是通过“面试”确定哪些员工可以参与,并提高每项任务的报酬。

在商业中,你不太可能有一个足够简单的数据集,只需要 MTurk 工人的低技能工作。除了数据集的复杂性之外,更大的挑战很可能是你的数据集是你的企业专有的,你的信息安全团队将规定你不能将它暴露给互联网上的任何匿名工作者。那么这是否意味着众包你的数据标注任务是不合适的呢?

Figure Eight

Figure Figure Figure(原名 CrowdFlower)提供了许多与 MTurk 相同的功能,但增加了让工人在 NDA 下操作的承诺。当然,我们不断添加到工人人才库来注释我们的数据的请求越多,我们的人才库就越小,报酬就越高。

当您深入研究您的数据集以定义您要求 NDA 手下的这些工人执行的任务时,您可能会得出这样的结论:数据集的复杂性如此错综复杂,以至于需要非常具体的知识才能正确地进行注释。在某些情况下,这种知识可能在你的业务中根深蒂固,以至于指望公司以外的任何人都能正确回答是不合理的。这就引出了一个问题,为什么我们不能让我们内部的主题专家(SME)来为我们做注释工作呢?如果我们要求内部员工注释我们的数据,为什么我们需要第三方服务?

PyBOSSA

要求内部 SME 注释数据的挑战通常集中在一致性、规模、优先级、相关性和紧迫性上。通常,你需要帮助注释数据集的 SME 在他们的职业生涯中已经超越了对单调乏味工作的兴趣。这些挑战大多可以通过良好的领导、沟通和适当的激励来解决。然而,对于剩下的技术挑战,请查看 PyBOSSA 。PyBOSSA 是一个开源的众包应用程序,源自 BOSSA ,构建于 Python、Redis 和 PostgreSQL 之上。

使用 PyBOSSA,我们可以公开 reCAPTCHA、MTurk 或 Figure Figure 8 的相同功能,以帮助注释我们的数据集。该解决方案的美妙之处在于,您拥有整个基础设施,并且可以对其进行定制,以满足您的确切的业务需求。这意味着您可以在内部部署它,在特定身份认证要求的保护下满足您的信息安全和法律团队的要求。以及将每个活动的现成 RESTful API 路由到 SME 的现有工作流中,以最小化注释数据的摩擦(类似于 reCAPTCHA)。它还包括基本的活动指标和基本的 web 界面,供您起草任何 HTML DOM 和 JavaScript 来处理任何类型的注释任务。

不管你选择哪个众包平台来注释你的数据集,仍然有一个关于注释质量的问题,以及我们能在多大程度上信任这些工作者??

为了回答这些问题,在以后的文章中,我们将介绍一些业务数据集的 数据注释最佳实践

如何自定义 JupyterLab 键盘快捷键

原文:https://towardsdatascience.com/how-to-customize-jupyterlab-keyboard-shortcuts-72321f73753d?source=collection_archive---------5-----------------------

我经常发现自己想要重新启动并运行所有单元格,所以我想制作一个键盘快捷键。我制作这个教程是为了帮助其他人,因为它不是一个点击选择的东西

JupyterLab 就像合成代谢类固醇的 Jupyter notebook 没有增加的癌症风险和其他负面副作用。JupyterLab 被宣传为 Jupyter 项目的下一代 UI。2018 年初 beta 发布。

有趣的事实是,Jupyter 人把 JupyterLab 写成一个单词,而 Jupyter notebook 写成两个单词😃。

这感觉就像使用您熟悉的 Jupyter 笔记本电脑,并增加了导航标签等功能。这是未来——它就在眼前。

如果你和我一样,你可能看过巨蟒之灾中的 JupyterLab,但却一直保存着你的 Jupyter 笔记本。试试看。它可以帮助你提高工作效率。说到生产力,我们来做一个键盘快捷键。🚀

正在做

conda install -c conda-forge jupyterlabpip install jupyterlab安装。然后在终端中用jupyterlab 运行 JupyterLab,或者在 Anaconda Navigator 中选择应用程序图标。

JupterLab 打开后,点击设置下拉菜单。选择高级设置编辑器

选择键盘快捷键

您将在系统默认设置面板中看到每个选项的字典。有一大堆选项,所以你可能想用Command+F(Windows 上的 Ctrl + F 来找到你想要的那个。复制您想要覆盖的代码。

这里是重启并运行全部的部分。

{
  "command": "runmenu:restart-and-run-all",
  "keys": [
        ""
   ],
   "selector": "[data-jp-code-runner]"
},

将此代码粘贴到用户首选项面板中。在列表中,输入您想要成为快捷键的键的名称。我在下面加了 CtrlShiftR

更新 2020 年 6 月 24 日,沙希达在评论中指出,JupyterLab 更改了用于更改键盘快捷键的 API。下面的代码已更新。谢谢沙希达!

{"shortcuts": 
    [
        {
            "command": "runmenu:restart-and-run-all",
            "keys": [
                "Ctrl Shift R"
            ],
            "selector": "[data-jp-code-runner]"
        }
    ]
}

我建议通过在系统默认面板中搜索您的新组合键来确保您没有覆盖另一个 JupyterLab 键盘快捷键。

现在你知道了。按下Command+S(Windows 上为 Ctrl + S )保存,打开笔记本文件,试用你的新键盘快捷键!

全部运行!

真见鬼。

您刚刚学习了如何通过在 JupyterLab 中制作键盘快捷键来节省时间。请注意,这将在 Jupyter 实验室的编辑模式或命令模式下运行。

有些命令不会出现在系统默认设置面板中。这里列出了可以绑定的命令。

尝试和享受!

包装

我希望这篇自定义 JupyterLab 快捷方式的指南对你有所帮助。如果你有,请在你最喜欢的社交媒体上分享,这样其他人也可以找到它。😀

我写关于 Python 、 SQL 和其他技术主题的文章。如果你对这些感兴趣,请注册我的邮件列表,那里有很棒的数据科学资源,点击这里阅读更多帮助你提高技能的内容。👍

没有学位如何学习数据科学

原文:https://towardsdatascience.com/how-to-data-science-without-a-degree-79d8388a49ba?source=collection_archive---------5-----------------------

一位数据科学家的想法和建议

Me at GoDaddy office

简介

你好。

我想向你展示如何成为一名没有学位(或免费)的数据科学家。具有讽刺意味的是,我有一个学位——甚至是为数据科学而设的学位(西北大学的分析学硕士)。但是给你一点背景,我以前是德勤的会计。这不是很疯狂吗?我远离数据科学或任何技术。由于我来自一个非技术背景的家庭,我不得不在工作之余,甚至在我的硕士课程期间,自己在网上学习很多东西,以赶上我的同龄人的水平。亲身经历过,我可以告诉你,学历很有帮助,但不是必须的。因为我一直站在获得学位和在线学习的两边,我想我可以给你一个独特的视角。获得数据科学硕士学位是进入该领域的一种可靠而快速的方式,但幸运的是,如果你不想花 6-9 万美元的学费,你不必这样做。不过,这需要你高度的自律。

如果有朋友问我如何进入数据科学领域,这篇文章就是为他们准备的。我希望你能发现我的建议是有价值的和相关的,因为我自己也经历过这个过程,并且发现这些资源是有用的。在我们进入细节之前,让我们先了解一下数据科学是什么。

作为一名数据科学家,您从事什么工作?

如果你已经知道这一点,请跳过这一部分。

嗯,根据我在 GoDaddy,HERE 和 GoGo 等几家公司担任数据科学家的经验,数据科学家通过对大数据应用机器学习来解决问题。一些例子是:预测客户取消订阅的概率,识别数据异常,计算千兆字节或兆兆字节数据的即席分析,将客户分组为有意义的组,文本分析以在客户聊天记录中找到主题,计算收入预测,并且列表不会结束。

作为一名数据科学家,你会遇到许多不同类型的问题。要想胜任,你需要有扎实的数学、统计和编程基础。您需要知道何时根据问题和数据使用特定的技术和算法。最后,您通常需要将结果和技术展示给高管和不太懂技术的观众。

此外,作为一名数据科学家,你需要继续学习和适应。因为这个领域变化很快,所以跟上时代和学习新技术很重要。即使是今天,我也花很多时间学习。

成为数据科学家需要什么(免费)

Free online resources

数据科学家的工作听起来让你兴奋吗?太好了。这是一个活着免费学习的好时机。我试图专注于免费或便宜的选择,因为谁不喜欢免费的东西?它只需要你的承诺和毅力。我将分三个阶段描述这个过程。

请记住,除了下面提到的,还有其他很好的资源。但这些恰好是我拍的,觉得有用。

第一阶段:婴儿期

为了擅长数据科学,你需要有良好的编程、统计和数学基础。至少,我建议您学习以下内容:

  • 大学水平的介绍计算机科学课程(对我来说是 C++)。
  • 大学级别的低年级数学课程,如多变量微积分、微分方程、线性代数。这将直接影响你对深度学习底层数学的理解,比如反向传播和矩阵运算。
  • 大学水平的统计介绍概率教你 r

好消息是他们不必在大学里参加。要在线学习我上面提到的技能,我推荐这些:

  • 数学:多变量微积分、微分方程、 线性代数 出自 可汗学院
  • 统计学:R 中的统计学与数据科学导论: 约翰霍普金斯大学 Coursera 上的数据科学专业
  • Python:CodeAcademy.com为 Python 中的一般编程。****

要查看数据科学可以做什么的示例,请查看 Kaggle.com 的,在那里人们学习和竞争数据科学项目。另外,看看 DataCamp.com 的,它提供了用 R 和 Python 编写的各种数据科学主题的实践教程。****

到第 1 阶段结束时,您应该能够熟练地在 R 或 Python 上执行简单的机器学习技术,如逻辑/线性回归和决策树。另外,我建议同时学习 R 和 Python。尽管我最近主要使用 Python,但根据您试图解决的问题,了解这两者是很有用的。

第二阶段:青春期

现在,您应该对数据科学和统计方法有了更好的了解。在第二阶段,你想更深入,专注于机器学习。我发现像 Coursera 这样的在线资源通常不会涵盖大学水平的课程。谢天谢地, 斯坦福的人工智能实验室 免费在线提供令人惊叹的课程。所以你可以免费观看世界一流的讲座、课堂笔记和许多其他课程材料。所以如果可以的话,我建议你参加 Coursera 课程,同时观看斯坦福大学的讲座。例如,Coursera 上的deep learning . ai向你展示了深度学习非常好和实用的一面,而斯坦福的cs 231n 计算机视觉课程要深入得多。****

在此阶段,采取以下措施:

  • 机器学习:吴恩达在 Coursera 上的机器学习课程 。我参加了这次考试,但没有支付认证费用,因为我的作业没有使用 python 或 r。但这对理解机器学习的基础仍然非常有用。
  • 机器学习: 斯坦福 CS229 机器学习课程 。这些是吴恩达的旧演讲视频,但仍然很好。
  • 文本分析: 在 Coursera 上应用 Python 中的文本挖掘。我没有上过这个课程,但是文本分析和自然语言处理(NLP)是一个数据科学家非常普遍和需要的技能。
  • PySpark: DataCamp 的 PySpark 课程简介 。Pyspark 是 spark 分布式计算框架的 python 版本。简单地说,它允许你在非常大的数据上使用 python。我每周都用它。
  • 深度学习:吴恩达 Coursera 上的 deep Learning . ai我付费认证是因为这门课的作业很好。因为它很实惠,所以我建议你付钱。
  • 计算机视觉: 斯坦福 CS231n 卷积神经网络视觉识别教程
  • 自然语言处理:斯坦福 CS224n 自然语言处理与深度学习课程
  • (2019–10–01 更新) PyTorch 与实用深度学习:fast . ai。我听说了很多关于这个免费课程的好消息,PyTorch 也越来越受欢迎。我打算亲自去看看这门课。****

同样,还有其他资源,如 DataCamp、Udacity、edX 和 fast.ai,您可以查看以了解各种主题。

第三阶段:独立

在这个阶段,你应该为面试做准备,并继续学习新的和更深入的话题。如果你已经掌握了材料,直到第二阶段,我认为你应该有足够的知识来申请一份入门级的工作。然而,还有几件事对你通过面试很关键。

第一,个人项目。如果你在一个数据科学项目中,大多数课程都会让你完成机器学习项目,这对练习你的技能和向雇主展示你所做的事情非常好。所以我真的建议你尝试一些个人项目,最简单的就是 Kaggle。另外,尽管没有必要,我还是建议你在 Github 上放一些你已经完成的示例代码和项目,给未来的雇主看看。

第二,你很可能会被面试 SQL。当我开始在 GoDaddy 工作时,我并不太了解 SQL。当我在面试的时候,我只是通过谷歌 SQL 面试问题了解了一点关于 W3Schools.com 的知识。即使要看公司,SQL 也没有你的机器学习和编程技能重要。在工作中学习相对容易。去 Leetcode.com看看,练习你的 SQL 和编程技能。

最后,到这个阶段,你应该有足够的知识来探索不同的机器学习主题,并进行更深入的学习。你可以关注任何你感兴趣的话题,无论是 RNN、CNN、NLP 还是其他。我呢,这几天在努力学习强化学习。

结论

这是我的第一篇文章,我真的希望你会觉得有用。我试图把重点放在你应该学习的特定课程上,而不是你需要学习的特定工具或 Python/R 包,因为这些课程会教你这些东西。

如果你想看机器学习的示例代码,请查看我的 Github 知识库,我会不断更新我学到的新东西。我计划分享更多我正在做的不同项目或任何其他关于媒体的想法!如果你有任何问题,或者希望我在未来报道任何具体的事情,请在下面的评论中提问。

感谢您的阅读!

( )领英 推特 )

你可以看看我的其他文章和项目!

  • 和我聊天:https://calendly.com/jasjung/30min
  • 中型:为什么有这么多不同类型的数据科学家? 机器学习工程师 vs 数据科学家(数据科学结束了吗?)
  • 中:好奇成为数据科学家后会发生什么?查看我的新文章, 如何作为一名数据/研究科学家保持最新状态
  • 项目:我最新的项目 www。薪.忍者 及对应文章 欢迎来到薪忍者
  • Youtube:我的程序( AlphaBlitz )使用深度学习击败了脸书的文字游戏。喜欢并订阅!😃
  • Medium : 我如何在 5 周内用 Django 构建并部署我的第一个 Web 应用
  • 中型: 我如何用我的前四篇中型文章 赚了 2000 多美元。
  • 中等: 四年内做过软件工程师、机器学习工程师、数据科学家。这些是我的主要收获。

如何进行数据实验:针对大型数据集运行笔记本电脑

原文:https://towardsdatascience.com/how-to-datalab-running-notebooks-against-large-datasets-2c4f932729f6?source=collection_archive---------2-----------------------

将大数据传输到本地计算环境既缓慢又昂贵。在这一集的人工智能冒险中,我们将看到如何将您的笔记本环境应用到您的数据中!

唯一比交互式 Python 笔记本更好的是什么?当然,这是一个具有快速简单的数据连接的交互式 Python 笔记本!

上一集我们看了 Jupyter 笔记本有多有用。这一次,我们将看到如何通过在云中运行它来实现更多的额外好处!

数据,但更大

随着您在云中处理越来越大的数据集,使用您的本地机器与它进行交互变得越来越困难。下载具有统计代表性的数据样本来测试你的代码会变得很困难,而在本地传输数据进行训练依赖于稳定的连接。那么,数据科学家应该做些什么呢?

如果您无法将数据带到您的电脑上,请将您的电脑带到您的数据上!让我们看看如何在云中运行笔记本环境,靠近您的数据集!

Google Cloud Datalab 建立在我们熟悉的 Jupyter 笔记本之上,增加了一些功能,包括轻松验证 BigQuery 数据集、快速操作 Google 云存储以及 SQL-query 支持!这个工具包在 GitHub 上也是开源的,所以你可以在你自己的环境中运行它。

让我们创建一个数据实验室环境,并为在云中运行我们的笔记本电脑做好准备。

使用gcloud components install datalab安装 datalab 组件。然后您将拥有一个名为datalab的新命令行工具。

Installing Datalab is a one-command operation

启动 Datalab 是一行命令:datalab create

Datalab still connects to localhost!

该命令启动您将用于分析的虚拟机,配置网络,并安装我们将使用的必要库,包括 TensorFlow、pandas、numpy 等等。

一旦 Datalab 启动,它将打开一个笔记本环境,看起来与我们在 Jupyter 笔记本中看到的非常相似。然而,这不是在本地运行,而是在云中的虚拟机上运行。Datalab 默认安装了一些示例,这是一个开始探索的好地方。让我们看看“你好,世界”笔记本,在“文档”文件夹中。

在这里,我们可以立即开始使用笔记本,运行细胞并进行实验。这非常方便,因为不需要管理和配置不同的 python 库。

让我们来看看几个内置的附加工具。在右上角的帐户图标上,有一些需要注意的数字设置和有用信息。

首先,请注意笔记本是作为服务帐户运行的。服务帐户已经使用我们所在项目的资产进行了身份验证,但是如果我们想要从另一个项目访问资源,我们需要授予服务帐户访问权限,而不是用户帐户。

由于运行笔记本的虚拟机对于能够访问项目的任何人都是可访问的,所以我们不想在 datalab 笔记本中暴露我们自己的帐户凭证。

继续向下,我们看到我们正在从一个名为 ai-adventures 的 Google Compute Engine 虚拟机运行笔记本,我们可以随时通过单击该按钮关闭虚拟机。

默认情况下,一旦虚拟机空闲 90 分钟,Datalab 就会关闭它。您可以通过单击消息来切换此功能。

超时也可以设置为自定义值。让我们去设置看看如何做到这一点。我们在此设置的值将在虚拟机重新启动后保持不变,如果设置为零,将不会发生自动关闭。

这也是我们可以选择亮或暗的主题的地方。

现在,我们已经设置好了 datalab 笔记本电脑,并熟悉了我们的环境,让我们看看可以用 datalab 做些什么吧!

Datalab 运行中的一个示例

今天我将通过一个例子来描述 Github 上使用的编程语言之间的相关性。也就是,“如果你用语言 A 编程,你有多大可能也用语言 B 编程?”笔记本在 docs 下的 samples 目录中。你也可以在 GitHub 上查看一下。

该分析仅使用了更大的 GitHub 公共数据集的一小部分样本。如果你想使用完整的 Github 提交历史,你可以点击查看数据集,点击查看随附指南。

结论和后续步骤

Datalab 是一种在靠近数据的地方运行云连接笔记本的好方法,它可以方便地连接到 BigQuery 等工具,并且可以轻松地在云中验证数据集。

去试试 Datalab,看看它是不是适合你的选择!

感谢阅读本集云 AI 冒险。如果你喜欢这个系列,请为这篇文章鼓掌让我知道。如果你想要更多的机器学习动作,一定要关注媒体上的me或订阅 YouTube 频道的来观看未来的剧集。更多剧集即将推出!

营销组合建模中的数字变量(MMM)

原文:https://towardsdatascience.com/how-to-deal-with-digital-variables-in-marketing-mix-modeling-mmm-9ceb36ba563f?source=collection_archive---------14-----------------------

Source: Pixabay

传统的 MMM 有助于理解电视、户外、印刷广告、店内促销和折扣等营销投入的影响。

随着数字技术的破坏,营销人员现在正在寻找一套新的营销投入,以了解他们的营销组合。MMM 中使用的一些数字变量是:脸书花费和印象、Instagram 花费和印象、有机会话、网站访问/流量、横幅花费、付费搜索花费和在线视频/内容花费。

那么,问题是如何处理 MMM 中的数字变量呢?

  1. 线性与非线性影响:

Source: https://www.bearfoxmarketing.com/marketing/difference-traditional-marketing-vs-digital-marketing/

在 MMM 中,TV 被视为非线性变量。非线性意味着电视支出/GRP 的每一个单位增长都不会产生单位销售回报。电视广告的效果开始随着时间而衰减。(详情请参考我在 MMM 上的第一篇文章:https://towardsdatascience . com/market-mix-modeling-MMM-101-3d 094 df 976 f 9)

另一方面,对许多品牌来说,数字媒体是一种相当新的投资媒介。因此,许多企业将数字视为线性变量。换句话说,随着数字支出/印象的增加,销售额也会增加。将数字花费/印象视为线性的另一个原因是,与传统的广告媒体(如电视、印刷和网络)相比,数字是相对便宜的媒体。因此,营销人员有足够的钱来增加对数字空间的投资,以获得更好的投资回报。

然而,并非所有品牌都是如此。例外情况可能包括那些可能没有开展有效的数字活动或在数字媒体上投资很少的品牌。随着时间的推移,脸书或 Youtube 广告的效果会减弱,从而使曲线变得非线性。

2。印象与花费(哪个更相关):

Source: Pixabay

通常,相同营销投入的印象和花费可能彼此具有非常高的相关性。因此,将模型中的两个变量放在一起考虑是不准确的。选择其中任何一个时,应考虑以下事项:

一、做 MMM 的目的是什么?目标是了解每项投入的投资回报率和资金投向,还是仅仅了解推动销售的因素?在前者的情况下,支出应被明确视为投入。

二。在后一种情况下,应检查整体模型统计和稳健性,并选择两个变量中的任何一个。

3。变量间多重共线性高:

Source: Asce Library

通常,数字变量以它们之间非常高多重共线性为特征。在构建模型时,最好进行几次迭代,并在模型中使用这些数字变量的不同组合。这应该由领域知识和模型的统计意义来支持。

4。投资回报影响:

Source: http://stephenlnelson.com/articles/quicken-annual-return/

如果在数字媒体上花费了大量资金,数字投资回报率通常会高于电视投资回报率。然而,如果在电视上投入大量资金,电视投资回报率将超过数字投资回报率。这不应该被认为是一个需要担心的问题,因为通常如果数字媒体的花费少了,就有机会在数字媒体上投入更多的钱(由于它的线性性质)

这是一个关于如何处理 MMM 中的数字变量的简介。

敬请关注更多文章!!

你也可以看我在 MMM 上的其他文章- 这里、这里、这里和这里。

更多详情,请联系:

网址:https://www.arymalabs.com/

领英

推特

版权所有 2018www.ridhimakumar.com版权所有。

如何在遗传算法中定义一个适应度函数?

原文:https://towardsdatascience.com/how-to-define-a-fitness-function-in-a-genetic-algorithm-be572b9ea3b4?source=collection_archive---------0-----------------------

在我的上一篇文章中,我已经解释了关于遗传算法的基础知识。这篇文章发表后,我收到了许多关于适应度函数评估策略的讨论请求。在本文中,我们将讨论适应度函数,以及如何针对给定的问题提出适应度函数。

什么是健身功能?

适应度函数(也称为评估函数)评估给定解决方案与期望问题的最优解决方案的接近程度。它决定了解决方案的适合程度。

我们为什么使用健身功能?

在遗传算法中,每个解一般被表示为一串二进制数,称为一个染色体。我们必须测试这些解决方案,并拿出最佳的解决方案来解决给定的问题。因此,需要给每个解决方案打分,以表明它与期望的解决方案的总体规格有多接近。该分数通过将适应度函数应用于测试或从测试解决方案获得的结果而生成。

适应度函数的一般要求

任何适应度函数都应满足以下要求。

  1. 应该清楚地定义适应度函数。读者应该能够清楚地理解健身分数是如何计算的。
  2. 应该有效地实现适应度函数。如果适应度函数成为算法的瓶颈,那么遗传算法的整体效率就会降低。
  3. 适应度函数应该定量地衡量给定的解决方案在解决问题时的适合程度。
  4. 适应度函数应该产生直观的结果。最佳/最差候选人应具有最佳/最差分值。

如何针对给定的问题想出一个适应度函数?

每个问题都有自己的适应度函数。应该使用的适应度函数取决于给定的问题。当使用遗传算法来公式化一个问题时,为给定的问题提出一个适应度函数是最难的部分。

没有硬性规定,特定的函数应该用于特定的问题。然而,对于某些类型的问题,数据科学家已经采用了某些函数。

通常,对于使用监督学习的分类任务,诸如欧几里德距离 e 和曼哈顿距离之类的误差度量已经被广泛用作适应度函数。

对于优化问题,诸如与问题域相关的一组计算参数之和的基本函数可以用作适应度函数。

我们来看几个例题和它们相关的适应度函数。

示例 1—生成序列

考虑下面给出的例子。我使用这个简单的例子主要是为了便于理解。

给定一组 5 个基因,它们可以保存二进制值 0 和 1 中的一个,我们必须得到全为 1 的序列。所以我们必须尽可能地增加 1 的数量。这可以认为是一个优化问题。因此,适应度函数被认为是基因组 中存在的 个 1。如果有五个 1,那么它有最大的适应性,解决了我们的问题。如果没有 1,那么 If 具有最小适应度。

下面给出的代码显示了如何实现适应度函数来计算适应度分数。

示例 2—时间表安排

Timetable for a week

可以使用遗传算法的一个非常著名的场景是制作时间表或时间表安排的过程。

假设您正试图为某一特定批次的大学课程制定一份每周时间表。我们必须安排课程,制定时间表,这样课程之间就不会有冲突。在这里,我们的任务是寻找最佳的时间表安排。

既然班级之间不应该有冲突,我们应该尽量减少有班级冲突的学生人数。你可以把适应度函数公式化为 有班级冲突的学生人数 的倒数。有班级冲突的学生人数越少,班级越适合。

示例 3-寻找满足给定约束的一组变量的值

考虑三个变量 x,y 和 z。问题是找到 x,y 和 z 的最佳值集合,使得它们的总值等于值 t。

x + y + z = t

我们必须减少 x+y+z 之和偏离 t,即|x + y + z — t|应该为零。因此,适应度函数可以被认为是|x + y + z - t| 的 逆。

Fitness function = 1/|x + y + z - t|

这些是应用遗传算法的几个例子,以及如何得出它们的适应度函数。为了便于理解,我使用了这些简单的例子。在对复杂的现实世界问题建模时,我们可能得不到如此简单的适应度函数。

最终注释

适应度函数必须能够衡量你的解决方案有多好。特别是,它应该能够处理生成的任何可用的解决方案,并且必须显示出改进它们的正确方法。

例如,除非答案是正确的,否则为零的适应度函数是不好的,因为它不能帮助您了解解决方案与正确答案有多接近。此外,随着解决方案变得更好而增加,但不识别最佳解决方案的适应度函数也不是那么好,因为您的群体将提高到某个点,然后停滞不前。

你必须处理这个问题,从不同的角度考虑,并考虑可以用什么样的函数来检验你的解决方案有多好。你想要一个函数,它对坏解给出低值,对好解给出高值。通过练习,你最终会更好地为给定的问题定义一个适应度函数。

希望你对如何为一个给定的使用遗传算法解决的问题定义一个适应度函数有了一个基本的概念。

感谢阅读…

如何在 AWS Lambda 上部署机器学习模型

原文:https://towardsdatascience.com/how-to-deploy-a-machine-learning-model-on-aws-lambda-24c36dcaed20?source=collection_archive---------0-----------------------

在本教程中,我将带您在 AWS Lambda 上部署一个机器学习模型。我们的模型也可以通过使用 Amazon API Gateway 的 API 进行访问。最终,我们将得到一个真正无服务器系统的完美配方。让我们直入主题吧。

将你的模型上传到亚马逊 S3

第一步是将你的模型上传到亚马逊 S3。如果你不熟悉亚马逊 S3,请访问此链接开始:http://docs . AWS . Amazon . com/amazons 3/latest/UG/uploadingobjectsintoamazons 3 . html

创建虚拟环境

当部署到 AWS Lambda 时,您需要上传一个包含代码和依赖项的虚拟环境。在项目文件夹中,编写以下几行。为了避免冲突,你应该而不是将你的虚拟环境命名为你的项目文件夹。

pip install virtualenv
virtualenv your_virtual_environment_name

要启动您的虚拟环境:

source your_virtual_environment_name/bin/activate

创建烧瓶 API

我们需要一个基本的 Flask 应用程序来处理我们的请求。该应用程序将从亚马逊 S3 加载我们的模型,并返回预测。首先创建一个名为 predictions.py 的文件,然后添加下面的代码。确保在进入下一步之前修改 BUCKET_NAMEMODEL_FILE_NAME

从亚马逊 S3 加载我们的模型

使用 Boto 库,我们加载之前保存在亚马逊 S3 上的模型,并保存到磁盘以备后用。

创建预测

最后但并非最不重要的是,我们准备得到一些预测。predict 方法接收发送给 API 的数据作为参数。您将需要添加一些代码来处理数据,以匹配您的模型。

最终文件应该是这样的

测试 API

  • 要运行您的应用程序,您必须创建一个环境变量来告诉 Flask 要执行哪些文件:
export FLASK_APP=predictions.py

在将代码部署到 AWS 之前,您应该确保代码在本地工作。

安装烧瓶,然后运行第二个命令来启动你的应用程序:

pip install Flask
flask run

打开终端,测试你的预测:

curl -d '{"payload": "Insert the data needed for your model to make predictions"}' http://127.0.0.1:5000/

当一切正常时,你可以进入下一步。

部署到 AWS Lambda

我们将使用一个名为 Zappa 的库,而不是手动创建和配置 AWS Lambda 和 API 网关。

Zappa 使在 AWS Lambda + API Gateway 上构建和部署所有 Python WSGI 应用程序变得非常容易。

重要提示:在部署之前,确保配置您的 AWS 凭证。更多信息请访问:http://docs . AWS . Amazon . com/CLI/latest/user guide/CLI-chap-getting-started . html

在您的虚拟环境中,安装所需的软件包:

pip install zappa sklearn boto numpy scipy

然后,初始化 Zappa 。当被问及 app 函数名时,写下 predictions.app. (或者,你的 Flask app +的名字。app)

zappa init

AWS Lambda 要求您的环境最大大小为 50mb,但我们的打包环境大约为 100mb。幸运的是,Lambda 可以从亚马逊 S3 加载代码,而不会有太大的性能损失(只有几毫秒)。

要激活此功能,您必须在 zappa_settings.json 中添加一个新行

"slim_handler": true

您现在可以开始部署了。在初始化 Zappa 时,使用带有您选择的环境名称的 deploy 命令。

zappa deploy your-environment-name

完成后,您将在最后一条消息中看到您的 API URL。它将看起来像“https://abcdefg . execute-API . us-east-1 . Amazon AWS . com/your-env-name”

您可以使用 cURL 测试您的部署:

curl -d '{"payload": "Insert the data needed for your model to make predictions"}' https://your-api-url.com/your-env

恭喜你!您已经在无服务器基础设施上部署了您的模型。

如果你喜欢这篇文章,请一定留下你的关注。我也有一些关于机器学习的很棒的文章即将发表,敬请关注!

你也可以在推特上联系到我。

如何使用 Docker 部署 MongoDB 副本集

原文:https://towardsdatascience.com/how-to-deploy-a-mongodb-replica-set-using-docker-6d0b9ac00e49?source=collection_archive---------0-----------------------

文章已更新

我写了一篇关于如何使用 DevOps 时尚风格部署 mongodb 集群的新文章,在这篇文章中,我使用了 Terraform、Ansible、Packer 和更多很酷的技术,我强烈建议您阅读它。

[## 以 DevOps 方式部署 MongoDB 副本集(作为代码的基础架构)

介绍

medium.com](https://medium.com/@cramirez92/deploy-a-mongodb-replica-set-in-a-devops-fashion-style-infrastructre-as-code-f631d7a0ad80)

本文将介绍如何使用 docker 设置带身份验证的 MongoDB 副本集。

本文中我们将使用的是:

  • MongoDB 3.4.1
  • Mac docker 1 . 12 . 6

副本集的体系结构

MongoDB Replica Set

用 docker 构建我们的副本集

Servers Distribution using Docker

在上图中,我们看到了用 docker 设置的复制结果。

#先决条件

  • 码头工人的基础知识
  • 对接机对接机安装完毕
  • mongoDB 中的基础知识
  • bash 脚本的基础知识

如果你在 Mac 或 Windows 上,考虑使用虚拟机。我将在 MacOS Sierra 上使用 VirtualBox 来运行我们的 mongoDB 实例。

#步骤 1 —创建我们的 3 台对接机

要创建 docker 机器,我们需要在终端中发出下一条命令:

$ docker-machine create -d virtualbox manager1

这个命令将创建一个名为 manager1 的机器,使用 virtualbox 作为我们的虚拟化提供者。

现在让我们创建两个左docker-machine

$ docker-machine create -d virtualbox worker1$ docker-machine create -d virtualbox worker2

要验证我们的机器是否已创建,让我们运行以下命令:

$ docker-machine ls// the result will be
NAME    ACTIVE   DRIVER     STATE     URL    
manager1   -   virtualbox   Running  tcp://192.168.99.100:2376           
worker1    -   virtualbox   Running  tcp://192.168.99.101:2376
worker2    -   virtualbox   Running  tcp://192.168.99.102:2376

#步骤 MongoDB 主节点的配置

现在我们有了三台机器,让我们将它放在第一台机器上,开始 mongodb 配置,让我们运行下一个命令:

$ eval `docker-machine env manager1`

在创建我们的 mongoDB 容器之前,有一个非常重要的主题已经在 docker 容器中围绕数据库持久性讨论了很久,为了实现这个挑战,我们将要做的是创建一个 docker 卷

$ docker volume create --name mongo_storage

现在让我们附加我们创建的卷来启动我们的第一个 mongo 容器并设置配置。

$ docker run --name mongoNode1 \
-v mongo_storage:/data \
-d mongo \
--smallfiles

接下来我们需要创建密钥文件。

密钥文件的内容作为副本集成员的共享密码。对于副本集的所有成员,密钥文件的内容必须相同。

$ openssl rand -base64 741 > mongo-keyfile
$ chmod 600 mongo-keyfile

接下来,让我们创建文件夹,用于保存 mongo_storage 卷中的数据、密钥文件和配置:

$ docker exec mongoNode1 bash -c 'mkdir /data/keyfile /data/admin'

下一步是创建一些管理员用户,让我们创建一个 admin.js 和一个 replica.js 文件,如下所示:

// admin.jsadmin = db.getSiblingDB("admin")// creation of the admin user
admin.createUser(
  {
    user: "cristian",
    pwd: "cristianPassword2017",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  }
)// let's authenticate to create the other user
db.getSiblingDB("admin").auth("cristian", "cristianPassword2017" )// creation of the replica set admin user
db.getSiblingDB("admin").createUser(
  {
    "user" : "replicaAdmin",
    "pwd" : "replicaAdminPassword2017",
    roles: [ { "role" : "clusterAdmin", "db" : "admin" } ]
  }
)
//replica.jsrs.initiate({
 _id: 'rs1',
 members: [{
  _id: 0, host: 'manager1:27017'
 }]
})

重要

密码应该是随机的、长的和复杂的,以确保系统安全并防止或延迟恶意访问。参见数据库用户角色了解内置角色以及与数据库管理操作相关的完整列表。

我们所做的直到知道:

  • 创建了 mongo_storage ,docker 卷。
  • 创建了 mongo-keyfile ,openssl 密钥生成。
  • 创建了 admin.js 文件,管理 mongoDB 的用户。
  • 创建了 replica.js 文件,以初始化副本集。

好了,让我们继续将文件传递到容器中。

$ docker cp admin.js mongoNode1:/data/admin/$ docker cp replica.js mongoNode1:/data/admin/$ docker cp mongo-keyfile mongoNode1:/data/keyfile/
// change folder owner to the user container$ docker exec mongoNode1 bash -c 'chown -R mongodb:mongodb /data'

我们所做的是将需要的文件传递给容器,然后/数据文件夹所有者 更改为容器用户,因为容器用户是需要访问该文件夹和文件的用户。

现在一切都已经设置好了,我们准备用副本集配置重新启动 mongod 实例。

在我们开始验证 mongo 容器之前,让我们创建一个env文件来设置我们的用户和密码。

MONGO_USER_ADMIN=cristian
MONGO_PASS_ADMIN=cristianPassword2017MONGO_REPLICA_ADMIN=replicaAdmin
MONGO_PASS_REPLICA=replicaAdminPassword2017

现在我们需要移除容器并开始一个新的。为什么?,因为我们需要提供副本集和身份验证参数,为此我们需要运行以下命令:

// first let's remove our container$ docker rm -f mongoNode1// now lets start our container with authentication $ docker run --name mongoNode1 --hostname mongoNode1 \
-v mongo_storage:/data \
--env-file env \
--add-host manager1:192.168.99.100 \
--add-host worker1:192.168.99.101 \
--add-host worker2:192.168.99.102 \
-p 27017:27017 \
-d mongo --smallfiles \
--keyFile /data/keyfile/mongo-keyfile \
--replSet 'rs1' \
--storageEngine wiredTiger \
--port 27017

这是怎么回事…🤔这似乎是对旗帜的滥用。

让我分两部分向你解释:

码头标志:

  1. --env-file读取一个 env 文件并在容器中设置environment变量。
  2. --add-host标志将条目添加到 docker 容器的/etc/hosts文件中,这样我们就可以使用主机名而不是 IP 地址。这里,我们正在映射我们之前创建的 3 台 docker-machine。

要更深入地理解 docker 运行命令、请阅读 docker 的文档。

蒙哥旗帜:

为了设置 mongo 副本集,我们需要各种 mongo 标志

  1. --keyFile这个标志是用来告诉 mongo】在哪里
  2. --replSet该标志用于设置副本集的名称。
  3. --storageEngine该标志用于设置 mongoDB 的引擎,不是必需的,因为 mongoDB 3.4.1 的默认引擎是 wiredTiger。

为了更深入地了解 mongo 副本集,阅读 MongoDB 文档,我也推荐mongou 大学的课程来学习关于这个主题的更多内容。

mongoNode1 容器的最后一步是启动副本集,我们将通过运行以下命令来完成这一步:

$ docker exec mongoNode1 bash -c 'mongo < /data/admin/replica.js'

您应该会看到类似这样的内容:

MongoDB shell version v3.4.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.1
{ "ok" : 1 }
bye

现在,让我们使用以下命令创建管理员用户:

$ docker exec mongoNode1 bash -c 'mongo < /data/admin/admin.js'

您应该会看到类似这样的内容:

MongoDB shell version v3.4.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.1
admin
Successfully added user: {
 "user" : "cristian",
 ...
Successfully added user: {
 "user" : "replicaAdmin",
...
bye

现在,要进入复制副本,请运行以下命令:

$ docker exec -it mongoNode1 bash -c 'mongo -u $MONGO_REPLICA_ADMIN -p $MONGO_PASS_REPLICA --eval "rs.status()" --authenticationDatabase "admin"'

你应该准备好看到这样的东西:

MongoDB shell version v3.4.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.1
{
 "set" : "rs1",
 ...
 "members" : [
  {
   "_id" : 0,
   "name" : "manager1:27017",
   ...
 "ok" : 1
}

#步骤 3——再添加 2 个 mongo 节点容器

现在一切都准备好了,让我们再启动两个节点,并将它们加入副本集。

要添加第一个节点,让我们切换到 worker1 docker 机器,如果您使用的是本地计算机,请运行以下命令:

eval `docker-machine env worker1`

如果你没有在本地运行,只要把你的终端指向下一个服务器。

现在,因为我们要重复我们为 mongoNode1 所做的几乎所有步骤,所以让我们编写一个脚本来运行我们所有的命令。

让我们创建一个名为 create-replica-set.sh 的文件,看看如何组成 main 函数:

function main {
  init_mongo_primary
  init_mongo_secondaries
  add_replicas manager1 mongoNode1
  check_status manager1 mongoNode1
}main

现在让我向您展示这个函数是如何组成:

初始化 MONGO 主函数

function init_mongo_primary {
  # [@params](http://twitter.com/params) name-of-keyfile
  createKeyFile mongo-keyfile

  # [@params](http://twitter.com/params) server container volume
  createMongoDBNode manager1 mongoNode1 mongo_storage

  # [@params](http://twitter.com/params) container
  init_replica_set mongoNode1
}

这个函数内部也有函数调用,没有新的功能,我们之前已经看到了所有的功能,让我来描述一下它的功能:

  1. 副本集验证创建密钥文件。****
  2. 创建一个 mongodb 容器,并接收 2 个参数:a)将要定位的服务器,b)容器的名称,docker 卷的名称,所有这些功能我们以前都见过。
  3. 最后,它将以与我们之前完全相同的步骤启动复制副本。

初始化 MONGO 辅助功能

function init_mongo_secondaries {
  # [@Params](http://twitter.com/Params) server container volume
  createMongoDBNode worker1 mongoNode1 mongo_storage
  createMongoDBNode worker2 mongoNode2 mongo_storage
}

这个函数的作用是为副本集创建另外两个 mongo 容器,并执行与 mongoNode1 相同的步骤,但这里我们不包括副本集实例化和管理员用户创建,因为这些都不是必需的,因为副本集将与副本集的所有节点共享数据库配置,稍后它们将被添加到主数据库。

添加副本功能

# [@params](http://twitter.com/params) server container
function add_replicas {
  echo '·· adding replicas >>>> '$1' ··' switchToServer $1

  for server in worker1 worker2
   do
    rs="rs.add('$server:27017')"
    add='mongo --eval "'$rs'" -u $MONGO_REPLICA_ADMIN 
         -p $MONGO_PASS_REPLICA --authenticationDatabase="admin"'
    sleep 2
    wait_for_databases $server
    docker exec -i $2 bash -c "$add"
  done
}

在这里,我们正在做的是,最后将另外 2 个 mongo 容器添加到副本集配置上的主数据库中,首先,我们循环通过剩余的机器来添加容器,在循环中,我们准备配置,然后我们检查容器是否准备好,我们通过调用函数wait_for_databases来完成,我们将机器作为参数传递给 check,然后我们在主数据库中执行配置,我们应该看到这样的消息:

MongoDB shell version v3.4.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.1
{ "ok" : 1 }

这意味着 mongo 容器被成功地添加到了副本中。

最后,我们用 main 中的最后一个函数检查副本集的状态:

# [@params](http://twitter.com/params) server container
function check_status {
  switchToServer $1
  cmd='mongo -u $MONGO_REPLICA_ADMIN -p $MONGO_PASS_REPLICA 
        --eval "rs.status()" --authenticationDatabase "admin"'
  docker exec -i $2 bash -c "$cmd"
}

既然我们已经看到了我们的自动化脚本的功能,并且我们知道将要这样做,那么是时候执行自动化 bash 脚本了,如下所示:

注意如果你已经完成了上面的所有步骤,你需要重置我们已经实现的所有东西,以避免任何冲突名称问题,重置配置在 github 存储库中有一个 reset.sh 文件

# and this how we can execute the script that will configure 
# everything for us.**$ bash < create-replica-set.sh**

如果一切设置正确,我们应该会看到来自 mongodb 的如下消息:

MongoDB shell version v3.4.1
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.1
{
 "set" : "rs1",
 ...
 },
 "members" : [
  {
   "_id" : 0,
   "name" : "manager1:27017",
   "health" : 1,
   "state" : 1,
   "stateStr" : "PRIMARY",
   ...
  },
  {
   "_id" : 1,
   "name" : "worker1:27017",
   "health" : 1,
   "state" : 2,
   "stateStr" : "SECONDARY",
   ...
  },
  {
   "_id" : 2,
   "name" : "worker2:27017",
   "health" : 1,
   "state" : 0,
   "stateStr" : "STARTUP",
   ...
  }
 ],
 "ok" : 1
}

正如您所看到的,每个容器现在都配置良好,需要注意的是,我们像以前一样使用 docker 中的--add-host标志,这将这些条目添加到 Docker 容器的/etc/hosts 文件中,因此我们可以使用主机名而不是 IP 地址。

两个节点从 mongoNode1 完成同步可能需要一分钟时间。

您可以通过查看日志来查看每个 mongo Docker 容器中发生了什么。您可以通过在任何 docker-machine 服务器上运行该命令来实现这一点。

$ docker logs -ft mongoContainerName

现在我们已经有了一个 MongoDB 副本集服务,让我们修改我们的用户,或者您可以创建另一个用户,并授予一些权限来对数据库进行 crud 操作,因此,仅出于说明的目的,这是一个不好的做法,让我为我们的 admin 用户添加一个超级角色。

# we are going to assign the root role to our admin user**# we enter to the container**
$ docker exec -it mongoNode1 bash -c 'mongo -u $MONGO_USER_ADMIN -p $MONGO_PASS_ADMIN --authenticationDatabase "admin"'**# Then we execute the following in the mongo shell**
# Mongo 3.4.1 shell
> use admin
> db.grantRolesToUser( "cristian", [ "root" , { role: "root", db: "admin" } ] )
>

现在他有了一个可以做任何东西的超级用户,所以让我们创建一个数据库并插入一些数据。

$ docker exec -it mongoNode1 bash -c 'mongo -u $MONGO_USER_ADMIN -p $MONGO_PASS_ADMIN --authenticationDatabase "admin"'# Mongo 3.4.1 shell
> use movies
> db.movies.insertMany([{
  id: '1',
  title: 'Assasins Creed',
  runtime: 115,
  format: 'IMAX',
  plot: 'Lorem ipsum dolor sit amet',
  releaseYear: 2017,
  releaseMonth: 1,
  releaseDay: 6
}, {
  id: '2',
  title: 'Aliados',
  runtime: 124,
  format: 'IMAX',
  plot: 'Lorem ipsum dolor sit amet',
  releaseYear: 2017,
  releaseMonth: 1,
  releaseDay: 13
}, {
  id: '3',
  title: 'xXx: Reactivado',
  runtime: 107,
  format: 'IMAX',
  plot: 'Lorem ipsum dolor sit amet',
  releaseYear: 2017,
  releaseMonth: 1,
  releaseDay: 20
}, {
  id: '4',
  title: 'Resident Evil: Capitulo Final',
  runtime: 107,
  format: 'IMAX',
  plot: 'Lorem ipsum dolor sit amet',
  releaseYear: 2017,
  releaseMonth: 1,
  releaseDay: 27
}, {
  id: '5',
  title: 'Moana: Un Mar de Aventuras',
  runtime: 114,
  format: 'IMAX',
  plot: 'Lorem ipsum dolor sit amet',
  releaseYear: 2016,
  releaseMonth: 12,
  releaseDay: 2
}])# inserted 5 documents
> 

现在我们有了一个电影数据库,其中的电影集合包含 5 部电影:d。

#是时候回顾一下了

我们所做的…

我们使用带有自动化脚本的 Docker、配置并启动带有认证的 MongoDB 副本集。****

在安全性方面,我们创建了:

  • 2 类用户,即管理数据库集群管理数据库。****
  • 我们创建一个密钥文件,并在启用身份验证的情况下启动副本。****

如果为数据库正确配置了访问控制,攻击者应该无法访问您的数据。查看我们的安全清单以帮助发现潜在的弱点。— @MongoDB Docs

如果我们想给我们的架构增加更多的安全性,我们可以用我们的 docker-machines 创建一个 Swarm 集群、,docker swarm 可以很好地处理网络通信,我们还可以在我们的容器中创建非根用户,我们可以在 mongoDB 中启用加密数据,但是这个主题不在本文的讨论范围之内。

#结论

现在我们有了一个工作的 MongoDB 副本集。您可以随时向该副本集添加节点。您甚至可以停止一个 mongo 容器或主 mongoNode1,并观察另一个 mongoNode 作为新的主 mongoNode。由于数据写入 docker 卷中,重启这些节点不成问题。数据将继续存在并完好无损地重新加入副本集。

对我们来说,一个好处是我们看到了如何用 bash 文件来自动化整个过程。

您面临的一个挑战是修改 bash 脚本并使其更加动态,因为该脚本非常依赖于本文规范,另一个挑战是向架构添加一个任意的 Mongo 节点。****

Github 知识库

要获得文章的完整脚本文件,您可以在下面的 repo 中查看。

**** [## GitHub-Crizstian/mongo-Replica-with-docker:如何使用 Docker 部署 MongoDB 副本集

如何使用 docker 部署一个 MongoDB 副本集

github.com](https://github.com/Crizstian/mongo-replica-with-docker)

进一步阅读

  • 部署带有密钥文件访问控制的副本集 — MongoDB Docs。
  • 向副本集添加成员 — MongoDB Docs。
  • MongoDB Docker Hub—Docker Docs。
  • 如何避免勒索您数据的恶意攻击
  • 如何在 ubuntu 16.04 上设置安全的 mongoDB 3.4 服务器****

我希望你喜欢这篇文章,我目前仍在探索 MongoDB 世界,所以我愿意接受反馈或贡献,如果你喜欢它,推荐给朋友,分享或再次阅读。

你可以在推特@ crami rez _ 92【https://twitter.com/cramirez_92】T3
关注我

直到下次😁👨🏼‍🎨👨🏻‍💻

如何将 Jupyter 笔记本部署为 Kubeflow ML 管道的组件(第 2 部分)

原文:https://towardsdatascience.com/how-to-deploy-jupyter-notebooks-as-components-of-a-kubeflow-ml-pipeline-part-2-b1df77f4e5b3?source=collection_archive---------10-----------------------

在 Kubernetes 集群上运行 Jupyter 笔记本的简单方法

在第 1 部分中,我向您展示了如何使用 Docker 组件创建和部署 Kubeflow ML 管道。在第 2 部分中,我将向您展示如何让 Jupyter 笔记本成为 Kubeflow ML 管道的一个组件。Docker 组件是为操作机器学习模型的人准备的,能够在任意硬件上运行 Jupyter 笔记本更适合数据科学家。

In this article, I show you an easy way to run your Jupyter notebook as a container in Kubernetes. (Photo by Cameron Venti on Unsplash)

我将假设您已经有了一个 Kubeflow 管道集群,并按照上一篇文章中的解释运行。通常,“ML 平台团队”(IT 部门的一部分)将管理供数据科学家团队使用的集群。

第一步。启动 JupyterHub

注意:当我写这篇文章时,您必须在集群本身上运行笔记本。不过,现在更好的方法是使用人工智能平台笔记本,并远程向集群提交代码。遵循本自述文件中的说明,确保启动 TensorFlow 1.10 笔记本电脑虚拟机。跳过这一步,从第 2 步开始。

从 Kubeflow pipelines 用户界面(http://localhost:8085/pipeline,如果您遵循了上一篇文章中的说明),单击笔记本的链接:

Click on the notebooks link from Kubeflow pipelines to start JupyterHub on the cluster and start working with notebooks

如果这是第一次,这将提示您启动 JupyterHub。使用您的 GCP 用户名/密码登录。然后,选择所需的 Tensorflow 版本:

Choose the version of TensorFlow

我在一个 cpu 上选择了 TensorFlow v1.10。

第二步。克隆 git repo

然后,打开一个终端窗口,git 克隆我的 repo:

git clone https://github.com/GoogleCloudPlatform/data-science-on-gcp

切换回 Jupyter 笔记本列表,导航到 data-science-on-GCP/updates/cloud ml,打开 flights_model.ipynb 。

第三步。用张量流预测航班延误

实际的 TensorFlow 代码(参见这里的完整笔记本: flights_model.ipynb )并不重要,但是我希望您注意一些事情。一个是,我开发这款笔记本电脑时,大部分时间都是在急切模式下进行的,以便于调试:

if EAGER_MODE:
    dataset = load_dataset(TRAIN_DATA_PATTERN)
    for n, data in enumerate(dataset):
      numpy_data = {k: v.numpy() for k, v in data.items()} # .numpy() works only in eager mode
      print(numpy_data)
      if n>3: break

然后,我对模型进行了几个步骤的训练,并指定了更多的步骤(如果“不在开发模式中”:

num_steps = 10 if DEVELOP_MODE else (1000000 // train_batch_size)

最后,我将其作为 web 服务部署到 Cloud ML Engine:

gcloud ml-engine versions create ${MODEL_VERSION} --model ${MODEL_NAME} --origin ${MODEL_LOCATION} --runtime-version 1.10

并确保我可以将 JSON 发送到已部署的模型:

{"dep_delay": 14.0, "taxiout": 13.0, "distance": 319.0, "avg_dep_delay": 25.863039, "avg_arr_delay": 27.0, "carrier": "WN", "dep_lat": 32.84722, "dep_lon": -96.85167, "arr_lat": 31.9425, "arr_lon": -102.20194, "origin": "DAL", "dest": "MAF"}
{"dep_delay": -9.0, "taxiout": 21.0, "distance": 301.0, "avg_dep_delay": 41.050808, "avg_arr_delay": -7.0, "carrier": "EV", "dep_lat": 29.984444, "dep_lon": -95.34139, "arr_lat": 27.544167, "arr_lon": -99.46167, "origin": "IAH", "dest": "LRD"}

为了返回,对于每个实例,航班将晚点的概率。

第四步。将笔记本电脑部署为组件

所以,我有一个完全成熟的笔记本电脑,可以完成一些 ML 工作流程。我能把它作为 Kubeflow 管道的一部分来执行吗?回想一下 第 1 部分 中的内容,一个组件所需要的只是一个自包含的容器,它接受几个参数并将输出写到文件中,或者在 Kubeflow 集群上,或者在云存储上。

为了将 flights_model 笔记本部署为一个组件:

  • 我的笔记本顶部有一个单元格,它的标签是“参数”。在这个单元格中,我定义了我想要用来重新执行笔记本的任何变量。特别是,我设置了一个名为 DEVELOP_MODE 的变量。在开发模式下,我将读取小数据集;在非开发模式下,我将在完整数据集上进行训练。因为我希望您能够轻松地更改它们,所以我还将 PROJECT(要计费)和 BUCKET(要存储输出)作为参数。
  • 然后,我构建一个能够执行我的笔记本的 Docker 映像。为了执行一个笔记本,我将使用 Python 包 papermill。我的笔记本用的是 Python3,gcloud,tensorflow。所以我的 docker 文件捕获了docker 文件中的所有依赖项
FROM **google/cloud**-sdk:latestRUN apt-get update -y && apt-get install --no-install-recommends -y -q ca-certificates **python3-dev** python3-setuptools python3-pipRUN python3 -m pip install **tensorflow==1.10 jupyter papermill**COPY run_notebook.sh ./ENTRYPOINT ["bash", "./run_notebook.sh"]
  • Docker 映像的入口点是 run_notebook.sh ,它使用 papermill 来执行笔记本:
gsutil cp $IN_NB_GCS  input.ipynb
gsutil cp $PARAMS_GCS params.yaml
**papermill input.ipynb output.ipynb -f params.yaml --log-output**
gsutil cp output.ipynb $OUT_NB_GCS
  • 实际上,该脚本将要运行的笔记本从 Google 云存储复制到 Kubeflow pod,用 papermill 运行笔记本,并将结果输出复制回 Google 云存储。
  • 但是 params.yaml?params.yaml 是什么?这些是笔记本电脑的可配置参数。例如,它可以是:
---
BUCKET: cloud-training-demos-ml
PROJECT: cloud-training-demos
DEVELOP_MODE: False
  • 就是这样!当这个 Docker 映像运行时,它将执行提供的笔记本并复制输出笔记本(标绘了图形,训练了模型等)。)到 GCS。

第五步。作为管道的一部分启动笔记本组件

将笔记本作为管道中的一个步骤来运行的意义在于,它可以在其他管道中进行编排和重用。但是,为了向您展示如何做到这一点,您应该这样创建一个仅执行该笔记本的管道:

import kfp.components as comp
import kfp.dsl as dsl# a single-op pipeline that runs the flights pipeline on the pod
[@dsl](http://twitter.com/dsl).pipeline(
   name='FlightsPipeline',
   description='Trains, deploys flights model'
)
def flights_pipeline(
   inputnb=dsl.PipelineParam('inputnb'),
   outputnb=dsl.PipelineParam('outputnb'),
   params=dsl.PipelineParam('params')
):
    notebookop = dsl.ContainerOp(
      name='flightsmodel',
      image='gcr.io/cloud-training-demos/**submitnotebook**:latest',
      arguments=[
        **inputnb,
        outputnb,
        params**
      ]
    )

没什么特别的——我正在创建一个容器,告诉它使用我的图像,它有 TensorFlow、papermill 等。并给它输入和输出笔记本和参数。随着管道的运行,日志流传输到管道日志,并将显示在 Stackdriver 中:

As the pipeline executes, the notebook cells’ outputs get streamed to Stackdriver

在我的 GitHub repo 中,创建和部署管道显示在 launcher.ipynb 中。

尝试一下

如果您还没有这样做,请阅读并浏览如何使用 Docker 映像 创建和部署 Kubeflow ML 管道的第 1 部分

尝试这篇关于如何在 Kubeflow 管道中部署 Jupyter 笔记本作为组件的文章:

  1. 按照第 1 部分中的说明启动一个集群
  2. 在集群上,打开 flights_model.ipynb ,将项目和 BUCKET 更改为您自己的东西,并运行笔记本,确保它可以工作。
  3. 打开 launcher.ipynb 并完成运行 flights_model.ipynb 和作为 Kubeflow 管道组件的步骤。

启动器笔记本还包括在深度学习虚拟机上启动 flights_model 笔记本的能力,但现在忽略它——我将在本系列的第 3 部分中介绍它。

笔记本可以是可组合性和可重用性的一个单元——但是为了实现这一点,你必须小心编写小的、单一用途的笔记本。我在这篇文章中所做的——一个巨大的单片笔记本——并不是一个好主意。权衡的结果是,如果您使用较小的笔记本,依赖性跟踪会变得困难。

什么时候用什么

  • 如果你是一个小团队,并且没有人为你维护像 Kubeflow clusters 这样的 ML 基础设施,那么使用深度学习 VM 进行开发和自动化。我将在本系列的第 3 部分中讨论这个问题。
  • 如果您在一个大型组织中工作,其中有一个独立的 ML 平台团队管理您的 ML 基础设施(即 Kubeflow 集群),本文(第 2 部分)将向您展示如何在 Jupyter 笔记本中开发并部署到 Kubeflow 管道。(如果您向 IT 团队展示这篇文章,他们可能会帮助您完成 Docker 部分)。
  • 虽然笔记本会帮助你变得敏捷,但是你也会积累大量的技术债务。单体笔记本很难重用,单一用途的笔记本很难跟踪依赖性。第二,即使你的日志会转到 GCP 的日志平台(Stackdriver),它们也可能是非结构化的单元输出。这使得很难监控管道和对故障做出反应。因此,计划将成熟的代码和模型从笔记本转移到单独的管道组件中,每个组件都是一个容器。这是我在 第一部 里给你看的。

换句话说,对小团队使用深度学习 VM,对实验工作使用 Jupyter 组件,对成熟模型使用容器操作

如何用 TensorFlow 部署机器学习模型?第 1 部分—准备好您的模型以供使用。

原文:https://towardsdatascience.com/how-to-deploy-machine-learning-models-with-tensorflow-part-1-make-your-model-ready-for-serving-776a14ec3198?source=collection_archive---------0-----------------------

在完成 Udacity 的深度学习基础课程后,我有一个大问题——我如何部署训练好的模型并对新的数据样本进行预测?幸运的是,TensorFlow 是为生产开发的,它为模型部署提供了解决方案— TensorFlow 服务。基本上,有三个步骤——导出你的服务模型,用你的模型创建一个 Docker 容器,并用 Kubernetes 将其部署到云平台,即谷歌云或亚马逊 AWS。在本文中,我主要关注第一部分——导出服务模型。

动机和工具

在 Udacity 的课程中,我总是问自己——我有我的模型,我可以在 Jupyter 笔记本上运行它并看到结果,但我能用它做什么呢?其他人如何使用它?

作为一名软件工程师,我对管道感兴趣:创建模型->在本地测试它->创建 web 服务来服务客户端请求->创建包含我的 web 服务的部署容器->测试容器->将其投入生产。我的问题的答案是:

  • 用于模型创建的 TensorFlow
  • 集装箱码头工人
  • 为模型托管服务的 TensorFlow
  • 用于生产部署的 Kubernetes

张量流

TensorFlow 是一个开源库,用于开发机器学习,尤其是深度学习模型。它是由 Google 创建和支持的,不仅面向学术界,也面向产品开发。

码头工人

Docker 是一个非常流行的容器化引擎,它提供了一种便捷的方式来将所有依赖项打包在一起,以便部署在本地或云中。文档非常全面,我鼓励你查看它的细节。

张量流服务

TensorFlow Serving,顾名思义,托管模型并提供对它的远程访问。TensorFlow Serving 有关于其架构的良好文档和有用的教程。不幸的是,他们使用准备好的例子,并得到一点解释,你需要做什么来为你自己的模型服务。

库伯内特斯

Kubernetes 是一个开源软件,也是由谷歌开发的,它提供容器编排,允许你自动水平扩展、服务发现、负载平衡等等。简而言之,它自动化了云中 web 服务的管理。

目的

作为一个例子,我采用了一个用于半监督学习的 GAN 模型,它在 Udacity 深度学习基础课程中讲授。我的意图是:

  • 在街景门牌号数据集上训练 GAN 模型进行半监督学习
  • 使用 GAN 鉴别器进行门牌号预测。作为输出,我希望有 10 个分数,对应于从 0 到 9 的数字。
  • 让 TensorFlow 在 Docker 容器中为我的模型提供服务
  • 创建一个客户端来请求数字图像的分数
  • 将模型部署到云中

模型准备

基于 Jupyter 笔记本,我将功能放入独立的 Python 文件中,测试保存的模型,实现模型导出和服务请求的客户端。一般来说,基本代码保持不变。你可以在我的 GitHub 库中找到实现细节。

主要步骤是:

  • 训练模型保存磁盘上的检查点
  • 加载保存的模型并测试其工作是否正常
  • 将模型导出为 Protobuf 格式(详情如下)
  • 创建客户端来发布请求(细节在下一部分)

对于使用 TensorFlow 创建深度学习模型的任何人来说,前两步都非常容易,我不想在这里详细介绍。但是最后两步对我来说很新,我花了一些时间来理解它是如何工作的以及需要什么。

TensorFlow 服务。这是什么?

TensorFlow Serving 实现了一个运行机器学习模型的服务器,并提供对它们的远程访问。常见的任务是对提供的数据(例如图像)进行预测和分类。

几个技术亮点:

  • 服务器实现了一个 gRPC 接口,所以您不能从浏览器发出请求。相反,我们需要创建一个客户机,它可以通过 gRPC 进行通信
  • TensorFlow Serving 已经提供了对存储为 Protobuf 的模型的操作
  • 您可以创建自己的实现来处理以其他格式存储的模型

我没有创建自己的实现,所以我需要将我的模型导出到 Protobuf 中。

原蟾蜍

协议缓冲区(或 Protobuf)允许高效的数据序列化。它是一个开源软件,是由谷歌开发的

将模型导出到 Protobuf 中

TensorFlow Serving 提供了 SavedModelBuild 类将模型保存为 Protobuf。这里描述的还不错。

我的 GAN 模型接受形状为【batch _ num,width,height,channels】的图像张量,其中批次数量为 1(您一次只能预测一个图像),宽度和高度为 32 像素,图像通道数量为 3。输入图像必须缩放,以使每个像素在[-1,1]的范围内,而不是在[0,255]的范围内。

另一方面,被服务的模型必须接受 JPEG 图像作为输入,因此为了服务,我需要注入层来将 JPEG 转换成所需的图像张量。

首先,我实现了图像转换。对我来说有点棘手。

serialized_tf_example = tf.placeholder(
                            tf.string, name=’input_image’) feature_configs = { ‘image/encoded’: tf.FixedLenFeature(
                                         shape=[], 
                                         dtype=tf.string), } tf_example = tf.parse_example(serialized_tf_example, feature_configs) jpegs = tf_example[‘image/encoded’] images = tf.map_fn(preprocess_image, jpegs, dtype=tf.float32) images = tf.squeeze(images, [0])
# now the image shape is (1, ?, ?, 3)

基本上,您需要一个序列化传入图像的占位符、一个特性配置(字典名称到特性)和特性类型,其中您列出了预期的输入(在我的例子中是 JPEG 的图像/编码的)。然后解析序列化的示例并从中提取 JPEG。最后一步是将 JPEG 转换成所需的图像张量。实现细节见 myGitHub(预处理 _ 图像方法)。

然后,我可以使用该图像张量作为我的 GAN 模型的输入,创建一个会话对象并加载保存的检查点。

......
net = GAN(images, z_size, learning_rate, drop_rate=0.)
......saver = tf.train.Saver() with tf.Session() as sess: 
    # Restore the model from last checkpoints 
    ckpt = tf.train.get_checkpoint_state(FLAGS.checkpoint_dir)    
    saver.restore(sess, ckpt.model_checkpoint_path)
......

对我来说,下一个挑战是理解如何用提供的 SavedModelBuilder 将恢复的模型转换成 Protobuf。

builder = tf.saved_model.builder.SavedModelBuilder(export_path)

你必须创建一个所谓的带有输入、输出和方法名的签名(例如分类或预测)。TensorFlow 提供了一个方法TF . saved _ model . utils . build _ tensor _ info来创建张量信息。我用它来定义输入和输出(在我的例子中是分数)。

predict_tensor_inputs_info = \
    tf.saved_model.utils.build_tensor_info(jpegs) predict_tensor_scores_info = \
    tf.saved_model.utils.build_tensor_info(net.discriminator_out)

现在我准备好创建签名了。

prediction_signature = (
    tf.saved_model.signature_def_utils.build_signature_def( 
        inputs={‘images’: predict_tensor_inputs_info}, 
        outputs={‘scores’: predict_tensor_scores_info},
        method_name=\
            tf.saved_model.signature_constants.PREDICT_METHOD_NAME)

【图像】【分数】是预定义的名称,您必须在输入和输出词典中使用它们。

在教程中,TensorFlow 团队创建了两个签名——一个用于分类,一个用于预测。我不想要任何分类结果,所以预测签名对我来说就足够了。

最后一步—保存模型。

legacy_init_op = tf.group(tf.tables_initializer(), 
                          name=’legacy_init_op’) builder.add_meta_graph_and_variables(
    sess, 
    [tf.saved_model.tag_constants.SERVING], 
    signature_def_map={ ‘predict_images’: prediction_signature }, 
    legacy_init_op=legacy_init_op) builder.save()

这非常简单,现在您已经将模型存储为 Protobuf。导出文件夹的结构应该类似于:

  • variables 文件夹,带有variables . data-XXX-of-yyyvariables.index
  • saved_model.pb 文件

第一部分工作已经完成——模型被成功导出为 Protobuf。

把它们放在一起

环境

我在以下环境中进行了开发和测试:

  • 基于 GPU 的电脑(英伟达 GeForce GTX 1060 6 GB)
  • Ubuntu 16.04
  • 蟒蛇
  • Python 3.5
  • 张量流 1.8

你自己试试

下面是您自己尝试时需要执行的步骤。

  • 克隆源
cd ~git clone [https://github.com/Vetal1977/tf_serving_example.git](https://github.com/Vetal1977/tf_serving_example.git)cd tf_serving_example
  • 训练模型
python svnh_semi_supervised_model_train.py

下载列车和测试街景门牌号码数据集和另一个 ca 大约需要 5-10 分钟。20 分钟训练模型(在我的环境下)。

  • 检查您是否保存了模型
ls ./checkpoints

您应该会看到数据、索引和元数据文件。

  • 将模型导出到 Protobuf,由 TensorFlow 提供服务
python svnh_semi_supervised_model_saved.py --checkpoint-dir=./checkpoints --output_dir=./gan-export --model-version=1

应该打印出以下内容

Successfully exported GAN model version '1' into './gan-export'

如果你打字

ls ./gan-export/1

你应该得到变量文件夹和 saved_model.pb 文件。

而不是结论

可能这听起来很简单,但我需要几个小时来理解 TensorFlow 如何为模型服务。我有什么输入和输出。我如何注册他们让 TensorFlow 知道,什么和如何服务。

在下一部分中,我将创建一个 Docker 容器,将我的模型放入其中,并创建一个客户端来发出请求。

如何用 TensorFlow 部署机器学习模型?第 2 部分—容器化!

原文:https://towardsdatascience.com/how-to-deploy-machine-learning-models-with-tensorflow-part-2-containerize-it-db0ad7ca35a7?source=collection_archive---------0-----------------------

如第 1 部分所述,我想将我的深度学习模型部署到生产中。我已经展示了如何为 TensorFlow 服务准备模型。我们将 GAN 模型作为 Protobuf 导出,现在它已经可以托管了。

可部署人工制品的步骤

TensorFlow 服务实现了一个处理传入请求并将其转发给模型的服务器。这个服务器可能运行在某个地方,很可能是在你的云提供商(比如 Amazon AWS,Google Cloud Platform,Microsoft Azure)那里,对全世界开放。

如今,将这样的服务器及其所有依赖项打包到一个包中,并作为一个整体进行配置和部署是很常见的。

为此,您可以创建一个虚拟机映像,但是它非常笨重,我不建议将其用于服务部署。(尽管预配置的虚拟机对于为开发人员提供工作环境非常有用)。

通常我们使用容器来创建可部署的工件。然后我们可以在任何地方部署它们——本地、内部网、云中。这样的容器将包括您的服务及其所有依赖项。你只需要在操作系统上安装一个运行你的容器的薄层。

最流行的容器平台是 Docker 。我们需要创建一个 Docker 映像,在该映像上创建一个容器并运行它。首先—在我们的本地操作系统中。

与我们的情况相对应——我们应该测试容器是否运行,TensorFlow 提供的服务器是否成功启动,接受对我们模型的请求并对它们做出响应。

在本地获取码头工人

在本地,我们应该安装 Docker 来运行我们的容器。我参考官方文档,因为我无法更好地描述安装程序。

提示:如果你在 Ubuntu 下,很可能你必须对每个 Docker 命令使用 sudo 。我强烈建议采取以下措施来避免这种情况:

  • 如果 docker 组不存在,添加该组
  • 将连接的用户 $USER 添加到 docker
sudo groupadd docker
sudo usermod -aG docker $USER
  • 重启你的电脑

现在你应该可以不用 T21 就能执行 Docker 命令了。例如

docker version

应该显示系统和版本信息,而没有任何关于缺少权限的错误。

为 TensorFlow 服务创建 Docker 映像并运行容器

TensorFlow 服务提供 Docker 映像,因此我们可以克隆存储库并使用它们。

获取 TensorFlow 服务

这非常简单——只需克隆存储库:

cd ~git clone https://github.com/tensorflow/serving.git

构建 Docker 映像并运行容器

Docker 映像的配置是通过 Docker 文件定义的。TensorFlow 服务提供了其中的两种—一种用于 CPU 构建,一种用于 GPU 构建。两者都可以在serving/tensor flow _ serving/tools/docker下找到:

  • 用于 CPU 构建的 Dockerfile.devel
  • 用于 gpu 构建的 Dockerfile.devel-gpu

英伟达 Docker

如果你的机器上有 NVidia GPU 并安装了 CUDA 和 cuDNN 库,我强烈建议创建一个支持 GPU 的 Docker 容器。之前要安装 nvidia-docker 才能正常工作。这里的简单明了,描述得很好。在我的例子中,我使用了以下命令序列:

curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \
  sudo apt-key add -distribution=$(. /etc/os-release;echo $ID$VERSION_ID)curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-docker.listsudo apt-get update
sudo apt-get install nvidia-docker2
sudo pkill -SIGHUP dockerd

提示:由于我使用了 GPU Dockerfile,所以在接下来的步骤中我会参考它。使用 CPU Dockerfile,您可以以同样的方式工作。唯一的区别是,你不需要通过运行容器 nvidia-dockerruntime=nvidia 标志。

让我们创建我们的 Docker 图像:

cd serving
docker build --pull -t $USER/tensorflow-serving-devel-gpu -f tensorflow_serving/tools/docker/Dockerfile.devel-gpu .

下载依赖项和构建映像大约需要一个小时或更长时间…现在我们可以运行 Docker 容器:

docker run --runtime=nvidia --name=tf_container_gpu -it $USER/tensorflow-serving-devel-gpu

如果一切正常,恭喜你!您现在位于 TensorFlow 服务 Docker 容器的外壳中。

提示:当您用退出命令离开集装箱外壳时,集装箱停止。要再次启动它,请执行:

docker start -i tf_container_gpu

不要移除容器!否则,您所做的更改将会消失。另外,请注意,我们在这里不需要 runtime=nvidia 参数。

Docker 容器中包含所有必要的组件,如 Python、Bazel 等。已安装,TensorFlow 服务器已准备就绪。如果我们执行

tensorflow_model_server

在 Shell 内部运行 Docker 容器,我们应该看到使用信息。

部署模型

首先,让我们创建一个工作目录。在运行容器的外壳中执行:

mkdir serving

接下来,我们将导出的模型(参见第 1 部分)复制到 TensorFlow 容器中。从您的 PC 上的 Shell:

cd <path to GAN project>
docker cp ./gan-export tf_container_gpu:/serving

您应该将导出的模型文件夹放在容器中。从它的外壳来看:

cd /serving
ls ./gan-export/1

你应该看到变量文件夹和 saved_model.pb 文件。

开始上菜

万岁!我们已经准备好通过 TensorFlow 托管我们的模型:-)

tensorflow_model_server --port=9000 --model_name=gan --model_base_path=/serving/gan-export &> gan_log &

如果你检查日志…

cat gan_log

…您应该在最后一个字符串中看到类似这样的内容:

I tensorflow_serving/model_servers/main.cc:298] Running ModelServer at 0.0.0.0:9000 …

断点

我们走了很多步,但都很简单明了。他们需要大量的时间,因为要从源代码下载和构建。

所以我们在 Docker 容器中开始我们的模型,它在本地运行。但是我们可以保存容器和我们的更改,并在以后部署它,例如,部署到云中。在此之前,我们希望确保我们的模型接受请求和对请求的响应。我们的模型需要一个客户!

创建客户端

TensorFlow 服务基于 gRPC 协议,因此您确实需要创建一个能够通过它进行“对话”的客户端。在教程中,他们使用了一个构建在 Docker 容器中的示例客户端。但是我想要一个在我的 PC 上运行的客户端,它可以向 TensorFlow 容器中托管的模型发出请求。

提示:我们在 PC 上执行的所有后续步骤(不在 Docker 容器中!).请记住,我们已经克隆了 TensorFlow 服务存储库。

其他 Python 库

首先,我们需要 Python 环境中的 gRPC 库。我从 PyPI 安装了它们:

pip install grpcio grpcio-tools

张量流预测服务

对于我们的客户,我们需要 TensorFlow 服务 API。问题— API 是以 Protobuf 的形式提供的(可以在serving/tensor flow _ serving/APIs)下找到)。如果我们想在客户机中使用它们,我们需要从这些 Protobuf 中生成 Python 文件。我这样做了,并将生成的文件放入我的存储库。如果你愿意,你可以自己做(虽然有点棘手):

# 1
cd <tensorflow serving source folder># 2
git clone [https://github.com/tensorflow/tensorflow.git](https://github.com/tensorflow/tensorflow.git)# 3
python -m grpc.tools.protoc ./tensorflow_serving/apis/*.proto --python_out=<path to GAN project> --grpc_python_out=<path to GAN project> --proto_path=.

步骤的简短说明:

  1. 更改到包含 TensorFlow 服务源的文件夹
  2. TensorFlow Serving 使用核心框架 Protobuf 的(Serving/tensor flow/tensor flow/core/framework)。获得它们最简单的方法是从 Git 存储库中克隆 TensorFlow 框架
  3. 这里我们从 Protobuf 为我们的客户生成 Python 文件

客户

我已经实现了客户端,这比上面所有准备工作都要简单:-)这里您只需使用 gRPC 和 TensorFlow 服务 API 来发出请求。最有趣的部分是:

# Send request 
with open(FLAGS.image, ‘rb’) as f: 
    # 1
    data = f.read() # 2
    request = predict_pb2.PredictRequest()    # 3    
    request.model_spec.name = 'gan' 
    request.model_spec.signature_name = 'predict_images' 
    request.inputs['images'].CopyFrom( 
        tf.contrib.util.make_tensor_proto(
            data, shape=[1])) # 4
    result = stub.Predict(request, 60.0)
  1. 打开(JPEG)文件
  2. 创建预测请求对象
  3. 初始化对我们的 GAN 模型的预测请求。在这里,我们指定:模型的名称(它必须与我们启动 tensorflow_model_server 时的 model_name 参数相匹配)、签名名称(我们只有 predict_images 和数据(在我们的例子中是 JPEG 图像)
  4. 服务器上的呼叫预测。

呼叫预测

现在我们可以调用运行在 Docker 容器中的模型。获取容器 IP 地址:

docker network inspect bridge | grep IPv4Address

我的情况是 172.17.0.2。

接下来,我们需要测试图像——我从街景门牌号码测试集中提取了几张图像(以 MATLAB 格式提供),并将它们放在这里处。现在—发出客户端请求:

cd <path to GAN project>
python svnh_semi_supervised_client.py --server=172.17.0.2:9000 --image=./svnh_test_images/image_3.jpg

提示:有时候,Docker 容器的 IP 地址不起作用。在这种情况下,我们可以使用0 . 0 . 0localhost 。如果你有问题,试试这些。例如:

python svnh_semi_supervised_client.py --server=localhost:9000 ...

您应该会看到类似这样的内容:

outputs {
  key: “scores”
  value {
    dtype: DT_FLOAT
    tensor_shape {
      dim {
        size: 1
      }
      dim {
        size: 10
      }
    }
    float_val: 8.630897802584857e-17
    float_val: 1.219293777054986e-09
    float_val: 6.613714575998131e-10
    float_val: 1.5203355241411032e-09
    **float_val: 0.9999998807907104**
    float_val: 9.070973139291283e-12
    float_val: 1.5690838628401593e-09
    float_val: 9.12262028080068e-17
    float_val: 1.0587883991775016e-07
    float_val: 1.0302327879685436e-08
  }
}

我用粗体标记了最高分,它实际上对应于样本图像中的“4”(数字从 0 到 9) :-)我的 GAN 模型相对简单,精确度约为 68%。

而不是结论

在第二部分中,我们创建了 TensorFlow 服务容器,将 GAN 模型复制到其中,并启动公开我们模型的服务器。为了进行测试,我们创建了 gRPC 客户端,可以在 PC 上本地运行,并向我们的模型发出请求。

在下一部中,我们将把我们的模型公之于众!

如何用 TensorFlow 部署机器学习模型?第 3 部分—进入云!

原文:https://towardsdatascience.com/how-to-deploy-machine-learning-models-with-tensorflow-part-3-into-the-cloud-7115ff774bb6?source=collection_archive---------1-----------------------

在第 1 部分和第 2 部分中,我们创建了一个 GAN 模型来预测街景门牌号码,并在 Docker 容器中使用 TensorFlow 本地服务来托管它。现在是将它引入云的时候了!

动机

当您实现一个 web 服务(比如预测服务)并希望其他人使用它时,您可以在云托管提供商处发布它。通常,您不想关心诸如服务的可用性、可伸缩性之类的事情;你想专注于开发你的模型和算法。

如今,你有大量的云平台提供商可供选择。最突出的是亚马逊 AWS、微软 Azure、谷歌云平台、IBM Bluemix。一旦服务被部署到他们的服务器上,他们就提供资源并负责服务的可用性。

第二个重要任务是自动化。您希望自动部署、扩展和管理您的服务。就我个人而言,我希望每次单击鼠标或运行一个简单的脚本就能部署,我希望我的服务在收到更多请求时能自动扩展,我希望在崩溃时无需手动干预就能恢复,等等。这里一个工具 Kubernetes 开始发挥作用。

Kubernetes 是一个开源系统,用于自动化部署、扩展和管理容器化的应用程序。

Kubernetes 是由 Google 开发和支持的。所以你绝对可以依赖它。上面列出的云提供商有内置的 it 支持。因此,我们可以相对容易地将部署设置到云中。

云提供商选择

对于这篇文章,我使用微软 Azure。主要是因为一个原因——他们提供 30 天的试用期和 200 美元的信用额度。

我也看了其他供应商。在 AWS,我没有找到免费获得小型 Kubernetes 集群的可能性。在谷歌你可以免费测试他们的云平台,但是他们用“账户类型=业务”吓到我了(我只是想给自己一个小的测试环境)。IBM Bluemix 不是很直观。

所以我选择了微软 Azure,他们也有很好的用户界面:-)

准备 Docker 图像

在我们进入 Kubernetes 之前,我们需要保存 Docker 容器以及我们所做的所有更改,作为一个图像。首先,我们需要容器 ID:

docker ps --all

您将获得所有 Docker 容器的列表——选择您已经创建的容器。例如:

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
**35027f92f2f8** <your user name>/tensorflow-serving-devel "/bin/bash" 4 days ago Exited (0) 4 days ago tf_container_cpu

我用粗体字标出了我们需要的 ID。

提示:由于我不想在云中使用昂贵的 GPU 驱动的虚拟机,我选择了 TensorFlow 服务 CPU Docker 容器。

现在我们可以从容器中创建 Docker 图像:

docker commit **35027f92f2f8** $USER/tensorflow-serving-gan:v1.0

如果你查看图片列表( docker images 命令),你应该会发现一个新创建的图片 <你的用户名> /tensorflow-serving-gan 标签为 v1.0 。图像是近似的。比原来的大 5 倍,因为我们下载并制作了很多新东西。

库伯内特。重要概念简介

我鼓励你查看 Kubernetes 的文档,了解它的功能、概念和教程。在这里,我只是给了一个非常粗略的想法,如何与它合作。

我们将 Docker 映像部署到 Kubernetes 集群中。Kubernetes 集群至少由一个主节点和一个或多个工作节点组成。

结节

节点是 Kubernetes 集群中的一个工作机(虚拟机或裸机)。它由主组件管理,拥有运行 Pods 的所有服务。这些服务包括,例如,Docker,这对我们很重要。

我们将创建一个主节点和一个工作节点。主节点不运行任何 Pod,它的职责是集群管理。

Pod

Pod 是由一个或多个容器、这些容器的共享存储以及关于如何运行容器的选项组成的组。所以 Pod 是逻辑相关容器的逻辑主机。

在我们的 Pod 中,我们只有一个 Docker 容器,即我们的 TensorFlow GAN 服务。我们将创建两个 pod,尽管它们将在同一个节点上运行。

服务

豆荚是会死的。他们出生和死亡。特别是复制控制器动态地创建和销毁 pod。虽然每个 Pod 都有自己的 IP 地址,但是这些 IP 地址并不可靠。因此,如果我们有需要相互通信的 pod(例如前端到后端),或者我们想要从外部访问一些 pod(在我们的例子中),那么我们就有问题了。

Kubernetes 服务解决。这是一个抽象概念,它定义了一组逻辑单元和访问它们的策略。在我们的例子中,我们将创建一个抽象两个 pod 的服务。

在 Microsoft Azure 上设置 Kubernetes 群集

Microsoft Azure 提供了一种设置和操作 Kubernetes 集群的便捷方式。首先你需要 Azure 账号。

进入 Microsoft Azure

  • 在https://azure.microsoft.com/free/获得 Azure 免费试用账户。如果你已经有微软帐号,你可以使用它。
  • 微软提供 200 美元的信用额度来启动 Azure。这对我们的目的来说已经足够了。
  • 去 Azure 门户,检查你是否有完全访问权限。
  • 在你的电脑上本地安装 Azure 命令行界面。在 64 位 Ubuntu 中,您可以从终端完成:
echo "deb [arch=amd64] [https://packages.microsoft.com/repos/azure-cli/](https://packages.microsoft.com/repos/azure-cli/) wheezy main" | \
sudo tee /etc/apt/sources.list.d/azure-cli.listsudo apt-key adv --keyserver packages.microsoft.com --recv-keys 417A0893sudo apt-get install apt-transport-httpssudo apt-get update && sudo apt-get install azure-cli

然后使用以下命令检查安装的版本:

az --version

它应该等于或大于 2.0.x。

创建 Kubernetes 集群

您需要通过简单的步骤来创建一个 Kubernetes 集群。

登录 Azure

az login

并遵循终端和浏览器中的指示。最后,您应该会看到一个带有云信息的 JSON 文档。

创建资源组

资源组是一个逻辑组,您可以在其中部署资源(例如虚拟机)并管理它们。

az group create --name ganRG --location eastus

您应该会看到一个包含资源组信息的 JSON 文档。

创建集群

现在是时候创建 Kubernetes 集群了。在 Azure 免费试用版中,我们最多可以使用 4 个内核,因此我们只能创建一个主内核和一个工作内核;它们每个都有两个内核。主节点是自动创建的, agent-count 指定工作(或代理)节点的数量。

az acs create --orchestrator-type=kubernetes \
--resource-group ganRG \
--name=ganK8sCluster \
--agent-count=1 \
--generate-ssh-keys

提示:不要使用很长的名称,我在创建 Kubernetes 服务时遇到了一个错误,它抱怨名称太长(Azure 给集群名称添加了相当长的后缀)。

如果 SSH 密钥不存在,您还会在默认位置收到生成的 SSH 密钥。稍等几分钟…如果一切正常,那么您应该会看到包含集群信息的相当长且详细的 JSON 文档。确信您的资源组中已经创建了一个集群

{
.........
  "resourceGroup": "ganRG"
}

您还可以在 Azure Portal 中检查我们在资源组 ganRG 中有两个虚拟机—k8s-master—…k8s-agent—…

注意事项

如果您不使用虚拟机,请注意停止或取消分配虚拟机,以避免额外成本:

az vm [stop|deallocate] — resource-group=ganRG — name=k8s-agent-…
az vm [stop|deallocate] — resource-group=ganRG — name=k8s-master-…

您可以使用以下命令重新启动它们:

az vm start — resource-group=ganRG — name=k8s-agent-…
az vm start — resource-group=ganRG — name=k8s-master-…

将 Docker 图像上传到 Azure

现在我和 Kubernetes 做一个短暂的休息,把我们的 Docker 图片上传到 Azure 容器注册中心。它是我们在云中的 Docker 私有注册表。我们需要这个注册中心将 Docker 映像放入我们的 Kubernetes 集群。

创建容器注册表

az acr create --name=ganEcr --resource-group=ganRG --sku=Basic

创建一个私有注册表 ganEcr 。作为响应,您应该得到一个包含注册表信息的 JSON 文档。有趣的领域有:

{
  "adminUserEnabled": false,
  .........
  "loginServer": "ganecr.azurecr.io",
  .........
}

第一个告诉您,注册表没有管理员,第二个告诉您资源组中服务器的名称。为了上传 Docker 图像,我们需要一名管理员,我们必须让他:

az acr update -n ganEcr --admin-enabled true

上传 Docker 图像

首先,我们必须提供上传凭证:

az acr credential show --name=ganEcr

您应该会收到类似以下内容的响应:

{
  "passwords": [
    {
      "name": "password",
      "value": "=bh5wXWOUSrJtKPHReTAgi/bijQCkjsq"
    },
    {
      "name": "password2",
      "value": "OV0Va1QXv=GPL+sGm9ZossmvgIoYBdif"
    }
  ],
  "username": "ganEcr"
}

您使用一个用户名和一个密码从 Docker:

docker login ganecr.azurecr.io -u=ganEcr -p=<password value from credentials>

然后以这种方式标记 GAN Docker 图像:

docker tag $USER/tensorflow-serving-gan:v1.0 ganecr.azurecr.io/tensorflow-serving-gan

现在你可以把它推到 Azure 容器注册!

docker push ganecr.azurecr.io/tensorflow-serving-gan

耐心点,这需要一段时间:-)记住,这个操作将 Docker 镜像从你的 PC 上传到微软服务器。

在 Kubernetes 集群上运行

回到库伯内特。对于集群上的操作,我们需要一个名为 kubectl 的工具。它是一个命令行界面,用于对 Kubernetes 集群运行命令。

我建议您查看 kubectl 文档中的可用命令列表。我在这里使用:

kubectl get [nodes|pods|services] 

分别获取关于 Kubernetes 节点、pod 和服务的信息

kubectl create ...

用于从配置文件创建 pod 和服务。

用 kubectl 连接到 Azure

首先从 Azure 获取凭据:

az acs kubernetes get-credentials --resource-group=ganRG --name=ganK8sCluster

这个命令从 Azure 获取凭证并将它们本地保存到 ~/。kube/config 。所以你不需要以后再问他们。

现在,使用 kubectl 验证到集群的连接:

kubectl get nodes

您应该会看到主节点和工作节点:

NAME                    STATUS                     AGE       VERSION
k8s-agent-bb8987c3-0    Ready                      7m        v1.6.6
k8s-master-bb8987c3-0   Ready,SchedulingDisabled   7m        v1.6.6

部署配置

我已经为部署到 Kubernetes 集群创建了一个配置文件 (YAML 格式)。在那里,我定义了一个部署控制器和一个服务。我鼓励您阅读 Kubernetes 文档以获取详细信息。

这里只是一个解释,我所做的。实际上,您可以使用 kubectl 命令来部署 pod 和服务,但是将所需的部署配置一次性写入这样的 YAML 文件并在以后使用它要方便得多。

在我们的例子中,它定义了一个部署和一个服务:

......
kind: Deployment
metadata:
  name: gan-deployment
......
---
kind: Service
metadata:
  labels:
    run: gan-service
  name: gan-service

部署

我想将我的 Docker 映像部署到两个单元中:

spec:
replicas: 2

并从我的 Azure 容器注册表中提取它:

spec:
  containers:
  - name: gan-container
    image: ganecr.azurecr.io/tensorflow-serving-gan

部署后,Pod 应该启动 Shell 并启动 TensorFlow,在 Docker 容器中为 GAN 模型提供服务:

command:
- /bin/sh
- -c
args:
- /serving/bazel-bin/tensorflow_serving/model_servers/tensorflow_model_server          --port=9000 --model_name=gan --model_base_path=/serving/gan-export

在端口 9000 上:

ports:
- containerPort: 9000

服务

服务必须在端口 9000 上接受外部请求,并将它们转发到 Pod 中的容器端口 9000:

ports:
- port: 9000
  targetPort: 9000

并在两个底层 pod 之间提供负载平衡:

type: LoadBalancer

部署到 Kubernetes 集群中

现在部署 Docker 映像,让 Kubernetes 来管理它!

cd <path to GAN project>
kubectl create -f gan_k8s.yaml

您应该看到:

deployment "gan-deployment" created
service "gan-service" created

现在检查 pod 是否正在运行:

kubectl get podsNAME                              READY     STATUS    RESTARTS   AGE
gan-deployment-3500298660-3gmkj   1/1       Running   0          24m
gan-deployment-3500298660-h9g3q   1/1       Running   0          24m

提示:状态变为运行需要一段时间。只有这样你才能确定豆荚已经准备好了。

服务准备就绪:

kubectl get servicesNAME          CLUSTER-IP     EXTERNAL-IP    PORT(S)          AGE
gan-service   10.0.134.234   40.87.62.198   9000:30694/TCP   24m
kubernetes    10.0.0.1       <none>         443/TCP          7h

提示:gan 服务的外部 IP 必须是有效的 IP(不是<><节点> )。否则,该服务不可操作。

检查它是否工作

所以现在我们可以检查我们的努力是值得的!

cd <path to GAN project>
python svnh_semi_supervised_client.py --server=40.87.62.198:9000 --image=./svnh_test_images/image_3.jpg

您应该看到:

outputs {
  key: "scores"
  value {
    dtype: DT_FLOAT
    tensor_shape {
      dim {
        size: 1
      }
      dim {
        size: 10
      }
    }
    float_val: 8.630897802584857e-17
    float_val: 1.219293777054986e-09
    float_val: 6.613714575998131e-10
    float_val: 1.5203355241411032e-09
    **float_val: 0.9999998807907104** float_val: 9.070973139291283e-12
    float_val: 1.5690838628401593e-09
    float_val: 9.12262028080068e-17
    float_val: 1.0587883991775016e-07
    float_val: 1.0302327879685436e-08
  }
}

如果你得到这个结果,恭喜你!您在 Kubernetes 集群的云中部署了 GAN 模型。Kubernetes 以可靠的方式扩展、负载平衡和管理 GAN 模型。

结论

在第 1 部分和第 2 部分中,我们创建了一个 GAN 模型,准备好供 TensorFlow 使用,并将其放入 Docker 容器中。工作量很大,但我们都是在当地生产的。

现在我们把它公之于众,并使用最先进的技术,以可靠和可扩展的方式做到了这一点。

当然,这个模型非常简单,并且以用户不友好的形式给出结果。自动化潜力很大,我做了很多手动步骤来解释其中的机制。所有步骤都可以打包到脚本中进行“一键式”部署,或者成为持续集成/持续部署管道的一部分。

我希望你喜欢这个教程,并发现它很有用。如有任何疑问或问题,请随时与我联系。

更新 12。2017 年 11 月

我用指令扩展了一个教程,如何为模型创建 REST API,由 TensorFlow Serving 托管。

如何设计人工智能系统?

原文:https://towardsdatascience.com/how-to-design-an-artificial-intelligent-system-part-1-concept-development-cdbc8aee30d8?source=collection_archive---------8-----------------------

概念开发、解决方案发现和资源评估,为您的第一个人工智能系统产品做好准备。

要开始设计一个智力模型,你需要制定目标。例如,学习洞察力,开发实验和知识,执行预测或训练系统来解决问题。

为了让这篇文章的阅读起作用,把你的项目记在心里,并把想法写下来。我向你保证,做完这个练习后,你对构建智能系统和所需资源规划的理解将会更加清晰。

在地上

我们都来自不同背景的人工智能,这种想法可能看起来模糊。让我们定义一些概念:

  • AI 是一套数学方法,让程序机器有意识地运转。这意味着机器有动机和能力设定任务并解决它。
  • 一个智能系统是狭义人工智能的同义词。它研究代理和机器,这些代理和机器使用基于相关领域知识的统计和机器学习算法来执行明确定义的任务的自动化。
  • 机器学习是一类算法,它通过吸收数据统计信息来学习执行一项任务并增强性能结果,而无需改进算法本身。

形成一个概念

技能:叙事讲故事,同情心

你打算解决什么问题?最好的答案是从为什么开始,而不是从如何或什么开始。为什么会有这个问题呢?你为什么想找到解决办法?“如何”这个问题回答了你将应用什么技术;什么描述了你想要产生的结果。为什么你坚持这个问题。你必须感受到问题的痛苦。当你理解其背后的动机时,你会看到多个解决方案,并能够选择一个满足项目约束的方案。

谁将从该解决方案中受益?没有目标受众的问题是不存在的。避免一概而论——将观众分成清晰的部分。这些人是谁?他们有什么共同点:有什么鲜明的特点吗?

进行研究

技能:批判性思维、数据分析

研究首先要了解以前的解决方案是如何解决这个问题的。参考资料使研究可靠,也让你与该领域的专家联系起来。在竞争分析之上的人工智能相关项目中,人们研究学术解决方案。一个全面的出版物将包括实验设计,数据选择的标准,模型描述,模型的优点和缺点,以及改进的想法。不需要重现一个实验,你所关心的只是算法如何解决问题,性能基准,以及引用源如数据集和开源代码。

我使用谷歌学术来研究最相关和被引用的解决类似问题的文章和模型。它可能包括算法伪代码,但最有可能链接到开源库,如 GitHub 。此外,大量记录良好的现成 ML 框架和工具集给出了最新方法的评论(例如, Azure 机器学习、 Amazon Sage Maker 、 PyTorch 1.0 、 TensorFlow )。不要忘记提到你选择使用或修改的模型或代码的版权——透明和交流是人工智能社区的主要驱动力。

最初的研究有助于创建你的假设,因此你准备好收集历史数据和在线观察。起初,你可能想积累更多的信息。然后,在数据探索之后,只有必要的体积将保留在研究中。但是,提问时不要提出答案,因为你不想用确认偏见影响结果,并保持批判性,包括可能与你的假设相矛盾的特征。

研究状态的关键是了解解决问题的成本。在业务建模中,这个过程被称为客户开发。您将需要这个答案来在同事、客户、赠款发放者中推广解决方案,以将项目推进到下一步。

拆分问题

技能:创意分析

对于流程阶段,一个事件从另一个事件开始。对于其余的,发现变量之间的关系:如果改变一个变量导致另一个变量的变化,那么后者是可靠的;如果没有—独立。反之亦然,以确定相互依赖。

在复杂的系统中,有更多的标准来划分阶段。例如,过程阶段的演化条件、不同的数据和知识来源、目标行动的约束以及相关的环境动态。形成独立的步骤和组件后,确保您有所有需要完成的部分。

作为一个例子,为了建立一个智能系统,该系统能够应用 R-CNN 对象检测模型来识别视频流中的事件,组件是:流输入源、相关条件、传递知识、预处理图像、为对象建议区域、计算 CNN 特征、对区域分类、标记对象。作为输出,智能模型可以捕捉视频流中的事件。

Example of criteria to split the stages and conditions for a complex system

地图和草图,例如绘制统一建模语言图和以产品为中心的流程图,对于看到完整的图片和进一步交流信息是有价值的。在你觉得舒服的任何程序中做插图。我使用 Keynote 构建简单的图表,使用 Cacoo 应用思维导图、ER 和 Azure/AWS 模板。

提出假设

技巧:提问

下一步是准备假设。如果一个假设有可能产生至少一个你可以用实验证明的精确预测,那么这个假设就是正确的。假设的结构因你所做的项目类型而异。为了研究——如果我们这样做,我们会发现。对于企业来说,如果我们这样做,我们将会赢得。

尽管如此,总体结构仍然是相似的:在选定的数据集上进行的实验显示了自变量是否如预期的那样变化,而因变量以特定的模式做出响应。为了使调查可靠,提及与代表偏见的主要结果或见解相矛盾的已知来源。

创建计划

技能:战略思维

当谈到在计划中执行解决方案的愿景时,我发现一些有用的草图,比如包含正面和负面场景的决策树。一个被拒绝的假设不会将整个项目置于定义明确的战略的不确定性风险中。相反,它支持一个有意识的决定,考虑剩下的时间和资源。大计划保持敏捷和灵活,因此行动响应即将到来的信息和见解。

估计资源

技能:正念

一切都可以用原来的公制或者至少从 0 到 5 来衡量。用数字定义成功和失败的计划意味着敏感性——理解表演阶段和状态的能力。此外,这种估计有助于推导出让你和利益相关者了解情况的影响概率。

在评估技术准备程度时,考虑您团队的独特优势和知识。如果你能反思以前的经验,也从中估计;如果没有,不要担心——寻求专家的建议或在这个过程中指导你。

资源测量通过减少一次做很多事情的欲望,保护你远离模糊的概念,并向太多的方向发展。资产和资源来源于团队的知识和技能、时间、金钱、情感和身体健康。因此,保持计划简单,不要对未来几年提出太精确的建议:专注——一次一步。

当日成绩

首先,祝贺你,你做得很好:你澄清了概念,并制定了可测试和可测量的假设。现在,您已经准备好交流已知和未知的信息,以填补缺失的信息并获取项目资源。我很高兴听到你的故事和问题——在推特上丰富我,让我们保持联系。

关于作者:
我是一名从事复杂系统建模和数据科学的应用数学家。我在计算神经科学领域进行数据翻译研究,并与各种客户一起解释业务数据源,以获得洞察力并创造产品。

如何开发成功的医疗保健分析产品

原文:https://towardsdatascience.com/how-to-develop-a-successful-healthcare-analytics-product-e36e0d4cb141?source=collection_archive---------6-----------------------

分析和数据科学是医疗保健的重要工具。不仅仅是因为他们能够预测某人何时会心脏病发作。良好的数据科学和分析是重要的工具,因为它们有助于在医疗保健支出和减少低效方面做出更好的决策。能够降低医疗服务提供者的医疗保健成本将反过来允许他们允许更多的人获得医疗保健。

当看着所有其他长期使用分析和算法的行业(如金融/银行和电子商务)时,医疗保健的诱惑是试图全面解决医疗保健中的所有数据问题。这反过来导致对数据团队、数据湖和其他以数据为中心的计划的大量投资,这些投资并不总是成功的。类似于 DC 电影未能像马福 l 一样吸引观众注意力的原因之一。他们匆忙尝试创造类似于漫威用三分之一的时间用十年创造的东西。同样,许多医疗保健公司试图建立数据科学商店,并试图在几年内复制谷歌、亚马逊和其他一些大型科技公司已经做了十多年的事情。

在这种熟练水平上建立分析团队和数据系统需要时间(让我们甚至不要开始数据标记)。而不是试图在一年内创建一个完整的数据分析和算法世界。我们已经取得了成功,从一两个问题开始(像在网上卖书,但在医疗保健行业),选择一个观点来解决问题,然后讲一个简单的故事。如果你的数据团队能够做到这一点并取得成功,那么你就离成功更近了,并且已经开始获得支持者和经理的支持。医疗保健是复杂的,所以在向一个大团队投资数百万美元之前,先从关注几个问题和有限的视角开始。

挑一个问题拿一个

当谈到医疗保健分析(或任何分析)时,重要的是选择一个特定的问题,然后将该问题分成更小的部分。例如,如果你试图开发一个检测欺诈的算法。设计一个模型、算法或系统来将欺诈的概念作为一个整体抽象成一个单一的数学表达式可能非常困难。尤其是当医疗保健互动很少被归类为欺诈或非欺诈时。

这并不妨碍你进行分析或预测建模。它只是改变了你的方法。与其开发复杂的数据科学模型,不如先关注那些有良好投资回报的东西。一个基本系统可以帮助首先减少分析师不得不为欺诈而费力处理的索赔数量,或者在更高的级别指出更大的系统性问题,可以帮助知道首先将精力集中在哪里。此外,他们可以通过互动来标记和记录模式。

在花一些时间查看这些案例后,您的分析团队将会对问题有进一步的了解,并会有许多优秀的最佳实践和标签数据。最后,这可能看起来很慢,但慢总比失败好。

专注于一个角度

当开发任何类型的分析时,你可以采取许多不同的角度和观点。例如,在医疗保健领域,您可以关注医疗保健提供商(医院、急诊室等)、患者或手术类型。你的团队可能没有足够的资源来开发一个工具、仪表盘或算法来立刻处理所有这些不同的角度。因此,当承担一个像“预测病人再入院”这样的新项目时,选择一个对你的团队最有益的类别。通常,首先关注提供商是更好的选择之一。这是因为与患者行为相比,改变提供者行为要容易得多。当你改变一个提供者的行为时,其影响比改变一个病人的行为要大得多。这也是为什么首先关注提供商层面的分析会有所帮助的两个原因。此外,就像上面讨论的那样,它可以帮助关注和查明患者层面的一些更具体的问题。

你的最终作品应该有一个清晰的故事

一旦你开发出了产品的最终数据点,这个产品就需要能够讲述一个故事。老实说,这对我来说仍然是一个困难的部分。然而,这是一个非常重要的概念。即使你是一个了不起的程序员、数据工程师或算法开发人员,如果你的产品没有向你的最终用户描绘一个清晰的故事,那么它可能会被忽略或误解。通常,我所看到的成功的报告流程是对问题有一个高层次的了解,如果适用的话,可能包括问题的成本。这让每个人都在同一页面上,也吸引了他们的注意力。如果你能说明问题有多大,花费了他们多少钱,最终用户就会被吸引过来。

然后你可以进一步深入问题,把它分解成子集,然后进入下一步。

接下来的步骤不一定是直接的解决方案。这可能是一个有问题的程序列表,导致大量的再入院或欺诈。这导致了下一个可能的项目是分析为什么。一旦你找到了可能的原因和解决方案,你就可以回头看看报告,看看事情是否有所改变。

Caption: Taking a quick detour, lets look at a few dashboards from actual companies. The dashboard above is from Health Catalyst. The top portion is attempting to state whether or not the cohort is currently meeting the target for various readmissions. This kind of states if there is a problem or not. It is pretty typical for medical analytics to do a comparison approach. The middle section is a little bit of a disconnect for me. It doesn’t really flow with the story they are trying to tell. It talks about interventions, but this doesn’t really connect with the first set of graphs. However, the last section that is a bar graph melded with a line chart makes sense because it tells you the history. So maybe you’re not hitting your target readmission numbers, but you are improving

总的来说,你处理医疗保健分析或开发算法来预测患者再入院等事件的方式与任何其他行业没有什么不同。试图解决整个问题,比如欺诈,或者将病人重新入院作为一个整体,这是很有诱惑力的。医疗保健行业的海量数据和复杂的交易并不容易。为了管理这种复杂性,分解问题并决定你计划采取的观点将有助于增加你的成功和结果率。

您的团队在开发医疗保健分析方面需要帮助吗?也许你正在寻找衡量供应商质量或分析患者模式。如果是这样,那么今天就联系我们的团队 y!我们有一个医疗保健分析专家团队,可以帮助您创建所需的工具。

我们已经致力于开发产品来帮助管理患者再入院、资源滥用、检测不必要的程序、慢性病预防和欺诈检测。

如果您想了解更多关于数据科学或分析的信息,请查看以下文章:

Men ' s wear house 如何使用数据科学
如何使用 R 开发预测模型
使用 Google Sheets 进行网页抓取
什么是决策树 算法如何变得不道德和有偏见
如何开发健壮的算法
4 数据科学家必须具备的技能

如何在一小时内开发、部署和扩展一个数据科学算法!

原文:https://towardsdatascience.com/how-to-develop-deploy-and-scale-a-data-science-algorithm-in-one-hour-6c43f2b78f1d?source=collection_archive---------3-----------------------

这样你就有了一张数据表。您希望使用所有其他列中的值来预测一列中的值。您需要训练、测试、部署和生产(即,使其在 API 背后可用)一种算法,该算法将根据输入特征准确预测输出特征。我们开始吧。

在我们开始之前,你需要一个 AWS 账户。不要问问题,直接报名,现收现付,很便宜。其次,您还需要访问 Linux 终端。我用的是云 9 ,它太棒了,而且有一个免费选项。最后,用你的 AWS 证书在你的 Linux 终端上安装并设置无服务器框架,这是开源的好日子。

第一步:去 S3 上传你的 CSV 格式的数据。

第二步:在 AWS 上进入亚马逊机器学习,点击‘新建...’然后是“数据源和 ML 模型”。遵循要求的步骤(步骤不多,应该很简单,只需使用默认选项)。一旦完成,亚马逊机器学习将构建、训练和测试算法。

第三步:每个人都知道好的模型需要好的数据,“垃圾进垃圾出”等等。现在请评估您的模型,如这里的所解释的。

步骤 4:现在让我们部署模型。按照这些步骤为您的模型创建一个实时端点(阅读文档并自己按照这些步骤来做确实是一个很好的实践)。

第五步:接下来是有趣的部分。我们将使用 AWS Lambda 和 Amazon API Gateway 来处理对算法的请求。最棒的是,你甚至不会知道你正在使用它们!我将更详细地介绍这些步骤:

步骤 5a:在您的 Linux 终端中,键入:

serverless create --template aws-nodejs --path my-first-algorithm

步骤 5b:在新创建的文件夹中,将其粘贴到“serverless.yml”文件中:

service: my-first-algorithmprovider:
  name: aws
  runtime: nodejs4.3iamRoleStatements:
  - Effect: Allow
    Action:
      - machinelearning:Predict
    Resource: "*"functions:
  model:
    handler: handler.model
    events:
    - http:
        path: model
        method: post
        cors: true

步骤 5b:将下面的代码粘贴到您的“handler.js”文件中,插入您在上面的步骤 4 中找到的正确的“MLModelId”和“PredictEndpoint”(我的示例只有一个输入特征,如果您的特定模型需要,请重命名并添加额外的特征):

// load aws sdk
const AWS = require('aws-sdk');// load AWS MachineLearning
var machinelearning = new AWS.MachineLearning({apiVersion: '2014-12-12'});module.exports.model = (event, context, callback) => { var data = JSON.parse(event.body);
  var inputFeature1Data = data.inputFeature1; var params = {
    MLModelId: **INSERT-THIS-YOURSELF**,
    PredictEndpoint: **INSERT-THIS-YOURSELF**,
    Record: {
      inputFeature1: inputFeature1Data
    }
  }; machinelearning.predict(params, function(err, data) {
    if (err) {
        const response = {
          headers: {'Access-Control-Allow-Origin': '*'},
          statusCode: err.statusCode,
          body: JSON.stringify(err)
        };
        callback(null, response);
    } else {
        const response = {
          headers: {'Access-Control-Allow-Origin': '*'},
          statusCode: 200,
          body: JSON.stringify(data)
        };
        callback(null, response);
    }
  });};

步骤 5c:确保您仍然在 Linux 终端中新创建的文件夹中,并键入serverless deploy,等待服务部署,一旦您看到“端点”url,您就可以开始了。

您可以通过将下面的代码粘贴到您的 Linux 终端来测试该模型的工作情况(将“endpoint-url”替换为步骤 5c 中的 url 端点) :

curl -X POST endpoint-url --data '{"inputFeature1":7}'

现在,您已经有了一个在生产中完全部署和可用的算法。它可以扩展到处理所有请求,并且完全由 AWS 管理,您不需要做任何维护,太棒了!这个工作流程很神奇,尤其是如果你想建立一个概念验证算法的话。添加 API 密钥或 JSON web 令牌验证将提供必要的安全性,只允许特定用户访问您的算法。

我希望您对此感兴趣,我确实认为这是数据科学工作流程中的一个范式转变。

附:这是我第一次在网上发帖,请评论但不要太苛刻:)

如何在数据科学面试中脱颖而出

原文:https://towardsdatascience.com/how-to-differentiate-yourself-during-data-science-interviews-9bae09d66367?source=collection_archive---------1-----------------------

注意:这篇文章的底部是一些行业数据科学家关于如何最好地获得你的第一个数据科学职位的回答。

获得一个新的数据科学职位需要采取一系列步骤来展示你处理数据的能力,以及你是否适合一家公司的文化。在这篇文章中,我将解决这个过程中最重要的部分之一(也是最可怕的部分):技术面试。

与我交谈过的大多数人都花了大量时间练习编码挑战,并温习像 SQL 查询这样的技能。虽然这些都是准备面试的重要方面,但它们只强调你能多好地使用键盘。

在我自己找工作的过程中,我花了很多时间思考如何利用技术面试作为一种手段,将自己从其他申请中区分出来。我们大多数人都能编写一个函数来表示一个数是否是质数(提示:模是你的朋友)。经常被忽视的是,你的每一个答案都是一个机会,为你解决问题的特定形式提供背景。最佳情境取决于你被问到的特定问题、面试官和你申请的职位。然而,从我的经验来看,在面试过程中,有三种主要类型的语境是有效的。

苦心经营

虽然编码问题通常可以简化为使用您偏好的编程语言的本地组件,但是它们表明您除了知道何时调用特定方法之外的解决问题的能力。无论是口头回答还是在白板上回答,您的解决方案的每一步都应该清楚地说明您为什么选择特定的方法。这允许您讨论可能不如您选择的解决方案执行得好的替代解决方案,并表明您能够思考您的代码如何影响产品的可伸缩性。

这里有一个很好的提示,就是知道如何测试不同方法的计算时间。因此,即使您不熟悉哪种规模更好,您也可以指出该问题有 n 种解决方案,并且测试每种解决方案的计算时间会很有趣。因此,即使你可能没有一个直接的答案,你仍然表明你在考虑性能,如果你坐在电脑前,你会知道如何测试不同的方法。

精化的另一个重要方面是讨论一个特定的编码解决方案如何被用于公司中某人可能正在处理的商业问题的上下文中。虽然这并不适用于每一个技术问题,但你应该抓住任何机会在这种背景下讨论解决方案。一个例子是处理预测客户流失的数据科学角色,你可以根据该问题解释基本的技术问题(例如,深度神经网络如何工作)。你可以谈论什么类型的数据将被输入到神经网络,以及该网络将如何使用与客户流失相关的特征来优化预测。

讲故事

讲故事类似于阐述,但涉及使用具体的过去事件来突出你的技能。在解决问题时,你可以指出你过去是如何实现类似的解决方案的。重要的是要强调项目的相关细节,你解决问题的步骤,以及你努力的具体结果。

我在项目 Y 的特征工程阶段采取了行动 X,这导致了模型准确性和 AUC 分数的 Z 增加。

讲故事的一个重要用途是展示传达公司价值观的行为。许多科技公司在他们的网页上列出了他们的核心价值观,有时被称为使命。其他公司,如银行和咨询机构,将寻找领导和解决问题的技能。例如,亚马逊将评估领导原则的问题与面向数据的问题交织在一起。行为故事的一个好框架是星型模式。

星形格式要求您用四个步骤陈述您的答案:

1.情况

2.工作

3.行动

4.反应

你可以在这里找到更多关于如何实现星星方法的信息。

后续

这个策略要求你就公司目前面临的某些问题引出细节。这里的想法是双重的:证明你是以解决方案为导向的心态来处理这个角色的,并且你能够实际上实施他们问题的解决方案。

具体做法是,当有机会向面试官提问时,你可以问一些你在这个角色中会遇到的问题的具体例子,或者团队目前正在解决的重要问题。面试结束后,你回到家,花一些时间概述问题和实施解决方案的计划。这不需要非常专业,只是一个概述,表明你理解手头的问题,并能提出自己要实施的解决方案。然后,你与面试官跟进,重申你在面试中的积极经历,并将文件发给他们,内容大致如下:“顺便说一下,我考虑了你目前面临的问题,提出了三个解决方案,我可以在进入贵公司的第一个月内实施。”这有效地给了面试官一个让你在公司起步的路线图,如果被录用,这可能会成为你的第一个项目。

一个很好的例子是拉米特·塞西的公文包技术。

关于差异化的进一步思考

在准备面试时,我询问了在数据科学岗位工作的朋友,听听他们进入该行业的经历。请注意,我和我的这些朋友从博士项目转到了数据科学职位,所以如果你来自不同的环境,他们的回答应该从这个角度来理解。

答案是半匿名的,来自脸书、优步和亚马逊等公司的数据科学家。希望它们对你思考如何在面试过程中进行阐述、讲故事和跟进有所帮助。

问题 1:除了良好的投资组合和技术技能,你认为对贵公司的数据/研究/nlp 科学申请人来说,什么是重要的?

回应 1: 产品感,强调产品指标。这是专门针对数据科学产品分析角色(FB 的绝大多数角色)的。此外,还有一个核心数据科学小组,他们基本上是软件工程师,也知道统计数据并构建其他 DS 使用的工具。还有基础设施数据科学,它们对我来说有些神秘,但在我们的数据仓库中工作。我们也有研究科学家的角色,但这些都是非常具体的领域。

回应 2: 商业意识/洞察力——能够直观地了解公司试图用数据科学解决什么问题,他们如何衡量成功,以及数据科学如何才能最好地满足这些需求。了解如何采纳 DS 见解并将其转化为可行的建议。此外,创造力、效率、独立性、协作/利他主义。

回应 3: 你能展示出你工作的影响力,并强调这是你工作中的一个考虑因素,这一点绝对重要。其中一部分是能够优先处理最重要的工作。在脸书,你总有一百万件事情可以做,知道哪些是最重要的、影响最大的是关键。

回答 4: 理解数据集的能力,快速学习这里的东西的能力,独立理解和学习概念的能力(有一大堆维基,你必须能够自己阅读和理解一些东西)。

问题 2:在找工作时,你关注的哪个领域(如投资组合、领域知识、特定技能、博客/外联)对被录用没有太大影响?

回应 1: 真的没有。我参加了 Insight Data Science fellowship,他们为通过 DS 面试做了很好的准备。(注意:如果你能进入数据科学训练营,你就处于有利地位。尤其是如果是洞察奖学金。)

回应二:我没有博客,但有个人网站和 github。我不确定我被聘用时是否考虑过他们,但我们现在肯定会考虑他们作为候选人。出版记录当然并不重要(除非它证明了完成项目的能力),但这是我所期望的。

回应 3: 这个问题真的很好。事实上,我发现在我进入科技行业的过程中,最有影响力的是人际关系。事实上,我仅仅写简历并没有得到任何工作。我所有的工作都是通过了解我或我的工作的人得到的。

回应 4: 我的投资组合真的不重要我觉得哈哈。

问题 3:如果你重新找工作,你会花更多时间在哪个方面?

回应 1: 我在这里没有很好的答案,但那可能是因为我目前的角色相当独特。如果我今天更广泛地看 DS 的空缺,我可能会想加强机器学习方法。

回应 2: 与上述类似。网络网络网络网络。我在演讲方面取得了巨大的成功。一次谈话后,基本上有 3-4 家公司有兴趣雇佣我。不过,这对于学术界来说可能有点困难。我肯定会建议寻找机会在会议上做志愿者。我也会优先去参加更多的聚会。根据你在哪里找工作,在 linkedin 上找到在那里工作的人并邀请他们见面(即使是通过视频会议)也是有意义的。对于那些会议,确保你已经研究过这个人,并且有具体的问题要问。另一个选择也可能是寻找指导项目(我是 chic geek 的导师)。基本上任何建立真实生活关系的事情,而不仅仅是发送简历。

回应 3: 本体建模(我还不完全知道它是什么)和机器学习的知识。

问题 4:你认为在学术界和工业界工作有什么大的不同?

回应 1: 快速运输远比完美运输重要。

项目所有权——我习惯于 100%拥有我所做的任何东西,但是在工业中有更多的相互依赖。

沟通是完全不同的,因为我几乎从来没有和其他数据科学家一起工作过。我正在与工程师/项目经理/等沟通,必须做出相应的调整(例如,没有人关心或理解方法,他们只想知道结果)。

回应 2: 速度——在行业中,快速获得可行的答案是最基本的要求,而完美是好的敌人。就速度/准确性的权衡而言,本能(和你的经理)会告诉你什么时候你已经得到了足够正确的答案,可以继续前进了。

跨功能性——许多数据科学家在 xf 团队中工作,需要能够与来自完全不同背景的人(如商业、设计、工程等)很好地沟通。

回应三:最大的肯定是时间线和现实生活约束的考虑。在学术界,目标通常是用最完美的方法找到最好、最合理的答案。你所花的时间往往是因为这个或那个考虑的结果。在行业中,时间表决定一切。你必须善于权衡,在你拥有的时间和资源内,你能做的最好的事情是什么,同时还要平衡其他三个项目。评论也不是很严谨,很少有像文学评论这样的努力(如果你有时间做得很好,但绝对不是一个要求)。

事实上,我喜欢工业的快节奏,但这也是学术界人士有时会纠结的问题。

还有,写报道。你必须善于将你的发现形象化,并让它为广泛的人群所接受。这包括能够撰写易于理解的执行摘要。

此外,您肯定需要能够从您所做的工作中定义可行的建议。有一个有趣的发现很好,但更重要的是你必须展示“那又怎样?”。采取什么步骤来修复您发现的任何问题,或者以对业务有影响的方式采取行动。因此,你还需要真正意识到你正在推动的业务成果是什么。

问题 5:对于在科技公司获得第一份工作,有什么建议吗?

回应 1: 我在这里写了一篇关于我从学术界到 DS 的转变的博文。

回应 2: 利用推荐,这至少会让你得到招聘人员或经理的进一步关注。为你申请的每一个职位定制你的简历(不超过一页)。如果你不能亲自证明你知道一项技能,就不要说你知道它。在面试前调查公司,如果可能的话尝试他们的产品。搜索 HackerNews 对了解硅谷公司很有帮助,可能对你也有用。

应对 3: 更新你的 Linkedin。确保你有一个总结,并记下以上所有的经验(说明你的工作的影响,表明你可以在紧张的时间表下工作,表明你可以向广泛的受众传达你的工作,等等。).无论谁考虑雇佣你,他都可能会看你的 Linkedin。如果你也有一个令人惊叹的网站。

也不要漏掉人的成分。展示你感兴趣的东西,让你与众不同的东西,志愿服务或为社会公益工作。据我所知,科技公司(至少是脸书)经常寻找持有某种观点的人。还要确保你回顾了你申请的公司的价值观,并在简历中反映出你了解这些价值观。(脸书的价值观包括:开放、注重影响力等。)

额外问题:你对亚马逊的面试过程有什么见解吗,或者你希望你已经为面试做了更具体的准备?

回应 1: 面试方面,大部分问题会是行为问题。他们会评估你在某种情况下的表现,而不是你的实际技能(尽管你可能会有一两次技术性面试——你申请了什么职位?)他们更喜欢你所有的答案都是“星形”格式——情境、任务、行动和结果<——如果你准备了一些这种格式的故事,很好(你会做得很好)。许多问题是愚蠢的和开放式的,比如“告诉我你不得不与你的主管(或顾问或研究伙伴)意见相左的一次经历”。它是什么?你是如何解决的?最终结果是什么。”如果你能将问题与这些所谓的领导原则联系起来,他们也会非常喜欢(你不必明确地说,比如,我想展示所有权或者我想深入探讨这个问题,但你在回答中展示某些领导原则的能力将在汇报中讨论。

我希望这能帮助每个人踏上数据科学之旅。如果您有任何其他提示或建议,请给我留下评论。

如何使用 Apache Livy 在 AWS EMR 中运行 spark 批处理作业

原文:https://towardsdatascience.com/how-to-do-better-deployments-of-spark-batch-jobs-to-aws-emr-using-apache-livy-adc2417f0d8b?source=collection_archive---------7-----------------------

在本文中,我们将讨论在 Apache Livy 的帮助下,使用 rest 接口在 AWS EMR 上运行 spark 作业。

我们将完成以下步骤:

  • 创建一个简单的批处理作业,从 Cassandra 读取数据并将结果写入 S3 的 parquet
  • 建造罐子并把它存放在 S3
  • 提交作业并等待它通过 livy 完成

什么是阿帕奇李维?

Apache Livy 是一个通过 REST 接口与 Spark 集群轻松交互的服务。它支持 Spark 作业或 Spark 代码片段的轻松提交、同步或异步结果检索,以及 Spark 上下文管理,所有这些都通过一个简单的 REST 接口或 RPC 客户端库实现。Apache Livy 还简化了 Spark 和应用服务器之间的交互,从而支持将 Spark 用于交互式 web/移动应用程序。

你为什么会使用它?

Apache livy 让我们的生活更轻松。我们不需要使用 EMR 步骤或 ssh 进入集群并运行 spark submit。我们只是使用了一个很好的 REST 接口。

让我们看看它的实际效果。

步骤 1:构建简单的批处理作业

批处理作业将是一个 scala 应用程序。

在我们的应用程序中,我们首先构建 spark 会话,并确保我们可以连接到 Cassandra 集群:

val sparkConf = new SparkConf()sparkConf.set("spark.cassandra.connection.host", "YOUR_CASSANDRA_HOST")
sparkConf.set("spark.cassandra.connection.port", "YOUR_CASSANDRA_PORT")val spark: SparkSession = SparkSession.builder()
      .appName("RunBatchJob")
      .config(sparkConf)
      .getOrCreate()

我们还需要确保能够访问我们要写入数据的 S3 存储桶:

spark.sparkContext.hadoopConfiguration.set("fs.s3a.acl.default", "BucketOwnerFullControl")

我们可以从数据库中读取输入数据:

val input = spark.read
      .format("org.apache.spark.sql.cassandra")
      .options(Map("table" -> "my_table", "keyspace" -> "my_schema"))
      .load()

Cassandra 桌子的结构非常简单:

CREATE TABLE my_schema.my_table (
    id1 text PRIMARY KEY,
    id2 text,
    id3 text,
    id4 text
);

最后,我们只需将数据帧写入 S3 的一个拼花文件,同时删除重复的行:

input
      .dropDuplicates
      .write
      .mode("append")
      .parquet("s3a://your_bucket/your_preffix/")

步骤 2:将 jar 部署到 S3

好,现在我们有了一个应用程序。我们需要把它装进一个大罐子里,然后复制到 S3。这样,远程访问 jar(从 livy)就更容易了。

使用 gradle 管理我们的应用程序的依赖关系。在教程的最后,我会发布 github repo 的链接,在那里你可以找到 gradle 文件的完整代码和细节。我不会在这里讨论细节,因为这超出了本教程的范围。

要创建 fat jar,我们需要在应用程序的根目录下运行:

gradle shadowJar

生成后,我们可以使用 aws cli 将其复制到 S3:

aws s3 cp build/libs/spark_batch_job-1.0-SNAPSHOT-shadow.jar s3://your_bucket/your_prefix/

一旦这样做了,我们终于可以从使用 livy 开始我们的 spark 工作了。

步骤 3:通过 Livy 提交作业

我们将使用一个简单的 python 脚本来运行我们的命令。主要功能非常简单:

def run_spark_job(master_dns):
    response = spark_submit(master_dns)
    track_statement_progress(master_dns, response)

它将首先提交作业,然后等待它完成。 track_statement_progress 步骤对于检测我们的作业是否成功运行非常有用。 master_dns 是 EMR 集群的地址。让我们更深入地研究我们各自的方法。

spark_submit 功能:

host = '[http://'](/') + master_dns + ':8999'data = {'className': "com.app.RunBatchJob", "conf":{"spark.hadoop.fs.s3a.impl":"org.apache.hadoop.fs.s3a.S3AFileSystem"}, 'file': "s3a://your_bucket/spark_batch_job-1.0-SNAPSHOT-shadow.jar"}headers = {'Content-Type': 'application/json'}response = requests.post(host + '/batches', data=json.dumps(data), headers=headers)

这只是使用请求库完成的一个 post 。在 EMR 上,livy 服务器运行在端口 8999 上。我们请求中的数据本质上是我们将提供给 spark-submit 命令的参数。我们需要使用 /batches 端点。这将告诉 livy 我们将提交一个批处理作业。

以及跟踪声明进度函数。这将每 10 秒轮询一次 livy 服务器,并检查应用程序的状态是否为成功。如果是,则作业已成功完成:

statement_status = ''
host = '[http://'](/') + master_dns + ':8999'
session_url = host + response_headers['location'].split('/statements', 1)[0]while statement_status != 'success':
        statement_url = host + response_headers['location']
        statement_response = requests.get(statement_url, headers={'Content-Type': 'application/json'})
        statement_status = statement_response.json()['state']
        logging.info('Statement status: ' + statement_status) lines = requests.get(session_url + '/log', headers={'Content-Type': 'application/json'}).json()['log']
        for line in lines:
            logging.info(line) if statement_status == 'dead':
            raise ValueError('Exception in the app caused it to be dead: ' + statement_status) if 'progress' in statement_response.json():
            logging.info('Progress: ' + str(statement_response.json()['progress']))
        time.sleep(10)

这是一个较长的函数,所以我将尝试一步一步地解释它。对于运行时间较长的作业,livy 会更改 url,因此我们需要存储最新的一个:

statement_url = host + response_headers['location']

然后,我们获取集群的当前状态并记录下来:

statement_response = requests.get(statement_url, headers={'Content-Type': 'application/json'})
statement_status = statement_response.json()['state']
logging.info('Statement status: ' + statement_status)

我们也正在获取应用程序的日志并显示它们。这对调试错误很有用:

lines = requests.get(session_url + '/log', headers={'Content-Type': 'application/json'}).json()['log']
for line in lines:
    logging.info(line)

如果我们有一个严重的异常,那么应用程序将会死亡。我们需要标记它并抛出一个异常:

if statement_status == 'dead':
    raise ValueError('Exception in the app caused it to be dead: ' + statement_status)

最后一步,我们记录进度并等待 10 秒钟,直到我们再次检查应用程序的状态:

if 'progress' in statement_response.json():
    logging.info('Progress: ' + str(statement_response.json()['progress']))
time.sleep(10)

这就是全部。代码在 github 上,可以从这里访问。

如何在你的公司做数据科学才能发挥最大作用?

原文:https://towardsdatascience.com/how-to-do-data-science-in-your-company-to-get-the-most-out-of-it-aba8f011b749?source=collection_archive---------6-----------------------

建立数据科学团队,营造健康的数据文化

年轻的公司从一开始就吸收了精益开发、以客户为中心和数据驱动的设计。然而,充分利用数据的潜力仍然非常困难。这一步对于传统企业来说更是难上加难。配备了多个创业公司的资源,数据的使用似乎要困难得多。由于公司文化和技术领域的必要变化,数据计划没有取得成功(根据 Brynjolfsson 2011 年的研究,即使简单的数据驱动决策在几年前就已经显示出可以将股票价值提高 5-6%,但情况仍然如此)。

最大的线索是,我们被大量的数据和可用的使用选项所淹没,而管理或业务部门对短期内的切实成果缺乏兴趣(Veeramachaneni 2016)。

在一家高速增长的公司建立数据科学部门,我将分享一些我个人的见解,如何克服这些困难,以及如何从贵公司的数据和数据科学中获得最大收益。

我最初是一名数据科学家,只是通过查询数据库来回答一些业务问题。我还开发了普通的 Excel 模型来模拟商业行为。只要有可能,我都支持使用数据驱动的方法和统计方法来支持决策。与此同时,与许多了不起的人一起,我们已经将几个复杂的机器学习模型投入生产,我正在组建一个团队,该团队将与产品经理、开发人员和我们的管理层合作,以更多地利用数据。

接下来,我将发布几个故事,揭示我在这段旅程中的许多收获。首先,我会建议一个做数据科学的潜在结构和有利条件(组件)。在下一个故事中,我将展示一些数据科学项目的结果和验收驱动的项目模式(流程)。最后,我将介绍一些数据科学的总体知识和成功因素(油脂)。为了简化,因为大多数发现适用于这两种团队焦点,我将使用术语数据单位/团队,而不是数据科学单位/团队。

太棒了,我们开始吧!

成功的数据驱动型组织是什么样的?

首先,我们遵循这个简单的模式从数据驱动的组织开始:我们将数据集成到我们的战略核心愿景中,并将其视为竞争优势。在公司层面,我们决定在任何有意义的时候用数据挑战直觉。这样,我们可以专注于上下文、案例和手头的客户,避免机械地使用过去的经验和其他领域的经验而产生的偏见。听起来不错!

然后,我们在公司设立了一个新的数据部门,作为另一个业务部门来执行我们自己制定的计划。会出什么问题呢?

Figure 1: Top-down structure for a data unit with the goal to provide additional business value.

显然,会出现很多问题。首先,由于新成立的部门是一个孤岛,与其他业务部门没有紧密联系,任何分析、建议的方法或结果的接受度都将非常低,因为它不是一个合资企业。第二,因为数据部门不参与价值创造链,所以数据部门对业务的了解不足以成为业务部门的积极合作伙伴。因此,利用数据集可能得到的解决方案并没有启动。最后,由于业务单位将数据单位视为他们需要协调的另一个单位(这甚至适用于更多的 todos),他们会将潜在的数据解决方案推到只需要日常工作所需的报告或分析的边缘。

那听起来不令人满意。有更好的方法吗?根据我的个人经验,从结构的角度来看,对于一个成功的数据驱动型组织来说,有几个要素是必不可少的。组成部分是文化融合赋能。在下文中,我将强调所有三个方面的关键因素,以使数据驱动的计划取得更好的结果。

Figure 2: More informal network structure that integrates a data unit with potential true business impact.

先说文化。对于一个数据驱动的企业来说,文化显然必须是数据驱动的(见图 2)。公司中的大多数人至少应该接受和重视数据支持的见解,即使他们不能在自己的影响范围内使用它们。然而,如果对数据的渴望根植于企业文化中,事情就会简单得多。这意味着人们天生希望更好地了解市场、客户和基于数据的衡量标准。公司应该高度重视数据,即使不把数据视为塑造业务的一种强大优势,因为它们反映了客户的信念、态度和行为。

问题来了,“一种文化是如何形成的?文化是人们从生活价值观和行为中汲取的东西,它不能直接形成”。然而,雕刻文化有一个众所周知的秘密。通过以身作则,可以做出改变。在我们的例子中,这意味着公司内有影响力的人和高管正在展示对数据和数据产品潜力的认真关注。为了克服一个主要的惯性,一个可见的和实质性的团体需要将数据置于直觉之上,寻求数据解决方案,并分别从所有的度量中寻求可测量的结果。

第二个也可能是最重要的组成部分是公司中数据团队或数据部门的集成(同样,我包含了数据科学)。有效的数据单元不是简单地添加到现有的结构中(参见图 1 和图 2)。如果将数据单元放在一个孤岛中,则存在与其他单元和业务目标不平衡和不一致的高风险。相反,如果数据单元与业务单元(最重要的是顶层决策)紧密联系和集成,新的见解和中断就有可能揭示隐藏在公司数据中的真正价值。简而言之:数据成功的真正秘诀是在组织的其他地方感知数据,而不是在数据团队本身(Newman 2015)。

只有决策者和产品经理了解数据模型的全部潜力,重视从争论的数据和数据解决方案中产生的洞察力,任何计划才会成功。最大的危险是,数据团队只被视为一个被动的团队,提供按需报告或分析。一个关注面如此狭窄的团队,效果将非常有限。此外,数据团队必须能够利用业务知识来开发可行的解决方案。如果数据团队一方面能够利用所有数据科学方法解决更大的问题,另一方面能够充分理解给定的业务环境,就可以找到新的有效解决方案。通过与利益相关者紧密合作,创建协作解决方案并促进数据和业务知识的交流,输出将成为在内部、面向市场或面向客户的产品中可见的结果。有了这样的端到端结果,数据可以产生真正的业务影响。

毕竟,成功的数据计划的最后一个要素是授权。这包括培养正确的技能并相应地定义角色。先说技巧。鉴于上述观点,最重要的技能是数据人员能够(也确实)承担责任,表达和沟通复杂的问题,并且是自我组织的。由于拥有丰富数据技能的人往往在细节层次上变得有些数学化和复杂化,这显然不是一个容易实现的需求。对于喜欢细枝末节的人来说,另一项重要技能变得清晰起来。能够走捷径并在数据争论的某一点停止的能力足以刺激业务。这需要高度的结果导向。如果你足够幸运,能为你的团队找到具备这些技能的球员,你就可以大显身手了。如果没有,最重要的任务之一就是每天练习这些技能。

这就引出了最后一点。为了从非凡的成果中获益,数据处理人员的角色需要以这样一种方式定义,即他们能够从一端到另一端自主工作。这意味着发现和解决任务或问题的责任必须完全委托给负责人,包括他或她会做正确事情的信心。此外,必须确保所有必要和有用的资源可用(例如,所有必要的数据和上下文信息)。只有消除障碍(即知识、结果和数据可以容易地获得),才能取得优异的成果。

顺便说一句,我认为这些成功要素中的大部分以类似的方式适用于许多其他类型的团队和任务!

暂时就这样了。敬请期待第二部。在第二个故事中,我将阐述使数据驱动的计划成功的程序因素(即项目流程):

阅读第二部分:

https://medium . com/@ till . grupp/how-to-do-data-science-in-your-company-to-get-out-of-it-part-ii-73d 7 f 7 c 86 e 51

如何在你的公司做数据科学才能发挥最大作用?第二部分。

原文:https://towardsdatascience.com/how-to-do-data-science-in-your-company-to-get-the-most-out-of-it-part-ii-73d7f7c86e51?source=collection_archive---------14-----------------------

定义数据项目的流程并理解它们的双峰性质

在一家快速发展的公司中建立数据科学团队,我将分享一些我个人对如何克服困难并从贵公司的数据中获得最大价值的见解。在上一个故事中,我提出了进行数据科学的潜在结构和有利条件(组件):

阅读第一部分:
https://towards data science . com/how-to-do-data-science-in-your-company-to-get-out-of-it-aba8f 011 b 749

在这个故事中,我将为数据科学项目呈现一些面向结果的项目模式( Flow )。在下一个故事中,我将总结数据科学的知识和成功因素(油脂)。所有这三个故事都传达了在实现数据计划成果最大化的道路上取得的经验。

但是让我们现在就开始。下面我将概述我们如何管理和领导数据项目。这不是一项容易的任务,因为数据项目的性质可能非常不同:有些简明的问题需要快速清晰地回答,有些非常抽象的问题需要更广泛的理解和更全面的解决方案。为了描述数据项目的这种双峰性质,我将区分两种类型的项目:数据分析项目和新颖的数据解决方案。

数据分析项目

什么是数据分析项目?公司的努力应该以其对公司绩效 KPI 的影响来衡量。这对于学习采取什么行动是很重要的。根据我的观察,有前瞻性和回顾性思维的人:前者首先想了解一个主题,然后启动精心选择的措施,后者想快速跟随直觉,稍后才确认结果。两种观点有相似的要求:需要对一些 KPI 的一些问题进行分析,以了解范围、变化、绩效或差异,从而支持决策并消除偏见。但是,需要分析数据的时间点和问题类型不同。

数据分析项目有一定的特点:需求可以提前设定,有明确的预期结果,必要的努力在一定程度上可以提前预估。这是一个重要的特征,因为结果与决策者非常相关,并且是及时需要的。由于数据分析项目的要求有些固定,即使有时很复杂,也可以应用预定义的工作流来管理它们。这降低了风险,为请求者提供了透明性,并支持快速迭代。

Pipeline Flow of a Data Analysis Project

我们如何处理数据分析项目?

为了能够有效地处理分析数据项目,我们试图以面向过程的方式来管理它们。虽然我们通过不同的联系点和不同的团队收到请求,但我们会很好地协调它们。分析请求得到细化、优先化和规划。首先,我们试图理解哪个数据集市可以回答这个问题,需要什么样的分析,然后我们决定哪个团队处理这个分析。然后我们给请求者第一次反馈。当任务被执行时,我们获得数据,分析数据,与请求者一起审查结果,根据需要迭代,并快速及时地交流结果。对于大多数任务,我们使用标准流程。这不同于需要不同过程的新颖的数据解决方案,我将在下面进行描述。

新颖的数据解决方案

什么是新颖的数据解决方案?当我谈到这些 moonshot 项目之一时,我指的是新颖的数据解决方案,例如,试图预测具有特定属性和价格的产品是否会被销售,或者产品类型是否可以通过其图像来识别。与数据分析项目不同,人们对如何完成项目知之甚少。关注公司的模糊、复杂和一般性问题(例如,“我们想了解我们的产品”,“客户想要什么?”).我们称之为大问题。通过回答这些问题,可以开发出对业务和客户价值有重大影响的新产品和解决方案。

尽管新颖的数据解决方案为公司提供了很高的价值,但它们有着非常不同的性质:时间表通常不明确,难以估计。然而,需要付出巨大的努力才能获得初步的成果(有时是正常努力的 10 倍)。获得结果的方式是不明确的和探索性的,结果是非常不确定的。总之,这些类型的项目构成了高风险高收益的特征:它们可能被证明是根本不可行的,例如,因为所需的信息不包括在数据中,但是它们也可能对业务产生强烈的影响。这意味着他们甚至有可能扰乱和改变整个行业。结果,这些项目感觉像是“实验”,有些不寻常和独立,但是有许多依赖关系。

Explorative and Complex Flow of a Novel Data Solution

我们如何处理新奇的数据解决方案?

新颖的数据解决方案由于其非常复杂的性质和高度依赖性,只能被引导而不能被管理。提前计划并设定最后期限似乎会适得其反。然而,从我们最初的试点项目中获得一些经验后,我们开始通过一些深思熟虑的优化来管理风险。首先,我们从非常有选择性的优先级开始,只允许一些精心挑选的项目开始。这有助于保持注意力高度集中。其次,我们已经开始与的时间盒的初始快速迭代(比如一个两周的原型)一起工作,以便在我们忙于它之前获得一些经验和对问题的理解。最后,我们已经成为了早期失败的忠实粉丝。这就是为什么我们从一开始就开始从端到端地切入项目的初始版本,以查看陷阱在哪里。

从完整的新数据解决方案项目组合的角度来看,我们在早期阶段就开始收集和酝酿广泛的主题,与来自产品管理、开发、营销、客户关系和管理的所有关键利益相关方进行讨论。这体现在我们定期修订的一系列大问题中。这个列表帮助我们首先对一个主题进行初步的思考和假设,包括专家的观点和市场势头,直到我们决定下一个要关注的项目。我们已经学会了一步一步地“发展”新的数据解决方案,而不是计划太难。但是我们总是与正在运行的项目仔细协调,看看我们站在哪里,并且能够控制努力和风险。我们由此采用一种播种育种剔除收获的方法。分享这一点很重要:不要固定长期路线图!由于这类项目的本质,只需计划下一步并定期(至少每季度一次)修改现状,然后再计划下一个项目。然而,我们在我们同时运行的精选 moonshots 的明确投资组合上分散风险,因为在某些情况下,结果可能是零,但在其他情况下,结果可能是一切。

在整个过程中与所有利益相关者进行良好的沟通是非常重要的。开始时,主要目标是将商业知识和背景带入项目。随后,我们希望将风险透明化,找到潜在障碍的解决方案,并明确目标。在原型开发接近尾声时,可能的结果必须作为公司产品的一部分进行整合或测试,概念和数据模型必须投入生产。然而,由于新数据解决方案项目的模糊性,预先规划是非常困难的,因此与所有利益相关者的良好沟通必须对此进行补偿。

如何连接两部分

显然,这两种类型的项目很难组织在一起,因为它们会将紧急和重要之间的冲突推向极端。因此,优先考虑和保护所需数量的开放和更不确定的新数据解决方案非常重要。这可以通过“强门”来实现,即通过限制目前运行的项目总数和严格限制接受的特别问题的数量。这有助于“大问题”以集中的方式得到解决,并且正在进行的项目不会被更紧急和更实际的事情所阻碍。

How to Organize a Bimodal Data Project Pipeline

从我们的第一个数据项目中,我们开发了以下程序(见上图):

首先,评估来自业务部门或管理层的请求。在这一步,我们了解任务是需要统计模型支持还是需要以更线性的方式进行分析,哪个团队能最好地完成任务,任务有多复杂,任务的优先级如何,以及需要什么数据源。之后,我们可以将任务转给合适的人/团队(绕过季度路线图),或者如果是更复杂的任务,将任务安排在下一季度(通过季度路线图),或者如果是不需要立即解决的较难问题,我们可以将任务放在大问题列表中。

我们定期审查和更新包含“可以用数据回答的基本业务问题”的大问题列表。该列表包含我们多年来从利益相关者、集思广益、最佳实践和许多其他来源收集的潜在项目。该列表包含许多可能提供真正潜力的项目,但同时解决起来非常复杂(例如,了解用户、预测市场等等)。这些大题都是在迭代中逐步复习和提炼的。

其次,根据新兴的业务目标,我们每个季度都从列表中获得最有希望的大问题(“backlog”),并在我们的季度路线图中计划其中的一些问题(尽管我们知道有些问题可能需要一个季度以上的时间来解决,但这是限制首先投入的时间量的一个很好的方法,只有在审查后才继续)。季度路线图的剩余部分将由其他计划填充。

路线图中的主题和已经通过特别旁路的任务然后或者(1)在分析的情况下通过看板在数据团队中简单地执行,或者(2)为开发和机器学习团队的流程安排(如果任务需要更多的开发或机器学习工作),或者(3)为主题的第一个原型创建时间盒(如果它非常复杂并且需要首先开发更好的理解)。这个时间盒直接分配给个人或项目团队,其他任务的日程为分配的时间盒留出了空间。

为了让事情变得透明,backlog 和 boards 是开放的。此外,正在进行的和计划中的下一次迭代的项目会在公司内部定期交流。此外,如果需要保持信息流,直接受影响的产品经理或开发人员可以通过站立协调。

到目前为止,这些是我对如何组织数据项目的发现。在下一部分中,我将总结使数据驱动计划成功的一般见解和成功因素。敬请期待!

如何用图卷积网络在图上做深度学习

原文:https://towardsdatascience.com/how-to-do-deep-learning-on-graphs-with-graph-convolutional-networks-7d2250723780?source=collection_archive---------0-----------------------

第 1 部分:图卷积网络的高级介绍

图的机器学习是一项困难的任务,因为图的结构非常复杂,但也能提供丰富的信息。本文是关于如何使用图形卷积网络(GCNs)对图形进行深度学习的系列文章中的第一篇,图形卷积网络是一种强大的神经网络,旨在直接对图形进行处理并利用其结构信息。系列文章包括:

  1. 图卷积网络的高级介绍(this)
  2. 利用谱图卷积的半监督学习

在本帖中,我将介绍 GCNs,并使用编码示例说明信息如何通过 GCN 的隐藏层传播。我们将了解 GCN 如何聚合来自之前图层的信息,以及这种机制如何在图表中生成有用的节点要素表示。

什么是图卷积网络?

GCNs 是一种非常强大的神经网络架构,用于在图上进行机器学习。事实上,它们是如此强大,甚至一个随机启动的 2 层 GCN 也能产生网络中节点的有用特征表示。下图显示了由这种 GCN 产生的网络中每个节点的二维表示。注意,即使没有任何训练,网络中节点的相对接近度也保留在二维表示中。

更正式地说,图卷积网络(GCN) 是一种对图进行操作的神经网络。给定一个图 G = (V,E) ,一个 GCN 取为输入

  • 输入特征矩阵 N × F⁰ 特征矩阵, X, 其中 N 是节点的数量, F⁰ 是每个节点的输入特征的数量,并且
  • 图结构的一个 N × N 矩阵表示如 g[1]的邻接矩阵 A

GCN 中的一个隐藏层因此可以写成= f(h【ⁱ⁻】,a)其中h⁰=xf 为每层对应一个n×f特征矩阵,其中每一行都是一个节点的特征表示。在每一层,使用传播规则 f 聚集这些特征以形成下一层的特征。通过这种方式,每个连续层的特征变得越来越抽象。在这个框架中,GCN 的变体仅仅在传播规则的选择上有所不同。**

一个简单的传播规则

一个最简单的可能传播规则是[1]:

f(hⁱa)=σ(ahⁱwⁱ)

其中 Wⁱ 是层 i 的权重矩阵,而 σ 是非线性激活函数,例如 ReLU 函数。权重矩阵有维度f×fⁱ;换句话说,权重矩阵的第二维的大小决定了下一层的特征数量。如果你熟悉卷积神经网络,这个操作类似于过滤操作,因为这些权重在图中的节点间共享。

简单化

让我们从最简单的层面来研究传播规则。让

  • i = 1 ,s.t. f 是输入特征矩阵的函数,
  • σ 是恒等函数,并且
  • 选择权重 s . t .ahw⁰=axw⁰=ax

换句话说,f(XA)=AX。这个传播规则可能有点太简单了,但是我们稍后会添加缺少的部分。作为旁注, AX 现在相当于一个多层感知器的输入层。

一个简单的图表示例

作为一个简单的例子,我们将使用下图:

A simple directed graph.

而下面是它的numpy邻接矩阵表示。

**A = np.matrix([
    [0, 1, 0, 0],
    [0, 0, 1, 1], 
    [0, 1, 0, 0],
    [1, 0, 1, 0]],
    dtype=float
)**

接下来,我们需要特性!我们基于其索引为每个节点生成 2 个整数特征。这使得稍后手动确认矩阵计算变得容易。

**In [3]: X = np.matrix([
            [i, -i]
            **for** i **in** range(A.shape[0])
        ], dtype=float)
        XOut[3]: matrix([
           [ 0.,  0.],
           [ 1., -1.],
           [ 2., -2.],
           [ 3., -3.]
        ])**

应用传播规则

好吧!我们现在有一个图,它的邻接矩阵A和一组输入特征X。让我们看看应用传播规则时会发生什么:

**In [6]: A * X
Out[6]: matrix([
            [ 1., -1.],
            [ 5., -5.],
            [ 1., -1.],
            [ 2., -2.]]**

发生了什么事?每个节点(每行)的表示现在是其相邻要素的总和!换句话说,图形卷积层将每个节点表示为其邻域的集合。我鼓励你自己检查计算。注意,在这种情况下,如果存在从 vn 的边,则节点 n 是节点 v 的邻居。

啊哦!即将出现的问题!

您可能已经发现了问题:

  • 一个节点的聚合表示不包括它自己的特性!该表示是相邻节点的特征的集合,因此只有具有自环的节点才会将它们自己的特征包括在集合中。[1]
  • 度数较大的结点在其要素制图表达中将具有较大的值,而度数较小的结点将具有较小的值。这可能导致梯度消失或爆炸[1,2],但对于通常用于训练此类网络的随机梯度下降算法来说也是一个问题,该算法对每个输入要素的比例(或取值范围)非常敏感。

下面,我将分别讨论这些问题。

添加自循环

为了解决第一个问题,可以简单地给每个节点添加一个自环[1,2]。实际上,这是通过在应用传播规则之前将单位矩阵I添加到邻接矩阵A来完成的。

**In [4]: I = np.matrix(np.eye(A.shape[0]))
        IOut[4]: matrix([
            [1., 0., 0., 0.],
            [0., 1., 0., 0.],
            [0., 0., 1., 0.],
            [0., 0., 0., 1.]
        ])In [8]: A_hat = A + I
        A_hat * X
Out[8]: matrix([
            [ 1., -1.],
            [ 6., -6.],
            [ 3., -3.],
            [ 5., -5.]])**

由于该节点现在是其自身的邻居,所以在对其邻居的特征求和时包括了该节点自身的特征!

标准化要素制图表达

通过将邻接矩阵A乘以逆矩阵D【1】来转换邻接矩阵A,可以通过节点度来归一化特征表示。因此,我们简化的传播规则如下所示[1]:

f( X a)=d*ax*****

让我们看看会发生什么。我们首先计算度矩阵。

**In [9]: D = np.array(np.sum(A, axis=0))[0]
        D = np.matrix(np.diag(D))
        D
Out[9]: matrix([
            [1., 0., 0., 0.],
            [0., 2., 0., 0.],
            [0., 0., 2., 0.],
            [0., 0., 0., 1.]
        ])**

在应用规则之前,让我们看看变换后邻接矩阵会发生什么变化。

****在之前

**A = np.matrix([
    [0, 1, 0, 0],
    [0, 0, 1, 1], 
    [0, 1, 0, 0],
    [1, 0, 1, 0]],
    dtype=float
)**

****在之后

**In [10]: D**-1 * A
Out[10]: matrix([
             [0\. , 1\. , 0\. , 0\. ],
             [0\. , 0\. , 0.5, 0.5],
             [0\. , 0.5, 0\. , 0\. ],
             [0.5, 0\. , 0.5, 0\. ]
])**

注意,邻接矩阵的每一行中的权重(值)已经除以了对应于该行的节点的度数。我们用转换后的邻接矩阵应用传播规则

**In [11]: D**-1 * A * X
Out[11]: matrix([
             [ 1\. , -1\. ],
             [ 2.5, -2.5],
             [ 0.5, -0.5],
             [ 2\. , -2\. ]
         ])**

并且获得对应于相邻节点的特征的平均值的节点表示。这是因为(经变换的)邻接矩阵中的权重对应于相邻节点特征的加权和中的权重。我再次鼓励你亲自验证这个观察结果。

把所有的放在一起

我们现在将自循环和规范化技巧结合起来。此外,我们将重新引入之前为了简化讨论而放弃的权重和激活函数。

加回重量

首先要做的是应用权重。注意,这里的D_hatA_hat = A + I的度矩阵,即带有强制自循环的A的度矩阵。

**In [45]: W = np.matrix([
             [1, -1],
             [-1, 1]
         ])
         D_hat**-1 * A_hat * X * W
Out[45]: matrix([
            [ 1., -1.],
            [ 4., -4.],
            [ 2., -2.],
            [ 5., -5.]
        ])**

如果我们想要减少输出特征表示的维数,我们可以减少权重矩阵的大小W:

**In [46]: W = np.matrix([
             [1],
             [-1]
         ])
         D_hat**-1 * A_hat * X * W
Out[46]: matrix([[1.],
        [4.],
        [2.],
        [5.]]
)**

添加激活功能

我们选择保留特征表示的维度,并应用 ReLU 激活函数。

**In [51]: W = np.matrix([
             [1, -1],
             [-1, 1]
         ])
         relu(D_hat**-1 * A_hat * X * W)
Out[51]: matrix([[1., 0.],
        [4., 0.],
        [2., 0.],
        [5., 0.]])**

瞧啊。一个完整的隐藏层,有邻接矩阵,输入特征,权重和激活函数!

回到现实

现在,最后,我们可以将一个图卷积网络应用到一个真实的图上。我将向您展示如何生成我们在本文前面看到的要素制图表达。

扎卡里空手道俱乐部

扎卡里的空手道俱乐部是一个常用的社交网络,其中节点代表空手道俱乐部的成员,边代表他们的相互关系。当扎卡里在学习空手道俱乐部时,管理员和教练之间发生了冲突,导致俱乐部一分为二。下图显示了网络的图形表示,节点根据俱乐部的位置进行标记。管理员和讲师分别标有“A”和“I”。

Zachary’s Karate Club

建造 GCN

现在让我们建立图形卷积网络。我们实际上不会训练网络,只是简单地随机初始化它,以生成我们在本文开头看到的要素制图表达。我们将使用networkx,它有一个很容易得到的俱乐部的图形表示,并计算A_hatD_hat矩阵。

**from networkx import karate_club_graph, to_numpy_matrixzkc = karate_club_graph()
order = sorted(list(zkc.nodes()))A = to_numpy_matrix(zkc, nodelist=order)
I = np.eye(zkc.number_of_nodes())A_hat = A + I
D_hat = np.array(np.sum(A_hat, axis=0))[0]
D_hat = np.matrix(np.diag(D_hat))**

接下来,我们将随机初始化权重。

**W_1 = np.random.normal(
    loc=0, scale=1, size=(zkc.number_of_nodes(), 4))
W_2 = np.random.normal(
    loc=0, size=(W_1.shape[1], 2))**

堆叠 GCN 层。我们这里只使用单位矩阵作为特征表示,也就是说,每个节点被表示为一个独热编码的分类变量。

**def gcn_layer(A_hat, D_hat, X, W):
    return relu(D_hat**-1 * A_hat * X * W)H_1 = gcn_layer(A_hat, D_hat, I, W_1)
H_2 = gcn_layer(A_hat, D_hat, H_1, W_2)output = H_2**

我们提取特征表示。

**feature_representations = {
    node: np.array(output)[node] 
    for node in zkc.nodes()}**

瞧啊。将扎卡里空手道俱乐部的社区很好地分开的特征表示。我们甚至还没有开始训练!

Feature Representations of the Nodes in Zachary’s Karate Club

我应该注意到,对于这个例子,随机初始化的权重很可能在 x 轴或 y 轴上给出 0 值,作为 ReLU 函数的结果,所以需要一些随机初始化来产生上面的图。

结论

在这篇文章中,我对图卷积网络进行了高度的介绍,并举例说明了 GCN 中每一层节点的特征表示是如何基于其邻域的聚合的。我们看到了如何使用 numpy 构建这些网络,以及它们有多么强大:即使是随机初始化的 gcn 也可以在 Zachary 的空手道俱乐部中分离社区。

在下一篇文章中,我将更深入地介绍技术细节,并展示如何使用半监督学习来实现和训练最近发布的 GCN。你在这里** 找到系列 的下一篇帖子。**

喜欢你读的书吗?考虑在Twitter上关注我,在那里,除了我自己的帖子之外,我还会分享与数据科学和机器学习的实践、理论和伦理相关的论文、视频和文章。**

如需专业咨询,请在LinkedIn上联系我,或在Twitter上直接留言。**

参考

[1]Thomas Kipf 关于图卷积网络的博文。

[2]Thomas Kipf 和 Max Welling 的论文称为图卷积网络半监督分类

如何在计算机视觉中做所有的事情

原文:https://towardsdatascience.com/how-to-do-everything-in-computer-vision-2b442c469928?source=collection_archive---------10-----------------------

将深度学习魔法用于计算机视觉

Mask-RCNN doing object detection and instance segmentation

想获得灵感?快来加入我的 超级行情快讯 。😎

想做计算机视觉?深度学习是当今的趋势。大规模数据集加上深度卷积神经网络(CNN)的代表能力有助于建立超精确和稳健的模型。只剩下一个挑战:如何设计你的模型。

像计算机视觉这样广泛而复杂的领域,解决方案并不总是清晰的。计算机视觉中的许多标准任务都需要特别考虑:分类、检测、分割、姿态估计、增强和恢复以及动作识别。尽管用于它们中每一个的最先进的网络展示了共同的模式,但是它们仍然需要它们自己独特的设计。

那么,我们如何为所有这些不同的任务建立模型呢?

我来给你演示一下如何用深度学习做计算机视觉中的一切!

分类

其中最著名的!图像分类网络以固定大小的输入开始。输入图像可以有任意数量的通道,但对于 RGB 图像通常是 3 个。设计网络时,从技术上讲,分辨率可以是任何大小,只要它足够大,能够支持整个网络中的缩减采样量。例如,如果在网络内进行 4 次缩减采样,则输入的大小至少需要为 4 = 16 x 16 像素。

随着网络的深入,空间分辨率将会降低,因为我们试图压缩所有的信息,并得到一维向量表示。为了确保网络始终有能力传送它提取的所有信息,我们增加了与深度成比例的特征地图的数量,以适应空间分辨率的降低。也就是说,我们在下采样过程中丢失了空间信息,为了适应这种丢失,我们扩展了我们的特征图以增加我们的语义信息。

在您选择了一定数量的缩减像素采样后,要素地图将被矢量化并输入到一系列完全连接的图层中。最后一个图层的输出与数据集中的类一样多。

目标检测

物体探测器有两种类型:一级和二级。两者都是从“锚箱”开始的;这些是默认的边界框。我们的探测器将预测这些盒子和地面真相之间的差异,而不是直接预测盒子。

在两级检测器中,我们自然有两个网络:盒建议网络和分类网络。盒子提议网络在它认为物体存在的可能性很高的地方提议边界盒子的坐标;同样,这些是相对于锚盒的相对位置。然后,分类网络采用这些边界框中的每一个,并对位于其中的潜在对象进行分类。

在一级检测器中,建议和分类器网络融合成一个单级。网络直接预测边界框坐标和位于该框内的类。因为两级融合在一起,所以单级检测器往往比两级检测器更快。但是由于两个任务的分离,两级检测器具有更高的精度。

The Faster-RCNN two-stage object detection architecture

The SSD one-stage object detection architecture

分割

分割是计算机视觉中更独特的任务之一,因为网络需要学习低级和高级信息。低级信息用于按像素精确分割图像中的每个区域和对象,高级信息用于直接对这些像素进行分类。这导致网络被设计成将来自早期层和高分辨率(低级空间信息)的信息与更深层和低分辨率(高级语义信息)的信息相结合。

正如我们在下面看到的,我们首先通过一个标准的分类网络运行我们的图像。然后,我们从网络的每个阶段提取特征,从而使用从低到高范围的信息。在依次将它们组合在一起之前,每个信息级别都被独立处理。随着信息的组合,我们对特征图进行上采样,最终得到完整的图像分辨率。

要了解更多关于深度学习如何分割的细节,请查看这篇文章。

The GCN Segmentation architecture

姿态估计

姿态估计模型需要完成两项任务:(1)检测图像中每个身体部位的关键点(2)找出如何正确连接这些关键点。这分三个阶段完成:

(1)使用标准分类网络从图像中提取特征

(2)给定这些特征,训练一个子网络来预测一组 2D 热图。每个热图与特定的关键点相关联,并且包含每个图像像素关于关键点是否可能存在的置信度值

(3)再次给定来自分类网络的特征,我们训练子网络来预测一组 2D 矢量场,其中每个矢量场编码关键点之间的关联程度。然后,具有高关联性的关键点被称为是连通的。

用子网以这种方式训练模型将共同优化关键点的检测和它们的连接。

The OpenPose Pose Estimation architecture

增强和恢复

增强和恢复网络是他们自己独特的野兽。我们不会对这些图像进行任何下采样,因为我们真正关心的是高像素/空间精度。下采样将真正杀死这些信息,因为它将减少多少像素,我们有空间的准确性。相反,所有处理都是在全图像分辨率下完成的。

我们首先以全分辨率将我们想要增强/恢复的图像不加任何修改地传送到我们的网络。该网络简单地由许多卷积和激活函数的堆栈组成。这些块通常是受启发的,偶尔也是最初为图像分类开发的那些块的直接拷贝,例如剩余块、密集块、挤压激发块等。最后一层没有激活函数,甚至没有 sigmoid 或 softmax,因为我们想直接预测图像像素,不需要任何概率或分数。

这就是这些类型的网络的全部内容!在图像的全分辨率下进行大量处理,以实现高空间精度,使用已被证明适用于其他任务的相同卷积。

The EDSR Super-Resolution architecture

动作识别

动作识别是少数几个特别要求视频数据正常工作的应用之一。为了对一个动作进行分类,我们需要了解场景随时间发生的变化;这自然导致我们需要视频。我们的网络必须被训练以学习空间时间信息,即空间时间的变化。最完美的网络是 3D-CNN。

顾名思义,3D-CNN 是一个使用 3D 卷积的卷积网络!它们与常规 CNN 的不同之处在于,卷积是在三维空间中应用的:宽度、高度和时间 T21。因此,每个输出像素都是通过基于其周围的像素以及相同位置的前一帧和后一帧中的像素的计算来预测的!

Passing images in a large batch directly

视频帧可以通过几种方式传递:

(1)直接进行大批量,如第一图。因为我们传递的是一系列帧,所以空间和时间信息都是可用的

Single frame + optical flow (left). Video + optical flow (right)

(2)我们也可以在一个流中传递单个图像帧(数据的空间信息)和来自视频的其对应的光流表示(数据的时间信息)。我们将使用常规的 2D 有线电视新闻网从两者中提取特征,然后将它们组合起来传递给我们的 3D 有线电视新闻网,后者将两种类型的信息组合在一起

(3)将我们的帧序列传递给一个 3D CNN,并将视频的光流表示传递给另一个 3D CNN。两个数据流都具有可用的空间和时间信息。这可能是最慢的选择,但也可能是最准确的,因为我们正在对包含所有信息的两种不同的视频表示进行特定的处理。

所有这些网络输出视频的动作分类。

如何使用梯度下降进行线性回归

原文:https://towardsdatascience.com/how-to-do-linear-regression-using-gradient-descent-79a2ff4ace05?source=collection_archive---------3-----------------------

梯度下降是我从 Siraj Raval 的深度学习基础纳米学位中学到的第一个有趣的话题。这个练习的回购可以在这里找到

这个练习的目的是研究学生的考试成绩和学习时间之间的关系。为了实现这一目标,我们使用称为线性回归的策略来模拟因变量(学生的考试成绩)和解释变量(学习时间)之间的关系。我们还使用梯度下降来进一步优化我们的模型。梯度下降可能是机器学习和深度学习中最流行的方法。

我们的数据集包含 x-y 平面中的 x 和 y 数据点的集合,其中 x 是学生的考试分数,y 是学生学习的小时数。

我们使用 Python 以编程方式计算最佳拟合线,该线描述了学生学习的小时数和学生在测试中获得的分数之间的线性关系。我们使用 Python 是因为它被认为是最流行和最具语言性的机器学习框架。

我们将从一个非常标准的起始代码开始。

if __name__ = '__main__':
    run()

然后,我们使用 numpy 在内存中提取并解析我们的数据集,以在其上运行算法。我们使用分隔符',',意思是用来在。csv 文件

学习率是超级参数(即我们用作模型的调谐旋钮,或者模型学习的速度)

如果学习率太低,我们的模型将太慢而无法收敛,如果学习率太高,它将永远无法收敛。我们想要达到一个平衡,一个最佳的学习速度。在机器学习中,我们并不总是知道最佳学习速率会是多少,所以猜测和检查是获得该值的最佳方式

我们从初始 m 和 b 值= 0 (方程 y = mx+b) 开始。我们从 0 开始,因为我们将随着时间的推移学习这些值。迭代次数= 1000(即我们希望从每个训练步骤中学习多少次迭代)。我们选择 1000 步,因为我们数据集很小。随着数据集变大,考虑到 CPU 等因素,迭代次数应该是 10K 或 100K

我们通过使用gradient _ descent _ runner函数计算 b 和 m,函数的输入为“点”——x,y 点数组,初始 b 值为起始 b 值,初始 m 值为初始 m 值,学习速率和上面定义的迭代次数

from numpy import *def run(): points = genfromtext('data.csv', delimiter=',')
    learning_rate = 0.0001 #y = mx + b (slope formula) initial_b = 0
    initial_m = 0 # ideal slope, will start with 0 num_iterations = 1000

    [b, m] = gradient_descent_runner(points, initial_b, initial_m, learning_rate, num_iterations)

    print "After {0} iterations b = {1}, m = {2}, error = {3}".format(num_iterations, b, m, compute_error_for_line_given_points(b, m, points))

gradient_descent_runner 函数定义如下:

def gradient_descent_runner(points, starting_b, starting_m, learning_rate, num_iterations):

    b = starting_b
    m = starting_m for i in range(num_iterations):
        b, m = step_gradient(b,m, array(points), learning_rate return [b, m]

这里,我们将 starting_b 和 starting_m 值赋给 b 和 m,对于每次迭代,我们将通过将 b 和 m 的先前值输入 step_gradient 函数来计算 b 和 m,该函数接受 b、m 的值、点 x、y 的数组和学习速率

然后我们返回这个最佳对 b 和 m。

在我们编写“step_gradient”函数之前,我们将编写另一个函数,该函数计算给定一组点的 b 和 m 的线性模型的误差平方和的平均值:

def compute_error_for_line_given_points(b, m, points):
    totalError = 0
    for i in range(0, len(points)):
    x = points[i, 0]
    y = points[i, 1] totalError += (y - (m * x + b)) ** 2 return totalError / float(len(points))

为了确定如何用给定的点集来最好地拟合我们的模型,我们希望最小化这些点到我们的线性模型之间的距离。计算总误差有助于我们确定我们的模型有多差,这样我们就可以每一步都更新它。“y”是真实数据,mx+b 是我们的模型用来预测“y”的数据,取这些值之间的差值,就得到我们模型的正(或负)误差值。我们迭代地对这些平方差求和,并除以点数,以便获得我们的线性模型的误差平方和。3D 下图显示了所有可能的 x 轴截距、y 轴截距和误差值。我们想找到误差最小的点,即曲线的底部(或局部最小值)

然后,我们继续为我们的模型编写阶跃梯度函数。梯度可以最好地理解为斜率、切线或移动方向(向上或向下),以便最小化误差。

为了计算梯度,我们计算 b 和 m 的偏导数。然后,我们通过从学习率和每个值的梯度值的乘积中减去 b 和 m 的当前值来计算新的 b 和 m 值

def step_gradient(b_current, m_current, points, learning_rate):

    b_gradient = 0
    m_gradient = 0
    N = float(len(points)) for i in range(0, len(points)):
        x = points[i, 0]
        y = points[i, 1] b_gradient += -(2/N) * (y - ((m_current * x) + b_current))
        m_gradient += -(2/N) * x * (y - ((m_current * x) + b_current)) new_b = b_current - (learning_rate * b_gradient)
    new_m = m_current - (learning_rate * m_gradient) return [new_b, new_m]

这里的学习率允许我们的模型学习并收敛于 b 和 m 的新的优化值,然后用于根据给定的学习小时数预测测试分数

完整代码如下:

from numpy import *def compute_error_for_line_given_points(b, m, points):
    totalError = 0
    for i in range(0, len(points)):
        x = points[i, 0]
        y = points[i, 1] totalError += (y - (m * x + b)) ** 2 return totalError / float(len(points))def step_gradient(b_current, m_current, points, learning_rate):

    b_gradient = 0
    m_gradient = 0
    N = float(len(points)) for i in range(0, len(points)):
        x = points[i, 0]
        y = points[i, 1] b_gradient += -(2/N) * (y - ((m_current * x) + b_current))
        m_gradient += -(2/N) * x * (y - ((m_current * x) + b_current)) new_b = b_current - (learning_rate * b_gradient)
    new_m = m_current - (learning_rate * m_gradient) return [new_b, new_m]def gradient_descent_runner(points, starting_b, starting_m, learning_rate, num_iterations):

    b = starting_b
    m = starting_m for i in range(num_iterations):
        b, m = step_gradient(b,m, array(points), learning_rate return [b, m]def run(): points = genfromtext('data.csv', delimiter=',')
    learning_rate = 0.0001 #y = mx + b (slope formula) initial_b = 0
    initial_m = 0 # ideal slope, will start with 0 num_iterations = 1000

    [b, m] = gradient_descent_runner(points, initial_b, initial_m, learning_rate, num_iterations)

    print "After {0} iterations b = {1}, m = {2}, error = {3}".format(num_iterations, b, m, compute_error_for_line_given_points(b, m, points))if __name__ = '__main__':
    run()

来源:

1/ Siraj Raval 的《如何用梯度下降法做线性回归:【https://www.youtube.com/watch?v=XdM6ER7zTLk

2/深度学习纳米度:

https://www . uda city . com/course/deep-learning-nano degree-foundation-nd 101

如何用 BigQuery ML 做在线预测

原文:https://towardsdatascience.com/how-to-do-online-prediction-with-bigquery-ml-db2248c0ae5?source=collection_archive---------10-----------------------

BigQuery ML 是一种在 Google Cloud 上的 Pb 级交互式数据仓库中直接进行机器学习的方法。你可以在几分钟内在数百万行上训练机器学习模型,而不必四处移动数据。

注意:BigQuery ML 现在支持将训练好的模型提取为 TensorFlow SavedModel。所以你可以简单的 导出模型,然后将它 部署到云 AI 平台预测。也就是说,这篇文章仍然是有用的,它提醒我们如何看待权重,并重申 BQML 是一个开放系统的观点。

不过,训练完模型后,你需要用它来预测。开箱即用的 BigQuery 支持批量预测——这适用于报告和仪表板应用程序。但是,BigQuery 查询通常有 1-2 秒的延迟,因此批量预测功能不能用于在线预测(例如从 web 或移动应用程序)。

Sometimes your predictions need to return immediately

在本文中,我将向您展示如何从训练输出表中提取必要的权重和缩放参数,并自己计算预测。这些代码可以包装在 web 应用程序框架中,或者您希望预测代码存在的任何地方。

本文的完整代码在 GitHub 上的。

创建模型

让我们首先创建一个简单的预测模型来预测飞机的到达延迟(更多详细信息,参见本文)。我将使用这个模型来说明这个过程。

CREATE OR REPLACE MODEL flights.arrdelay
OPTIONS
  (model_type='linear_reg', input_label_cols=['arr_delay']) AS
SELECT
  arr_delay,
  carrier,
  origin,
  dest,
  dep_delay,
  taxi_out,
  distance
FROM
  `cloud-training-demos.flights.tzcorr`
WHERE
  arr_delay IS NOT NULL

这花了我大约 6 分钟,在 600 万行和 267 MB 数据上训练,花费大约 1.25 美元。( BigQuery 的自由层可能会帮你解决这个问题;为了降低成本,使用较小的表)。

模型批量预测

一旦有了训练好的模型,就可以在 BigQuery 内部进行批量预测。例如,要查找从 DFW 到洛杉矶国际机场的航班在一系列出发延迟时间内的预计到达延迟时间,您可以运行以下查询:

SELECT * FROM ml.PREDICT(MODEL flights.arrdelay, (
SELECT 
  'AA' as carrier,
  'DFW' as origin,
  'LAX' as dest,
  dep_delay,
  18 as taxi_out,
  1235 as distance
FROM
  UNNEST(GENERATE_ARRAY(-3, 10)) as dep_delay
))

在上面的查询中,我硬编码了承运人、原产地等的输入值。并使用 GENERATE_ARRAY 函数生成-3 分钟到 10 分钟范围内的出发延迟。这产生了一个表,该表具有每个出发延迟的预测到达延迟:

Predicted arrival delay if a flight from Dallas to Los Angeles departs 3 minutes early (dep_delay=-3) to 10 minutes late (dep_delay=10)

批量预测成本低。上面的查询处理了 16 KB,花费了 0.000008 美分。

虽然这种预测机制适用于离线预测,但实际上您不能将其用于在线预测。如果预测是作为网站或移动应用程序中用户交互的结果来显示的,那么您无法承受与每个 BigQuery 调用相关的 1-2 秒的延迟。您通常希望延迟在几毫秒的数量级,因此您需要一个更快的推理解决方案。

重量和比例

幸运的是,BigQuery 公开了自己计算预测值所需的所有信息。您可以将这些代码直接嵌入到您的应用程序中。我用 Python 来说明这一点,但是你可以用任何你想用的语言来说明。

你需要获取 3 条信息:

  • 使用此查询可以获得的每个数字列的权重:
SELECT
  processed_input AS input,
  model.weight AS input_weight
FROM
  ml.WEIGHTS(MODEL flights.arrdelay) AS model
  • 使用以下查询可以获得的每个数字列的缩放比例:
SELECT
  input, min, max, mean, stddev
FROM
  ml.FEATURE_INFO(MODEL flights.arrdelay) AS model
  • 使用该查询可以获得的每个分类列的词汇和权重(如果您不熟悉 UNNEST,请参阅本文):
SELECT
  processed_input AS input,
  model.weight AS input_weight,
  category.category AS category_name,
  category.weight AS category_weight
FROM
  ml.WEIGHTS(MODEL flights.arrdelay) AS model,
  UNNEST(category_weights) AS category

假设您已经将所有这三个查询的结果读入三个独立的 Pandas 数据帧,下面是一个计算预测的函数:

我正在做的是:我遍历每个数字列,并找到与该列相关的权重。然后,我取出平均值和标准差,用它们来调整输入值。两者的乘积就是与本专栏相关的贡献。然后,我遍历分类列。对于每个分类列,该列采用的每个值都有一个单独的权重。因此,我找到了与输入值相关联的权重,这就是贡献。所有贡献的总和就是预测。

上面的代码假设您训练了一个回归模型。如果你训练了一个分类模型,你需要对预测应用一个逻辑函数来得到概率(为了避免溢出,在 GitHub 上处理 pred < -500 as zero):

prob = (1.0/(1 + np.exp(-pred)) if (-500 < pred) else 0)

Here is an example of predicting the arrival delay of a specific flight:

rowdict = {
  'carrier' : 'AA',
  'origin': 'DFW',
  'dest': 'LAX',
  'dep_delay': -3,
  'taxi_out': 18,
  'distance': 1235
}
predicted_arrival_delay = compute_prediction(
  rowdict, numeric_weights,  scaling_df, categorical_weights)

This yields the following columns and their contributions:

col=dep_delay wt=36.5569545237 scaled_value=-0.329782492822 contrib=-12.0558435928
col=taxi_out wt=8.15557957221 scaled_value=0.213461991601 contrib=1.74090625815
col=distance wt=-1.88324519311 scaled_value=0.672196648431 contrib=-1.26591110699
col=__INTERCEPT__ wt=1.09017737502 scaled_value=1.0 contrib=1.09017737502
col=carrier wt=-0.0548843604154 value=AA contrib=-0.0548843604154
col=origin wt=0.966535564037 value=DFW contrib=0.966535564037
col=dest wt=1.26816262538 value=LAX contrib=1.26816262538

The total of the contributions is -8.31 minutes, which matches the batch prediction value, confirming that the code is correct.

The full code for this article is 的概率)。尽情享受吧!

如何在 OpenShift 上使用 Flask、uWSGI、NGINX 和 Docker 进行快速原型制作

原文:https://towardsdatascience.com/how-to-do-rapid-prototyping-with-flask-uwsgi-nginx-and-docker-on-openshift-f0ef144033cb?source=collection_archive---------4-----------------------

这篇文章将详细介绍将你的原型放入 Docker 容器的技术方面(带有参考代码), Docker 容器可以使用任意用户 id 在 OpenShift 上运行。

如果你像我一样,你喜欢一头扎进去,然后弄清楚它是如何工作的。为此,请随意查看 源代码图像 然后回来理解它是如何工作的。

对于我收集的许多数据科学原型,它们通常属于基本的 Flask 应用程序。就我个人而言,比起 Django,我更喜欢 Flask,因为同样的原因,在设计乐高雕塑时,我更喜欢单独的乐高积木,而不是 BURP 和 LURP。如果你感兴趣的话,这篇关于 Flask vs Django 的博客很好地展示了 web 框架的差异。

LEGO Brick, which do you prefer using when building?

为了在一个我们可以从对原型输出感兴趣的涉众那里获得反馈的环境中建立并运行原型,我们需要一个 web 服务器。为此,我们需要在网络上的真实 web 服务器中运行 Flask 应用程序。输入 NGINX 和 uWSGI!其他帖子详细介绍了这三个组件如何协同工作来服务您的 webapp,我们将探索如何让它在 Docker 和 OpenShift 中运行。

A Guide to Scaling Machine Learning Models in Production

有很多 Docker 教程,但是没有几个遵循 Docker 最佳实践。要让 Docker 映像在 OpenShift 这样的 Kubernetes 环境中运行,可能需要遵循更严格的最佳实践。我最近遇到的主要最佳实践是,您的容器应该作为“非根”(或任意)用户启动!

现在,让我们来看看让您的原型在这种类型的环境中运行所需的最低要求。为此,我们将定义一组配置文件,然后将它们合并到一个 Docker 映像中。

项目布局

$ tree .
.
├── deploy.sh
├── deployment
│   ├── docker-entrypoint.sh
│   ├── Dockerfile
│   ├── nginx.conf
│   ├── supervisord.conf
│   └── uwsgi.ini
└── src
    ├── __init__.py
    ├── static
    │   └── index.html
    └── wsgi.py

上述结构将所有的容器信息推送到“ deployment 文件夹,而所有的 Python 代码和资产作为伪模块放入“ src 文件夹。想象您的数据科学代码位于 src 下,并在 wsgi.py 文件中定义端点。在以后的文章中,我将介绍如何用 cookiecutter 标准化项目布局。

在这个结构中,要在调试模式下运行 Flask,我们可以简单地从命令行执行以下命令

$ python ./src/wsgi.py

在尝试将 Flask 应用程序放入 uWSGI、NGINX 和 Docker 映像之前,您应该使用上述命令进行所有本地验证测试,以确保 Flask 应用程序可以按预期运行和操作。

uWSGI 配置

在这篇文章中,我们想在 OpenShift 上运行 NGINX 和 uWSGI 中的 Flask 应用程序。所以我们需要首先配置 uWSGI,让它能够找到 Flask 应用程序。这在中完成。/deployment/uwsgi.ini 配置文件。

[uwsgi]
chdir=/opt/repo/src
chdir2=/opt/repo/src
master = true
module=wsgi
callable=app
buffer-size=65535
lazy=true
socket = /run/uwsgi.sock

这里我们定义了标准的 uWSGI 选项。要注意的主要选项是模块可调用。这两个参数指示 uWSGI 服务在哪里寻找要执行的 Python 代码。在我们的例子中,我们告诉它在“ /opt/repo/src ”文件夹中查找“ wsgi.py ”文件,以及该文件中的“ app ”变量(这是我们的主 Flask 可调用变量)。我们还为这个服务明确指定了套接字文件的位置,这需要与 NGINX 配置相匹配。

NGINX 配置

接下来,我们需要告诉 NGINX 它可以在哪里找到 uWSGI 套接字文件,这样当新的请求进入它正在监听的端口时,它知道如何相应地路由请求。这是在中完成的。/deployment/nginx.conf 文件。

pid /run/nginx.pid;
error_log /var/log/nginx/error.log;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    sendfile on;
    tcp_nopush on;

    client_body_temp_path /spool/nginx/client_temp 1 2;
    fastcgi_temp_path /spool/nginx/fastcgi_temp 1 2;
    proxy_temp_path /spool/nginx/proxy_temp 1 2;
    scgi_temp_path /spool/nginx/scgi_temp 1 2;
    uwsgi_temp_path /spool/nginx/uwsgi_temp 1 2;

    server {
        listen 8080;
        server_name localhost;

        access_log /var/log/nginx/access.log;

        location / {
            try_files $uri @app;
        }
        location @app {
            include uwsgi_params;
            uwsgi_pass unix:///run/uwsgi.sock;
        }
        location /static {
            alias /opt/repo/src/static;
            expires 1d;
        }
    }
}

在这里,我们明确定义了 NGINX 服务应该在哪里创建日志、临时文件,以及监听哪些端口。因为 OpenShift 将以任意用户的身份启动这个映像,所以我们不能使用任何低于 1024 的端口号(即特权端口,比如标准的 HTTP 80 或 HTTPS 443)。所以我们告诉服务监听端口 8080 。然后在位置路由中,我们告诉 NGINX 将所有请求路由到 uWSGI 套接字和 Python 应用程序(即“ @app ”),除了任何静态文件,它们应该直接进入磁盘上的那个文件夹。

超级用户配置

我们需要配置的最后一件事是让所有这些在单个映像中运行的方法。Docker 最佳实践强烈建议每个图像一个应用程序,但是在我们的例子中,我们需要 uWSGI 来运行我们的 Python 代码,NGINX 路由到 uWSGI。因此,我们将使用启动 Supervisord 的技巧来处理多个并发服务。这是在中完成的。/deployment/super visor . conf文件。

[unix_http_server]
file=/run/supervisor.sock
chmod=0770

[supervisord]
nodaemon=true
pidfile=/run/pid/supervisord.pid
logfile=/var/log/supervisor/supervisord.log
childlogdir=/var/log/supervisor
logfile_maxbytes=50MB
logfile_backups=1

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///run/supervisor.sock

[program:nginx]
command=/usr/sbin/nginx -g "daemon off;" -c /etc/nginx/nginx.conf
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

[program:uwsgi]
command=/usr/local/bin/uwsgi --ini /etc/uwsgi/apps-enabled/uwsgi.ini
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

在这里,我们明确了要为每个“服务”执行哪些命令,以及我们前面详述的配置文件的位置。通常,您可以以 root 用户身份启动 supervisord 或 systemd,并切换用户以执行特定的服务。然而,对于 OpenShift 上的任意用户 id,我们需要允许这些服务作为“root”组中的任何用户启动。这就是为什么我们没有在配置文件中指定任何用户参数,而是将日志路由到 /dev/stdout (这将允许它们在映像运行时显示在 Docker 日志文件中)。

码头入口点

配置文件都设置好了,我们只需要告诉 Docker 运行映像时要执行什么。在一些 Python 应用程序中使用任意用户 id 给这些计划带来了麻烦。此问题在问题 10496 中有详细记录。

好消息是有一个简单的解决方法。每次运行 Docker 映像时,我们只需要添加一个检查来验证任意用户在 /etc/passwd 文件中有一个条目。这在中完成。/deployment/docker-entry point . sh文件。

#!/bin/bash
set -e

# if the running user is an Arbitrary User ID
if ! whoami &> /dev/null; then
  # make sure we have read/write access to /etc/passwd
  if [ -w /etc/passwd ]; then
    # write a line in /etc/passwd for the Arbitrary User ID in the 'root' group
    echo "${USER_NAME:-default}:x:$(id -u):0:${USER_NAME:-default} user:${HOME}:/sbin/nologin" >> /etc/passwd
  fi
fiif [ "$1" = 'supervisord' ]; then
    exec /usr/bin/supervisord
fi

exec "$@"

但是,为了使其正确工作,我们需要设置 Docker 映像,以允许所有用户对/etc/passwd 文件进行写访问。一旦准备就绪,我们指定第二个条件来捕捉何时执行“supervisord”应用程序(它将依次执行 uWSGI 和 NGINX)作为任意用户 id,并将所有日志传送到/dev/stdout。

Dockerfile 文件

部署这个原型的最后一步是告诉 Docker 如何用我们上面指定的配置文件构建和配置映像。最好的部分是,一旦我们这样做了一次,我们就可以在多个项目的未来迭代中重用这个结构/映像!这是在中完成的。/deployment/Dockerfile 文件。

# Use the standard Nginx image from Docker Hub
FROM nginx

ENV HOME=/opt/repo

# install python, uwsgi, and supervisord
RUN apt-get update && apt-get install -y supervisor uwsgi python python-pip procps vim && \
    /usr/bin/pip install uwsgi==2.0.17 flask==1.0.2

# Source code file
COPY ./src ${HOME}/src

# Copy the configuration file from the current directory and paste 
# it inside the container to use it as Nginx's default config.
COPY ./deployment/nginx.conf /etc/nginx/nginx.conf

# setup NGINX config
RUN mkdir -p /spool/nginx /run/pid && \
    chmod -R 777 /var/log/nginx /var/cache/nginx /etc/nginx /var/run /run /run/pid /spool/nginx && \
    chgrp -R 0 /var/log/nginx /var/cache/nginx /etc/nginx /var/run /run /run/pid /spool/nginx && \
    chmod -R g+rwX /var/log/nginx /var/cache/nginx /etc/nginx /var/run /run /run/pid /spool/nginx && \
    rm /etc/nginx/conf.d/default.conf

# Copy the base uWSGI ini file to enable default dynamic uwsgi process number
COPY ./deployment/uwsgi.ini /etc/uwsgi/apps-available/uwsgi.ini
RUN ln -s /etc/uwsgi/apps-available/uwsgi.ini /etc/uwsgi/apps-enabled/uwsgi.ini

COPY ./deployment/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
RUN touch /var/log/supervisor/supervisord.log

EXPOSE 8080:8080

# setup entrypoint
COPY ./deployment/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh

# https://github.com/moby/moby/issues/31243#issuecomment-406879017
RUN ln -s /usr/local/bin/docker-entrypoint.sh / && \
    chmod 777 /usr/local/bin/docker-entrypoint.sh && \
    chgrp -R 0 /usr/local/bin/docker-entrypoint.sh && \
    chown -R nginx:root /usr/local/bin/docker-entrypoint.sh

# https://docs.openshift.com/container-platform/3.3/creating_images/guidelines.html
RUN chgrp -R 0 /var/log /var/cache /run/pid /spool/nginx /var/run /run /tmp /etc/uwsgi /etc/nginx && \
    chmod -R g+rwX /var/log /var/cache /run/pid /spool/nginx /var/run /run /tmp /etc/uwsgi /etc/nginx && \
    chown -R nginx:root ${HOME} && \
    chmod -R 777 ${HOME} /etc/passwd

# enter
WORKDIR ${HOME}
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["supervisord"]

这篇文章并不打算遍历 Dockerfile 文件的每一行。只需知道我们是从官方的 NGINX 构建(已经安装了 NGINX)开始,通过 PIP 添加几个 Python 包,并显式设置 NGINX、uWSGI 和 Supervisord 在执行期间需要接触的所有文件夹的权限,以便“root”组中的任意用户 id 拥有它需要的权限。最后,我们告诉映像查看默认运行的每个映像上的“ docker-entrypoint.sh ”文件以启动“ supervisord ”。

建立码头形象

要将上述所有构建块组合在一起,我们只需执行 Docker 映像的构建。这可以在您的本地计算机上通过以下方式完成:

$ cd {{project root directory}}
$ docker build -f ./deployment/Dockerfile -t prototype:latest .

在上面的例子中,我们需要从根目录执行构建,这样构建上下文就可以访问两个。/部署。/src 文件夹。

测试 Docker 图像作为任意用户 id

成功构建 Docker 映像是一回事,让它以任意用户 id 在 OpenShift 中运行则完全是另一回事。好消息是,我们可以在本地机器上用用户标志测试这一点

$ docker run -p 8080:8080 -u 112233 prototype:latest

在上面的例子中,我们选择了“ 112233 的任意用户 id,但是使用什么号码并不重要。您应该能够将其更改为任何数值,并且您的图像应该仍然能够正确运行(因此在 OpenShift 的任意用户 id 中是“任意的”)。

此外,我们将本地机器上的端口 8080 路由到容器内的 NGINX 服务,这意味着我们应该能够在本地机器上打开 web 浏览器,并在这些端点查看我们的简单原型:

  • http://localhost:8080/static/index . html:从 NGINX 加载静态 HTML 页面
  • http://localhost:8080/ :从 Flask 加载通用 home 端点
  • http://localhost:8080/Echo _ request:将请求头从 Flask 中回显给调用者

Docker 映像故障排除

如果上述方法不起作用,您需要在本地进行调试,以确定您的应用程序需要什么权限,并相应地修改 docker 文件。要调试映像,可以用以下内容覆盖 entrypoint 命令:

$ docker run -it -p 8080:8080 -u 0 prototype:latest /bin/bash

这将使您以 root 用户身份进入交互式 bash 命令提示符,以便您在本地挖掘映像内部的问题。您可能还需要切换-u 参数中使用的用户 id。使用 CTRL+D退出终止图像。

要测试 supervisord 的执行情况,可以在 bash 命令提示符下执行以下命令来查看日志,以确定问题可能是什么。

$ supervisorctl [start|stop|restart] nginx # NGINX service
$ supervisorctl [start|stop|restart] uwsgi # uWSGI service

有时,您的构建状态会因为一堆您不再需要的映像而变得“脏”,从而消耗 Docker 守护进程的磁盘空间。要清理这种情况,您可以运行:

$ docker system prune

部署到容器存储库

在我们修改了任意用户 id 几次,并且对单个图像原型的执行有信心之后,是时候将它推到容器存储库中进行部署了。

在 OpenShift 中有多种构建和部署映像的方法。在这篇文章中,我们不打算讨论部署管道。相反,我们需要做的只是将我们的映像推送到一个容器存储库(比如 Docker Hub),然后指示 OpenShift 提取并部署该映像。

首先,我们需要对我们的容器存储库进行认证。其中 yourhubusername 是你在容器库中的用户名,而youremail@company.com是你在容器库中指定的电子邮件地址。

$ docker login --username=yourhubusername --email=youremail@example.com

然后构建/标记/推送我们图像到容器存储库。其中 yourhubusername 是您在容器存储库上的用户名,您向其进行了身份验证。

$ docker build -f ./deployment/Dockerfile -t prototype:latest . 
$ docker tag $(docker images | grep ^prototype |awk '{print $3}') yourhubusername/prototype:latest
$ docker push yourhubusername/prototype:latest

现在图像应该在您的容器存储库中了!如果您使用的是 public Docker Hub,您可以通过此 URL 导航到您的存储库(在鉴定之后),并查看您的新图像:

https://hub.docker.com/

部署到 OpenShift

接下来,让我们告诉 OpenShift 从该映像进行部署。为此,我们将使用open shift CLI工具。首先,我们需要认证我们的 OpenShift 服务器。只需用您的 OpenShift 服务器替换 URL,用您的 OpenShift 令牌替换< MY_TOKEN >。

$ oc login https://my.openshift-servername.com --token=<MY_TOKEN>

为了从 CLI 创建部署,我们只需要告诉 OpenShift 在哪里定位我们的 Docker 映像。有关 OpenShift 配置的详细信息,请访问他们的部署如何工作页面。本质上,只需将它指向我们刚刚创建的容器存储库上的图像。

$ oc new-app yourhubusername/prototype

接下来,我们需要告诉 OpenShift 添加一条路线,这样我们的 web 流量就可以到达我们的图像。在下面,我们告诉它将流量路由到“prototype.example.com ”,以使用 TCP 8080 端口上的“prototype”服务。这有效地告诉 OpenShift 如何将流量路由到我们刚刚创建的 NGINX 映像。

$ oc create route edge --service=prototype --hostname=prototype.example.com --port=8080-tcp

现在,您应该能够导航到 hostname:port 组合,以任意用户身份查看在 OpenShift 上运行的应用程序!

神奇的迭代时间

现在我们已经完成了所有的配置和构建,我们可以快速迭代原型了!因为我们的 over 文件只是从复制了我们的 Python 代码。/src 文件夹中,要更新我们的映像,我们只需确保我们的新代码在中。/src 文件夹,并使用我们的 debug Flask 命令进行本地测试:

$ python ./src/wsgi.py

一旦我们对新功能感到满意,我们就可以用一个简单的来构建和推送图像。/deploy.sh 命令:

$ bash ./deploy.sh yourhubusername prototype latest

一旦该命令完成,您在 OpenShift 中的 URL 将对服务执行滚动更新,并在短短 5 分钟内在您的原型中展示您的新功能

源代码回购

这篇文章中引用的代码和配置的一个例子在我的 GitHub 页面这里

如何使用 scikit 进行无服务器机器学习-在 Google Cloud ML 引擎上学习

原文:https://towardsdatascience.com/how-to-do-serverless-machine-learning-with-scikit-learn-on-google-cloud-ml-engine-db26dcc558a2?source=collection_archive---------9-----------------------

在 Google 云平台上,Cloud ML Engine 提供无服务器的机器学习,用于训练、超参数优化和预测。直到最近,这还只是针对 TensorFlow 的。不过最近,该团队已经为 scikit-learn 实现了所有三种功能。在这篇文章中,我将带它兜一圈。

问题是在给定一些怀孕信息的情况下预测婴儿的体重。这是我用 TensorFlow 端到端解决的一个问题,在我为 GCP NEXT 2018 开发的训练营中。现在让我来谈谈 scikit-learn。跟着我一起看看 GitHub 上的这个 Jupyter 笔记本。

输入数据,从 BigQuery 到 Pandas

输入数据在 BigQuery 中,我将整个数据集的 1/1000 放入熊猫数据帧:

**def** query_to_dataframe(query):
  **import** **pandas** **as** **pd**
  **import** **pkgutil**
  privatekey = pkgutil.get_data(KEYDIR, 'privatekey.json')
  **print**(privatekey[:200])
  **return** pd.read_gbq(query,
                     project_id=PROJECT,
                     dialect='standard',
                     private_key=privatekey)

**def** create_dataframes(frac):  
  *# small dataset to fit into memory*
  **if** frac > 0 **and** frac < 1:
    sample = " AND RAND() < {}".format(frac)
  **else**:
    sample = ""

  train_query, eval_query = create_queries()
  train_query = "{} {}".format(train_query, sample)
  eval_query =  "{} {}".format(eval_query, sample)

  train_df = query_to_dataframe(train_query)
  eval_df = query_to_dataframe(eval_query)
  **return** train_df, eval_dftrain_df, eval_df = create_dataframes(0.001)

如果我使用较大的虚拟机,就有可能使用完整的数据集,我将在最后一步进行服务培训时这样做。然而,对于开发模型来说,拥有一个小的数据集是很有帮助的。

培训 sci kit-学习模型

为了训练模型,我首先编写了一个函数来获取用于训练的 x 和 y(我将它们称为特征和标签):

**def** input_fn(indf):
  **import** **copy**
  **import** **pandas** **as** **pd**
  df = copy.deepcopy(indf)

  *# one-hot encode the categorical columns*
  df["plurality"] = df["plurality"].astype(pd.api.types.CategoricalDtype(
                    categories=["Single","Multiple","1","2","3","4","5"]))
  df["is_male"] = df["is_male"].astype(pd.api.types.CategoricalDtype(
                  categories=["Unknown","false","true"]))
  *# features, label*
  label = df['label']
  **del** df['label']
  features = pd.get_dummies(df)
  **return** features, label

然后,我创建了一个 RandomForestRegressor,并将 x 和 y 传递给它的 fit()方法:

**from** **sklearn.ensemble** **import** RandomForestRegressor
estimator = RandomForestRegressor(max_depth=5, n_estimators=100, random_state=0)
estimator.fit(train_x, train_y)

通过在评估数据帧上调用 predict()并计算 RMSE,可以评估模型的性能:

**import** **numpy** **as** **np**
eval_x, eval_y = input_fn(eval_df)
eval_pred = estimator.predict(eval_x)
**print**(eval_pred[1000:1005])
**print**(eval_y[1000:1005])
**print**(np.sqrt(np.mean((eval_pred-eval_y)*(eval_pred-eval_y))))

将教练打包成一个包

代码运行后,我将以下 Jupyter 魔术添加到笔记本的单元格中,将单元格写出到 Python 文件中:

*#%writefile -a babyweight/trainer/model.py*

我还将许多硬编码的数字(比如随机森林中的树的数量)作为命令行参数。通过让它们成为命令行参数,我可以对它们进行超参数调优。

我在本地测试了这个包,仍然是在 1/1000 的数据集上:

%bash
export PYTHONPATH=${PYTHONPATH}:${PWD}/babyweight
python -m trainer.task \
   --bucket=${BUCKET} --frac=0.001 --job-dir=gs://${BUCKET}/babyweight/sklearn --projectId $PROJECT

无服务器培训

关于 Cloud ML Engine 的培训就像提交 Python 包一样简单:

RUNTIME_VERSION="1.8"
PYTHON_VERSION="2.7"
JOB_NAME=babyweight_skl_$(date +"%Y%m**%d**_%H%M%S")
JOB_DIR="gs://$BUCKET/babyweight/sklearn/${JOBNAME}"

gcloud ml-engine jobs submit training $JOB_NAME \
  --job-dir $JOB_DIR \
  --package-path $(pwd)/babyweight/trainer \
  --module-name trainer.task \
  --region us-central1 \
  --runtime-version=$RUNTIME_VERSION \
  --python-version=$PYTHON_VERSION \
  -- \
  --bucket=${BUCKET} --frac=0.1 --projectId $PROJECT

这一次,我在全部数据集的 1/10 上进行训练。为了在完整数据集上训练,我需要一台更大的机器。我可以通过更改为自定义层来做到这一点:

%writefile largemachine.yaml
trainingInput:
  scaleTier: CUSTOM
  masterType: large_model

并传入上面的配置文件:

RUNTIME_VERSION="1.8"
PYTHON_VERSION="2.7"
JOB_NAME=babyweight_skl_$(date +"%Y%m**%d**_%H%M%S")
JOB_DIR="gs://$BUCKET/babyweight/sklearn/${JOBNAME}"

gcloud ml-engine jobs submit training $JOB_NAME \
  --job-dir $JOB_DIR \
  --package-path $(pwd)/babyweight/trainer \
  --module-name trainer.task \
  --region us-central1 \
  --runtime-version=$RUNTIME_VERSION \
  --python-version=$PYTHON_VERSION \
  --scale-tier=CUSTOM \
  --config=largemachine.yaml \
  -- \
  --bucket=${BUCKET} --frac=1 --projectId $PROJECT --maxDepth 8 --numTrees 90

我如何获得最大深度和最大树数?为此,我做了超参数调整。

超参数调谐

对于 ML 引擎中的超参数调整,在评估后写出一个摘要度量。这是代码,假设您有一个名为 rmse 的变量,它保存最终的评估度量:

## this is for hyperparameter tuning
hpt = hypertune.HyperTune()
hpt.report_hyperparameter_tuning_metric(
    hyperparameter_metric_tag=’rmse’,
    metric_value=rmse,
    global_step=0)

要提交超参数优化作业,请使用要优化的参数编写一个配置文件:

%writefile hyperparam.yaml
trainingInput:
  hyperparameters:
    goal: MINIMIZE
    maxTrials: 100
    maxParallelTrials: 5
    hyperparameterMetricTag: rmse
    params:
    - parameterName: maxDepth
      type: INTEGER
      minValue: 2
      maxValue: 8
      scaleType: UNIT_LINEAR_SCALE
    - parameterName: numTrees
      type: INTEGER
      minValue: 50
      maxValue: 150
      scaleType: UNIT_LINEAR_SCALE

然后,通过以下方式将其传递给 ML 引擎:

--config=hyperparam.yaml

试验的输出将开始填充,如果您查看 GCP web 控制台,将会列出具有最低 RMSE 的试验及其运行时参数。

部署模型

经过培训后,可以部署 scitkit 学习模型:

gcloud alpha ml-engine versions create ${MODEL_VERSION} --model ${MODEL_NAME} --origin ${MODEL_LOCATION} \
    --framework SCIKIT_LEARN --runtime-version 1.8  --python-version=2.7

部署的模型有一个端点,您可以访问它来获得预测:

**from** **googleapiclient** **import** discovery
**from** **oauth2client.client** **import** GoogleCredentials
**import** **json**

credentials = GoogleCredentials.get_application_default()
api = discovery.build('ml', 'v1', credentials=credentials)

request_data = {'instances':
  *# [u'mother_age', u'gestation_weeks', u'is_male_Unknown', u'is_male_0',*
  *#     u'is_male_1', u'plurality_Single', u'plurality_Multiple',*
  *#     u'plurality_1', u'plurality_2', u'plurality_3', u'plurality_4',*
  *#     u'plurality_5']*
  [[24, 38, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0], 
   [34, 39, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0]]
}

parent = 'projects/**%s**/models/**%s**/versions/**%s**' % (PROJECT, 'babyweight', 'skl')
response = api.projects().predict(body=request_data, name=parent).execute()
**print** "response={0}".format(response)

目前,请求必须是文本行的形式,并且必须是预处理的数据。自然,这就对 scikit-learn 模型的可操作性提出了一些警告。

再说一遍,我的完整代码在 GitHub 上。编码快乐!

如何用 CNN,TensorFlow,单词嵌入做文本分类

原文:https://towardsdatascience.com/how-to-do-text-classification-using-tensorflow-word-embeddings-and-cnn-edae13b3e575?source=collection_archive---------0-----------------------

假设我给你一篇文章的标题“Twitter Bootstrap 的惊人扁平版本”,并问你这篇文章出现在哪个出版物上:纽约时报、TechCrunch 或 GitHub。你的猜测是什么?一篇题为“最高法院审理党派选区重大案件”的文章怎么样?

你猜到 GitHub 和纽约时报了吗?为什么?像 Twitter 和 Major 这样的词很可能出现在任何出版物中,但像 Twitter Bootstrap 和 Supreme Court 这样的词序列更有可能分别出现在 GitHub 和纽约时报中。我们能训练一个神经网络来学习这个吗?

注意:评估者现在已经进入核心张量流。 更新了使用 tf.estimator 而不是 tf.contrib.learn.estimator 的代码现已在 GitHub——以更新后的代码为起点。

创建数据集

机器学习就是从例子中学习。为了了解给定标题的文章的可能来源,我们需要大量文章标题及其来源的示例。尽管它存在严重的选择偏差(因为只包括 HN 书呆子成员感兴趣的文章),但黑客新闻文章的 BigQuery 公共数据集是这一信息的合理来源。

query="""
SELECT source, REGEXP_REPLACE(title, '[^a-zA-Z0-9 $.-]', ' ') AS title FROM
(SELECT
  ARRAY_REVERSE(SPLIT(REGEXP_EXTRACT(url, '.*://(.[^/]+)/'), '.'))[OFFSET(1)] AS source,
  title
FROM
  `bigquery-public-data.hacker_news.stories`
WHERE
  REGEXP_CONTAINS(REGEXP_EXTRACT(url, '.*://(.[^/]+)/'), '.com$')
  AND LENGTH(title) > 10
)
WHERE (source = 'github' OR source = 'nytimes' OR source = 'techcrunch')
"""
traindf = bq.Query(query + " AND MOD(ABS(FARM_FINGERPRINT(title)),4) > 0").execute().result().to_dataframe()
evaldf  = bq.Query(query + " AND MOD(ABS(FARM_FINGERPRINT(title)),4) = 0").execute().result().to_dataframe()

本质上,我从 BigQuery 中的黑客新闻故事数据集中提取 URL 和标题,并将其分离到一个训练和评估数据集中(完整代码请参见 Datalab 笔记本)。可能的标签是 github、纽约时报或 techcrunch。以下是生成的数据集的外观:

Training dataset

我将两只熊猫的数据帧写成 CSV 文件(总共有 72,000 个训练样本,大约平均分布在纽约时报、github 和 techcrunch 上)。

创造词汇

我的训练数据集由标签(“源”)和单个输入列(“标题”)组成。然而,标题不是数字,神经网络需要数字输入。因此,我们需要将文本输入列转换为数字。怎么会?

最简单的方法是对标题进行一次性编码。假设数据集中有 72,000 个唯一的标题,我们将得到 72,000 列。如果我们随后就此训练一个神经网络,这个神经网络基本上必须记住标题——没有进一步推广的可能。

为了让网络通用化,我们需要将标题转换成数字,使得相似的标题以相似的数字结束。一种方法是找到标题中的单个单词,并将这些单词映射到唯一的数字。然后,有相同单词的标题在这部分序列中会有相似的数字。训练数据集中的唯一单词集被称为词汇

假设我们有四个标题:

lines = ['Some title', 
         'A longer title', 
         'An even longer title', 
         'This is longer than doc length']

因为这些标题都有不同的长度,所以我会用一个虚拟单词来填充短标题,并截断很长的标题。这样,我就可以处理长度相同的标题了。

我可以使用下面的代码创建词汇表(这并不理想,因为词汇表处理器将所有内容都存储在内存中;对于更大的数据集和更复杂的预处理,比如合并停用词和不区分大小写, tf.transform 是更好的解决方案——这是另一篇博文的主题):

**import** **tensorflow** **as** **tf**
**from** **tensorflow.contrib** **import** lookup
**from** **tensorflow.python.platform** **import** gfile

MAX_DOCUMENT_LENGTH = 5  
PADWORD = 'ZYXW'

*# create vocabulary*
vocab_processor = tf.contrib.learn.preprocessing.VocabularyProcessor(MAX_DOCUMENT_LENGTH)
vocab_processor.fit(lines)
**with** gfile.Open('vocab.tsv', 'wb') **as** f:
    f.write("{}**\n**".format(PADWORD))
    **for** word, index **in** vocab_processor.vocabulary_._mapping.iteritems():
      f.write("{}**\n**".format(word))
N_WORDS = len(vocab_processor.vocabulary_)

在上面的代码中,我会用一个填充词填充简短的标题,我希望它不会出现在实际的文本中。标题将被填充或截短至 5 个单词的长度。我传入训练数据集(上面示例中的“lines”),然后写出结果词汇。词汇变成了:

ZYXW
A
even
longer
title
This
doc
is
Some
An
length
than
<UNK>

注意,我添加了 padword,词汇处理器在这组行中找到了所有独特的单词。最后,在评估/预测期间遇到的不在训练数据集中的单词将被替换为,因此这也是词汇表的一部分。

根据上面的词汇表,我们可以将任何标题转换成一组数字:

table = lookup.index_table_from_file(
  vocabulary_file='vocab.tsv', num_oov_buckets=1, vocab_size=None, default_value=-1)
numbers = table.lookup(tf.constant(**'Some title'**.split()))
**with** tf.Session() **as** sess:
  tf.tables_initializer().run()
  **print** "{} --> {}".format(lines[0], numbers.eval())

上面的代码将查找单词“Some”和“title ”,并根据词汇返回索引[8,4]。当然,在实际的训练/预测图中,我们还需要确保填充/截断。让我们看看接下来该怎么做。

文字处理

首先,我们从行(每行是一个标题)开始,将标题拆分成单词:

*# string operations*
titles = tf.constant(lines)
words = tf.string_split(titles)

这导致:

titles= ['Some title' 'A longer title' 'An even longer title'
 'This is longer than doc length']
words= SparseTensorValue(indices=array([[0, 0],
       [0, 1],
       [1, 0],
       [1, 1],
       [1, 2],
       [2, 0],
       [2, 1],
       [2, 2],
       [2, 3],
       [3, 0],
       [3, 1],
       [3, 2],
       [3, 3],
       [3, 4],
       [3, 5]]), values=array(['Some', 'title', 'A', 'longer', 'title', 'An', 'even', 'longer',
       'title', 'This', 'is', 'longer', 'than', 'doc', 'length'], dtype=object), dense_shape=array([4, 6]))

TensorFlow 的 string_split()函数最终创建了一个 SparseTensor。谈论一个过于有用的 API。但是我不希望自动创建映射,所以我将把稀疏张量转换成密集张量,然后从我自己的词汇表中查找索引:

*# string operations*
titles = tf.constant(lines)
words = tf.string_split(titles)
densewords = tf.sparse_tensor_to_dense(words, default_value=PADWORD)
numbers = table.lookup(densewords)

现在,densewords 和 numbers 与预期的一样(注意填充的 PADWORD:

dense= [['Some' 'title' 'ZYXW' 'ZYXW' 'ZYXW' 'ZYXW']
 ['A' 'longer' 'title' 'ZYXW' 'ZYXW' 'ZYXW']
 ['An' 'even' 'longer' 'title' 'ZYXW' 'ZYXW']
 ['This' 'is' 'longer' 'than' 'doc' 'length']]
numbers= [[ 8  4  0  0  0  0]
 [ 1  3  4  0  0  0]
 [ 9  2  3  4  0  0]
 [ 5  7  3 11  6 10]]

还要注意,数字矩阵具有数据集中最长标题的宽度。因为这个宽度会随着处理的每一批而变化,所以它并不理想。为了保持一致,让我们将其填充到 MAX_DOCUMENT_LENGTH,然后将其截断:

padding = tf.constant([[0,0],[0,MAX_DOCUMENT_LENGTH]])
padded = tf.pad(numbers, padding)
sliced = tf.slice(padded, [0,0], [-1, MAX_DOCUMENT_LENGTH])

这会创建一个 batchsize x 5 矩阵,其中较短的标题用零填充:

padding= [[0 0]
 [0 5]] 
padded= [[ 8  4  0  0  0  0  0  0  0  0  0]
 [ 1  3  4  0  0  0  0  0  0  0  0]
 [ 9  2  3  4  0  0  0  0  0  0  0]
 [ 5  7  3 11  6 10  0  0  0  0  0]] 
sliced= [[ 8  4  0  0  0]
 [ 1  3  4  0  0]
 [ 9  2  3  4  0]
 [ 5  7  3 11  6]]

在上面的例子中,我使用的 MAX_DOCUMENT_LENGTH 为 5,这样我可以向您展示正在发生的事情。在真实数据集中,标题长于 5 个单词。所以,在我会用

MAX_DOCUMENT_LENGTH = 20

切片矩阵的形状将是 batchsize x MAX_DOCUMENT_LENGTH,即 batchsize x 20。

把...嵌入

既然我们的单词已经被数字取代,我们可以简单地进行一次性编码,但这将导致非常广泛的输入——在标题数据集中有数千个独特的单词。一个更好的方法是减少输入的维度——这是通过嵌入层来实现的(参见完整代码):

EMBEDDING_SIZE = 10
embeds = tf.contrib.layers.embed_sequence(sliced, 
                 vocab_size=N_WORDS, embed_dim=EMBEDDING_SIZE)

一旦有了嵌入,我们现在就有了标题中每个单词的表示。嵌入的结果是一个 batch SIZE x MAX_DOCUMENT_LENGTH x EMBEDDING_SIZE 张量,因为一个标题由 MAX _ DOCUMENT _ LENGTH 个单词组成,每个单词现在用 EMBEDDING _ SIZE 个数字表示。(养成在 TensorFlow 代码的每一步计算张量形状的习惯——这将帮助你理解代码在做什么,维度意味着什么)。

如果我们愿意,我们可以简单地将嵌入的单词连接到一个深度神经网络中,训练它,然后开始我们的快乐之路。但是仅仅使用单词本身并没有利用单词序列具有特定含义的事实。毕竟,“最高法院”可以出现在许多场合,但是“最高法院”有更具体的含义。我们如何学习单词序列?

盘旋

学习序列的一种方法是不仅嵌入独特的单词,还嵌入二元模型(单词对)、三元模型(单词三元组)等。然而,对于相对较小的数据集,这开始变得类似于对数据集中的每个唯一单词进行一次性编码。

更好的方法是增加一个卷积层。卷积只是一种将移动窗口应用于输入数据并让神经网络学习应用于相邻单词的权重的方法。虽然在处理图像数据时更常见,但这是帮助任何神经网络了解附近输入之间的相关性的便捷方式:

WINDOW_SIZE = EMBEDDING_SIZE
STRIDE = int(WINDOW_SIZE/2)
conv = tf.contrib.layers.conv2d(embeds, 1, WINDOW_SIZE, 
                stride=STRIDE, padding='SAME') # (?, 4, 1)    
conv = tf.nn.relu(conv) # (?, 4, 1)    
words = tf.squeeze(conv, [2]) # (?, 4)

回想一下,嵌入的结果是一个 20 x 10 的张量(我们暂且忽略 batchsize 这里的所有操作都是一次对一个标题进行的)。我现在将 10x10 窗口中的加权平均值应用于标题的嵌入表示,将窗口移动 5 个单词(步幅=5),然后再次应用它。所以,我会有 4 个这样的卷积结果。然后,我对卷积结果应用非线性变换(relu)。

我现在有四个结果。我可以简单地将它们通过密集层连接到输出层:

n_classes = len(TARGETS)     
logits = tf.contrib.layers.fully_connected(words, n_classes, 
                                    activation_fn=None)

如果你习惯于图像模型,你可能会感到惊讶,我用了卷积层,但没有最大池层。使用 maxpool 图层的原因是为了增加网络的空间不变性-直观地说,您希望找到一只猫,而不管这只猫在图像中的位置。然而,标题中的空间位置非常重要。很有可能《纽约时报》文章的标题与 GitHub 文章的标题有所不同。因此,我没有在这个任务中使用 maxpool 层。

给定 logit,我们可以通过执行 TARGETS[max(logit)]来找出源。在 TensorFlow 中,这是使用 tf.gather 完成的:

predictions_dict = {      
'source': tf.gather(TARGETS, tf.argmax(logits, 1)),      
'class': tf.argmax(logits, 1),      
'prob': tf.nn.softmax(logits)    
}

为了完整起见,我还发送了实际的类索引和每个类的概率。

培训和部署

代码都写好了(见完整代码这里),我就可以在 Cloud ML 引擎上训练它了:

OUTDIR=gs://${BUCKET}/txtcls1/trained_model
JOBNAME=txtcls_$(date -u +%y%m%d_%H%M%S)
echo $OUTDIR $REGION $JOBNAME
gsutil -m rm -rf $OUTDIR
gsutil cp txtcls1/trainer/*.py $OUTDIR
gcloud ml-engine jobs submit training $JOBNAME \
   --region=$REGION \
   --module-name=trainer.task \
   --package-path=$(pwd)/txtcls1/trainer \
   --job-dir=$OUTDIR \
   --staging-bucket=gs://$BUCKET \
   --scale-tier=BASIC --runtime-version=1.2 \
   -- \
   --bucket=${BUCKET} \
   --output_dir=${OUTDIR} \
   --train_steps=36000

数据集非常小,所以训练不到五分钟就结束了,我在评估数据集上获得了 73%的准确率。

然后,我可以将该模型作为微服务部署到云 ML 引擎:

MODEL_NAME="txtcls"
MODEL_VERSION="v1"
MODEL_LOCATION=$(gsutil ls \
     gs://${BUCKET}/txtcls1/trained_model/export/Servo/ | tail -1)
gcloud ml-engine models create ${MODEL_NAME} --regions $REGION
gcloud ml-engine versions create ${MODEL_VERSION} --model \
     ${MODEL_NAME} --origin ${MODEL_LOCATION}

预言;预测;预告

为了让模型进行预测,我们可以向它发送一个 JSON 请求:

**from** **googleapiclient** **import** discovery
**from** **oauth2client.client** **import** GoogleCredentials
**import** **json**

credentials = GoogleCredentials.get_application_default()
api = discovery.build('ml', 'v1beta1', credentials=credentials,
            discoveryServiceUrl='https://storage.googleapis.com/cloud-ml/discovery/ml_v1beta1_discovery.json')

request_data = {'instances':
  [
      {
        'title': 'Supreme Court to Hear Major Case on Partisan Districts'
      },
      {
        'title': 'Furan -- build and push Docker images from GitHub to target'
      },
      {
        'title': 'Time Warner will spend $100M on Snapchat original shows and ads'
      },
  ]
}

parent = 'projects/**%s**/models/**%s**/versions/**%s**' % (PROJECT, 'txtcls', 'v1')
response = api.projects().predict(body=request_data, name=parent).execute()
**print** "response={0}".format(response)

这会产生一个 JSON 响应:

response={u'predictions': [{u'source': u'nytimes', u'prob': [**0.777**5614857673645, 5.86951500736177e-05, 0.22237983345985413], u'class': 0}, {u'source': u'github', u'prob': [0.1087314561009407, **0.890**9648656845093, 0.0003036781563423574], u'class': 1}, {u'source': u'techcrunch', u'prob': [0.0021869686897844076, 1.563105769264439e-07, **0.997**8128671646118], u'class': 2}]}

经过训练的模型预测,最高法院的文章有 78%的可能性来自《纽约时报》。根据该服务,Docker 的文章 89%可能来自 GitHub,而时代华纳的文章 100%可能来自 TechCrunch。那是 3/3。

资源:所有代码都在 GitHub 这里:https://GitHub . com/Google cloud platform/training-data-analyst/tree/master/blogs/text classification

如何将闪亮的应用程序分类——第 1 部分

原文:https://towardsdatascience.com/how-to-dockerize-an-r-shiny-app-part-1-d4267659312a?source=collection_archive---------2-----------------------

Docker : Representational Image

在我之前的帖子中,我写了如何在 AWS cloud 上托管一个 R shiny 应用程序。成功托管应用后,您的终端用户可以轻松访问该应用。但是,如果您的最终用户希望在他们的系统中本地托管应用程序,并可能对应用程序本身进行更改,该怎么办呢?

虽然我在上一篇文章中展示了一个“Hello world”版本,但在真实的工作环境中,R shiny 应用程序可能会变得非常复杂。一些闪亮的应用程序可以在后端运行复杂的算法,例如客户流失预测、设备故障概率、天气预测等。所有这些用 R 写的算法都调用了很多包。这些软件包中的一些可能与接收者系统中安装的 R 版本不兼容。

当我在真实环境中托管一个闪亮的应用程序时,我也面临着许多障碍,包括缺少数据文件、缺少工作空间、缺少闪亮的应用程序组件(UI。R &服务器。r ),当然更不用说各种缺失或不是“最新”的库包了。我希望有一种方法,负责开发 R shiny 应用程序的人只需给我一个 zip 文件,去掉所有依赖项,我所要做的就是解压缩并运行代码来托管应用程序。有些人可能会说这是痴心妄想,但事实并非如此。进入‘码头工人’。

什么是码头工人?

尽管软件工程人员可能已经知道了 Docker,但我将尝试用通俗的语言为不熟悉它的人解释。所以它开始了

想象你在地球上某个偏远的小镇。你希望用乐高搭建一个玩具建筑,但是你所在的城镇既没有乐高,也不知道如何把积木拼起来搭建一个建筑。

Image source : http://www.thinkgeek.com/product/edab/

输入您的朋友“码头工人”。码头工人已经用乐高积木预建了这座建筑,并将其包装在一个礼品盒中。谈论理想的圣诞礼物😉。现在你要做的就是打开包装,把它放在你的桌子上。Tada!!!你的愿望实现了。

你刚刚避免了哪些麻烦

购买正确的乐高积木,帮助你建造玩具建筑

将乐高积木拼在一起

故意拖延时间

现在让我们扩展乐高类比,更深入地研究 Docker。

乐高积木类似于您的代码及其依赖项(包、库)和环境(操作系统、软件版本、IDE)。

礼品盒是安全地包含所有组件的“容器”。

你打开包装并安全地把它放在桌子上就是代码的部署。

进行上述操作时,您的优势是

您不必安装该语言的最新版本或其包/库

您不必配置您的环境

你可以直接部署代码,是的,你节省了很多时间

好了,现在我们对 Docker 有了一个直观的概念,让我们更进一步,从技术上探索它。

引擎盖下的 Docker:

Docker 基本上是一个容器。容器是图像的运行实例。

Image 是运行代码的环境的快照。它包含操作系统、软件和库包。

dockerfile 文件有助于定义图像。这是创建图像的一系列步骤。它将包含加载哪些库包、从哪里复制文件以及将文件复制到哪个位置的详细信息。

下图恰当地说明了这一过程

Picture adapted from Slideshare

杰克·赖特写的关于码头工人的优秀教程可以在下面的链接中看到。

所以伙计们,Docker 帮助托管一个 R shiny 应用程序,如下图所示。多亏了 Docker,系统 B 成功托管了闪亮的应用程序。

Representational image of R shiny app hosted successfully

希望你喜欢我的文章。这里是第二部

你可以联系我

领英

推特

如何将一个闪亮的应用程序分类——第二部分

原文:https://towardsdatascience.com/how-to-dockerize-an-r-shiny-app-part-2-b029d915e6ac?source=collection_archive---------12-----------------------

大家好!!

首先,我想为第二部分的出版延迟道歉。延迟的原因是第 2 部分的一些博客材料(命令、快照)在我的笔记本电脑中被意外删除了。

由于时间不够,而且我的工作性质变得更像数据科学,而不是开发工作/数据工程,不允许我将这些碎片拼凑起来,使之成为一篇有价值的文章。

然而,自从我读完第一部分后,我已经收到了很多读者关于第二部分的询问。我最终决定写第二部分。

所以,读者们,感谢你们的耐心。让我们从我在第 1 部分留下的地方开始阅读这篇文章。

好吧,那么,快速复习一下 Docker 及其概念。

什么是 Docker、Container 和 Dockerfile?

Docker 基本上是一个容器。容器是图像的运行实例。

Image 是运行代码的环境的快照。它包含操作系统、软件和库包。

Dockerfile 文件有助于定义图像。这是创建图像的一系列步骤。它将包含加载哪些库包、从哪里复制文件以及将文件复制到哪个位置的详细信息。

下图恰当地说明了这一过程

Picture adapted from Slideshare

如何将一个 R 闪亮的 App Dockerize

因此,这里有一系列的步骤来解释如何做到这一点。

第一步:安装 Oracle VM 虚拟箱

第二步:安装 Centos,也可以使用 ubuntu。

给出用户名和密码

你会看到如下图片

第三步:获取 docker CE for centos(https://docs . docker . com/engine/installation/Linux/docker-CE/centos/)

第四步:启动 docker(见下图)

第五步:运行 hello world(见下图)

第六步:创建文件夹。例如图像

通过命令:须藤 mkdir 图片

步骤 7 :创建 docker 文件(如 dock)

命令: Vi dock

按 I 键开始进入文件。输入详细信息后

按 esc -> : wq

docker 文件如下所示。这个 dockerfile (摇滚/闪亮)我是从 dockerhub 本身拿的。你可以调整 docker 文件例如,你可以安装一个你选择的 R 版本。

请注意,需要在 docker 文件中设置代理。

接下来的步骤将告诉你如何将 R Shiny 应用程序的内容复制到“images”文件夹中

第八步:输入 ip add 命令,获取虚拟机的 Ip 地址

第九步:打开 winscp 输入 ip

单击登录

步骤 10 :现在将 R shiny app 内容 s 复制到文件夹中

步骤 11 :现在输入 docker 图片

步骤 12 :复制图像 ID 或标签(在我的例子中,图像 ID 是 144146d3d082)

步骤 13 :运行以下命令

docker run--RM-p 3838:3838 144146 d3d 082

第 14 步:使用 vm 后缀:3838 的 ip,然后按回车键,你闪亮的 app 托管成功,对接成功!!。

见下图

现在你可能会问,用户如何在他/她的系统中部署 R shiny 应用程序?要做到这一点,需要采取以下步骤。

第 15 步:加载图像并放入 tar 文件格式(使用下面的命令:用你的应用程序的名称替换‘App ’)

docker save-o ~/App . tar App

步骤 16 :把这个 tar 文件交给安装了 docker 的用户就可以了。

步骤 17 :用户只需加载图片,然后运行 app。

步骤 18 :闪亮的 app 成功托管在用户系统上!!

伙计们,就是这样。再次感谢你的耐心。有很多种方法可以将一个 R Shiny App docker ize。本文采用虚拟机路线,也有其他方法。一个很好的来源是这个博客。

希望你喜欢这篇文章。如果你做了,你可以给它一些掌声。

你可以联系我

领英

推特

如何下载您所有的原始 fitbit 数据

原文:https://towardsdatascience.com/how-to-download-all-of-your-raw-fitbit-data-d5bcf139d7ed?source=collection_archive---------7-----------------------

出于好奇,有些人会想挖掘自己所有的原始 fitbit 数据。在本文中,我将讨论如何实际检索原始 fitbit 数据,假设他们有兴趣并且知道如何这样做。

2019 年更新

FitBit 现在提供一次性下载你所有的数据!从网页浏览器进入你的 fitbit 账户设置,将一个大的 zip 文件放入队列。您将收到一封电子邮件,内容如下:

所需操作:确认您的 Fitbit 数据导出请求

按照那里的指示,你就完成了!下面的原始博客帖子仍然具有编程价值,FitBit 限制了您重新下载所有数据的 zip 文件的频率,因此仍然有理由使用我在这里描述的应用程序编程接口方法。感谢媒体用户侏儒在八月份对这个选项的评论。该功能至少从 2019 年 4 月开始出现。

附文

在这种情况下,短语“原始数据”不是指加速度计信号,如你慢跑时的手速,这些信号经过瞬时片内处理,以识别每个原子脚步或楼梯攀爬。蓝牙带宽和电池寿命方面的考虑限制了你的 fitbit 设备只能将聚合数据传输到你的手机、平板电脑或电脑上。

在这种情况下,原始数据是指可用的最细粒度形式的数据,即 fitbit 生成并上传到云中某处持续更新的数据库的所谓数据耗尽。目前,最精细的数据形式是你每分钟的步数、心率和睡眠时间序列。

FitBit(该公司,不同于 fitbit ,追踪器/应用)声明“你的数据属于你”:任何人都可以在任何时候访问他或她自己的数据。尽管如此,在实践中检索数据需要克服一些重大的技术障碍。在过去的两年里,我开发并应用了一个 Python 框架来查询我的 fitbit 数据并将其编译成易于使用的格式,以便进行交互式数据科学和个人生理学研究。这是我发现的。

以编程方式访问 fitbit 数据

查看博客顶部今年的更新,您现在可以一次性下载您所有的 fitbit 数据!

据我所知,没有办法一次性下载你所有的 fitbit 数据。—这篇博文,2018

FitBit 在其开发者网站上提供应用编程接口(API),其中门户网站包含关于如何获取数据的适度高级指令。登录到 fitbit 帐户后,您可以阅读文档以了解系统如何工作。你将不得不用 RESTful HTTP 请求编写查询。如果您以前没有这样做过,这需要一点时间来适应,但是有一个例子可以说明这一点。如果您想获得从 2018 年 9 月 21 日开始的所有“日内心率数据”,您应该编写这个长 HTTP 查询字符串:

[https://api.fitbit.com/1/user/-/activities/heart/date/2018-09-21/1d/1min.json](https://api.fitbit.com/1/user/-/activities/heart/date/2018-09-21/1d/1min.json)

…但是你还没有完成。你需要说明你想如何处理这些数据——获取、更改或删除——并且你需要证明你有权这么做。有史以来最受欢迎的 Python 包之一, requests ,如果您了解 Python,它允许您以编程方式执行这些命令。每一种现代计算语言都有一个等同于请求的语言,但是我将主要关注 Python。在 Python 中,您可以:

import requests
response = requests.get(query_str, headers=secret_header)

其中query_str是上面的查询字符串,secret_header包含关于您的授权的信息。

批准

只有你能看到你的“日内”数据 FitBit 采用这个名称来表示你的心率和步数的每分钟时间序列。FitBit 使用标准的加密安全认证程序来验证你的身份,它们使检索当天数据变得特别困难:你需要注册一个免费的个人应用程序来获得 API 客户端证书。这篇 2016 的博文描述了如何让你的secret_token成为标题。一旦你有了令牌,你就可以写:

secret_header = {‘Authorization’: ‘Bearer {}’.format(secret_token)}

注意,这个秘密令牌不应该公开共享——毕竟,它是秘密的。

保存和检查数据

您得到的响应对象包含json格式的数据,它有多层原始数据和元数据。出于备份目的,您可以将未删节的数据保存在本地(推荐):

import json
with open(path, ‘w’) as f:
     json.dump(response.json(), f)

…其中,path是一个描述性的文件名,您可以编造,例如HR_20180921_1d_1min.json。当您准备好分析您的数据时,您可以将笨拙的 json 格式打开成更方便的pandas DataFrame:

import pandas as pd
with open(path, ‘r’) as f:
     json_data = json.load(f)
df = pd.DataFrame(json_data[‘activities-heart-intraday’][‘dataset’])

现在,您可以开始检查、合并和转换数据,以制作一些令人惊叹的图表。根据我的经验,我不得不做一些标准的清理操作,比如将索引设置为日期和时间,并将“值”重命名为更具信息性的名称,比如“heart_rate”或简单的“HR”。数据清理、合并和分析的主题是另一篇文章的主题。

My intraday heart rate data for January 1, 2017, from midnight to midnight.

纵向扩展和横向扩展

此时,下一步是获取所有数据。你可能想写一个for-循环所有可用的日期和所有可用的数据类型。你将遇到的主要问题是,FitBit 只允许你每小时请求 150 包数据。这种看似反常的速率限制可能令人沮丧,但在公共 API 中是一种常见的做法——我们将不得不绕过节流。在你的 for 循环中插入下面的小技巧,在计算机等待下一个小时的时候显示一个实时的进度条:

from tqdm import tqdm
import timeif response.status_code == 429:
     wait = int(response.headers[‘Fitbit-Rate-Limit-Reset’])+30 
     for seconds in tqdm(range(wait)):
         time.sleep(1)

如果你有一个启用心率的 fitbit(如 Charge 2Alta HR ,那么你将可以访问至少三个当天数据流:1) 步数,2) 心率,以及 3) 睡眠。如果你有,比如说,2 年的这些数据,你最终会得到成千上万的文件 :
2 years * 365 days/year * 3 streams/day * 1 file/stream = 2190 files

…假设您将每天和每个流的完整 json 数据保存到自己的文件中。你一次只能下载 150 个文件,所以你要花 15 个小时才能得到所有 2 年的数据。FitBit 文档确实一次提供了更多天的查询,所以如果您不耐烦等待 15 个小时以上,您可以尝试这些替代方法。

辅助数据

你可能还想要其他类型的数据,比如健身活动日志、可选的 GPS 地图文件、体重日志(假设你有 fitbit Aria ,或者你手动记录你的体重),等等。我不会详细介绍如何下载这些文件,但是这些方法非常相似,并且在 FitBit Web API 上有很好的记录。

回顾和展望

普通 fitbit 用户能够完成所有这些步骤的现实程度如何?不太可能。然而,普通的 fitbit 用户可能会从非常好的 fitbit 应用程序和网络仪表盘中获得大多数可用的见解。原始的 fitbit 日内数据很吸引人,但从中收集见解需要一些相当先进的数据科学技能,或者至少需要大量的奉献。

如何让 Pandas 从服务帐户访问 BigQuery

原文:https://towardsdatascience.com/how-to-enable-pandas-to-access-bigquery-from-a-service-account-205a216f0f68?source=collection_archive---------7-----------------------

服务账户是一种严格控制你的应用程序在谷歌云平台上做什么的方式。您通常希望应用程序对组织资源的访问受到严格限制,而不是使用您的用户帐户拥有的所有权限来运行应用程序。

How to use a private key in a service account to access BigQuery from Pandas

假设您希望 Pandas 针对 BigQuery 运行一个查询。您可以使用熊猫的 read_gbq(在 pandas-gbq 包中提供):

import pandas as pdquery = """
SELECT
  year,
  COUNT(1) as num_babies
FROM
  publicdata.samples.natality
WHERE
  year > 2000
GROUP BY
  year
"""df = pd.read_gbq(query,
                     project_id='MY_PROJECT_ID',
                     dialect='standard') print(df.head())

如果您在本地运行它,这将会起作用(因为它使用您的身份,并且假设您有能力在您的项目中运行查询)。

但是,如果您尝试从一个基本帐户运行上面的代码,它将不起作用。您将被要求通过一个 OAuth2 工作流来专门授权该应用程序。为什么?因为您不希望一个任意的应用程序运行一个 BigQuery 账单(或者更糟,访问您的公司数据),所以您必须为它提供所需的权限。

让我们试一试。

1.创建 GCE 实例

要跟随我,使用 GCP web 控制台并创建一个具有默认访问权限的 Google 计算引擎实例(这通常只包括最基本的内容,不包括对 BigQuery 的访问权限):

Creating a Google Compute Engine instance with restricted access

2.创建一个准系统服务帐户

从 GCP web 控制台,创建一个新的服务帐户。这是您将为其生成私钥的帐户。为了额外的安全性和审计,我建议为每个应用程序创建一个全新的服务帐户,并且不要在应用程序之间重用服务帐户。

进入 IAM & Admin,选择“服务帐户”,然后点击+创建服务帐户。按如下方式填写表格:

Creating a barebones service account for Pandas

上述角色允许服务帐户运行查询,并将这些查询记入项目。但是,数据集所有者仍然需要允许服务帐户查看他们的数据集。

如果您使用非公共的 BigQuery 数据集,请通过转到 BigQuery 控制台并与服务帐户的电子邮件地址共享数据集,授予服务帐户对该数据集的适当(通常只是查看)访问权限。出于本教程的目的,我将使用一个公共的 BigQuery 数据集,所以我们可以跳过这一步。

3.将示例代码放在 GCE 实例上

SSH 到 GCE 实例,并在命令行中键入以下命令:

sudo apt-get install -y git python-pipgit clone [https://github.com/GoogleCloudPlatform/training-data-analyst](https://github.com/GoogleCloudPlatform/training-data-analyst)sudo pip install pandas-gbq==0.4.1

4.不使用默认凭据运行

更改 nokey_query.py 中的项目 id,然后运行它:

cd training-data-analyst/blogs/pandas-pvtkey# EDIT nokey_query.py to set the PROJECT IDpython nokey_query.py

它将要求您完成一个 OAuth2 工作流。按 Ctrl-C 退出。您不希望此应用程序使用您的凭据运行。

遇到这种错误时,您会听到一个常见的建议,那就是运行:

# BAD IDEA! DO NOT DO THIS
gcloud auth application-default login

并在启动应用程序之前在 shell 中完成交互式 OAuth 2 工作流。要小心这样做:(1)上面的命令是一个火箭筒,允许应用程序做你能做的任何事情。(2)不可脚本化。每次运行应用程序时,您都必须这样做。

最好的方法是创建计算引擎虚拟机,不是使用最基本的服务帐户,而是使用您已经授予 BigQuery 查看器权限的服务帐户。换句话说,交换步骤 1 和 2,当您创建 GCE 实例时,使用新创建的服务帐户。

但是,如果您不在 GCP 上(因此您的机器不是由服务帐户 auth 创建的)或者您正在使用云数据流或云 ML 引擎等托管服务(因此虚拟机是由该服务的服务帐户创建的),该怎么办呢?在这种情况下,更好的方法是按如下方式更改熊猫代码:

 df = pd.read_gbq(query,
                     project_id='MY_PROJECT_ID',
                    ** private_key='path_to/privatekey.json',**
                     dialect='standard',
                     verbose=False)

应用程序现在将使用与该私钥相关联的权限。

5.不使用私钥运行

在 query.py 中更改项目 id,然后运行它:

cd training-data-analyst/blogs/pandas-pvtkey# EDIT query.py to set the PROJECT IDpython query.py 

它会失败,说找不到私钥

6.为服务帐户生成私钥

还记得在创建服务帐户时创建了一个 JSON 私有密钥吗?你需要把它上传到 GCE 虚拟机。(如果您没有创建密钥文件,请导航到 IAM >服务帐户,并为 pandas 服务帐户创建一个私钥。这将创建一个 JSON 文件,并将其下载到您的本地计算机。您也可以从这里撤销密钥。)

在 SSH 窗口的右上角,有一个上传文件的方法。将生成的 JSON 文件上传到 GCE 实例,并将其移动到位:

mv ~/*.json trainer/privatekey.json

7.用私钥运行

python query.py

现在它可以工作了,您将得到查询的结果。

8.将私钥放入 Python 包中

如果您没有使用 GCE,而是使用托管服务(云数据流、云 ML 引擎等),该怎么办?)反而?

在这种情况下,您将提交一个 Python 包。使用 package_data 属性在 setup.py 中将私钥标记为资源:

from setuptools import setupsetup(name='trainer',
      version='1.0',
      description='Showing how to use private key',
      url='[http://github.com/GoogleCloudPlatform/training-data-analyst'](http://github.com/GoogleCloudPlatform/training-data-analyst'),
      author='Google',
      [author_email='nobody@google.com](mailto:author_email='nobody@google.com)',
      license='Apache2',
      packages=['trainer'],
      **## WARNING! Do not upload this package to PyPI
      ## BECAUSE it contains a private key**
      **package_data={'trainer': ['privatekey.json']},**
      install_requires=[
          'pandas-gbq==0.4.1',
          'urllib3',
          'google-cloud-bigquery'
      ],
      zip_safe=False)

然后,执行以下操作,而不是硬编码 privatekey.json 文件的路径:

private_key = pkgutil.get_data('trainer', 'privatekey.json')

这里有一个更完整的例子。注意 Python 没有将包标记为私有的方法,所以您应该小心不要错误地将这个包发布在公共存储库中,比如 PyPI。

9.保护私钥

私钥实质上为提供它的任何人解锁了已经可用的资源。在这种情况下,任何提供私钥的人都可以进行 BigQuery 查询。没有第二种形式的身份验证(IP 地址、用户登录、硬件令牌等)。)是必需的。因此,要注意如何/在哪里存储私钥。我的建议是:

(1)确保 Python 包中有一个显式忽略私钥的. gitignore:

$cat trainer/.gitignore
privatekey.json

(2)使用 git 秘密来帮助防止密钥泄漏

(3)旋转你的钥匙。详见本博客。

(4)确保不要将 Python 包发布到任何 Python 包的存储库中,因为您的存储库中包含私钥。

摘要

  • 使用 JSON private_key 属性来限制 Pandas 代码对 BigQuery 的访问。
  • 创建具有准系统权限的服务帐户
  • 与服务帐户共享特定的 BigQuery 数据集
  • 为服务帐户生成私钥
  • 将私钥上传到 GCE 实例或将私钥添加到可提交的 Python 包中
  • 确保不要将私钥签入代码或包存储库中。使用密钥旋转器和 git 机密。

下面是 GitHub 中这篇文章的示例代码。编码快乐!

鸣谢:感谢我的同事 Tim Swast 和 Grace Mollison 的帮助和建议。文章中的任何错误都是我自己的。

如何走出缓慢的模式

原文:https://towardsdatascience.com/how-to-engineer-your-way-out-of-slow-models-e62568f02fde?source=collection_archive---------8-----------------------

你刚刚完成了你那个伟大的神经网络架构的设计。它有数量惊人的 300 个完全连接的层,与 200 个各有 20 个通道的卷积层交织在一起,其结果被作为一个光荣的双向 堆叠 LSTM 的种子,并受到少量关注。训练后,你获得了 99.99%的准确率,你就可以把它投入生产了。

但是随后您意识到生产约束不允许您使用这个工具进行推理。你需要在 200 毫秒内完成推断。

换句话说,你需要砍掉一半的层,放弃使用卷积,让我们不要开始昂贵的 LSTM…

要是你能让那个神奇的模型更快就好了!

有时候你可以

在塔布拉,我们做到了。嗯,不完全是…让我解释一下。

我们的一个模型必须预测一个项目的点击率,或者换句话说,用户喜欢一篇推荐文章并点击它的概率。

该模型有多个模态作为输入,每个模态都经历不同的转换。其中一些是:

  • 分类特征:这些特征嵌入到一个密集的表示中
  • 图像:像素通过卷积层和全连接层
  • 文本:在被标记后,文本通过 LSTM,接着是自我关注

然后,这些处理过的模态通过完全连接的层,以学习模态之间的交互,最后,它们通过 MDN 层。

可想而知,这种模式很慢。

我们决定坚持模型的预测能力,而不是修整组件,并提出了一个工程解决方案。

如果可以的话,请把我藏起来

让我们把重点放在图像组件上。该组件的输出是图像的学习表示。换句话说,给定一个图像,图像组件输出一个嵌入。

该模型是确定性的,因此给定相同的图像将导致相同的嵌入。这是很昂贵的,所以我们可以缓存它。我来详细说说我们是怎么实现的。

(缓存的,而不是模型的)架构

  • 我们使用一个 Cassandra 数据库作为缓存,将图像 URL 映射到它的嵌入。
  • 查询 Cassandra 的服务叫做 EmbArk(嵌入存档,当然拼错了)。这是一个 gRPC 服务器,它从客户端获取图像 URL,并从 Cassandra 检索嵌入内容。在缓存未命中时,EmbArk 发送一个异步请求来嵌入该映像。为什么是异步?因为我们需要尽可能快地对结果做出反应。鉴于它不能等待图像被嵌入,它返回一个特殊的 OOV(不在词汇表中)嵌入。
  • 我们选择使用的异步机制是Kafka——一个用作消息队列的流媒体平台。
  • 下一个链接是 KFC (Kafka 前端客户端)—我们实现的 Kafka 消费者,用于将消息同步传递到嵌入服务,并将结果嵌入保存在 Cassandra 中。
  • 嵌入服务被称为视网膜。它从肯德基获得一个图像 URL,下载它,预处理它,并评估卷积层以获得最终的嵌入。
  • 使用链接器完成所有组件的负载平衡。
  • EmbArk,KFC,Retina,Linkerd 在 Docker 内部运行,由 Nomad 编排。这使我们可以根据自己的需要轻松扩展每个组件。

这种架构最初用于图像。在证明了它的价值之后,我们决定将它用于其他组件,比如文本。

EmbArk 对迁移学习来说也是一个很好的解决方案。假设我们相信图像的内容具有预测 CTR 的良好信号。因此,一个被训练用来对图像中的物体进行分类的模型,比如《盗梦空间》,对于我们的需求来说是有价值的。我们可以将 Inception 加载到 Retina 中,告诉我们打算训练的模型,我们要使用 Inception 嵌入,就这样。

不仅提高了推理时间,还改进了训练过程。只有当我们不想进行端到端的训练时,这才是可能的,因为梯度不能通过 EmbArk 反向传播。

所以当你在生产中使用模型时,你应该使用 EmbArk,对吗?嗯,不总是…

警告

这里有三个非常严格的假设。

1.新输入的 OOV 嵌入不是一件大事

当我们第一次看到一幅图像时,我们不会有它的嵌入,这不会伤害我们。

在我们的生产系统中,这是可以的,因为在很短的时间内,同一项目的 CTR 会被评估多次。我们每隔几分钟就创建一个我们想要推荐的商品列表,所以即使一个商品因为非最佳点击率预测而没有进入列表,它也会在下一个周期出现。

2.新投入的比率很低

的确,在 Taboola,我们一直都有很多新商品。但是相对于我们需要对已知项目进行的推理数量来说,这并不算多。

3.嵌入不会经常改变

因为嵌入是缓存的,所以我们相信它们不会随时间而改变。如果是这样,我们将需要执行缓存失效,并使用 Retina 重新计算嵌入。如果这种情况经常发生,我们将失去架构的优势。对于像 inception 或语言建模这样的情况,这种假设成立,因为语义不会随着时间的推移而显著改变。

一些最后的想法

有时,使用最先进的模型会因其计算需求而产生问题。通过缓存中间结果(嵌入),我们能够克服这一挑战,并且仍然享受最先进的结果。

这种解决方案并不适合所有人,但是如果上述三个假设适用于您的应用程序,您可以考虑使用类似的架构。

通过使用微服务范式,该公司的其他团队能够使用 EmbArk 来满足 CTR 预测之外的需求。例如,一个团队使用 EmbArk 来获得图像和文本嵌入,以检测不同项目之间的重复。但是我会把这个故事留给另一篇文章…

【engineering.taboola.com】**最初由我在* 发表。*

如何增强你的机器学习工具箱脱颖而出

原文:https://towardsdatascience.com/how-to-enhance-your-machine-learning-toolbox-to-stand-out-95fc917efdaf?source=collection_archive---------22-----------------------

即使每个机器学习工程师使用的工具略有不同,但在核心方面,他们仍然是相似的:一种脚本语言,一个 ML/DL 框架,也许还有一些数据准备工具。但是当谈到作为一名机器学习工程师工作时,尤其是远程工作时,你可能需要添加一些东西来突出自己。

这个故事最初出现在【RemoteML.com】上。

在生产中弄脏你的手

在一些公司,机器学习模型不仅仅是分析数据或玩玩的东西,它们还被积极部署在网络、手机或嵌入式设备上。

你可以获得的任何帮助你优化推理速度、最小化模型大小和增强可部署性的技能都可以极大地帮助一个团队。

在许多情况下——对于许多框架来说——这意味着你要么能够使用预构建的工具,要么能够编写一些 C++或类似的代码来使用低级 API。但是,知道可以采取什么步骤来缩小模型大小以及对性能有什么影响也很重要。

如何处理海量数据

当学习机器学习时,你通常会得到很好的清理和处理过的训练数据。在某些情况下,您甚至可以将它本地下载到您的机器上使用。

嗯,特别是在创业环境中工作时,情况可能不是这样。您可能需要处理大量(1TB 以上)嘈杂的、未清理的数据。那你是怎么做到的呢?

自学在分布式集群上处理数据,比如使用 Apache Spark,并学习一些关于如何处理远程数据的最佳实践。提示:如果您必须使用远程数据存储,那么一个一个地下拉图像是行不通的。

这是当今机器学习就业市场上问得最多的技能之一,也是年轻机器学习工程师的工具箱中最缺少的技能之一。

画面

很多人是视觉型的人。他们喜欢图像胜过数字,喜欢电影胜过书籍。与取得令人印象深刻的结果同样重要的是向全世界展示它们——或者至少向你的经理展示。一个精心制作的逻辑图或图表是做这件事的正确方法。

大多数人都知道如何处理像matplotlib这样的图形框架,但是一旦你知道了一些高级功能和技巧,你的图形就会更清晰、更好,更容易让非技术人员理解。这将成为一项有价值的技能,特别是如果你在一家非 ML 公司做演示或从事机器学习。

有了这三个技巧,你的技能将变得更广泛,对一系列不同的公司更有价值。一个研究机构可能不需要生产就绪的代码,但是可以使用你的图形技能。对于机器学习初创公司来说,反之亦然。

如何扩展固定张量流估计量

原文:https://towardsdatascience.com/how-to-extend-a-canned-tensorflow-estimator-to-add-more-evaluation-metrics-and-to-pass-through-ddf66cd3047d?source=collection_archive---------6-----------------------

或者在使用固定评估器时,如何添加更多的评估指标并传递实例键

像 DNNRegressor 和 DNNLinearCombinedRegressor 这样的预构建的(“封装的”)估算器使编写 TensorFlow 程序变得简单。例如,下面是一个完整的 TensorFlow 程序,用于从内存中的 Pandas 数据帧开始训练 TensorFlow 模型:

import tensorflow as tffeatcols = [
  tf.feature_column.numeric_column("sq_footage")
]
model = tf.estimator.LinearRegressor(featcols, './model_trained')def train_input_fn(df, num_epochs):  # a Pandas dataframe
  return tf.estimator.inputs.pandas_input_fn(
    x = df,
    y = df['price'],
    num_epochs=num_epochs)model.train(train_input_fn(df,100), steps=1000)

如果你想像 scikit-learn 一样使用 TensorFlow,代码行数也差不多。

稳健估计量

然而,实际上,你想要比这更健壮。你想要读取不完全适合内存的分片文件,批处理它们,等等。这涉及到在您的输入函数中使用 TensorFlow 中的数据集 API 的更多代码。当你训练的时候,你需要时不时的检查和评估。所以,你不要只叫 train,你要叫 train_and_evaluate 。

预构建的评估者非常简单,但也非常固执——他们选择一种特定的做事方式,并给你一堆现成的东西。如果你想要更大的灵活性?好吧,写一个自定义估算器(见例)!

但两者之间存在灰色地带。您可以使用固定的估计器,并且仍然可以获得一定的灵活性。怎么会?使用 extenders.py 中的功能。在这篇博文中,我将向您展示两种这样的能力(顺便提一下,这是两个非常常见的问题)。

You can extend a canned estimator too!

如何添加额外的评估指标

当您使用 DNNRegressor 时,作为评估循环一部分的度量只有 average_loss,在本例中恰好是 RMSE。但是如果您想要更多的度量标准呢?简单地用 add_metrics 包装估算器,如下所示:

def my_rmse(labels, predictions):
    pred_values = predictions['predictions']
    return {'rmse': tf.metrics.root_mean_squared_error(labels, pred_values)}def train_and_evaluate(output_dir):

    estimator = tf.estimator.DNNLinearCombinedRegressor(
        ...)

    estimator = tf.contrib.estimator.add_metrics(estimator, my_rmse)  
    ... tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)

让我们稍微解释一下:

  1. 编写一个函数,根据标签和预测值计算感兴趣的指标,并返回一个字典。
  2. 将该函数与您的原始估算器一起传递给 add_metrics
  3. 从该点开始使用返回的估计量

注意,上面的 my_rmse 方法接收标签和整个预测张量。这样,如果您正在进行分类,并且您的一些指标需要预测的类,而其他指标需要预测的概率,您可以计算您想要的。

在这里看到一个完整的例子。

如何将键和输入特征转发到输出

由固定估计器返回的预测 dict 中只有预测(咄!).但是,在很多情况下,您希望预测也包含一些输入。例如,您可能有一个与每一行相关联的唯一键,并且您希望该键成为预测的一部分,以便您知道预测对应于哪一行。或者,您可能希望根据特定的输入值来计算评估(例如,根据婴儿是早产还是足月来计算婴儿体重的 RMSE)。

为此,用 forward_features 包装估计器,如下所示:

estimator = tf.contrib.estimator.forward_features(estimator, KEY_COLUMN)

你可以传入一个单独的字符串(就像我上面做的那样)或者一个字符串列表。理想情况下,这就是你所需要的。然而,有两个警告。

第一个警告是,上面的键列被添加到预测的输出中,但没有添加到导出签名中,因此当模型在内存中时它可以工作,但如果在训练后恢复,它就不能工作(这没有意义:我已经向 TensorFlow repo 提交了一个 pull 请求来解决这个问题)。在那之前,你需要这个解决方案:

def forward_key_to_export(estimator):
    estimator = tf.contrib.estimator.forward_features(estimator, KEY_COLUMN)
    # return estimator## This shouldn't be necessary (I've filed CL/187793590 to update extenders.py with this code)
    config = estimator.config
    def model_fn2(features, labels, mode):
      estimatorSpec = estimator._call_model_fn(features, labels, mode, config=config)
      if estimatorSpec.export_outputs:
        for ekey in ['predict', 'serving_default']:
          estimatorSpec.export_outputs[ekey] = \
            tf.estimator.export.PredictOutput(estimatorSpec.predictions)
      return estimatorSpec
    return tf.estimator.Estimator(model_fn=model_fn2, config=config)
    ##

第二个警告是,你不能既传递一个特征把它作为模型的输入。要么消费输入,要么传递输入。这里的解决方法是使用 tf.identity 在输入函数中复制这样的列:

features['gw'] = tf.identity(features['gestation_weeks'])

希望这有所帮助!

如何使用 Python 从 MS Word 文档中提取数据

原文:https://towardsdatascience.com/how-to-extract-data-from-ms-word-documents-using-python-ed3fbb48c122?source=collection_archive---------0-----------------------

这篇博客将详细介绍如何从本地 Word 文档中提取信息。由于许多公司和角色都与 Microsoft Office 套件密不可分,对于任何面临通过传输数据的人来说,这都是一个有用的博客。多克还是。docx 格式。

作为先决条件,您需要在计算机上安装 Python。对于那些在工作中这样做的人,你可能没有管理员权限。这篇博客解释了如何在没有管理员权限的情况下在 Windows 机器上安装 Anaconda。

你可以在这里找到支持这个博客的笔记本。

Image created with Microsoft Word and google searches “Microsoft Word Logo” and “Python Logo”

我们将利用每个 word 文档的 XML 构成。从那里,我们将使用 regex 库来查找文档文本中的每个 URL,然后将这些 URL 添加到一个列表中,这对于执行 for 循环来说将是完美的。

#specific to extracting information from word documents
**import** **os**
**import** **zipfile**#other tools useful in extracting the information from our document
**import** **re**#to pretty print our xml:
**import xml.dom.minidom**
  • os 将允许您在操作系统上导航和查找相关文件
  • zipfile 将允许你从文件中提取 xml
  • xml.dom.minidom 解析 xml 代码

首先,我们需要指导我们的代码在文件存储的位置打开文件。要从我们的笔记本上看到这一点(而不是打开文件浏览器),我们可以使用os。虽然知道了感兴趣的单个文件的路径就不需要在这个简单的例子中使用os,但是这个库以后可以用来创建存储在目标文件夹中的文档列表。如果您想编写一个 for 循环来从文件夹中存储的所有 word 文档中提取信息,那么在文件夹中存储一个文档列表会很有帮助。

要查看当前目录中的文件列表,请在os文件路径中使用一个句点:

os.listdir('.')

要查看当前位置上方目录中的文件列表,请使用双句点:

os.listdir('..')

一旦找到 word 文档的存储位置,就可以将找到的文件路径转换为 zip 文件。ZipFile 文件类型,对于我们来说,它是可读的。

ZIP 文件格式是一种常见的归档和压缩标准

https://docs.python.org/3/library/zipfile.html

document = zipfile.ZipFile('../docs/TESU CBE 29 Employee Job Description Evaluation - Final Approved.docx')#document will be the filetype zipfile.ZipFile

现在,zipfile 类的.read()对象需要一个名称参数,它不同于文件名或文件路径。

ZipFile.read(name, pwd=None)

要查看可用名称的示例,我们可以使用.name()对象

document.namelist()

在这个博客的 Jupyter 笔记本中,我探究了其中几个名字来展示它们是什么。包含 Word 文档正文文本的名称为“word/document.xml”

我在 StackOverflow 用户 Nate Bolton 对问题的回答中发现了漂亮的打印技术:用 Python 漂亮地打印 XML。

我们将只使用漂亮的字体来帮助我们识别 XML 中的模式以提取我们的数据。我个人不太了解 XML,所以我将依靠语法模式来查找 word 文档文本中的每个 URL。如果您已经知道提取数据的语法模式,您可能根本不需要打印出来。

在我们的例子中,我们发现字符>http<包围了文档文本中包含的每个超链接。

我需要完成我们的目标,收集上述字符之间的所有文本。为了帮助使用 regex 实现这一点,我使用了下面的 StackOverflow 问题,它包含了我在最初的 ask 中要寻找的内容:正则表达式查找两个字符之间包含的字符串,同时排除分隔符。

虽然我确实想保留http,但我不想保留<>。我将使用字符串切片和列表理解对列表项进行这些修改。

link_list = re.findall('http.*?\<',xml_str)[1:]
link_list = [x[:-1] for x in link_list]

要查看这个博客后面的完整 Jupyter 笔记本,点击这里!

如果您对使用 python 创建和编写 MS Word 文档感兴趣,请查看库 python-docx 。

还有其他从 word 文档中提取文本和信息的方法,比如在下面的 Python 论坛帖子的回答中提到的 docx2txt 和 docx 库。

这是我关于托马斯·爱迪生州立大学(苏特)开源材料可访问性倡议的博客的姊妹博客。中邮 / Github 资源库

我为这个项目撰写的第一篇博客很具体,有点笨拙,所以这篇博客是我将撰写的系列文章中的第一篇,深入探讨苏特项目的各个方面,并使材料更容易理解。

如何使用 Python 从 pdf 中提取关键词并按权重排序

原文:https://towardsdatascience.com/how-to-extract-keywords-from-pdfs-and-arrange-in-order-of-their-weights-using-python-841556083341?source=collection_archive---------1-----------------------

Batman masked Word cloud : Find code at the bottom

关键词提取只不过是识别最能描述文档主题的术语的任务。

关键术语“关键片段“或仅仅是“关键词”是不同的术语,通常用于定义表示包含在文档中的最相关信息的术语。虽然它们听起来不同,但它们都服务于相同的目的:描述文档中讨论的主题。

为什么要提取关键词?

在文本挖掘、信息检索和自然语言处理领域,提取关键词是处理文本数据时最重要的任务之一。

使用案例:

读者从关键词中受益,因为他们可以更快地判断给定的文本是否值得阅读。

网站制作者从关键词中受益,因为他们可以根据主题对相似的内容进行分组。

算法程序员受益于关键字,因为它们将文本的维度减少到最重要的特征。

这些只是许多例子中的几个。

让我们开始讨论这个话题的实质。接下来是一个教程,教你如何解析一个 PDF 文件,并把它转换成一个关键字列表。我们将通过动手解决问题来学习和巩固我们的理解,所以一起编码吧!

问题陈述-

给定一个特定的 PDF/文本文档,如何使用 Python 提取关键词并按权重排序?

依赖关系:

(本教程我用的是 Python 2.7.15 版本。)

你需要在你的机器上安装下面提到的库来完成这个任务。如果您没有,我在下面的代码块中插入了每个依赖项的代码,您可以在 windows 的命令提示符下或 mac 操作系统的终端上键入。

  • PyPDF2 (将简单的基于文本的 PDF 文件转换成 Python 可读的文本)
pip install PyPDF2
  • textract (将重要的扫描 PDF 文件转换成 Python 可读的文本)
pip install textract
  • 回复(查找关键字)
pip install regex

:我尝试了三种方法来完成这项任务。对于方法 1,上述库就足够了。然而,我刚刚提到了我在网上找到的另外两种方法。把他们当做替代品。下面是 jupyter 笔记本,上面有这三种方法。看一看!

Jupyter 笔记本:

所有必要的备注都用“#”表示。

  • 方法 1 未装箱

第一步:导入所有库。

第二步:将 PDF 文件转换为 txt 格式,读取数据。

第三步:使用。findall()" 正则表达式提取关键字的功能。

步骤 4 :将提取的关键字列表保存在数据帧中。

第五步:应用 TF-IDF 的概念计算每个关键词的权重。

第六步:将结果保存在数据帧中,使用。sort_values()"来按顺序排列关键字。

更多详情请点击这里 !

参考文献:

  1. www.wikipedia.org

2.PDF 到文本转换的中等帖子

3.关键词提取教程

4.正则表达式

我希望你觉得这篇教程很有收获,值得一读。此外,我相信一定有很多其他方法可以让你完成上述任务。如果你遇到了,请在评论区分享它们。

屏蔽字云的代码:

在这里找到 GitHub 回购

***# modules for generating the word cloud* 
from os import path, getcwd 
from PIL import Image 
import numpy as np 
import matplotlib.pyplot as plt 
from wordcloud import WordCloud%matplotlib inline 
d = getcwd()  
text = open('nlp.txt','r').read()#Image link = '[https://produto.mercadolivre.com.br/MLB-693994282-adesivo-decorativo-de-parede-batman-rosto-e-simbolo-grande-_JM](https://produto.mercadolivre.com.br/MLB-693994282-adesivo-decorativo-de-parede-batman-rosto-e-simbolo-grande-_JM)' mask = np.array(Image.open(path.join(d, "batman.jpg")))

wc = WordCloud(background_color="black",max_words=3000,mask=mask,\
               max_font_size=30,min_font_size=0.00000001,\
               random_state=42,)    
wc.generate(text) 
plt.figure(figsize=[100,80]) 
plt.imshow(wc, interpolation="bilinear") 
plt.axis("off") 
plt.savefig('bat_wordcloud.jpg',bbox_inches='tight',pad_inches=0.3);**

阅读我发表的其他文章

  1. 如何使用 Python 从 Excel 创建 PDF 报告
  2. 最后一分钟修订:第一部分—机器学习&统计
  3. 什么是探索性数据分析?

机器学习失败的 5 种方式

原文:https://towardsdatascience.com/how-to-fail-at-machine-learning-36cf26474398?source=collection_archive---------2-----------------------

https://lawschooli.com/wp-content/uploads/2014/03/shutterstock_123177382.jpg

机器学习是艰难的。当我第一次知道它的时候,我真的认为它可以做任何事情。你只要朝它扔点东西,它就会发出“滴滴答答”“哔哔”的声音,然后出来……什么东西?我甚至不确定机器学习的最终结果是什么。

从那以后,我学会了在我的产品中实现机器学习时正确地设定我的期望,以便它为我的客户提供价值。这是我学到的一些事情的一个过于简单化的例子:

  1. 机器学习是为了预测。这就是它的作用。它可以预测你正在展示的图片是一只猫还是一座火山,或者根据你的教育程度和年龄预测你目前赚了多少钱。你基本上是用一种模式来武装它,然后当你向它展示新的信息时,它试图根据与模式的匹配程度来对信息进行分类。
  2. 不能含糊。至少,现在还没有。你需要解决一个具体的问题。你需要认真思考你要解决的问题,从小事做起。你不能把你所有的数据都扔进去,然后期望得到有用的回报。最幸运的是,我开始训练一个模型来预测两件事情中的一件。这个客户评价是好是坏?这幅画是一只猫还是一只狗?你可以在此基础上成长,但要确保你真的在思考你试图解决的问题。
  3. 你需要大量的训练数据。在面部识别方面已经有了一些令人着迷的进步,例如,你需要用来训练的面部数量非常少。但对于大多数其他类型的机器学习模型,你需要高质量的训练数据,而且是大量的数据。不要指望只用 100 个例子就能训练出一个预测房价或交通模式的模型。你的训练数据也需要高质量。也就是说,让它尽可能与你期望的真实输入相匹配。不要用加州的房价来训练你的模型,然后期望它能很好地适应纽约的房价。
  4. 不要指望准确率超过 80% 。当然,尽可能接近 100%的准确性是很好的,但事实证明,80%是非常好的。事实是,大多数人的平均准确率约为 80%。如果你将顾客评论外包给 1000 个人,并要求他们将评论分为正面或负面,经过全面分析后,你会发现所有回答的准确率约为 80%。但是你猜怎么着?你的机器学习驱动的产品为他们做到了这一点,所以你刚刚为你的客户节省了一大笔钱,获得了与雇佣 1000 个人相同的结果。这就是价值。
  5. 机器学习不能解决一切。你可能认为房价或股市有规律可循,但实际上可能没有。即使你用纽约证券交易所的每笔交易训练了一个机器学习模型,然后试图用它来预测市场,你也会失败。有些事情是无法预测的。你必须记住,没有机器学习模型是在真空中运行的。它只和你提供给它的数据一样好,如果数据没有足够的信息或者太不一致,模型就不能解决你的问题。

用数据科学加速旧金山的住房搜索

原文:https://towardsdatascience.com/how-to-find-housing-in-san-francisco-with-data-science-2991ff503602?source=collection_archive---------4-----------------------

不久前有人问我如何在旧金山找到住房。一年前,在我找到我现在的客厅沙发之前,我开始寻找住房,并且很快成为一种压倒性的经历,试图找到任何低于一只胳膊和一条腿的租金。我花越来越多的时间在网上搜索,并把搜索范围从金融区扩大到旧金山的几个地区,包括臭名昭著的嫩腰区。这种搜索慢慢消耗了我的精力,以至于我每天醒来至少花一个小时点击 Craigslist,看到熟悉的地方,一张疲惫的脸。

我心想:“一定有什么办法可以加快找房子的速度!”作为一名有抱负的数据科学家,我的解决方案是创建一个 web scraper,它可以收集旧金山几个地区的信息,并以简洁的方式呈现它们,而不是所有的绒毛。虽然不能保证找到房子,但至少我可以把 1 个多小时的搜索时间减少到 10 分钟。

TLDR:我写了一个脚本,以地点和价格为参数来抓取 Craigslist。代码位于底部,但除此之外继续阅读,看看整个网页抓取过程!

One of the most helpful pictures I had in finding housing

第 0 步:了解你的敌人

What the Craigslist interface looks like

What I wanted the results to look like

很多时候,我们很容易超越自己,一头扎进问题中。对我的编码技能有很大帮助的一件事是从较小的目标开始,然后把它变成一个大的、宏伟的目标。我的大目标是得到每篇文章的标题以及它到个人页面的链接。然后我想从旧金山的一个地区(比如格伦公园)搬到另一个地区(比如巴尔博亚公园)。查看 Craigslist 界面,似乎每篇文章都有一个标题和一个蓝色超链接,显示在描述旁边会很有用。

因此,分解大目标,我的攻击计划是:

  1. 使用 Selenium 打开一个远程控制页面
  2. 刮一页 Craigslist 住房获得标题
  3. 进一步抓取以获得卖家帖子的链接
  4. 移动到另一个位置而不重写任何内容
  5. 重复此过程,直到所有位置都被刮除
  6. 把所有的都集中到一个好的功能上

第一步:引入网络抓取工具

from selenium import webdriver
from bs4 import BeautifulSoup
import urllib2
import re
import pandas as pd
import numpy as np
pd.set_option('max_colwidth', 5000)
pd.options.display.max_rows = 999

第二步:用硒打开一个网页

Selenium 是一个工具,它让我们在浏览器中自动操作,就像我们像人一样点击或打字一样。这让我们可以登录并做任何人类在使用浏览器时可以做的事情。也许最重要的是,它允许我们从网页中抓取数据,这些网页使用在浏览器中执行的 JavaScript 生成 HTML 旧金山大学的 Terence Parr 教授说

为了初始化 Selenium 工具,我们需要从 Chromedriver(或 geckodriver)所在的路径调用它。(链接下载 Selenium)

driver = webdriver.Chrome(executable_path="/Users/shsu/Downloads/chromedriver")

在那里,我们可以使用驱动程序打开某些网页,例如:

driver.get('http://google.com')

这应该会在你的 Chrome 上打开一个新的浏览器,然后可以用代码自动完成。用你选择的任何网站试试吧!

第三步:从页面上刮下帖子标题

A general query for my housing limitations

如前所述,我们宏伟计划的第一个目标是抓取 Craigslist 的一个页面。让我们打开一个页面,实际输入一些过滤器(参数),然后查看内容(左边的图片)。就我的预算而言,我正在寻找一个低于 900 美元的地方,并希望最近的帖子首先显示出来。当我查看由该查询创建的超链接时,我得到这样的结果:

"【https://sfbay.craigslist.org/search/roo?query=】T4格伦+公园sort =datemax _ price =900availability mode = 0

你知道什么?看起来 url 中的头包含了我输入的参数,也就是查询字符串和。让我们从代码开始。

url = [https://sfbay.craigslist.org/search/roo?query=glen+park&sort=date&max_price=1000&availabilityMode=0](https://sfbay.craigslist.org/search/roo?query=glen+park&sort=date&max_price=1000&availabilityMode=0)driver.get(url)

此时,你可能会奇怪为什么我选择 Chromedriver 而不是其他 web 驱动。主要原因是因为开发者工具可以用这三个键打开:

选项+命令+ U

通过同时点击这三个键,您可以查看任何网页背后的 HTML 代码。

Inside the developer source with the tag information we need

通过搜索单个标题文章,我们可以提取该文章的标签和标题。在这种情况下,请注意上图顶部带有“result-info”类的“p”标签。在这个标签中包含了关键文本(特别是“Lafayette 的出租房间”、“1100 美元”和“(Lafayette/or inda/moraga)”,我们可以用. text 来抓取。

craig_title = []
all_posts = driver.find_elements_by_class_name("result-row")
for post in all_posts:
    craig_title.append(post.text)

现在我们已经从帖子的标题中获得了所有重要的信息!接下来我们要做的就是抓取这个页面,不仅要获取标题信息,还要获取标题所指向的网页。

第四步:抓取个人帖子的链接

棘手的部分来了:如果我不能在不重定向 Selenium 浏览器的情况下点击链接并获得它的超链接,我如何获得到个人卖家页面的链接?

解决方案:使用我们的网络抓取工具寻找一个标题,然后将其推广到页面上的所有帖子。

What we see on the website

What the code on the website looks like

通过搜索原始标题文章,我们可以看到“a”标签和“href”类等同于我们正在搜索的文章链接。我们将首先用 urllib2 打开 url(因为我们不想用 selenium 远程打开另一个页面),然后按照与步骤 2 类似的过程获得 post 超链接。

link_list = []
html_page = urllib2.urlopen(url)
soup = BeautifulSoup(html_page, "lxml")
for element in soup.findAll("a", {"class": "result-title hdrlnk"}):
    print element['href']

我们现在已经抓取了文章标题和它们各自的链接。

第 5 步和第 6 步:迭代整个过程并进行归纳

我们可以用变量代替所有参数来概括我们的刮削。

例如,转动这个:

craig_title = []
url = **"https://sfbay.craigslist.org/search/roo?query=glen+park&sort=date&max_price=1000&availabilityMode=0"**
driver.get(url)
allthing = driver.find_elements_by_class_name("result-row")
for post in allthing:
    craig_title.append(post.text)

变成这样:

**place = ['glen+park']
price = '900'**craig_title = []
url = **"**[**https://sfbay.craigslist.org/search/roo?query=**](https://sfbay.craigslist.org/search/roo?query=)**"+ \
                str(place)+ 
                "&sort=date&max_price="+
                str(price)+
                "&availabilityMode=0"**
driver.get(url)
all_posts = driver.find_elements_by_class_name("result-row")
for post in all_posts:
    craig_title.append(post.text)

我们可以对所有其他变量重复这个过程,比如当我们遍历页面并添加到列表中时。

第七步:把所有东西放在一起

我们有(1)抓取一个页面的标题和链接,(2)移动到另一个页面并重复步骤 1,以及(3)将所有信息附加到一个列表。所以现在,我们要做的就是创建一个漂亮的小函数,允许我们包含一些参数并返回一个数据帧。姑且称之为: craig_list()

from selenium import webdriver
from bs4 import BeautifulSoup
import urllib2
import re
import pandas as pd
import numpy as np
pd.set_option('max_colwidth', 5000)
pd.options.display.max_rows = 999
from IPython.display import display, HTMLdriver = webdriver.Chrome(executable_path="/Users/shsu/Downloads/chromedriver")def craig_list(price, location_list=list):
    """
    craig_list is a function that creates the condensed Craigslist post information
    Inputs:
        price_max: integer of the maximum price of houses one wants
        places: list of strings where the string represents the region of choice 
    Output:
        a dataframe with the description and the link of the post 
    """
    craig_title = []
    link_list = []
    for place in location_list:
        print("--------- MOVING TO PLACE: " + str(place) + " -----")
        link_list.append(" ")
        craig_title.append(str(place).upper())

        url = "[https://sfbay.craigslist.org/search/roo?query=](https://sfbay.craigslist.org/search/roo?query=)"+ \
                str(place)+ "&sort=date&max_price="+ str(price)+"&availabilityMode=0"
        driver.get(url)
        all_posts = driver.find_elements_by_class_name("result-row")
        for post in all_posts:
            craig_title.append(post.text)

        html_page = urllib2.urlopen(url)
        soup = BeautifulSoup(html_page, "lxml")
        for pid in soup.findAll("a", {"class": "result-title hdrlnk"}):
         link_list.append(pid['href'])
    craig_df = pd.DataFrame(np.column_stack([craig_title,link_list]), 
columns = ["Info", "Link"])
    return craig_dfplaces = ["glen+park", "balboa+park"]
price_max = 900
craig_df = craig_list(price_max, places)
display(craig_df)

就像这样,你现在也可以节省 40 分钟在 Craigslist 上搜索房屋的时间,最终在一个改造过的客厅里租到一张沙发!

Even San Francisco is not safe from satire

总之,我们了解到,虽然抓取看起来困难且耗时,但它可以被分解为更容易的部分,在实际的用户界面和背后的 HTML 源代码之间可视化,并最终概括为模拟整个人类行为。感谢你的阅读,祝你找房子好运!

附言:很多帖子都是垃圾邮件制造者,他们复制真实的帖子,并给出一个通用的消息“请把你的联系电话发给我,我会尽快与你联系。”

参考资料:

  1. 硒下载页面
  2. 特伦斯·帕尔教授的硒教程
  3. 美汤文档
  4. 查询字符串
  5. 【Beautifulsoup 网页抓取教程
  6. 旧金山 Craigslist

如何用 TURI (Twitter 低估指数)在 Twitter 上找到被低估的人

原文:https://towardsdatascience.com/how-to-find-underrated-people-on-twitter-with-turi-twitter-underrated-index-c3ab8867bea9?source=collection_archive---------6-----------------------

你可以培养的最好技能之一是在别人之前找到有才华的人的能力。

泰勒·考恩(边际革命的经济学家和博客作者)的这个好建议让我思考:有什么策略可以找到有才华但被低估的人?

一个可能的来源是 Twitter。很长一段时间,我没有“得到”Twitter,但在遵循了迈克尔尼尔森的建议后,我正式成为了一名皈依者。关键是仔细选择你关注的人的名单。如果你做得好,你的 Twitter feed 就会变成源源不断的有价值的信息和有趣的人。

如果你仔细观察,你会发现 Twitter 上有很多被严重低估的人,即非常聪明的人,他们提供有价值和有趣的内容,但他们的追随者比你想象的要少

这些人是最值得关注的:你可以获得很多其他人得不到的见解(因为没有多少人关注他们),他们更有可能回应询问或参与讨论(因为他们需要管理的关注者较少)。

寻找这些人的一个选择是试错法,但我想看看是否有可能量化人们在 Twitter 上被低估的程度,并自动化寻找优秀人物的过程。

我称之为 TURI (Twitter 低估指数),因为嘿,它需要一个名字,缩写词让事情听起来如此官方。

TURI 的组件

该指数有三个主要组成部分:增长、追随者的影响力和追随者的数量。

增长(G):用户发布的每单位内容(即每条推文)的关注者数量。

一个推特粉丝迅速增长的用户暗示他们被低估了。这意味着他们正在推出高质量的内容,人们开始迅速注意到这一点。我衡量的方法是一个人在每条推特上获得的关注者数量。

另一个可能的增长衡量标准是用户在单位时间内获得的关注者数量(即关注者数量除以 Twitter 账户存在的时间长度)。然而,这个选项有几个问题:

  • Twitter 账户可能会休眠数年。举例来说,有人可能开了一个账户,但 5 年没有发微博,然后发布了很棒的内容。用时间来衡量增长会不公平地惩罚这些人。
  • 一个人可能有不断发微博的策略。部分内容产生了追随者,但整体质量仍然较低。我们在寻找发布伟大内容的人,不一定是发布大量内容的人。

关注者影响力(IF):用户的关注者的平均关注人数。

在我看来,一个人的粉丝影响力是决定他们在 Twitter 上是否被低估的最重要因素。以下是几个原因:

  • 一般来说,有影响力的人能更好地判断好内容。
  • 有影响力的人在决定追随谁时更有选择性,尤其是如果 Twitter 是他们在线“品牌”的重要组成部分。
  • 有影响力的人往往在他们的线下个人生活中与其他高质量的人接触或有某种联系,这些人更有可能出现在他们的 Twitter feed 中,即使他们还没有被广泛了解或欣赏。

我有点偏向于这种方法,因为从我个人的经验来看,当我浏览那些在我的 feed 上被有影响力的人关注的人时,这种方法非常有效。如果我看到有人被泰勒·考恩、亚历克斯·塔巴罗克、鲁斯·罗伯兹、帕特里克·科利森和马克·安德森追随,但他们只有 5000 名粉丝,那么我很有信心这个人目前被低估了。

经过一番考虑,我认为利用 Twitter API 中的可用数据来衡量用户追随者影响力的最佳方式是获取用户追随者的追随者的平均数量。

我仔细考虑了使用中间值而不是平均值的可能性,但决定不这么做:如果一个有 100 万粉丝的人关注一个有 50 个粉丝的人,我想更多地了解那个人,即使他们的 TURI 很高只是因为那个有很大影响力的粉丝。离群值是好的——我们在寻找未经雕琢的钻石。

关注者总数(NF):用户当前拥有的关注者总数。

在这种情况下,我们对“被低估”的定义是,当一个用户没有你预期的那么多追随者时,那么追随者的总数显然将在 TURI 中发挥重要作用。

因此,总结 TURI 背后的主要思想:如果一个人拥有大量“有影响力的”追随者,相对于他们发布的内容量,他们的追随者数量增长很快,但他们仍然拥有少量的追随者,那么他们很可能被低估。

定义索引

对于任何用户 I,我们可以计算他们的 Twitter 低估指数(TURI)为:

其中 G 是增长,IF 是追随者的影响力,NF 是追随者的数量。

这个公式具有我们正在寻找的一般关系:每单位内容用户的高增长,高影响力的追随者,以及低数量的总追随者都推动 TURI 向上。

我们可以通过重写 G = NF / T 来简化等式,其中 T 是用户的推文总数。取消一些条款,这给了我们最终版本的指数:

换句话说,我们关于一个人在 twitter 上被低估程度的指数是由用户 I 的每条 tweet 的平均粉丝数给出的。

在为一组用户计算 TURI 之前,您可能需要采取一些预处理步骤来改善结果:

  1. 过滤掉已核实的账户 。TURI 的缺点之一是,如果一个用户已经是名人,他的成长/轨迹会非常高。这些人通常在每条推特上有大量的追随者,不是因为他们发布的内容,而是因为他们已经在其他地方获得了名气。幸运的是,Twitter 有一个名为“验证账户”的功能,如果被确定为公共利益的账户,则应用“”。通常,这包括用户在音乐、表演、时尚、政府、政治、宗教、新闻、媒体、体育、商业和其他关键兴趣领域维护的账户。这是一个要过滤掉的素数群,因为我们找的不是知名人士。
  • 虽然可能会有这样的情况,一个拥有 50 万追随者的人被低估了,但这似乎不太可能是你要找的那种人,所以不值得 API 资源。
  • 通过一些较高的追随者阈值进行过滤降低了包括没有经过验证的账户的名人的风险。
  • 您可以限制调用 API 的次数。就 API 调用而言,成本最高的操作是计算出关注者的影响力。一个人的追随者越多,计算 TURI 所需的 API 调用就越多。

试用 TURI

为了测试这个指数,我计算了 49 个人的一个子集的价值,这些人是泰勒·考恩(Tyler Cowen)关注的,他们有 1000 个或更少的关注者(泰勒在我最喜欢的博客的上写博客,激发了这个项目,并对关注的人有很好的品味)。

下图显示了这些用户的 TURI(不包括由于隐私设置而无法访问的 4 个帐户)。

正如你所看到的,有一个用户( @xgabaix )是一个显著的异常值。仔细看看这个简介,这是哈佛大学的著名经济学家 Xavier Gabaix。他的 TURI 很高,因为他有几个非常有影响力的追随者,而且他还没有发微博。

那么 TURI 在这里失败了吗?我不这么认为,因为如果他真的在发微博,这很可能是一个值得关注的人。然而,将一个实际上没有任何 Twitter 内容的人放在列表的顶部似乎有点奇怪。

所以,我再次筛选了发布了至少 20 条推文的用户:

下面的图表只关注不同用户的 IF(他们的追随者的影响力)。有趣的是,另一个用户 @shanagement 拥有迄今为止最有影响力的关注者。然而,他们在总体旅游指数中排名第三,因为他们发推特的次数明显多于@davidbrooks13 或@davidhgillen。

限制

当然,TURI 也有一些缺点:

  • 很难判断 TURI 的表现有多好 :这些指标是基于直觉,显然没有关于 twitter 用户实际上被低估程度的“基本事实”数据。所以,我们并没有一个真正的基于数据的方法来观察指数的效果,并系统地改进它。例如,你可能会问增长 G 是否应该包含在指数中。我认为这有一个很好的论据:如果人们在每单位内容上很快获得追随者,那么该内容一定有吸引其他人的地方。但是,另一方面,也许他们并没有被真正低估。也许真正被低估的人有很好的内容,但是你的普通 Twitter 用户即使读了一些帖子也低估了他们。当人们看到高质量时,并不总是知道它。
  • 计算 TURI 需要相当长的时间:这是由于 API 请求的 Twitter 速率限制。例如,计算上面 49 个 Twitter 用户的 TURI 大约需要一个小时。对于拥有大量追随者的人来说,这需要更长的时间(记住,我只关注拥有 1000 或更少追随者的人)。所以,如果你想做一个大批量的人,这可能是一个好主意,在一个服务器上运行这个持续的基础上,并存储用户和 TURI 信息到一个数据库中。

其他想法?

有很多不同的方法可以指定这样的索引。如果你有任何建议,请在推特或电子邮件上留言或联系我。

另一个可能的调整是计算用户关注的人数。我注意到一些 Twitter 用户似乎有一个策略,那就是关注大量的人,希望被跟踪回来。在这些情况下,他们的跟随战略可能是他们高增长的原因,而不是他们内容的质量。一种解决方案是通过乘以(用户关注者的数量)/(用户关注的人数)来调整 TURI。举例来说,这将惩罚那些拥有 15,000 名追随者但自己却追随 15,000 人的人。

技术细节

你可以在这里找到我用来与 API 交互并计算 TURI 的代码。代码使用了 python-twitter 包,它提供了一种与 Twitter API 交互的好方法,抽象出令人讨厌的细节,因此您不必处理它们(例如,使用 OAuth 进行认证,处理速率限制)。

原载于 2018 年 7 月 8 日 www.marknagelberg.com。要访问我共享的 Anki deck 和 Roam Research notes 知识库,以及关于间隔重复和提高学习效率的技巧和想法的定期更新,* 加入“下载马克的大脑”。***

如何用神经网络找到沃利

原文:https://towardsdatascience.com/how-to-find-wally-neural-network-eddbb20b0b90?source=collection_archive---------1-----------------------

如何训练一个模型来解决沃利难题的指南

Process of a Neural Network learning to find Wally from start to finish

深度学习提供了另一种方法来解决 Wally 在哪里的难题。但与传统的图像处理计算机视觉方法不同,它只使用少数几个带标签的例子,包括沃利在图像中的位置。

如果神经网络可以为你做这件事,为什么还要去找沃利呢?

带有评估图像和检测脚本的最终训练模型发布在 my Github repo 上。

这篇文章描述了使用 Tensorflow 对象检测 API 训练神经网络的过程,并使用围绕它构建的 Python 脚本来找到 Wally。它由以下步骤组成:

  • 通过创建一组带标签的训练图像准备数据集,其中标签代表 Wally 在图像中的 x-y 位置
  • 获取并配置模型以与 Tensorflow 对象检测 API 一起使用
  • 在我们的数据集上训练模型
  • 使用导出的图表在评估图像上测试模型

启动前,请确保按照说明安装 Tensorflow 对象检测 API。

准备数据集

虽然处理神经网络是深度学习中最值得注意的过程,但令人遗憾的是,数据科学家花费最多时间的步骤是准备和格式化训练数据。

最简单的机器学习问题的目标值通常是标量(如数字检测器)或分类字符串。Tensorflow 对象检测 API 训练数据使用两者的组合。它由一组图像组成,并附有所需对象的标签以及它们在图像中出现的位置。位置由两个点定义,因为(在 2d 空间中)两个点足以在对象周围绘制边界框。

因此,为了创建训练集,我们需要提供一组 Wally 在哪里的拼图图片,以及 Wally 出现的位置。

虽然我可以花几个星期的时间用注释工具如 LabelImg 手工标记图像来解决 Wally 谜题,但我发现了一个已经解决的训练集Wally 谜题在哪里。

Where’s Wally training dataset with last four columns describing where Wally appears in an image

准备数据集的最后一步是将标签(保存为.csv)和图像(.jpeg)打包成一个二进制.tfrecord文件。这样做的过程在这里解释,但是你可以找到 train 和 eval Wally 在哪里。tfecord我的 Github 回购上的文件。

准备模型

Tensorflow 对象检测 API 提供了一组在几个公共数据集上训练的具有不同性能(通常是速度-精度权衡)的预训练模型。

虽然该模型可以从随机初始化的网络权重开始从头开始训练,但这一过程可能需要数周时间。相反,我们使用了一种叫做迁移学习的方法。
它包括采用一个通常被训练来解决一般问题的模型,并对其进行再训练来解决我们的问题。迁移学习背后的想法是,我们可以使用预训练模型中获得的知识,并将其转移到我们的新模型中,而不是通过从头开始训练我们的模型来重新发明轮子。这为我们节省了大量时间,因此我们可以将花在培训上的时间用于获取针对我们问题的知识。

我们使用了 RCNN 和在 COCO 数据集上训练的 Inception v2 模型以及它的管道配置文件。该模型包括一个检查点.ckpt文件,我们可以用它来开始训练。

下载配置文件后,请确保用指向您的检查点文件、培训和评估的路径替换“PATH_TO_BE_CONFIGURED”字段。tfrecord 文件和标签映射文件。

需要配置的最后一个文件是labels.txt地图文件,它包含了我们所有不同对象的标签。因为我们只寻找一种类型的对象,所以我们的标签文件看起来像这样

item {
  id: 1
  name: 'waldo'
}

最后,我们应该以下列内容结束:

  • 带有.ckpt检查点文件的预训练模型
  • 训练和评估.tfrecord数据集
  • 标签映射文件
  • 指向上述文件的管道配置文件

现在,我们准备开始训练。

培训

Tensorflow 对象检测 API 提供了一个简单易用的 Python 脚本来本地重新训练我们的模型。它位于models/research/object_detection中,可以运行:

python train.py --logtostderr --pipeline_config_path= PATH_TO_PIPELINE_CONFIG --train_dir=PATH_TO_TRAIN_DIR

其中PATH_TO_PIPELINE_CONFIG是我们的管道配置文件的路径,PATH_TO_TRAIN_DIR是新创建的目录,我们的新检查点和模型将存储在这里。

train.py的输出应该是这样的:

寻找最重要的信息是损失。它是训练集或验证集中每个例子的错误总和。当然,您希望它尽可能低,这意味着如果它缓慢下降,这意味着您的模型正在学习(…或过度拟合您的训练数据)。

还可以使用 Tensorboard 更详细地显示训练数据。

该脚本会在完成一定数量的步骤后自动存储一个检查点文件,这样您就可以在学习时随时恢复您保存的检查点,以防您的计算机崩溃。

这意味着当您想要完成模型的训练时,您可以终止脚本。

但是什么时候停止学习呢?关于何时停止训练的一般规则是当我们的评估集上的损失停止减少或通常非常低时(在我们的示例中低于 0.01)。

测试

现在,我们可以通过在一些示例图像上测试来实际使用我们的模型。

首先,我们需要使用models/research/object_detection中的脚本从存储的检查点(位于我们的火车目录中)导出一个推理图:

python export_inference_graph.py — pipeline_config_path PATH_TO_PIPELINE_CONFIG --trained_checkpoint_prefix PATH_TO_CHECPOINT --output_directory OUTPUT_PATH

导出的推理图现在是我们的 Python 脚本可以用来查找 Wally 的。

我写了几个简单的 Python 脚本(基于 Tensorflow 对象检测 API ),您可以使用它们在您的模型上执行对象检测,并在检测到的对象周围绘制框或暴露它们。

[find_wally.py](https://github.com/tadejmagajna/HereIsWally/blob/master/find_wally.py)[find_wally_pretty.py](https://github.com/tadejmagajna/HereIsWally/blob/master/find_wally_pretty.py)都可以在我的 Github repo 中找到,并且可以简单地运行

python find_wally.py

或者

python find_wally_pretty.py

在您自己的模型或评估图像上使用脚本时,请确保修改model_pathimage_path变量。

最后的想法

在我的 Github repo 上发布的模型表现得出奇的好。

它设法在评估图片中找到了 Wally,并在网上找到了一些额外的随机例子。它没能在沃利真正大的地方找到他,凭直觉这应该比在他真正小的地方找到他更容易解决。这表明我们的模型可能过度拟合我们的训练数据,主要是因为只使用了少量的训练图像。

任何希望通过手动标记一些来自网络的额外图片来提高模型性能的人,都可以在我的 Github repo 上提交 PR,并帮助改进训练集。

如何在非递归优雅 Python 中展平深度嵌套的 JSON 对象

原文:https://towardsdatascience.com/how-to-flatten-deeply-nested-json-objects-in-non-recursive-elegant-python-55f96533103d?source=collection_archive---------0-----------------------

用递归 python 解决方案来扁平化深度嵌套的 JSON 对象是很危险的。因为 python 解释器限制了堆栈的深度,以避免可能导致堆栈溢出的无限递归。从性能的角度来看,递归通常比迭代解决方案慢。

Deeply Nested “JSON”. Photo credit to wikipedia.

本文的目的是分享一种使用 python 源代码和提供的示例来展平深度嵌套的 JSON 对象的迭代方法,这类似于迭代地将所有嵌套的 matryoshka 玩偶带到外面呼吸一些新鲜空气。

Photo credit to MagiDeal

简化 JSON 的传统递归 python 解决方案

下面的函数是递归展平 JSON 的一个例子。第 16 行和第 20 行的代码调用函数“flatten”来保持 JSON 对象中项的解包,直到所有值都是原子元素(没有字典或列表)。

在下面的示例中,“pets”是两级嵌套的。键“dolphin”的值是一个字典列表。

将展平后的结果加载到 pandas 数据框中,我们可以得到

使用迭代方法展平深度嵌套的 JSON

函数“flatten _ json _ iterative _ solution”用迭代的方法解决了嵌套的 JSON 问题。这个想法是,我们扫描 JSON 文件中的每个元素,如果元素是嵌套的,就只解包一层。我们不断迭代,直到所有的值都是原子元素(没有字典或列表)。

  • 第 27 行的 chain.from_iterable() 用于从单个可迭代参数中获取链式输入,即 chain.from_iterable(['ABC ',' DEF']) → A B C D E F
  • 第 27 行的 starmap() 用于创建一个迭代器,该迭代器使用从 dictionary.items()获得的参数来计算函数“unpack”

使用新的迭代解决方案“flatten _ JSON _ iterative _ solution”,例如“pets”:

使用另一个示例“pets2”进行单元测试,该示例在键“dolphin”处嵌套了 3 层。一个 list [{ "鸟":"蓝鸟" },{ "鱼":"海豚" }] 打包成 key "老虎"的值。

在本文中,我描述了一种用于展平深度嵌套的 JSON 对象的迭代解决方案。在实践中可以随意使用源代码。如果你有任何优化迭代解的想法,请给我发消息。

恭喜你!你刚刚读完一篇文章,同时解放了一些套娃。

报名参加🦞:的 Udemy 课程

具有机器学习和统计的推荐系统

https://www.udemy.com/course/recommender-system-with-machine-learning-and-statistics/?referralCode=178D030EF728F966D62D

如何在数据科学工作面试中炫耀自己对分析的热情?

原文:https://towardsdatascience.com/how-to-flaunt-your-passion-for-analytics-in-data-science-job-interviews-2cb432cc3d3d?source=collection_archive---------5-----------------------

Photo by Jason Rosewell on Unsplash

“数据科学家是本世纪最性感的工作。”

每个人都想分一杯羹。数以百万计的有志之士都在追求那些有限的、有价值的职位,并愿意为此付出一分一毫。那么,如何真正表明他们是特别的一个适合数据科学的角色呢?

多年来,我一直在面试 Gramener 的分析职位,我经常遇到一些求职者试图通过声称自己对分析有着深厚的热情来让自己与众不同。有些人甚至声称数据在他们的血液中流动。

但事实上,除了每天申请这个职位的数千份简历之外,没有什么能真正让大多数候选人的简历脱颖而出。他们的项目或职业兴趣并没有显示出对分析的关注,更不用说对它的热情了。而且,他们的答案没有给出最微妙的暗示,暗示 T4 内心深处燃烧的火焰。

在没有事实证据支持的情况下,以纯粹的情感理由为数据工作辩护,这难道不具有讽刺意味吗?

“有数据,就看数据。如果我们只有意见,那就用我的吧。”— 吉姆·巴克斯代尔

每当一个“数据科学”的流行语被说出,下一批渴望分析的人就会从一所精修学校毕业。虽然我不确定数据科学家的开放职位是否如分析师报告所述达到数百万,但毫无疑问的是,分析培训课程正在蓬勃发展。

考虑到供需不平衡的情况,我们不能只在 JD 清单上打勾。考虑到明显有利的经济形势,要么是天生对数据有热情,要么是试图凭空捏造;即使他们的教育背景或工作经验并不太好。

因此,最大的挑战往往是在数据科学采访中展示和捍卫这种对分析的热情。一个人怎样才能从人群中脱颖而出呢?根据我的经验和许多从业者对候选人的要求,以下是实现这一目标的 5 个步骤。

1.读、写并熟悉数据

Photo by Annie Spratt on Unsplash

当被问到简历中所列术语以外的问题时,应聘者往往会张口结舌。虽然人们可能会解释情绪分析,并提出一种从社交媒体数据中提取行为洞察的方法,但他们也必须知道这种收获如何被滥用于社会操纵。

尽管有多年的工作经验,有些求职者说,逻辑回归还没有学会简单的神经网络,或者懒得去好奇为什么世界会因为深度神经网络而疯狂。这些模式并没有公正地对待那些声称要成为这个行业一部分的热情。

人们必须超越分析课程的教学大纲。除了一些核心技术的深度之外,获得分析的广度也很重要。探索像博客、书籍、播客或视频这样的途径,并沉迷于数据内容。在信息过剩的今天,缺少的是时间和兴趣。

2.执行您自己的数据项目

Photo by Laith Abuabdu on Unsplash

人们几乎可以通过查看候选人简历上的模板“实时项目】来确定毕业学校。专家面试官倾向于自动掩饰不真诚的内容和无差别的项目。横向思维者经常犯下不把注意力放在直接工作线之外的项目上的错误。

不通过个人项目支持对数据的热情是不真诚的,即使是初步的。开放数据运动正在使世界各地的数据民主化,无论人们喜欢与否,每一个世界事件都留下了大量的数据。一些谷歌搜索可以获取任何感兴趣领域的数据。

人们只需要挑选一个问题,并把分析学习作为一个小项目来应用。个人数据项目的不完美解决方案远比付费直播项目的完美答案更有说服力。更重要的是主动性和努力,这肯定会引起别人的注意。

3.公开展示你的商品

Photo by Annie Spratt on Unsplash

那些把自己的能力局限在简历或刻板的 LinkedIn 页面上的求职者只是在光天化日之下,在就业市场上束缚自己。我在简历中首先寻找的是外部网站、门户网站或任何支持候选人的公共知识库的链接。

网络是一个充满可能性的奇妙地方。在 Github 上发布你的代码,通过在 Stackoverflow 上破解 bug 来展示你的技术能力。在公众可视化 门户上炫耀你的数据可视化技能。通过在媒体上撰写博客,展示你在数据科学领域的思想领导力。

今天,有无数种方式在公共场合兜售你的商品。这不再是一个平衡谦虚和表演技巧的问题。这已经成为建立一个人的可信度的最低要求,同时也有助于摆脱 PDF 文档的束缚。

4.与数据科学家竞争

Photo by Timothy Eberly on Unsplash

今天,当公司招聘转向公开的黑客马拉松和编码竞赛时,一个从未在像 Kaggle 这样的平台上竞争过的候选人看起来就像一个来自互联网时代的时间旅行者。

一个显而易见的展示激情的方法就是挤进竞争的竞技场。一个人不需要出现在比赛排行榜上就能得分。与任何运动一样,这都是关于采取主动,在正确的技能水平上竞争,坚持一些高质量的参赛项目,而不是以最终结果为目标。

各种技能的数据竞赛如雨后春笋般涌现,如 Kaggle 、 InformationIsBeautiful 和 open data 竞赛。从技能培养的角度来看,没有比应用更好的学习方法了。与人联系、在团队中竞争以及与数据科学家同事一起忙碌都有助于加速这一过程。

5.开始在你做的所有事情中看到(吃饭、睡觉和做梦)数据

Photo by Radu Florin on Unsplash

谷歌由你的数据驱动。脸书收获了它。你从来不知道存在的公司已经用你的数据建立了完整的商业模型。当一个人开始对其他人的数据进行新奇的预测分析时,难道他们不应该关心如何利用自己拥有和产生的数据做最简单的事情吗?

一个真正对数据感兴趣的人会开始看到数字生活在他们周围。无论是从你的手机和健身追踪器中提取数据,还是下载我们慷慨捐赠给谷歌、脸书或 Linkedin 的数据,利用你新发现的数据技能来兜一圈吧。

想出用例,将数据用于一些有趣的或个人的用途。用数据来决定什么时候买最便宜的票?为什么不建立一个个性化的模型来为自己推荐下一部电影呢?吃你自己的山茱萸,享受数据带来的乐趣,因为这些花絮也能在面试中创造精彩的故事。

摘要

展示对分析的强烈热情的捷径是培养对数据的真正兴趣。

如果你认真对待一份与数据有关的工作,那就全力以赴,成为一名与数字打交道的人。或许就像葡萄酒一样,数据有一种后天习得的味道。一个人只需要系好安全带,开始这个认真的旅程,享受它总是给予的兴奋。

如果你觉得这很有趣,你会喜欢我写的这些相关文章:

  • 让你在数据科学职业生涯中不可或缺的 4 种超能力
  • 数据科学家面试失败的 4 种方式

对数据科学充满热情?随时在LinkedIn上加我,订阅我的 简讯

如何使用自动编码器生成图像

原文:https://towardsdatascience.com/how-to-generate-images-using-autoencoders-acfbc6c3555e?source=collection_archive---------10-----------------------

你知道什么会很酷吗?如果我们不需要所有这些标记数据来训练我们的模型。我的意思是标记和分类数据需要太多的工作。遗憾的是,现有的从支持向量机到卷积神经网络的模型,大部分都离不开它们的训练。

除了一小组他们能做到的算法。好奇吗?这叫做无监督学习。无监督学习通过自身从未标记的数据中推断出一个函数。最著名的无监督算法是 K-Means 和 PCA,K-Means 已被广泛用于将数据聚类成组,PCA 是降维的首选解决方案。K-Means 和 PCA 可能是有史以来最好的两种机器学习算法。让它们更好的是它们的简单。我的意思是,如果你抓住了它们,你会说:“为什么我没有早点想到呢?”

我们想到的下一个问题是:“有没有无监督的神经网络?”。你大概从帖子的标题就知道答案了。自动编码器。

为了更好地理解自动编码器,我将在解释的同时提供一些代码。请注意,我们将使用 Pytorch 来构建和训练我们的模型。

自动编码器是简单的神经网络,其输出就是输入。就这么简单。他们的目标是学习如何重建输入数据。但这有什么帮助呢?诀窍在于它们的结构。网络的第一部分就是我们所说的编码器。它接收输入,并在低维的潜在空间中对其进行编码。第二部分(解码器)获取该向量并对其进行解码,以产生原始输入。

中间的潜在向量是我们想要的,因为它是输入的压缩的表示。应用非常广泛,例如:

  • 压缩
  • 降维

此外,很明显,我们可以应用它们来复制相同但稍有不同甚至更好的数据。例如:

  • 数据去噪:给它们一幅有噪声的图像,然后训练它们输出没有噪声的相同图像
  • 训练数据扩充
  • 异常检测:在单个类上训练它们,使得每个异常都给出大的重构误差。

然而,自动编码器面临着和大多数神经网络一样的问题。他们倾向于过度拟合,并遭受梯度消失问题。有解决办法吗?变分自动编码器是一个非常好的和优雅的努力。它本质上增加了随机性,但不完全是。

让我们进一步解释一下。变分自动编码器被训练来学习模拟输入数据的概率分布,而不是映射输入和输出的函数。然后从该分布中采样点,并将它们馈送到解码器,以生成新的输入数据样本。但是等一下。当我听到概率分布时,我想到的只有一件事:贝叶斯。是的,贝叶斯法则再次成为主要原则。顺便说一下,我不想夸大其词,但贝叶斯公式是有史以来最好的方程式。我不是在开玩笑。到处都是。如果你不知道什么是,请查一下。放弃这篇文章,学习贝叶斯是什么。我会原谅你。

回到变分自动编码器。我认为下面的图片说明了问题:

这就是了。随机神经网络。在我们自己构建一个生成新图像的示例之前,有必要再讨论一些细节。

VAE 的一个重要方面是损失函数。最常见的是,它由两部分组成。重建损失衡量重建数据与原始数据的不同程度(例如二进制交叉熵)。KL-divergence 试图调整该过程,并尽可能保持重建数据的多样性。

另一个重要的方面是如何训练模型。困难的出现是因为变量是确定性的,但随机和梯度下降通常不会这样工作。为了解决这个问题,我们使用了重新参数化。潜在向量(z)将等于我们分布的学习均值(μ)加上学习标准差(σ)乘以ε(ε),其中ε遵循正态分布。我们重新参数化样本,使随机性与参数无关。

在我们的例子中,我们将尝试使用可变自动编码器生成新图像。我们将使用 MNIST 数据集,重建的图像将是手写的数字。正如我已经告诉你的,我使用 Pytorch 作为一个框架,没有特别的原因,除了熟悉。首先,我们应该定义我们的层。

正如你所看到的,我们将使用一个非常简单的网络,只有密集的(在 pytorch 的例子中是线性的)层。下一步是构建运行编码器和解码器的函数。

只是几行 python 代码。没什么大不了的。最后,我们开始训练我们的模型,并看到我们生成的图像。

快速提醒:Pytorch 有一个与 Tensorflow 相反的动态图,这意味着代码正在运行。不需要创建图形,然后编译并执行它,Tensorflow 最近通过其急切执行模式引入了上述功能。

当训练完成时,我们执行测试函数来检查模型的工作情况。事实上,它做得相当好,构建的图像几乎与原始图像相同,我相信没有人能够在不了解整个故事的情况下区分它们。

下图显示了第一行中的原始照片和第二行中生成的照片。

很好,不是吗?

在我们结束这篇文章之前,我想再介绍一个话题。正如我们所见,变分自动编码器能够生成新的图像。这是生成模型的经典行为。生成模型正在生成新数据。另一方面,判别模型是对现有数据进行分类或判别。

用一些数学术语来解释:生成模型学习联合概率分布 p(x,y ),而判别模型学习条件概率分布 p(y|x)。

在我看来,生成模型要有趣得多,因为它们为许多可能性打开了大门,从数据扩充到可能的未来状态的模拟。但是在下一篇文章中会有更多的介绍。可能是关于一种相对新型的生成模型的帖子,叫做生成对抗网络。

在那之前,继续学习 AI。

如果您有任何想法、评论、问题或者您只想了解我的最新内容,请随时在LinkedinTwitterinsta gramGithub或在我的

原载于 2018 年 9 月 8 日sergioskar . github . io

如何在 Keras 中使用 LSTM 神经网络生成音乐

原文:https://towardsdatascience.com/how-to-generate-music-using-a-lstm-neural-network-in-keras-68786834d4c5?source=collection_archive---------0-----------------------

介绍

网络正被用来改善我们生活的方方面面。它们为我们提供想要购买的物品的建议,根据作者的风格生成文本,甚至可以用于改变图像的艺术风格。近年来,已经有一些关于如何使用神经网络生成文本的教程,但缺乏关于如何创作音乐的教程。在本文中,我们将介绍如何使用 Keras 库在 Python 中使用递归神经网络来创作音乐。

对于不耐烦的人,在教程的最后有一个 Github 库的链接。

背景

在我们进入实现的细节之前,有一些术语我们必须澄清。

递归神经网络(RNN)

递归神经网络是一类利用序列信息的人工神经网络。它们之所以被称为递归,是因为它们对序列中的每个元素都执行相同的功能,其结果取决于之前的计算。而输出与传统神经网络中的先前计算无关。

在本教程中我们将使用一个【LSTM】长短期记忆网络。它们是一种可以通过梯度下降有效学习的递归神经网络。使用门控机制,LSTMs 能够识别和编码长期模式。LSTMs 对于解决网络必须长时间记忆信息的问题非常有用,例如音乐和文本生成。

音乐 21

Music21 是一个用于计算机辅助音乐学的 Python 工具包。它允许我们教授音乐理论的基础知识,生成音乐示例并研究音乐。该工具包提供了一个简单的接口来获取 MIDI 文件的乐谱。此外,它允许我们创建音符和和弦对象,以便我们可以轻松地制作自己的 MIDI 文件。

在本教程中,我们将使用 Music21 来提取数据集的内容,并获取神经网络的输出,将其转换为乐谱。

克拉斯

Keras 是一个高级神经网络 API,它简化了与 Tensorflow 的交互。它的开发重点是支持快速实验。

在本教程中,我们将使用 Keras 库来创建和训练 LSTM 模型。一旦模型被训练,我们将使用它来为我们的音乐生成乐谱。

培养

在本节中,我们将介绍如何为我们的模型收集数据,如何准备数据以便在 LSTM 模型中使用,以及我们模型的架构。

数据

在我们的 Github 库中,我们使用了钢琴曲,主要由《最终幻想》的配乐组成。我们选择《最终幻想》音乐是因为大部分作品都有非常独特和美丽的旋律,而且作品数量庞大。但是任何由单个乐器组成的 MIDI 文件集都可以满足我们的需求。

实现神经网络的第一步是检查我们将使用的数据。

下面我们可以看到使用 Music21 读取的 midi 文件的摘录:

...
<music21.note.Note F>
<music21.chord.Chord A2 E3>
<music21.chord.Chord A2 E3>
<music21.note.Note E>
<music21.chord.Chord B-2 F3>
<music21.note.Note F>
<music21.note.Note G>
<music21.note.Note D>
<music21.chord.Chord B-2 F3>
<music21.note.Note F>
<music21.chord.Chord B-2 F3>
<music21.note.Note E>
<music21.chord.Chord B-2 F3>
<music21.note.Note D>
<music21.chord.Chord B-2 F3>
<music21.note.Note E>
<music21.chord.Chord A2 E3>
...

数据分为两种对象类型:音符 s 和和弦 s。音符对象包含关于音符的音高八度音程偏移的信息。

  • 音高是指声音的频率,或者说高低,用字母【A、B、C、D、E、F、G】来表示,A 最高,G 最低。
  • 八度 指的是你在钢琴上使用的那一组音高。
  • 偏移指音符在乐曲中的位置。

和弦对象实质上是同时播放的一组音符的容器。

现在我们可以看到,为了准确地产生音乐,我们的神经网络必须能够预测下一个音符或和弦。这意味着我们的预测数组必须包含我们在训练集中遇到的每个音符和弦对象。在 Github 页面上的训练集中,不同音符和和弦的总数是 352。对于网络来说,这似乎需要处理很多可能的输出预测,但 LSTM 网络可以轻松处理。

接下来我们要担心我们要把笔记放在哪里。正如大多数听过音乐的人所注意到的,音符之间通常有不同的音程。你可以在短时间内连续弹奏许多音符,然后是一段休息时间,在这段时间内没有音符弹奏。

下面我们有另一个用 Music21 读取的 midi 文件的摘录,只是这次我们在它后面添加了对象的偏移量。这让我们可以看到每个音符和和弦之间的音程。

...
<music21.note.Note B> 72.0
<music21.chord.Chord E3 A3> 72.0
<music21.note.Note A> 72.5
<music21.chord.Chord E3 A3> 72.5
<music21.note.Note E> 73.0
<music21.chord.Chord E3 A3> 73.0
<music21.chord.Chord E3 A3> 73.5
<music21.note.Note E-> 74.0
<music21.chord.Chord F3 A3> 74.0
<music21.chord.Chord F3 A3> 74.5
<music21.chord.Chord F3 A3> 75.0
<music21.chord.Chord F3 A3> 75.5
<music21.chord.Chord E3 A3> 76.0
<music21.chord.Chord E3 A3> 76.5
<music21.chord.Chord E3 A3> 77.0
<music21.chord.Chord E3 A3> 77.5
<music21.chord.Chord F3 A3> 78.0
<music21.chord.Chord F3 A3> 78.5
<music21.chord.Chord F3 A3> 79.0
...

从这段摘录和大部分数据集可以看出,midi 文件中音符之间最常见的音程是 0.5。因此,我们可以通过忽略可能输出列表中的变化偏移来简化数据和模型。它不会太严重地影响网络产生的音乐的旋律。因此,在本教程中,我们将忽略偏移量,将可能的输出列表保持在 352。

准备数据

既然我们已经检查了数据,并且确定了我们想要使用的特征是作为我们的 LSTM 网络的输入和输出的音符和弦,那么是时候为网络准备数据了。

首先,我们将数据加载到一个数组中,如下面的代码片段所示:

from music21 import converter, instrument, note, chordnotes = []for file in glob.glob("midi_songs/*.mid"):
    midi = converter.parse(file)
    notes_to_parse = None parts = instrument.partitionByInstrument(midi) if parts: # file has instrument parts
        notes_to_parse = parts.parts[0].recurse()
    else: # file has notes in a flat structure
        notes_to_parse = midi.flat.notes for element in notes_to_parse:
        if isinstance(element, note.Note):
            notes.append(str(element.pitch))
        elif isinstance(element, chord.Chord):
            notes.append('.'.join(str(n) for n in element.normalOrder))

我们首先使用 converter.parse(file) 函数将每个文件加载到一个 Music21 流对象中。使用这个流对象,我们得到了文件中所有音符和和弦的列表。我们使用每个音符对象的字符串符号来附加其音高,因为音符的最重要部分可以使用音高的字符串符号来重新创建。我们通过将和弦中每个音符的 id 编码到一个字符串中来添加每个和弦,每个音符用一个点来分隔。这些编码使我们能够轻松地将网络生成的输出解码成正确的音符和和弦。

现在我们已经把所有的音符和和弦放入一个序列列表中,我们可以创建序列作为我们网络的输入。

Figure 1: When converting from categorical to numerical data the data is converted to integer indexes representing where the category is positioned in the set of distinct values. E.g. apple is the first distinct value so it maps to 0, orange is the second so it maps to 1, pineapple is the third so it maps to 2, and so forth.

首先,我们将创建一个映射函数,从基于字符串的分类数据映射到基于整数的数值数据。这样做是因为神经网络对于基于整数数字数据的性能比基于字符串的分类数据好得多。从分类到数字转换的一个例子可以在图 1 中看到。

接下来,我们必须为网络及其各自的输出创建输入序列。每个输入序列的输出将是音符列表中输入序列中音符序列之后的第一个音符或和弦。

sequence_length = 100# get all pitch names
pitchnames = sorted(set(item for item in notes))# create a dictionary to map pitches to integers
note_to_int = dict((note, number) for number, note in enumerate(pitchnames))network_input = []
network_output = []# create input sequences and the corresponding outputs
for i in range(0, len(notes) - sequence_length, 1):
    sequence_in = notes[i:i + sequence_length]
    sequence_out = notes[i + sequence_length]
    network_input.append([note_to_int[char] for char in sequence_in])
    network_output.append(note_to_int[sequence_out])n_patterns = len(network_input)# reshape the input into a format compatible with LSTM layers
network_input = numpy.reshape(network_input, (n_patterns, sequence_length, 1))
# normalize input
network_input = network_input / float(n_vocab)network_output = np_utils.to_categorical(network_output)

在我们的代码示例中,我们将每个序列的长度设为 100 个音符/和弦。这意味着,为了预测序列中的下一个音符,网络有前 100 个音符来帮助进行预测。我强烈建议使用不同的序列长度来训练网络,以查看不同的序列长度对网络生成的音乐的影响。

为网络准备数据的最后一步是标准化输入和一次性编码输出。

模型

最后,我们开始设计模型架构。在我们的模型中,我们使用四种不同类型的层:

LSTM 层是一个递归神经网络层,它将一个序列作为输入,可以返回序列(return_sequences=True)或矩阵。

辍学层是一种正则化技术,包括在训练期间的每次更新时将一部分输入单元设置为 0,以防止过拟合。该分数由该层使用的参数决定。

密集层全连接层是全连接神经网络层,其中每个输入节点连接到每个输出节点。

激活层决定了我们的神经网络将使用什么激活函数来计算一个节点的输出。

model = Sequential()
    model.add(LSTM(
        256,
        input_shape=(network_input.shape[1], network_input.shape[2]),
        return_sequences=True
    ))
    model.add(Dropout(0.3))
    model.add(LSTM(512, return_sequences=True))
    model.add(Dropout(0.3))
    model.add(LSTM(256))
    model.add(Dense(256))
    model.add(Dropout(0.3))
    model.add(Dense(n_vocab))
    model.add(Activation('softmax'))
    model.compile(loss='categorical_crossentropy', optimizer='rmsprop')

现在,我们已经了解了将要使用的不同层的一些信息,是时候将它们添加到网络模型中了。

对于每个 LSTM、密集和激活层,第一个参数是该层应该有多少个节点。对于丢弃层,第一个参数是训练期间应该丢弃的输入单元的分数。

对于第一层,我们必须提供一个名为 input_shape 的参数。该参数的目的是通知网络它将训练的数据的形状。

最后一层应该总是包含与我们系统的不同输出相同数量的节点。这确保了网络的输出将直接映射到我们的类。

在本教程中,我们将使用一个简单的网络,包括三个 LSTM 层,三个下降层,两个密集层和一个激活层。我建议试验一下网络的结构,看看能否提高预测的质量。

为了计算每次训练迭代的损失,我们将使用分类交叉熵,因为我们的每个输出只属于一个类,而我们有两个以上的类要处理。为了优化我们的网络,我们将使用 RMSprop 优化器,因为它通常是递归神经网络的一个非常好的选择。

filepath = "weights-improvement-{epoch:02d}-{loss:.4f}-bigger.hdf5" checkpoint = ModelCheckpoint(
    filepath, monitor='loss', 
    verbose=0,        
    save_best_only=True,        
    mode='min'
)    
callbacks_list = [checkpoint] model.fit(network_input, network_output, epochs=200, batch_size=64, callbacks=callbacks_list)

一旦我们确定了网络的架构,就该开始培训了。Keras 中的 model.fit() 函数用于训练网络。第一个参数是我们之前准备的输入序列列表,第二个参数是它们各自的输出列表。在我们的教程中,我们将训练网络 200 个历元(迭代),通过网络传播的每一批包含 64 个样本。

为了确保我们可以在任何时间点停止训练而不丢失我们所有的辛苦工作,我们将使用模型检查点。模型检查点为我们提供了一种在每个时期后将网络节点的权重保存到文件中的方法。这使得我们一旦对损失值感到满意,就可以停止运行神经网络,而不必担心失去权重。否则,在我们有机会将权重保存到文件之前,我们将不得不等待网络完成所有 200 个时期。

创作音乐

既然我们已经完成了对网络的训练,现在是时候让我们花了几个小时训练的网络玩一玩了。

为了能够使用神经网络生成音乐,你必须将它置于与以前相同的状态。为简单起见,我们将重用培训部分的代码来准备数据,并以与之前相同的方式建立网络模型。除了不是训练网络,而是将我们在训练部分保存的权重加载到模型中。

model = Sequential()
model.add(LSTM(
    512,
    input_shape=(network_input.shape[1], network_input.shape[2]),
    return_sequences=True
))
model.add(Dropout(0.3))
model.add(LSTM(512, return_sequences=True))
model.add(Dropout(0.3))
model.add(LSTM(512))
model.add(Dense(256))
model.add(Dropout(0.3))
model.add(Dense(n_vocab))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')# Load the weights to each node
model.load_weights('weights.hdf5')

现在,我们可以使用训练好的模型开始生成注释。

由于我们有一个完整的音符序列列表,我们将在列表中选择一个随机索引作为我们的起点,这允许我们在不做任何更改的情况下重新运行生成代码,并且每次都会得到不同的结果。但是,如果您希望控制起始点,只需用命令行参数替换 random 函数。

这里我们还需要创建一个映射函数来解码网络的输出。这个函数将从数字数据映射到分类数据(从整数到注释)。

start = numpy.random.randint(0, len(network_input)-1)int_to_note = dict((number, note) for number, note in enumerate(pitchnames))pattern = network_input[start]
prediction_output = []# generate 500 notes
for note_index in range(500):
    prediction_input = numpy.reshape(pattern, (1, len(pattern), 1))
    prediction_input = prediction_input / float(n_vocab) prediction = model.predict(prediction_input, verbose=0) index = numpy.argmax(prediction)
    result = int_to_note[index]
    prediction_output.append(result) pattern.append(index)
    pattern = pattern[1:len(pattern)]

我们选择使用网络生成 500 个音符,因为这大约是两分钟的音乐,并给网络足够的空间来创作旋律。对于我们想要生成的每个音符,我们必须向网络提交一个序列。我们提交的第一个序列是起始索引处的音符序列。对于我们用作输入的每个后续序列,我们将删除序列的第一个音符,并在序列的末尾插入前一次迭代的输出,如图 2 所示。

Figure 2: The first input sequence is ABCDE. The output we get from feeding that to the network is F. For the next iteration we remove A from the sequence and append F to it. Then we repeat the process.

为了从网络的输出中确定最可能的预测,我们提取最高值的索引。输出数组中索引 X 处的值对应于 X 是下一个音符的概率。图 3 有助于解释这一点。

Figure 3: Here we see the mapping between the an output prediction from the network and classes. As we can see the highest probability is that the next value should be D, so we choose D as the most probable class.

然后,我们将网络的所有输出收集到一个数组中。

现在我们已经将所有音符和弦的编码表示放在一个数组中,我们可以开始解码它们并创建一个音符和弦对象的数组。

首先,我们必须确定我们正在解码的输出是音符还是和弦。

如果模式是一个和弦,我们必须将弦分成一系列音符。然后我们遍历每个音符的字符串表示,并为每个音符创建一个音符对象。然后我们可以创建一个包含这些音符的和弦对象。

如果模式是一个音符,我们使用模式中包含的音高的字符串表示创建一个音符对象。

在每次迭代结束时,我们将偏移量增加 0.5(正如我们在上一节中所决定的),并将创建的音符/和弦对象添加到一个列表中。

offset = 0
output_notes = []# create note and chord objects based on the values generated by the modelfor pattern in prediction_output:
    # pattern is a chord
    if ('.' in pattern) or pattern.isdigit():
        notes_in_chord = pattern.split('.')
        notes = []
        for current_note in notes_in_chord:
            new_note = note.Note(int(current_note))
            new_note.storedInstrument = instrument.Piano()
            notes.append(new_note)
        new_chord = chord.Chord(notes)
        new_chord.offset = offset
        output_notes.append(new_chord)
    # pattern is a note
    else:
        new_note = note.Note(pattern)
        new_note.offset = offset
        new_note.storedInstrument = instrument.Piano()
        output_notes.append(new_note) # increase offset each iteration so that notes do not stack
    offset += 0.5

现在我们有了网络生成的音符和和弦列表,我们可以使用该列表作为参数来创建 Music21 Stream 对象。最后,为了创建包含网络生成的音乐的 MIDI 文件,我们使用 Music21 工具包中的 write 函数将流写入文件。

midi_stream = stream.Stream(output_notes)midi_stream.write('midi', fp='test_output.mid')

结果

现在是惊叹结果的时候了。图 4 包含使用 LSTM 网络生成的音乐的活页乐谱表示。我们一眼就能看出它有一定的结构。这在第二页倒数第三行尤为明显。

了解音乐并能读懂乐谱的人会发现乐谱上散布着一些奇怪的音符。这是神经网络无法创造完美旋律的结果。在我们目前的实施中,总会有一些错误的注释,为了能够取得更好的结果,我们需要一个更大的网络。

Figure 4: An example of sheet music generated by the LSTM network

从这个相对较浅的网络得到的结果仍然令人印象深刻,这可以从 Embed 1 中的音乐示例中听出来。对于那些感兴趣的人,图 4 中的活页乐谱代表了 NeuralNet Music 5 的乐谱。

Embed 1: Examples generated by the network

未来的工作

我们用一个简单的 LSTM 网络和 352 节课取得了显著的效果和优美的旋律。然而,也有可以改进的地方。

首先,我们目前的实现不支持音符的不同持续时间和音符之间的不同偏移。为了实现这一点,我们可以为每个不同的持续时间添加更多的类,并添加代表音符之间的休止符的休止符类。

为了通过添加更多的类来获得令人满意的结果,我们还必须增加 LSTM 网络的深度,这将需要一台功能强大得多的计算机。我在家里使用的笔记本电脑花了大约 20 个小时来训练现在的网络。

第二,将开头和结尾添加到片段中。由于网络现在没有片段之间的区别,也就是说网络不知道一个片段在哪里结束,另一个片段在哪里开始。这将允许网络从头到尾生成一个片段,而不是像现在这样突然结束所生成的片段。

第三,添加一个处理未知音符的方法。现在,如果网络遇到它不知道的通知,它将进入失败状态。解决该问题的可能方法是找到与未知音符最相似的音符或和弦。

最后,向数据集添加更多仪器。现在,网络只支持只有一个乐器的作品。看看它是否能扩展到支持整个管弦乐队会很有趣。

结论

在本教程中,我们已经展示了如何创建一个 LSTM 神经网络来生成音乐。虽然结果可能并不完美,但仍然令人印象深刻,并向我们展示了神经网络可以创作音乐,并有可能用于帮助创作更复杂的音乐作品。

点击这里查看 Github 资源库中的教程

如何用 Python 代码将 AE (Autoencoder)应用于 Mnist 生成机器学习中的新数据

原文:https://towardsdatascience.com/how-to-generate-new-data-in-machine-learning-with-vae-variational-autoencoder-applied-to-mnist-ca68591acdcf?source=collection_archive---------6-----------------------

链接到 github

自动编码器是用于生成新数据的神经网络(无监督学习)。该模型用于为数据集生成新数据,或者在我们想要从数据中消除噪声的情况下使用。网络由多个神经网络组成;一个编码器和一个解码器通过一个瓶颈连接;这个瓶颈就是下图所示的潜在空间;

font: Hackernoon

编码器处理数据,直到瓶颈(潜在空间)减小尺寸,并且解码器获取数据并重构数据结构,以给出与我们的原始数据相同的输出。我们可以把潜在空间看作是我们数据的一种表示。

在这个具体的例子中,我们正在读取 28x28 像素(784 个元素)的数字(Mnist 数据集)图像,我们希望将它们减少到 32 个元素(潜在空间),再次创建 28x28 像素的图像。

MNIST 数据集 是一个大型的 c 手写数字集合,常用于图像处理。

font: Wikipedia

我们可以开始导入我们将需要的所有库:

import

我们正在使用来自 keras.models 的类模型。为了更深入,使用 keras 功能 API 的教程是有用的,这是定义复杂模型的方法,例如多输出模型、有向无环图或具有共享层的模型。

在所有的导入之后,我们需要导入数据集,在本例中是由 keras 提供的。

我们使用的图像是 28x28 像素的黑白图像。每个像素由 1 到 255 范围内的一个数字表示。

导入数据后,我们将对它们进行归一化,将每个像素值除以 255,这是可能的最大值,所有值的范围为 0-1。

标准化之后,我们需要为输入层重新调整数组的形状。

Importing and Data Normalization

一旦我们有了所有的数据,我们可以开始定义我们的模型,在这里我们可以清楚地看到 3 个部分(编码,瓶颈和解码。通过我们的模型结构,我们可以看到,我们有超过 25k 个参数需要训练,这些参数由权重和偏差表示。这些参数将帮助你生成新的数据。

模型架构的代码可以在 github 上看到。

在建模之后,我们需要编译(定义优化器和损失函数)并使其适合我们的训练集。

Compiling the model

Plotting the Validation Loss

与训练损失相比,验证损失告诉我们我们的模型在泛化方面有多好。

现在我们已经编译和训练了模型,我们可以使用模型的预测功能生成新数据。

code for plotting

用这个代码我们绘制了两行,每行 10 个数字。第一行是真实的图像,第二行是生成的图像。正如我们所看到的,我们丢失了一些信息,但数量显然是相同的。

1s row real <***> 2nd row generated

这是一个非常强大的模型,可以与管道中的其他机器学习模型相结合,也可以用于预训练模型或减少数据中的噪声。

如果你愿意支持我写其他类似的文章, 请我喝杯咖啡 😃

如何获得一份数据科学家的工作?

原文:https://towardsdatascience.com/how-to-get-a-job-as-a-data-scientist-f417078fe13e?source=collection_archive---------0-----------------------

大家好。这篇博客文章来自我最近在 LinkedIn 发表的三篇文章。他们是第一部分的、第二部分的和第三部分的。

这是一个很难回答的问题。这一个和我一起挂吧(而这并不是关于宇宙、存在和一切的最终答案)。

这是我最常从我认识的人或我的关系@ LinkedIn 那里收到的问题之一。

我告诉你我的经历。我现在已经做了一段时间的数据科学家(尽管有些人仍然认为这不是一个职业,或者可能不是一个新的职业)。不过我还是要说说我是如何在 BBVA 数据&分析 得到现在这份工作的。

我去年完成了我的硕士学位,我做了一个关于宇宙学和贝叶斯机器学习的物理学。就在毕业前,我想了想我想做什么,我决定我想在数据科学领域工作。

我申请了将近 125 份工作(真的,也许你申请了更多),我只收到了 25-30 份回复。有些人只是说:谢谢,但是不用了。我接受了将近 15 次采访。我从每一个人身上学到了东西。变好了。我不得不面对许多拒绝。一些我实际上没准备好的事情。但我喜欢接受采访的过程(说实话,并不是所有人)。我学习了很多,每天编程,看了很多文章和帖子。他们帮了大忙。

但是,我是怎么得到这份工作的?

很有耐心。这并不容易,但到了第七次面试时,我意识到了几件事:

  • 有些人不知道什么是数据科学。
  • 招聘人员是你面试时最好的朋友,他们想帮你进去。所以相信他们,让他们帮助你,提出问题!
  • 人们更感兴趣的是你如何解决问题,如何处理一些特定的情况,而不是你的技术知识。

我真的做好了回答算法、机器学习、Python、Spark 等问题的准备。但是我还没有准备好回答关于我如何解决一个问题,或者我将如何处理一个情况的问题。

到第八次面试时,我回顾了我以前作为数据科学家、计算机工程师、物理学家和人类所做的一切。我准备好回答关于现实生活工作的问题,如何处理复杂的情况,如何处理新数据,如何做数据科学工作流,如何向经理解释困难的概念等等。

我做得好多了。我也平静下来了。我知道面试我的人是想让我进公司,这不是调查。

我的建议是找一份数据科学家的工作:

  • 耐心点。在找到一份工作之前,你可能会申请上百份工作。
  • 准备好。很多。不仅要学习重要的概念、编程和回答商业问题,还要记住你将是组织中的重要一员,你将与不同的人和情况打交道,准备好回答关于你在不同工作情况下如何表现的问题。
  • 有一个投资组合。如果你正在寻找一份严肃的数据科学的有偿工作,做一些有真实数据的项目。如果你能把它们发布在 GitHub 上。除了 Kaggle 比赛,找一些你喜欢的事情或者你想解决的问题,用你的知识去做。
  • 招聘人员是你的朋友。面试你的人也是。他们希望你进入公司,这是我每天都记得的一个强有力的建议。
  • 询问人们是做什么的。我建议您关注马修·梅奥 关于“数据科学家的一天”的帖子,以便更好地了解我们的工作。
  • 如果你想要一份实习工作,就要有你的学术技能。

祝你一切顺利,成功:)。

跟我来:【https://www.linkedin.com/in/faviovazquez/】T4。

没有经验如何在 AI 找工作

原文:https://towardsdatascience.com/how-to-get-a-job-in-ai-with-no-experience-16526874165d?source=collection_archive---------4-----------------------

Photo by James Harrison on Unsplash

介绍

在我们开始之前,我想我应该给一些背景信息,关于我写这篇文章的动机。我刚刚从计算机科学学士学位毕业。大约在我第三年的中途,我知道我唯一想从事的领域是人工智能。我的大学没有任何人工智能的专门课程,在都柏林也没有多少人工智能实习。我很高兴地说,我现在作为一名毕业生在一个人工智能研发团队工作。

这篇文章将简要概述我是如何为一份没有经验的人工智能工作做准备的。现在承认,这些信息中没有一个是令人兴奋的,大多数提示都是显而易见的。然而,就像健康饮食和锻炼一样,我发现尽管每个人都知道这是你需要做的事情,但很多人还是不去做。我希望这篇文章能帮助人们制定自己的计划,进入令人兴奋的人工智能世界。我想指出的另一件事是,这个建议通常适用于软件开发的所有领域,然而具体的指导方针和主题显然将集中在 AI/ML 上。

人工智能的现状

Nvidia provides a nice infographic of how AI has progressed over the past several decades, source

对于软件毕业生和初级开发人员来说,ML 是一个非常独特的领域。这个领域在过去 5 年才真正起步,而且还相对年轻。这为新的开发者和雇主提供了一个真正的问题/机会。

毕业生:对这个领域没有任何扎实的信息,大学里的模块很少,很难获得相关的经验。

雇主:发现很难找到有相关经验的人。

作为一名大学生,这是一个艰难的困境,但也提供了一个很好的机会。目前,合格的机器学习(ML)开发人员数量严重不足。所有公司都在招聘这些职位,但都招不到人。如果你能证明你有相关的专业知识,你将是一个非常理想的候选人,不仅会从毕业生中脱颖而出,也会在有经验的雇员中脱颖而出。

这在理论上听起来很棒,但当然没那么简单。很难找到这些人是有原因的。这是一个很难精通的领域,而且这个领域正在快速发展,每个月都有更多的进步需要跟上。下面我将介绍你需要努力的关键领域,以便建立你作为机器学习专家的品牌。

  • 经验
  • 对理论的理解
  • 专业化
  • 大学

经验

但是题目说没经验??Wtf!

是的,我知道,但是说实话,没有人会雇佣一个完全没有经验的人。

Source

就像我之前说的,在做 ML 的公司工作很难获得经验。因此,如果这不是一个选项,你需要为自己提供所需的经验。下面是一些你可以做到这一点的好方法。

  • 个人项目
  • 黑客马拉松
  • 编码挑战
  • 开源项目

个人项目

你 100%需要在你的 GitHub 中有 ML 项目。这是从招聘过程中剔除人员的一个非常快速的方法,也是招聘人员在看完你的简历后首先要看的。现在,当你还在学习 ML 的时候,想出一个项目可能有点困难,没关系。它不需要很大或华而不实或创新,它只需要显示你对主题的理解,并给人们一个信号,表明你能够以良好的编码标准独立工作/研究。构建 GitHub 项目时需要关注的几件事。

  1. 完成这个项目不会超过一个月
  2. 确保你的代码是干净的,模块化的,有注释的
  3. 为您的代码提供自述文件和其他文档,如使用的技术、参考教程、依赖项等
  4. 如果可能,为代码库的关键部分提供单元测试

接下来的事情是选择做什么项目。你希望它足够简单,你可以在一个月内完成,并且足够相关,你可以在这个过程中学到有用的技能。以下是一些例子:

  • 使用 CNN 的图像分类器。只是让它区分两种类型的图像(即狗/猫)。
  • 标准前馈神经网络对数据进行分类。Kaggle.com 有很多很棒的数据集。以虹膜数据集为例,根据给定的数据对一种花的虹膜类型进行分类。
  • 电影评论的情感分析。另一个受欢迎的 first 项目是使用神经网络对电影评论的情绪进行分类(好的或坏的),你可以使用 IMDB 数据集,也可以在 kaggle 上找到。

黑客马拉松

黑客马拉松之所以伟大,有几个原因。它迫使你走出去,建立一些东西,你会遇到更多有经验的人,你可以把它放在你不断增长的简历/投资组合中。试着去找专门的人工智能黑客马拉松,但也去找一般的软件黑客马拉松,试着在你的项目中加入人工智能元素。查看 meetup.com的,看看你所在的地区是否有专注于人工智能或软件开发的 meetup 团体。这些团体通常每年至少有一次黑客马拉松。

编码挑战

类似于黑客马拉松,编码挑战迫使你建立一个你所学的实际应用,当你申请你的 ML 工作时,这是值得的。作为一个额外的奖励,这些比赛通常很有趣,增加的竞争意识可以成为一个很好的动力。看看 Kaggle 、 CodinGame 和 Halite.io 等地方

开源项目

这是你能得到的最接近真实世界的经验,除了真正得到一份 ML 开发者的工作。开源项目让你真正了解产品级代码,并教会你有价值的技能,如调试、版本控制、与其他人一起开发,当然还有大量的 ML(取决于项目)。

理解理论

好的,所以最主要的事情是获得一些项目和经验,但这不仅仅是跟随一些教程并贴在 GitHub 上(尽量不要这样做,😄)你需要了解你正在构建什么。很多大学生都知道,学习一个东西和理解它是有很大区别的。

有很多很好的资源,清楚地介绍了 ML 和深度学习的重要理论。另一个重要的事情指出,不要只关注深度学习。我知道这是 AI“更性感”的一面,但这只是一面。熟悉更多传统形式的 ML,如回归模型、支持向量机和所有主要的概率和统计概念。无论你在构建什么类型的人工智能,这些都是有价值的。

以下是我发现的一些更好的资源。

  • 斯坦福机器学习是 coursera 上的一门免费课程,涵盖了你需要了解的从回归模型到深度学习的所有机器学习知识
  • DeepLearning.ai 作者吴恩达。与之前的课程一样,Ng 对人工智能进行了非常全面的研究,然而这门课程是专门针对深度学习的,而不是一般的 ML。
  • 安德鲁·特拉斯克的《探索深度学习》可能是我找到的关于深度学习的最好的书。除了 numpy,这本书没有使用任何库来构建神经网络。它更复杂,也更费钱,但如果你有时间仔细阅读,它是非常有价值的。
  • Siraj Raval' 的 youtube 频道是一个很好的地方,可以获得几乎所有相关 ML 主题的高水平概述,观看起来也很有趣。

专业化

diagram showing some of the major areas of AI today, source

对于雇主来说,这是一个去粗取精的好方法。ML 是一个巨大的领域。一个人不可能什么都知道。这就是为什么人们专门化并成为专家。如果你不仅能展示出你对 ML/Deep Learning 总体上有着扎实的理解,而且在某个领域有专长,你将对潜在雇主变得更有价值。但是注意不要把自己放在一个盒子里,你不必现在就决定你的整个职业道路,相反,试着找到一个真正让你兴奋的领域,了解更多,如果可以的话,也许可以做几个项目。这里有一些专业化的例子。

  • 计算机视觉: CNN,分割,标记,描述,物体检测
  • 经常性网络:时间序列数据如股票市场和一个视频,LSTM 细胞
  • 强化学习:教代理学习技能,比如玩视频游戏或驾驶
  • 自然语言处理:聊天机器人、情感分析、内容生成、内容摘要
  • 生成对抗网络:学习生成内容,如图像、3D 模型、学习策略、音频
  • 元学习:学会学习
  • 一次性学习:用很少的数据学习
  • 神经网络可视化和调试:巨大的研究领域,神经网络仍然是一个黑匣子,我们很难可视化它们,也很难理解为什么它们在损坏时不工作。

大学

这是很多人不同意的一点。成为软件开发人员的道路正在改变。大学不再像以前那样是进入这个行业的硬性要求。谷歌和苹果等科技巨头甚至已经开始放弃对学士学位的要求。这是因为创新型公司认识到,他们希望与之共事的人充满激情,自我驱动,渴望采取主动。所有这些都不需要明确的学位,有了互联网上的大量资源,你可以在家自学任何东西,只要你愿意付出努力。

话虽如此,在大学里表现良好是一个很大的奖励,不应该被低估。因此,我的建议是,如果你的情况不允许你上大学,不要纠结于此,还有许多其他途径向你敞开。如果你在大学,那么你需要粉碎它。

如果你执行了这篇文章中提到的所有其他事情,你很有可能在大学成绩不好的情况下找到一份工作。然而,如果你得了 1.1 分(根据爱尔兰教育系统,这是最好的成绩)或高 GPA,并且有一个围绕前面提到的主题的令人敬畏的最后一年项目(FYP),你将处于一个更好的位置。所以这是你需要关注的事情。抱着“我要碾压这个”的攻击性心态进大学。每节课都去,记笔记,早点完成作业,好好学习,拿成绩。

结论

现在是进入人工智能行业的最好时机。就像互联网的出现一样,人工智能将影响所有领域的所有业务,使其成为任何组织最受追捧的工具之一。目前,我们仍处于人工智能能力的初级阶段。这意味着该行业正处于巨大的创新、发现和不确定状态。专家很少,没有人知道所有的答案。人工智能社区处于不断学习和完善的状态。所以,投入时间,尽可能多的学习,你很快就会发现你能多快提高你的技能。这不是一件容易的事,需要时间。所以要有耐心,坚持不懈,保持专注。

如何获得远程机器学习工作

原文:https://towardsdatascience.com/how-to-get-a-remote-machine-learning-job-aa378d9879f9?source=collection_archive---------2-----------------------

如今,大部分软件公司都提供远程工作。然而,这大多忽略了机器学习职位:大多数仍然局限于办公室。那么,进入远程机器学习的最佳方式是什么呢?

这篇内容首先在 RemoteML 上发布——远程机器学习的全球社区。

ML 为什么不一样?

是什么让机器学习不同于其他通常提供远程工作的工程职位?嗯,最大的机器学习雇主通常是大型科技公司,他们正在建设大型办公园区,很少提供远程工作。

初创公司通常喜欢提供远程工作,通常外包机器学习或使用公共 API 和服务。然而,这在不久的将来可能会改变。机器学习变得越来越实用,用不了多久(远程优先)初创公司也会开始招聘机器学习人员。

准备

远程工作听起来很棒。但是你确定你适合吗?在开始申请之前,问自己这些问题:

  • 你是否生活在一个可以安静工作、不受干扰、有稳定电力/互联网连接的环境中?
  • 工作时,你需要帮助或询问问题的频率如何?你是自导自演吗?在远程环境中,您必须依赖异步通信。如果你不停地检查每个人,没人会有效率。你需要能够独立工作。
  • 你的社交生活准备好了吗?你不会和你的同事有很多社交互动。所以你需要一个社会环境来帮助你不变得孤独。

寻找职位和申请

你认为你已经准备好接受机器学习领域的远程职位了吗?你需要找到一些远程机器学习的位置。这样做的一些好地方有 AngelList (针对初创公司) RemoteML (针对远程机器学习职位) RemoteOK 和we work Remote。设置职位通知,并始终阅读职位描述:有时远程职位只适用于某些时区或国家。

如前所述,能够独立工作在远程工作中非常非常重要,所以在申请职位时,向他们展示你以前是如何独立工作的。可以说,在实现远程工作的过程中,预期、沟通和性格比你实际的硬技能更重要。

另外请记住:选择远程工作时,您是在与全球人才库竞争!对你所做的事情充满信心,你会很快找到你梦想的职位。

如何让临床人工智能技术获得监管机构的批准

原文:https://towardsdatascience.com/how-to-get-clinical-ai-tech-approved-by-regulators-fa16dfa1983b?source=collection_archive---------0-----------------------

本文于 2019 年 6 月更新,以适应医疗器械法规即将到来的变化

医学中的人工智能正在迅速发展,除了一个讨厌的障碍,几乎没有什么可以阻止它。无论你是一家三人创业的小公司,还是一家价值数十亿美元的国际企业集团,你都必须通过医疗器械监管的试金石测试。没有回避它,没有躲避它,所以你不妨拥抱它。还记得儿童故事书《我们要去猎熊吗?…

与医疗保健产品相关的法规比人工智能存在的时间要长得多。这一切开始于 20 世纪 60 年代,当时人们开始意识到(可悲的是)沙利度胺会严重损害未出生的婴儿。因此,药品开始要求上市前证据和质量控制监管,以避免这种灾难性事件再次发生。在药品之后不久,医疗器械也被纳入监管范围。

医疗器械法规传统上适用于物理产品(例如手术器械)和运行物理临床机器的软件(心电图机内的软件)。制定这些法规的原因很简单——患者安全。监管机构只想知道一件事——您的产品是否能安全有效地用于预期目的?医学上(或任何地方)没有什么是 100%完美的,所以你必须提供证据,证明你已经尽了最大努力来确保使用该设备的好处大于任何风险,并且任何未减轻的风险都是可以接受的。

试图以极快的速度创新固然很好,但监管者并不在乎这些。他们希望你停下来,测试,验证并证明你不会“造成伤害”。请记住,你现在是在医疗保健行业,而不是某个应用商店或研究实验室,你和任何医生一样对病人负有责任。你不会希望你的技术被认为和沙利度胺一样危险吧?

你不仅要使用可验证的数据真实准确地描述设备的性能和功能,还必须以你的营销团队能够传达的方式进行描述,而不要过度宣传、错误销售或错误品牌。一个巨大的错误是告诉监管者一件事,然后又卖另一件…

听说过 Theranos 吗?这家美国实验室公司告诉 FDA,他们的血液测试只能检测极少量样本的结果,但随后被发现有多达三分之一的内部质量控制检查失败,影响了凝血测试结果的患者护理,并可能导致中风和心脏病发作,从而损失了近 90 亿美元的价值。这里要学习的一课——对你的产品能做什么要真实和诚实!

在本文中,我将介绍根据最新版本的医疗器械法规,使您的产品获准进入欧洲市场所需的最新步骤,并获得圣杯式的认证标志——CE 标志。

你可能想知道一个学术放射学家是如何知道这些东西的?2016 年,我在英国数字健康技术初创公司( Babylon Health )负责监管事务,并成功为一个人工智能支持的医疗移动应用程序获得了世界上第一个 CE 标志(I 级),现在是 Kheiron Medical 的临床总监,这是第一家获得放射学深度学习软件 CE 标志(IIa 级)的英国公司。

你可以这样做…但是我警告你,这不是为容易被吓住的人准备的…

什么是 CE 标志?

CE 是法语短语“Conformité Européene”的首字母缩写。希望这不需要翻译...

CE 标志不仅适用于医疗器械,在欧洲几乎任何产品上都可以找到。只要看一下你附近的一个物体,在小字的某个地方会有一个 CE 标志。该标志表示该产品符合相关指令的基本要求,并且可以合法地在整个欧洲成员国自由投放市场。就医疗器械而言,产品必须符合欧盟委员会制定的欧盟医疗器械法规 2017/745 (MDR)的要求。这些法规是强制性和规范性的,将于 2020 年 5 月取代现有的医疗器械指令(MDD 或 MEDDEVs)。它们也是治疗失眠的好方法,但这不是它们的预期用途。

预期用途

无论你的算法或 AI 产品做什么,你都需要仔细清晰地定义它。这种描述在监管术语中被称为设备的“预期用途”,它是你进入监管行业迷宫之旅的基石。定义一个目的不仅能让监管者清楚地了解你的设备,还能帮助你的团队牢牢记住他们在做什么。

预期用途通常分为几个部分:

名称、型号、设备描述、安全分类、操作原理、预期用途、确切的医疗适应症、医疗条件的阶段和严重程度、预期使用环境、预期患者人群(包括排除)、预期用户、使用风险、预期结果限制和正常使用条件。

明确设备的预期用途是获得监管机构批准的第一步,因此确保正确非常重要。你必须准确描述你的设备能做什么,而不是它能做什么。(如果你不确定它的预期用途是什么——去你的浴室橱柜,拿出一包药片,并阅读里面那张纸的开头。这是您需要生成的最低限度的文档级别)。一旦你定义了你的预期用途,就是这样。没有回头路可走——监管机构将根据你的描述对你的产品进行分类和评判。对你预期用途的任何改变都意味着你必须重新开始整个过程。

找出你的设备的类别

在欧洲,医疗器械的分类是由 MDR 定义的(见下面分类的最新变化)。在美国,FDA 规定了设备类别。根据对患者的潜在风险,分类分为三种主要类型:

I 级—低风险,如听诊器、温度计或助残工具。

II 级——中等风险在欧洲也分为 IIa 级和 IIb 级,后者风险更大,如与人体直接接触的隐形眼镜。

III 级—高风险,如手术器械或植入式除颤器。

这些等级(I、IIa、IIb、III)决定了您需要走四条合格评定路线中的哪一条。

不言而喻,你的设备风险越大,它的故障就越具有侵入性或危险性,它的副作用就越多,它的级别就越高。类似地,所需的监管审查水平随着设备类别的增加而增加。

一般来说,根据当前的规则,支持医生决策的人工智能算法被称为临床决策支持软件(CDS),并被视为第二类。它是 IIa 类还是 b 类取决于您的算法的预期用途。我希望我能给你一个精确的分类,到底哪个算法函数属于哪个类,但不幸的是,这不是非黑即白的。然而,根据经验,其输出能够被人重写的 CDS 装置通常是 IIa,而那些更自主的是 IIb。

如果你不确定,你应该和监管者或监管顾问展开对话。不要浪费时间去申请一个不正确的课程!

二级符合性

一旦您确定了您的预期用途和设备类别,您需要指定一个认证机构(NB)。这是一个独立的外部组织,它来到你的工作场所,审查你如何制造和测试你的产品。指定机构的原因是,欧盟委员会没有时间或资源自己完成这项工作(并且不信任您自己完成这项工作,除非您的设备属于 I 类),因此他们转而依赖第三方,而第三方又受当地政府机构的监管。例如,在英国,负责监管医疗器械法规的政府机构是执行 MDR 的药品和医疗保健产品监管局(MHRA)。他们要求开发人员使用经批准的 NB,以使 CE 标志有效。

对于 IIa 类医疗器械,您可以选择 NB 按照以下四种规定的合规途径之一对您进行审核:

  • 每个产品的检查和测试;
  • 生产质量保证体系的审核;
  • 最终检验和测试的审计;或者
  • 全面质量保证体系的审计。

对于 IIb 类,你需要一个 NB 来执行第四个选项,前三个中的任何一个。

在实践中,临床人工智能开发人员不会想走批量测试路线或最终检查和测试(选项 1 和 3),因为这意味着算法的每一次更新都需要经过反复的临床验证。这将是极其缓慢和昂贵的。相反,人工智能开发人员应该选择质量保证路线,因为这是一个衡量你在确保产品开发过程中严格质量保证的标准。

质量管理体系简介

质量管理体系是一系列文件和标准操作程序(sop ),详细说明贵公司的开发程序、风险管理和测试。不出所料,这听起来很无聊,但如果你想卖掉你的算法,这绝对是至关重要的。对你来说幸运的是,有一个固定的标准可以遵循,即所谓的【ISO13485:2016】。这也是治疗失眠的另一个好方法。幸运的是,即使是监管行业的人也意识到了这一点,甚至有人把它翻译成简单的英语,让它稍微容易理解一些。

ISO13485 有许多不适用于人工智能系统,如消毒、包装和环境危害,但其中许多仍然对您的 ce 标志之旅直接至关重要,并且基本上是医疗设备 CE 标志所需的唯一标准。另一方面,许多 ISO13485 已经被其他指令覆盖,如质量管理(【ISO9001】,你的组织可能已经有了)、风险管理(,同上)和信息安全管理(【ISO27001】,双重同上)。是的,几乎所有事情都有一个标准,所以不要认为你可以偷工减料!如果你的人工智能正在使用实时患者数据并以任何方式存储它,你很可能需要后者。

A typical QMS will contain all of the above… and much more! Get expert advice if you don’t know where to start!

我的建议是尽可能早地开始按照这些标准工作,因为仅仅为了进入市场而改变你的开发过程是不会成功的。审核员希望看到完整的质量管理体系,并有证据证明你在审核开始前至少已经使用了三个月。如果你有困难,你可以把一些工作外包给无数以此为生的第三方公司。

与认证机构合作,您必须通过两阶段审核才能获得 ISO13485 认证。然而,要获得 CE 标志还需要做更多的事情!

技术文件

除了通过质量管理测试之外,您还必须通过额外的审核才能获得 CE 标志。这将考虑到你的 13485 认证,但也要求你出示所谓的技术文件。该文件是一份电子或硬拷贝档案,不仅与您的 QMS 相关联,还包含几个关键因素,使您能够证明您符合 MDR 中规定的基本要求。

使用说明;如您的手册/支持材料或软件本身所示

标签;盒子和包装上的标签。这也是一个好主意,有营销文案的例子,所以你知道你的营销将是光明正大的。

设计规范,如可接受的功能和为确保设备按预期工作而采取的措施。

系统架构;这是设计档案的形式。

符合性声明;公司负责人签署的声明,基本上说一切都符合要求。

最后…

临床评估报告(CER)

到目前为止,你们当中精明的(并且仍然清醒的)人会注意到还没有提到临床表现数据。你以为你逃脱了,是吗?嗯,抱歉,你还需要通过进行临床研究来证明你的人工智能有效。

CER 是您的设备在开发、上市前测试和上市后性能期间进行的所有临床测试的档案。

你不需要证明你的设备 100%准确地工作——在医学中没有什么是需要证明的。相反,你必须证明你已经按照你的预期用途在正确的临床环境下对你的设备进行了适当的测试,并且可以用证据支持任何准确性的声明。例如,市场上的化疗药物只能治愈 5%的患者。这很好,只要这是在临床试验中证明的,并在任何标签或营销中明确说明。必须明确风险/效益比率,该比率在很大程度上取决于正在接受治疗/诊断的疾病的严重程度以及任何临床研究的结果。

您的 CER 将包括四个关键部分:

  1. 文献综述—您需要确定您的设备的最先进水平,任何同等设备的性能和安全指标,并对您的设备的潜在优势和风险有一个关键的了解。
  2. 临床研究计划——这是一份正式的研究大纲,通常由独立的研究伦理委员会(REC)批准,该委员会既遵守良好临床实践(GCP)原则,也遵守 ISO 14155 标准。是的,另一个 ISO 标准供你阅读和入睡!
  3. 临床调查结果和分析——包括阳性和阴性结果。这通常是以可发表论文的形式,但你不一定需要在杂志上发表结果,只需准备好供专家分析。如果你不确定要运行什么样的统计分析,我会在这里支持你——或者你可以从 FDA 查看一些好的建议。
  4. 最终报告——总结文献综述的风险和益处,以及关于您的设备的临床性能及其局限性的结论。

如果你的公司缺乏临床研究的专业知识,你可以和一个被认可的学术机构,合同研究组织(CRO)合作,或者在内部雇佣相关的专家。在大多数情况下,认证机构希望看到真实世界的证据(RWE),因此这意味着您需要对真实的临床数据或患者进行试验,因此在这方面,拥有良好的临床合作伙伴关系至关重要。也不要低估一项适当的临床研究需要多长时间——记住,大多数研究从计划到完成需要一年或更长时间!

那么是什么改变了呢?

新法规于 2017 年 5 月生效,过渡期为 3 年,这意味着对于那些希望保持合规并进入市场的人来说,最后期限是 2020 年 5 月。MDD 和 MDR 之间的主要变化如下(非详尽列表):

  • 医疗器械的定义已经扩大到包括不受 MDD 监管的非医疗和美容器械。例如吸脂设备。因此,到 2020 年 5 月,你可能会看到吸脂服务的减少…
  • 被通知机构的严格监督被通知机构更严格的审查(其影响之一是一些国家统计局最近已经放弃提供这些服务,例如 LRQA )。
  • 在新的 MDR 中,“安全”一词出现了 290 次,而 MDD 只用了 40 次。你想读什么就读什么…
  • 附录 I 基本要求现在是“一般安全和性能要求”(GSPR),它确定了组织必须针对大多数遗留设备解决并重新认证的新条件(即那些在 MDD 下具有 ce 标志的设备需要更新到新的 MDR)。
  • 根据新规定,大多数设备制造商需要更新临床数据、技术文件和标签。
  • 可植入器械和 III 类器械需要更严格的临床证据。
  • 将实施唯一设备识别(UDI ),这使得随着时间的推移跟踪设备版本变得更加容易。
  • 根据更高的风险对设备进行重新分类,这意味着许多聊天机器人将被移至 IIa 类,一些放射人工智能软件将被移至 IIb 类。
  • 确定公司内部法规遵从性的“负责人”。我和你一样惊讶地发现这在以前并不是一项要求。
  • 更加重视警戒报告、上市后临床随访(PMCF)和经前综合症收集数据。记住,CE 标志是终身的,不仅仅是圣诞节的!

唷——就是它

一旦你有了一个有效的质量管理体系,ISO 13485 认证和一份完整的临床评估报告,你就为你的最终 ce 认证审核做好了准备!

然而,它并不止于此…

一旦获得认证,您需要保持您的 ISO 认证,并定期重新审核和重新测试您的设备的性能。拥有一个良好的售后市场监督(PMS)系统将有助于你保持 CER 更新,正确使用 QMS 将确保你在事情的顶部。雇佣一个质量经理是个好主意,因为你需要有人来确保你在竞争中领先——记住——监管者可以随时来看你的文件!

如果您想在欧洲之外的其他地方推出,有一个新的流程称为医疗器械单一审核计划( MDSAP ),其中包括一个进一步的审核,让您获得澳大利亚、巴西、日本和加拿大、美国认可的质量管理体系,并很可能在不久的将来成为医疗器械的国际标准。并非所有的认证机构都有资格进行 MDSAP 审计,所以一定要先询问。

最后……进入美国市场涉及到众所周知的严格的美国食品药品监督管理局( FDA ),它有相似但稍微更严格和详细的程序要通过。但是我已经告诉你够多了,所以我现在就把它留在这里!

监管机构,上马!

如果你和我一样对人工智能在医学成像领域的未来感到兴奋,并想讨论这些想法,请联系我们。我在推特@drhughharvey

如果你喜欢这篇文章,点击推荐并分享它会很有帮助。

关于作者:

Harvey 博士是一名委员会认证的放射科医生和临床学者,在英国国民医疗服务体系和欧洲领先的癌症研究机构 ICR 接受过培训,并两次获得年度科学作家奖。他曾在 Babylon Health 工作,领导监管事务团队,在人工智能支持的分诊服务中获得了世界第一的 CE 标记,现在是顾问放射科医生,皇家放射学家学会信息学和人工智能委员会成员,以及人工智能初创公司的临床总监,包括 Kheiron Medical。

如何让 fbprophet 在 AWS Lambda 上工作

原文:https://towardsdatascience.com/how-to-get-fbprophet-work-on-aws-lambda-c3a33a081aaf?source=collection_archive---------11-----------------------

解决 fbprophet 无服务器部署的包大小问题

Adi Goldstein / Unsplash

我假设你正在阅读这篇文章,因为你正在寻找在 AWS Lambda 上使用令人敬畏的 fbprophet(脸书开源预测)库的方法,并且你已经熟悉了完成它的各种问题。我将使用 python 3.6 示例,但是这种方法适用于其他运行时以及其他大型 ML 库。事不宜迟:

  1. 本地安装 Docker。另一种方法是运行 EC2 实例,并在实例和本地机器之间复制文件,这对我来说更复杂,也更不可靠。
  2. 使用您的代码在工作目录中的相关 lambda 映像上运行一个 shell(看一下 lambci ),它应该在 Lambda 上运行(它有 Lambda 处理程序):
docker run --rm -it -v “$PWD”:/var/task lambci/lambda:build-python3.6 bash

关于这里使用的命令的解释,请点击 Docker docs 或这里。

3.创建虚拟环境并安装相关软件包:

python3 -m venv venv
. venv/bin/activate
pip install --upgrade pip
pip install fbprophet --no-cache

4.你可以检查你的代码是否工作正常:python lambda_handler.py

5.将 venv 的大小减少到 250Mb 以下:

pip uninstall -y matplolibfind "$VIRTUAL_ENV/lib/python3.6/site-packages" -name "test" | xargs rm -rffind "$VIRTUAL_ENV/lib/python3.6/site-packages" -name "tests" | xargs rm -rfrm -rf "$VIRTUAL_ENV/lib/python3.6/site-packages/pystan/stan/src"rm -rf "$VIRTUAL_ENV/lib/python3.6/site-packages/pystan/stan/lib/stan_math/lib"echo "venv size $(du -sh $VIRTUAL_ENV | cut -f1)"

这里发生的事情是,您正在摆脱 matplotlib(如果您不需要绘图)、测试和 pystan 源代码(软件包中最重的部分)。最后一个命令显示 venv 的大小,应该低于 250Mb。

6.确保你的代码在清理后仍然工作:python lambda_handler.py

7.创建一个. zip 文件上传到 Lambda:

pushd $VIRTUAL_ENV/lib/python3.6/site-packages/zip -r -9 -q /var/task/name_of_your_zip.zip *popdzip -9r name_of_your_zip.zip name_of_your_code_folder/zip -9 name_of_your_zip.zip lambda_handler.py

8.现在您的工作目录中有了一个. zip 文件,可以用于 Lambda。你现在可以停止/退出 Docker 了——这个压缩文件仍然在你的文件夹里。

其他资源:

关于为 Lambda 准备 ML 库的精彩帖子:https://medium . com/@ Mae Bert/machine-learning-on-AWS-Lambda-5dc 57127 aee 1

为 Lambda 准备 fbprophet 的讨论:https://gist . github . com/CarstVaartjes/77 DBE 8249d 171 e 592 BD 17847 f 7009272

缩小 scipy 的大小:https://gist . github . com/wrwrwr/4a 38 a 17113 e 3845 f 3385 e 9388 effc 064

如何进入数据科学领域

原文:https://towardsdatascience.com/how-to-get-into-data-science-ca61930360c8?source=collection_archive---------9-----------------------

几个朋友发现我的故事对他们自己的求职和进入数据科学很有用。我想分享我的故事,让更多人受益。我不仅想分享我是如何在没有工作的情况下收拾行李搬到旧金山的,还想分享我对数据科学的热情,以及为什么我认为这是目前最好的技术领域。

关于我自己的一点点。2017 年 4 月,我决定搬到旧金山,没有工作,但有几个面试在排队。这就是旧金山湾区的伟大之处——你周围的每个人都愿意提供帮助,也更愿意了解你的故事。你只需要问:)我在 Fit 3D 公司担任数据科学家,这是一家专注于健身和健康的 3D 人体扫描公司。找工作并不容易——我使用了所有的在线门户网站(Angellist、Linkedin、Kaggle 等。)终于收到 Fit3D 的 offer 了。

我的工作:你有多胖?

自从加入 Fit3D 以来,我已经参与了各种项目,包括使用人体测量数据预测身体脂肪成分,使用图像分类验证扫描,以及使用机器学习来建立可被消费者用作产品的预测模型。使用回归和统计概念,我们能够建立一种算法,该算法随着时间的推移不断改进,为用户提供最准确的体脂值。事实上,我开发的一个功能最终被现实世界中的客户所使用,这是所有这些中最有价值的部分。

Check out Fit3D: https://www.fit3d.com/solutions/

Complete blog post: http://hd2i.org/blog/2018/03/07/fit3d-training-set-update.html

上图显示了随着 Fit3D 积累了更多的身体数据,增加了我们的数据集,以及我对身体脂肪算法进行了改进,RMSE(均方根误差)随着时间的推移而减少。较低的 RMSE 意味着残差中的误差幅度较低(与样本均值的偏差,例如:DEXA 机器上的观察值)。

数据科学增长

最棒的是,数据科学行业一直在快速发展,这使得找到更多与你的特定技术经验相关的职位变得很容易。数据科学行业的增长是有意义的。所有其他行业和公司都可以从使用数据进行数据分析和预测中受益。Fit3D 使用数据为人体提供测量/健身解决方案,谷歌和苹果都在其所有产品中使用机器学习来改善人工智能功能、客户参与、语音识别和计算机视觉,航空公司使用客户数据来波动机票价格。

狩猎

Percentage growth per year in DS jobs

到了找工作的时候,我在研究生院的研究工作中是一名兼职数据科学家,但缺乏成为全职数据科学家的专业技能。在电气工程项目期间,我很幸运地被拉进了数据科学和机器学习项目。在哥伦比亚大学的两年里,电气工程是我的必修课,但机器学习是我的主要关注和兴趣。毕业后,我决定花几个月的时间,通过 Udemy(我强烈推荐任何在特定领域寻找工作的人)等在线资源上的编程课程,严格学习机器学习,同时练习我的编程技能。从我的经验来看,数据科学领域有三个关键领域(高度重叠)——分析、机器学习和编程,你越早决定要从事哪一个或两者的结合,找工作就越容易。成功找工作的关键是找到合适的机会,帮助你最好地利用技能,只有首先选择你想要学习的技能,你才能做到这一点。这一点非常重要,因为这将是你在工作中大部分时间要做的事情。

无论你属于光谱的哪个领域,R/Python 库如 caret 和 scikit-learn 都是最好的开始方式,机器学习概述(不是很必要),基本(必要)和高级统计概念很重要。计算机科学中级和高级基础更多的是软件开发的角色。挑选数据集和从事预测/分析项目是练习这些技能的最佳方式。我建议使用 hackhive,这是一个非常容易使用的在线平台,可以向招聘人员展示你的项目(下面是我的项目的链接),在这里你还可以与具有相似技能和兴趣的开发人员联系。如果你没有技术背景,也没有研究生学位,投资一个新兵训练营是个不错的主意。有一些非常有竞争力的训练营有奖学金,可以让你免费参加训练营,比如数据孵化器。我进入了数据孵化器奖学金的最后一轮,如果我能走到那一步,你也能。

Hackhive Profile and Projects UI

带有机器学习的 R 和 Python 课程是最便宜的,而且在 Udemy 上非常有吸引力。任何关于统计学的书都可以。通常,Hastie 的《统计学习元素》是很好地介绍统计学和机器学习背后的数学的最佳书籍。如果你觉得你已经很好地掌握了上面的概念和技巧,在线博客和关于面试的一般文章也非常有用。为了提高你的编程技能,破解编码面试是你最好的选择。你可以通过谷歌找到很多其他资源,但我提到的是我用过的。

数据真的让我兴奋,因为它真的是现在和未来。通过一个简单的散点图和几个字节的数据,你可以了解任何主题或行业的很多信息。我能够从 lending club 快速积累一个数据集,其中包含客户银行贷款和违约率的信息,并建立一个客户贷款违约分类器。一旦你真正开始详细探索一个主题,它会变得非常复杂和有趣,这就是数据科学的全部乐趣。

hack hive:https://www.thehackhive.com/profile/kobe2792

LinkedIn(随意伸手):【https://www.linkedin.com/in/rikinmathur/T2

Instagram(关注我,因为我想多去旅行):【instagram.com/rikinmathur

如何在你的博客上获得更多赞(1/2)

原文:https://towardsdatascience.com/how-to-get-more-likes-on-your-blogs-1-2-f5a564c29d27?source=collection_archive---------5-----------------------

使用数据分析揭开媒体博客上掌声的神秘面纱

作为一个业余博主,我总是想知道是什么让一个好的博客变得“好”。重要的是内容,还是我们也必须关注其他方面?为了解开这个谜,我使用了我能想到的唯一工具——数据!

这是我和 Neerja Doshi 写的两篇博客中的第一篇,旨在了解影响媒体博客点赞/鼓掌的因素。第一部分包括网页抓取、特征提取和探索性数据分析。在的第二篇博客中,我们将应用包括一些机器学习算法在内的数据科学技术来确定特征的重要性,并有望尝试预测掌声。

免责声明:本博客的目的是出于好奇,应用数据科学获得有用的见解。我们绝不是在贬低博客实际内容的重要性。这是也将永远是决定一个博客质量的最重要的因素。此外,“鼓掌”是决定一个博客的有用性或质量的指标之一。还可以有其他指标,如“浏览量”。然而,我们只用“拍手”作为指标。

方法

我们用 python 构建了一个 web-scraper(谢谢,美丽的汤&硒!)获得了大约 600 篇博文。为了保持一致性,我们只抓取与数据科学和人工智能相关的博客。我不打算在这里写 python 脚本(我们谦卑地试图保持博客的整洁)。但是特别好奇的人可以去这个 GitHub 链接上找到它。

Raw Data Scrapped from Blogs

特征工程

***#Title***
from nltk.sentiment.vader import SentimentIntensityAnalyzer
sid = SentimentIntensityAnalyzer()data = pd.DataFrame()
for i in range(data_scrapped.shape[0]):
    data.loc[i, "title_length"] = len(data_scrapped.loc[i, "title"])
    data.loc[i, "title_emot_quotient"] =  abs(sid.polarity_scores(data_scrapped.loc[i, "title"])['compound'])***#Body***data.loc[i, "ct_image"] = len(data_scrapped.loc[i, "images"])
    text =  " ".join(data_scrapped.loc[i, "para"] +      data_scrapped.loc[i, "bullets"]).split()
    data.loc[i, "ct_words"] = len(text)
    data.loc[i,'read_time'] = int(data_scrapped.loc[i,'read_time'])***#Additional***
    data.loc[i, "days_passed"] = (datetime.now() -     data_scrapped.loc[i,'datePublished'] ).days
    data.loc[i, "featured_in_tds"] = 'Towards Data Science' in data_scrapped.loc[i,'tags']
   data.loc[i, "ct_tags"] = len(data_scrapped.loc[i, "tags"]

数据汇总

形象化

Scatter plot of Claps vs Features

片段与特征的相关图

Correlation Plot

最常用的词语

from wordcloud import WordCloud, STOPWORDS
from nltk.corpus import stopwords
stop = STOPWORDS.union(set(stopwords.words('english')))
wordcloud = WordCloud(relative_scaling = 1.0, stopwords = stop, width=1500, height=800).generate(text)
plt.figure(figsize=(18, 16))
plt.imshow(wordcloud)
plt.axis("off")
plt.show()

一些有趣的观察

  1. 与中值相比,鼓掌次数的平均值要高得多。这表明,大多数博客获得的掌声数量较低,并且分布向右倾斜
  2. 大多数标题在情感商数方面是中性的,在掌声和标题的情感内容值之间没有明显的趋势
  3. 阅读时间、字数和图片数量与鼓掌次数正相关,这是我们通常所期望的(越长的博客获得越多的喜欢)。此外,words_count/img_count 具有负相关性,因为图像比文本更能吸引注意力。
  4. 从上面的图表可以清楚地看出,标签数量越多的博客获得的掌声越多。所以下次别忘了加标签。
  5. 标题的平均长度是 6-7 个单词。然而,具有 10 个单词的标题具有最高的平均鼓掌次数(异常值被移除以创建下图)。

6.拍击次数随着天数的增加而增加,直到达到某个值。从图中可以看出,150 天后,days_passed 并不重要,因为 claps 已经饱和。

7.一个博客的平均阅读时间是 6-7 分钟。然而,长度为 11 分钟的博客拥有最高的平均鼓掌次数(异常值被删除以创建下图)。

我希望你喜欢读它!更多有趣的观察,请阅读第二篇博客。对于探索性分析,我们只使用了 600 篇博客,但是对于采用机器学习技术,我们使用了更大的数据集——4000 篇博客。让我们看看这些推论中有多少仍然成立。

第二篇博客的链接可以在这里 找到

领英:www.linkedin.com/in/alvira-swalin

资源:

  1. 网络报废的灵感来自于特伦斯·帕尔在 USF 的数据采集讲座
  2. https://stack overflow . com/questions/21006940/how-to-load-all-entries-in-a-infinite-scroll-once-to-parse-the-html-in-pytho

如何在你的博客上获得更多赞(2/2)

原文:https://towardsdatascience.com/how-to-get-more-likes-on-your-blogs-2-2-f8ef0be21771?source=collection_archive---------7-----------------------

估算你得到的掌声,数据科学的方式

想知道如何让你的故事更有趋势吗??是标题、图片、引语还是内容让你赢得更多掌声?在我和阿尔维拉·斯瓦林的这个系列中,我们试图探索一个博客的特征和它获得的点击量之间的关系。第 1 部分,讲述了特征提取和初步探索性数据分析(EDA),而在第 2 部分,我们建立模型来预测一个博客可以获得的掌声。

数据

第 1 部分中的 EDA 基于 600 个数据科学博客,但是为了进一步分析,我使用了大约 4000 个中型博客。为了内容和受众的一致性,我们从数据科学、人工智能、技术和编程类别中挑选了这些博客。我们的功能包括博客的长度,图片/文字,标签数量,标题的情感分数,博客发表以来的持续时间和追随者的数量。从初步的 EDA 中,我们可以看到 claps 与阅读时间和标签数量成正相关。更多的标签似乎能获得更多的掌声,而标题的情感似乎对掌声没有太大的影响。

方法学

为了进一步研究这个问题,我们首先尝试先将这个问题视为回归,然后再进行分类。正如所料,回归没有做得很好,因为预测和变化的范围很大。因此,我们决定对这些数据进行分类处理,并将进一步讨论这种方法。

看看我们的初步分析是否适用于更广泛的博客——

  • 3 标签分类,看看一个博客是否得到低,中或高的掌声
  • 20 标签分类获得更精细的预测

特色工程

总之,我包含了 24 个特征,包括直接提取的特征以及与内容、作者和日期相关的特征。

基于标签的预处理

拍手的范围从 1 到 62,000,标准偏差为 2.8k!这是一个很大的预测范围,所以为了处理这种变化,我们在第 90 百分位截取数据。

Before and after clipping the data

3 标签分类

为此,我根据鼓掌次数将博客分为低、中、高三个等级。

  • 低:< 150 claps → corresponds to the 45th %ile
  • Medium: 150–750 claps → corresponds to the 85th %ile
  • High: > 750 拍手

我在两种方法中尝试的分类器是逻辑回归和随机森林,因为两者都是可解释的。随机森林优于后者,因为它可以捕捉非线性和逻辑回归不能捕捉的特征之间的相互作用。

经过一些参数调整,我不会在这里深入讨论,我们得到以下结果—

我们的模型能够比类别 2 相对更准确地预测类别 0 和 1。这是由于在训练数据中跨类的观察分布的不平衡。

20 标签分类

为了将标签转换成类别,这里我根据它们的分布分类了拍手。这确保了观察值均匀地分布到所有类别中(不同于 3 标签方法),并且类别不平衡得到处理。以下是对应于箱的几个范围。

与前面的案例一样,我们使用 5 重交叉验证来调整参数,对大约 3300 个博客的训练数据建立了逻辑回归和随机森林模型。

结果和解释

我们在这里使用日志损失作为度量。该模型在预测拍手的 bin 时给出了 2.7 的对数损失。因为我们的类是连续的,所以我们也可以计算平均绝对误差。对于我们的模型,我们得到 MAE = 5.16。

多类分类的测井损失——

预测仓给了我们博客能获得的掌声范围。让我们来看看一些实际和预测的范围:

虽然有些预测(红色的)完全不准确,但也有一些预测(橙色的)实际上非常接近,但仍然被错误分类。

那么决定你的博客是否会流行的特征是什么呢?
在计算功能重要性时,我们看到的关注者数量的内容质量 t 是更多鼓掌数量的可靠指标,当然,除了博客发表后的天数。图片占博客长度的比例是另一个重要因素。

令人惊讶的是,标题的字数和阅读时间似乎不是一个非常关键的因素,这与我们在最初的 EDA 中观察到的情况相矛盾。

更进一步,让我们看几篇博客,试着解释这些因素的影响是积极的还是消极的(以及我们的预测有多接近)。

作为一个例子,我们选取了两个样本博客,分别有大约 760 和 1800 次点击。你可以在这里找到第第和第第二的博客。让我们先来看看他们的特点和预测:

第一篇博客的预测是 17 次,即 754–1000 次鼓掌(砰!)和 14 秒,即 380-490 拍。这完全超出了 1400–2000 次拍手的实际范围。

要了解为什么我们对第二篇博客的预测如此错误,让我们再来看看那篇博客。对于这个博客来说,内容为王指出了我们模式的一个缺点。我们的模型无法捕捉博客在内容和写作风格方面的吸引力。为此,需要对文章本身进行更多的分析。目前,我们只能根据粉丝数量、图片、情感、篇幅等特征来评判博客。

结束注释

其他可以在博客上完成的工作可以是—

  • 分析博客的目的——是否旨在教育、探索问题、提供问题的解决方案等
  • 计算两个博客之间的相似度,以避免重复/抄袭
  • 根据一个话题能获得多少掌声来决定它的受欢迎程度
  • 如前所述,更多的 NLP 用于确定一个博客有多受欢迎,例如,我们可以检查一个博客是否包含当前的流行语(如加密货币),它是否提供了相关主题的解决方案等。

我希望你喜欢读这篇文章!欢迎任何想法、建议或评论!

领英—https://www.linkedin.com/in/neerja-doshi/

参考

  1. 使用 Python 实现的 Github repo】
  2. 这是一个关于写好博客的非常酷的博客作者昆西·拉森!

如何开始学习 NLP

原文:https://towardsdatascience.com/how-to-get-started-in-nlp-6a62aa4eaeff?source=collection_archive---------0-----------------------

Dependency parse tree visualized by displaCy

我在某处读到过,如果你不得不回答同一个问题两次,把它变成一篇博客文章可能是个好主意。为了遵守这条规则,也为了给未来的自己节省一些时间,我现在给出了这个问题的标准答案:“我的背景是科学,我对学习 NLP 感兴趣。我从哪里开始?”

在您开始之前,请注意下面的列表实际上只是一个非常一般的起点(并且很可能是不完整的)。为了帮助浏览大量的信息,我在括号中添加了简短的描述和难度估计。建议掌握基本编程技能(例如 Python)。

在线课程

  • 丹·茹拉夫斯基&克里斯·曼宁:自然语言处理【很棒的入门视频系列】
  • Stanford CS224d:面向自然语言处理的深度学习【面向 NLP 的更高级的 ML 算法、深度学习和 NN 架构】
  • Coursera:自然语言处理简介【密歇根大学提供的自然语言处理简介课程】

图书馆和开源

  • spaCy ( 网站,博客)【Python;新兴开源库,包含奇妙的使用示例、API 文档和演示应用
  • 自然语言工具包(NLTK) ( 网站,书籍)【Python;NLP 编程实用入门,主要用于教学]
  • 斯坦福 CoreNLP ( 网站)【Java;高质量的分析工具包]
  • AllenNLP ( 网站)【Python;NLP 研究库建立在 PyTorch 之上
  • fastText ( 网站)[c++;用于文本分类和表示学习的高效库]

活跃的博客

  • 自然语言处理博客 (Hal Daumé III)
  • 语言日志(马克·利伯曼)
  • 谷歌研究博客
  • 爆炸 AI 博客
  • 抱脸
  • 塞巴斯蒂安·鲁德博客

  • 语音和语言处理 (Jurafsky 和 Martin)[涵盖所有基础知识的经典 NLP 教科书,第 3 版即将出版]
  • 统计自然语言处理基础(Manning and schütze)[更高级的统计 NLP 方法]
  • 信息检索导论 (Manning,Raghavan,schütze)[排名/搜索优秀参考]
  • 自然语言处理中的神经网络方法(gold Berg)[NN 方法深度介绍 NLP,此处引子 ]
  • 自然语言处理的语言基础(Bender)[更成功的自然语言处理的形态学和句法基础]
  • 深度学习(古德费勒、库维尔和本吉奥)[深度学习最佳入门]

多方面的

  • 如何在 TensorFlow 中构建 word2vec 模型【教程】
  • 针对自然语言处理资源的深度学习【针对深度学习的最先进资源概述,按主题组织】
  • 最后一句话:计算语言学和深度学习——看看自然语言处理的重要性。(配员)【文章】
  • 分布式表示的自然语言理解 (Cho)【关于 NLU 的 ML/NN 方法的独立讲稿】
  • 贝叶斯含泪推断(骑士)【教程练习册】
  • 计算语言学协会
  • Quora:我如何学习自然语言处理?
  • 自然语言理解和计算语义学 (Bowman)【带综合幻灯片的开源课程大纲】
  • fast.ai [“让神经网络再次变得不酷”]

DIY 项目和数据集

Source: http://gunshowcomic.com/

Nicolas Iderhoff 已经创建了一个公开可用的 NLP 数据集的完整列表。除此之外,我还可以向任何想要尝试的 NLP 新手推荐一些项目:

  • 基于隐马尔可夫模型 (HMM)实现词性标注器
  • 实现 CYK 算法来解析上下文无关文法
  • 实现文本集合中两个给定单词之间的语义相似度,例如点态互信息 (PMI)
  • 实现一个朴素贝叶斯分类器来过滤垃圾邮件
  • 基于单词间的编辑距离实现一个拼写检查器
  • 实现一个马尔可夫链文本生成器
  • 使用潜在狄利克雷分配 (LDA)实现一个主题模型
  • 使用 word2vec 从大型文本语料库中生成单词嵌入,例如维基百科
  • 使用 k-means 聚类 tf-idf 文本向量,例如新闻文章
  • 实现一个命名实体识别器 (NER)(也称为名称标记器),例如遵循 CoNLL-2003 共享任务

社交媒体上的 NLP

  • 推特: #nlproc ,nl pers 名单(作者杰森·鲍德里奇)
  • Reddit:/r/language technology
  • 中: Nlp

在推特上联系我@ melto mene

如何入门 Kaggle 竞赛和数据科学?或者“如何在没有机器学习或统计的情况下获得一个像样的分数”

原文:https://towardsdatascience.com/how-to-get-started-with-kaggle-competitions-and-datascience-26d27108a444?source=collection_archive---------7-----------------------

这是一个面向初学数据科学和机器学习的程序员(比如我自己)的入门教程。它向人们介绍了 Kaggle 竞赛、Python 中的 Jupyter 笔记本,以及 Pandas 和 NumPy 库。

我展示了在没有任何统计、数据科学或机器学习的情况下,我们如何能够在 Kaggle 的泰坦尼克号竞赛排行榜上名列前三。

0.先决条件— Anaconda、Jupyter 笔记本

我们需要一些编程的基础知识(变量,基本的 Python 语法)。安装您需要的东西的最简单方法是前往 Anaconda 并下载 Python 3.7 GUI 安装包。它将自动安装最常用的库,包括下面我们正在使用的库。

一旦安装了 Anaconda,启动“Anaconda Navigator”启动程序,然后从它启动“Jupyter Notebook”。或者,从命令行输入“ jupyter 笔记本”。

这将打开一个 web 界面,您可以在其中浏览、打开和创建新的“笔记本”(一种 Python 程序,让您以交互方式编写和运行代码、编辑文本和绘制图像,大多数从事数据科学和机器学习的人都在使用它)。本教程就是在这样的笔记本上写的。你可以在我的 GitHub 库上查看完整的笔记本并下载以运行它。

在 Jupyter 笔记本中,您可以编辑单元格,通常是代码或降价。

有许多可用的快捷键,您可以在帮助->键盘快捷键菜单中查看,或者在不编辑单元格时按“h”键查看。

您可以通过按下 Ctrl+Enter 来执行代码单元格内的代码(或者格式化一个 markdown 单元格)。您执行代码并通过按下 Shift+Enter 自动前进到下一个代码。

单击单元格的侧面将其选中,单击其内容或双击单元格开始编辑。按 Escape 键退出编辑模式。

1.首先,参加一个 Kaggle 比赛。

在全球最大的人工智能、机器学习和数据科学在线社区 Kaggle 上创建一个用户账户。

Kaggle 泰坦尼克号幸存者比赛是任何 Kaggle 新人都应该开始的比赛,因为它总是开放的(排行榜定期清理),简单易懂。

从列出泰坦尼克号灾难中幸存或未幸存乘客的样本训练集得知,我们的模型可以基于不包含幸存信息的给定测试数据集来确定测试数据集中的这些乘客是否幸存。

在你参加比赛之后,去数据区,点击“下载全部”,然后将下载的档案文件解压到你想要编写 Jupyter 笔记本程序的子文件夹中。

我在“ MyWork 文件夹下工作,已经将下载的测试和训练数据保存到“ titanic_data 子文件夹下。

2.导入用过的库

3.加载培训和测试数据

train_raw 和 test_raw 都是 Pandas 的“DataFrame”对象,为操作表格数据、访问任何行、列或单元格提供了有用的方法和变量。

我们通常使用语法 dataframe["ColumnName"]来访问一个列,但是偶尔,为了简洁起见,我们将使用 dataframe。请改为 ColumnName。

数据框的一个很棒的特性是我们可以对它们进行选择。例如,这是幸存的女性乘客名单:

请在竞赛数据页面上查看有关数据文件中各列含义的详细信息。

让我们看看存活率是如何与其他数据相关的:

Pandas crosstab 函数可以让您看到一个特性(列)如何与另一个相关联,它显示了一个漂亮的表格,在垂直方向上计算一个特性的值,在水平方向上计算另一个特性的值。

因为我们将熊猫作为 pd 导入(这是最常见的约定),所以我们将这样使用它:

在 Pandas 中,我们可以通过它的名称(在我们的 csv 文件中,从第一行开始读取)来寻址一个列(特性)。我们通常会说

现在,我们可以根据训练数据文件得出初步结论:

  1. 培训数据中 65%的人是男性(577 人),35%是女性(314 人)
  2. 在所有男性中,约 80%死亡(0.523 / 0.647,又名 468 / 577)
  3. 在所有妇女中,不到 26%的人死亡(81 / 314)
  4. 在所有人中,62%死亡,38%幸存(“所有”栏)

基于以上的见解,我们可以做一些琐碎的尝试来解决问题。

现在,我们前往 Kaggle 泰坦尼克号比赛页面,点击选项卡菜单上的“提交预测”按钮。将上面生成的“submission_zeros.csv”文件拖放到“上传文件”区域,然后单击“提交”按钮。

等待计算分数,然后…

我们获得了 0.72727 的准确度分数,这使我们在超过#10000 名竞争对手中排名大约#9000(在撰写本文之日,2018 年 11 月 16 日)。这意味着 1000 多人比我们错得更多——这比最微不足道的答案还要错。

4.首次提交——性别

不如说所有的男人都死了,所有的女人都活了下来?Kaggle 已经在这方面帮助了我们,他们在数据存档中提供了一个 gender_submission.csv 文件。您可以直接上传,或者我们可以在下面的单元格中自己生成一个:

我们可以测试我们的版本和从 Kaggle 得到的版本之间的差异

diff-w my _ gender _ submission . CSV gender _ submission . CSV

它们是相同的(除了空格之外,这取决于您的计算机/操作系统)。

将新文件上传到 Kaggle 并测试其得分,我们的得分为 0.76555,在 10000 多名竞争者中排名第 6300 位。

换句话说,近 4000 人(40%)除了上传他们从 Kaggle 得到的默认答案之外,并没有做得更好。

我们的基础教程大概可以到此为止,因为它已经达到了目的,向你展示了很多有用的东西:

  • 如何参加 Kaggle 比赛
  • 如何开始写代码给竞赛一个答案
  • 如何在 csv 文件中加载数据
  • 如何看数据的前 5 行(表头法)
  • 如何使用交叉表命令查看一个要素与另一个要素的关系
  • 如何为解决方案创建新的数据框架并将其保存到 csv 文件中
  • 如何向 Kaggle 提交您的解决方案文件并了解您的分数

但是,我们的无编码“性别解决方案将我们置于最后 40%。我很好奇,用很少的编码或知识,我们是否能在排行榜上爬得更高一点。我们可能需要使用 pandas/numpy 库中的一些方法。

5.调整性别解决方案

我们已经达到了一个合理的分数,声称所有的男性都死了,所有的女性都活了下来。这显然不是 100%的真实。让我们看看是否能找到一些其他可以帮助我们取得更好成绩的唾手可得的果实。

我们可能看过电影,当一艘船正在下沉时,妇女和儿童通常被首先放在船上。

我将添加一个新列,说明乘客是妇女还是儿童(10 岁以下),并将其命名为“MightSurvive”(也用于其他生存标准)

那么,这与我们声称只有女性幸存的时候相比如何呢?

在加载训练数据后生成的交叉表中,我们注意到,当我们说只有女性幸存而所有男性都死了时,在总共 891 次中,我们对了 233 次(女性实际幸存)+ 468 次(男性实际死亡)。这大约是正确的 78.6 倍。

在我们目前的情况下,如果我们说只有妇女或儿童幸存,891 次中我们有 252 + 455 次是正确的。这大约是 79.3% —一个小而显著的进步。

现在让我们将这个解决方案上传到 Kaggle,看看它的得分如何。

Kaggle 给了我们 0.77033 的分数,这是相当大的成就。在#10100 排行榜中,我们已经上升到了第 5500 名左右,位列前 55%。

如果“有钱人活下来了”呢?

在同一部《泰坦尼克号》电影中,看起来富人通常能活下来(凯特),而穷人却不能。让我们使用现有的工具来检查这些假设。

乘客财富与乘客等级相关(一等比三等好)。让我们用生存来交叉分析乘客等级。

基于此,说只有 1 班的人活了下来,其他人都死了,那就对了 891 次中的 136 次(实际 1 班幸存者)+ 469 次(2 班实际非幸存者 97 次+ 3 班实际非幸存者 372 次)。这仅仅是 67%倍,比上面的估计还要差。

所以,现在我们可能不应该关注人工尝试的乘客等级,忽略这个假设。

6.大家庭里的小孩子怎么办?

这可能是轶事,但我可以想象贫穷移民的大家庭努力聚集所有留下的人,因此无法到达救援船。也许他们的父母幸存了下来,但大多数孩子没有。这可能不是一个普遍的事实,但在这种情况下,一些家庭可能会帮助我们获得更好的分数。因此,我想验证大家庭成员更容易死亡的假设。

SibSp(兄弟姐妹和配偶)和 Parch(父母和子女)列包含这些信息。交叉表显示,对于大量同胞来说,它确实与无存活率相关。

我们发现至少有 4 个兄弟姐妹的孩子存活的可能性更小(30 个孩子中只有 3 个存活)。

同样,至少有 4 个孩子的父母不太可能存活(只有十分之一存活)。

让我们将上述见解添加到我们的可能幸存标准中(到目前为止,该标准仅适用于妇女和儿童)

交叉表显示,我们的“可能幸存于”标准将是正确的(248 + 480)/891 = 81.7%倍。这明显比以前好,比性别解决方案提高了近 3%。

7.构建我们的解决方案并将其发送给 Kaggle

现在我们正在谈话!我们从 Kaggle 得到的分数是 0.78468,明显比以前好。

这使我们在排行榜上排名第 3200 位左右——我们现在排名前 32%,没有使用机器学习或统计数据。

我们的教程到此结束。分数的进一步提高和洞察力的提高可能需要统计、可视化和机器学习。但是今天我们已经做得足够好了。

恭喜你!

如何通过 5 个步骤开始使用指标

原文:https://towardsdatascience.com/how-to-get-started-with-metrics-in-5-steps-7de6d496bc71?source=collection_archive---------5-----------------------

所以,你决定使用 KPI 和指标,用数据来发展你的创业公司。恭喜你!您将获得奖励!现在,艰难的工作从实际决定什么指标重要和创建数据驱动的文化开始。那么你从哪里开始呢?启动行动是来帮忙的。在本指南中,你会找到几个步骤,让你朝着正确的方向前进:

1。定义你的战略目标

因为你想为你的事业做每一件事,所以在有限的几个目标上做出决定可能是困难的。但是这确实是您需要开始的地方,因为您的度量应该是您的战略目标的延伸。与几个关键绩效指标相关联的几个目标将帮助您专注于重要的事情。

一旦你做出决定,将它们分成财务目标客户价值目标

让我们从财务开始考虑,这显然是最简单的。我假设你正在经营一家初创公司,这意味着你正在经营一个从零开始的组织,然后你的财务目标可能是在不消耗太多现金的情况下实现收入最大化。更多的钱进来,更少的钱出去!另一方面,如果你在经营一个更成熟的组织,你的目标可能是达到或增加盈利能力。如果你还没有开始赚钱,你的财务目标可能是未来与你的收入流紧密相连的东西,比如在保持低成本的同时最大化活跃用户的数量。

如果你经营订阅业务,你的目标可能是月经常性收入 (MRR)。然而,对于一个市场,你可能会关注商品总值 (GMV)。

现在你可以明白为什么尽早确定你的目标很重要了!

设定客户价值目标更加棘手。简单来说,把它们想象成你公司的愿景或使命。它可能是你如何帮助你的客户,解决问题,或者为他们创造价值。设定一个目标,如果达到这个目标,将保证客户需要你的产品,为你的企业创造长期稳定。例如,如果你提供一个 B2C 预算节省应用程序,你的目标可能是帮助你的用户节省更多的钱。尽量保持低数量的客户价值目标——两个是一个好数字,如果你是一家早期创业公司,不要超过三个。俗话说,不会走路就不要试着跑!

为了决定你的目标,确保你和你的核心团队(创始/执行团队和/或董事会)坐下来好好谈谈。如果你的目标被具体地写了下来,你们很有可能达成一致。这对于实现长期目标至关重要,因为整个团队需要朝着同一个方向努力。不要犹豫改变或更新你的目标,因为你可能会学到关于你的市场的新东西,并在你业务的不同生命周期阶段之间移动。适应性是关键。

The whole team needs to push in the same direction

2。使其可测量

你的下一个挑战是将你的目标转化为可衡量的 KPI。这些将是 2-3 个指标,推动你的企业朝着你的目标前进。通过这样做,你将能够具体地定义你的目标是什么,以及你每天都在努力提高什么样的绩效。让你的目标变得可衡量会让你更容易监控你的创业是否越来越接近你的目标。为了进一步分析你的 KPI,你需要将它们分解成更小的部分,也称为指标,这将使你更清楚地了解哪些杠杆可以提高你的 KPI。

例如,如果你设定了 MRR、GMV 或 MAU,财务目标几乎不需要转化为 KPI。因此,让我们深入探讨如何分解它。你如何做到这一点完全取决于你的商业模式,但你需要做的是把你的收入一点一点分开。例如,如果你是一家 SaaS 公司,向你的客户收取月订阅费,你的第一层指标将是付费客户的数量和月费用。看一看:

客户数量 *** 月费=MRR(月经常性收入)

你的下一层指标将是新的、保留的和流失的客户。我们是这样计算的:

新增 + 留存—流失 = 客户数量。

这种细分可以一直进行到你的漏斗的开始,网站访问者转化为试用用户,试用用户转化为新的付费客户。

要查看一个虚构的 SaaS 企业的示例,您可以查看下面链接的指标树。在不同的列中,您可以看到绝对数量、客户总数的百分比以及与前一个月相比的变化。通过做这个练习,团队可以很好地理解你的收入是如何形成的,以及所有的数字是如何与你的月绩效联系起来的。理解这些数据将使原始数据转化为结果变得更加容易。要阅读度量树的详细分解,请查看这篇文章

为了控制成本和优化利润,您还可以增加收入成本比。这意味着你要从普通客户那里获得净收入,换句话说,就是你的客户终身价值** (LTV),然后把它除以你的不同成本组。例如,如果你为客户获取付费,你应该计算你的客户获取成本 (CAC)。然后你计算 LTV/CAC,得到一个比率,帮助你控制最重要的可变成本。该比率应该优选至少为 3 或 4。如果更低,通常意味着你还没有以最具成本效益的方式接近你的客户,或者你的客户没有被产品吸引,因此离开(流失)。**

要分解客户价值目标,你的挑战将是具体定义它们是什么。它需要一些创造力来得出比率和百分比,这将有助于你确定你是否实现了你的客户价值目标。

让我们再来看看预算节省应用程序的例子。他们的目标是帮助用户省钱。这个目标可以转化为一个 KPI,其形式为用户在第三个月与第一个月相比节省的量的比值。如果这个比例很高,证明这个 app 帮用户省了更多的钱。

为了分解这个 KPI,你可以看看有多少第一次下载应用程序的用户回来使用它(保留)以及使用频率。这两个指标可以作为您可以优化的指标,以帮助您将 KPI 推向正确的方向。

当你在创业时,你的团队会不断地添加新功能,纠正产品中的错误。这意味着,根据用户到达的时间,他们可能会看到不同的产品。此外,这意味着通过根据用户行为指标到达的时间对它们进行分组来研究它们是值得的。这是通过群组完成的,如下图所示。

您希望从群组表中看到的是,每一组新客户都比前一组客户表现得更好。例如,如果在第一周下载你的应用的客户的三周保留率是 29 %,你希望在第二周加入的客户的三周保留率更高。所以在上图中,你会希望数字沿着箭头的方向增加。

当看到你的指标与前一个月的差异时,奇迹真的会发生。然后,您可以将您的指标与您在一个月中采取的不同行动联系起来,看看这些行动对您的成长有何直接影响。反过来,这将启动你的反馈循环,你的结果将有助于你计划下个月的行动。一般来说,这都是为了进入你的客户的头脑,看看你的行动如何影响他们的决策和行为。不要害怕利用自己作为消费者的经验!

3。可视化

你一天刷两次牙,一周锻炼三次,每天吃 500 克青菜。跟踪您的指标也应该是一个健康的习惯,以保持对您公司健康状况的掌控。你不想花时间更新仪表板,所以投资于自动化仪表板,因为这样你就可以始终确保完成。

你可以在我的关于创业仪表板的文章中了解不同的仪表板软件。我想在这里提一个,那就是克利普弗利奥。他们提供了一个非常灵活和强大的工具,但引导友好的定价。

在您的仪表板中,您应该从两个角度显示您的 KPI 和指标:

  1. 每月或每周概览,您可以在其中查看历史发展。
  2. 滚动总数或平均值。例如,过去 7 天与之前 7 天的对比,或过去 30 天与之前 30 天的对比。这是为了让你对你的行动获得快速反馈——你不应该等到月底才衡量你行动的效果。

仪表板应该总是告诉你一个不需要任何人解释的故事,这意味着它需要简单明了。看到仪表板的人应该想,“哦,我看到我们添加的新功能对参与度有非常积极的影响,但它没有帮助我们降低流失率。嗯,我想知道我们还能做些什么来减少客户流失?”

要实现这一点,请使用条件格式来自动标记某些内容是否有所改进、减少或保持不变。你可以使用颜色,像箭头一样的符号,或者简短的单词。让它充满活力,但保持简单。

4。问为什么

你会意识到,可视化你的创业公司的表现的仪表板将回答很多问题,但它也会让你提出新的问题。这正是你想去的地方。

我建议你每周召开团队会议,检查你的表现和仪表盘。在这些会议中,每个团队成员都应负责展示他们的图表,并解释他们增加或减少的原因。这件事我怎么强调都不为过——无论何时你讨论你的仪表盘,都应该是关于为什么,为什么,为什么(你好,两岁的孩子!).这个想法是,你的仪表板将是你的公司健康状况的截图,这需要通过对业绩具体变化之外的原因进行更深入的特别分析来跟进。

当你知道你的表现是什么以及你为什么会有这样的表现时,你将学会什么样的行动是有效的,以及如何使用有效的杠杆。你将能控制自己的表现,并能实现快速增长。

5。教育

在您的组织中工作的每个人都应该了解您的仪表板中的 KPI 和指标的作用。你们都应该知道他们为什么在那里,以及他们如何提高你的创业公司的业绩。与每一位新员工坐下来,就如何使用该系统对他们进行培训,这应该是一个优先事项。为了简化这一部分,一起写一个文档,解释你所有的 KPI、指标和图表,这样你就有了一个参考。

最后,你的努力应该会导致一个创新和可持续发展的公司,在那里员工可以被激励,并更好地了解公司的立场。这使得团队成员更容易采取主动,更快地做出决策,而没有沉重的官僚作风。

如何开始使用 PySpark

原文:https://towardsdatascience.com/how-to-get-started-with-pyspark-1adc142456ec?source=collection_archive---------1-----------------------

PySpark 是使用 Spark 的 Python API,Spark 是运行大数据应用的并行分布式引擎。开始使用 PySpark 花了我几个小时——这是不应该的——因为我必须阅读大量的博客/文档来调试一些设置问题。这个博客旨在帮助您尽快开始使用 PySpark!

更新:我写了一篇关于 PySpark 以及如何使用一些托管服务(如 Databricks 和 EMR)和一些常见架构开始使用 Spark 的新博文。片名为 从熊猫到星火。有兴趣了解更多就去看看吧!

How do we analyze all the “big data” around us?

这些步骤适用于 Mac OS X(我运行的是 OS X 10.13 High Sierra)和 Python 3.6。

1.开始新的康达环境

你可以安装 Anaconda ,如果你已经有了它,使用conda create -n pyspark_env python=3启动一个新的conda环境。这将创建一个新的 conda 环境,使用最新版本的 Python 3,供我们尝试我们的 mini-PySpark 项目。
source activate pyspark_env激活环境

2.安装 PySpark 包

你可以尝试使用pip来安装pyspark,但是我无法让pyspark集群正常启动。看了几个关于堆栈溢出的答案和官方文档,我发现了这个:

Spark 的 Python 打包并不打算取代所有其他用例。Spark 的 Python 打包版本适合与现有集群(无论是 Spark standalone、YARN 还是 Mesos)进行交互,但不包含设置您自己的独立 Spark 集群所需的工具。你可以从 Apache Spark 下载页面下载 Spark 的完整版本。

使用上面的链接,我继续下载了[spark-2.3.0-bin-hadoop2.7.tgz](https://www.apache.org/dyn/closer.lua/spark/spark-2.3.0/spark-2.3.0-bin-hadoop2.7.tgz),并将解压后的版本存储在我的主目录中。

3.安装 Java 8

一些说明建议使用 Java 8 或更高版本,我继续安装了 Java 10。当我试图在我的 Spark 集群中运行collect()count()时,这实际上导致了如下几个错误:

py4j.protocol.Py4JJavaError: An error occurred while calling z:org.apache.spark.api.python.PythonRDD.collectAndServe.: java.lang.IllegalArgumentException

我最初的猜测是,它必须与Py4J安装做一些事情,我试图重新安装了几次,没有任何帮助。没有多少人谈论这个错误,在阅读了几篇堆栈溢出的帖子后,我看到了这篇帖子,它讨论了 Spark 2.2.1 如何与 Java 9 及更高版本发生问题。推荐的解决方案是安装 Java 8。

所以,安装 Java 8 JDK,进入下一步。

4.“改变”。“bash_profile”变量设置

为了告诉 bash 如何找到 Spark 包和 Java SDK,在您的.bash_profile中添加以下几行(如果您使用 vim,您可以做vim ~/.bash_profile来编辑这个文件)

export JAVA_HOME=$(/usr/libexec/java_home)
export SPARK_HOME=~/spark-2.3.0-bin-hadoop2.7
export PATH=$SPARK_HOME/bin:$PATH
export PYSPARK_PYTHON=python3

这些命令告诉 bash 如何使用最近安装的 Java 和 Spark 包。运行source ~/.bash_profile获取该文件或打开新终端自动获取该文件。

5.启动 PySpark

运行pyspark命令,您将会看到:

PySpark welcome message on running pyspark

您可以使用命令行来运行 Spark 命令,但是这不是很方便。可以使用pip install jupyter notebook安装 jupyter 笔记本,运行jupyter notebook时可以访问笔记本中的 Spark 集群。您也可以使用vimnano或您选择的任何其他代码编辑器将代码写入 python 文件,您可以从命令行运行这些文件。

6.用 PySpark 计算圆周率!

运行一个小而快速的程序来估算pi的值,看看你的火花簇在起作用!

import random
NUM_SAMPLES = 100000000
def inside(p):
 x, y = random.random(), random.random()
 return x*x + y*y < 1count = sc.parallelize(range(0, NUM_SAMPLES)).filter(inside).count()
pi = 4 * count / NUM_SAMPLES
print(“Pi is roughly”, pi)

7。接下来的步骤

PySpark 中有很多东西可以探索,例如弹性分布式数据集或 rdd(更新:现在 DataFrame API 是使用 Spark 的最佳方式,rdd 谈论“如何”完成任务,而数据帧谈论“什么”——这使得数据帧更快和优化)和 MLlib 。

2021 年 6 月更新:我写了一篇关于 PySpark 以及如何开始使用 Spark 的一些托管服务(如 Databricks 和 EMR)和一些常见架构的新博客。它的名字叫 从熊猫到星火。有兴趣了解更多就去看看吧!感谢您的阅读。

如何开始使用 word 2 vec——然后如何让它工作

原文:https://towardsdatascience.com/how-to-get-started-with-word2vec-and-then-how-to-make-it-work-d0a2fca9dad3?source=collection_archive---------4-----------------------

一个 Gensim Word2Vec 教程

Photo by Hugo Ruiz on Unsplash

Word2Vec 背后的想法非常简单。我们假设一个词的意思可以通过它所结交的朋友来推断。这类似于一句谚语,“让我看看你的朋友,我就知道你是谁”。”

如果你有两个单词有非常相似的邻居(意思是:使用它的上下文大致相同),那么这些单词可能在意思上非常相似,或者至少是相关的。例如,单词震惊惊骇、惊讶通常用在类似的上下文中。

使用这个基本的假设,您可以使用 Word2Vec 来表现相似的概念,找到不相关的概念,计算两个单词之间的相似性,等等!

谈正事

在本教程中,您将学习如何使用 Word2Vec 的 Gensim 实现,并实际使用它。我早就听到了关于总体性能不佳的抱怨,但这真的是两件事的结合: (1)您的输入数据(2)您的参数设置

请注意,Gensim 包中的训练算法实际上是由 Google 从最初的 Word2Vec 实现移植而来的,并扩展了附加功能。

导入和日志记录

首先,我们从导入开始,并建立日志记录:

# imports needed and logging
import gzip
import gensim 
import logginglogging.basicConfig(format=’%(asctime)s : %(levelname)s : %(message)s’, level=logging.INFO) 

资料组

我们的下一个任务是找到一个真正好的数据集。让 Word2Vec 真正为您工作的秘密是在相关领域拥有大量的文本数据。例如,如果你的目标是建立一个情感词典,那么使用来自医学领域甚至维基百科的数据集可能不是有效的。所以,明智地选择你的数据集。

在本教程中,我将使用来自我的一些博士论文的 OpinRank 数据集的数据。该数据集包含汽车和酒店的完整用户评论。我特意将所有的酒店评论收集到一个大文件中,压缩后大约 97 MB,解压缩后大约 229 MB。在本教程中,我们将使用压缩文件。该文件中的每一行都代表一篇酒店评论。

现在,让我们通过打印第一行来仔细看看下面的数据。

Printing the OpinRank Word2Vec dataset

您应该看到以下内容:

b"Oct 12 2009 \tNice trendy hotel location not too bad.\tI stayed in this hotel for one night. As this is a fairly new place some of the taxi drivers did not know where it was and/or did not want to drive there. Once I have eventually arrived at the hotel, I was very pleasantly surprised with the decor of the lobby/ground floor area. It was very stylish and modern. I found the reception's staff geeting me with 'Aloha' a bit out of place, but I guess they are briefed to say that to keep up the coroporate image.As I have a Starwood Preferred Guest member, I was given a small gift upon-check in. It was only a couple of fridge magnets in a gift box, but nevertheless a nice gesture.My room was nice and roomy, there are tea and coffee facilities in each room and you get two complimentary bottles of water plus some toiletries by 'bliss'.The location is not great. It is at the last metro stop and you then need to take a taxi, but if you are not planning on going to see the historic sites in Beijing, then you will be ok.I chose to have some breakfast in the hotel, which was really tasty and there was a good selection of dishes. There are a couple of computers to use in the communal area, as well as a pool table. There is also a small swimming pool and a gym area.I would definitely stay in this hotel again, but only if I did not plan to travel to central Beijing, as it can take a long time. The location is ok if you plan to do a lot of shopping, as there is a big shopping centre just few minutes away from the hotel and there are plenty of eating options around, including restaurants that serve a dog meat!\t\r\n"

你可以看到这是一篇很好的、有很多单词的全面综述,这正是我们想要的。在这个数据集中,我们有大约 255,000 个这样的评论。

为了避免混淆,Gensim 的 Word2Vec 教程说,您需要将一系列句子作为输入传递给 Word2Vec。然而,如果你有大量的数据,你实际上可以将整个评论作为一个句子(也就是说,一个大得多的文本)来传递,并且它不会产生太大的差异。最后,我们使用数据集的目的是获取给定目标词的所有相邻词。

将文件读入列表

现在我们已经有了数据集的一个峰值,我们可以将它读入一个列表,这样我们就可以将它传递给 Word2Vec 模型。请注意,在下面的代码中,我直接读取了压缩文件。我还使用gensim.utils.simple_preprocess (line)对评论进行了温和的预处理。这将进行一些基本的预处理,如标记化、小写等,并返回一个标记(单词)列表。该预处理方法的文档可在官方 Gensim 文档网站上找到。

read user reviews into a list

训练 Word2Vec 模型

训练模型相当简单。您只需实例化 Word2Vec 并传递我们在上一步中阅读的评论。因此,我们本质上传递了一个列表列表,其中主列表中的每个列表都包含一组来自用户评论的标记。Word2Vec 使用所有这些标记在内部创建词汇表。我所说的词汇是指一组独特的单词。

上面的代码应该开始训练过程。在幕后,我们实际上是在训练一个简单的只有一个隐藏层的神经网络。但是我们实际上不会在训练后使用神经网络。相反,目标是学习隐藏层的权重。这些权重本质上是我们要学习的单词向量。

在 Word2Vec OpinRank 数据集上的训练需要几分钟。所以请喝一杯茶,耐心等待。

有趣的部分——一些结果!

Photo by Victor Rodriguez on Unsplash

让我们开始有趣的事情吧!因为我们是在用户评论上训练的,所以在一些形容词上看到相似性会很好。第一个示例显示了对类似于单词“dirty”的单词的简单查找。这里我们需要做的就是调用most_similar函数,并提供单词‘dirty’作为正例。这将返回前 10 个相似的单词。

Words similar to ‘dirty’

哦,看起来不错。让我们看看更多。

类似客气:

Words similar to ‘polite’

类似法国:

Words similar to “France”

类似震惊:

Words similar to “shocked”

总的来说,结果实际上是有意义的。对于给定的查询单词,所有相关单词倾向于在相同的上下文中使用。

现在,您甚至可以使用 Word2Vec 通过调用similarity(...)函数并传入相关单词来计算词汇表中两个单词之间的相似度。

Compute similarity between two words in the vocabulary

下面,上面的三个代码片段使用两个指定单词的单词向量来计算它们之间的余弦相似度。从上面的分数来看,dirtysmelly高度相似而dirtyclean不相似是有道理的。如果你在两个相同的单词之间做相似性,分数将是 1.0,因为余弦相似性的范围可以从[-1 到 1],有时在[0,1]之间,这取决于它是如何计算的,以及你的向量是否有正值和负值。你可以阅读更多关于余弦相似性评分这里。

你会在我的 Jupyter 笔记本中找到更多关于如何使用 Word2Vec 的例子。

仔细查看参数设置

Photo by Emiliano Vittoriosi on Unsplash

为了更早地训练模型,我们必须设置一些参数。现在,让我们试着理解其中一些是什么意思。作为参考,这是我们用来训练模型的命令。

model = gensim.models.Word2Vec (documents, size=150, window=10, min_count=2, workers=10, iter=10)

size

表示每个标记或单词的密集向量的大小。如果您的数据非常有限,那么 size 应该是一个更小的值。如果你有大量的数据,最好尝试不同的大小。对于相似性查找,100–150 的值对我来说很合适。

window

目标单词与其相邻单词之间的最大距离。如果您的邻居的位置大于左侧或右侧的最大窗口宽度,则一些邻居不被认为与目标单词相关。理论上,一个更小的窗口应该给你更相关的术语。如果你有大量的数据,那么窗口的大小不应该有太大的影响,只要它不会太窄或太宽。如果您对此不太确定,就使用默认值。

min_count

单词的最小频率计数。该模型将忽略不满足min_count的单词。极不常用的单词通常不重要,所以最好把它们去掉。除非数据集非常小,否则这不会真正影响模型。

workers

后台要用多少线程?

iter

要训练多少个纪元?对于中小型数据集,我通常使用 10 或更多。

什么时候应该使用 Word2Vec?

Word2Vec 有很多应用场景。想象一下,如果你需要建立一个情感词典。在大量用户评论上训练 Word2Vec 模型有助于你实现这一点。你有一个不仅仅是情感的词汇,而且是词汇中大多数单词的词汇。

除了原始的非结构化文本数据,您还可以使用 Word2Vec 来处理更多的结构化数据。例如,如果您有一百万个 StackOverflow 问题和答案的标签,您可以找到相关的标签,并推荐这些标签进行探索。您可以通过将每组共现的标签视为一个“句子”并根据该数据训练一个 Word2Vec 模型来做到这一点。当然,你仍然需要大量的例子来使它工作。

源代码

要使用本教程的 Jupyter 笔记本,你可以去我的 GitHub repo 并按照说明如何让笔记本在本地运行。我计划上传预先训练的向量,可用于您自己的工作。

卡维塔·加内桑是《人工智能的商业案例:人工智能战略领导者指南,最佳实践&现实世界应用 的作者。要了解更多关于卡维塔的信息,请访问www.kavita-ganesan.com

如何充分利用数据科学

原文:https://towardsdatascience.com/how-to-get-the-most-out-of-towards-data-science-3bf37f75a345?source=collection_archive---------5-----------------------

最后更新于 2022 年 5 月

找到您需要的内容,并在您的学习之旅中前进

About us — Photo by Leone Venter

你好。

如果你的目标是…

  • 了解数据科学、机器学习、编程或人工智能
  • 转行成为数据科学家、机器学习工程师或相关职位
  • 及时了解该领域最重要的发展和对话

…那么走向数据科学就是你的正确选择。我们是任何想要扩展数据科学和机器学习知识的人的首选目的地。我们也是一个欢迎和支持的社区,将学习者和专业人士聚集在一起。

我们的网站包含数千篇文章、教程和其他资源,因此我们准备了这个简短的路线图来帮助您找到方向。准备好了吗?我们走吧!

找到你需要的信息

我们最好的内容总是一次点击(或两次)就能看到

我们每天在 TDS 上发布几十篇文章,但我们希望让您能够轻松找到与您当前需求最相关的文章。

编辑推荐的是最近引起我们注意的值得关注的文章。它们包括教程、观点文章和原创研究——它们都值得你花费时间。如果你不确定下一步该读什么,这将是你最好的选择。

我们的专栏是精选的集合,专注于广阔的数据科学世界中的特定兴趣和工作流——从准备你的第一份工作到使用人工智能带来社会变革。

标签页显示特定区域内最新的帖子。你可以选择从非常宽泛的(像 Python 或机器学习)一直到非常专业的(特征工程),有人吗?).

获取我们的每周简讯

养成阅读习惯从未如此简单

对于每周一次的顶级数据科学阅读,注册我们每周一期的时事通讯,这是我们每周四发送的变量。

我们专注于包含真实世界用例、前沿研究和技术以及基于经验的职业和商业主题的教程。我们的目标是帮助您了解数据科学、机器学习和人工智能领域的最新理念和创新。

成为中等会员

无限好奇?获得无限制访问权限。

通过成为 Medium 会员,你可以无限制地访问 TDS 的全部档案(以及 Medium 上的所有其他帖子),并确保你的学习永不停止。

同样重要的是:会员资格直接支持你最喜欢的 TDS 贡献者的写作,并鼓励他们分享新文章。

与我们的社区分享您的作品

你的想法、故事和项目值得更广泛的受众

写下你的数据科学和 ML 工作是更深入理解它的最好方法之一。这也是一个展示你成长的机会,也是一个和其他与你有共同兴趣的专业人士交流的机会。它可以激励你去发现新的想法和技术,并帮助你扩大你的人际网络。如果你对写数据科学感兴趣,你可以在这里找到更多信息。

如何获得正确的数据?试着要求它。

原文:https://towardsdatascience.com/how-to-get-the-right-data-why-not-ask-for-it-d26ced1bbd46?source=collection_archive---------8-----------------------

为什么数据科学中最重要的技能可能不是技术性的

虽然数据科学的技术技能——想想用梯度推进机器建模——得到了最多的关注,但其他同样重要的通用问题解决能力可能会被忽视。熟练地提出正确的问题、坚持不懈和利用多种资源对于数据科学项目的成功至关重要,但当人们问及成为数据科学家需要什么时,编码能力往往退居其次。

最近,我在从事一个数据科学促进良好发展的项目时,想起了这些非技术技能的重要性。这个项目目前在 Kaggle 上运行,它包括确定纽约市的学校,这些学校将从鼓励弱势学生参加 T2 高中入学考试(SHSAT)的项目中受益最大。这项任务带有一个小数据集,包括 2016 年的测试结果,但组织者鼓励使用任何公开可用的数据。

Data Science is for more than just getting people to click on ads (Get Started Here)

知道数据科学项目的成功与数据的质量和数量成正比(T4),我开始寻找更新的测试结果。毫不奇怪,有了现在唾手可得的大量资源,我最终获得了成功,并且在这个过程中,我学到了一些关于数据科学所必需的“其他”技能的经验,我在下面列出了这些经验。

第一步:问正确的问题/有正确的目标

资源的广泛可用性可能是一件好事,也可能是一件坏事:有这么多选择,有时可能很难找到一个起点(当人们想学习数据科学时,我经常看到这种现象)。正确的问题或目标可以帮助你缩小选择范围。

如果我问“有没有我可以使用的纽约市的数据?”我可能会被各种可能性淹没,就像“想学习 Python”的人面对令人眼花缭乱的资源一样(更好的目标是“我想为 x 学习 Python ,因为这将限制选择)。

如果你在最初的目标上没有成功,你总是可以撒更大的网或者改变问题/目标。此外,有时你可以用一组与你想象中不同的数据来回答你最初的问题,或者你可能会发现有一个更好的问题要问。记住这一点,我带着一个问题开始了我的搜索:我能找到 SHSAT 的最新结果吗?

第二步:探索资源

对于我的唯一一个重点问题,最好的起点是纽约市开放数据门户网站。像许多大城市一样,纽约市有大量的数据可供免费下载并在您的项目中使用。开放数据门户是探索问题和利用数据科学产生影响的绝佳起点。

不幸的是,尽管纽约市的数据很广泛,但没有一个涵盖 SHSAT。所以我扩大了搜索范围——这意味着我在谷歌搜索结果列表中走得更远——看到了《T4 时报》的一篇文章,这篇文章准确地分析了我想要的数据(带有一些很棒的信息图表)!

One of several interactive maps in the article

第三步:伸出手

很明显,如果 NYT 能够得到的话,这些数据是可以公开获取的!因为我已经检查了开放数据门户,所以我决定尝试一个更直接的途径来联系作者。我以前用这种方法取得过成功——我曾经通过给作者发电子邮件获得了一本绝版的免费大学教材——现在很容易找到社交媒体或专业联系地址。只要你的请求是有礼貌的(一两句赞美不会有什么坏处),大多数作者都会尽可能地乐意帮忙。

然而,在这种情况下,我的直接方法失败了,因为作者在我使用的任何渠道上都没有回应。老实说,我不怪她:作为一个作家,处理所有的请求可能很难,我更希望她专注于写更多的文章,而不是回复每一条评论!

步骤 4:坚持不懈

作为一名数据科学家,最重要的一点是关注细节的能力。有价值的信息可能隐藏在意想不到的地方(如文件名),在这种情况下,阅读信息图下的小字可以发现来源:纽约市教育局,我已经通过开放数据门户搜索过了!

Always read the details

虽然我已经尝试过这个来源,但我还是回到了门户网站,并决定从联系人页面发出一个请求。我提交了一张包含我想要的具体数据的票,并收到了一个稍微令人沮丧的通知,可能需要 2 周才能听到回复。幸运的是,这似乎是一个悲观的高估,两天之内我就收到了回复——来自一个真实的人类!我所要求的数据是可用的。同一天,的全部数据出现在纽约市数据门户网站上,供全世界免费使用,以造福纽约市的学生。公开数据没有任何障碍,有人只需要问一下就行了!

第五步:向前分享

虽然这个项目在技术上是 Kaggle 上的一个竞赛,但我不可能对这些数据的可用性保密。我立即建立了一个讨论线程,并分享了数据源的链接。几个小时内,其他数据科学家就开始使用这些数据进行自己的分析,然后分享他们的发现。这就是数据科学社区的伟大之处:它不是关于竞争,而是关于相互学习。

一个人只能有这么多的经验,但一个群体的集体知识可以是巨大的。这意味着,当你发现一些有趣的事情时,不要把它藏在心里,而是与他人分享,这样其他人也可以学习!从 Kaggle 上的其他数据科学家那里获得了这么多,能够回馈一点感觉很好。

这个小例子说明了几个关键点:第一,问一问无妨!我以前写过这方面的文章,但当你向某人寻求帮助时(只要要求合理),他们最糟糕的回答是不。第二,利用多种资源并坚持不懈的能力会比你职业生涯中的任何特定技能都更能让你进步。我采取的所有步骤都不涉及任何编码,但是如果不完成这些步骤,我就无法获得进行分析所需的数据!最后,不要害怕向人们寻求帮助,或者使用我们现在可以利用的任何伟大的资源。

一如既往,我欢迎评论、建设性的批评和讨论。可以在推特上找到我

如何走进数据科学?

原文:https://towardsdatascience.com/how-to-go-into-data-science-c1f6ef258438?source=collection_archive---------1-----------------------

面向有抱负的数据科学家的终极问答,附有严肃的指南

那么…你想成为一名数据科学家?酷毙了。你是一个自我激励的人,对数据科学和通过解决复杂问题为公司带来价值充满热情。太好了。但是你对数据科学毫无经验,也不知道如何在这个领域入门。我明白了。我去过那里,我绝对能感受到你。这就是为什么这篇文章献给你——充满热情和抱负的数据科学家——来回答大多数人面临的最常见的问题和挑战。

如果数据是“新的石油”,那么数据科学家的职能就像一个炼油厂,将数据转化为既能省钱又能产生资本的见解

——伊娃·肖特

下面所有的问题都不是我创造的,而是你们——充满活力的数据科学社区。非常感谢大家对我之前的 LinkedIn 帖子的支持,包括我从电子邮件和其他渠道收到的问题!请注意,以下问题没有按顺序排列,因此请随意跳到您认为合适的问题部分。

我希望通过在这篇文章中分享我的经验,能够对如何从事数据科学职业有所启发,并给你一些一般性的指导,希望能让你的学习之旅更加愉快。我们开始吧!

数据科学技能缺口的当前趋势是什么?

国际数据公司(IDC)预测,2020 年全球大数据和商业分析收入将超过 2100 亿美元。

根据 2018 年 8 月美国 LinkedIn 劳动力报告,2015 年全国有数据科学技能的人过剩。三年后,随着越来越多的公司面临拥有数据科学技能的人才短缺以及大数据被越来越多地用于产生见解和做出决策,趋势发生了巨大的变化。

从经济学上讲,这完全是供求关系。

好消息是:“桌子”现在被翻转了。坏消息是:随着数据科学领域工作机会的增加,许多有抱负的数据科学家仍然面临着入门的挑战,因为他们缺乏与当前就业市场要求相关的数据科学技能差距。

在接下来的部分中,您将看到如何提高数据科学技能来缩小“差距”,从其他候选人中脱颖而出,并最终增加获得理想工作的机会。

问题与答案

(Source)

1.需要什么样的技能,如何掩盖这些技能?

我会非常诚实地告诉你。学习数据科学中的所有技能几乎是不可能的,因为范围太广了。总会有一些技能(技术/非技术)是数据科学家不知道或没有学到的,因为不同的业务需要不同的技能组合。

总的来说,根据我的经验和向其他数据科学家的学习,我认为要成为一名数据科学家,必须掌握一些核心技能。

技术技能。数学与统计、编程和商业知识。尽管无论使用何种语言,我们都精通编程,但作为数据科学家,我们应该能够用商业语言向利益相关者解释我们的模型结果,并得到数学和统计数据的支持。

(Source)

要学习数学和统计学(或更全面的数据科学资源),请查看由 Randy Lao 创建的他的网站。 Randy 一直在帮助有抱负的数据科学家,他在网站上的知识库真是一座金矿

我仍然记得当我第一次开始研究数据科学时,我读了这本教科书— 统计学习介绍—以及 R 中的应用。我向初学者强烈推荐这本教科书,因为这本书侧重于统计建模和机器学习的基本概念,并附有详细而直观的解释。如果你是一个数学铁杆,也许你会更喜欢这本书:统计学习的要素。

学习编程技巧,特别是对于没有经验的初学者,我建议专注于学习一门语言(我个人更喜欢 Python!😊)因为如果需要的话,这些概念也适用于其他语言,而且 Python 更容易学习。Python 或 R 的重要性和用法一直是数据科学中争论的话题。就我个人而言,我认为重点应该是你如何帮助企业解决问题,不管使用何种语言。

最后,我再怎么强调对商业知识的理解也是极其重要的,因为我已经在中收录了我的一篇文章(你可以在这里查阅)。

软技能。其实软技能比硬技能更重要。惊讶吗?我希望不会。

LinkedIn 调查了 2000 名商业领袖,他们最希望看到自己的员工在 2018 年具备的软技能是:领导力、沟通、协作和时间管理。我真的相信这些软技能在数据科学家的日常工作中起着至关重要的作用。特别是,我学到了沟通技巧的重要性,你可以在这里阅读。

2.当有大量的训练营和在线课程时,如何选择合适的呢?

随着围绕人工智能和数据科学的大肆宣传以及许多人加入这一潮流,许多 MOOCs、训练营、在线课程、研讨会(免费/付费)如雨后春笋般涌现,希望不会“错失良机”。

外面有很多资源。足智多谋。

所以问题来了:如何选择适合自己的学习资料?

我筛选和选择适合我的在线课程/研讨会的方法:

  • 要明白没有一门最好的课程可以涵盖你需要的所有材料。有些课程在某些领域重叠,不值得花钱购买不同的课程,而是重复大部分教材。
  • 首先要知道你需要学习什么。永远不要仅仅因为花哨和吸引人的标题就一头扎进课程。还记得前面提到的技术技巧吗?在网上查看数据科学家的职位描述,你会注意到一些公司需要的通用技能。现在你已经知道了需要的技能和你缺少的技能。太棒了。去搜索可以帮助你提高知识(理论和实践)的课程。
  • 在网上搜索不同平台提供的最佳课程。一旦你列出了几门适合你的课程,看看他们各自的评价(非常重要!)被别人在你掏出钱包报名之前。另一方面, Coursera 、 Udemy 、 Lynda 、 Codecademy 、 DataCamp 、 Dataquest 等等也有很多免费课程。我是不是也提到了 YouTube ?是的,你明白了。
  • 提示:一些平台可能会提供财政援助来补贴你的课程费用(Coursera 等。).试试看!
  • 一些我个人最喜欢的课程对我帮助很大:
  1. Coursera 联合创始人吴恩达教授的机器学习
  2. 何塞·波尔蒂利亚教授的数据科学与机器学习训练营Python。
  3. 深度学习 A-Z:基里尔·叶列缅科和哈德琳·德·庞特维斯教授的动手操作人工神经网络
  4. Python 对于数据科学的必备培训 莉莲皮尔森教授。
  5. 终极实践 Hadoop —驯服您的大数据! 由弗兰克·凯恩教授。

3.向开源学习足以成为一名数据科学家吗?

我要说的是,从开源学习足以让你开始学习数据科学,除此之外的任何事情都是为了进一步发展你作为数据科学家的职业生涯,这也取决于业务需求。

4.一个初学者(来自完全不同的背景)应该从阅读材料开始了解基础知识吗?你会推荐什么书?

(Source)

学习没有固定的道路,因为条条大路通罗马。阅读材料绝对是理解基本面的一个很好的开始,我也是这样做的!

只是要注意不要试图去阅读和记忆数学和算法的本质。因为很有可能,当涉及到编码时,如果没有真正将概念应用到实际问题中,你会忘记一切。

只要知道和理解到足以让自己开始,并进入下一步。实用一点。不要仅仅因为完美主义在不知不觉中成为拖延和不前进的最佳理由,就试图在知道一切方面做到完美。

下面是一些我建议用来理解 Python、机器学习和深度学习基础的书籍(希望有所帮助!):

  • 学习 Python
  • 用于数据分析的 Python
  • 统计学习简介
  • 绝对初学者的机器学习
  • Python 机器学习
  • Python 数据科学手册
  • Python 机器学习简介
  • 用 Python 进行深度学习
  • 使用 Keras 进行深度学习

5.如何在理解业务问题(制定解决方案)和发展技术技能(编码、核心数学知识等)之间取得平衡。)?

在了解业务问题和制定解决方案之前,我从发展我的技术技能开始。

商业问题给你什么,为什么。要解决一个商业问题,首先要知道如何解决问题。方法来自于技术技能。同样,方法取决于情况,我的建议主要基于个人经验。

6.我们如何克服开始数据科学家职业生涯的挑战?

许多有抱负的数据科学家(包括我)面临的主要挑战之一是数据科学是信息的海洋。我们很容易因为被来自不同方向的建议和资源(在线课程、研讨会、网络研讨会、聚会等等)淹没而失去注意力。保持专注。知道你拥有什么,你需要什么,然后全力以赴。

在我的数据科学之旅中,挑战数不胜数,但也正是这些挑战塑造了今天的我。我将尽力解释我面临的主要挑战以及如何克服这些挑战:

  • 刚开始的时候,我对这么多的资源感到困惑。我艰难地过滤掉了噪音。收听播客,观看数据科学家举办的网络研讨会,阅读大量关于如何在该领域发展的数据科学文章,尝试各种在线课程,参与 LinkedIn 上的数据科学社区,并向他们学习。最后,我只关注我在这篇文章中分享的有用资源。
  • 有一段时间我几乎要放弃了。当学习曲线过于陡峭,我开始怀疑自己时,放弃的想法出现在我的脑海中。我真的有能力这样做吗?我真的在追求正确的道路吗?激情和耐心把我重新引回,让我继续前行。日复一日,继续努力,继续忙碌。

你的工作将占据你生活的很大一部分,而真正满足的唯一方式就是做你认为伟大的工作。做伟大工作的唯一方法是热爱你的工作。

—史蒂夫·乔布斯

  • 获得一份数据科学家的工作( 或类似的工作范围但不同的头衔 )。我希望我能早点读到这些由 Favio Vázquez — 如何找到一份数据科学家的工作?和获得数据科学家工作的两面性。由于就业市场竞争激烈,找工作对我来说并不容易。我提交了大量的求职简历,但毫无结果。我正在深思,一定是出了什么问题。我改进了我的方法,开始建立关系网:参加聚会和研讨会,在网上分享我的学习经验,在招聘会上接触未来的雇主,以更系统的方式分享会议,在提交简历后跟进等等。事情开始改变,机会开始敲我的门。

7.如何把我的工作经历放在简历里,这样我才会被录用,我的经历才会被计算在内?

我相信这里有一个误解——你不会仅仅因为简历中的经历而被录用。事实上,你的简历是获得你下一阶段申请——面试——的第一张入场券的方法之一。

因此,学会如何在简历中写工作经历对获得入场券至关重要。研究表明,一般招聘人员会花六秒钟浏览简历的 ,然后决定应聘者是否适合这个职位。换句话说,要通过简历测试,你的简历只有 6 秒钟的时间给未来的雇主留下好印象。就我个人而言,我参考了以下资源来润色我的简历:

  • 跳马
  • 顶部简历
  • 优化指南 (个人喜好!)
  • 简历专家给出职业建议
  • 如何通过 6 秒简历测试
  • 如何为数据科学职位量身定制你的学术简历
  • 招聘经理在数据科学家的简历中寻找什么?
  • 你简历上需要的 14 件事,让你找到理想的工作

8.什么样的投资组合可以帮助我们在数据科学或机器学习领域获得第一份工作?

(Source)

在我关于媒体的第一篇文章中,我提到了建立投资组合的重要性。没有好的作品集,有一份精心打磨的简历不足以让你获得面试机会。

在第一眼看完你的简历后,未来的雇主想要更多地了解你的背景,这就是你的简历出现的地方。虽然你可能想知道如何从零开始建立一个文件夹,从记录你的学习旅程开始。通过社交媒体平台(LinkedIn、Medium、脸书、Instagram、个人博客——没关系)分享你的学习经验、错误、收获——技术或非技术。

对着录像机说话有意思?然后开始制作视频(采访其他有抱负的/公认的数据科学家)并在 YouTube 上分享。擅长写作?然后开始在不同的平台上写你热衷的话题。如果你对视觉和写作不感兴趣,那么联系其他人,和他们一起做播客

我的观点是:互联网带来了大量的机会来建立你的投资组合,获得关注,或者潜在的吸引你未来雇主的注意。

我做过的最好的决定之一是在 LinkedIn 上与数据科学社区接触,并在 T2 媒体上记录我的学习历程。在 LinkedIn 上,在这样一个有益的共享学习环境中,我从紧密团结的数据科学社区中学到了最多。

渐渐的,我学会了(还在学!)如何用我不同来源的经历在 LinkedIn 上建立我的投资组合。一路上,我从不同的招聘人员那里得到了关于工作机会的信息,我甚至有机会喝了点咖啡,和他们中的一些人聊了会儿天。

现在,我非常兴奋地分享我所学到的东西,并为社区做出贡献。所以我给出了一些有用的指导,教你如何用一些严肃的技巧建立你的 LinkedIn 个人资料!

请在下面的评论中留下你的电子邮件地址,我会直接发送到你的收件箱。😄

—更多资源—

在这一点上,你可能想知道我是如何在这篇文章中同时分享这么多资源的。嗯,我的显而易见的秘密:把我觉得有用的网站和文章标上书签,并不时地参考它们。

这被证明是非常有帮助的,当我需要一些参考和修改时,这对我很有用。我当然可以分享书签网站的完整列表,但对于这篇文章来说太长了(我想可能在另一篇文章中)。

尽管如此,我还是会列出一些有用的资源:

  • 走向数据科学QuoraDZoneKDnuggetsAnalytics vid hyaDataTau fast.ai
  • 网络研讨会 — 数据科学办公时间、数据科学交流、数据科学的人类(HoDS)
  • 用数据讲故事:商业专家数据可视化指南
  • 闯入数据的坏蛋指南
  • 10 必须具备数据科学技能
  • 我的数据科学&机器学习,初学者的学习路径
  • 机器学习掌握度
  • 24 个终极数据科学项目提升您的知识和技能

追随鼓舞人心的数据科学家和专业人士

(Source)

LinkedIn 上的数据科学社区非常棒,我强烈建议您关注下面提到的鼓舞人心的数据科学家和专业人士:

  • 兰迪·劳

  • 凯尔·麦基乌

  • 法维奥·巴斯克斯

  • Vin Vashishta

  • 埃里克·韦伯

  • 莎拉·诺拉维

  • 凯特·斯特拉奇尼

  • 塔里·辛格

  • 梅根·西尔维

  • 伊马德·穆罕默德·汗

  • 安德烈亚斯·克雷茨

  • 安德烈·布尔科夫

  • 卡拉金特里

  • 尼克瑞恩

  • 情郎沃克

最后的想法

Taking a Leap of Faith

你一路赶到这里?!感谢阅读。

这是迄今为止最长的帖子,还有很多我渴望与你分享的(也许在下一篇帖子里,谁知道呢?😊).

不要让任何人催促你完成他们的时间表

希望我的分享已经为你解答了燃眉之急。每当您在数据科学之旅中遇到任何障碍时,请记住,您并不孤单,作为社区的一部分,我们都在这里提供帮助。只要给我打电话,我会非常乐意帮忙的!

现在你已经有了问题的答案(如果你有其他问题,请在下面留下你的评论),是时候采取大规模行动来实现你作为一名有抱负的数据科学家的目标了。没有什么行动是微不足道的。一步一步向前。当你濒临放弃时,坚持是关键。

我知道这是一篇很长的帖子,所以请在评论中让我知道哪些部分对你最有用。

一如既往,如果您有任何问题或意见,请随时在下面留下您的反馈,或者您可以随时通过 LinkedIn 联系我。在那之前,下一篇文章再见!😄

—注释—

如果你在寻找一些有用的指南,关于如何用一些严肃的技巧建立你的 LinkedIn 个人资料,在下面的评论中留下你的电子邮件地址,我会直接发送到你的收件箱。

关于作者

Admond Lee 目前是东南亚排名第一的商业银行 API 平台 Staq 的联合创始人/首席技术官。

想要获得免费的每周数据科学和创业见解吗?

你可以在 LinkedIn 、 Medium 、 Twitter 、脸书上和他联系。

[## 阿德蒙德·李

让每个人都能接触到数据科学。Admond 正在通过先进的社交分析和机器学习,利用可操作的见解帮助公司和数字营销机构实现营销投资回报。

www.admondlee.com](https://www.admondlee.com/)

如何增长数据

原文:https://towardsdatascience.com/how-to-grow-data-7d1892792b6f?source=collection_archive---------3-----------------------

Image by Staleybk from Pixabay

数字化和人工智能这两股浪潮已经高涨到任何企业都无法忽视的地步。它已经从幕后成为价值和创新的驱动力。难怪最近一期的《经济学人》宣称“世界上最有价值的资源不再是石油,而是数据”。

由于现在几乎每一项人类活动都会产生数字痕迹,优势在于那些能够利用数据中的洞察力的人。顾客什么时候会购买?最好的产品组合是什么?什么时候应该做保养?什么使我的员工最有效率?

令人惊讶的是,驱动这些见解的算法并不是秘方。尽管定价很高,但使用它们的数据科学家也不感兴趣。价值在于数据本身,以及应用于您的业务时的潜力。

尽管使用数据来降低成本或优化流程会带来很多好处,但这还不是全部。大量的数据创造了未来的可能性和竞争优势。例如,通过交付联网汽车,特斯拉获得了对驾驶模式的独特和巨大的洞察力:对抗竞争对手的壁垒,以及在未来创新中可以利用的丰富资源。

通过运营当前业务来创造这种未来潜力的能力是数据驱动的最终定义:当价值而不仅仅是决策由数据驱动时。

这使得数据访问成为每个人的当务之急。增加数据储备的计划应该在每一项企业战略中占据首要位置。但是你怎样才能让它成为现实呢?

不断增长的数据投资有四个层次:购买、集成、工具和设计。真正的数据驱动型企业参与所有四个层面。

Four levels of growing data investment

购买数据

获得洞察力的最快方法之一是购买数据,这对许多企业来说并不新鲜。由于 Acxiom、LexisNexis 或 Hoovers 等信息公司,购买数据已经成为消费者和竞争情报领域几十年的行业惯例。金融数据、天气和地理数据都是许多企业的主要需求。
通过获取第三方数据,您可以更深入地了解现有运营,并改善决策支持。然而,可供出售的数据往往局限于大规模数据集,主要是环境性质的数据集。购买数据可以推动业务发展,但你无法通过购买数据来实现竞争优势。

整合您的数据

甚至在大数据时代之前,公司就产生了大量信息,这些信息可以用来推动增长和创造更多价值。整合这些信息的潜力很大。组合数据集往往会对数据的功效产生倍增效应,而不仅仅是累加效应。

公司的每个系统都在不断地创造数据。然而,数据孤岛是一个系统性问题,严重限制了这些数据的有用性。孤岛来自软件应用程序和流程,这些应用程序和流程是在数据的价值未被真正认识到的时代构建的,在这个时代,资源约束更加严格。面向流程的一个自然副作用是导致业务功能之间的语义差异,并增加了进一步的复杂性:遇到诸如“客户”等概念的多种不同定义并不罕见。

工具

当你真正专注于使用数据来推动决策和价值时,下一步就是使用仪器。插装是将数据生成嵌入到过程和系统中的行为,它报告它们随时间的状态。多亏了运筹学领域,这个概念并不新奇,但是随着数字化程度的提高,仪器化的范围越来越大,成本也越来越低。

举一个软件方面的例子:软件检测的范围曾经是记录错误,以便给支持技术人员诊断的希望。现在,记录用户的每一次交互,鼠标的每一次移动都是可行的,我们可以问的问题进一步延伸:不仅仅是“为什么会出错”,而是“这个产品使用起来有多容易?”再举一个零售业的例子,无线电信标现在可以监控商店的客流量,从而评估实体布局的有效性。

仪器和数据科学的结合使我们能够收集细节并解决问题,这在以前需要昂贵的人工干预。

面向数据的设计

任何在上述三个层面深度投入的组织都已经处于强大的领先地位,只是在实现数据的潜力方面还有一步。如果您真正理解数据的力量,那么围绕数据的积累和利用来设计活动,将数据构建为战略资产。

达到这一点就是开始对谷歌、亚马逊和脸书这些科技巨头有了答案。作为以数据为基础的公司,它们的灵活性、数据积累和财务实力使它们能够在新市场中令人信服地发起挑战。

为数据而设计的业务的本质是,产品或服务的交付产生进一步增强服务的数据,并为下一步的创新和扩展创建平台。客户不是孤立的接受者,而是生态系统的一部分,他们的参与使产品对每个人都更好。与前三个阶段的带外应用相比,以客户生成的数据为基础,分析和人工智能被用作产品的一部分。

数据不是一种可替代的商品,因此它的积累给竞争对手设置了一个令人望而生畏的障碍:也许正如《经济学人》所观察到的,一种新的反垄断方法将在未来变得必要。

如果你喜欢这个并想听更多,请加入我的简讯。

如何处理丢失的数据

原文:https://towardsdatascience.com/how-to-handle-missing-data-8646b18db0d4?source=collection_archive---------0-----------------------

“归罪的想法既诱人又危险”(R.J.A Little & D.B .鲁宾)

我在数据清理/探索性分析中遇到的最常见的问题之一是处理丢失的值。首先,要明白没有好的方法来处理丢失的数据。我遇到过不同的数据插补解决方案,取决于问题的类型——时间序列分析、ML、回归等。并且很难提供通用的解决方案。在这篇博客中,我试图总结最常用的方法,并试图找到一个结构性的解决方案。

插补与删除数据

在讨论数据插补方法之前,我们必须了解数据丢失的原因。

  1. 随机缺失(MAR): 随机缺失是指一个数据点缺失的倾向与缺失数据无关,但与一些观察到的数据有关
  2. 完全随机缺失(MCAR): 某个值缺失的事实与其假设值无关,也与其他变量的值无关。
  3. 非随机缺失(MNAR): 两种可能的原因是,缺失值取决于假设值(例如,高收入的人一般不愿意在调查中透露自己的收入)或缺失值取决于其他一些变量的值(例如,我们假设女性一般不愿意透露自己的年龄!这里年龄变量中的缺失值受性别变量的影响)

在前两种情况下,根据缺失值的出现情况删除缺失值的数据是安全的,而在第三种情况下,删除缺失值的观测值会在模型中产生偏差。因此,在删除观察值之前,我们必须非常小心。请注意,插补不一定给出更好的结果。

删除

  • 列表式 列表式删除(全病例分析)删除具有一个或多个缺失值的观察的所有数据。特别是如果缺失的数据仅限于少量的观察值,您可以选择从分析中排除这些情况。然而,在大多数情况下,使用列表式删除通常是不利的。这是因为 MCAR 的假设(完全随机缺失)通常很难得到支持。因此,列表式删除方法会产生有偏差的参数和估计值。
newdata <- na.omit(mydata)# In python
mydata.dropna(inplace=True)
  • 成对 成对删除分析感兴趣的变量存在的所有情况,从而最大化分析基础上可用的所有数据。这种技术的一个优点是它增加了你的分析能力,但是它也有很多缺点。它假设丢失的数据是 MCAR。如果你成对地删除,那么你会得到不同数量的观察值,这些观察值对你的模型的不同部分有贡献,这会使解释变得困难。

#Pairwise Deletion
ncovMatrix <- cov(mydata, use="pairwise.complete.obs")#Listwise Deletion
ncovMatrix <- cov(mydata, use="complete.obs")
  • 丢弃变量 在我看来,保留数据总是比丢弃好。有时,如果超过 60%的观测数据缺失,您可以删除变量,但前提是该变量不重要。话虽如此,插补法总是优于剔除变量的选择
df <- subset(mydata, select = -c(x,z) )
df <- mydata[ -c(1,3:4) ]In python
del mydata.column_name
mydata.drop('column_name', axis=1, inplace=True)

时序特定方法

  • 上一次观察结转(LOCF) &下一次观察结转(NOCB)
    这是纵向重复测量数据分析的常用统计方法,其中一些随访观察可能会丢失。纵向数据在不同的时间点跟踪相同的样本。这两种方法都可能在分析中引入偏差,并且当数据有明显趋势时表现不佳
  • 线性插值
    这种方法适用于具有某种趋势的时间序列,但不适用于季节性数据
  • 季节性调整+线性插值
    该方法适用于同时具有趋势和季节性的数据

Data: tsAirgap form library(imputeTS), Interpolated Data in Red

library(imputeTS)na.random(mydata)                  # Random Imputation
na.locf(mydata, option = "locf")   # Last Obs. Carried Forward
na.locf(mydata, option = "nocb")   # Next Obs. Carried Backward
na.interpolation(mydata)           # Linear Interpolation
na.seadec(mydata, algorithm = "interpolation") # Seasonal Adjustment then Linear Interpolation

平均值、中间值和众数

计算总体均值、中位数或众数是一种非常基本的插补方法,它是唯一一种没有利用时间序列特征或变量之间关系的测试函数。它非常快,但有明显的缺点。一个缺点是均值插补减少了数据集中的方差。

library(imputeTS)na.mean(mydata, option = "mean")   # Mean Imputation
na.mean(mydata, option = "median") # Median Imputation
na.mean(mydata, option = "mode")   # Mode ImputationIn Python
from sklearn.preprocessing import Imputer
values = mydata.values
imputer = Imputer(missing_values=’NaN’, strategy=’mean’)
transformed_values = imputer.fit_transform(values)# strategy can be changed to "median" and “most_frequent”

线性回归

首先,使用相关矩阵来识别具有缺失值的变量的几个预测值。选择最佳预测值并将其用作回归方程中的独立变量。有缺失数据的变量作为因变量。预测变量数据完整的案例用于生成回归方程;然后,该方程用于预测不完整情况下的缺失值。在迭代过程中,插入缺失变量的值,然后使用所有情况来预测因变量。重复这些步骤,直到从一个步骤到下一个步骤的预测值之间的差异很小,即它们收敛。它“理论上”为缺失值提供了很好的估计。然而,这种模式有几个缺点,往往大于优点。首先,因为被替换的值是从其他变量中预测出来的,它们往往“太好”地吻合在一起,所以标准误差被缩小了。我们还必须假设回归方程中使用的变量之间存在线性关系,而实际上可能没有线性关系。

多重插补

  1. 插补:对不完整数据集的缺失条目进行插补 m 次( m =图中 3)。请注意,估算值来自分布。模拟随机抽取不包括模型参数的不确定性。更好的方法是使用马尔可夫链蒙特卡罗(MCMC)模拟。这一步产生了 m 个完整的数据集。
  2. 分析:分析每个 m 完成的数据集。
  3. 汇总:将 m 分析结果整合成最终结果

Source: http://www.stefvanbuuren.nl/publications/mice%20in%20r%20-%20draft.pdf

# We will be using mice library in r
library(mice)
# Deterministic regression imputation via mice
imp <- mice(mydata, method = "norm.predict", m = 1)

# Store data
data_imp <- complete(imp)# Multiple Imputation
imp <- mice(mydata, m = 5)#build predictive model
fit <- with(data = imp, lm(y ~ x + z))#combine results of all 5 models
combine <- pool(fit)

这是目前最受欢迎的插补方法,原因如下:
-易于使用
-无偏差(如果插补模型正确)

分类变量的插补

  1. 模式插补是一种方法,但它肯定会引入偏差
  2. 缺失值本身可以被视为一个单独的类别。我们可以为缺失的值创建另一个类别,并将它们用作不同的级别。这是最简单的方法。
  3. 预测模型:在这里,我们创建一个预测模型来估计将替代缺失数据的值。在这种情况下,我们将数据集分成两组:一组没有变量的缺失值(训练),另一组有缺失值(测试)。我们可以使用逻辑回归和方差分析等方法进行预测
  4. 多重插补

KNN (K 个最近邻居)

还有其他机器学习技术,如 XGBoost 和随机森林用于数据插补,但我们将讨论 KNN,因为它被广泛使用。在这种方法中,基于某种距离度量来选择 k 个邻居,并且将它们的平均值用作插补估计。该方法需要选择最近邻的数量和距离度量。KNN 可以预测离散属性(k 个最近邻中最频繁的值)和连续属性(k 个最近邻中的平均值)
距离度量根据数据类型而变化:
1。连续数据:连续数据常用的距离度量有欧几里德、曼哈顿和余弦
2。分类数据:在这种情况下通常使用汉明距离。它接受所有的分类属性,并且对于每个属性,如果两点之间的值不相同,则计数 1。然后,汉明距离等于值不同的属性的数量。
KNN 算法最吸引人的特点之一是它简单易懂,易于实施。KNN 的非参数性质使其在某些数据可能非常“不寻常”的情况下具有优势。
KNN 算法的一个明显缺点是在分析大型数据集时变得非常耗时,因为它会在整个数据集中搜索相似的实例。此外,对于高维数据,KNN 的精度会严重下降,因为最近的和最远的邻居之间几乎没有差别。

**library**(DMwR)
knnOutput <- **knnImputation**(mydata)In python
from fancyimpute import KNN    

# Use 5 nearest rows which have a feature to fill in each row's missing features
knnOutput = KNN(k=5).complete(mydata)

在上面讨论的所有方法中,多重插补和 KNN 被广泛使用,而更简单的多重插补通常更受青睐。

如果你对这个帖子有任何问题,请在评论中提问,我会尽力回答。

资源: 1。https://www.bu.edu/sph/files/2014/05/Marina-tech-report.pdf 2。https://arxiv.org/pdf/1710.01011.pdf3。https://machinelingmastery . com/k-nearest-neighbors-for-machine-learning/ 4 .https://kevinzakka.github.io/2016/07/13/k-nearest-neighbor/ 5。纳撒尼尔·史蒂文斯在旧金山大学的时间系列讲座

如何突出 3D 大脑区域

原文:https://towardsdatascience.com/how-to-highlight-3d-brain-regions-2e6c15a35574?source=collection_archive---------9-----------------------

最近,我在读霍华德 et。艾尔。,(2018)“对 807,553 名个体进行的抑郁症全基因组元分析确定了 102 个独立的变异,并在另外 1,507,153 名个体中复制”并看到了与抑郁症相关的突出显示大脑区域的非常酷的 3D 可视化:

Source: https://goo.gl/7rY5KV

经过彻底的搜索,我无法在方法或补充信息中找到任何关于这是如何完成的参考,所以我联系了作者。在我等待回复的时候,我也联系了推特上的T21,看看是否有人知道可以用来创建这样一个可视化的工具。

头盔卡里姆暗示说,也许这些图像是使用MATLAB中的BrainNet Viewer创建的,所以这是我尝试的第一种方法。

注意:本文中涉及的所有方法都使用了所谓的brain Atlas叠加在标准化 T1 MRI 图像上作为mask。我选择突出显示这些方法的left hippocampus,以便它们具有可比性。

BrainNet 浏览器

首先遵循BrainNet Viewer 的安装说明,然后从终端启动图形用户界面(GUI)。

接下来选择加载文件,并选择一个表面模板surface template和一个mapping文件( a brain atlas)。软件包提供了样本,所以我选择了BrainMesh_ICBMI52_smoothed.nv和[aa l90](http://neuro.imm.dtu.dk/wiki/Automated_Anatomical_Labeling)brain atlas,它们已经标记了 90 个大脑区域的体积。

接下来将弹出一个包含 7 个部分的窗口,我们对其中的layoutsurfacevolume感兴趣。

layout中选择您想要的视图,我选择了full view,它将显示八个不同的视角。

surface选项卡中,你可以选择表面贴图的透明度——我已经将它设置为 0.75

volume选项卡中选择ROI drawing,取消选择draw all,在自定义框中输入37(hippocampus_L的代码)。然后选择确定

芒果

我目前正在与霍华德实验室讨论,试图获得他们用来创建他们的数字图像的确切方法,但我认为这是他们如何用[ 芒果 ]做到的。

Mango有很好的视频教程、用户指南和论坛但是对于我们这些唯一感兴趣的是创建一个高亮的 3D 大脑图像的人来说,这是一大堆需要浏览的材料。因此,我决定为这个过程创建一个详细的协议来节省其他人的时间。

我决定下载锤子大脑图谱作为蒙版/覆盖图和Mango提供的样本图像

接下来选择Add Overlay并选择hippocampus_L

现在选择Image > Build Surface创建大脑的 3D 图像。

在这个新的弹出 GUI 中,我们想做一些事情。首先,将背景改为白色,这样就可以在手稿中发表了。第二,将这张图片的透明度改为 0.75

View选项卡下取消选择十字光标。

在另一个面板中选择Analysis > Create Logical Overlays,然后在表面面板中选择Shapes > Add Logical

然后在Surface > Views下,你可以选择任何你喜欢的方向,然后Surface > Create Snapshot保存为.png

下面是海马体的三视图 _L: :

r 实施

约翰·穆斯切利约翰·霍普金斯大学彭博公共卫生学院的助理科学家,他写了许多R包(例如 fslr)几周后回复了我的推特。他想出了一个要点来强调《T2》中的 3D 大脑图像。

library(rgl)
library(misc3d)
library(neurobase)
if (!requireNamespace("aal")) {
  devtools::install_github("muschellij2/aal")
} else {
  library(aal)
}
if (!requireNamespace("MNITemplate")) {
  devtools::install_github("jfortin1/MNITemplate")
} else {
  library(MNITemplate)
}img = aal_image()
template = readMNI(res = "2mm")
cut <- 4500
dtemp <- dim(template)# All of the sections you can label
labs = aal_get_labels()# Pick the region of the brain you would like to highlight - in this case the hippocamus_L
hippocampus = labs$index[grep("Hippocampus_L", labs$name)]mask = remake_img(vec = img %in% hippocampus, img = img)### this would be the ``activation'' or surface you want to render 
contour3d(template, x=1:dtemp[1], y=1:dtemp[2], z=1:dtemp[3], level = cut, alpha = 0.1, draw = TRUE)
contour3d(mask, level = c(0.5), alpha = c(0.5), add = TRUE, color=c("red") )
### add text
text3d(x=dtemp[1]/2, y=dtemp[2]/2, z = dtemp[3]*0.98, text="Top")
text3d(x=-0.98, y=dtemp[2]/2, z = dtemp[3]/2, text="Right")
rglwidget()

John Muschelli 也在R教授一些关于成像的短期课程,我目前正在上他的[ 神经黑客课程。我真的很感谢他花时间做这件事。

如果你有兴趣在R了解更多关于医学成像的知识,一定要去看看神经传导

如果你觉得这篇文章有用,请随意与他人分享或推荐这篇文章!😃

一如既往,如果您有任何问题或意见,请随时在下面留下您的反馈,或者您可以随时通过 LinkedIn 联系我。在那之前,下一篇文章再见!😄

如何建立一个机器学习团队

原文:https://towardsdatascience.com/how-to-hire-a-machine-learning-team-b8055fff57f?source=collection_archive---------10-----------------------

领域专家、ML 实践者和数据工程师的正确组合,在机器学习中取得成功

我偶尔会做的事情之一是建议谷歌云的客户建立他们的机器学习团队。一家公司可能会启动一项计划,在整个组织中注入机器学习,这对于他们雇佣一名高级数据科学家并建立一个从业者团队非常重要。他们给我看了几份简历,问我的想法,或者问他们应该去参加什么样的招聘会议。

我在一个能为价值数百万美元的机器学习项目提供强有力的技术领导的人身上寻找什么?团队中资历较浅的成员怎么样?

你在 ML 团队成员身上寻找什么

想象你正在面试一个程序员。“你以前编过程序吗?,“你问得微妙。“是的!候选人声称,“这是一个 GitHub repo,包含我在参加的在线编程课程中编写的 Hello World 程序。”

“我希望有一些真实世界的程序,”你坚持说,“比你好世界更深刻的东西。”

“我学会了用 Python、Java 和 C++编写 Hello World 程序,”候选人回答,“我甚至修改了它们,让它们说 Hello Earth”。

你会雇佣这个人吗?

You wouldn’t hire a programmer whose entire experience consists of “Hello World” in 3 languages. Why would you do that when it comes to machine learning?

然而…这正是许多机器学习候选人的简历所表明的!在线和大学课程教授理论和玩具示例,许多学习者只是止步于此。你需要你的 ML 从业者超越这一点。

他们应该知道如何建立端到端的机器学习解决方案来解决现实世界的问题,我的意思是他们需要收集/整理数据,摄取数据,探索数据,并清理数据。他们还需要编写模型,训练它,评估它,迭代它,最后部署它进行批量和在线预测。然后,也只有到那时,他们才能声称知道如何进行机器学习。

在招聘你的 ML 团队成员时,确保区分希望从事机器学习研究的人和希望将机器学习应用于你的业务问题的人。对于你的 ML 团队,雇佣优秀的程序员,他们通常会重用现有的框架和库,但是对数据科学中固有的模糊性感到舒服。

你在 ML 技术领导中寻找什么

知道如何进行机器学习并不等于精通它,就像知道如何编写 Java 类并不意味着面向对象和企业设计模式是你的第二天性。你不会为你的团队雇佣一个不能创造性地组装高级组件的高级架构师,你也不应该为机器学习领导这样做。

知道如何端到端地实现机器学习模型并不等同于创造性地使用机器学习。因此,机器学习课程可能会教你如何建立序列到序列的模型,这是建立翻译模型的良好起点。但是,野外的翻译系统不仅仅是使用欧洲议会的演讲记录来编写和训练一个英语到德语的模型。

我什么意思?让我用谷歌搜索“谷歌翻译”时发生的事情来说明一下。在链接页面的顶部,我有一个框,我可以在里面输入我想翻译的文本并选择目标语言:

Even a simple user journey will involve multiple ML models. You need a technical lead for ML who can creatively think through a use case and identify all the machine learning models you will build, the data you will collect to train those models, the model architecture you will use, and how you will evaluate those models.

在这个简单的用户旅程中,我可以识别至少六个机器学习模型(见上图中的数字):

Whether or not to bring up this translation UI in response to a search involves ML.

  1. 当我搜索“谷歌翻译”时,我得到的不仅仅是一组链接——我还得到了这个特殊的用户界面(见左图)。还有哪些搜索词可以调出翻译界面?我甚至成功地找到了一个甚至不包含“翻译”这个词的查询。

Whether or not to bring up this translation UI in response to a search involves ML — notice that is not as simple as looking for the word “translate” in the search term.

决定什么时候把盒子拿出来?那很可能是 ML 型号。

2.请注意,UI 显示“检测到英语”。检测源文本使用的语言?另一个机器学习模型。

3.然后当然是核心的翻译模型。在我的第一个例子中,我以一种辩论的语气写英语,泰米尔语以类似的语气回复。让事情变得更难的是,泰米尔语的自然顺序是把第二个短语(“而不是仅仅依靠例子”)放在前面,翻译就是这样做的。

4.翻译后的文本出现在一个框中,该框为我提供了文本到语音转换的选项,即大声朗读泰米尔语文本。如果我在国外,只是想让我的设备用外语和我的对话人交流,这非常有用。

5.但是万一我想读,又不读泰米尔文字,有一个很有帮助的拼音指南。这是另一种 ML 模型,一个音节一个音节地转录翻译的文本。

6.最后,当然,可以选择完全通过语音进入翻译界面。模型 4 和 6 向谷歌助手用例开放了基于网络的翻译服务。

熟悉机器学习意味着能够创造性地思考一个用例,并确定您将建立的所有机器学习模型,您将收集来训练这些模型的数据,您将使用的模型架构,以及您将如何评估这些模型。当你为你的 ML 团队雇佣一个高级领导时,你希望有人有能力做到这一点。

不幸的是,没有任何课程或书籍谈论机器学习的这一方面。我目前正与 Coursera 合作,根据我为谷歌云客户提供咨询的经验,为决策者创建一个机器学习课程。

完整的数据科学组织

构建各种模型并让它们协同工作的需求意味着您的大型数据科学团队还需要许多其他角色。我的同事凯西列了一张便利清单。

特别是,你还需要一个数据工程团队和一个数据分析团队来支持 ML 团队。数据工程师构建管道来定期接收和转换数据。数据分析师构建仪表板并创建报告,以支持整个组织的决策制定-除非您的分析团队已经手动进行了几次分析,并且您了解到这是您的企业通常会做出的决策,否则您不会想要构建 ML 模型来自动化任何决策制定。

这是员工人数约为 60 人的数据组织的典型设置,也是适合员工人数约为 10 人的组织的简化版本:

My suggestion for typical 60-person and 10-person data science organizations. The colored shapes represent tech leads while the gray circles represent individual contributors. Transparent shapes are managers whose primarily role is organizational (i.e. they lead either programs or people).

构建组织

在 Google Cloud,我们确实为所有这些角色提供培训,以便您可以提升现有团队成员的技能。参见 https://cloud.google.com/training/data-ml报名参加在线课程和面授课程,或者咨询您的 Google Cloud 销售或客户代表。

对于数据工程职位,谷歌云提供了数据工程认证和 Coursera 数据工程专业认证来帮助培训你的组织获得该认证。对于 GCP 的数据分析,我们提供从数据到洞察专业化。

为了跟上实际机器学习的速度,我建议 GCP 的带 TensorFlow 的机器学习和 GCP 的高级机器学习Coursera 的专门化。我有偏见,但我认为它们是最实际、最实用的机器学习课程。他们专注于帮助你建立一个 ML 从业者的团队,而不是研究人员。

如何通过 7 个简单的步骤在 AWS 云上托管一个 R Shiny 应用程序

原文:https://towardsdatascience.com/how-to-host-a-r-shiny-app-on-aws-cloud-in-7-simple-steps-5595e7885722?source=collection_archive---------0-----------------------

R Shiny App 是什么?

闪亮的应用程序是一个交互式网络界面。R shiny app 有两个组件用户界面对象(UI。r)和服务器功能(server。r)。这两个组件作为参数传递给创建闪亮 app 对象的闪亮 app 函数。更多关于如何构建闪亮应用的信息,请参考这个链接。R Shiny App 基础知识

步骤 1 : 创建一个 EC2 实例

登录 AWS 帐户,点击“计算”标题下的 EC2 或点击“最近访问的服务”下的 EC2

单击启动实例

选择你选择的机器镜像,这里我选择了 Ubuntu server 16.04 LTS (HVM)

选择实例类型;可以从 t2.micro、t2.small 或 t2.medium 实例开始。对于较大的应用程序,可以使用 t2.large 或更大的。

然后单击“启动实例”,您将转到下面的页面

单击编辑安全组,您将被定向到下面的页面(配置安全组)。

在 SSH 行中,将 source 更改为“我的 IP”

单击添加规则,将添加自定义 TCP 规则。在“端口范围”下输入 3838。这是 R shiny 服务器的端口。

单击“查看并启动”,然后单击“启动”。这样做后,你会看到一个如下的对话框。该对话框有助于创建一个私钥,这将使我们能够 ssh 到 EC2 实例。为密钥命名,然后单击“下载密钥对”。你会得到。pem 文件。保存了。pem 文件/密钥安全

按启动实例。您将看到如下屏幕

如果实例创建成功,实例状态将显示为“正在运行”

复制公共 DNS (IPv4)下的 IP 地址,这将是我们以后托管 R shiny 应用程序的 URL 的基础。

步骤 2:通过 SSH 从 Putty(基于 Windows)访问 EC2 实例

下载 putty,下载后,转换。pem 文件转换为 ppk 文件。

皈依。pem 文件保存到 ppk,请在 windows 开始对话框中键入 puttygen。点击“puttygen”。应该会出现下面的框。

单击文件选项卡,然后单击加载“私钥”。

导航到保存的文件夹或路径。pem 文件并选择它。的。pem 文件将被导入,您应该会看到如下画面。

现在将密钥保存为“保存私人密钥”,为密钥命名,并将其保存在您想要的位置。保存密钥后,应出现以下图标。

打开 putty,在主机名框中输入 EC2 实例的 IP,即一个相邻的 IPv4 公共 IP(54.148.189.55 ),如图 a 所示

接下来导航到左侧面板上的“Auth ”,并浏览您之前保存的 ppk 密钥。

浏览 ppk 密钥后,单击打开。如果您的密钥有效,您将会看到如下所示的命令提示符屏幕。输入您的登录凭据,然后按 Enter 键

步骤 3:安装 WinSCP,将文件从主机传输到 EC2 实例,反之亦然

在主机名框中输入 EC2 实例的 IP 地址。点击“高级”。

导航到左侧面板,在 SSH 下单击“Authentication ”,输入私钥,如下所示

输入私钥后,单击确定。你会看到下面的屏幕。点击“登录”。

你会看到一个如下的对话框。只需点击“是”。

最终结果将是下面的屏幕

步骤 4:在 EC2 实例中安装 R base 和 R shiny 服务器。

运行 R shiny app 的首要前提是安装 r base、shiny server、shiny package 以及关联包。

要安装上面的,第一步是去根目录安装它们。原因是如果你在 Ec2 中作为非根用户登录,你将有你自己的库路径,并且可能 R 包,r base,shiny 服务器可能不会在系统范围内安装。要在系统范围内安装它,请转到 root 并安装上面的

转到根目录的步骤:

在提示中键入以下内容

须藤一号

然后,您应该会看到一个#符号,如下所示

现在运行以下命令

sudo apt-get 更新

sudo apt-get 安装 r-base

sudo apt-get 安装 r-base-dev

下面的命令安装 R 闪亮包

sudo su—-c " R-e \ " install . packages(' shiny ',repos = ' http://cran . R studio . com/')\ " "

下面的命令安装闪亮服务器

wgethttps://download 3 . rstudio . org/Ubuntu-12.04/x86 _ 64/shiny-server-1 . 4 . 4 . 807-amd64 . deb

sudo dpkg-I shiny-server-1 . 4 . 4 . 807-amd64 . deb

第五步:转移 R 闪亮 app 组件

执行上述步骤后,将在路径/srv/shiny-server/中创建一个名为“shiny-server”的目录(文件夹)

下一步是在 shiny-server 目录中创建一个文件夹,我们可以在其中放置我们的 R shiny 应用程序组件(UI。r,服务器。R、配置文件、R 工作空间、数据文件或 R 程序)。

起初,我们可能无法在 shiny-server 文件夹中创建文件夹,首先执行以下命令

须藤 chmod 777 /srv/shiny-server

sudo mkdir/SRV/shiny-server/myapp

在上面的命令中,我创建了一个文件夹‘myapp’来放置所有的 R shiny 应用程序组件。

步骤 6:使用 Winscp 将 R shiny app 组件从本地机器转移到 Ec2 实例

现在将 R shiny app 组件从本地机器复制到 Ec2 实例,路径如下/srv/shiny-server/myapp/

需要考虑的一件重要事情是配置 shiny-server.conf

shiny-server.conf 可以在 /etc/shiny-server/ 中找到

同样,您可能无法访问/etc/下的 shiny-server 目录。

因此运行下面的命令

须藤 chmod 777 /etc/shiny-server

执行上述命令后,您可以将配置文件复制到本地系统,编辑它,然后将编辑后的配置文件传输回/etc/shiny-server 位置。

要制作的版本如下:请注意#后面的单词是注释。

下面的结果显示了在路径/srv/shiny-server/myapp 中复制的 shiny 组件

第七步:托管应用

现在是最后一步。在 amazon 控制台中,转到正在运行的 EC2 实例。复制公共 DNS (Ipv4),例如:ec2–34–215–115–68.us-west-2.compute.amazonaws.com

在浏览器中复制这个并像下面一样加上后缀 : 3838/myapp 然后按回车键。

你的 R shiny app 托管成功!!!!

需要考虑的重要注意事项:

复制 R 工作空间是很重要的,因为它将在创建的文件夹(即 myapp)中包含 R 对象和数据文件。在上面的例子中,我们使用了一个简单的闪亮的应用程序“hello world equivalent ”,因此我们没有任何 R 工作空间或数据文件。

有时,应用程序可能会因为某些原因无法加载,或者屏幕可能会“变灰”。请刷新并重试。

来源:

在 AWS 上运行 R

在亚马逊 EC2 上托管 shiny

闪亮的服务器故障排除

如果你喜欢我的文章,给它几个掌声。

你可以在 Linkedin 上联系我

如何使用搜索引擎优化和文本挖掘识别公共话语中的空白

原文:https://towardsdatascience.com/how-to-identify-gaps-in-public-discourse-using-seo-and-text-mining-f5e468f265da?source=collection_archive---------6-----------------------

搜索引擎优化(SEO)通常用于将内容推至谷歌搜索结果页面的顶部。然而,使用今天可用的数据以及文本分析和可视化技术,我们可以将 SEO 方法应用于更有趣的事情:发现公共话语中的差距。这些差距是人们寻找的东西和他们实际发现的东西之间的差异。一旦我们确定了这些差距,我们就可以制作相关的内容来弥补需求和供给之间的不足,无论是政治话语、利基市场还是科学研究。

我们提出的方法的核心是基于文本网络分析、可视化技术和文本挖掘的结合。

问题#1:当前话语的状态是什么?

第一步是确定目标和兴趣。例如,在我们之前的一项研究中,我们专注于“文本挖掘”这一主题。我们的目标是吸引在互联网上搜索这个主题的观众到我们研究实验室的网站, Nodus Labs ,为这些观众提供 InfraNodus 文本网络可视化工具。

我们使用 InfraNodus 来可视化“文本挖掘”的当前搜索结果——人们在谷歌上搜索时实际看到的内容。

Text network visualization of Google search results for “Text Mining” — what people actually find when they look for this search query, visualized using InfraNodus

我们发现,很明显,有一个占主导地位的主题集群
文本——挖掘——分析

以及其他主题集群如
流程—分析—大型

数据—非结构化—分析

模式—转折—有趣

这向我们表明,当人们在谷歌上搜索“文本挖掘”时,他们实际上找到的大多是对它的好处(识别非结构化数据中的模式)及其工作方式的一般性描述。

当然,为了获得更好的图片,建议查看几个不同的相关关键字,以便构建更好的表示。例如,在我们的例子中,我们可以添加“数据挖掘”、“文本分析”等。

问题 2:人们实际上在寻找什么?

一旦我们确定了当前话语的状态,我们现在就可以发现当人们想要进入话语时,他们实际上在寻找什么。这将有助于我们了解人们想要的和他们实际得到的之间是否有任何差异,因此我们可以在以后用新的内容、想法、产品或服务来针对这种差异。

为了做到这一点,我们可以使用谷歌关键词规划工具,它是 AdWords 平台的一部分。首先,我们需要看到与我们的搜索查询“文本挖掘”相关的搜索词列表。

这些包括“文本分析”、“情感分析”、“文本数据挖掘”等。然后我们可以将它们下载为 CSV 文件,在 Google Sheets 中打开,然后将表格中的关键字列复制并粘贴到 InfraNodus 中,以可视化主要术语及其之间联系的图表:

What people search for when they look for “text mining” — related queries from Google Keywords Tool visualized with InfraNodus

我们可以看到,“文本挖掘”和“数据分析”这两个词在人们搜索这个话题时使用的关键词列表中相当突出。这些都是不言而喻的,所以我们可以从图表中删除它们(和其他主题),看看当我们删除所有我们已经知道的主题时,还剩下哪些主题:

“Text mining” associated search queries with “text”, “analytics”, “analysis”, “data”, “mining” removed from the graph

我们现在可以看到,当人们搜索“文本挖掘”(和相关搜索)时,他们的搜索查询中有一个主题集群,由以下内容组成:

软件—工具—在线

这意味着人们寻找在线软件工具来进行文本挖掘,识别文本处理工具的内容和市场中的潜在缺口。

问题 3:人们寻找的和他们发现的有什么区别?

既然我们已经确定了人们在搜索“文本挖掘”时所寻找的特殊主题群,我们现在可以将其与谷歌搜索结果的文本图进行比较。为了做到这一点,我们可以使用结节下比较特征。它向我们展示了第二张图中的哪些术语(人们寻找的内容)没有出现在第一张图中(人们得到的搜索结果),并根据它们的重要性对它们进行了排序:

The black nodes on the graph are the terms that people look for (in relation to “text mining”) but don’t really find in Google search results — identifying a gap and, thus, a potential content / product / service opportunity.

这些术语是:
web —检索—应用—算法

正如我们所看到的,需要找到基于 web 的文本检索应用程序和各种可以在线使用的文本挖掘算法。

因此,如果我们要创建新的内容,它将是相关的,具有较低的竞争性,并满足某种需求,这是其他内容所不能满足的,我们就需要写与基于 web 的应用程序和算法相关的“文本挖掘”。这就是人们寻找却没有找到的东西。

此外,这也向我们展示了市场中一个潜在的有趣缺口,一个我们可以用新产品或服务来填补的缝隙。

当然,需要进行更彻底的研究,包括围绕“文本挖掘”的所有搜索词,但上面介绍的这个通用简化示例可用于研究任何公共话语,并根据受众的需求确定潜在的有趣领域,以增加话语的价值。

如果你想尝试这种方法,你可以在 www.infranodus.com 的上建立一个新账户。要导入谷歌搜索结果,请前往infranodus.com/google

如何用谷歌的自动增强功能改进你的图像分类器

原文:https://towardsdatascience.com/how-to-improve-your-image-classifier-with-googles-autoaugment-77643f0be0c9?source=collection_archive---------1-----------------------

通过使用优化的数据增强技术,获得了关于 CIFAR-10、CIFAR-100、SVHN 和 ImageNet 的最新结果。自己从这个 仓库 中使用它们。

Some of the best augmentations found for ImageNet. From https://arxiv.org/abs/1805.09501v1

AutoML——使用机器学习来改善机器学习设计选择,如架构或优化器的想法——已经达到了数据扩充的空间。这篇文章解释了什么是数据增强,Google 的自动增强如何搜索最佳增强策略,以及如何将这些策略转换为您自己的图像分类问题。

数据扩充

数据扩充意味着在训练机器学习模型时,对您的输入随机应用各种转换。随着新的可能的输入-输出对的生成,这人为地扩大了您的训练数据。这也有助于防止过度拟合,因为网络几乎不会两次看到完全相同的输入,也不能只记住它们。用于图像的典型数据扩充技术包括从输入图像中随机裁剪部分,水平翻转它们,并应用仿射变换,如平移、旋转或剪切。

From https://github.com/aleju/imgaug

事实上,正如 AutoAugment 的作者所指出的,近年来已经投入了大量的努力来为 ImageNet 寻找更好的网络架构,而 Krizhevsky 等人在 2012 年为 AlexNet 使用的数据增强技术仍然基本相同,只有微小的变化。

现状

选择使用哪种数据扩充的标准方法是提出不同的假设,说明哪种变换适合您的数据集,然后进行试验。你可以从随机裁剪或随机调整大小裁剪和水平翻转开始,因为它们几乎总是有效的,接下来可以尝试小的旋转。由于重复训练运行导致的验证性能的随机波动,很难确定这些添加的旋转是否提高了模型性能。你可以从一次运行到另一次运行得到随机的改进,这并不是因为增加了增强。

通常,因为你的实验是高度不明确的,你没有时间或资源来严格测试所有可能的组合,你会放弃整个搜索或坚持一些增强,而不知道它们是否有很大贡献。但是,如果有一种方法可以转移有益的数据增强技术,就像我们在迁移学习中从预训练模型转移权重一样,会怎么样呢?

从数据中学习增强策略

自动增强的想法是在强化学习(RL)的帮助下,学习给定数据集的最佳增强策略。因为在图像上应用和组合变换的所有可能方式的搜索空间是巨大的,他们用几个设计选择来限制它。一个策略由 5 个子策略组成,每个子策略按顺序应用 2 个映像操作。这些图像操作中的每一个都有两个参数:应用它的概率和操作的幅度(例如,在 70%的情况下旋转 30 度)。

这种策略如何应用于训练时的图像?对于我们当前批次中的每个图像,首先随机统一选择一个子策略,然后应用该子策略。让我们来看一个应用于来自 SVHN 数据集的图像的具有 5 个子策略的示例策略:

子策略 1 在 90%的情况下在任一 x 方向上剪切幅度为 7 的图像。然后,以 20%的概率,图像的颜色被反转。子策略 4 在 90%的情况下反转颜色,然后在 10 次中均衡颜色直方图 6。操作的幅度是固定的,但是由于子策略应用的随机性和操作的概率,对于单个图像有许多可能的增强结果。

Example of applying some of the best found augmentations to an SVHN image. From https://arxiv.org/abs/1805.09501v1

让我们看看 AutoAugment 的 RL 模型的搜索空间。他们考虑了 16 种操作:14 种来自 Python 图像库 PIL 的操作,如旋转、颜色反转和不太为人所知的操作,如色调分离(减少像素位)和曝光(反转阈值以上的颜色),加上数据增强领域的新来者剪切和样本配对(类似于混合)。将 11 个离散化的概率值(0.0,0.1,…,1)和 10 个从 0 到 9 的均匀间隔的量值相加,这对于一个子策略来说等于(16 * 11 * 10)个可能性,对于 5 个子策略来说等于(16 * 11 * 10)个⁰ ≈ 2.9 * 10 个可能性。强化学习拯救世界!

自动增强是如何训练的?

自动增强像 NASNet 一样被训练——这是谷歌的一篇早期 AutoML 论文,其中 RL 系统为图像分类找到了最先进的模型架构。方法如下:我们有一个控制器,它决定目前哪种数据扩充策略看起来最好,并通过在特定数据集的小子集上运行子模型实验来测试该策略的泛化能力。在子实验完成后,使用称为近似策略优化算法(PPO) 的策略梯度方法,用验证准确度作为奖励信号来更新控制器。让我们更详细地看看控制器和子模型实验,因为解释 PPO 超出了本文的范围。

控制器

控制器以 softmax 的形式输出要应用哪个操作的决定。这个决定然后作为输入输入到控制器的下一步。这是可行的,因为控制器是 RNN(对于 NASNet,使用了具有 100 个隐藏单元的 LSTM)。然后,控制器决定以何种幅度应用该操作。在第三步中,选择概率。因此,为了做出下一个最好的选择,控制者拥有所有其他操作的上下文、概率和大小。(这是一个说明性的例子,因为该论文目前没有告诉我们以什么顺序选择运算、大小和概率)。

Illustrative controller model architecture. Adapted from https://arxiv.org/abs/1707.07012

总共有 30 个 softmax 预测,因为有 5 个子策略,并且每个子策略需要关于操作、幅度和概率的两个决策(5 * 2 * 3 = 30 ),用于其顺序应用的两个操作。

子模型

我们如何告诉控制器哪些策略选择得非常好,哪些策略没有真正提高性能(想象一下将亮度设置为零)?为此,我们对使用当前数据扩充策略的子神经网络进行了一个泛化实验。实验结束后,RNN 控制器的权值以验证精度作为奖励信号进行更新。当最终将总体最佳的 5 个策略(每个策略有 5 个子策略)合并到最终策略(现在有 25 个子策略)中时,这样做 15,000 次。该最终策略用于该数据集的所有结果。

结果

由于副标题已经泄露,自动增强改善了数据集的最先进水平,如 CIFAR-10 、 CIFAR-100 、 SVHN 、 ImageNet 等。此外,还有一些特别有趣的细节:

  • CIFAR-10 和 ImageNet 的最佳策略主要是基于颜色的转换。对于 SVHN,与 CIFAR-10 相比,AutoAugment 选择了非常不同的转换:剪切图像和反转颜色,这对门牌号有意义。

Test set error rates (%) on CIFAR-10. Lower is better. From https://arxiv.org/abs/1805.09501v1

Validation set Top-1 / Top-5 error rates (%) on ImageNet. Lower is better. From https://arxiv.org/abs/1805.09501v1

  • 在数据较少的情况下,使用自动增强功能可以更好地改善结果。这是数据增强技术的预期行为,但值得注意。
  • 在 CIFAR-10 上发现的最佳数据增强策略转化为在 CIFAR-100 上的实质性改进,从 12.19%的错误率降低到 10.67%。

Test set error rates (%) on CIFAR-100. From https://arxiv.org/abs/1805.09501v1

  • 将在 ImageNet 上找到的最终策略应用于 5 个不同的困难数据集显著提高了准确性。这是数据增强而非权重的迁移学习。这些结果是在从头开始训练 Inception v4 而不是从 ImageNet 微调权重时获得的。

Test set Top-1 error rates (%) on FGVC datasets. An Inception v4 was trained from scratch with an without applying the best ImageNet augmentation policy. From https://arxiv.org/abs/1805.09501v1

双转移学习

如果我们想解决我们自己的图像分类问题,我们通常从使用 ImageNet 的预训练权重开始,并根据我们的问题对这些权重进行微调。我们刚刚看到,在从头开始训练时使用 AutoAugment 的最佳 ImageNet 策略也有类似的积极效果。如果我们双管齐下:在使用 ImageNet 自动增强策略的同时微调 ImageNet 权重,会怎么样?积极的效果会累积起来,并为我们提供解决任何新的图像分类问题的新的最佳方法吗?

为了回答这个问题,我使用了相同的 5 个 FGVC 数据集(牛津 102 Flowers,加州理工学院 101,牛津-IIIT Pets,FGVC Aircraft 和 Stanford Cars),并在应用或不应用来自 AutoAugment 的 ImageNet 策略的情况下对盗梦空间 v4 进行了微调。

实验设定

  • 初始 v4 在一个 GPU 上训练,批量为 32,SGD 动量为 0.9,学习速率为 0.01。
  • 如果验证准确性在 5 个时期内没有增加,则将学习率除以 2。在 3*5=15 个阶段的验证准确度无改善后,停止培训。
  • 本报告使用了提供的经过预先培训的 ImageNet 权重。仅交换顶部的输出层,以说明不同类别的数据集。所有层从开始都是可以训练的。
  • 输入图像大小为 448x448,如自动调整纸上所示。
  • 两种微调场景都使用随机水平翻转和随机调整大小裁剪作为基线数据增强。随机调整大小裁剪的最小裁剪百分比是根据较小 ResNet18 模型的验证集性能选择的。
  • 在随机调整大小裁剪之后,将应用 ImageNet 自动调整策略。实验表明,无论是在种植前还是种植后应用,这似乎都无关紧要。
  • 利用这些选定的超参数,最终模型在训练和验证集的组合上训练,并在测试集上测试。为了确保稳定的结果,以这种方式训练了五个模型,并对测试结果进行了平均。

Test set Top-1 error rates (%) on FGVC datasets averaged over five runs. An Inception v4 was fine-tuned from ImageNet weights with and without the AutoAugment ImageNet policy. Interestingly, fine-tuned results are better on only 3 out of 5 datasets in comparison to the results trained from scratch from the AutoAugment paper above. Fine-tuning does not seem to benefit the performance in all cases as also discussed in “Do Better ImageNet Models Transfer Better (Kornblith et al. 2018)” https://arxiv.org/abs/1805.08974

对不同数据集应用最佳 ImageNet 策略可使 5 个数据集中的 3 个数据集的错误率平均降低 18.7% 。在 2 个数据集上,错误率略微增加,平均为 5.3%。

这些结果表明,当您通常需要微调 ImageNet 的权重时,您应该尝试额外应用 ImageNet 自动调整策略。通常情况下,您基本上可以免费获得显著的改进。

如何对您的问题应用自动建议策略

我已经创建了一个存储库,其中包含了本文附录中的最佳 ImageNet、CIFS-10 和 SVHN 策略。一些实施细节仍不清楚,但我正在与作者联系,一旦我知道更多,将尽快更新回购协议。

使用此基本语法,ImageNet 策略的随机子策略将应用于 PIL 映像:

要将其应用为 PyTorch 转换,您将执行以下操作:

结论

AutoML 再次做到了这一点:给定数据集的最佳数据扩充操作是可以学习的,甚至可以转移到类似的数据集。这可能只是即将到来的许多 AutoML 优化数据增强策略中的第一个。提高学习这些策略的效率是另一个令人兴奋的途径,以使任何人都能够使用这些技术(无需 GPU 服务器群)。ENAS 表明这是可能的。

祝你好运,把这个新工具应用到你自己的问题中。让我知道你的结果,如果他们同意或不同意我的实验。关于错误和问题,请发电子邮件到 philip@popien.net 给我。