如何成为一名数据科学家?
简介:
我很确定我们中的许多人都在 2012 年看过《哈佛商业评论》的这篇文章。数据科学家是被称为 21 世纪最性感的职业。此外,麦肯锡全球研究所早在 2013 年进行的研究预测,到 2018 年,北美将分别有大约 425,000 和 475,000 个空缺的数据分析职位。这里要传达的信息是,所有行业都将需要源源不断的分析人才,公司在这些行业收集和使用数据以获得竞争优势。
到底什么是数据科学家?
在一个过于简化的描述中,数据科学家是能够处理大量数据并提取分析见解的专业人士。他们向利益相关者(即高层领导、管理层和客户)传达他们的发现。因此,公司可以受益于做出最明智的决策来推动其业务增长和盈利能力(即,取决于行业环境)。
为什么成为数据科学家这么难?
数据科学的本质是许多学科的混合。由不同的学科领域组成,如数学(如统计学、微积分等。)、数据库管理、数据可视化、编程/软件工程、领域知识等。在我看来,这可能是有意跳入入门级数据科学职业的人常常感到完全迷失的首要原因。大多数人不知道从哪里开始,因为你可能在一个领域完全缺乏,或者多个领域取决于一个人的教育背景和工作经验。
不过,好消息是,你不需要对此过于担心。这些天来,我们面对一个完全相反的问题。有太多的资源可供选择。所以,你不一定知道哪一个最适合你。在本文中,我将从三个角度重点介绍如何成为一名数据科学家。
第一节:从哪里学习数据科学?
Figure 1. Data Science Education Path and Job Placement Rate
先从哪里学数据科学开始吧。从海量开放在线课程(MOOC)、大学学位/证书和新兵训练营培训中获得数据科学教育有三大途径。
下面是一个示例图,展示了每个选项的预计时间承诺与工作安排成功率。这提供了一个想法,即训练营教育可以让你比其他两种选择更快地获得数据科学家的工作。
下面是一个汇总表,提供了有关每个教育途径的更多详细信息。基本上,每个选项在成本、灵活性和项目长度方面都有优点和缺点。然而,做出正确决定的最佳建议是问问自己什么对你来说最重要。比如,你有充裕的时间,想把投资成本降到最低。或者你可能是一个想尽快找到工作的人,即使最初的投资成本很高。
Table 1. Breakdown Analysis of Data Science Learning Path Comparison
第二节:学什么数据科学?
作为一名数据科学家,肯定有很多东西要学。让我们从五个主要步骤开始了解数据科学教育途径。
Figure 2. Data Science Learning Pathways
第一步,补上与统计、微积分和线性代数相关的基础数学是一个好的开始。作为一名数据科学家,这对于理解不同算法背后的机制至关重要。它建立了关于如何调整或修改算法以解决独特业务问题的直觉。此外,了解统计数据有助于您将实验性设计测试(即 A/B 测试)中的发现转化为关键业务指标。
第二步,数据科学家必须熟悉在各种环境中处理数据的工具集。工具集包含 SQL、命令行、编码和云工具的组合。这里总结了每种工具的使用方法。对于从关系数据库中提取和操作数据,SQL 是几乎在任何地方使用的基本语言。用于一般编程目的(即函数、循环、迭代等)。),Python 是一个不错的选择,因为它已经打包了许多库(例如,可视化、机器学习等)。).对于额外的提升,了解命令行提供了额外的好处,特别是对于在云环境中运行作业。
第 3 步,这是学习一些语言来构建数据科学基础的最佳时机。对于商业软件,你可以选择 SAS 或者 SPSS。从开源平台,很多人要么选择 R,要么选择 Python。从这里,您可以了解有关数据管理/争论的概念(即,导入数据、聚合、透视数据和缺失值处理)。在此之后,您将从数据可视化(即,条形图、直方图、饼图、热图和地图可视化)中获得最有趣的数据。
第四步,你可以选择应用机器学习或大数据生态系统途径。请注意,你可以随时回来掌握另一条道路。就我而言,我选择先学习应用机器学习。基本上,它涵盖了从端到端建立机器学习模型的方面(即,从数据探索到模型部署)。为了了解大数据,我将更多地介绍从哪里获得这种教育(即书籍和课程)。
第五步,这是展示你作为数据科学家候选人潜力的最关键的一步。一旦你熟悉了数据科学,你必须有一个项目组合。项目组合是你展示你从学习和工作经历中所做的最好机会。从数据收集开始(即,你自己在哪里挑选或收集数据),提出你的假设,进行探索性分析(即,提取一些有趣的见解),建立你的机器学习模型,最后分享你在写作或演示中的发现。就我而言,我通过与指定的导师一起完成顶点项目,完成了一篇报道和一个视频播客。对于拥有一个可以直接与你一对一合作的导师的重要性,我怎么强调都不为过。当你陷入一些项目想法、调整你的模型、交流你的结果等时,你的导师是指导你并寻求帮助的最好朋友。事实上,一些研究提到,有一个导师可以比没有导师的人多五倍地促进你的职业发展。
第三节:如何学习数据科学?
在本节中,您将学习如何挑选成为数据科学家的最佳资源。我想根据我的学习经验提出建议。
Figure 3. Suggested Resource on Learning Data Science Education
对于 SQL 教育来说,微软从 Edx 提供的 DAT201x 课程是最好的选择之一。本课程从数据类型、筛选、连接、聚合(分组)、窗口函数和高级概念(如存储过程)等方面介绍了 SQL 的以下内容。本课程确保您通过使用最佳样本数据仓库(即 AdventureWorks)进行大量练习。或者,您可以使用模式分析平台来练习和增强您的 SQL 技能。模式分析最大的好处是,您不需要在机器上安装 SQL server 和示例数据仓库。你所需要的是有一个免费的帐户和互联网连接来享受你的学习。
对于机器学习教育,我喜欢推荐两个选项。第一个课程是该领域的任何数据科学从业者都熟知的。吴恩达的机器学习课程来自 Coursera。我用这个课程来理解如何调整我的机器学习模型的基本概念和技巧。从编码体验的角度来看,我强烈推荐塞巴斯蒂安·拉什卡的《Python 机器学习第二版》。我真的觉得这是最好的机器学习书。这本书从每个算法的基本机制、大量的编码示例和补充参考资料(即研究文章)来帮助你理解。这本书最棒的一点是,他一行一行地详细解释了如何实现每个机器学习算法。正如许多数据科学家提到的,这非常重要,人们应该能够从头开始编写代码,并知道如何实现它。如今,有许多复杂的问题无法通过使用 Python 现有的库直接解决。
这里是一个完整的资源列表,您可以参考这些资源来学习数据科学教育的每个组成部分。
1。数学:
可汗学院数学赛道
麻省理工学院开放课件:线性代数与微积分
Udacity:介绍和推断统计学
2。数据科学工具包:
结构化查询语言
o Edx: DAT201x —使用 Transact SQL 进行查询(*)
o 模式分析:SQL 教程(高级入门)
o WiseOwl: SQL 教程(高级入门)(*)
命令行
o Book:命令行中的数据科学
Python 编码
o Udemy:完整的 Python 训练营
o 书:艰难地学习 Python(第三版)
o Book:用 Python 自动化枯燥的东西
3。机器学习:
Coursera:吴恩达的机器学习(*)
Coursera:应用机器学习(密歇根大学)
哈佛:CS109 —数据科学简介(*)
书:Python 机器学习(第二版)Sebastian Raschka (*)
书:Python 机器学习示例
书:Python 机器学习入门
4。大数据:
Hadoop
o 图书:Hadoop 权威指南
o uda city:Hadoop 和 MapReduce 简介
o IBM: Hadoop 基础知识学习徽章
火花
o Edx:加州大学伯克利分校星火课程(CS105,CS120)
o data camp:PySpark 简介,在 PySpark 中构建推荐引擎
o 图书:学习 PySpark,使用 Spark 进行高级分析
奖励部分:寻求帮助和建立关系网
现在,我想通过提供一些额外的技巧来结束这篇文章。一开始,作为一个新手数据科学爱好者,你不一定有一个可以指导你学习经验的导师。因此,您需要一个向数据科学社区征求意见和反馈的地方。好消息是,有几个论坛你可以寻求帮助来解决你的问题。少数网站如 StackOverflow、Quora 等。让您发布您的问题,并收到对您帖子的回复。
另一个提示与网络有关。这真的适用于任何真正寻找新机会和建立联系的人。在多伦多,有许多与数据科学相关的本地聚会和大型会议。尽量多参加活动,介绍自己(即动机、目标、激情)。此外,如果你有机会接触演讲者和活动组织者,努力与他们建立有意义的联系。我认为我从经验中学到的一个有用的策略是寻找机会在任何可用的媒体上展示我的项目组合。我指的是在本地会议上发表演讲的机会,甚至是通过远程数据科学办公时间进行的视频网络广播。从这次经历中,我能够从我愚蠢的错误中学习,并从一个演示文稿到另一个演示文稿做出改进。这为数据科学家候选人带来了很多价值,可以提供有效的演示,并能够清晰地传达分析见解。
感谢阅读这篇文章。随着我在成为数据科学家的旅程中获得更多经验,我希望带来更多令人愉快和丰富的信息。
如何在 2020 年成为伟大的数据科学家
给新的一年开个好头的 5 个新年决心
Photo by Alex Radelich on Unsplash
明年是你的一年。
明年的这个时候,当你回首往事时,你会惊讶地发现自己作为一名数据科学家成长了这么多。我不怀疑。你也不应该。
然而,要做到这一点,需要努力和奉献。为了给你一个好的开始,我想讨论 5 个新年决心来帮助你进入下一个阶段。
每天学习
对你来说,明年是成长的一年。承诺每天至少花 30 分钟学习。
学习可以采取任何你想要的形式。可能是读一本书,开始一门新的在线课程,去一个聚会,或者开一个博客。如果你需要一些好书的想法,看看这个帖子:
建立一个伟大的知识基础
towardsdatascience.com](/the-top-3-books-to-get-started-with-data-science-right-now-3f9945d78011)
为了这个目标,不要过度思考学什么,开始学就好。从我的经验来看,几乎所有的数据科学家都受到学习的激励,但我发现我们经常会花太多时间来考虑要学习什么。我们想选择最好的科目,所以我们不花时间学习,而是花时间思考学习。
这并不是说你不应该花时间去思考你想学什么,而是一旦你有了想法,就去实现它。也许你一直想了解更多关于强化学习的知识。去做吧!你最初几天的学习可能只是发现强化学习的最佳资源。然后你就可以开始挖了。
另外,不要忘记这是你学习的时间。如果你害怕这个时候,那么你需要改变它。选择一个不同的主题,寻找另一种学习方法,或者找一个朋友参与进来。关键是找到一种坚持每天花时间学习的方法。如果你能做到这一点,当你回顾 2020 年时,你会发现这是巨大增长的一年。
成为主人
无论你的角色是什么,在 2020 年,人们都会将你视为如何为公司创造重大价值的榜样。除了“按现状”接受一个项目并检查向您提出的问题之外,您还可以通过询问以下问题来培养一种主人翁精神:
- 这个项目如何使公司更接近其目标?
- 我是否理解了项目的愿景,因此我能够创造性地思考潜在的解决方案?
- 我如何主动确保该项目交付价值?即使其中一些项目不属于我的“工作描述”
你还可以问很多其他问题,但这 3 个问题应该是将你的思维模式从任务执行者转变为价值传递者的良好开端。你会惊讶地发现这会给你的工作带来多大的变化。它会促使你成为一个更好的合作者,学习新的技能,跳出框框思考,因为你的工作只有在提供价值后才算完成。
我发现这种技能对数据科学家来说尤其重要,因为数据通常跨越公司的很大一部分。这通常意味着,作为一名数据科学家,你必须在公司的很多部门工作,以确保你的工作能够带来价值。如果你能掌握这项技能,你将变得无价。
从简单开始
在 2020 年,你不会为了炒作而被最新最伟大的炒作所吸引。当然,有复杂的模型可以产生惊人的结果,但是当开始一个项目时,你会问自己:
我如何在一天内建立我的第一个模型
如果你需要一些帮助,看看这篇文章:
在任何项目中度过前 8 个小时的最佳方式
towardsdatascience.com](/my-potent-first-day-routine-for-phenomenal-success-on-your-next-data-science-project-c96874f4bf16)
在一天内建立你的第一个模型将迫使你专注于保持简单,只解决最关键的问题。你的模型很可能很糟糕,但是你现在有了一个可以建立的基线。增加复杂性要比消除复杂性容易得多。作为一名数据科学家,遵循这条简单的规则将会促使你忽略无关紧要的事情,专注于你需要解决的核心问题。
失败更多
俗话说:“你在失败中学到的比成功更多。”我 100%相信这是你自作聪明。仅仅失败并不意味着你学习或成长。失败,然后花时间去理解为什么,并设定改进目标,可以帮助你显著成长。
今年,你将设定一个目标:比任何人都更擅长失败。
你设定的目标会将你推向极限,也会导致一些失败。当你失败时,你会花时间去成长。
例如,也许你设定了一个目标,用一种你从未使用过的机器学习模型来传递价值。这可能是强化学习或概率深度学习之类的东西。这种类型的目标会把你推出舒适区,迫使你成长。
不过,要小心,你要适当地失败。在时间敏感的关键任务项目上冒大风险不是一个好主意。不过,在第三产业项目中,同样的目标可能很有意义。这个目标很好地补充了“从简单开始”的目标,因为它确保你继续推进你的极限。否则,可能会有真正有价值的算法或技术你没有利用,因为你从来没有分支。
恢复
最后,在 2020 年,定一个目标,回馈他人。找时间指导、教导、引导或帮助他人成长。下次初级数据科学家在 LinkedIn 上寻求建议时,请回复并尝试提供帮助。亚当·格兰特很好地证明了作为一名给予者的价值,我完全同意。不仅帮助了别人,也帮助了你。
我确信,无论你的经验或技能水平如何,你都可以找到帮助他人的方法。你只需要看看。
我希望我的 5 个新年决心将帮助你正确地开始新的一年,并让你回顾 2020 年,这是成长、学习和成功的重要一年。
这篇文章也可以在这里找到。
加入我的 邮箱 列表保持联系。
如何成为人工智能驱动的公司
人工智能正在以前所未有的速度改变我们做生意的方式,但过渡到人工智能驱动比你想象的要容易。现在是投资并保持在游戏顶端的时候了。
几周前,随着被广泛称为计算界“诺贝尔奖”的今年图灵奖获奖者的公布,人工智能成为人们关注的焦点。约舒阿·本吉奥、杰弗里·辛顿和扬·勒昆因他们 30 多年来在人工智能领域的开创性工作而受到表彰。在 80 年代,当人工智能研究非常不流行时,三人组的动机是创造可以像大脑一样运行的算法,至少在隐喻的层面上。大脑中的神经元作为一个整体工作,一起学习它们观察到的输入的内部表示,这些研究人员认为他们的人工神经网络也可以做到这一点。30 多年后,他们的联合研究导致了计算机视觉、自然语言处理和机器人技术的革命性进步,形成了一系列令人印象深刻的新技术,其中许多我们在零售决策平台编辑中使用。
人工智能与工业
值得注意的是,这项工作是在考虑工业应用而不仅仅是学术应用的情况下完成的。Hinton 目前是谷歌的副总裁兼工程研究员,LeCun 是脸书的副总裁兼首席人工智能科学家。事实上,LeCun 的突破性工作训练 CNN 通过手写数字的图像来阅读银行支票——据估计,他的系统在 20 世纪 90 年代末和 21 世纪初阅读了美国所有支票的 10%以上。人工智能在工业上有着丰富的遗产,有着无数的实际应用。尽管很难忽视它更引人注目的用例——亚马逊的仓库机器人,或特斯拉的自动驾驶汽车——但可以说人工智能最有影响力的成功故事是在消费技术领域。人工智能为翻译引擎、推荐系统、图像分类和预测提供了动力——所有这些我们都在 EDITED 使用——更重要的是,支持它们的规模潜力。研究员吴恩达有一句格言,“如果一个典型的人可以用不到一秒钟的思考来完成一项脑力任务,我们很可能现在或在不久的将来用人工智能来自动化它”。这提供了一种有用的方法来识别领域中的 AI 应用。
人工智能驱动意味着数据驱动
更便宜的计算和大量数据的结合是人工智能进步不可或缺的一部分,它将导致公司现在引入人工智能的成功。到 2020 年——基于云的平台提供商 Domo 的年度信息图——估计地球上每个人每秒将产生 1.7 MB 的数据。利用数据对人工智能的成功至关重要,幸运的是它被大量创造出来。其中大部分是由大公司收获的,很难利用。因此,重要的是首先确定您需要的数据范围,无论这些数据是以客户为中心的还是与产品相关的,包括背后的道德考量。在 EDITED,我们既利用产品数据推动公司发展,也利用用户数据让我们深入了解客户。我们使用爬虫和人工智能来获取在线服装行业提供的商业数据,并将其转化为用户可以触摸到的东西。这创造了世界上最大的实时零售数据来源。然后,我们能够通过用户交互了解我们功能的成功之处,并根据数据对新功能做出决策。
扩展和升级
人工智能技术在大规模提供可操作的见解时最有用,但开发可持续和可扩展的基础设施可能具有挑战性。在 EDITED,我们努力成倍增加我们的抓取,并为每个产品增加更多的智能,同时保持其准确性。随着全球各地机构中机器学习和人工智能学位的兴起,越来越多的人才库已经出现。将此与广泛的在线和基于课程的资源相结合,以提升您当前劳动力的技能,实施量身定制的人工智能解决方案现在对许多组织来说是可以实现的。
对于更不喜欢人工智能的人来说,有几个机器学习平台需要很少的领域知识来执行。然而,最好的数据驱动型决策来自数据科学家和工程师团队,他们了解技术以及如何利用技术推动改进。更好的办法是与数据科学、产品管理和领导力共同努力,评估人工智能可以改善价值链的机会,以及实施的适当时间表。
勇敢点
为了让人工智能取得成功,实验文化需要成为标准,并始终强调提高劳动力的技能。当本吉奥、辛顿和勒村开始他们在人工智能方面的关键工作时,文化停滞不前,投资也很低。他们的研究花了几十年才见成果。重要的是,我们要意识到人工智能的潜力,以及反复投资和学习的必要性。在 EDITED,我们不断将新技术和能力引入我们的数据科学团队。我们鼓励其他人致力于新的人工智能应用并促进知识共享,同时通过管理用户和公司对如何利用人工智能的期望来避免投资减少。At EDITED 的基本价值观是“勇敢”,这是我们人工智能成功的关键。人工智能已经证明了它在工业中的价值,所以如果你还没有做出改变,你可能会发现你的竞争对手已经这样做了。
如何成为更有市场的数据科学家
这个标题对你来说可能有点奇怪。毕竟,如果你是 2019 年的数据科学家,你已经有市场。由于数据科学对当今的企业有着巨大的影响,对 DS 专家的需求也在增长。在我写这篇文章的时候,仅 LinkedIn 上就有 144,527 个数据科学职位。
但是,重要的是要把握行业脉搏,了解最快、最有效的数据科学解决方案。为了帮助你,我们痴迷于数据的简历编译器团队分析了一些空缺职位,并定义了 2019 年数据科学就业趋势。
2019 年最受欢迎的数据科学技能
下图显示了 2019 年雇主对数据科学工程师的技能要求:
为了进行这项分析,我们查看了 StackOverflow、AngelList 和类似网站的 300 个数据科学职位空缺。一些术语可能在一个职务列表中重复多次。
**注意:**记住,这项研究代表了雇主的偏好,而不是数据科学工程师本身。
关键要点和数据科学趋势
显然,数据科学更多的是关于基础知识,而不是框架和库,然而仍然有一些趋势和技术值得注意。
大数据
根据 2018 年大数据分析市场研究,企业对大数据的采用率从 2015 年的 17%飙升至 2018 年的 59%。因此,大数据工具也越来越受欢迎。如果不把 Apache Spark 和 Hadoop 考虑在内,(下一节我们会详细讲后者),最受欢迎的是 MapReduce (36),和 Redshift (29)。
Hadoop
尽管 Spark 和云存储很受欢迎,Hadoop的“时代”还没有结束。因此,一些雇主仍然希望应聘者熟悉 Apache Pig (30)、 HBase (32)以及类似的技术。HDFS(20 岁)仍然在空缺职位中被提及。
实时数据处理
随着各种传感器、移动设备和物联网 (18)的使用越来越多,公司正致力于从实时数据处理中获得更多见解。因此,像 Apache Flink 这样的流分析平台在一些雇主中很受欢迎。
特征工程和超参数调整
准备数据和选择模型参数是任何数据科学家工作的关键部分。数据挖掘这个术语在雇主中非常流行。一些雇主也非常重视超参数调优 (21)。但是,作为数据科学家,你需要先关注特征工程 。为模型选择最佳特征至关重要,因为它们决定了模型在创建的最初阶段能否成功。
数据可视化
处理数据并从中提取有价值的见解的能力至关重要。然而,数据可视化 (55)对于任何数据科学家来说都是一项同样重要的技能。重要的是,你可以用一种任何团队成员或客户都能理解的格式来表示你的工作成果。至于数据可视化工具,雇主更喜欢 Tableau (54)。
总体趋势
在空缺中,我们遇到了AWS(86)Docker(36)Kubernetes(24)这样的术语。因此,软件开发行业的一般趋势也适用于数据科学领域。
专家怎么说
该评级中的技术不相上下。然而,在数据科学中,有些东西和编码一样重要。它是从“数据输出”中收集见解的能力,如最终数据集和趋势、可视化以及用这些数据讲述故事。此外,它是以一种可以理解的方式展示发现的能力。了解你的听众——如果他们是博士,以适当的方式与他们交谈,但是如果他们是 C 语言的,他们不会关心编程——只关心结果和投资回报率。
快照数据有助于了解市场的当前状态,但并不代表趋势,因此很难仅根据快照来规划未来。我想说,R 的使用将继续稳步下降(MATLAB 也是如此),而 Python 在数据科学家中的受欢迎程度将继续上升。Hadoop 和大数据上榜是因为行业有一些惯性:Hadoop 会消失(再也没有人认真投资它)大数据不再是热门趋势。人们是否必须投入时间学习 Scala 还不清楚:Google 官方支持 Kotlin(也是一种 JVM 语言),学习起来更简单,而 Scala 的学习曲线很陡。我也对 TensorFlow 的未来持怀疑态度:学术界已经转向 PyTorch,与其他行业相比,学术界在数据科学领域的影响力最大。(这些观点是我的,可能不代表 Gartner 的观点。)
Gartner 机器学习总监,
百页机器学习著作的作者 。
LinkedIn
PyTorch 是用 GPU 对 CUDA 张量进行数学运算的强化学习的驱动力。它也是一个更强大的框架,可以同时在多个 GPU 上并行化代码,而不像 TensorFlow 需要将每个操作打包到一个设备上。PyTorch 还构建了对递归神经网络有效的动态图。基于 ano 的 TensorFlow 生成静态图表,与基于 Torch 的 PyTorch 相比,学习起来更复杂。张量流反映了更大的开发人员和研究人员社区。PyTorch 在构建 TensorBoard 等机器学习仪表盘可视化工具时,将表现出更大的势头。PyTorch 用 matplotlib 和 seaborn 在调试和数据可视化库方面更 Pythonic 化。Python 的大多数调试工具也可以用来调试 PyTorch。TensorFlow 自带调试工具 tfdbg。
Ganapathi puli paka 博士,
埃森哲首席数据科学家,
50 大技术领袖奖获得者。
LinkedIn|Twitter**
我认为数据科学的“工作”不同于数据科学的“职业”工作列表提供了对市场现在需要的特定技能的洞察,但对于职业来说,我见过的最重要的技能之一是学习能力。数据科学是一个快速发展的领域,如果你想取得长期的成功,你需要能够轻松地掌握新的技术、工具和领域知识。通过挑战自己来做到这一点,避免过于舒适。
【隆·里斯伯格】 数据药剂 前 NASA 创始人/策展人。 推特 | 领英
数据科学是一个快速发展的复杂行业,一般知识和特定技术的经验同样重要。希望这篇文章能帮助你获得宝贵的见解,了解你需要哪些技能才能在 2019 年保持市场竞争力。祝你好运!
本文由 CV 编译器 团队为您带来——一款面向数据科学家、机器学习工程师和其他 IT 专业人士的在线简历增强工具。
如何在 Kaggle 上开始比赛
你刚刚完成了你的第一门机器学习课程,但你不知道从哪里开始应用你的新知识。你可以从玩 Iris 数据集或梳理泰坦尼克号记录开始(这可能是你应该做的第一件事)。但是有什么比直接跳进来和网上的陌生人竞争金钱更有趣的呢?
如果你正在阅读这篇文章,你可能已经知道 Kaggle 是一个数据科学竞赛平台,爱好者使用结构化(表格格式的数字和/或分类数据)和非结构化数据(例如,文本/图像/音频)在一系列机器学习主题中进行竞赛,目的是获得奖金和令人垂涎的 Kaggle 金牌。虽然你可能会发现与他人竞争的想法令人生畏,但重要的是要记住,目标永远是尽可能多地学习,而不是专注于结果。通过这种心态,你会发现竞争变得有趣,有益,甚至上瘾。
选择比赛的第一步
找一个你感兴趣的比赛。
这是开始新比赛时要考虑的最重要的事情。你想给自己大约两个月的时间来梳理一个问题,并真正熟悉数据的来龙去脉。这是相当多的时间。选择一个你不感兴趣的比赛会让你变得不感兴趣,放弃几周的时间。在时间线的早期加入还会让您有更多的时间来获取背景知识,并在您与社区的其他成员一起处理问题的各个阶段时提高您的学习质量。
专注学习
如果你发现自己对一场比赛感到沮丧,认为它太难了,那就专注于尽可能多的学习,然后继续前进。通过这种方式,你可以通过接触这些材料学到更多。当你不再担心自己在排行榜上的位置时,你甚至会发现自己取得了突破!
努力理解最高得分内核的每一行
问问自己,是否有一些明显的方法可以改进他们的工作。例如,有没有一个你可以创造的新颖的功能可以提高他们模型的分数?你能稍微调整一下他们用来提高性能的学习速度吗?追求唾手可得的果实,不要试图多此一举。这种心态将大大加快你的学习,同时确保你不会发现自己变得沮丧。
查看规则中是否有奇怪的规定
这一个没有其他的重要,但仍然值得一提。最近的一次竞赛中有一条规则规定如下:
[您的提交内容]不包含机密信息或商业秘密,并且不是注册专利或未决专利申请的主题
一名用户在论坛上表示,这项规定将使退学成为非法,因为这是谷歌的专利技术!
内核和讨论
在比赛过程中应该定期检查内核和讨论标签
首先查看一些 EDA(探索性数据分析?,探索性数据分析的?探索性数据分析?)和衡量你对领域和主题的兴趣程度。当你浏览其他人的作品时,在数据的合适模型类型、特征工程等方面,想想你想到的任何新颖的想法。
讨论标签中的“欢迎”帖子提供了很好的背景阅读
获得竞争领域的领域知识不会有什么坏处。这有助于深入了解模型的执行情况,并极大地有助于特征工程。我通常会在比赛开始时花一两周时间尽可能多地阅读,以了解问题空间。为了有助于这一点,大多数竞赛组织者在论坛上创建一个 onboarding 帖子,链接到该领域的重要论文/文章。他们还可能提供关于如何处理较大数据集的技巧和对数据的基本见解。当您获得关于手头问题的更多信息时,这些线索总是值得检查和回顾的。
探索性数据分析
你应该关注什么?
您对数据集的初始分析将根据您正在检查的数据类型而有所不同。但是,这些概念在不同领域中通常是相似的,下面的信息可以根据您的具体领域进行调整。为了简化事情,让我们假设我们正在看结构化数据。在任何初始 EDA 中,都有一些基本问题要问:
- 目标是如何分布的?
- 特征之间有什么显著的相关性吗?
- 数据中是否有缺失值?
- 训练和测试数据有多相似?
目标是如何分配的?
在任何数据集中,首先要注意的是类的分布。你会想要很快发现是否有阶级不平衡,因为这会对你的模型产生重大影响。特别是如果一个班级在培训中淹没了其他班级的信息。有许多技术可以处理类别不平衡(例如, SMOTE , ADASYN ,手动移除样本,模型参数来处理不平衡的数据集),但首先我们想知道类别是否在数据中不均衡地表示。检查这一点的快速方法是通过绘图库 seaborn ,基于流行的 matplotlib 。
**import** seaborn **as** snssns.countplot(df['target'])
Multi-class target imbalance
正如我们所看到的,90 级在我们的数据中占了很大比例。前述 SMOTE 技术和其他技术可以创建更平衡的训练数据集。反过来,这可以导致一个模型,更好地推广到看不见的数据,这种不平衡可能不存在。
特征之间有没有显著的相关性?
计算特征之间的皮尔逊相关系数可以提供对特征的一些宝贵见解。知道特性是否相关可以允许创造性的特性工程或删除不必要的列。例如,在下面显示的热图中,EXT_SOURCE_1
是由外部来源提供的贷款申请人的信用评级。DAYS_BIRTH
,申请人的年龄天数(负整数),与EXT_SOURCE_1
负相关。这可能意味着EXT_SOURCE_1
的计算涉及申请人的年龄。一般来说,我们希望避免包含可以从另一个特征线性导出的特征(这被称为线性相关性),因为它为模型提供了冗余信息。
**import** seaborn **as** sns
**import** matplotlib.pyplot **as** plt**def** correlation_map(df, columns, figsize=(15,10)):
correlation = (df.loc[:, columns]).corr()
fig, ax = plt.subplots(figsize = figsize)
sns.heatmap(correlation, annot = **True**, ax = ax)
Correlation heatmap showing positive and negative values for Pearson correlation coefficient between numerical features
数据中是否有缺失值?
您总是希望确保拥有一个完整的训练数据集,并且丢失的值尽可能少。例如,如果您的模型发现某个要素非常重要,但事实证明该要素中有大量的行缺少值,则可以通过输入缺少的值来大大提高模型的性能。这可以通过基于不包含NaN
的相似行来推断特性的值来完成。另一种策略(称为*回填)*是用下一个非空值填充缺失值。其余要素的平均值、中值或众数有时也用于估算缺失值。[pandas.DataFrame.fillna()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.fillna.html)
方法提供了一些不同的选项来处理这个场景,并且这个 Kaggle 内核是一个非常有用的资源。
但是,缺少值并不总是意味着没有记录数据。有时,为某个特性包含一个NaN
值是有意义的,这个值不适用于单独的行。例如,假设一个贷款申请数据集有一个二进制目标(申请人是否被批准),其中包括一个关于个人是否拥有汽车的特性。如果一个给定的人没有汽车,那么汽车注册日期的另一个特征将包含一个NaN
值,因为在这里没有信息可以填写。
训练和测试数据有多相似?
熊猫 DataFrame
对象包含一个[pandas.Dataframe.describe()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.describe.html)
方法,该方法提供数据集中每个特征的统计数据,如最大值、平均值、标准差、第 50 百分位值等。该方法返回另一个DataFrame
,因此您可以根据需要添加更多信息。例如,您可以使用以下函数让另一行检查该列中缺失值的数量:
**def** describe_df(df):
stats_df = df.describe()
stats_df.append(pd.Series(df.isna().any(), name='nans'))
**return** stats_df
这是一个非常有用的方法,允许您快速检查训练和测试中的特征之间的相似性。但是,如果你有一个单一的数字值,给你一个很好的想法,只是如何密切训练和测试一目了然?这就是对抗性验证进入*的地方。*我知道这听起来有点吓人,但一旦你理解了这一技巧,你会发现它非常简单。对抗性验证包括以下步骤:
- 将训练数据集和测试数据集连接成一个大数据集
- 将所有列车行的目标特征设置为值 0
- 在所有测试行中为目标特性填充值 1(您可能会看到这是怎么回事)
- 从数据中创建分层折叠(我喜欢使用 sklearn 实现)
- 将类似 LightGBM 的模型安装到培训文件夹中,并在验证文件夹中进行验证
- 对整个数据集进行验证预测,并计算接收器操作特征曲线(ROC AUC) 下的面积。我使用这个实现来计算面积。
- ROC 曲线下 0.5 的面积意味着模型无法区分训练行和测试行,因此这两个数据集是相似的。如果面积更大,模型可以看到训练和测试之间的一些差异,因此值得您深入挖掘数据,以确保您的模型可以很好地预测测试。
我发现以下两个内核有助于掌握这项技术:
- https://www.kaggle.com/tunguz/adversarial-santander
- https://www . ka ggle . com/pnussbaum/adversarial-CNN-of-PTP-for-vs b-power-v 12
为什么从基于树的模型开始?
在你第一次开始的时候,找出正确的模型是很重要的,而且可能会很混乱。让我们再次假设您正在处理结构化数据,并且您希望在陷入建模之前对数据有所了解。我发现 LightGBM 或 XGBoost 型号非常适合在你刚参加新的比赛时就把数据扔给你。这两个都是基于树的提升模型,具有很强的可解释性并且易于理解。两者都提供了绘制分割图的功能,因此创建max depth = 3
左右的树并从一开始就查看模型分割的具体特征是很有用的。
lightgbm.Booster.feature_importance()
方法根据模型对特定特征的分割次数(importance_type="split"
)或对特定特征的每次分割所获得的信息量(importance_type="gain"
)来显示模型最重要的特征。查看要素的重要性在匿名化的数据集中特别有用,您可以获取前 5 个左右的要素,并推断出这些要素可能是什么,知道它们对模型有多重要。这可以极大地帮助特征工程。
您还会发现 LightGBM 特别快(请原谅双关语),即使不使用 GPU 也能进行训练。最后,这两种模型都有很好的文档,所以初学者应该不难掌握。
估价
如果不使用可靠的评估方法,您可能在竞争中拥有性能最佳的型号,但却不知道这一点。在参赛之前,了解比赛的官方评估标准是至关重要的。一旦您对如何评估您的提交有了坚实的理解,您应该确保在培训和验证中使用官方评估指标(或者如果不容易获得合适的实现,则使用您自己的版本)。将这一点与可靠的验证集相结合,将避免您在提交时焦头烂额,并允许您快速、经常地进行试验。
除此之外,您希望以这样一种方式设置您的模型评估,以使您最终得到一个单一的数字。查看训练损失与验证损失或一系列指标,包括精确度、召回率、F1 分数、AUROC 等。有时在生产中很有用,但在竞争中,您希望能够快速浏览一个数字,然后说“这个型号比我以前的型号好”。同样,这个数字应该是官方指标。如果不是,你应该有一个很好的理由。
如果你遵循上面的建议,你将会达到这样一个点,在那里你会经常实验,以至于你需要一个可靠的方法来跟踪你的结果。我喜欢使用在 Docker 容器中运行的 MongoDB 实例,每次运行我的评估脚本后,我都会将我的模型参数和验证分数发送到该容器中。我为每个模型保留了一个单独的表(或者 MongoDB 喜欢称之为集合)。当我运行完一些实验后,我将记录作为一个 MongoDB .archive
文件和一个.csv
文件转储到我机器上的一个本地目录中,以便快速通读。代码可以在这里找到。应该注意的是,关于如何处理记录结果有不同的思想流派,这是我的首选方法,但我很想听听其他数据科学家如何处理它!
Chirag Chadha 是爱尔兰都柏林 UnitedHealth Group/Optum 的数据科学家。你可以通过他的电子邮件(chadhac@tcd.ie),通过他的LinkedIn,或者在ka ggle和GitHub上关注他。
如何从 Databricks-Spark-Hive 中获取数据
Fingers Trying to break out of jail, Pixabay.
简单的方法。
这篇文章是为那些使用 Databricks (DB)笔记本并希望通过使用 Pyspark 将基于 Hive 的数据集导出到外部机器的科学家而写的,以便使用 Pandas 获得更高效的工作流。
有很多方法可以做到以下几点,但这个方法对我很有效。
首先,在 DB 笔记本中创建一个 SQL 查询,并等待结果。以下查询是从 table_x 中选择所有列并将结果分配给 spark 数据框的简单示例。
df = spark . SQL(" " SELECT * FROM table _ x " " " ")
Spark 不会参与,直到您要求它物化数据,因此,您必须执行以下命令。
df.show()
此时,您应该会看到一个非常难看的打印输出,其中包含一些数据。
在打印输出之后,您需要安装 DB 客户机,对其进行配置,并在 DB 文件存储上创建一个目录。
pip3 安装数据块-cli
设置和配置 DB 客户端,我假设您可以遵循文档或者熟悉设置过程。点击此处获取文件。
dbfs mkdirs dbfs:/file store/my/path/is/here
按照这些步骤,在 DB 笔记本中执行 write-to-JSON 命令,数据帧将保存在预定义路径的多个 JSON 文件中。请注意,路径应该根据您的配置进行更改。
df . write . JSON(
f " dbfs:/FileStore/my/path/is/here ",
mode="overwrite ",
compression=“gzip”
)
执行这些命令后,我们将在我们的机器上创建一个新目录,转到该目录,检查文件是否在我们的云目录中等待,最后使用 DB 客户端复制文件。
mkdir/data/our data
CD/data/our data
dbfs ls dbfs:/file store/my/path/is/here
dbfs CP-r dbfs:/file store/my/path/is/here。
按照这些步骤,您可以将 location 指向您机器的数据目录并处理文件,将所有下载的 JSON.GZ 文件连接到一个 Pandas 数据框中。
进口熊猫作为 pd
location = '/data/ourData ’
从 pathlib 导入路径
files = list(路径(位置)。glob(" * . JSON . gz ")
l =[]
for f in files:
l . append(PD . read _ JSON(f,lines = True))
df = PD . concat(l)
现在,您可以使用 Pandas,处理数据的速度比使用 DB 笔记本更快。唯一的条件是,你实际上可以把所有的数据都放进你的机器的内存里。
我要感谢巴拉克·亚伊尔·赖夫的宝贵帮助,感谢阿黛尔·古尔审阅本文。
Ori Cohen 博士拥有计算机科学博士学位,主要研究机器学习。他是 TLV 新遗迹公司的首席数据科学家,从事 AIOps 领域的机器和深度学习研究。
如何在机器学习和软件工程之间架起桥梁
Photo by Tyler Lastovich on Unsplash
将数据科学转化为软件的实用工作流程
数据科学/机器学习社区越来越沮丧地看到又一个 PoC(概念验证)创造了有希望的结果,但从未变成有影响力的东西。主要原因:开发和部署之间的差距很大。
越来越多的工具和框架——开源的和商业的——有望弥合这一鸿沟。然而,将他们引入组织是一项耗时且昂贵的工作。
为这样的解决方案而战是光荣的,也是必要的。尽管如此,在此期间我们还可以做些别的事情来缩小差距:使我们的工作流程与软件开发原则保持一致。要学的第一件事:单元测试。
不幸的是,大多数介绍和文档都以抽象的方式处理这个主题。相比之下,这篇博客通过一个具体的例子向你展示了一个实用的工作流程。我们开始吧!
方案
我们在一家迅速扩大客户群的初创公司工作。虽然这对公司来说是个好消息,但有些流程需要适应新的形势。其中之一是电子邮件营销。
当我们公司开始发送营销邮件时,客户群很小,而且很专注。因此,所有注册客户都收到了所有的电子邮件,这很好。这不再是真的了。虽然仍有一些忠实的客户不想错过促销和产品更新,但许多新客户却不那么兴奋了。更糟糕的是,越来越多的潜在客户选择退出营销通讯,因为不相关或太多的电子邮件。
经过一番讨论后,我们初创企业的创始人决定加强营销流程。他们设想了一种系统,可以将电子邮件发送给关心他们的客户,让其他人免受收件箱的额外压力。
我们的工作是构建该系统的机器学习部分。
要求
让我们总结一下我们拥有的和我们需要的:
- 我们有一些顾客的信息。
- 我们有一些关于计划营销电子邮件的信息。
- 我们需要每个客户与给定营销电子邮件互动的可能性(不包括选择退出简讯的互动)。
对于数据科学家和机器学习工程师来说,跳入收集数据和建立复杂模型是非常非常诱人的。然而,这不是我们现在需要的。请记住,我们的目标是构建一个完整的系统,而不是一个独立的模型。那么,我们如何使我们的工作符合这些要求呢?
工作流程
我们决定采用四步工作流程:
- 选择下一个要开发的组件。
- 编写捕捉我们想要实现的目标的单元测试。
- 编写通过单元测试的代码。
- 重复一遍。
我们开始吧!
步骤 1:选择下一个要开发的组件
现在,什么都没有。然而,我们知道其他团队开始在整个系统上工作,我们想要支持他们。因此,我们的第一个任务是为整个流程创建一个接口,它接受两个输入并返回期望的输出。我们把这个主类叫做 CampaignPredictor 。它采用一个 pandas 数据框作为客户数据,一个字典作为计划活动的信息,并有一个方法返回所有客户与电子邮件交互的概率。它看起来像这样:
注意,我已经包含了类型提示、一个(初步的)docstring 和一个 NotImplementedError。在这一点上继续编码是非常有诱惑力的。然而,如果我们首先陈述我们对这段代码的期望,我们就帮了自己一个大忙。向我们以及将我们的代码集成到整个过程中的团队表达这些期望的最佳方式是:单元测试。
步骤 2:编写捕捉我们目标的单元测试
编写好的单元测试本身就是一门艺术。尽管如此,我们还是想在代码的两个维度上使用它们。第一个尺寸是有效的,而不是无效的输入。在有效输入的情况下,我们关注正确的输出。在无效输入的情况下,我们关注错误处理和快速失败。前者帮助用户了解哪里出错了,而后者确保用户在出错时不必等待。
第二个维度是结构与功能质量。结构单元测试包括输入和输出的正确类型和形状。功能单元测试覆盖了代码的功能。也就是说,它是否提供了它承诺要解决的问题。下面是这些单元测试的样子:
对于无效的输入,主要有两种错误。 TypeErrors 捕获我们期望一种类型的输入并得到另一种类型的输入的所有情况。例如,我们期望一个熊猫数据帧,但是得到一个 numpy 矩阵。 ValueErrors 捕获类型正确的情况,但是我们不能处理值本身。例如,我们期望一个字典有一个“campaign_type”键,该键的值是一个字符串,但是要么这个键丢失了,要么这个值不是一个字符串。这两种情况都会导致以后的问题,所以我们希望尽早发现并提供有意义的错误消息。
对于有效的输入,不应有任何错误。首先,我们期望输出具有正确的类型和形状。在我们的例子中,这是一个长度与输入中的客户数量相同的列表。第二,我们期望这个列表中的所有值都是有效概率,也就是说,它们的范围从 0 到 1。
如您所见,我们讨论了有效和无效输入的结构和功能方面。因为所有这些测试现在都失败了,所以一切都按预期运行。也就是说,根本不是。让我们解决这个问题。
步骤 3:构建通过测试所必需的东西(第一次尝试)
虽然测试没有明确的顺序,但是我们从无效输入的测试开始。这有助于我们在做一些事情之前澄清我们实际期望得到什么。
因为我们的主要目标是在有无效输入时快速失败,所以我们将编写验证代码作为类初始化的一部分。在我们的例子中,我们需要确保得到一个包含预期键值对的字典和一个至少有一行的数据框,即至少有一个客户可供选择。
这段代码通过了无效输入的测试。在进行这项工作时,您可能会获得关于应该测试什么的其他想法。总的来说,这是一件好事,因为这表明你开始更详细地考虑你的方法。然而,不要太具体,因为事情可能会改变。
看第二个测试是非常诱人的——最后!—从建模开始。然而,这不是我们现在的目标。我们的目标是整个过程。同时,有许多不同的方法来预测客户与电子邮件交互的概率。
解决办法?我们在兔子洞里更深入一步。单元测试的美妙之处在于,一个失败的测试会提醒我们还有一些东西需要修复。首先,让我们实现一个简单的方法来为活动选择客户:简单随机化。
延时拍摄中的步骤 1-3
第一步:我们现在正在为选择客户的更复杂的方法构建蓝图。对于简单的集成测试来说,这个占位符应该是快速的——并且不是完全愚蠢的。姑且称之为 RandomSelector 类。它需要一些客户来选择,以及他们中应该收到电子邮件的百分比。然后,它应用一种方法来随机选择一组客户,并将结果作为列表返回。
**第二步:**我们为有效和无效的输入编写单元测试。关于输入,我们希望确保客户的数量多于一个,并且要选择的百分比在 0 和 1 之间。如果输入与此不符,我们希望看到正确的错误类型。关于输出,我们希望得到一个长度正确的列表,并且至少有一个选定的客户。
正如您在第 42–51 行看到的,我还包括了一个我在编写测试时想到的边缘案例。同样,单元测试有助于澄清你实际期望得到什么,这使得之后的编码更加集中。
**第 3 部分:**我们更新了类的初始化,以检查输入和产生正确输出的方法。一旦我们通过了测试,我们就完成了这个任务。
现在我们可以使用这个新类来处理我们开始时的事情:CampaignPredictor。
步骤 3:构建通过测试所必需的东西(第二次尝试)
如果我们正确地从 CampaignPredictor 为**random selection类翻译我们的需求,我们几乎不需要额外的代码来通过有效输入的测试:
所有测试都通过了,我们可以庆祝我们的第一次迭代。在我们开始第二个之前,这是更新 docstring 并将代码提交给我们的版本控制系统的好时机。
重复
我们的下一步取决于业务优先级。在这种情况下,随机化将是不可接受的,因此我们需要集成一段能够加载训练模型并将其应用于所提供的数据集的代码。我把这个练习留给思考什么是有效的和无效的输入,以及这样一个模块需要传递给你什么。
外卖
这个工作流和场景被简化了。然而,每个案例都有其自身的复杂之处,这一微不足道的观察不能成为使一切复杂化的理由。相反,在构建下一个组件时,只有四个问题:
- 我期望的输入是什么?
- 如何处理无效或不完整的输入?
- 从结构的角度来看,我希望输出是什么样的?
- 从功能角度来看,我希望我的输出达到什么目的?
诚然,回答这些问题会让人觉得很烦。我认为主要有两个原因:
- 这些问题出奇的难。很好。你意识到你不确定你想要实现什么。现在比 1000 行额外的代码要好。
- 感觉又慢又啰嗦,尤其是截止日期临近的时候。如果你不在乎你要去哪里,感觉很快会更容易。然而,在压力下,方向感不清晰是最糟糕的。
关于测试本身的更多例子和更多细节,请参阅我的上一篇博文和其中包含的参考资料:
数据科学家和机器学习工程师应该向软件开发人员学习的另一件事
towardsdatascience.com](/tdd-datascience-689c98492fcc)*
如果这篇文章对你有所帮助或者你想补充什么,请在评论中或者在 Twitter 上告诉我。我也很乐意在 LinkedIn 上联系。感谢阅读!
如何将您的数据科学项目投入生产
将 Azure 数据块与 Spark、Azure ML 和 Azure DevOps 一起使用
1.介绍
许多公司努力将他们的数据科学项目投入生产。一个常见的问题是,模型越接近生产,就越难回答以下问题:
- 为什么模型会预测到这一点?
拥有数据科学项目的构建/发布管道有助于回答这个问题。它使您能够追溯:
- 模型 M 由人 P 用算法 A 在数据集 D 上训练
- 型号 M 在 R 版中于时间 T 投入生产
这种审计跟踪对于生产中运行的每个模型都是必不可少的,并且在许多行业中都是必需的,例如金融业。
博客/git 回购最后更新:2021 年 7 月 21 日。感谢Pardeep Singla修复了 Azure ML 中一些突破性的改动。
我了解到这个博客/回购经常用在演示、教程等中。如果你也这样做,请不要犹豫联系我,我很想知道。
2.目标
在本教程中,机器学习项目的构建/发布管道创建如下:
- 创建一个 HTTP 端点,使用年龄、每周工作时间、教育程度等特征来预测一个人的年收入是高于还是低于 50k。
- Azure Databricks 与 Spark、Azure ML 和 Azure DevOps 一起用于创建模型和端点。Azure Kubernetes 服务(AKS)同时用作测试和生产环境。
该项目可以在以下高级概述中进行描述:
2. High level overview
在本博客的剩余部分,将执行以下步骤:
- 3.先决条件
- 4.在 Azure Databricks 中创建机器学习模型
- 5.Azure 机器学习服务中的管理模型
- 6,7.在 Azure DevOps 中构建和发布模型
- 8.结论
博客的后续可以在这里找到,其中安全性被嵌入到构建/发布管道中。此外,审计跟踪的细节将在的博客中讨论。最后,如果你对如何在 Azure Data Factory 中使用 Azure Databricks 感兴趣,请参考这个博客。
3.先决条件
本教程需要以下资源:
4。在 Azure Databricks 中创建机器学习模型
Azure Databricks 是一个基于 Apache Spark 的分析平台,针对 Azure 进行了优化。它可以用于许多分析工作负载,其中包括机器学习和深度学习。在此步骤中,将完成以下工作:
- 4a。创建新集群
- 4b。导入笔记本
- 4c。运行笔记本
4a。创建新的集群
启动 Azure Databricks 工作区并转到群集。使用以下设置创建新集群(2020 年 9 月编辑:在 devOps pipeline 中,Databricks Runtime 6.6。被使用,建议在数据块中也使用这个运行时版本进行交互式分析):
4a1. Create cluster
4b。导入笔记本
转到您的 Azure Databricks 工作区,右键单击,然后选择导入。在单选按钮中,选择使用 URL 导入以下笔记本:
[https://raw.githubusercontent.com/rebremer/devopsai_databricks/master/project/modelling/1_IncomeNotebookExploration.py](https://raw.githubusercontent.com/rebremer/devopsai_databricks/master/project/modelling/1_IncomeNotebookExploration.py)
另请参见下图:
4b1. Import notebook
4c。运行笔记本
选择您在 4b 中导入的笔记本,并将该笔记本连接到您在 4a 中创建的集群。确保集群正在运行,否则启动它。阅读笔记本中的步骤,其中研究了数据,并尝试了几种设置和算法,以创建一个预测一个人收入阶层的模型。使用快捷键 SHIFT+ENTER 逐个单元格地浏览笔记本。
4c1. Steps in notebook
5.Azure 机器学习服务中的管理模型
Azure 机器学习服务(Azure ML)是一种云服务,您可以使用它来训练、部署、自动化和管理机器学习模型。在这个上下文中,上一步中创建的模型将被添加到您的 Azuere ML 实例中。将执行以下步骤
- 5a。将库添加到数据块群集中
- 5b。使用 Azure ML 将笔记本导入到 Azure Databricks
- 5c。在 Azure ML 中查看结果
5a。将库添加到数据块群集中
右键单击您的工作区并选择“创建库”
5a1. Create library
选择 PyPi,然后填写:azureml-sdk[databricks]
5a2. Add PyPi library with azureml-sdk[databricks]
最后,将库连接到群集。
5a3. Attach library to cluster
5b。使用 Azure ML 将笔记本导入到 Azure Databricks
在本教程的上一部分,我们在 Azure Databricks 中创建了一个模型。在这一部分中,您将把创建的模型添加到 Azure 机器学习服务中。
再次转到您的 Databricks 服务,右键单击,选择导入,并使用以下 URL 导入笔记本:
[https://raw.githubusercontent.com/rebremer/devopsai_databricks/master/project/modelling/2_IncomeNotebookAMLS.py](https://raw.githubusercontent.com/rebremer/devopsai_databricks/master/project/modelling/2_IncomeNotebookAMLS.py)
同样,确保它已连接到群集,并且群集正在运行
5b1. Import Azure ML notebook
随后,为 workspace、subscription_id 和 resource_grp 填入正确的值。所有值都可以在 Azure 门户的 Azure 机器学习服务工作区的 overview 选项卡中找到。
5b2. Add variables notebook
现在,使用快捷键 SHIFT+ENTER 逐个单元格地运行笔记本单元格。
在 cell 6 中,您需要向笔记本中的 Azure 机器学习服务进行身份验证。按照笔记本中的说明打开 URL,并输入生成的代码进行身份验证。
5c。在 Azure ML 中查看结果
在步骤 5b 中,运行一个笔记本,其中的结果被写入 Azure 机器学习服务。在这方面,完成了以下工作:
- 在 you Azure ML 中创建了一个新的实验
- 在这个实验中,具有 6 个子运行的根运行可以找到不同的尝试。
- 子运行包含模型的描述(例如正则化为 0 的逻辑回归)和尝试的最重要记录(例如准确性、假阳性的数量)
- 模型人工制品(。mml)也是子运行的一部分。最佳子运行的工件可以投入生产。
转到您的 Azure ML 实例。选择笔记本中使用的实验名称(例如,experiment_model_int)。
5c1. Find experiment in Azure Machine Learning Service
现在单击实验,单击您想要查看指标的运行和子运行。
5c2. Find metrics of a childrun in Azure Machine Learning Service
你去输出的时候会发现模型神器,也可以下载。在本教程的下一部分中,最佳运行的模型工件将被用作使用 Azure DevOps 部署的容器的基础。
5c3. Model artifact
6.创建和准备 Azure DevOps 项目
Azure DevOps 是一个工具,可以持续地构建、测试和部署你的代码到任何平台和云。在第 6 章中,将创建并准备一个 Azure DevOps。该项目将采用以下步骤进行准备:
- 6a。在数据块中创建个人访问令牌
- 6b。创建 AKS 集群
- 6c。创建 Azure DevOps 项目和服务连接
- 6d。向代码中添加变量
在第 7 章中,实际的构建-发布管道将被创建并运行以创建模型的一个端点。
6a。在数据块中创建个人访问令牌
要在 Azure DevOps(使用 REST APIs)触发的 Azure Databricks 中运行笔记本,需要 Databrics 访问令牌(PAT)进行身份验证。
进入 Azure Databricks,点击右上角的人物图标。选择用户设置,然后生成新令牌。
6a1. Generate Databricks Access Token
请确保现在复制令牌。你再也看不到它了。稍后从 Azure DevOps 构建管道访问数据块需要令牌
6b。创建 AKS 集群
在这一步中,在 Azure Kubernetes Services (AKS)中创建了一个测试和生产环境。通常,这是两个独立的 AKS 环境,但是,为了简化和节约成本,只创建了一个环境。首先,转到您的 Azure ML 服务工作区并选择 Compute。取计算机名 blog-devai-aks 并选择 Kubernetes 服务作为计算机类型,也见下文。
6b1. Add AKS compute to Azure ML Service
创建 AKS 集群大约需要 10 分钟。继续下一步。
6c。创建带有服务连接的 Azure DevOps 项目
按照这个教程,在 Azure DevOps 中创建新项目。创建新项目后,单击存储库文件夹并选择导入以下存储库:
[https://github.com/rebremer/devopsai_databricks.git](https://github.com/rebremer/devopsai_databricks.git)
另请参见下图:
6c1. Add repository to your Azure DevOps project
从 Azure DevOps 访问资源组中的资源需要服务连接。转到项目设置、服务连接,然后选择 Azure 资源管理器。
6c2. Go to Service Connection
选择服务主体身份验证,并将范围限制在部署了机器学习工作区服务的资源组中。确保将连接命名为如下所示:devopsaisec _ service _ connection。
6c3. Create Azure Resource Manager service connection
6d。向代码中添加变量
在您在上一步中创建的 Repos 中,应更改以下文件:
- \ project \ config code _ build _ release . yml
对于工作空间、subscription_id 和 resource,使用与步骤 5b 中的机器学习服务工作空间的值相同的变量。此外,填写您在步骤 6a 中生成的 Databricks 个人访问令牌。
variables:
# change 5 variables below with your own settings, make sure that
# : with a space is kept and not replaced with =
workspace: '<<Name of your workspace>>'
subscription_id: '<<Subscription id>>'
resource_grp: '<<Name of your resource group with aml service>>'
domain: 'westeurope.azuredatabricks.net' # change loc.when needed
dbr_pat_token_raw: '<<your Databricks Personal Access Token>>'
在 Azure DevOps 中,可以通过在 Repos 中查找文件,点击“编辑”,更改变量,然后“提交”文件来更改文件。您还可以克隆项目并从那里开始工作。请注意,在生产环境中,绝不能将键添加到代码中。相反,Azure DevOps 管道中的秘密变量将被使用,并在后续的教程中处理。
在本章中,创建并准备了一个 Azure DevOps 项目。现在模型已经准备好在 Azure DevOps 项目中构建和发布了。
7.在 Azure DevOps 中构建和发布模型
在这一部分中,使用以下步骤在 Azure DevOps 中构建和发布模型:
- 7a。创建构建-发布管道
- 7b。运行构建-发布管道
- 7c。使用邮递员消费 HTTP 端点
7a。创建构建-发布管道
在这一步中,您将创建一个构建-发布管道。转到您在 6c 中创建的 Azure DevOps 项目,然后单击 Pipelines。将显示一个向导,您可以在其中选择 Azure Repos Git,另请参见下文。
7a1. Create Pipeline
随后,选择附加到这个项目的 Git repo,然后选择“现有的 Azure Pipelines YAML 文件”。然后浏览目录\ project \ config code _ build _ release _ ACI _ only . yml 或\ project \ config code _ build _ release . yml(如果在步骤 6b 中创建了 AKS 集群,另请参见下文)。
7a2. Select build-release YAML file
最后,检查您的管道并保存您的管道,另见下文。
7a3. Save pipeline
在本章中,配置了管道。在此管道中,将执行以下步骤:
构建:
- 选择 Python 3.6 并安装依赖项
- 将笔记本上传到数据块
- 通过运行 notebook 使用 Azure Databricks 创建模型。向 Azure 机器学习服务添加模型
- 创建构建工件作为发布 deployTest 和 deployProd 的输入
发布部署测试:
- 检索在构建步骤中创建的模型
- 将模型作为 docker 映像部署到作为测试端点的 AKS
- 测试 AKS 中的“测试端点”
释放部署杆:
- 检索在构建步骤中创建的模型
- 将模型作为 docker 映像部署到作为 prd 端点的 AKS
- 在 AKS 中测试“生产端点”
在下一部分中,将运行管道。
7b。运行构建-发布管道
在这一步中,构建-发布管道将在 Azure DevOps 中运行。转到上一步中部署的管道,选择管道,然后选择队列,另请参见下文。
7b1. Run build-release pipeline
当管道启动时,会在构建步骤中使用 Azure Databricks 和 Azure ML 创建一个包含 ML 模型的 docker 映像。随后,docker 映像在 ACI 和 AKS 中部署/发布。下面可以看到一次成功的运行。
7b2. Successful run of build-release pipeline
请注意,如果您决定不在 AKS 中部署 docker 映像,前面的步骤仍将执行,AKS 步骤将失败。要获得详细的日志记录,您可以单击各个步骤。
7c。使用邮递员消费 HTTP 端点
当你进入 Azure ML 工作区时,你可以找到你在 7b 中部署的模型的端点。这些端点现在将被邮递员用来创建预测。可以在项目中的项目/services/50_testEndpoint.py 中找到一个示例负载。在本例中,预测了三个人的收入等级。
- 对第一个人的预测是收入高于 50k,
- 对于另外两个人,预测值低于 50k。
7c2. Use HTTP endpoint to create predictions
8.结论
在本教程中,创建了一个机器学习项目的端到端管道。在此:
- Azure Databricks with Spark 用于探索数据和创建机器学习模型。
- Azure 机器学习服务用于跟踪模型及其度量。
- Azure Devops 用于构建最佳模型的映像,并将其作为端点发布。
通过这种方式,您可以协调和监控从构思到模型投入生产的整个过程。这使您能够回答问题:为什么模型会预测到这一点?
可以在下面找到架构概述。在这个后续教程中,管道的安全性得到了加强。
8. High level overview
如何构建聊天机器人——自然语言处理中的一课
一个 5 步的自然语言处理过程可以帮助你设计简单的聊天机器人
顾名思义,聊天机器人是一种和你聊天的机器。不过,诀窍是让它尽可能像人类。从“美国运通客户支持”到谷歌 Pixel 的电话筛选软件,聊天机器人的种类繁多。
Photo by Blake Wisz on Unsplash
它实际上是如何工作的?
聊天机器人的早期版本使用了一种叫做模式匹配的机器学习技术。与目前使用的高级 NLP 技术相比,这要简单得多。
什么是模式匹配?
要理解这一点,想象一下你会问一个卖书的人什么,比如——“_ _ 本书的价格是多少?"或"你有哪些 __ 作者的书?“这些斜体问题中的每一个都是一种模式的示例,当类似的问题在未来出现时,可以进行匹配。
模式匹配需要大量预先生成的模式。基于这些预先生成的模式,聊天机器人可以很容易地选择最匹配客户查询的模式,并为其提供答案。
你认为如何创建下面的聊天
简单地说,问题我可以知道的价格吗被转换成模板的价格<星/ >。这个模板就像一把钥匙,所有未来的答案都将存储在里面。所以我们可以有下面的
- iPhone X 的价格是 1500 美元
- Kindle Paperwhite 的价格——100 美元
用 AIML(人工智能建模语言)编写的代码看起来会像这样
**#PATTERN MATCHING**
<category>
<pattern>**MAY I KNOW THE PRICE FOR ***</pattern>
<template>
<srai>**THE PRICE OF <star/>**</srai>
</template>
</category>------------------------------------------------
**#PRE_STORED PATTERNS**<category>
<pattern>**THE PRICE OF iPhone X?**</pattern>
<template>*iPhone X Costs $1500.*</template>
</category><category>
<pattern>**THE PRICE OF Kindle Paperwhite?**</pattern>
<template>*The all-new kindle paperwhite costs $100\. Yay!! You
have got an offer!! You can get it for $85 if you apply
the coupon* ***MyGoodBot***
</template>
</category>
NLP 聊天机器人
模式匹配实现起来简单快捷,但也只能到此为止。它需要大量预先生成的模板,并且只对期望有限数量问题的应用有用。
进入 NLP !NLP 是一个稍微高级的技术的集合,可以理解广泛的问题。创建聊天机器人的 NLP 过程可以分为 5 个主要步骤
1)标记化— 标记化是将文本分割成小块的技术,称为标记,同时丢弃某些字符,如标点符号。这些标记在语言学上代表了文本。
Tokenizing a sentence
2)规格化— 规格化处理文本,找出可能改变用户请求意图的常见拼写错误。一篇很好的研究论文很好地解释了这个概念
Syntactic normalisation of tweets research
3)识别实体— 这一步有助于聊天机器人识别正在谈论的事物,例如,它是一个物体、一个国家、一个号码还是用户的地址。
在下面的例子中,观察谷歌、IBM 和微软是如何联合起来的。这一步也称为命名实体识别。
Entities for various words.
4)依存句法分析——在这一步中,我们把句子分成名词、动词、宾语、常用短语和标点符号。这项技术帮助机器识别短语,进而告诉它用户想要传达什么。
Stanford — dependency parsing example
5)生成— 最后,生成响应的步骤。以上所有步骤都属于 NLU(自然语言理解)。这些步骤有助于机器人理解所写句子的意思。然而,这一步属于 NLG(自然语言生成)。这一步接收前面 NLU 步骤的输出,并生成许多意思相同的句子。生成的句子通常在以下方面是相似的
- 词序— “厨房灯”类似于“厨房里的灯”
- 单数/复数— “厨房灯”类似于“厨房灯”
- 问题— “关上门”类似于“你介意关上门吗?”
- 否定——“19:00 开电视”类似于“19:00 不开电视”
- 礼貌——“打开电视”类似于“麻烦你打开电视好吗?”
基于用户问题的上下文,机器人可以用上述选项之一进行回复,用户会满意地返回。在很多情况下,用户无法区分机器人和人类。
自 AIML 于 1995 年发明以来,聊天机器人一直在稳步发展,并取得了长足的进步。即使在 2016 年,普通用户也要花 20 多分钟在即时通讯应用上,Kakao、Whatsapp 和 Line 是最受欢迎的应用。
世界各地的企业都希望通过使用这些机器人来削减客户服务成本,并提供全天候的客户服务。
这个故事被发送到 BI Intelligence 应用和平台简报订阅者。要了解更多信息并订阅…
www.businessinsider.com](https://www.businessinsider.com/80-of-businesses-want-chatbots-by-2020-2016-12?IR=T)
聊天机器人背后的技术相当标准。NLP 还有很长的路要走,但即使在目前的状态下,它也为聊天机器人领域带来了很多希望。
如何使用 Dash 和 Plotly 构建报告仪表板
在这篇博文中,我将提供一个分步指南,介绍如何使用 Dash 构建一个报告仪表板,这是一个用于构建分析性 web 应用程序的 Python 框架。我没有详细介绍构建 Dash 应用程序的基础知识,而是提供了一个使用数据表和图表构建多页仪表板的详细指南。
我将报告仪表板构建为一个多页面应用程序,以便将仪表板分成不同的页面,这样就不会太多,并以一种有组织的方式呈现数据。在每个仪表板页面上,有两个数据表、一个日期范围选择器、一个数据下载链接,以及两个仪表板下方的一组图表。我在构建仪表板时遇到了几个技术挑战,我详细描述了我是如何克服这些挑战的。
完成的仪表盘可以在https://David comfort-dash-app 1 . heroku app . com/cc-travel-report/payed-search/查看,代码在 Github 中提供。(应用程序中使用的数据是随机数据,产品名称是“虚拟”名称。)
Figure 1: Dashboard built using Dash
Figure 2: Second Part of Dashboard
目录
- **1。**简介
- 2。我想用仪表板实现什么?
- 3。构建仪表板的挑战
- 4。创建新环境并安装 Dash
- 5。破折号入门
- 6。构建多页面应用程序
- 构建索引页面
- 自定义页面标题和图标
- 页面布局概述
- App 的本地测试
- 7。构建日期选择器元素
- 给 CSS 添加一个修正,这样日期选择器就不会隐藏在数据表后面
- 8。构建第一个数据表
- 根据日期选择改变数据表中显示的日期
- 计算指标的变化,以及计算每次会话的成本、转换率和每次收购的成本。
- 一种选择压缩数据表或完整数据表的方法。
- 有条件地对不同的数据表单元格进行颜色编码
- 使用重身幽灵列的单元格的条件格式
- **9。**建筑下载数据链接
- 10**。构建第二个数据表**和
- 11**。通过选择仪表板数据表**中的行来更新图形
- 第一步
- 第二步
- 第三步
- 12**。动态更新图表和计算指标**
- 13。Plotly 图形工具
- 14。部署仪表板
- 解决 Custom.css 文件和认证问题
- Dash 部署服务器
- 15。包装完毕
- 16。破折号的资源
1.介绍
今年 1 月,我参加了我的第一次 PyData 会议,PyData Miami,参加了切尔西·道格拉斯关于 Dash 的精彩演讲。
Embedded Video 1: Dash: data exploration web apps in pure Python — Chelsea Douglas
很快,Dash 的强大功能变得显而易见,我可以使用 Python 轻松地构建 web 应用程序和仪表盘。
从我的角度来看,我的公司确实需要自动化报告,取代 Microsoft Excel 数据透视表和电子表格,并提供商业智能工具的替代方案。尽管我的公司中的各种利益相关者依赖 Excel 电子表格进行定期报告,但它们的使用变得很笨拙,容易出错,它们不是独立于平台的,并且它们不适合自动化。
因此,我努力使用 Dash 构建一个多页面的 web 应用程序。这篇文章深入探讨了我的努力的本质和细节,以及我是如何克服几个技术挑战的。我应该指出,我来自一个数据科学家的角度,并没有声称自己是一个软件开发人员。因此,我的代码当然还有改进的空间,我欢迎读者的建议。同时,如果读者需要构建复杂的仪表板和数据表,我希望他们能够从我的工作中受益。
2.我想用仪表板实现什么?
在我现在的公司,许多定期报告都是通过 Excel 电子表格和数据透视表完成的,或者使用商业智能工具,如 Birst 或 Qlikview 。因此,我想建立一个报告仪表板,作为一个概念验证,可以取代和增强我们的报告。具体来说,我想为一个品牌构建一个报告 web 应用程序,它可以报告不同的营销渠道指标,实现自动化并提供方便的访问。
电子商务营销仪表板的要求包括:
- 将不同的营销渠道分成不同的页面,这样仪表盘中显示的数据量就不会过多。
- 日期选择器,用户可以选择日期范围来过滤数据。
- 一个数据表,显示所选日期范围内,以及去年同期和所选日期范围之前的相应时期内,每个数字营销渠道或产品类型的基本指标(支出、会话、交易数量和收入)。*
- 另一个数据表显示所选日期范围(以及去年同期和前期)的计算指标。这些指标包括每次会话成本(CPS)、转换率(CVR)和每次收购成本(CPA)。
- 下载每个数据表中显示的数据(Excel 格式)的链接。
- 数据表下方将显示每周的指标图表。
- 对应的先前时段的一个示例是,如果用户选择了 2019 年的第 5 和第 6 周,则对应的先前时段将是 2019 年的第 3 和第 4 周。
3.构建仪表板的挑战
当我构建 dashboard 应用程序时,出现了多个挑战。一些主要挑战包括:
- 找出一种方法来显示压缩的数据表或完整的数据表。
- 能够根据单元格中的值对数据表中的单元格进行颜色编码。
- 能够选择多个产品以包括在数据的图形表示中。
- 能够根据用户选择的日期范围动态更新数据表中的指标。
- 能够下载数据表中呈现的数据,而无需任何附加格式。
- 在与给定指标相同的 x 轴上描绘指标的逐年变化。
- 能够同时放大所有的图表。
4.创建新环境并安装 Dash
有一个 Dash 用户指南,它提供了 Dash 的一个相当全面的介绍,我鼓励读者在处理一个完全成熟的仪表板之前浏览用户指南并构建一些简单的 Dash 应用程序。此外,还有一个 Dash 社区论坛,一个论坛的展示和讲述部分,突出 Dash 社区的工作,一个 Dash 项目的画廊,一个令人敬畏的 Dash 资源的精选列表,以及一篇关于 Dash 的介绍性文章:
Dash 是一个开源的 Python 库,用于创建基于 Web 的反应式应用程序。两年前,Dash 开始在 GitHub 上公开进行概念验证。我们在网上保留了这个原型,但是 Dash 的后续工作是秘密进行的。我们使用来自银行、实验室和数据科学团队的私人试验的反馈来指导产品的发展。今天,我们很高兴地宣布 Dash 的首次公开发布,它既是企业级的,也是 Plotly 开源工具的一流成员。 Dash 现在可以从 Python 的包管理器中下载,带有
pip install dash
——它是完全开源的,得到了 MIT 的许可。你可以在这里找到入门指南和 GitHub 上的 Dash 代码。Dash 是一个用于创建分析性 web 应用程序的用户界面库。那些使用 Python 进行数据分析、数据探索、可视化、建模、仪器控制和报告的人会立即发现 Dash 的用处。
Dash 使围绕数据分析代码构建 GUI 变得非常简单。
在安装 Dash 之前,按照惯例,我使用 conda : conda create --name dash
创建了一个新环境,然后激活了那个环境conda activate dash
。然后,我简单地按照用户指南中提供的 Dash 安装协议进行操作:
Code Block 1: Pip installing Dash and its components
我应该注意的是,Dash 及其组件的版本将会有所不同,您应该参考用户指南。
5.Dash 入门
已经有相当多的 Dash 教程了,所以我将在本教程中重点介绍如何使用数据表和图表构建多页仪表板,而不是复习构建 Dash 应用程序的基础知识。
如果你刚刚开始使用 Dash,我会鼓励读者至少通读优秀的 Dash 用户指南的前三节。在仪表板数据表上也有一个部分。有几个教程可以让你入门 ***** :
- 介绍 Plotly Dash——《Dash》的作者 Chris Parmer 对 Dash 的高水平介绍。这篇文章是 Dash 官方发布(2017 年 6 月 21 日)的一部分。
- Plotly 的教程—第一部分:应用布局
- Plotly 的教程—第二部分:交互性
- Plotly 的教程——第三部分:交互式绘图
- Plotly 的教程—第 4 部分:带状态的回调
- Python 中基于 Web 的交互式仪表盘—MVC 模式如何适用于 Dash 以及构建应用程序的演练。
- 使用 Plotly 的 Dash 交付公共部门决策支持仪表板 —逐步构建复杂的仪表板。
- OPS code day:Dash Plotly Map+Graph—如何使用 Jupyter 笔记本与 Dash 协同创建映射,即
- 使用 Plotly 的 Dash 框架创建交互式可视化效果—Dash 入门指南。
- 用 Dash 寻找大脚怪,第 1 部分 —构建大脚怪目击仪表板的演练。第二部分,第三部分。
- 用 Dash 来想象地震——Dash 替代品的环境扫描,随后是一个教程。
- ARGO Labs — Plotly Dash 教程(视频) —创建交互式仪表盘的详细介绍。
- 使用 Dash 和 Python 的数据可视化 GUI(视频播放列表) —探索 Dash 特性的五部分系列。
***** 来自 牛逼 Dash Github 页面。
本质上,Dash 应用程序由两部分组成:(1)描述应用程序外观和感觉的应用程序的“布局”,以及(2)使应用程序能够交互的“回调”。用户指南中提供了一个简单的 Dash 应用程序布局,如下所示:
Code Block 2: Simple Dash App Layout
我在本教程中描述的仪表板将 Dash 应用程序分割成不同的文件,并使用户能够构建多页面应用程序。
有一个“索引”页面,根据 URL 呈现不同的页面或布局。每个布局都由几个不同的 Dash 组件组成,包括日期范围选择器、数据表、下载链接和几个图表。这些组件中的每一个都与一个或多个“回调”相关,这些“回调”使仪表板能够进行交互。
用户可以与 Dash 组件之一交互(例如,改变日期范围),并且其他组件反映该改变(例如,导致数据表中呈现的数据改变)。
这种方法的示意图如下图所示:
Figure 3: Schematic of Dashboard files
6.构建多页应用程序
基于在https://dash.plot.ly/urls的 Dash 文档,多页 Dash 应用程序的结构略有改动,如下所示:
Code Block 3: File Structure of a Multi-page Dash App
文件app.py
仅包含以下内容:
Code Block 4: app.py
注意,我使用的是 dash 认证模块(https://dash.plot.ly/authentication)。这有一些含义,我将在下面加以阐述。
构建索引页面
index.py
文件通过定义函数display_page
来定义应用程序的 URL 页面结构,该函数根据应用程序的 URL 来决定应该呈现什么样的页面布局。
Code Block 5: index.py
这与https://github.com/plotly/dash-vanguard-report的 Dash Vanguard 报告中的index.py
页面非常相似,在(https://Dash-gallery . plot ly . host/Dash-Vanguard-Report/portfolio-management)有一个演示。
然而,我不得不包括行from app import server
,以便克服我在 Heroku 上部署应用程序时的一个问题(详见https://community . plot . ly/t/nolayoutexception-on-deployment-of-multi-page-dash-app-example-code/12463)。
自定义页面标题和图标
此外,我想定制应用程序的 HTML 索引模板,特别是页面标题和 favicon。为此,我在index.py
中添加了以下index_string:
:
Code Block 6: index_string in index.py File
为了定制 favicon,可以将favicon.ico
图像放在资产目录中。
页面布局概述
index.py
文件中的回调将应用程序 URL 作为输入,并根据布局输出不同的布局:
Code Block 7: Callback in index.py File
layouts.py
文件包含以下内容:
- 普通 python 导入语句
- 将数据 CSV 文件读入 pandas 数据帧的语句
- 定义不同布局变化中所需的数据表列
- 每个页面布局部分的定义
noPage
布局的定义
layouts.py
文件的开头如下:
Code Block 8: Beginning of layouts.py File
每个页面布局部分包含以下元素:
- 调用导入的
Header()
,这样就可以拥有共同的元素(徽标、品牌名称等。)跨多个 app。 - 数据范围元素
- 标题栏
- 用于选择压缩数据框和完整数据框的单选按钮
- 第一个数据表
- 下载按钮
- 第二数据表
- 图表
layouts.py
中一个布局部分的简化代码块如下:
Code Block 9: Section of layouts.py to render Paid Search Page
上面的代码不包括条件格式,我将在下面讨论。
应用程序的本地测试
按照用户指南,在创建了index.py
和app.py
文件后,用户可以调用应用程序
$ python app.py
...Running on http://127.0.0.1:8050/ (Press CTRL+C to quit)
并在您的网络浏览器中访问http:127 . 0 . 0 . 1:8050/cc-travel-report/payed-search/。
7.构建日期选择器元素
Figure 4: Date Selector Element
日期选择器元素提供了更新两个数据表中显示的数据以及下载的数据链接的方法。我还想让日期选择器对用户选择的日期提供反馈。
我干脆选择 2018 年 1 月 1 日作为允许的最小日期(min_date_allowed
);允许的最大日期基于 CSV 数据文件(max_date_allowed
)中的最大日期;所选日期中显示的初始月份基于 CSV 数据文件中的最大日期(initial_visible_month
);初始开始日期是最大日期减去 6 天(start_date
);初始结束日期是最大日期。
以下代码位于layouts.py
文件中,需要在 Dashboard 应用程序的每个“页面”上重复。
Code Block 10: Html Element for Date Picker in layouts.py File
我使用了一个回调函数和一个函数update_output
来向用户提供反馈。具体来说,我希望提供关于所选日期、所选天数以及相应的前期日期的文本反馈。例如,如果用户使用日期范围选择器选择了 2019 年的第 5 周和第 6 周,则对应的过去时间段将是 2019 年的第 3 周和第 4 周。下面的update_output
函数提供了这一功能。
Code Block 11: Callback and Function for Date Picker in layouts.py file
日期选择器元素为第一个数据表、第二个数据表、下载链接以及数据表下面的一组图表的回调提供输入。我将详细介绍这些回调是如何工作的,以及它们相关的输出。
向 CSS 添加一个修正,以便日期选择器不会隐藏在数据表后面
我必须纠正的一个问题是数据表模糊了日期选择器元素,所以我必须相应地纠正 CSS。
Code Block 12: CSS for change z-index of data table in custom.css file
8.构建第一个数据表
Figure 5: First Data Table with a Condensed View
仪表板中的第一个数据表显示了支出(与给定广告产品相关的成本)、网站会话、预订(交易)和收入等指标。这些指标根据在所选日期中选择的日期进行汇总,通常会显示所选日期范围内当前年度的数据、之前相应期间的数据、去年的数据,以及这些期间之间的百分比和绝对差异。
基于日期选择改变数据表中呈现的日期
我想要的第一个数据表的主要功能是使它具有交互性,由此显示的数据根据所选的日期而变化。首先,数据表元素需要包含在layouts.py
文件中,如下面的(简化)代码所示:
Code Block 13: Data Table Component in layouts.py File
数据表的不同参数包括:
id
:标识符,以便数据表可以被回调引用。columns
:表格中呈现的列;deletable
让用户能够在使用应用程序时删除列。editable=True
让用户能够在使用应用程序时更改表格中的数据。n_fixed_columns=2
冻结前两列(在我们的例子中是复选框和位置类型),因此当用户滚动整个数据表时,用户仍然可以查看复选框和位置类型。style_table
允许 CSS 样式应用于表格。row_selectable='multi'
允许用户通过复选框选择多行。这将根据选择更新下面的图表。selected_rows=0
包含最初选择的行的索引(如下图所示)。style_cell
允许将 CSS 样式应用于表格单元格。
我将在后续步骤中添加额外的参数,以便我们可以有条件的样式格式。在 pandas 中添加了数字格式,如美元符号、逗号和百分号,并定义为一系列格式化程序。
我应该注意,我没有在layouts.py
文件中为数据表指定data
参数。相反,数据表的data
参数将来自回调:
Code Block 14: Callback for First Data Table in layouts.py File
计算指标的变化,以及计算每次会话的成本、转换率和每次收购的成本。
因为我们需要计算指标的变化,以及 CPA、CPS 和转换率,这些都取决于“动态”选择的日期,所以我将这些计算放入一个单独的文件中,functions.py
。然后,我可以在不同的仪表板页面上重复使用这些功能。我还在这个文件中定义了格式化函数:
Code Block 15: Data Formatters in functions.py file
第一个数据表和第二个数据表的功能是相似的,所以我在这里只给出一个:
Code Block 16: update_first_datatable Function in functions.py
数据表元素、回调和函数之间的流程可以描述为:
Figure 6: Flow for the first data table
一种选择压缩数据表或完整数据表的方法。
我希望数据表的一个特性是能够显示表的“压缩”版本以及完整的数据表。因此,我在layouts.py
文件中包含了一个单选按钮来选择要呈现的表格版本:
Code Block 17: Radio Button in layouts.py
此功能的回调接受单选按钮的输入,并输出要在数据表中呈现的列:
Code Block 18: Callback for Radio Button in layouts.py File
这个回调稍微复杂一点,因为我要为条件格式添加列(我将在下面讨论)。本质上,正如下面的回调基于使用回调语句Output('datatable-paid-search', 'data'
选择的日期更改数据表中显示的数据一样,这个回调也基于使用回调语句Output('datatable-paid-search', 'columns'
选择的单选按钮更改数据表中显示的列。
有条件地对不同的数据表单元格进行颜色编码
利益相关者希望数据表具有的特性之一是,能够根据指标值突出显示数据表中的某些数字或单元格;例如,红色代表负数。然而,数据表单元格的条件格式有三个主要问题。
- 目前 Dash 数据表中缺少格式化功能。
- 如果在将数字包含到 Dash 数据表中之前对其进行了格式化(例如在 pandas 中),则数据表功能(如排序和过滤)将无法正常工作。
- Dash 数据表代码中有一个缺陷,其中条件格式不能正常工作。
尽管有上述限制,我最终还是格式化了熊猫数据表中的数字。我发现 Dash 中的条件格式不适用于格式化的数字(带逗号、美元符号、百分号等的数字)。).事实上,我发现 Dash 数据表用户指南的条件格式—突出显示单元格一节中描述的方法有一个错误:
Code Block 19: Conditional Formatting — Highlighting Cells
纽约市温度的单元格显示为绿色,即使该值小于 3.9。*我在其他场景中测试过,数字的条件格式似乎只使用了条件的整数部分(“3”而不是“3.9”)。用于条件格式的温度过滤器以某种方式截断了有效数字,并且只考虑数字的整数部分。我在 Dash 社区论坛上发布了关于这个 bug 的帖子,它已经在 Dash 的最新版本中被修复了。
*这已在 Dash 文档中得到纠正。
使用重身幽灵列的单元格的条件格式
由于单元格条件格式的上述限制,我想到了一种替代方法,在该方法中,我将“二重身”列添加到 pandas 数据框和 Dash 数据表中。这些二重身列要么是原始列的值,要么是原始列的值乘以 100(以克服条件筛选不考虑值的小数部分时的缺陷)。然后,可以将重影列添加到数据表中,但使用以下语句隐藏这些列:
Code Block 20: Adding Doppelganger Columns
然后,可以使用以下语法实现条件单元格格式:
Code Block 21: Conditional Cell Formatting
本质上,过滤器应用于“二重身”列,Revenue_YoY_percent_conditional
(过滤值小于 0 的单元格)。然而,格式化被应用于相应的“真实”列Revenue YoY (%)
。人们可以想象这种条件格式编排方法的其他用途;例如,突出显示异常值。
数据表的完整语句如下(奇数行和偶数行的条件格式,以及使用 doppelganger 方法突出显示高于特定阈值的单元格):
Code Block 22: Data Table with Conditional Formatting
我描述了使用下面数据表中的选定行来更新图形的方法。
9.构建下载数据链接
Figure 7: Download data link
我希望仪表板的一个特性是能够下载数据表中显示的数据。具体来说,我希望下载的数据根据选择的日期进行更新(并显示在数据表中)。此外,由于没有显示日期,有必要将日期添加到下载的文件中。此外,尽管数据表中的数据是格式化的(带有$
、%
和千个逗号分隔符),我还是希望下载的数据没有格式化。
有两个关键的 Plotly 社区线程帮助我在建立了这个功能,允许用户点击下载 Excel 和允许用户点击下载 CSV。
下载数据功能通过以下方式实现:
- 在
layouts.py
文件中有一个用于下载按钮的占位符。
Code Block 23: Placeholder for Download Button
- 要使下载链接正常工作,您需要以下模块:
Code Block 24: Import Statements to Enable Download Functionality
- excel 下载的回调放在
callbacks.py
文件中。回调从日期选择器元素获取start_date
和end_date
,并输出对下载链接的文件引用。 update_link
功能是根据开始和结束日期更新要提供的 URL 链接。- 函数
download_excel_1
获取 URL 值并将其拆分回start_date
和end_date
,这样我就可以根据开始和结束日期以及当前日期来命名filename
。
Code Block 25: Callback and function for excel download data link
- 函数
download_excel_1
还调用另一个函数update_first_download
,它与上面给出的update_first_download
函数非常相似,只是数据没有格式化。 - 下载的 Excel 文件根据产品名称、选择的开始和结束日期以及当前日期命名。开始和结束日期以及其他适当日期的列被添加到下载的数据文件中。
Figure 8: Snap shot of the downloaded data.
10.建立第二数据表
Figure 9: Data Table with Calculated Metrics
第二个数据表显示了诸如每次会话成本、转换率和每次会话成本之类的指标,这些指标是根据所选日期范围内选择的日期“动态”计算的。
第二个数据表的创建方式与第一个数据表相似,所以本教程不再赘述,但是完整的文件在 Github 上。
11.通过选择仪表板数据表中的行来更新图形
Figure 10: Digital Marketing Metric Graphs
数据表下方的图形显示按周汇总的指标,包括本年度的数据、去年的数据以及两者之间的百分比变化。
Figure 11: Diagram of callback and function to update graphs
更新图表的步骤如下:
- 在
layouts.py
文件中设置占位符。 - 在
callbacks.py
文件中为每组图形、仪表板的每一页创建回调。 - 构建一个函数,该函数根据 Dash 数据表中选择的产品列表过滤完整的产品列表,然后根据该选择创建一个 pandas 数据框。
- 然后,过滤后的数据帧被传递给另一个函数,
update_graph
,该函数(a)计算诸如每次会话成本、转换率和每次会话成本之类的指标,以及(b)生成图形输出。
这些步骤详述如下。第 12 节“动态更新图表和计算指标”详细介绍了第 4 步
第一步
在layouts.py
文件中,只有一个图形占位符:
Code Block 26: Placeholder for Graphs
第二步
在callbacks.py
文件中,每页上的每组图形都有一个回调函数:
Code Block 27: Callback for Graphs
回调从第一个数据表中获取输入,以及从日期选择器中获取输入,并通过id
、paid-search
输出到dcc.Graph
元素。
第三步
我遇到的一个挑战是,如何根据数据表中选择的产品来更新图表。
在第一个数据表的代码中,需要设置row_selectable
到multi
和selected_rows=[0]
的参数。前一个参数启用数据表中每一行旁边的复选框,而后一个参数确保所选行有初始值。参数n_fixed_columns
冻结数据表中的前两行,以便当用户启用完整的数据框时,它们是可见的(从而显示所有可用的列)。
以下是第一个数据表的简化代码块(在layouts.py
文件中):
Code Block 28: Simplified Data Table Definition
因此,图形的回调获得了selected_rows
。在更新图表的函数update_paid_search
中,通过按照仪表板页面类别过滤原始数据框(在本例中为付费搜索)并获得唯一放置类型的完整列表,构建了一个产品列表。然后,for
循环根据数据表中选择的产品列表过滤该列表。随后,通过根据所选产品列表过滤原始数据框并执行熊猫groupby
以及对花费、会话、预订和收入列求和,创建过滤数据框filtered_df
。图表的回调和函数update_paid_search
如下所示:
Code Block 29: Callback and Update Function for Graphs
12.动态更新图表和计算指标
每个指标的图表按周和数据表中选择的产品进行汇总(如上所述)。
我想要的图形和更新功能包括:
- 由于图表可以一次描述多个产品的指标,因此更新功能需要实时计算指标。
- 每个指标的图表应包括今年的值、去年的值以及年度间的百分比差异。这些数据应覆盖在同一张图表上,数值以线图显示,年度变化以条形图显示。
- 我希望缩放功能能够同时作用于所有的图形,这样,放大一个图形,就可以以相同的缩放级别放大其他图形。
完整的update_graph
函数(位于functions.py
文件中)如下:
Code Block 30: update_graph Function in functions.py File
为了将图表“组合”在一起,我使用了在https://plot.ly/python/subplots/中详细描述的子情节功能。update_graph
功能有以下主要元素:
- 指标的动态计算。
- 使用 Plotly 库中的
graph_objs
方法定义每个图形“轨迹”(记住通过import plotly.graph_objs as go
导入该方法)。具体来说,每个图形都用go.Scatter
方法定义:
Code Block 31: Trace Assignment for each Graph element
- 当我们调用
tools.make_subplots
时,定义了主图形及其参数。在应用程序开发期间,我发现潜在的错误来源是在添加额外的跟踪(rows=6
)时没有记住更改行数,以及确保标题的数量与图形的数量相同。这两种情况都可能导致应用程序失败。
Code Block 32: make_subplots To Set Parameters for Subplots
- 不同的子图“轨迹”被附加到主图形中,带有诸如
fig.append_trace(sessions_ty, 1, 1)
的语句,其中sessions_ty
是上面定义的轨迹名称;第一个数字1
是图形编号,最后一个数字是列编号(在任何情况下都是1
,因为我们只有一列)。为了在下一步中帮助我,我已经为每个跟踪添加了注释掉的数字。
Code Block 33: Appending Trace to the Figure
为了覆盖每年的变化,我必须有几个 update 语句,并为每个覆盖图(每年的变化图)添加新的 y 轴。这些重叠图形所需的语法有点复杂。
Code Block 34: Code to Overlay Year-to-Year Change Graphs
- 例如,在第一个 update 语句中,语句
fig['data'][2]
中的索引号2
引用第三个 trace,sessions_yoy
(因为 Python 是零索引的)。
下图有助于可视化组合图中各种元素的索引。
Figure 12: Schematic of the Different Axis Indexes
- 语句
yaxis='y7'
中的 y 轴名称y7
需要是7
,因为已经有 6 个 y 轴(每个指标一个:会话、花费、预订、cpa、cps 和 cr。对于每个指标,今年和去年的数据共享同一个左侧 y 轴)。因此,我们需要从7
开始对右侧 y 轴进行编号。 - 我们需要使用
fig['layout']['yaxis']
语句为每个额外的 y 轴分配参数。具体来说,第一个右侧轴表示会话的逐年变化,与第一个图表中的其他会话轨迹重叠。因此,我们需要相应地分配参数:overlaying='y1', anchor='x1'
,当然,我们需要通过设置side='right'
将其分配到右侧。此外,我用以下内容更新了这组图表的标题:
Code Block 35: Update Title of Graphs
最后,我需要用下面的语句更新整个图形布局。我应该注意到下面有几个参数被注释掉了,因为我还在试验不同的参数。
Code Block 36: Update Overall Figure Layout
13.绘图工具
我应该注意到,在 Dash 中有几个有用的工具可以用来操作图形。如果您将鼠标悬停在图表右上方,就可以查看这些工具。
Figure 13: Plotly Graph Tools
使用这些工具,您可以:
- 拖动以放大,双击以返回原始图形。
- 拖动图形的角沿一个轴缩放。
- 双击以自动缩放单个轴。
- 更改悬停模式以比较数据或调查单个数据点。
当然,最好的工具之一是下载图片的能力:
Figure 14: Downloaded image of the graphs
14.部署仪表板
我基本上遵循了 Dash 用户指南中的部署 Dash 应用指南,做了一些改动。具体来说,我使用以下步骤在 Heroku 上部署了仪表板:
- 步骤 1 :我已经在前一步中为我的仪表板代码创建了一个文件夹。
Code Block 37: Mkdir and cd Code
- 第二步:用
git
初始化文件夹。我之前为 Dash 设置了一个 conda 环境,而不是使用venv
。
Code Block 38: Init Git and Active Dash Conda Environment
我已经使用conda
或pip
安装了应用程序的依赖项:
Code Block 39: Pip Installation of Dash and other Modules
您还需要一个新的依赖项gunicorn
,用于部署应用程序(上面代码段中的第 10 行)。
- 第三步:用一个 app (
app.py
)、一个.gitignore
文件、requirements.txt
文件、Procfile
文件初始化文件夹进行部署。我们只需要最少的app.py
,因为我们使用多个文件定义我们的应用程序。您需要在项目文件夹中创建以下文件。
app.py
Code Block 40: app.py file (previously created)
.gitignore
Code Block 41: .gitignore file
还有一个Procfile
文件:
Code Block 42: Procfile file
您还需要生成一个requirements.txt
文件。您可以通过以下方式实现这一点:
Code Block 43: Create new requirements.txt file
- 第四步:初始化 Heroku,添加文件到 Git,部署。在初始化 Heroku 之前,你需要安装 Heroku 命令行界面(CLI ),或者在 https://devcenter.heroku.com/articles/heroku-cli 用他们的安装程序安装,或者在 Mac 上用家酿软件安装。
Code Block 44: Initialize Heroku and Deploy
您应该可以在https://my-dash-app.herokuapp.com
查看您的应用程序(将my-dash-app
更改为您的应用程序的名称)。
- 第五步:更新代码,重新部署。当您修改应用程序的任何元素时,您需要将更改添加到 git,并将这些更改推送到 Heroku。此外,每当我更改底层 CSV 数据文件时,您都需要将新数据集推送到 Heroku。
Code Block 45: Pushing changes to Heroku via Git
我应该注意,如果您在部署 Heroku 时遇到问题,请先尝试部署一个简单的应用程序,并测试您是否正确地执行了每个步骤。例如,我发现我需要将以下内容添加到index.py
文件中,以便 Heroku 部署能够工作:from app import server
。
解决 Custom.css 文件和身份验证的问题
另外,我发现当我给我的 app 添加认证时,app 已经无法访问我的custom.css
文件,所以我需要在 codepen.io 上创建一个 css 文件,并将其包含在外部 css 文件列表中(我假设这是 Dash 中的一个 bug)。
Dash 部署服务器
Plotly 还提供了一个 Dash 部署服务器
要在商业 IT 环境中轻松部署应用程序,请从关键任务项目的支持计划和研讨会开始,或者联系我们世界一流的工程团队进行定制功能开发或概念验证应用程序开发。
我应该指出,我与 Plotly 没有任何关系。
15.包扎
从开始到结束,这个项目花了大约两个半星期。我以前没有使用过 Dash,使用 Plotly 的经验有限。我用来构建仪表板的一些方法包括:
- 首先构建仪表板的最小部分。基本上,我不会试图一次解决所有问题。在将元素添加到整个仪表板之前,我一次构建一个元素,通常是单独构建。
- 为了确保我的 python 语法是正确的,我使用了一个 Jupyter 笔记本来记录原始数据框,并以分段的方式应用每个更改。
- 我会对应用程序进行小的增量更改,然后进行测试。冲洗并重复。
- 我首先开发了一个部分,并让它正常工作,达到了我的要求。然后,我会将此部分复制并粘贴到其他部分,并进行适当的更改。
- 我为最后一步保存了部署。我在本地测试了所有东西。
我希望更新仪表板的内容包括:
- 向每个图表轴添加周,很可能使用注释。
- 让图表的 x 轴跨越几年,而不是只描绘 2018 年或 2019 年。
- 为报告添加“打印 PDF”按钮。我试着实现了一个,但是还没有成功。
- 添加带有元数据的页脚(数据源、提取数据的日期、提取数据的位置等。)
谢谢你读到这里。我知道这有点让人不知所措,但我基本上把事情分成了易于管理的几个部分。
16.Dash 资源
这里有一些资源可以进一步帮助您使用 Dash:
- Dash 用户指南
- Udemy 课程(我没有上过这个在线课程,所以我不能对此发表评论。
- Dash 社区论坛
- Github 上的超赞 Dash 资源指南
如何构建基于内容的电影推荐系统
创建基于内容的电影推荐系统
Designed by rawpixel.com / Freepik
在这篇文章中,我将尝试解释我们如何在没有用户数据的情况下创建一个推荐系统。我还将分享一个我用 Python 做的例子,并一步步告诉你它是如何工作的。
我不打算单独解释推荐系统的类型,因为它在互联网上很容易找到。所以,我们先来说说基于内容的推荐系统吧!
什么是基于内容的推荐系统?
基于内容的推荐系统不包括从除你之外的用户那里检索的数据。它只是通过识别与你喜欢的产品相似的产品来帮助你。
例如,您有一个在线销售商品的网站,但您还没有注册用户,但您仍然想向网站的访问者推荐产品。在这种情况下,基于内容的推荐系统将是您的理想选择。
然而,基于内容的推荐系统是有限的,因为它们不包含其他用户数据。它也不能帮助用户发现他们潜在的品味。
举个例子,假设用户 A 和用户 B 喜欢剧情电影。用户 A 也喜欢喜剧电影,但是既然你没有那方面的知识,你就继续提供剧情电影。最终,你排除了用户 B 可能喜欢的其他选项。
反正!在创建这个系统之前,我们先来讨论几个术语。先说核密度估计!
核密度估计
核密度估计是一个非常有用的统计工具,有一个吓人的名字。通常简称为 KDE ,这是一种让你在给定一组数据的情况下创建平滑曲线的技术。
KDE plot example from seaborn
KDE 是一种帮助确定数据分布密度的方法。它提供了许多点位于何处和不在何处的信息。因此,在一维数组中,它通过将最低密度点(局部最小值)与最高密度点(局部最大值)分开来帮助您进行聚类。只要遵循这些步骤,
- 计算密度
- 寻找局部最小值和局部最大值
- 创建集群
余弦相似性
余弦相似度是一种度量向量之间相似度的方法。数学上,它计算两个向量之间角度的余弦值。如果两个向量之间的角度为零,则相似性被计算为 1,因为零的余弦为 1。所以这两个向量是相同的。任何角度的余弦值从 0 到 1 不等。因此,相似率将从 0 变化到 1。该公式表示如下:
Cosine similarity formula
现在够了!我们来编码吧!
特征重要性
我想为每部电影或连续剧设定一个分数,并且我需要为每个特征设定一个系数,所以我将查看特征的重要性。
数据集如下:
Sample data
通过合并在https://datasets.imdbws.com共享的文件,你可以很容易地获得这个数据集。我通过将 title.basics.tsv.gz 的与 title.ratings.tsv.gz 的合并得到这个数据,之后,我删除了一些特征。例如, end_year 字段包含了太多的空值,所以我删除了它。更多详细信息,请查看我的知识库。在本文最后分享。
我还得多说一个细节,我已经通过使用标签编码器将种类字段转换为整数字段。
Feature importances
正如你在上面看到的,我已经尝试了三种不同的方法。首先是由 随机森林 模型直接提供的特性的重要性。
另一个是 排列重要性 。这种方法通过对每个预测值使用随机重排技术来直接测量磁场对模型的影响。它保持了变量的分布,因为它使用了随机重排技术。
最后是 降列特征重要度 。这种方法是完全直观的,每次它删除一个特征,并将其与使用所有列的模型进行比较。它通常要安全得多,但处理时间可能会很长。处理时间对我们的数据集来说并不重要。
结果是这样的:
Feature importance results
我们在这些方法中选择了删除列特征重要性方法。正如我们之前指出的,它更加可靠,当我们看一眼结果时,它们对计算分数更有意义。
**dataset['score'] = (
0.4576 * dataset['num_votes'] +
0.3271 * dataset['runtime'] +
0.3517 * dataset['start_year'] +
0.0493 * dataset['kind']
)**
使聚集
我将使用分数来创建聚类。所以我可以推荐平均分数相同的电影。
我有一个分数的一维数组,我可以用 KDE 聚类。我用这个代码来看分数的分布:
**import matplotlib.pyplot as plt
import seaborn as snsplt.figure(figsize=(9, 6))
sns.distplot(dataset['score'])
plt.axvline(18000, color='r');**
我得到了这样一张图表,
Score distribution
我加了一条竖线 18000,因为密度在 650 到 18000 之间。如果我在应用 KDE 时给你大于 18,000 的点,它会将所有小于 18,000 的点收集在一个聚类中,这不是我们想要的,因为这会降低多样性。
正如我在文章开头提到的,我应用了 3 个阶段对 KDE 进行聚类。
- 计算密度
**from sklearn.neighbors.kde import KernelDensityvals = dataset['score'].values.reshape(-1, 1)
kde = KernelDensity(kernel='gaussian', bandwidth=3).fit(vals)
s = np.linspace(650, 18000)
e = kde.score_samples(s.reshape(-1, 1))**
2.寻找局部最小值和局部最大值
**from scipy.signal import argrelextremami = argrelextrema(e, np.less)[0]
ma = argrelextrema(e, np.greater)[0]points = np.concatenate((s[mi], s[ma]), axis=0)
buckets = []
for point in points:
buckets.append(point)buckets = np.array(buckets)
buckets.sort()**
3.创建集群
**dataset['cluster'] = buckets.searchsorted(dataset.score)**
文本相似度
最后,我计算了类型之间的相似性,以便能够尽可能准确地推荐同一类型的电影。为此我使用了 TF-IDF 和线性内核。因此,在背景中使用余弦相似性来寻找相似性。
**from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import linear_kerneltfidf_vectorizer = TfidfVectorizer()
matrix = tfidf_vectorizer.fit_transform(dataset['genres'])kernel = linear_kernel(matrix, matrix)**
现在就来看看推荐吧!
**def get_recommendations2(movie_index):
print(dataset.iloc[movie_index])
print('**' * 40)
sim_ = list(enumerate(kernel[movie_index]))
sim = sorted(sim_, key=lambda x: x[1], reverse=True)
index = [i[0] for i in sim if i[0] != movie_index and i[1] > .5]
cond1 = dataset.index.isin(index)
cond2 = dataset.cluster == dataset.iloc[movie_index]['cluster'] selected = dataset.loc[cond1 & cond2] \
.sort_values(by='score', ascending=False).head(20) print(selected[['title', 'cluster', 'genres']])**
这对我来说似乎很有用!如果你想看更详细的代码,用 烧瓶 上菜,用 橡皮筋搜索 索引电影,用 docker ,你可以看看我的资源库:
** [## egemenzeytinci/recommovie
对于所有选项,克隆存储库,$ git 克隆 https://github.com/egemenzeytinci/recommovie.git 构建并运行…
github.com](https://github.com/egemenzeytinci/recommovie)
感谢您的阅读!
参考
- Eryk Lewinson,以随机森林为例解释特征重要性 (2019)
- 马修·康伦**,**,核密度估计
- 马修·奥弗比, 1D 与 KDE (2017)
- 计数矢量器,tfidf 矢量器,预测评论 (2018)**
如何为 Tensorflow 构建自定义数据集
Tensorflow 激励开发人员在想到的几乎任何领域尝试他们令人兴奋的人工智能想法。在 ML 社区中有三个众所周知的因素,它们构成了一个好的深度神经网络模型,可以做神奇的事情。
- 模型架构
- 高质量的培训数据
- 足够的计算能力
我感兴趣的领域是实时通信。想出可以为 RTC 应用增加价值的实际 ML 用例是容易的部分。我最近写了一些关于这些的文章。
正如我的共同创始人和好朋友 Jean Deruelle 指出的,如果我们走进环境计算,新一代通信设备无缝增强家庭和工作体验,会有更多相邻的用例。
所以我想构建一个简单的原型,并直接将 Restcomm 连接到 Tensorflow。经过几天的研究,我意识到没有简单的方法将实时流音频/视频媒体(SIP/RTP)输入 tensorflow 模型。类似于 Google Cloud 的语音转文本流 gRPC API 的东西本来是一个可以接受的初始后备,但我在开源 Tensorflow 社区中没有找到。
有多种方法可以从离线的音频文件和视频文件中读取,但这与处理实时延迟敏感的媒体流完全不同。
最终,我的搜索将我带到了由唐勇领导的 Tensorflow IO 项目。TF IO 是一个年轻的项目,有一个由 Google、IBM 和其他公司支持的不断发展的社区。Yong 指给我一个公开的 github 问题,等待贡献者的现场音频支持。这开始了一次愉快的谈话。几个周末后,我鼓起足够的勇气接受了一个小小的编码挑战——为 PCAP 网络捕获文件实现一个新的 Tensorflow 数据集。
PCAP 文件与实时媒体流密切相关,因为它们是网络活动的精确历史快照。PCAP 文件能够记录和重放进入媒体处理软件的实际网络数据包,包括丢包和时间延迟。
回到本文的主题——我现在将向您介绍构建 TF PcapDataset 并将其贡献给 Tensorflow IO 项目的主要步骤:
- Fork Tensorflow IO 和从源构建
- 查看源树中的相邻数据集,选择一个最接近 pcap 的数据集。我利用了来自文本、 cifar 和拼花的代码。还有一份关于创建 TF ops 的文件被证明是有帮助的。
- 在 gitter 频道上寻求帮助。有些人会在几小时内关注并回复。我从斯蒂芬·阿普霍夫和勇那里得到了宝贵的建议。还有每月电话会议,在那里任何人都可以就项目问题发表意见。
- 准备好后提交一个拉取请求。TF IO 团队响应迅速,支持性很强,通过调整和修复来指导贡献者满足最佳实践。
第 2 步是我花了大部分周末业余时间学习 TF 基础设施和 API 的一步。让我给你分析一下。
从根本上讲,TF 是一个在每个节点都有操作的图结构。数据进入图中,操作将数据样本作为输入,处理这些样本并将输出传递给图中其节点所连接的下一个操作。下图是来自官方文档的 TF 图示例。
操作使用名为 tensors 的常见数据类型(因此得名 TensorFlow)。术语张量有数学定义,但张量的数据结构本质上是一个 n 维向量:0D 标量(数字、字符或字符串)、标量的 1D 列表、标量的 2D 矩阵或向量的更高维向量。
在将数据输入到 TF 模型之前,必须对其进行预处理并将其格式化为张量数据结构。这种张量格式要求是由于深度神经网络中广泛使用的线性代数,以及这些结构在 GPU 或 TPU 上应用计算并行性的可能优化。
它有助于理解 TF 数据集的优势和所有开箱即用的便利功能,如批处理、映射、混排、重复。这些函数使得利用有限的数据量和计算能力来构建和训练 TF 模型变得更加容易和高效。
数据集和其他 TF 操作可以用 C++或 Python 构建。我选择 C++路线只是为了学习一些 TF C++框架。然后我用 Python 把它们包起来。以后打算写几个纯 Python 数据集,应该会简单一点。
让我们看一下 TF IO 数据集的源代码文件结构。
Source code directory structure for the TF IO pcap Dataset
Tensorflow 使用 Bazel 作为构建系统,谷歌在 2015 年开源了该系统。下面是 PcapDataset 构建文件。它声明了动态 pcap 库的公共名称(_pcap_ops.so)。列出了要构建的两个源文件(pcap_input.cc 和 pcap_ops.cc)。并声明了构建所需的一些 TF 依赖项。
Main Bazel BUILD file for the pcap dataset
下一个重要的源文件是 pcap_ops.cc,我们在其中声明了 TF ops,它将注册到 TF 运行时环境中,并可用于 TF 应用程序中。
这里的大部分代码都是样板文件。它说我们正在引入一个可以读取 pcap 文件的 PcapInput 操作和一个由 PcapInput 填充的 PcapDataset 操作。两者之间的关系将在稍后变得更加明显。
从我开始我的贡献工作直到它被 TF master 分支接受,在基本的 TF 2.0 框架中引入了一些简化,减少了我的文件中的样板代码。我怀疑在不久的将来会有更多这样的简化。
TF 的核心团队明白,为了吸引更多的贡献者,降低进入门槛是很重要的。新的贡献者应该能够只关注他们正在编写的全新代码,而不要为与 TF 环境交互的细节伤脑筋,直到他们为此做好准备。
包中的下一个文件是 pcap_input.cc 。那里是大部分重物搬运的地方。我花了相当多的时间来编写和测试这个文件。
它有一个部分声明了 PcapDataset、PcapInput 和 PcapInputStream 之间的关系。我们将会看到它们各自的作用。
PcapInputStream 包含从原始 pcap 文件中读取并将其转换为张量的大部分逻辑。为了了解输入的味道,这里有一个用 CocoaPacketAnalyzer 查看的测试 http.pcap 文件的截图。
CocoaPacketAnalyzer view of http.pcap
让我跳过特定于 pcap 文件的逻辑,指出一些从原始二进制文件数据到张量转换的定义元素。
Read a packet record from the pcap file and convert to tensors
此 ReadRecord 行从 pcap 文件中读取下一个 pcap 包,并填充两个局部变量:packet_timestamp double 和 packet_data_buffer 字符串。
ReadRecord(packet_timestamp, &packet_data_buffer, record_count);
如果成功填充了新的 pcap 记录,标量将被放入各自的张量占位符中。结果输出张量的形状是一个有两列的矩阵。一列保存每个读取的 pcap 数据包的时间戳标量。另一列将相应的数据包数据保存为字符串。输出张量(矩阵)中的每一行对应于一个 pcap 分组。
Processing pcap file input to TF tensor output
Tensor timestamp_tensor = (*out_tensors)[0];
timestamp_tensor.flat<double>()(*record_read) = packet_timestamp;Tensor data_tensor = (*out_tensors)[1];
data_tensor.flat<string>()(*record_read) = std::move(packet_data_buffer);
out_tensors 是从 PcapDataset 请求新批次时准备的占位符张量。那是在这里完成的;在读循环之前。
使用类型化平面函数将 packet_timestamp 标量放在第一列(index [0])和(*record_read)行。数据包数据缓冲区分别位于第二列(索引[1])和同一(*记录读取)行。
这涵盖了 C++代码的关键元素。现在让我们看看 Python 文件。
init。顶层 pcap 目录级别的 py 指示 TF Python 文档生成器如何遍历 Python 代码并提取 API 参考文档。你可以在这里阅读更多关于文档最佳实践。
上面的代码指示 Pyhton API 文档生成器专注于 PcapDataset 类,忽略该模型中的其他代码。
接下来, pcap_ops.py 包装 C++数据集 op,并使其对 Python 应用程序可用。
C++动态库按如下方式导入:
from tensorflow_io import _load_library
pcap_ops = _load_library('_pcap_ops.so')
数据集构造函数的主要作用之一是提供关于它生成的数据集张量类型的元数据。首先,它必须描述单个数据样本中的张量类型。PcapDataset 样本是两个标量的向量。一个用于 tf.float64 类型的 pcap 分组时间戳,另一个用于 tf.string 类型的分组数据
dtypes = [tf.float64, tf.string]
Batch 是通过神经网络的一次正向/反向传递中的训练样本数。在我们的例子中,当我们定义批量的大小时,我们也定义了张量的形状。
当多个 pcap 数据包被分组为一批时,时间戳(tf.float64)和数据(tf.string)都是一维张量,具有 tf 的形状。TensorShape([batch])。
由于我们事先不知道总样本数,总样本数也不一定能被批量大小整除,所以我们宁愿把形状设为 tf。TensorShape([None])给我们更多的灵活性。
批量大小为 0 是一种特殊情况,其中每个单独张量的形状退化为 tf。TensorShape([]),或 0-D 标量张量。
shapes = [
tf.TensorShape([]), tf.TensorShape([])] if batch == 0 else [
tf.TensorShape([None]), tf.TensorShape([None])]
快到了。我们只需要一个测试案例。test_pcap_eager.py 在从 http.pcap 采样的同时练习 PcapDataset。
测试代码很简单。遍历所有 pcap 数据包,并根据已知常数测试第一个数据包中的值。
为了构建 PcapDataset 并运行其测试,我使用了本地 io 目录中的以下代码行:
$ bazel build -s --verbose_failures //tensorflow_io/pcap/...
$ pytest tests/test_pcap_eager.py
就是这样!希望这有助于您构建自己的自定义数据集。当你这样做的时候,我希望你会考虑把它贡献给 TF 社区,以加速开源 AI 的进步。
欢迎在评论区提问。我将尽力回答。
如何为你的机器学习项目建立数据集
你会为你的组织考虑人工智能吗?您已经确定了一个 ROI 得到验证的用例?完美!但没那么快…你有数据集吗?大多数公司都在努力建立一个人工智能就绪的数据集,或者干脆忽略这个问题,我想这篇文章可能会对你有所帮助。
让我们从基础开始…
一个数据集是一个数据的集合。换句话说,数据集对应于单个数据库表或单个统计数据矩阵的内容,其中表的每一列代表一个特定变量,每一行对应于所讨论的数据集的给定成员。
在机器学习项目中,我们需要一个训练数据集。是实际的数据集,用于训练模型执行各种动作。
我为什么需要数据集? ML 非常依赖数据,没有数据,一个“AI”是不可能学习的。是让算法训练成为可能的最关键的方面……无论你的 AI 团队有多伟大,或者你的数据集有多大,如果你的数据集不够好,你的整个 AI 项目都会失败!我见过一些很棒的项目失败,因为我们没有一个好的数据集,尽管我们有完美的用例以及非常熟练的数据科学家。
在训练数据的语料库上训练有监督的 AI。
在人工智能开发过程中,我们总是依赖数据。从训练、调整、模型选择到测试,我们使用三个不同的数据集:训练集、验证集和测试集。供您参考,验证集用于选择和调整最终的 ML 模型。
你可能认为收集数据就足够了,但事实恰恰相反。在每个人工智能项目中,对数据集进行分类和标记花费了我们大部分的时间,尤其是那些足够准确以反映市场/世界现实愿景的数据集。
我想向你介绍我们需要的前两个数据集——训练数据集和测试数据集,因为它们在你的人工智能项目中用于不同的目的,项目的成功在很大程度上取决于它们。
- 训练数据集用于训练算法,以理解如何应用神经网络等概念,学习并产生结果。它包括输入数据和预期输出。
训练集占总数据的大部分,约 60 %。在测试中,模型在被称为调整权重的过程中与参数相适应。
- 测试数据集用于评估你的算法用训练数据集训练的有多好。在人工智能项目中,我们不能在测试阶段使用训练数据集,因为算法已经提前知道了预期的输出,这不是我们的目标。
测试集代表 20%的数据。通常通过人工验证,确保测试集是与验证的正确输出分组在一起的输入数据。
根据我的经验,在测试阶段之后尝试进一步调整是一个坏主意。这可能会导致过度拟合。
什么是过度拟合?
对于数据科学家来说,一个众所周知的问题是… 过度拟合是一个建模错误,当一个函数过于接近有限的数据点集时就会出现这种错误。
需要多少数据?所有项目在某种程度上都是独一无二的,但我认为你需要的数据是正在构建的模型中参数数量的 10 倍。任务越复杂,需要的数据越多。
我需要什么类型的数据?我总是通过向公司决策者提出精确的问题来启动人工智能项目。你想通过 AI 达到什么目的?根据您的回答,您需要考虑您实际需要哪些数据来解决您正在处理的问题。对您需要的数据做一些假设,并仔细记录这些假设,以便您可以在以后需要时测试它们。
以下是一些对你有帮助的问题:
- 你能为这个项目使用什么数据?你必须对你能使用的所有东西有一个清晰的了解。
- 你希望拥有哪些不可用的数据?我喜欢这个问题,因为我们总能以某种方式模拟这些数据。
我有一个数据集,现在怎么办?
没那么快!你应该知道所有的数据集都是不准确的。在项目的这个时刻,我们需要做一些数据准备,这是机器学习过程中非常重要的一步。基本上,数据准备就是让你的数据集更适合机器学习。它是一组程序,消耗了花在机器学习项目上的大部分时间。
即使你有数据,你仍然会遇到数据质量的问题,以及隐藏在你的训练集中的偏见。简单来说,训练数据的质量决定了机器学习系统的性能。
你听说过 AI 偏见吗?
人工智能很容易受到影响……多年来,数据科学家发现,一些用于训练图像识别的流行数据集包含性别偏见。
因此,人工智能应用程序需要更长的时间来构建,因为我们试图确保数据是正确的,并正确集成。
数据不够怎么办? 可能会发生这样的情况,你缺乏集成一个人工智能解决方案所需的数据。我不会对你撒谎,如果你仍然依赖于纸质文档或其他工具,建立一个人工智能就绪的数据集需要时间。 csv 文件。我建议你首先花时间建立一个现代的数据收集策略。
如果你已经确定了你的 ML 解决方案的目标,你可以要求你的团队花时间创建数据或者外包这个过程。在我最近的项目中,公司想要建立一个图像识别模型,但是没有图片。因此,我们花了几周时间拍摄照片来建立数据集,并找到未来客户为我们做这件事的方法。
你有数据策略吗?在一个组织中创造一种数据驱动的文化可能是一名人工智能专家最难的部分。当我试图解释为什么公司需要数据文化时,我可以在大多数员工的眼中看到沮丧。事实上,数据收集可能是一项烦人的任务,会加重员工的负担。然而,我们可以自动化大部分的数据收集过程!
另一个问题可能是数据的可访问性和所有权…在我的许多项目中,我注意到我的客户有足够的数据,但是这些数据被锁起来,很难访问。您必须在组织中的数据仓库之间创建连接。为了获得特殊的见解,你必须从多个来源收集数据。
关于所有权,合规性也是数据源的一个问题—仅仅因为公司可以访问信息,并不意味着它有权使用它!请不要犹豫,询问您的法律团队(欧洲的 GDPR 就是一个例子)。
质量、范围、数量! 机器学习不仅仅是关于大数据集。事实上,你不需要向系统提供任何相关领域的所有已知数据。我们希望向系统提供精心策划的数据,希望它能够学习,或许在边际上扩展人们已经拥有的知识。
大多数公司认为,收集每一个可能的数据,将它们结合起来,让人工智能找到洞察力就足够了。
当构建数据集时,您应该以数据的多样性为目标。我总是建议公司收集内部和外部数据。目标是建立一个独特的数据集,让你的竞争对手难以复制。机器学习应用确实需要大量的数据点,但这并不意味着模型必须考虑广泛的特征。
我们想要与项目相关的有意义的数据。你可能拥有某个主题的丰富、详细的数据,但这些数据并不十分有用。人工智能专家会问你一些精确的问题,关于哪些领域真正重要,以及这些领域如何可能对你获得的洞察力的应用产生影响。
在我最近的任务中,我必须帮助一家公司建立一个用于营销目的的图像识别模型。这个想法是建立和确认一个概念证明。这家公司没有数据集,除了一些他们产品的 3D 渲染。我们希望人工智能能够识别产品,阅读包装,确定它是否适合客户,并帮助他们了解如何使用它。
我们的数据集由 15 种产品组成,每种产品我们都有 200 张照片。这个数字是合理的,因为它仍然是一个原型,否则,我会需要更多的图片!这假设你正在利用迁移学习技术。
在拍摄照片时,我们需要不同的背景、光线条件、角度等。
每天,我都会从训练集中随机选择 20 张图片并进行分析。这让我对数据集的多样性和准确性有了一个很好的了解。
每次我这样做的时候,我都会发现一些关于我们数据的重要信息。这可能是具有相同角度的不平衡数量的图片、不正确的标签等。
一个好主意是从一个已经在大型现有数据集上预先训练好的模型开始,并使用迁移学习来用您收集的较小数据集对其进行微调。
数据预处理
好吧,让我们回到我们的数据集。在这一步,你已经收集了你认为对你的人工智能项目来说必要的、多样的和有代表性的数据。预处理包括从完整的数据集中选择正确的数据并建立训练集。以这种最佳格式将数据放在一起的过程被称为特征转换。
- **格式:**数据可能分散在不同的文件中。例如,使用不同货币、语言等的不同国家的销售结果。这些数据需要收集在一起形成一个数据集。
- **数据清理:**在这一步,我们的目标是处理丢失的值,并从数据中删除不需要的字符。
- **特征提取:**在这一步,我们重点分析和优化特征的数量。通常,团队成员必须找出哪些特征对于预测是重要的,并选择它们以实现更快的计算和更低的内存消耗。
完美的数据策略
最成功的人工智能项目是那些在服务/产品生命周期中整合数据收集策略的项目。的确,数据收集不可能是一系列一次性的练习。它必须内置于核心产品本身。基本上,每次用户使用你的产品/服务时,你都想从互动中收集数据。目标是利用这种持续不断的新数据流来改进您的产品/服务。
当您达到这种数据使用水平时,您添加的每个新客户都会使数据集更大,从而使产品更好,这会吸引更多的客户,从而使数据集更好,以此类推。这是某种良性循环。
最好的、面向长期的 ML 项目是那些利用动态的、不断更新的数据集的项目。建立这种数据收集策略的好处是,你的竞争对手很难复制你的数据集。有了数据,人工智能变得更好,在某些情况下,比如协同过滤,它是非常有价值的。协同过滤基于用户之间的相似性提出建议,它将随着访问更多数据而改进;一个人拥有的用户数据越多,该算法就越有可能找到相似的用户。
这意味着您需要一种策略来持续改进您的数据集,只要它对提高模型准确性有任何用户好处。如果可以的话,找到创造性的方法来利用微弱的信号来访问更大的数据集。
让我再一次使用图像识别模型的例子。在我上一次的体验中,我们设想并设计了一种方式,让用户给我们的产品拍照并发送给我们。这些照片将被用于我们的人工智能系统,使我们的系统随着时间的推移变得更加智能。
另一种方法是提高标签管道的效率,例如,我们过去非常依赖一个系统,该系统可以建议由模型的初始版本预测的标签,以便贴标机可以更快地做出决定。
最后,我看到一些公司只是雇佣更多的人来标记新的培训投入……这需要时间和金钱,但很有效,尽管在传统上没有这种支出预算的组织中,这可能很困难。
不管大多数 SaaS 公司怎么说,机器学习需要时间和准备。每当你听到人工智能这个术语,你一定会想到它背后的数据。我希望这篇文章能帮助你理解数据在 ML 项目中的关键作用,并说服你花时间反思你的数据策略。
如何建立一个没有框架的深度神经网络
了解如何使用 NumPy 构建可扩展的深度神经网络,并将其用于图像分类
Photo by Sneaky Elbow on Unsplash
介绍
之前,我们从零开始构建了一个非常简单的神经网络用于图像分类。尽管如此,我们还是获得了 70%的准确率。
现在,我们将在不使用框架的情况下构建更深层次的神经网络。以下几段代码可扩展到任何神经网络架构。这意味着你可以使用不同数量的层和不同的激活和成本函数,只需对代码做最小的改动!
你可以在 Github 上抓取总结代码的两个笔记本。第一个笔记本构建必要的函数,第二个笔记本应用它们进行图像分类。
作为先决条件,我强烈推荐你阅读我的上一篇文章,因为它包含了关于构建神经网络的不同步骤的详细解释。
现在,让我们开始编码吧!
关于机器学习、深度学习和人工智能的实践视频教程,请查看我的 YouTube 频道。
The feeling you will get when you are done building the neural network!
构建神经网络
步骤 1:初始化权重和偏差
像往常一样,构建神经网络的第一步是初始化权重矩阵和偏差矩阵。
请记住,权重必须是随机的非零值,而偏差可以初始化为 0。
对于这一步,函数非常简单:在神经网络的层数上循环,并为您的输入初始化每个权重和偏差。在代码中,应该是这样的:
步骤 2:正向传播模块
现在,我们将构建正向传播模块。在前向传播中,我们需要将加权和提供给激活函数。
该模块将分三步构建:
- 为加权和写一个函数
- 编写一个函数,将加权和提供给激活函数
- 编写一个函数,在最后一层使用 sigmoid 函数,在所有前面的层使用 ReLU
可选阅读:什么是 ReLU?
ReLu 代表RectivedLlinearUnit,表示为:
ReLU function
看起来是这样的:
ReLU plot
如你所见,正值的导数是 1,负值的导数是 0。请注意,函数在 0 处不可微。
实际上,激活函数通常是正的,这意味着导数将大于 0。因此,参数将更新得更快,并且网络最终通过 ReLU 学习得更快。
通常,如果您不确定使用什么激活函数,ReLU 是一个很好的默认函数,在大多数情况下都能很好地工作。
因此,对于加权和,函数很简单:
够简单!现在,我们构建一个函数来将结果提供给激活函数(ReLU 或 sigmoid):
现在,我们想在最后一层使用 sigmoid 函数,并依赖于所有先前的层。这是特定于该应用的,因为我们将执行二值图像分类,所以在最后一层使用 sigmoid 函数是有意义的。
太好了!
步骤 3:定义成本函数
当然,我们现在需要定义一个成本函数。然后,该函数将被最小化,并且它将驱动对权重和偏差矩阵的更新。
为此,我们使用交叉熵损失表示为:
Cross-entropy loss function
现在,我们用代码实现了一个矢量化版本:
成本函数到此为止!
第四步:反向传播
与正向传播类似,我们将分三步构建反向传播模块:
- 计算重量和偏差的导数
- 计算激活函数的导数
- 对整个网络执行反向传播
首先,我们为权重和偏差的导数写一个函数:
然后,我们找到激活函数的导数:
最后,我们编写一个函数在整个网络上执行反向传播:
现在这已经完成了,我们需要更新我们的参数!
步骤 5:用梯度下降更新参数
现在,我们简单地定义梯度下降来更新我们的参数,以便最小化交叉熵成本函数:
完美!我们现在准备在一个用于图像分类的神经网络中使用上述所有功能!
使用神经网络
随着所有助手功能的建立,我们现在可以在深度神经网络中使用它们来识别它是否是一张猫图片,并看看我们是否可以在我们的以前的模型上进行改进。
查阅笔记本导入合适的库并预处理数据。
在这种情况下,我们将训练一个 5 层网络。我们定义每个维度的维度,并按如下方式训练模型:
训练此模型需要几分钟时间。如果一切都做对了,你应该看到我们达到了 80%的测试准确率!这比我们以前的型号好多了!
当然,您可以随意调整模型的参数和结构。上面代码的优点是完全灵活。你可以添加任意多的层,改变迭代次数,提高学习速度等等。
恭喜你构建了一个没有任何框架的深度神经网络!你现在已经有了深度学习的坚实基础,你甚至可以将上面的代码重用到任何神经网络结构中。
在接下来的文章中,我将教授不同的方法来改善你的神经网络,并取得更好的效果。
干杯!
如何在 NumPy 中构建 DIY 深度学习框架
通过从头开始构建神经网络来理解神经网络的细节
作为学习的一般经验法则,只有当你能够自己构建时,你才会详细地理解一些东西。对于机器学习和神经网络等技术学科来说尤其如此。在您第一次接触深度学习时,您可以通过学习和掌握 TensorFlow 或 PyTorch 等高级框架来迈出几大步。然而,如果你想真正深入,你需要回到起点:你需要从头开始建立自己的神经网络和优化器!对于深度学习工程师和研究人员来说,这是一个常见的成人礼。掌握这些算法的细节会给你在这个领域带来非常有价值的优势。
当我最近开始这段旅程时,成功对我来说是一个提升的时刻。在这篇文章中,我们将一起走过这条道路,最终实现一个全功能的神经网络。如果你熟悉高水平的主题,并且知道什么是梯度下降,你就可以开始了!(如果你不熟悉梯度下降,看看这个帖子!)
然而一个重要的注意事项。与其马上阅读这篇文章,我鼓励你将这篇文章加入书签,然后尝试完全依靠自己建立一个神经网络。在我作为一名开发人员和科学家的生活中,很少有时刻像看着我的第一个神经网络学习一样有成就感和智力满足感。
这篇文章的代码可以在我的 GitHub 知识库https://GitHub . com/cosmic-cortex/neural-networks-from-scratch中找到。(在这里,我稍微超出了这篇文章的范围:实现了额外的层,如批量规范化和卷积层。)
究竟什么是神经网络?
在高层次上,神经网络只是一个函数,将输入(例如图像)映射到预测(例如可能标签上的概率分布)。从根本上说,有两个简单的操作你想做的函数:计算输出和导数,给定一个输入。第一个是需要获得预测,后一个是训练你的网络梯度下降。在神经网络术语中,计算输出被称为正向传递,而相对于输入的梯度被称为局部梯度。
对 Python 建模非常简单。
在local_grad()
方法中,我们将返回一个渐变字典,而不是渐变的 NumPy 数组。当我们实现神经网络的层时,这样做的原因就变得很明显了。由于层有可调参数,这些参数将有自己的梯度。因此,区别对待变量组的梯度是有用的。
举个简单的例子,我们来考虑一下著名的 Sigmoid 函数!
注意,这个函数也适用于 NumPy 数组输入。目前,你可以认为这是一个单一变量的函数。然而,在后面,我们将把多元函数看作是带有张量输入的单变量函数。这一抽象层对于为神经网络编写紧凑的构件是必不可少的。
将乐趣分层
本质上,神经网络只是函数的重复应用,其中每个函数可以被认为是一层。对于复合函数来说,计算正向传递很简单。然而,如果我们要计算梯度,函数组合会使事情变得复杂,这对我们的目的是必不可少的。为了看看会发生什么,让我们考虑一个简单的例子!假设 N(x) 函数代表我们的神经网络,由一个线性函数与 Sigmoid 的组合定义。
A very simple “neural network”.
为了简单起见,我们还没有任何权重。为了计算它的导数,我们可以使用链式法则:
Derivative of N(x)
总结一下,我们需要三样东西来计算这个。
- Sigmoid 的导函数。
- f 的导函数。
- 在 x 处 f 的输出。
让我们从实用和计算的角度来思考这个问题。我们总是可以手动计算 N(x) 的导数,并将其硬编码到我们的程序中:
Derivative of N(x), expanded
然而,这不是一个好主意。首先,我们想要比这更复杂的功能,可能由数百层组成。计算数百个函数组合的导数实际上是不可能的。第二,我们希望我们的代码是模块化的,所以我们不是为我们的网络定义一个单一的功能,而是将它定义为功能的组合。
正因为如此,我们最好采用链式法则。然而,如果你注意到,计算导数本身也依赖于计算 f(x) 的值,所以我们不能简单地计算导数函数。为了确保一切正常,我们可以基于我们的Function
实现下面的算法。(注意函数后面的撇,它表示它的导数。有时候很难看到,所以我提前强调一下。)
- 乘 x 。传递给代表 f 的
Function
对象,计算 f(x) 和局部导数 f’(x) 。将两个结果都存储在缓存中。返回 f(x) 。 - 取 *f(x)。*传递给代表 Sigmoid 的对象,计算 Sigmoid(f(x)) 和局部导数 Sigmoid’(f(x))。将两个结果存储在缓存中。返回 Sigmoid(f(x)) 。
- 取乙状结肠’(f(x)) 。并返回 Sigmoid’(f(x)) 。(是的,我知道,这不是有史以来最复杂的步骤,但为了算法正确,这必须完成。)
- 将其传递给代表 f 的对象,从缓存中检索局部导数f’(x),最后与*Sigmoid’(f(x))*相乘。退回产品。
如果您再看一看,您可以看到步骤 1。第二。对于 f 和s 形的正向传递+局部梯度计算+缓存是否链接在一起。步骤三。第四。都是新东西:它们被称为倒传球代替乙状结肠和 f 。向后传递的返回值是梯度。请注意,这不仅仅是特定图层的局部渐变,而是该图层及其后所有图层的全局渐变。在技术文献中,它通常不会明确地与局部渐变区分开(因为它们都是渐变),但我喜欢通过使用全局和局部前缀来强调区别。
为了在我们的Function
中反映这些方法,我们向它添加了缓存和向后方法。值得注意的是,当对象被调用时(即使用Function.__call__
方法),局部渐变被自动缓存。
有了这个新模型,我们可以将 Sigmoid 函数定义如下。
这不仅是可组合的,而且我们也有方法计算组合函数的梯度。我们正在使用的这个算法叫做自动微分。这是现代深度学习框架的核心。没有它,梯度下降在计算上将是不可行的。
请注意,缓存起着非常重要的作用。例如,我们在向前传递过程中保存输入供以后使用,以节省梯度计算的时间。考虑这一点:如果特定的全连接线性层是神经网络中的第 109 层,则其输入是前 108 个函数的合成的输出。我们真的不想每次都重新计算,因为这会导致巨大的计算成本。
引入可调参数
在前面的例子中,我们只看到了某种意义上的静态函数,比如 Sigmoid。为了使模型适合训练数据,我们需要一组参数来调整。一个参数化的可微函数就是我们所说的层。理论上,可调参数(称为权重)可以被认为是另一组输入。然而实际上,分开处理这些参数更容易,因为
- 我们不会直接指定它们的值,而是存储一组当前值,
- 我们需要在每次反向传递后修改这些方法来执行梯度下降。
为此,我们通过使用权重初始化和权重更新方法扩展Function
来创建Layer
类:
例如,一个简单的全连接线性层表示具有参数 W 和 b 的 f(X) = Wx + b 函数,可以如下实现。
你可能会注意到,虽然这个函数从in_dim
维空间映射到out_dim
维空间,但是向前传递只有一个变量。这是因为我们的代码是矢量化的:我们使用线性代数运算来压缩代码,而不是对每个维度的不同变量进行操作。一般来说,矢量化代码的执行速度也更快,因此这是机器学习武器库中一个不可或缺的技巧。
除此之外,我们的线性层还批量接受输入。也就是说,如果你在 d- 维空间中有 n 个数据点,你传递一个 n x d 矩阵,而不是调用函数 n 次。使用批处理弄清楚向前和向后传递的正确实现可能需要一些脑力劳动,但是我也建议你自己至少一次详细地解决这个问题。当然如果你卡住了,你可以随时查阅上面的代码!
损失函数
在神经网络的构件中,损失函数起着某种特殊的作用。损失函数不是只将前一层的输出作为输入,而是还将地面实况作为输入,输出反映函数拟合训练数据的能力的单个数字。损失越小,拟合越好。在任何情况下,它们都只是没有可调参数的可微函数。
实际上,这意味着两个重要的区别。
- 正向传递需要两个参数:最终层的输出和地面实况。
- 由于是最后一层,全局渐变等于局部渐变。
例如,一个常用的损失函数是交叉熵损失,它可以实现如下。
构成图层
到目前为止,我们只创建了神经网络的构建模块,而不是实际的网络本身。为了能够舒适地使用这样一个 DIY 深度学习框架,我们希望有一个这样的界面。
我们已经完成了大部分工作,所以Net
只是一个简单的容器,将图层和损耗组合在一起。这个对象只是在层列表中循环,将每一层的输出传递给下一层。
测试我们的框架
现在我们已经构建了必要的工具,是时候将它们投入工作了!我们将使用具有 ReLU 激活的简单 2 层全连接神经网络来分类二维平面中的点。
完整的例子可以在这里找到,你可以在你自己的电脑上本地运行并试验它,这是非常鼓励的。我建议设置一个随机种子(以保持权重初始化的确定性),并尝试学习率参数。
超越完全连接的层
当然,这个简单的架构只是冰山一角。还有更复杂的架构可用,例如用于计算机视觉的卷积网络、用于序列学习的递归网络等。
在附带的代码中,您可以找到卷积层和池层的实现,以及一个 2d 批处理规范化层,您可以使用它来研究和试验某些组件。
在我的探索过程中,斯坦福大学著名的 CS231n:用于视觉识别的卷积神经网络课程对我帮助很大,所以如果你决定开始这段旅程并从头实现一个卷积网络,我可以向你推荐这个。
玩得开心,不断学习!
如果你喜欢把机器学习概念拆开,理解是什么让它们运转,我们有很多共同点。看看我的博客,我经常在那里发表这样的技术文章!
如何建立一个人脸检测和识别系统
基于计算机视觉和深度神经网络的解决方案
将机器学习技术应用于生物安全解决方案是新兴的人工智能趋势之一。今天,我想分享一些关于如何使用 OpenCV 库、DLib 和通过摄像机的实时流来开发基于人脸识别的生物识别系统的想法。
为了让系统正常运行,有必要实施三个步骤。首先,它必须检测到一张脸。然后,它必须几乎立即认出那张脸。最后,它必须采取任何需要的进一步行动,比如允许被批准的用户访问。
我在视频中的队友大致解释了这个想法,下面你可以阅读更详细的描述。
人脸检测和识别过程
面部识别过程从安装在与所述相机通信的任何兼容设备上的相机应用开始。该应用程序是用 Golang 编写的,可以作为本地控制台应用程序与 Raspbian 和 Ubuntu 一起使用。当应用程序第一次启动时,需要使用 JSON 配置文件配置本地摄像机 ID 和摄像机读取器类型。
然后,该应用程序能够使用计算机视觉和深度神经网络,以便在其流中找到预期的人脸。有两种主要的有效方法来做到这一点:第一种是 TensorFlow 对象检测模型,第二种是 Caffe 人脸跟踪。这两种方法都运行良好,并且是 OpenCV 库的一部分。
一旦捕捉到人脸,裁剪后的图像将通过 HTTP 表单数据请求转发到后端。然后,这个面部图像由 API 保存在本地文件系统和检测日志中,并附加一个 personID。
在后端,一种算法识别“classified=false”的记录,并使用 Dlib 函数生成 128 维向量,详细描述这张脸的属性。然后,该算法使用欧几里德距离将该向量与数据库中的所有面部条目进行交叉引用,以发现该新面部是否与记录中的任何面部相匹配。
下图是 Dlib 函数的代码表示,索引点对应于面部的各个部分。
在计算欧几里德距离之后,该算法将为未知类型的人生成新的 personID(如果距离大于 0.6),或者将面部标记为已分类并匹配 personID(如果距离小于 0.6)。
当一张脸被发现身份不明时,这张图像可以通过信使程序中的聊天机器人或其他方式与通知一起转发给经理或主管。经理或主管将会看到一系列关于如何处理这种情况的选项。
实现一个简单的聊天机器人警报系统需要大约两到五天的时间,可以使用像 Errbot (基于 Python)或微软的机器人框架这样的工具来创建。
面部记录可通过管理面板进行事后管理。这个空间将包含所有记录的图像及其 ID 号的链接。有可能创建一个所有相关员工面部图像的数据库,可以在系统上线前将其放入数据库。
一个潜在的问题是伸缩性。在我们的例子中,数据库中有大约 200 个条目,因此系统可以无缝地处理和立即识别人脸。当数据库膨胀到成千上万的条目时,或者如果需要多个摄像头时,事情变得更加复杂。如果不采取对策,处理速度将会减慢。
幸运的是,并行化提供了一个解决方案。可以创建一个负载平衡器和多个能够同时工作的 Web workers。这允许数据库被分成子部分,从而产生显著更快的搜索结果。
以下是对该面部识别解决方案所实施的技术和整体结构的总结。
解决方案中的 API 请求使用 RESTful API,后端员工数据收集使用 MongoDB 集合和 Golang。可以使用常规的工作站设置来测试解决方案。
值得注意的是,支持安全措施可以并且可能应该增强面部识别。面部图像比视网膜扫描或指纹更容易获得。如果安全需要足够重要,采取额外的面部反欺骗措施确保没有人能够用面部照片或图像击败面部识别系统。
你可以在我之前的文章 中了解更多人脸识别解决方案的反欺骗技术 。
这个解决方案以及其他类似的解决方案可以处理大量的数据。假设企业能够协调清晰的业务需求,数据科学公司将能够提供业务洞察力。人脸识别软件开发正在兴起,并将决定人工智能应用的未来。
人脸识别只是实现这种方法的开始。人脸只是要检测的对象之一。其他物体也可以用同样的方式识别。例如,如果使用对象在数据集上创建和训练了 DS 模型,那么它可以是车辆、家具、花卉、动物。
此外,还可以开发多模式生物识别系统,将两种或两种以上的生物识别凭证结合起来,例如,面部和声音识别,或基于 OCR 的身份识别。
想知道如何推出具有 DS/ML 特性的软件产品吗?阅读我最近的文章数据科学咨询:从想法到部署。
如何在 Node.js 中不用 TensorFlow 建立一个 k-NN
Points connected to each other, Image from Pixabay
k-NN 是一个简单直观的基于实例的学习器,当训练数据很大时,它工作得很好。因为模型必须记住训练数据中的所有点,所以它也消耗了相当多的内存。为了在 Node.js 中构建 k-NN,人们首先会想到 TensorFlow.js ,这是一个流行的机器学习框架,在 JavaScript 中提供 API。
但是,如果你是一个有经验的研究人员,想稍微改变一下模型,看看是否有改进的余地,那该怎么办呢?然后,您将需要进入另一个级别来更改核心架构。如果你是一个初学者,能够从头开始编写模型肯定会提高你的理解能力。
让我们开始吧!
万一你还没有,你得先安装 Node.js 。Node.js 是一种基于 JavaScript 的服务器端语言,相对容易学习。为了以最佳效率构建 k-NN,您将需要一个 k-d 树。k-d 树允许用分治法在 k 维空间中搜索点。对于设计涉及 k-means 或 LBS 服务等多维数据的系统确实很有用。更多关于 k-d 树的信息可以在这里找到。
Visualization of a k-d Tree
我们可以从 这里 下载整个 GitHub 存储库到我们的项目文件夹,为了导入它,我们使用了下面的 JavaScript 代码。
const kdtree = require('./kd-tree-javascript/kdTree');
现在为了测试 k-d 树是否有效,我们可以使用下面的代码:
const kdtree = require('./kd-tree-javascript/kdTree');
var points = [
{x: 1, y: 2},
{x: 3, y: 4},
{x: 5, y: 6},
{x: 7, y: 8}
];
var distance = function(a, b){
return Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2);
}
var tree = new kdtree.kdTree(points, distance, ["x", "y"]);
var nearest = tree.nearest({ x: 5, y: 5 }, 2);
console.log(nearest);
代码应该打印以下对象:
[ [ { x: 3, y: 4 }, 5 ], [ { x: 5, y: 6 }, 1 ] ]
我们可以使用下面的代码来构建我们的 k-d 树,其中 x 和 y 是 2 个特征, train 是训练数据。在距离方程中,要素除以其最大值。这样,计算出的欧几里德距离就不会太偏向于任何一个特征。还有许多其他有趣的方法来计算距离。
const kdtree = require('./kd-tree-javascript/kdTree');
var distance = function(a, b){
return Math.pow((a.x - b.x)/Xmax, 2) + Math.pow((a.y - b.y)/Ymax, 2);
}
var tree = new kdtree.kdTree(train, distance, ["x", "y"]);
var k = 5;
训练数据是对象的数组,其中每个对象至少包含 k-d 树内的两个特征。下面是一个如何在 for 循环中构造对象的例子。
var newObject = {
label: newLabel,
x: newX,
y: newY
}
data.push(newObject)
为了拆分训练数据,我们还可以使用以下代码混洗数据,在本例中,80%的数据被混洗到训练数据中。
Diagram illustrating how the data is processed
var shuffledData = shuffle(data);
var train = shuffledData.slice(0, Math.floor(shuffledData.length * 0.8));
var test = shuffledData.slice(Math.floor(shuffledData.length * 0.8) + 1, shuffledData.length);
function shuffle(array) {
var currentIndex = array.length, temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element...
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
最后,我们可以使用下面的代码来运行我们的模型。
var total = 0;
var correct = 0;
while(test[total] != null)
{
var nearest = tree.nearest(test[total], k);
var label = test[total].label;
var classa = 0;
// Count k nearest points that is labeled as "Class A"
for(i = 0; i < k; i++)
{
if(nearest[i][0].label == "Class A")
{
classa++;
}
}
// Validate if the actual label matches the majority
if(classa > k - classa && test[total].label == "Class A")
{
correct++;
}
else if(classa < k - classa && test[total].label == "Class B")
{
correct++
}
else if(classa == k - classa)
{
// In the case of a tie, evaluate randomly 50%/50%
if(Math.random() > 0.5 && test[total].label == "Class A")
{
correct++;
}
else if(test[total].label == "Class B")
{
correct++;
}
}
total++;
}
console.log("k-NN accuracy: " + correct/total);
该代码主要针对测试集运行 k-NN 算法,并对成功分类的实例进行计数。如果该实例周围的 k 个点的大多数被标记为该类,则该实例被分类为该类之一。在出现平局的情况下,算法会将其随机放入其中一个类中。
k-NN Illustrated, Image from Medium
恭喜你!您刚刚学习了如何从零开始构建 k-NN!现在由您来深入研究这个模型!
最后…
我对许多事情都充满热情,数据科学就是其中之一。在 Unity 机器学习框架准备好之前,我还从头开始构建了一个 BPANN。我当时唯一能找到的人工神经网络是用遗传算法来训练的。我没有把它写成一篇文章,但是我可以根据要求来写。
我喜欢学习新的东西,并与社区分享,如果有你特别感兴趣的主题,请让我知道,我可能会写它。我目前正在写一篇长文,详细解释 AlphaGo 是如何工作的,我需要一些时间来完成。
敬请关注,享受数据科学的乐趣!