TowardsDataScience 博客中文翻译 2016~2018(一百一十八)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

2018 年需要关注的四大分析趋势

原文:https://towardsdatascience.com/four-analytics-trends-to-keep-an-eye-on-in-2018-854646e390f6?source=collection_archive---------12-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Courtesy:Flickr

当你想到 2018 年的分析时,是什么让你早上起床?是 AI 在我们生活中的突出地位、数据的民主化还是高级分析让你感到兴奋?让我们接受这一点,去年是多事之秋,自助分析、物联网分析以及聊天机器人变得越来越智能。感受到这些发展,2018 年应该成为分析行业加速创新的又一年-当然会有一些预期和意外的中断!激动吗?毫不费力地阅读我们在 2018 年要关注的四大分析趋势!

人工智能聊天机器人不再是镇上的“新手”,很快将成为所有操作的主要驱动力!

“Siri,今晚我该看哪部电影?或者“谷歌,告诉我去办公室的最佳路线”,熟悉这些日常对话?想象一下没有他们的生活吧!可以吗?不太可能,对吧?考虑到它们对我们繁忙生活的影响。2017 年,围绕智能推荐有太多的噪音,人工智能聊天机器人可以识别我们的情绪,并相应地回应我们。不仅是关于天气或交通拥堵的更新,聊天机器人将会发展,还可能有助于搜索财务运营指标或获得“为什么”和“如果”问题的答案,从而实现商业和消费者空间的转型。尽管这可能需要几年时间才能成熟,但我们可以预计 2018 年也不会有多少成功故事。

增强现实:从卷轴到现实,增强现实正在并将改变我们周围的世界

还记得 2016 年 7 月,数百万人如何穿过公园,走过人们的坟墓,进入教堂,寻找增强现实版的神奇宝贝角色。记忆犹新,对吧?虽然口袋妖怪的狂热已经消退,但增强现实却没有,我们可以在 2018 年看到一些更先进和更动态的 AR 模式。随着企业已经在使用 AR 来增强制造和研究流程或提供新的客户体验,人机交互将会增强。为什么这对分析行业很重要?根据 Gartner 副总裁 David Cleary 的说法,“增强分析是一个特别具有战略意义的增长领域,它使用机器学习来为广泛的企业用户、运营人员和公民数据科学家自动化数据准备、洞察发现和洞察共享。”因此,是的,在几年内,所有的资源消耗和时间敏感的分析将大大变得容易和流畅的增强分析!

物联网分析:2018 年,每个行业的银弹?

2017 年,是“互联互通”收获巨大的一年。尽管存在大量安全问题,但围绕物联网还是有很多投资和采用。2018 年怎么样?物联网分析会像 2017 年一样激动人心吗?不可忽视的是,物联网今年也将继续扩展,几乎每秒钟都会有越来越多的设备联网。尽管零售**、**医疗、工业/供应链行业一直在使用物联网来提高投资回报率,但今年我们可以看到越来越多的公司将物联网用于更加个性化的营销工作。此外, Business Insider 预测,到 2021 年,企业在物联网解决方案上的支出将达到 6 万亿美元。根据这一预测,我们将看到许多风险投资家继续向物联网的承诺投入资金,这凸显了物联网在几乎每个行业改善客户体验的潜力!

区块链科技:实现新形式的数据货币化

所有人都同意,2017 年是区块链取得巨大增长的一年?许多人认为我们已经处于采用的“早期多数”阶段,并且我们正在朝着完全采用区块链的方向前进。与任何新技术一样,数据的重要性也在增长。今年,我们可能会看到区块链变得更加主流,医疗保健和零售等行业也开始使用它来处理数据,以防止黑客攻击数据泄露。根据戴尔 EMC 服务首席技术官 Bill Schmarzo 的说法,区块链技术还“有可能通过消除促成交易的中间人,使数据和分析的共享和货币化民主化。”因此,是的,组织将加快对这些虚拟货币的数据分析过程,以揭示强大的趋势、欺诈和洞察力,并做出明智的决策!

如何搭上虚拟货币涨势?请继续阅读,了解更多信息。

虽然很难说这些分析趋势会以多快的速度在我们的生活中体现出来,但我们相信 2018 年将再次成为多事之秋。将会有关于安全、治理以及最重要的消费者接受和适应这些创新和变化的能力的问题。唯一可以确定的是,今年的未来会有所不同,非常有希望!敬请关注!

四个破碎的系统& 2018 年的四大技术趋势

原文:https://towardsdatascience.com/four-broken-systems-four-tech-trends-for-2018-bd4698a3bef0?source=collection_archive---------11-----------------------

我受邀在未来女性活动上发表关于 2018 年科技趋势的演讲。未来女性是一场由现任和有抱负的女性企业家组成的运动。我非常钦佩这类女性,所以我很荣幸被邀请来演讲。此外,这是一个多么吉祥的方式来结束这一年,被要求思考未来,所以这里有一些关于这个巨大的话题的想法。

免责声明:我来自天体物理学,偏爱数据科学、统计学和目前归入机器学习和人工智能范畴的算法家族。

如何看待技术趋势这个话题?关于这方面的报道刊物文章领域 - 具体分析、、信息图。如何在这个时髦词汇的海洋中航行,并试图理解它对我们明年或以后的人意味着什么?我的出发点是问:

什么坏了?哪些在 2017 年行不通的,在 2018 年应该会更好?

虽然这个列表可能很长,但我想到了 4 个系统,它们在 2017 年表现出了多么不合适、不准确或彻底崩溃。

1.社会和政治工程

2017 年,社交媒体网络证明,它们并不像以前宣称的那样是一股团结的力量,在世界各地的人们之间建立桥梁。事实上,社交媒体平台恰恰相反,它分化了社区,分裂了社会,暴露了深刻的意识形态分歧,并以 YouTube 评论中首次发现的恶意和攻击性进行辩护。事实证明,南非本身并没有小到可以不被旨在煽动党派观点的推特机器人所注意。

我们已经看到公关公司改变公众舆论,加剧政治动荡,外国国家 利用社交媒体平台影响其他国家的投票和选举。我们已经看到政治预测者,从传统的民意测验专家到前沿的统计分析师都搞错了。

很明显,这没用。

2.传统(技术)教育

每年都有很多声音描述教育系统是如何崩溃的。虽然这可能是真的,而且太大了,无法在这里解决,但我认为专注于技术教育会很有趣,因为那里正在发生一些非常有趣的事情。

问题是,许多公司认为他们不能雇佣大学毕业生,因为他们(T2)不能像这些公司所希望的那样立即投入运营。南非的毕业生失业是一个问题。有一些努力。金伯利的 Sol Plaatjie 大学于 2014 年成立,专注于数据科学。像 CourseraedXUdacityothers 这样的大规模开放在线课程平台现在不仅提供课程,还提供专业学位,或者纳米学位,这些学位捆绑了一组急需的技能。这些在线学位在就业市场上越来越受到重视,以至于许多大公司,如微软,在这些平台上开设了许多认证课程。

让这个领域的创新变得有趣的另一个方面是不同商业模式的出现,以及除了赚钱之外的其他激励手段的使用。我想到的例子有 Insight 数据科学奖学金Ecole 42 以及它的南非版本,最优秀的我们认为代码 _ 。在这些科技教育机构中,学生不负责学费,但需要他们培养的人才的企业负责。这极大地改变了游戏的可访问性。Ecole42 和我们认为 code_ 在资格方面没有任何先决条件。没错。有人可能在 15 岁就辍学了,但仍然被录取,只要他们通过了在线解决问题技能测试。它不是对知识的测试,而是对人们如何处理问题的测试。这是大多数学校都不教的。

3.数据管理

今年我们已经看到了历史上一些最大的数据泄露事件,以及一些最大的掩盖事件。无论是优步、Equifax 还是雅虎,至少有一个漏洞最有可能影响到我们每一个人。在南非,我们已经看到一个数据泄露事件泄露了身份证号码和其他个人信息,这些信息可能被用于身份盗窃。

这里的问题是激励、所有权和风险都以错误的方式分配。我们都从系统中受益,大公司利用我们的数据来销售有针对性的广告,作为交换,我们愿意将我们的数据交给他人,这样我们就可以免费使用社交网络、网络平台和搜索引擎。当出现漏洞时,问题就来了。虽然这些大公司可能拥有数据,但他们不承担违规带来的风险。这种风险——身份盗窃、信用卡滥用等等——仍然由我们自己——消费者——承担。因此,应用能够抵御越来越聪明的黑客攻击的适当数据安全措施的动机不在于拥有和保存数据的大公司。完整的报告存在于被盗数据经济中;事实证明,在黑暗网络上,一个身份并不昂贵

这些待售的身份不是大公司的信息,而是你我的。很明显这没用。

这个问题如此严重,以至于有些人投入巨资试图改变这种状况。这里面有很多钱。

4.人工智能应用传播其创造者的偏见

今天使用的人工智能算法主要建立在机器学习算法的基础上,这些算法经过编程,然后根据数据进行训练。这为算法和训练阶段偏差留下了空间,后者可能是最能揭示问题的。AI 的偏见已经在 2017 年被多家主要刊物彻底记录。(请点击所有这些链接了解更多信息,有些文章可能在付费墙后面)。

下面的两个例子说明了这些偏见有多普遍。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

第一张图片是谷歌图片搜索“正面”的屏幕截图,带有额外的彩色图片过滤器和知识共享许可,允许我在其他地方显示图片。寻找一张脸,我得到了一个雕像,一幅画,一座建筑,两只动物,但只有一个黑人。这实质上意味着,当搜索一张脸的图像时,黑色的脸出现的频率不会比动物和建筑物之类的错误更高!这不仅是对世界面孔的拙劣表现,也是一种完全有偏见的信噪比。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在第二个案例中,我的一个朋友玩了剑桥大学(Cambridge University)开发的在线人工智能服务,该服务通过分析推文或 facebook 帖子获得人口统计数据。不用说,我的朋友、我自己和一大群女科学家立即被贴上了男性标签,提出了一个合理的问题:“在人工智能时代,泛化是合理的吗?”。

答案当然是否定的。因此,这显然是行不通的。如果我们要信任我们的人工智能,我们都需要改进它,并记住人工智能会错过的边缘情况。我们必须比人工智能更聪明(我们也能)。

这涵盖了 2017 年的一些重大破事,以我谦卑和人性偏见的观点来看。现在谈谈我(和许多其他人)预见的一些有趣的技术趋势。

2018 年,技术可能会对我们的生活产生怎样不同的影响?

同样,这不是一个详尽的清单。我刚刚确定了四个有趣的趋势,我渴望看到发展。这个列表有一个偏差,因为这主要是对消费者可见的技术,如果不是直接的消费者技术的话。在工业和研究领域有着迷人的技术发展,我们无法直接看到,这是一个全新的探索世界。

1.与机器人一起工作和生活

几年来,这已经成为许多科学家的标准,但这仍然有助于科学研究。从用于寻找水污染源头的机器鳗鱼到学校认可的隐形 T2 机器斑马鱼,机器人技术正以创造性的方式应用于尖端领域。离我们更近的是,机器人手术正在成为许多医生的现实(伴随着过渡期的自然痛苦),因此也成为病人的现实。更有趣的是,价格实惠、外观自然的个性化智能假肢的兴起。有了 3D 打印,假肢不再需要看起来像商店橱窗里的人体模型,它们可以适合任何个人。随着神经修复术的进步,现在这是真正的机器人生活。

我认为,我们还将看到机器人更多地进入我们的物理空间。除了电话号码末尾的机器人,或者管理我们的社交媒体,我们将开始看到它们。任何自动驾驶车辆实际上都是机器人,无论是自动驾驶汽车、穿梭车卡车,还是无人驾驶飞机、室内或室外,机器人正在变得可见,它们将很快成为我们生活环境的一部分。

2.消失的界面

在过去,我们会出去购买一些技术来访问一些东西,无论是听音乐的随身听,玩游戏的游戏机,还是阅读电子邮件的电脑。现在,这种情况似乎越来越少,我们不再需要购买更多的技术,而是回来坚持使用几十年来我们一直使用的一些产品,这些产品似乎会一直存在下去;汽车,手表,电话,娱乐系统。我们喜欢的一切的界面开始存在于那些对象中,但是在它们之间无缝导航。我们从手机上听音乐,但当我们开始开车时,汽车会接管它,它会接下一个电话,等等。

界面现在正在消失,无处不在,这为未来几年带来了一些非常有趣的机遇和挑战,从界面/交互设计到数据和隐私。期待看到 2018 年这个趋势会如何发展。

  1. 人工智能作为一种商品

人工智能是不可避免的。它将贯穿我们的大部分工作。人工智能有一些非常有趣的创造性应用,例如根据难民被重新安置的地点优化他们获得就业的机会,到你的普通聊天机器人。不同的是,现在人工智能正在变得商品化,因此,任何人都可以将其纳入他们的产品和服务。这种商品化有三个主要方面:

  • 开源软件
    tensor flowSparkpy brainopen nn等。一些最好的人工智能和机器学习库是开源的。不再躲在专有的微调算法后面。除此之外,还有丰富的免费在线课程,几乎任何人都可以学习将机器学习和人工智能应用到自己的业务中。
  • 例如,如果没有大量数据来训练机器学习算法,那么可以通过 API 轻松访问预先训练的引擎。比方说,每次调用分析一张图片或一些文本,都不再非常昂贵。所有大公司都有一套全面的人工智能 API 可供使用;微软 Azure 的认知服务,谷歌的云服务——比如针对语音视觉自然语言,或者亚马逊的认知
  • 边缘计算
    在我看来,这是一个特别有趣的问题。以前,如果你环顾互联设备的世界,你几乎可以说物联网主要是一堆互联的传感器,收集数据并在其他地方集中分析,因此需要连接。现在,世界各地的芯片制造商已经意识到 GPU 革命——图形处理单元(通常在游戏电脑中发现)比普通 CPU、中央处理器——笔记本电脑和手机中的芯片等更有效地用于机器学习和人工智能。去年我们已经看到了主要芯片制造商发布了一系列公告,这是一种为人工智能设计的新型芯片;神经形态计算(称为神经形态,指大多数人工智能使用的神经网络)。芯片就是芯片,它们往往价值数十亿,而且价格低廉。这将在传感器所在的边缘带来负担得起的人工智能硬件能力。我相信这将改变我们对世界上人工智能应用的看法,我很高兴看到这将引领我们走向何方。

4.区块链

最后,我必须提一下这种“房间里的大象”技术,我不是这方面的专家。我了解它的工作原理,但不要问我加密货币和交易所之间的具体区别。区块链是加密货币的基础技术,据观察,在中央当局不再受信任的地方,这些加密货币提供了有吸引力的替代方案。他们也吸引了有着邪恶目的的组织。这让我想到了区块链科技的两个特点,正是这两个特点让它成为了游戏规则的改变者:

  • 可信的分散化取代不可信的集中式系统
  • 数字人工制品的独特性

第一点是,为什么加密货币在中央经济当局陷入困境或不受信任的国家如此有吸引力。它可以应用于合同、供应链等。第二点是前所未有的。在此之前,用数字人工制品区分原作和复制品的能力是不可能的。这可以保证艺术品的真实性,限制版权材料的复制等。

我将把它留在这里,不做进一步的开发,但我认为重要的是不要被围绕加密货币的所有宣传所蒙蔽,要看到这项技术的独特性,也许要看看它可以在任何行业中实现什么。2018 年无疑会看到一些有趣的应用从加密货币价值波动的噪音中出现。

最后

因为这是写给企业家的,所以我决定思考一下机会在哪里。我的印象是,光有技术和要解决的问题是不够的,还需要正确的经济激励模式,这里有大量创造力的空间,这是我试图说明的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果你有时间继续读下去:

我想强调的最后一点是经济激励的“超越企业社会责任”思想。

在这篇文章中,有两个双赢的例子,一点也不仁慈。第一个是 we think code_(和 Ecole 42)的商业模式。通过资助学校,雇佣他们毕业生的公司可以被视为自私地照顾他们的利益,即解决他们所需人才的稀缺问题,但事实上远不止如此。在南非,一个有工作的人常常要养活整个家庭,通常也是一个大家庭,特别是如果他们进入编码学校时没有主要资格证书,这有助于减轻贫困的可怕影响。因此,除了这种模式本身的双赢之外,还有一个额外的积极副作用。

第二个例子是大赦国际申请重新安置难民,以增加他们找到工作的机会。虽然这个例子不是来自私营部门,学术界的回报/货币是科学出版物,这显然导致了至少一个。但它也应用了尖端技术来造福那些利益往往被放在最后的人。此外,结果,更高的就业机会,直接导致更好的融合,看到融合是双向的,也导致更多的宽容。因此,除了这个项目的双赢之外,还有一个额外的积极副作用。

底线是,通过进一步关注而不仅仅是一个单一的受益者,一个人可以围绕价值/财富/健康创造和技术的生成链进行创新,这是不可能改变的。

针对实时分析的大数据堆栈四败一胜

原文:https://towardsdatascience.com/four-fails-and-a-win-at-a-big-data-stack-for-realtime-analytics-4f82f651d476?source=collection_archive---------8-----------------------

构建一个用户友好的应用程序来实时分析大数据(即保持响应时间低于 60 秒)是一项挑战。在大数据世界中,你要么进行批量分析,没有人真正关心查询时间(大多数企业);或者你在做流媒体(优步、脸书和 kin),在这种情况下,查询时间至关重要,但数据总量很大——每个用户只看到或使用很小一部分,并且后台正在进行批处理作业。

我正在开发一个 web 应用程序,该应用程序使非数据科学家用户能够实时构建和可视化地理数据的复杂分析,随着我们的数据和用户以及我们产品复杂性的增长,我们不得不修改堆栈以满足性能标准。我们的问题似乎应该是一个常见的问题,但奇怪的是,在用户友好的时间框架内对大量数据进行密集只读计算的指导非常少。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

How analyses look in the web app

一年前,我还不是大数据领域的专家,这个领域有足够多的工具、术语和观点,很难知道从哪里开始。我还不知道所有的答案,但我已经想出了足够的办法,可以试探性地、谦恭地帮助其他人朝着对我们有用的堆栈前进。

失败 1:幼稚的 Postgres

首先,我会说不到万不得已不要修改你的堆栈。这可能是数据应该被视为的时候——当您现有的基础设施难以应对时。我们愉快地用 SQL 做了很长时间的事情。Postgres 是一个令人惊叹的数据库,我的经验是,通过正确的索引和构造良好的查询,可以实时聚合和查询多达 8000 万行的表。

(虽然我提到了地理空间领域,但在本文中,我并不是在谈论地理计算,比如使用 PostGIS 。它们在计算上非常昂贵,但是我们在最初的 ETL/数据摄取过程中完成了大部分工作。)

不幸的是,执行所有必要的数据库维护、找出正确的索引以及编写和重写查询可能相当痛苦。您还必须将数据正确地存储在整齐规范化的行和列中。

失败 2:反规范化

还是你?总的来说,保持 SQL 数据的规范化和单一的真实来源是好的,但是复杂和频繁的表连接会降低性能。由于我们无法再满足用户的需求,我们不得不停止愚蠢的查询,并对一些较大的表进行反规范化。比如说,

这需要我们在 ETL 步骤中做更多的工作,并确保良好的数据治理,但这大大提高了速度。为了在团队规模保持不变的情况下弥补额外的时间,我们从自托管 Postgres 迁移到 AWS Aurora Postgres。性能没有改变,但它确实消除了一些数据库管理难题。

失败三:极光

只不过这也带来了新的性能问题。我们的应用程序的最大特点之一是,它可以根据用户指定的标准,对城市的微小六边形区域进行评分和聚类。一个城市可能由 50 万个六边形组成;对于每一个妖术,用户可能想要根据其夜间居民和白天工作者的中值收入和心理特征,以及它离最近的星巴克有多远来评价它。这需要大量的数据和计算。

迁移到 Aurora 让我们失去了将数据保存在自己机器的内存缓存中的能力。当不同的用户试图依次或者更糟的是同时给不同的城市打分时,数据被拉入(大概是从 S3)并从我们的虚拟机中弹出。这种数据加载时间,就像某种页面抖动一样,大大超过了计算时间:最终结果是,当数据可用时,一个城市的得分需要 3 分钟——对于打算实时进行的事情来说,这本身不是一个很好的结果——迅速增加到 10 分钟或超时。

现在,在大数据领域,我可以说,我并没有参与太久,目前“没有人因为收购 IBM 而被解雇”的是 Apache Spark。我努力着手创建一个 Spark 机器集群,看看它是否能有所帮助。

由于我们现在处理的表有数亿行,Postgres 运行缓慢,如果我们的应用程序要扩展,就必须对数据进行分区,并在多个节点上进行计算。

次要胜利 1:集群

多亏了 Kubernetes 和 Kops,在 AWS 上创建一个集群并不困难。

此时,您将获得一批新的 AWS 资源,包括集群主机和计算节点的实例。Docker 容器可以部署到这些实例中,由于 Kubernetes magic,它们将能够相互通信,与同一 VPC 上的其他机器通信,如果您选择通过暴露的负载平衡器与外界通信。

借助 Helm ,我能够快速启动并运行一系列 Spark 节点,以及一些用于 HDFS 文件存储的 Hadoop 节点。

失败 4:火花

我发现 Spark 很难管理,很难使用(它都是 Java 的,并且是为 Java 应用程序设计的,尽管 PySpark 的承诺可能会让您相信),而且总体来说没有那么快。

我确信 Spark 可以在一些人的批处理工作流中发挥作用,并且我知道它也有流扩展。然而,即使是简单的工作也需要几分钟来启动机器,这使得它在实时用例中毫无用处。

此外,HDFS 跑得并不快,现在我们有了 S3,这看起来有点无关紧要了。

此外,如果你像我一样来自 Python 生态系统,就不可能不去想念我们所拥有的大量工具。如果你是这样的人,并且你今天正在开始或发展一个大数据项目,我知道有一个更好的方法。

胜利:与 Dask 一起分发熊猫

Pandas 处理数字数据的速度已经是最快的了。数组计算以本机速度进行(感谢 Cython ),并且经常利用向量指令(感谢 NumPy)。

尽管如此,我一直认为 Pandas 实际上是用于处理数据的 ETL 和分析部分;更像是一个数据科学工具,而不是一个可以部署到生产中的库。我错了:

熊猫已被广泛应用于生产和金融领域

Dask ,Anaconda 背后的同一批人制作的分布式计算库,将大型数据帧划分到不同的节点上,在这些节点上调度并行计算(构建一个图,像 Spark 一样将计算延迟到最后一分钟),收集结果并管理分布式数据。它与熊猫集成在一起,并且在很大程度上可以与熊猫互操作,所以一起工作是一种乐趣。

(不是 100%;有些事情,例如在多列上索引一个数据帧,对于一个分区的数据帧没有意义)。

而且速度很快:每个节点都利用了 Pandas 及其矢量化的代码。分布式计算不是免费的;Dask 需要一些时间和网络延迟来构建图形和调度每个节点的计算,以及在最后合并/减少数据。如果能够将整个数据帧放入内存,基本的 Pandas 会更快——如果我们扩展我们的基本机器,这是可能的,但这不会永远持续下去:我们仍然需要在某些时候水平扩展我们的平台。

用 Dask 编码很大程度上是熟悉的。例如,下面是 SQL SELECT MAX(col + col2) FROM table WHERE zip_code IN ('94105', '94106') AND day_of_week IN (1,2,3)的替换

from dask.distributed import Client
import dask.dataframe as dd
c = Client('172.x.x.x:8786')
df = dd.read_parquet('s3://my-bucket/mydatafile.parquet')
df = c.persist(df)
subset = df[df["zip_code"].isin(['94105', '94106']) & df["day_of_week"].isin([1,2,3])]
df["sum"] = df["col1"] + df["col2"]
print(df["sum"].max().compute())

将 Dask 部署到我之前制作的 Kubernetes 集群中也是相当容易的:他们有自己的掌舵图记录在这里。我们的基础设施现在看起来像这样:

  • 单片 Node.js 后端
  • 它调用 Python 微服务(用 Flask 构建,并将任务队列与 SQS 集成)
  • 连接到集群并指示节点
  • 从 S3 下载他们的数据部分(使用预先分区的 Parquet 文件非常快,因为从每个节点的读取是并行发生的)
  • 用 Dask/Pandas/NumPy 处理其数据
  • 并向后端返回一个 JSON 响应,后端将其转发给客户端 webapp

在 Postgres 中需要几分钟的分析,如果需要从持久存储中读取数据,则通常需要更长时间,现在不到 30 秒就可以返回到客户端。

结论

如果你有钱花,尤其是如果你还没有证明产品/市场适合,就去找供应商解决方案。一个快速的、面向列的内存 SQL 数据库不需要对我们的流程和代码做太多的修改。

否则,对于作为 SaaS 的一部分实时处理大数据,我建议看看 Dask 是否能满足您的需求:它速度快,可水平扩展,允许您使用您习惯的相同库以相同的方式编写代码,并且它目前正在生产中使用(至少被我们使用)。

显然,我认为 Dask 杀死了 Spark,但是如果你感兴趣的话,Dask 的作者确实给出了一个更微妙的观点。

傅立叶变换及其数学

原文:https://towardsdatascience.com/fourier-transformation-and-its-mathematics-fff54a6f6659?source=collection_archive---------1-----------------------

信号分解、时域和频域

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

source

简介

傅立叶变换(FT)将信号分解成组成它的频率。

这是什么意思?

所以,我们来举个例子。让我们有一个信号 S1。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

S1: x-axis is time and the y-axis is amplitude

如果我们想在某个特定的*时间测量这个信号的强度。*我们用它的 振幅 来衡量。

所以,信号 S1 的振幅是 1

如果我们对另一个信号进行同样的操作,选择相同的时间点,测量其幅度。让我们有另一个这样的信号 S2

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

S2: x-axis is time and the y-axis is amplitude

同样,信号 S2 的幅度是 2

现在,我们同时发出这两个信号(S1 和 S2)会发生什么?

因此,当我们在同一时刻发射这两个信号时,我们会得到一个新信号,它是这两个信号幅度的*之和。*这是因为这两个信号被加在一起。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

S3=S1+S2: x-axis is time and the y-axis is amplitude

所以,S3 的幅度= S1 的幅度+S2 的幅度= 1 + 2 = 3
所以,信号 S3 的幅度是 3

现在,有趣的问题是:

如果只给我们信号 S3(也就是信号 S1 和 S2 之和)。我们能恢复 S1 和 S2 的原始信号吗?

是的。这就是傅立叶变换的作用。它接收一个信号,并将其分解成组成该信号的频率。

在我们的例子中,傅立叶变换会将信号 S3 分解成其组成频率,如信号 S1 和 S2

但是,我们怎么才能恢复原来的信号呢?傅立叶变换能为我们做什么?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

y-axis is the strength of the signal (amplitude)

假设上图中的三个信号是 S1、S2 和 S3,当我们将这三个信号合并在一起时,我们得到的是红色的信号,实际上是 S1+S2+S3。

傅立叶变换的作用是将我们从时域转移到频域。

万一有人在疑惑,我们要从频域回到时域怎么办?

我们可以通过使用逆傅立叶变换(IFT) 来实现。但我们不会在本文中讨论这个问题。

信号产生和相移

如果我们想描述一个信号,我们需要三样东西:

  1. 信号的频率,它显示了在我们的周期内发生了多少次。
  2. 振幅显示信号的高度或信号的强度。
  3. 相移至于信号从哪里开始。

我们举的第一个例子非常简单,每个信号都有相同的频率相位差,只有不同的幅度

现在我们来看一个稍微复杂的例子,我们来看上面例子中的单个信号,因为为了更好地理解傅里叶变换,我们需要仔细观察单个信号。

下面是我们在上面看到的原始信号。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Signal 1

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Signal 2

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Signal 3

**频率:**如果我们仔细观察这三个信号,我们会注意到所有三个信号的频率都是不同的。

如果在同一时间段内,信号 1 中有 n 个波,则信号 2 中有 2n 个波,反之亦然。

**相位:**同样,当我们仔细观察信号实际上是从哪里开始的。我们会发现,当信号 1 开始于(0,0) 时,信号 2 开始于(-0.5,0) ,如果我们追踪波形以在 0 处与 y 轴相交。因此,在 0,我们已经有了信号的最大幅度。这就是我们所说的相移

振幅:三个信号的振幅不同,信号 1 的振幅为 1,信号 2 和信号 3 的振幅分别为 2 和 3。

这一切都包含在一个优雅而超级简单的数学公式中。因此,在上述示例中,如果 x 轴表示为 x,y 轴表示为 y,我们可以将y生成为t的函数,如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用这个公式,我们可以产生我们想要的任何类型的信号,然后我们可以将它们合并在一起并进行处理。例如,如果我们合并信号 1、2 和 3。我们会得到这样的信号:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Signal 1 + Signal2 + Signal3

傅立叶变换背后的数学原理

傅立叶变换背后的主要思想是:

时域中的任何连续信号都可以由一个无限正弦系列唯一且明确地表示。

这意味着什么?

这意味着,如果我们有一个信号,并且这个信号是由某个函数x(t)产生的,那么我们可以得出另一个函数f(t),这样:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

因此,信号有多强并不重要,我们可以找到一个类似于f(t)的函数,它是一系列正弦曲线的之和,实际上可以完美地代表信号。

现在的问题是,我们如何在上面的等式中找到系数,因为这些值将决定输出的形状,从而决定信号。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

因此,为了获得这些系数,我们使用傅立叶变换,傅立叶变换的结果是一组系数。因此,我们使用X(F)来表示傅立叶系数,它是频率的函数,我们通过求解积分得到,如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个积分中棘手的部分实际上是表示复数的i。所以,我们大概记得i² = -1或者i = √-1。记住复数的形式是a + *i*b 可能会有所帮助。所以,它有一个实部虚部

此外,当我们实际求解上述积分时,我们会得到这些复数,其中ab对应于我们要寻找的系数。

然而,我们确实有三个问题需要处理:

  1. 如何应对*i*
  2. 如何处理离散信号?

所以,我们从第二个开始。

要理解离散傅里叶变换,我们首先需要理解如何对连续信号进行采样?

根据维基百科介绍,在信号处理中,采样是将连续时间信号还原为离散时间信号。下面是一个信号形式如何随采样速率变化的示例:

假设原始信号是在一秒钟内振幅为 2、频率为 5 的信号:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

sampling rate = 1000

现在,当我们降低采样率时,让我们看看信号的形状是如何变化的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

sampling rate = 50

当我们进一步降低采样率时,我们得到:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

sampling rate = 15

所以,底线是 : 采样速率越高,信号质量越好,我们也可以区分更多频率。

现在,我们知道了如何对信号进行采样,接下来我们来看看称为离散傅里叶变换的算法的修改。

离散傅里叶变换

时域中任何长度为 N 的采样信号都可以由一系列有限的正弦曲线唯一且明确地表示。

所以,在我们的新定义中,我们不用再处理无穷大了。

有什么区别?

在标准傅立叶变换中,我们使用时间函数x(t)来产生连续信号。在离散情况下,我们没有函数,只有数据集,即通过对连续信号进行采样获得的一组点。因此,我将使用{x}来捐赠一个数据集,使其包含来自采样的读数,这样:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

离散傅立叶变换将为我们做的是它将把{x}的数据集变换成另一个包含傅立叶系数的数据集{X},使得:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果我们看一下傅立叶变换的定义,{X}中的每个X都是一个复数,它包含频率的ab分量。

但是,两个数据集 ***{x}*** ***{X}*** 怎么会有相同的长度呢?

如果我们想一想,驱动{x}数据集长度的是采样率,因为在一段时间内,我读取的数据点数量正好是采样率,对吗?如果我们考虑另一个数据集{X},我们说过频率是单位时间内出现的次数。因此,如果我以某一频率进行采样,我无法识别频率高于采样频率的信号,因为我们没有获得足够的数据点。

因此,如果我们以非常低的采样速率获得非常高频率的信号,我们根本无法识别这些信号。因此,我们可以通过应用傅立叶变换识别的频率数量实际上也是由采样速率决定的。

因此,现在我们有了数据集{x},我们将得到{X*k}* ,这样它就是{X}中的一个元素,它们是我的傅立叶系数,这样:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Fourier Transform

这本质上就是离散傅里叶变换。我们可以进行这种计算,它将产生一个形式为a + *i*b的复数,其中我们有两个傅立叶级数的系数。

现在,我们知道如何对信号进行采样,以及如何应用离散傅立叶变换。我们想做的最后一件事是,我们想通过使用所谓的欧拉公式来去掉复数*i*,因为它在mllibsystemML中不受支持,该公式表示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Eulers Formula

所以,如果我们把欧拉公式代入傅里叶变换方程,我们得到

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们还知道cos(-θ) = cos(θ)sin(-θ) = -sin(θ),如果我们在上面的等式中使用它,等式可以简化为:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

实际上,我们可以将上述等式分解为两部分,即:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在,如果我们将上面的等式与一个复数的等式a + *i*b相比较,那么我们得到相应的值为:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

所以,现在我们可以把这些值放入*f(t)*的方程中,得到结果。

结论

在实践中,我们使用一种称为快速傅立叶变换的离散傅立叶变换的微小修改,因为离散傅立叶变换非常简单、基本且缓慢。如果我们真的想在生产环境中做些什么,这是不合适的。离散傅立叶变换的计算复杂度是二次时间O(n²),用于比较的快速傅立叶变换是准线性时间O(nlogn)快速傅立叶变换通过利用傅立叶变换中的不对称性来实现这一点。

框定狩猎…

原文:https://towardsdatascience.com/framing-the-hunt-913f9a0eae6a?source=collection_archive---------7-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这是我如何成功地从地球科学转向数据科学系列的第三篇文章。来刷新一下,这里是第一集第二集

好了,现在每个人都赶上了,我给你们留下了一个悬崖衣架。我去了一个编码“训练营”,非常热衷于网络,但是从来没有真正去了解我如何选择寻找哪些机会。我拥有石油和天然气行业之外很少有人能与之相关的技能和丰富的行业经验,以及越来越多的人脉。

对于我的正式求职,我有一套宽松的目标,可以缩小为两个标准:

  1. 在西雅图找工作(最好是我爱上了西雅图)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

What geoscientist wouldn’t fall in love with their very own volcano?

2.一些支持“技术”产业的东西(不管 T4 真正的意思是什么)

好吧,含糊,我知道。我可以用很多方法来寻找答案。就其最基本的形式而言,找工作有两种方法,一种是窄范围的,一种是宽范围的。作为一名数据科学家,我将简要回顾一下 我对这些因素的 定义,以及它们如何影响我的求职目标。

缩小范围

这种方法适合那些确切知道自己想要什么并且不会降低要求的人。

更明确地说,我将它定义为具有以下标准:

  1. 有一个“数据科学家”的头衔或胸围
  2. 角色完全符合个人对数据科学的看法(例如,机器学习重点或“大数据”要求)
  3. 从事特定行业(如初创企业、公司、顾问)

优点 :

  1. 你确切地知道你想要什么,并能使你的面试策略与之相匹配。
  2. 你会有你喜欢的头衔和角色,但是你可能会被限制在你所在的特定公司。

缺点 :

  1. 你为那些没有正式贴上“数据科学家”标签,但实际上是数据科学家的机会留下了盲区。回想一下,直到 2008 年左右,数据科学这个术语才被完全创造和接受。一些组织仍然使用较老的术语,如分析师或统计师,而不是数据科学家。
  2. 可能最终会把自己定位成一个专家,未来的行动没有多少回旋的余地。
  3. 你可能最终会让你原本喜欢的美好事物与你擦肩而过。与此相关的还有“未知,未知”类别。你不知道你不知道什么。听听推销,你可能会找到你真正喜欢的东西。

谁应该考虑这种策略:

  1. 一个有可靠理由支持他们调查的人。你以前在类似的组织中担任过类似的角色。大多数来自石油和天然气行业的地球科学家还不知道这一点。如果你有,就把自己当成“独角兽”吧。
  2. 在数据科学领域寻找第二份工作(或以后工作)的人。我通常不会向这个领域的新人推荐这种策略,即使是对我们这些处于职业生涯中期的人。

再说一遍,大多数人都不完全属于这一类。求职者希望认为他们知道自己想要什么。见鬼,有一段时间,我以为我很清楚自己想要什么。但是,我建议采用第二种方法,即大范围方法。

最终,我会认为<10% of geoscientists who are pivoting to data science will fall into this category. Of this, most of them will be going into data science roles within the energy industry.

Wide Scope

For most experienced professionals pivoting to the field of data science, the wide scope provides the best “bang for your buck”.

In this approach a job seeker:

  1. Casts their net wide. Look into all titles holistically. Data Scientist, Data Analyst, Business Analyst, Decision Scientist, Business Systems Analyst, Business Intelligence…
  2. Reads into the details. Look into job descriptions holistically. Not all job descriptions are created equal. One company’s Data Scientist is another company’s Data Analyst. Another company’s Data Scientist is simply a Data Analyst at another.
  3. Looks at a variety of opportunities across business types and industries.

有利 :

  1. 更多的选择和机会。这种方法可以让你在公司面试你的时候控制和面试他们。因为你有更多的选择,它允许你在驾驶座上。
  2. 你可以开始承认未知,未知列表。了解你以前从未接触过的行业和职能。例如,作为一名勘探地球科学家,我打赌你从未直接与社交媒体营销团队打交道。你甚至可能会被它吓跑。你和他们谈过了吗?在你尝试以前的大学生活之前,不要把他们排除在外。
  3. 你仍然可以从一个狭窄范围的方法中得到你想要的东西。这些工作仍然存在,你仍然可以申请。这就需要和更多不同的人交谈,来强化你对下一个角色的期望。

:

  1. 一些职称可能会让你更难转换到另一家有不同职称的公司。真的不应该有关系,角色和职责应该为王,但如果你是冷申请(即没有内部推荐),有时会归结为简历排序的算法。

谁应该考虑这种策略:

  1. 人人 。大家都要考虑一下。如果你没有,你就没有适当地缩小你的范围。开始大,削减,如果你必须。

最终,我相信这应该是 90%以上转向数据科学的地球科学家的策略。除非你是一个“独角兽”,拥有无缝过渡到一个新行业或留在能源行业的背景,否则你应该使用这种策略。

这个分析对我个人来说意味着什么?

让我们回到我在本文开始时提出的两个主要目标:

  1. *在西雅图找工作(最好是,我爱上了西雅图)——*我把这个扩展到了许多城市,包括波斯顿、三藩市/海湾地区和 DC 地区
  2. 支持“技术”行业的东西(不管它真正的意思是什么)——这扩展到了“技术”、金融、保险等等,我没有特别歧视任何行业,并听取了每一个向我抛出的建议

既然我们已经想好了范围。你实际上是如何理解和阅读数据科学领域的工作描述的?你需要整齐地满足所有的需求吗?如何申请每个职位?你应该对公司进行个性化设计还是使用一种简单的方法?

这是一个很大的难题。下周,我将介绍我在寻找第一个数据科学职位时最常看到的不同类型的“数据科学”帖子。

继续进入第 4 集第 5 集第 6 集第 7 集第 8 集

关于“独角兽”和“紫色松鼠”的描述,请参见这篇文章

极端类别不平衡下的欺诈检测

原文:https://towardsdatascience.com/fraud-detection-under-extreme-class-imbalance-c241854e60c?source=collection_archive---------3-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据科学中的一个热门领域是欺诈分析。这可能包括信用卡/借记卡欺诈、反洗钱或网络安全。所有这些领域的一个共同点是阶级不平衡的程度。一般来说,交易总数中只有一小部分是真正的欺诈。以信用卡诈骗为例。在给定用户的 1000 次交易中,只有 1 次是真正的欺诈。这可能是因为客户的信用卡信息被盗,或者供应商的 PoS 设备受损。需要尽快抓住这个问题,以最大限度地减少对客户和供应商的经济损失。同时,我们需要注意假阳性。很自然,如果信用卡在没有发生实际欺诈的情况下被银行冻结,信用卡所有者会不高兴。在这篇博客中,我将介绍一些常用策略,用于揭露金融和网络不端行为,同时最大限度地减少假警报。

无监督学习模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当交易记录没有被标记时,无监督学习模型是有用的。对于互联网流量数据来说尤其如此,因为没有明确的方法来判断特定的互联网交易本质上是否是恶意的。在这种情况下,异常检测是常见的。

异常检测

想象你在浏览互联网时有某种行为。你在浏览 YouTube 时传输了一定量的数据,通过脸书信使发送了一定量的数据。现在,让我们将它汇总到整个组织中。平均而言,端点将具有可预测的端口使用率。现在,假设其中一个端点碰巧使用某个端口(它通常从不使用)来访问服务器端口(该端口可能因发送恶意软件而被列入黑名单)。这可能是潜在的端口扫描,甚至是公司网络上的 torrent 使用。另一个例子可能是一个或多个端口的突然高使用率,这表明 DDoS 攻击。有很多无监督学习算法,从 K-Means 到高斯混合模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于时间序列数据,可以查看数据点的标准偏差来寻找异常值。时间序列中的某些异常值可能显示不同的模式,可以使用傅立叶变换或隐马尔可夫模型来检测。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

更多细节,请查看我关于基于聚类的无监督学习的博客。

监督学习模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

某些欺诈检测数据集带有标签。就拿信用卡诈骗来说吧。如果银行怀疑有欺诈行为,他们可以打电话给持卡人,检查卡是否真的被盗。该信息可以用作新模型构建的训练数据。正如我将在本节中介绍的那样,监督学习模型也有自己的一系列机遇和挑战。

标签错误的数据

在欺诈检测问题中,数据集已经严重失衡。想象一下,除此之外还有贴错标签的数据?可惜现实世界没有 Kaggle 干净。你会得到极其杂乱的数据。我个人的一般策略是使用 K-Means 来可视化数据,以检查标记是否真的有意义。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然而,这是非常主观的,将取决于用例。如果做得好,我们可以得到一个更可靠的数据集来训练我们的模型。不利的一面是,有目标泄露的可能。

模型复杂性

自然,对于大多数欺诈检测用例,模型往往更复杂。考虑到所需的粒度和特性工程水平,简单的线性回归可能没有帮助。也就是说,人们需要意识到过度拟合他们的数据集。学习曲线通常有助于检查模型是否具有高偏差或高方差。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果模型是高度偏向的,那么就有可能研究更复杂的东西,比如决策树、随机森林甚至神经网络。通常,在金融机构中,通常使用系综模型。某些工程特征在单独的模型上工作得最好(通常是由于方差的巨大差异)。或者甚至将无监督学习模型与有监督模型结合使用(特别是当错误标签的可能性很大时)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

关于学习曲线、集合模型和其他基础知识的复习,请查看我的数据科学面试指南

惩罚模型

你可以使用相同的算法,但给他们一个不同的角度来看问题。惩罚分类对模型施加了额外的成本,用于在训练期间对少数类进行分类错误。这些惩罚会使模型偏向于更多地关注少数群体。通常,类别惩罚或权重的处理专用于学习算法。有惩罚版本的算法,如惩罚 SVM 和惩罚 LDA。

性能指标

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

评估模型性能最常用的方法是分类得分。然而,当只有 2%的数据集属于一个类别(欺诈),而 98%属于其他类别(非欺诈)时,错误分类分数实际上没有意义。你可以达到 98%的准确率,但仍然没有发现任何欺诈行为。此外,请记住,在处理欺诈时,我们关心误报。在这一部分,我将讨论一些可供选择的性能指标。

混淆矩阵

在分析误分类时,混淆矩阵是一种常见的偏好。矩阵的每一行代表预测类中的实例,而每一列代表实际类中的实例

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对角线代表已被正确分类的类别。这很有帮助,因为我们不仅知道哪些类被错误分类,还知道它们被错误分类为什么。

精确度、召回率和 F1 分数

为了更好地了解错误分类,我们经常使用以下指标来更好地了解真阳性(TP)、真阴性(TN)、假阳性(FP)和假阴性(FN)。

精度是正确预测的正观测值与总预测正观测值之比。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

回忆是正确预测的正面观察值与实际类中所有观察值的比率。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

F1-Score 是准确率和召回率的加权平均值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

F1 分数越高,模型越好。对于所有三个指标,0 是最差的,而 1 是最好的。

ROC 曲线

接收器操作特性或 ROC 曲线是欺诈分析(以及数字信号处理)领域中非常流行的指标。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

45 度线是随机线,其中曲线下面积或 AUC 是 0.5。曲线离这条线越远,AUC 越高,模型越好。一个模型能得到的最高 AUC 是 1,其中曲线形成一个直角三角形。ROC 曲线也可以帮助调试模型。例如,如果曲线的左下角更接近随机线,则暗示模型在 Y=0 处分类错误。然而,如果右上角是随机的,则意味着误差发生在 Y=1 处。此外,如果曲线上有尖峰(而不是平滑的),这意味着模型不稳定。对付诈骗模特,ROC 是你最好的朋友。更多信息,请阅读接收器工作特性曲线解密(Python 语言)

重新取样

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我的最后一个建议是重新采样。如果有可能获得更多的数据来使这些类更加平衡,这将是最简单和最好的方法。如果没有,创建合成数据也是一种可能。本节将介绍这些方法。

过采样

对模型中的欺诈记录进行过采样有助于改进分类。但是,要意识到它需要代表真实世界(相对于非欺诈,欺诈实际上很少发生)。SMOTE 和 ADASYN 是这方面的常用算法。自动编码器也可用于创建合成欺诈数据。

欠采样

欠采样非欺诈是另一种被使用的技术。基于聚类方法(例如 K-Means)生成质心是一种常见的策略。

结束语

理想情况下,我在这篇博客中提到的内容将帮助你想出更好的方法来应对欺诈模型(无论是工作、学校还是 Kaggle 竞赛)。我提到的许多事情可以在我的其他博客中找到更多细节:

[## 数据科学面试指南

数据科学是一个相当大且多样化的领域。因此,做一个万事通真的很难…

towardsdatascience.com](/data-science-interview-guide-4ee9f5dc778) [## 基于聚类的无监督学习

无监督机器学习是一种机器学习任务,它从神经网络中推断出一个描述隐藏结构的函数

towardsdatascience.com](/clustering-based-unsupervised-learning-8d705298ae51) [## Scikit-Learn 上决策树和集成的研究

现在科技界最热门的话题之一是机器学习领域。应用范围从…

medium.com](https://medium.com/@sadatnazrul/study-of-decision-trees-and-ensembles-on-scikit-learn-e713a8e532b8)

池保护器:利用网络分析防止支付欺诈

原文:https://towardsdatascience.com/frauddetection-f801b781410b?source=collection_archive---------14-----------------------

一个典型的组织会因欺诈损失大约5%的收入。对于规模较小的企业来说,情况可能更为严峻,因为它们通常受到的保护更少,承受损失的能力也更弱。通过Insight Data Science Fellowship,我为一家支付服务初创公司提供咨询,该公司因欺诈遭受了重大损失。这家公司,我们称之为公司 A,为用户提供了一个平台来集中他们的钱进行一次购买。例如,假设爱丽丝和鲍勃要去克里斯家参加聚会,他们都想分摊费用。在这种情况下,Chris 创建了一个池,他、Bob 和 Alice 都参与其中。克里斯然后取出钱来支付聚会的费用。然而,有可能稍后爱丽丝决定她不想为聚会付钱。她可以对自己向泳池支付的费用提出异议,而不是要求克里斯退款。如果她拿到了钱,而克里斯已经提取了资金池的余额,A 公司就只剩下支票了!这样的交易被称为退款

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

按存储容量使用计费旨在保护消费者。例如,在上面的案例中,如果 Chris 多收了她的钱并且拒绝退款,Alice 可以对她的付款提出异议。尽管如此,一些用户滥用退款流程,故意从公司 A 偷窃。由于不可能了解公司 A 每笔退款交易背后的真实动机,我从公司的角度将所有退款视为欺诈交易,因为它们都会给公司造成直接损失,并使用这种启发式方法在数据中找到可能指出真正欺诈的模式。

概观

在 2017 年的前三个季度,我所工作的公司因退款而损失了大约一半的交易费收益。记录显示,不到 1%的用户和不到 1%的交易会导致这种严重的损失。为了防止潜在的退款,该公司已经开始努力提取特定于用户和交易的特征,以建立一个欺诈检测模型。鉴于欺诈通常不是一个孤立的事件,我认为利用用户网络环境中的用户信息来增强模型是有价值的。具体来说,我发现用户的池社区和社交网络影响他们欺诈行为的机会,这可以用来提高公司 A 预测欺诈的能力。

泳池社区

在公司 A 的平台上进行的每一笔交易都将一群用户联系在一起。经过多年的支付,一个丰富的、潜在的强大的网络结构开始形成。关于这些泳池社区的第一个问题是:泳池的大小重要吗?下面是涉及按存储容量使用计费的池与完全合法的池的池大小的频率分布。总的来说,合法交易更有可能发生在中等规模的池中,有趣的是,有退款的大部分池的规模为 1。一号池一开始就是奇怪的实体(人们试图与自己分担成本吗?)这强烈表明用户只是利用它们来实施欺诈。下面的数据表明,阻止甚至标记从 1 号池中的提款将会减少三分之一以上的退款频率,同时减少不到 10%的合法交易。假设交易金额和费用不会随着池的大小而变化太大,这些数字表明,与交易费用损失相比,像阻止大小为 1 的池这样的简单政策转变将节省大约两倍的费用,从而对公司的底线产生重大影响。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于更大的池,分析池的组成可以让我们了解人们如何相互影响。将罪责归咎于个人可能取决于他们所交往的人,而不是他们犯下的任何欺诈行为,这种行为被称为“牵连犯罪”。下图显示了每个池中涉及按存储容量使用计费的欺诈用户与完全合法用户的百分比分布。按存储容量使用计费池组中有很大一部分池包含超过 10%的欺诈用户。这强烈表明,处于欺诈环境中会增加人们申请退款的倾向。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

社交网络

除了池社区,用户的社交网络也可能与他们提交退款的机会有关。我们鼓励该平台的用户使用他们的脸书帐户进行注册。下面我展示了脸书的欺诈用户友谊网络,其中圆圈上的每个点代表一个用户,每个用户都标有一种颜色,表示他或她已提交的退款数量。连接线代表用户在平台内的脸书连接。与上一节显示欺诈用户倾向于群集相反,当涉及到实际的社会联系时,欺诈用户似乎是独立的。此外,有许多欺诈用户在记录上没有一个脸书朋友,可能是因为他们选择不将他们的脸书账户链接到该公司的平台。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Facebook friendship network of fraudulent users

我们可以使用每个用户的“度中心性”来量化用户在网络中的重要性,即用户的朋友数量除以网络中的用户总数。下面的分布显示,与合法用户相比,在按存储容量使用计费用户组中没有朋友的用户的频率要高得多。合法用户往往有更多的朋友,如果我们进一步查看二级连接,并测量用户朋友的平均朋友数量(分布如下所示),情况也是如此。换句话说,与欺诈用户的朋友相比,合法用户的朋友也有更多的朋友。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

预测退款交易

上面讨论的网络特性本身显然是强大的。为了利用他们的集体力量,我将他们与公司 A 已经拥有的基于用户和基于交易的功能结合到一个单一的机器学习模型中。选择了一个随机森林模型来将每个交易分类为欺诈或合法。使用网格搜索来调整模型参数,这产生了具有 1300 棵树和最大深度 10 的模型。受试者工作特征(ROC) 曲线(左下)显示该模型具有很高的预测性。“完美”模型的曲线下面积(AUC)为 1.0,表明它对每个样本进行了完美分类,而“抛硬币”模型的 AUC 为 0.5。我训练的最终模型的 AUC 为 0.97。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

由于欺诈的成本(每月约 4800 美元)比调查合法交易的成本(每月约 300 美元)高得多,A 公司主要对实现高召回率的模型感兴趣。混淆矩阵(中上)显示最终模型的召回率为 74.8%。与 61.0%的无网络功能的原有型号召回相比,这相当于在公司当前规模下,每年大约增加价值 8,600 美元的欺诈防范。虽然模型的精确度从 74.3%下降到 53.8%,但欺诈防范节省的成本远远超过了增加的调查成本。突出在此项目中构建的网络要素的重要性是它们的重要性-这些要素由模型中 4 个最重要的要素中的 3 个组成(上图最右侧仅显示了重要性> 0.08 的要素)。我工作过的公司已经在努力将这种模式纳入他们的平台,这将有助于调查人员在案件结束前标记案件,转化为实际的节约。

未来工作

在模型参数的网格搜索中,我当前的模型在优化过程中使用 AUC 作为度量。虽然这种选择可以产生具有高总体预测能力的模型,但我们可以使用 F_beta 分数来更好地优化模型,以降低退款造成的总损失,同时考虑调查成本。F_beta 分数是精确度和召回率的加权调和平均值。一方面,召回率高的车型可以减少退换货带来的损失;另一方面,模型的精确性也很重要,因为每一项交易的调查都伴随着成本。因此,为了平衡损失和成本,需要以 F_beta 作为优化度量来网格搜索更好的模型。F_beta 分数中的权重 beta 可以从退款的平均损失和调查的平均成本中得出。我与该公司的未来工作将是利用损失和成本的知识来优化模型,以便我们可以降低退款造成的总损失,同时最大限度地减少合法交易的标志。

关于惠宗 ( )领英 )

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我目前是纽约市的 Insight 数据科学研究员,也是西北大学应用物理学的博士生。我的研究生研究主要集中在用于基因治疗的聚合基因递送系统的计算研究。在使用深度学习技术开发聚合物凝胶化的预测模型时,我对数据科学产生了兴趣。在这个项目中,我看到了数据驱动的方法如何解决有趣和相关的问题,我期待着继续沿着这个方向前进!

冻结 Keras 模型

原文:https://towardsdatascience.com/freezing-a-keras-model-c2e26cb84a38?source=collection_archive---------2-----------------------

如何为服务和其他应用程序冻结模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

“landscape photography of snowy mountain and body of water” by Joel & Jasmin Førestbird on Unsplash

简介

Keras 已经成为工业界和学术界开发和测试神经网络的主要 API 之一。由于其各种后端可能性,它结合了用户友好的语法和灵活性,这意味着你可以用 TensorFlow,Theano 或 CNTK 编写并在 Keras 中调用它。

一旦你用 Keras 设计了一个网络,你可能想在另一个 API 中,在网络上,或者在其他媒介上服务它。做上述许多事情的最简单的方法之一是使用预先构建的 TensorFlow 库(例如用于 C++环境中的模型推理的 TensorFlow C++ API )。为了做到这一点,由于这些 API 的后端工作方式,您很可能不得不“冻结”您训练过的 Keras 模型。不幸的是,为了轻松地做到这一点,您必须在 Keras 的 TensorFlow 实现中重新训练您的模型。然而,幸运的是,如果你知道你的目标是什么,这个过程非常简单,这要归功于 Keras 集成到 TensorFlow 的方式,以及 TensorFlow 为此任务提供的各种其他材料。

当我最初研究如何在 C++环境中为模型提供服务时,我从类似的帖子中找到了几个可能的答案,比如关于堆栈溢出的帖子,以及关于介质的帖子。类似地,一些人已经制作了各种很棒的开源包来做到这一点,比如 keras2cpp 。然而,我发现这些文章缺乏一些关键的细节,并且经常使用复杂的技术,这些技术在写作时是必要的,但由于 TensorFlow 的更新,这些技术已经大大简化了。

我希望这篇文章提供了一个简单的、最新的演练,展示了如何为任何一般需求冻结 Keras 模型,而不仅仅是为了在 C++环境中服务。虽然本文中描述的方法是专门为转换 Keras API 中编写的模型(本机或 TensorFlow 实现)而编写的,但它也可以用于任何用本机 TensorFlow 编写的模型。

为什么我需要转换我的模型?

如果您的模型经过训练并保存在 Keras API 中,那么您可能已经保存了模型的 hdf5 文件,其中网络架构和权重一起保存在一个文件中。这个文件可以被调用并加载回 Keras API 进行推理。然而,遗憾的是,TensorFlow APIs 无法识别这种文件类型,而且存储、加载和执行推理也不必要太大。

同样,如果你在 TensorFlow Python API 中编写一个模型,那么训练过程将使用 Google 的 ProtoBuf 库保存一个 TensorFlow ,以及一系列检查点文件。该图存储了关于带有Variable ops 的网络架构的信息,而检查点文件包含了训练不同阶段的权重值(取决于训练期间您的会话检查点的频率)。这些通常可以在 TensorFlow Python API 会话中加载用于推断,在此期间,来自检查点文件的权重被插入到图中的Variable ops 中。然而,当仅仅执行推理时,这是低效的。另一方面,一个保存的 Keras .h5文件仅仅是图形和最终状态检查点文件的组合,同时仍然保持超参数存储为Variable ops。(注:以上不需要详细了解,我只是给想要更详细解释的人补充一下。)

冻结模型意味着生成一个包含图和检查点变量信息的单一文件,但是将这些超参数作为常量保存在图结构中。这消除了保存在检查点文件中的额外信息,例如每个点的梯度,这些信息包括在内,以便可以重新加载模型并从您停止的地方继续训练。因为这在为纯粹用于推理的模型服务时是不需要的,所以它们在冻结时被丢弃。冻结模型是一个谷歌.pb文件类型的文件。

要求

冻结推理模型的要求很简单,但是,根据您的应用程序,您可能需要安装各种其他包来实际执行推理:

  • 将 Keras 与 TensorFlow 后端一起使用
  • 尽管安装了 TensorFlow 应该可以自动运行,但您需要确保 TensorBoard 在您的计算机上运行
  • 从 TensorFlow 存储库中,将 freeze_graph.py python 脚本复制到您的工作目录中。或者,您可以使用定制设计的freeze_graph函数,我们将在后面看到。

转换模型

为了生成包含必要信息的.pb文件,TensorFlow 编写了freeze_graph.py文件,该文件在被调用时将合并 TensorFlow 图形和检查点文件。使用这个 Python 脚本通常是明智的,因为它是由 TensorFlow 团队编写的,他们确保它可以与他们内部的文件格式一起工作。但是,为了使用它,您必须首先拥有正确格式的图形和检查点文件。Keras API 不会自动生成这个文件,所以您需要重新训练模型来生成它们。

有两种相对简单的方法来获取以正确格式保存的训练模型以进行冻结。如果您直接使用 Keras API,那么您将需要切换到在 TensorFlow 环境中实现的 Keras API。

**注意:**这应该只需要在导入阶段进行更改,例如,您将拥有from tensorflow.keras.layers import Convolution2D而不是from keras.layers import Convolution2D

第一种方法调用模型,然后将其转换为 TensorFlow 估计器,后者将处理训练。第二个要求理解 TensorFlow 会话是如何工作的,因为这种方法训练网络就像你用本地 TensorFlow 编写的一样。实施这些训练方法后,您将能够运行freeze_graph以获得正确的输出。

让我们通过一个例子来演示这个过程。在这里,我们将把一个简单的 Keras 模型转换成一个估计量,用于对 MNIST 数据集进行数字分类。

首先,我们在 TensorFlow 中实现的 Keras API 中构建模型,确保命名您的输入和输出层,因为我们稍后将需要这些名称:

Defining the model, note we do not define an input layer here since the type of input layer depends on which method you choose for training

选项 1:转换为估计值

一般来说,这种方法可能是两种方法中最简单的,但是,由于处理定制估计器的性质,它可以很快变得更复杂,这取决于您想要如何训练模型。如果您只熟悉原生 Keras API 中的训练模型,那么这是最相似的训练模型的方式。TensorFlow 1.4 引入了将 Keras 模型转换为 TensorFlow 估算器的功能,本教程对此进行了描述。

要将上述模型转换成估算器,首先使用 TensorFlow 中实现的普通 Keras API 编译模型,然后使用model_to_estimator()函数:

Converting the model into an Estimator, here the checkpoint files and graph will be saved in the model directory

现在estimator_model表现得像一个张量流估计器,我们可以相应地训练模型。有关如何培训评估员的指南,请参见文档

对于训练,定义一个输入函数并相应地训练模型:

模型现在已经训练好了,并且graph.pbtxt和检查点.ckpt文件将保存在./Keras_MNIST模型目录中。

选项 2:像原生张量流模型一样训练

另一种方法是通过启动张量流会话并在会话中训练来训练模型。这需要对会话如何工作有更详细的了解,这超出了本文的范围,我建议读者参考这个 MNIST 教程作为这种培训的例子。然而,与示例不同的是,您不需要在 native TensorFlow 中编写模型,相反,我们可以调用上面的模型,只需更改输入层:

剩下的就可以从教程中遵循了。

冻结模型

现在模型已经训练好了,图形和检查点文件也制作好了,我们可以使用 TensorFlow 的freeze_graph.py将它们合并在一起。

**注意:**确保freeze_graph.py与您想要冻结的检查点和图形文件在同一个目录中。

或者,我发现由摩根开发的简化版更不容易标记错误。

Simplified freeze_graph implementation by Morgan

此函数使用图形重新启动临时会话,以恢复最近的检查点。使用这种实现的另一个优点是,您不必确保指定了正确的检查点文件,或者处理语法上更加密集的freeze_graph.py输入。

我们需要知道输出节点的名称,作为函数的引用点。这和我们用不用freeze_graph的简化版是一样的。你给最后一层起的名字是不够的,打开 TensorBoard 会给出一个可视化的图形。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

TensorBoard output showing input to ‘metrics’ node

在这个例子中,我们想要的是进入“度量”节点的张量,叫做output_node/Softmax

这将在模型目录中生成一个冻结的图形。

关键要点

  1. Keras 模型可以在 TensorFlow 环境中训练,或者更方便的是,变成一个语法变化很小的估计器。
  2. 要冻结一个模型,你首先需要生成检查点和图形文件,以便调用freeze_graph.py或上面的简化版本。
  3. TensorFlow 上有许多标记为 Keras GitHubs 的问题,以及关于冻结模型的堆栈溢出,其中许多问题可以通过了解需要生成的文件以及如何指定输出节点来解决。
  4. 输出节点可以很容易地从 TensorBoard 可视化中找到,但它并不总是你指定的最后一层的名称。

使用异构网络嵌入的朋友推荐

原文:https://towardsdatascience.com/friend-recommendation-using-heterogeneous-network-embeddings-54f95babdb13?source=collection_archive---------22-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

想象一下史努比没有伍德斯托克或者卡尔文没有霍布斯,老友记没有瑞秋,蝙蝠侠没有罗宾或者无忌没有布鲁。社交平台的繁荣依赖于成员找到相关朋友进行互动的能力。网络效应是驱动应用程序增长或花费时间和每日活跃用户的因素。这对于 Hike 来说更加重要,因为 Hike 是一个亲密朋友的网络。因此,我们需要确保找到朋友、邀请他们并将其添加到网络中很容易。

从一个人第一次开始徒步旅行,提供朋友建议作为登车体验的一部分是至关重要的。我们的数据显示,在加入后的最初几分钟内找到朋友的新用户,其留存率明显高于没有找到朋友的用户。因此,好友推荐算法的功效对于平台的增长和参与度至关重要。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

“Society friendship and love, Divinely bestow’d upon man” — William Cowper, The Solitude of Alexander Selkirk

在像 Hike 这样活跃的现实社会网络上设计一个朋友推荐系统意味着:

  1. 好友建议需要相关 —由于屏幕空间有限,一次只能显示几个好友建议,这意味着我们需要推荐相关的人
  2. 好友推荐需要顺利进行这样新用户可以毫不费力地加入网络
  3. 它需要以未来为中心。网络在不断发展,每天都有新用户加入,添加朋友,老用户之间建立友谊等等。基于当前网络,我们希望能够预测网络中即将发生的变化,并相应地提出建议

在 Hike,我们在自然语言处理(NLP)、计算机视觉、相关性和推荐、网络分析等领域部署了最先进的机器学习算法。(ML @ Hike 概述)。我们的朋友建议模型是使用深度学习和网络分析的高级研究建立的。我们对此进行了深入研究,并开发了一个框架,用于在具有多种边缘类型的异构网络上进行图形表示学习,以进行朋友推荐。这对我们来说非常好,除了商业收益,当这项研究被提名发表在 2019 年 4 月的欧洲信息检索会议(ECIR)上时,我们非常兴奋。

朋友推荐问题符合社交网络中的经典链接预测问题。我们将平台上的用户表示为位于一个图上,图中的边是用户之间的连接。给定一个社交网络在时间 t 的快照,我们能否准确预测在从时间 t 到给定的未来时间 t` 的间隔期间将被添加到网络的边?简而言之,网络的当前状态可以用来预测未来的链接吗?传统的链路预测方法是基于分析网络中节点“接近度”的测量。具体而言,如果两个节点的邻域有很大的重叠,则这种方法将指示它们很可能共享一条链路。*共同邻居、Jaccard 系数、Adamic-Adar 度量、*是已经被设计用于评估节点邻域之间的重叠的不同度量。还有使用节点特征来训练分类模型的监督机器学习技术。这些功能并不总是容易获得,因此需要大量的功能工程。

两个节点的节点嵌入可以被组合以形成连接它们的边的表示。在链接预测的情况下,这种边缘嵌入可以被给予分类器,以预测边缘是否可能存在。

最近,在开发用于学习图形表示的方法方面已经有了很多工作。这些表示捕捉节点与其邻居的关系。我们可以使用这些图形表示来跳过我们的模型的手动特征工程,并且可以使用节点向量来训练模型,以解决诸如链接预测、节点分类和社区检测之类的问题。这种表现形式已被证明比手工设计的特征更有效。其思想是学习一种映射,该映射将节点投影到低维向量空间中,从而保持相邻关系。嵌入生成通常遵循两个步骤:

  1. 网络中每个节点的样本邻域,例如通过生成从节点发出的随机行走。这些示例捕获了节点之间的上下文关系。
  2. 一种 skip-gram 类型的模型,它将随机行走作为输入,并将节点投影到低维空间。

一个类比是文本文档中的单词嵌入(word 2 vec)——随机游走是句子的网络对应物。两种流行的节点嵌入方法如下:

Deepwalk 方法学习同构网络中的节点嵌入。首先,我们从每个节点开始,生成固定数量的选定长度的无偏且均匀的随机行走。Skip-gram 算法用于从随机行走中获得节点嵌入,随机行走期望捕获网络节点的上下文属性——出现在相同上下文中的节点具有相似的向量嵌入。

学习同构节点嵌入的另一个重要方法是 node2vec,其中随机行走偏向于导航节点的邻域,使得它们可以从广度优先搜索(BFS)过渡到深度优先搜索(DFS)遍历。BFS 和 DFS 之间的插值由一个参数指定,为了获得良好的性能,这需要进行大量调整。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

朋友推荐可以被定义为二元分类问题,该问题从一对用户获取特征,并且如果是朋友对,则学习将它们映射到 1,否则映射到 0。我们可以利用网络嵌入来获取用户特征。如果 u,v 是两个用户,并且 vec_u,vec_v 分别是对应的节点嵌入,我们可以以各种方式组合这些嵌入来创建分类模型的输入,例如

  • 串联,vec =**vec _ uvec _ v
  • 平均值,vec =(vec _ u+vec _ v)/n
  • 哈达玛乘积,vec =vec _ uvec _ v*

注意,这些都是向量运算。向量 vec 可以认为是边< u,v >的嵌入。然后将 vec 输入机器学习模型,如逻辑回归、神经网络等。训练分类器需要模型“学习”的已知朋友和非朋友对的大量标记数据

D = { < u,v >,label},其中 label ∈ {0,1}

为了评估,保留了一个测试集。这种模型可以通过各种度量来评估,例如

ROC 曲线下面积(AUC)

-k 处的精度(P @ k)

为了在 Hike 等真实世界的活跃社交网络上测试朋友推荐模型,人们还需要评估该模型在应用程序上的功效,这可以通过比较前 k 名推荐的点击率(CTR)来完成。

Hike 的社交图谱相当独特。网络是高度异构的,具有多种节点类型,例如用户、帖子、主题等。以及多个边缘类型,例如友谊、喜欢、评论、关注等。对于朋友推荐系统,我们假设一个徒步旅行的用户网络是同类型的,但是这个网络的边是异构的,在节点之间有多种类型的边。为了便于说明和扩展,我们使用了具有三种边缘类型的异构网络:

“联系人”—如果用户在彼此的联系人中

“朋友”——如果用户是徒步旅行的朋友

“聊天”——如果用户在一段时间内至少聊过一次

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这允许在两个节点之间存在多条边,例如,如果用户出现在彼此的联系人列表中,是朋友并且在过去的一个月中交换了聊天消息,则在他们之间将存在三条边。Hike 网络比以前使用网络嵌入方法对链接预测进行的研究要大得多。边缘类型的异质性对于我们的网络也是非常独特的,我们的网络在数学上可以描述为具有多种边缘类型的多图。我们数据中的另一个混淆因素是,在我们的验证数据中,46%的节点对没有共同的朋友——有许多孤立和松散连接的节点。这些挑战增加了朋友推荐问题的难度。

DeepWalk 和 Node2vec 的适用性仅限于具有一种类型的节点和节点间单一类型的边的同构网络。为同构网络设计的现有网络嵌入方法可能不直接适用于异构网络。最近, metapath2vec 提出了一种异构网络的嵌入技术,它定义了元路径(一系列节点类型)来限制随机游走。然而,如何定义这样的元路径并不明显,因为我们通常缺乏对路径和元路径以及元路径长度的直觉。此外,对于具有不同边类型和两个节点之间的多条边的异构网络(异构多图),没有直观的方式来定义边类型的元路径。在 metapath2vec 中,提出了一种在具有图像和文本节点的多模态网络中学习节点嵌入的深度架构。然而,它不能推广到一个多图,其中一对节点之间存在不同类型的边。对于异构网络,Deepwalk 有一些简单的扩展。

无偏随机行走是通过分配穿过两个节点之间的任何边的相等概率来生成的。这增加了随机行走到与当前节点有多条边的节点的概率。一个限制是,在 Hike 网络中,接触边远远多于朋友,聊天连接甚至更少。因此,随机漫步有更高的机会通过接触边,在某些情况下完全避免聊天边。

一个简单的解决方案是,随机游走受主导边类型的影响,随机游走是这样生成的,即有相等的概率跳到每个边类型上。这通过随机选择边缘类型来实现,然后在所选边缘类型中随机选择边缘。实际上,不同的边类型对随机游走的贡献不同,并且会有不同的权重。我们没有直观的方法来获得这些权重。

这些方法的主要缺点是,没有明显的方法来找出如何对每种边类型的随机游走进行偏置;没有理由认为边类型具有同等的重要性。

我们提出了一种方法来自动估计每个边缘类型的贡献,以获得边缘的最终嵌入。我们展示了与朋友推荐问题的相关性。计算过程如下:

  1. 将 Hike 网络分为朋友子网、联系人子网和聊天子网,用户分别通过友谊、联系人列表和聊天连接。这些子图中的每一个都是同质的。
  2. 使用 DeepwalkNode2Vec 从每个子网中获取节点嵌入。我们现在有了一个节点在多个空间中的表示。
  3. 在每个同质嵌入空间中,从节点嵌入计算边缘嵌入
  4. 为链路预测训练统一的异构边缘嵌入。

用于学习统一表示的模型基于多输入神经网络,该网络从不同空间获取同质边缘嵌入,并将它们组合以在新空间中形成嵌入,该新空间具有来自 3 种边缘类型的贡献。下图显示了神经网络体系结构,其中节点嵌入被连接以产生边嵌入:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

与其他最先进的技术相比,这种方法表现出优越的性能。我们报告了 AUC 分数比 Deepwalk 方法提高了 20%,并且在 5 处的精确度提高了 4.4%。我们还通过发送最可能的友谊作为应用内通知进行了用户实验,我们观察到比基线提高了 7.6%。

简单说一下工程方面——该系统有离线和在线组件。在离线系统中,社交图每天重新计算,节点嵌入被计算并存储在像 FIASS 这样的可扩展系统中,该系统建立索引以促进快速相似性搜索。如前所述,我们还基于神经网络训练了一个新的推荐模型。用户的朋友建议是以在线方式创建的,其中我们查找用户的节点嵌入并执行最近邻搜索以获取候选集,然后使用神经网络模型对其进行评分。布隆过滤器检查确保不会为用户重复推荐。以这种方式生成的前 k 个推荐在 Hike 应用程序上的不同推荐部件中提供。该系统如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

改进对远足的朋友推荐是我们团队本季度的一项关键 OKR 指标,我们已经达到了本季度的改进指标。在这次旅程中,我们开发了一个框架,用于在具有边缘异构性的图上进行图形表示学习,本文中介绍的模型基于我们即将在 2019 年 ECIR 会议上发表的研究论文🏆😎

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

原载于 2018 年 12 月 18 日blog . hike . in

使用生成的谷歌表单进行更友好的数据标注

原文:https://towardsdatascience.com/friendlier-data-labelling-using-generated-google-forms-d25e3e9f6aa6?source=collection_archive---------7-----------------------

手动标记数据是无人喜爱的机器学习琐事。如果你能给别人一个愉快的工具来完成这项任务,你就不必担心要求别人帮忙。让我向您展示:使用 Google App 脚本生成的 Google 表单!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Google App Scripts allow you to build automation between Google Apps

人们给数据加标签的常规方式是在电子表格中输入标签。我通常也会这样做,但是在最近的一项任务中,我需要标记文本段落。你曾经尝试过阅读电子表格中的文本段落吗?…简直是地狱!幸运的是,当我试图找出一种方法使标签过程不那么累的时候,我遇到了一种使用 Google App Script 根据电子表格文档中的数据自动生成表单的方法。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Nasty! Nobody wants to strain their eyes trying to read documents in spreadsheet cells!

创建将生成我们表单的脚本

首先,我们只需从包含我们想要收集标签的数据的 Google 电子表格中进入应用程序脚本编辑器:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Opening the App Script editor from a Google Spreadsheet

使用应用程序脚本(pssst!这只是 JavaScript)我们可以读取电子表格数据,并向其他谷歌应用程序(在这种情况下,谷歌表单)发送命令。

使用表单进行标记的好处在于,您可以通过指定数据输入类型来保证用户输入的一致性。例如:

号码范围:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

form.addScaleItem()
.setTitle(dataToLabel)                    
.setBounds(1, 10)        
.setRequired(true);

二进制标签:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

form.addCheckboxItem()
.setTitle(dataToLabel)
.setChoices([
           item.createChoice('Is a cat')
           ])

多类标签

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

form.addMultipleChoiceItem()
.setTitle(dataToLabel)
.setChoices([
         item.createChoice('Cats'),
         item.createChoice('Dogs'),
         item.createChoice('Fish')   
])

App Script API docs 中查看更多输入类型的详细信息(或者手动创建 Google 表单时只查看不同的输入类型)。

您可以从我的 Github 中获取我用来生成用数字 0 到 10 标记文本文档的表单的脚本:

[## ZackAkil/更友好的数据标签

更友好的数据标注代码资源,用于生成标注数据的 google 表单。

github.com](https://github.com/ZackAkil/friendlier-data-labelling/blob/master/Code.gs)

在你写好剧本(或者复制粘贴)之后;然后选择脚本的入口点并运行它!警告:第一次做的时候,你可能需要通过一些授权环节。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Make sure to select the entry point function of the script before running.

使用生成的表单

脚本运行后,您可以前往您的 Google 表单,在那里您应该会找到一个全新的表单!你可以把表格发给任何你想贴标签的人:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Finally you can send your labellers a convenient link to a familiar Google Form that they can use to carry out the labelling task.

访问数据标签

完成标记后,您可以将标签作为电子表格查看,并导出为 CSV 格式:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

It’s pretty straight forward to get the labels out as a CSV.

希望这能让你在未来的机器学习工作中少一点头痛!

本文中使用的完整脚本和数据集可以在我的 Github 上找到:

[## ZackAkil/更友好的数据标签

更友好的数据标注代码资源,用于生成标注数据的 google 表单。

github.com](https://github.com/ZackAkil/friendlier-data-labelling)

Frieze London 2018(第二部分):自然语言处理

原文:https://towardsdatascience.com/frieze-london-2018-part-2-natural-language-processing-66d0627f39af?source=collection_archive---------18-----------------------

第二部分:5.6k Instagram 和 3.2k Twitter 帖子的自然语言处理

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

介绍

Frieze 是一家国际艺术商业特许经营公司,1991 年以杂志起家,但后来发展成为一家组织一些年度日历上最重要的艺术博览会和活动的机构。

自 2003 年以来,每年 10 月,Frieze 都会在伦敦摄政公园的中央组织一次大型当代艺术展,吸引成千上万的人。来自 20 多个国家的 150 多家画廊通常会参加盈利性艺术博览会。

然而,Frieze 现在已经不仅仅是一个艺术博览会。
“楣周”已经成为一个文化娱乐周,人们纯粹是为了观赏而参加,这里有一个雕塑公园,甚至主要的拍卖行也举办他们的中期当代拍卖会,以配合楣周。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

本文的目的是通过展示我对关于艺术博览会的 5.6k Instagram 和 3.2k Twitter 帖子的自然语言处理分析的发现,更好地了解 Frieze London 2018。

请向下滚动,通过交互式数据可视化查看我的分析!

数据和方法

这一事件的官方标签是#frieze。在通过 Twitter API 和 Instagram API 收集了事件发生时包含这个标签的 9000 个帖子之后,我首先清理了 Python 笔记本中的文本数据。

然后,我使用谷歌的 langdetect 库 过滤掉非英语推文,并从 NLP 分析中删除所有转发,这样就不会出现重复。在这些步骤之后,我剩下了 7400 个独特的帖子。接下来,我使用谷歌云自然语言 API 来获取每条推文的情感。

最后,我使用 gensim 库的 Word2Vec 模型来获取整个 tweets 语料库中与单词“frieze”相关的每个单词的单词嵌入向量。Word2Vec 用于从大型文本语料库中计算单词之间的相似度——卡维塔·加内桑文章就是一个很好的解释。

一旦我有了每个单词的向量,我就使用 scikitlearn 库来执行主成分分析(PCA)以进行降维,并绘制出与“frieze”最相似的单词(最近邻居)。

你可以在这里查看我的 Kaggle 内核这篇文章的所有分析。

分析帖子

在这一节中,我将展示我的自然语言处理(NLP)分析的发现。下面,我报告以下三个指标:

  1. 每日推文的情感分析;
  2. 词频和标签频率分析;
  3. Word2Vec 模型的输出:主成分分析(PCA)和最近邻分析。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

情感分析

每条推文的情绪是使用谷歌的云 NLP API 计算的。下面的条形图显示了每天推文的平均情绪,其中-1 表示非常消极的情绪,+1 表示非常积极的情绪。

不幸的是,我们看到,随着展会的进行,人们对 2018 年伦敦奥运会的热情逐渐降低。开始时为 0.47,到周日时一路下跌至 0.37。然而,到了交易会的最后一天,它又反弹到了 0.47!

Figure 1: Line chart showing the average sentiment of the tweets per day

文本频率分析

下面的条形图显示了一个词和一个标签在所有社交媒体帖子中出现的次数,分别在左侧和右侧。不出所料,“中楣”出现的次数最多。

但是,因为标签也出现在社交媒体帖子的主体中,所以在计算单词频率时,它们成为了一个混淆变量。因此,我采取措施将 hashtag 计数从单词计数中移除。

然而,下面的结果并不能很好地告诉我们人们对该事件的看法。我们只发现名词而不是形容词。我们可以使用一些机器学习技术来尝试挖掘一些形容词。

Figure 2: Bar graphs showing the count of words and hashtags appearing in all the tweets

最近的邻居

Word2Vec 是神经语言机器学习模型。它采用大量的文本,在这种情况下,来自 9000 个社交媒体帖子的文本作为输入,并产生一个向量空间,通常有数百个维度,每个唯一的单词对应于空间中的一个向量——单词嵌入。然后使用主成分分析将 Word2Vec 空间的维度降低到 xy 坐标。

重要的是,Word2Vec 用于从 9000 条推文中捕捉单词之间的相似性和关系。具体来说,空间中距离较近的对象意味着它们是相似的。“最近邻”是来自 Word2Vec 模型的少数几个基于余弦度量相似性得分与“frieze”最相似的单词。

Figure 3: PCA output of the nearest neighbours of #frieze from the Word2Vec model

上面的散点图使用两个不同的语料库显示了“frieze”的最近邻居;一个包含标签,一个没有标签。

在带有标签的语料库中,我们看到许多与“frieze”最近的邻居实际上就是标签;比如《friezelondon 2018》《friezeartfaire》《friezemasters》。有趣的是,“regentspark”和“sculpture”出现在附近,可见雕塑公园的受欢迎程度。

不幸的是,很少有形容词或描述性词语来描述人们对艺术博览会的看法。在没有标签的语料库中,我们看到一些描述性的词,如“谢谢”、“最好”和“亮点”,但同样,这些词很少告诉我们人们对事件的看法。需要更深入的分析。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结论

所以你有它!我已经展示了我对关于艺术博览会的 5.6k Instagram 和 3.2k Twitter 帖子进行 NLP 分析的结果。我的发现没能告诉我们人们对博览会的看法。

在未来的研究中,我将致力于更深入的分析。有这么多的 NLP 库,我很可能会在未来使用 GloVeTensorflowBert 重新审视这个分析。

下次…

在我的下一篇文章(第 3 部分)中,我将展示我的计算机视觉分析的发现。期待看到哪些艺术品出现的次数最多。敬请关注。

感谢阅读!

Vishal

我是一名文化数据科学家,是伦敦 UCL 学院的研究生。我对城市文化的经济和社会影响感兴趣。我欢迎反馈和建设性的批评。 你可以在TwitterLinkedIninsta gram或我的 网站 上与我取得联系。

从大数据到微服务:如何通过 AWS lambdas 为 Spark 训练的模型提供服务

原文:https://towardsdatascience.com/from-big-data-to-micro-services-how-to-serve-spark-trained-models-through-aws-lambdas-ebe129f4849c?source=collection_archive---------6-----------------------

通过预先训练的 Spark 模型为端点供电的快捷方式

介绍

“我们选择它是因为我们要处理海量数据。另外,听起来真的很酷。”—拉里·佩奇

恭喜你!你用 Spark 训练了你的决策树,得到了一个很好的模型。现在呢?

你想利用你的模型来提供实时预测,但在 Spark 中没有简单的方法来获得网站或应用程序所需的交互性:如果你正在构建,比如说,欺诈检测,在每个用户动作时,你都想触发实时预测并采取相应的行动——时间是关键!

我们需要的是一种 快速简单 的方式,从我们的大数据模型转向一种微服务,一次只按需提供一个预测。

当然,可能会有更好的选项满足您的需求,并且味道更好:您可能事先知道测试集(在这种情况下,请参见这里的中的示例);您可能乐于处理传入的流数据,并定期访问缓存以进行接近实时的预测(例如,选项 B 在此处详述);最后,你可能喜欢 JVM,并寻找一些完善的、现成的东西(在这种情况下,你应该完全检查一下 Mleap )。

相反,我们在这里要做的是分享一个纯 Pythonic 式的端到端工作流,它将在几分钟内让您从 Spark 中训练的模型到服务于预测的公共端点。

我们的工作流程基于以下“原则”:

  • 它是你所了解和喜爱的 Python,从头到尾(加上一个非常小的 yml 文件);
  • 这涉及到一些语言解析(在也是如此,我们确实热爱语言);
  • 它不会涉及部署服务器,甚至不会显式地编写端点(对于中等工作量也是免费的);
  • 我们将使用决策树来演示工作流,但同样的想法可以很容易地扩展到其他 Spark ML 算法。

不仅仅是一种部署 Spark 模型的方法(以及其他方法),我们将有机会看到一个真正的数据工程挑战,以及将一个模型规范从一种语言翻译成另一种语言是多么有趣(嗯,如果你喜欢这种事情)。

这是“懒于开发”系列的上一篇文章的概念性续篇,那篇文章的特色是 AWS Lambdas(还有什么?)和 Tensorflow 模型

先决条件

在深入研究代码之前,请确保:

  1. 有一个可用的 Spark 集群:为了方便,我们使用了由微软 Azure 提供的 Linux Spark 2.2,但是当然我们所说的任何东西也可以很容易地应用于其他设置;
  2. 设置一个 AWS 帐户,它将用于将我们的代码部署到 AWS Lambda
  3. 设置无服务器,可以按照这里的说明轻松安装(记住还要设置您的 AWS 凭证!).

你可以在我们的公共 GitHub repo 中找到所有代码:开始工作吧。

前传:在 Spark 中训练一个机器学习模型

Spark 机器学习库的内部工作不是本文的重点:如果你在这里,你可能已经知道如何训练你的模型——如果你知道,跳到下一节,因为我们唯一需要的是一个文本文件中训练模型的序列化版本。我们决定在 Spark 上包含一个小部分来共享一个端到端的、自包含的用例,所以我们只需要做最少的工作来获得一个经过训练并准备好使用的玩具模型。

SPARK 初学者注意事项:如果您已经为您的集群使用了 Azure 部署,您可以遵循微软的指南开始查询一些样本数据和/或花一些时间使用集群提供的示例笔记本。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The PySpark folder in Azure Jupyter contains several ready-made notebooks to get you started.

repo 中包含的 decision_tree_training 笔记本只包含加载一些数据并获得训练好的模型的基本步骤。我们使用的数据集是钞票认证数据集的 csv 版本(此处也有),有四个连续变量作为预测变量,两个目标类,在数据集中用 1/0 标识:多亏了 Spark,我们可以用简单的 SQL 语法快速了解类的分布情况:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Notebooks will let you easily display basic statistics of your datasets, with tables and simple charts.

为了训练我们的决策树模型,我们只需要将数据转换为标签点,并将结果 RDD 馈送到机器学习库。

经过快速计算后,模型终于可以使用了!请记住,我们的目标是将我们在 Spark 上学到的知识转化为现成的无服务器端点,因此我们需要一种方法来提取我们在培训期间学到的数据知识,以便它可以在运行时应用于我们堆栈中的其他地方。幸运的是,决策树可以只用一行代码导出:

serialized_model = model.toDebugString()

serialized_model 包含在训练期间推断的决策规则列表,例如:

DecisionTreeModel classifier of depth 5 with 37 nodes
  If (feature 0 <= 0.23874)
   If (feature 1 <= 7.2797)
    If (feature 0 <= -0.36279)
     If (feature 2 <= 6.6779)
      If (feature 1 <= 5.496)
       Predict: 1.0
...
...
...

作为一个简单的 python 字符串,可以使用标准的 Spark 方法或通过简单的复制+粘贴将它导出到一个文本文件中(可以在 repo 中找到通过数据集训练生成的模型的副本)。

解决方案概述

下面详细介绍了我们快速而有效的解决方案。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Solution overview: from CSV to a lambda-powered endpoint.

从左至右:

  • 我们从 Spark 读取一个 CSV 文件开始(当然,这里用您拥有的任何数据管道来代替);
  • 我们训练我们的 ML 模型(一个决策树)并使用 Spark 序列化选项来使它——可以说— 可移植
  • 我们编写了一个 Python 函数(细节如下),它将读取序列化的模型,并生成模型的 Python-runnable 版本;
  • 我们在 AWS 中部署了一个基本的 lambda 函数,它将加载 Python-runnable 模型,并利用 API Gateway 向外界公开它的预测。

很明显,所有的神奇之处在于将模型从其 Spark 表示“移植”到 Python 可运行的代码中。在下一节中,我们将看到如何以一种有原则且优雅的方式来完成它:输入 DSL 解析

作为形式语义学练习的模型转换

“这些是我的原则。如果你不喜欢他们,好吧,我还有其他人。”—格劳乔·马克斯

主要的见解(也是大部分的乐趣——在 Tooso 我们做了很多语言相关的东西!)是将问题视为一个语义挑战:我们有一种形式语言(Spark 序列化语言),我们为它提供了一种模型理论意义上的解释,即我们需要找到一种系统的方法来将 Spark 模型的语法组件与 Python 数据结构配对,这样我们就可以通过这些结构运行预测,同时保留原始模型中的信息。听起来很难?让我们先用一个例子来建立我们的直觉(熟悉形式语义学思想的读者可以安全地跳过下一段)。

让我们拿正式的玩具语言 L 来说,这样定义:

  • 字母表由整数 1、2 … 10 和运算符“+”组成
  • 一个良构公式 (wff)是形式为 A + B 的任何符号序列,其中 A 和 B 是整数或 wff。

为了产生有效的句子,我们只需要应用(一次或多次)语言规则。例如,我们可以这样做:

A + B > 2 + B > 2 + 9

为了得到 wff‘2+9’,或者我们可以这样做:

A + B > 2 + B > 2 + A + C > 2 + 9 + C > 2 + 9 + 7

其中我们将第二步中的 B 展开为一个新的 wff‘A+C’,然后用整数填充公式得到‘2+9+7’。显然,在 L 中并不是所有的公式都是可以接受的:例如,下面这些都是无效的:

2 9 +
+ 2 9
2 9
12 + 2

L 是一种非常简单的语言,具有 no 的内在含义:虽然人类不可避免地会认为‘2+9+7’是基于 L 的算术运算2 + 9 + 7 (18)的表示,但是到目前为止 L 中并没有任何指定的东西可以证明这一结论(例如,很容易想象一个外星种族将+的含义与*互换:如果我们给他们的话)).为了赋予 L- 句子“自然”的算术含义,我们需要语义学家所说的模型(不要与机器学习模型混淆),也就是说,我们需要以一种原则性的方式指定我们如何将“含义”附加到 L 句子上。由于“意义”是一个相当抽象的概念,我们将满足于更简单且对我们的教程直接有用的东西:我们将使用另一种正式语言 Python 来给出 L. 的解释

因此,我们的语义将是从 L 句子到 Python 指令的映射,这具有可操作性的非次要好处(这样我们就可以L 句子做运算)

我们的(粗略定义的)模型 M 可以如下:

  • 整数 1,2 … 10 映射到 Python int 1,2 … 10
  • 运算符“+”映射到 Python lambda lambda x, y : x + y
  • 像 A + B 这样的一个 wff 映射到 Python 函数map(+, [A], [B])),即一个 wff 是用实际值在’+'操作中“填充槽”的结果。

有了 M 的武装,我们现在可以将我们无意义的 L 语句翻译成易于理解的 Python 命令,这样‘2+9’就可以被视为一种 L 的方式来表达下面的代码:

map(lambda x, y: x + y, [2], [9]))

更复杂的东西会按预期进行翻译,因此“2 + 9 + 7”将变成:

map(lambda x, y: x + y, map(lambda x, y: x + y, [2], [9]), [7])

我们的建模语言 Python 很酷的一点是,表达式可以被运行,这样,既然它们有了意义,L-句子就可以被看作是进行算术计算的简洁的 Python 指令:对于所有的L-表达式,我们可以关联一个相应的、唯一的 Python 代码来运行那个表达式。

既然我们理解了模型构建的含义,我们可以回到 Spark 序列化模型的原始语言,即产生“wff”的语言,例如:

DecisionTreeModel classifier of depth 5 with 37 nodes
  If (feature 0 <= 0.23874)
   If (feature 1 <= 7.2797)
    If (feature 0 <= -0.36279)
     If (feature 2 <= 6.6779)
      If (feature 1 <= 5.496)
       Predict: 1.0
...
...
...

我们的目标是以一种有原则的方式给这些字符串赋予一个“Python 含义”,以便每个字符串都有一个相应的、唯一的 Python 代码来运行该决策树。

我们利用 lark 构建了我们的 spark2python 服务(在这个项目之前我们从未使用过它,我们非常喜欢它!),这是一个很棒的工具,给定一个语法规范一个目标字符串,它将生成一个“解析树”,一个组成字符串的语法片段的嵌套表示。我们跳过了带有 L 的树,因为这种语言足够简单,但是如果你想一想我们是如何构建“2 + 9 + 7”句子的,就很容易看出它的结构:首先将 2 和 9 相加,然后将结果相加为 7。

 +
          7
  +
2   9

当 lark 解析一个 Spark 模型时,结果是一个嵌套了 if/else 块的树(如预期的那样):一旦我们有了解析树,我们就可以逐个节点地导航它,并用等价的 Python 片段替换(非常类似于上面的L)Spark 令牌,我们可以对目标值的特征向量运行这些 Python 片段。

如果您查看处理程序中的 predict 函数(AWS lambda 入口点,见下文),您可以很容易地了解运行时发生的情况:客户端在调用服务时将一个特征向量作为查询参数传递;启动时初始化的 Spark2Python 类,加载 lark 语法并解析序列化的模型字符串。

当客户端提供的特征向量到达映射服务时, run_instruction 将开始遍历所有 if/else 块:对于每个节点,组成等式测试的令牌将被映射到相应的 Python 对象。例如,这个火花节点:

(feature 0 <= 0.23874)

将等效于 Python 表达式:

map(lambda x, y: x <= y, [feature_vector[0]], [0.23874])

将根据客户端作为输入提供的向量中的特征 0 来评估结果表达式。当到达一个预测节点时,例如:

Predict: 1.0

给定特征向量和存储的模型,程序将停止并向客户端返回预测值。

虽然 run_instruction 看起来令人生畏,但一旦上述直觉得到巩固,它实际上是一个相当简单的概念:程序将递归地遍历 if/else 树结构的分支,并在每次遇到适当的节点时运行等效的 Python 代码。这就是服务执行的“自动”转换的全部内容!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Runtime comparison of the input features with the model decision rules: at each node a decision is made and the corresponding branch is explored until a prediction is reached.

重要的是要理解我们的语义到底有多普遍。由于我们为 Spark 模型建立了正式的语法,然后定义了结果树的递归 Python 解释,所以我们“保证”所有未来的模型,无论有多长或如何嵌套,都将被系统正确执行,就像我们保证所有现在和未来的L-句子都可以被 Python 评估一样。俗话说,循环是人,递归是神

(我们将在下面讨论这个问题,但是是的,显然有一个更简单的选择,那就是直接顺序解析模型文件*。“蛮力”是有效的(利用 Python 和 Spark if/else 结构中的同构),但是 DSL 方法不仅更优雅,而且也是尝试新事物的好借口,比如 lark 。*

使用 AWS Lambda 服务模型

我们的承诺是在几分钟内为您的原型开发提供一个微服务,不需要服务器,只需要 Python 代码就可以了。实现这一点的方法是使用一个 AWS Lambda 来包装我们训练好的模型,并使用无服务器框架来发布我们的服务,让全世界都能看到!

并不缺少关于 Lambda 函数剖析的教程和解释(我们自己的版本是这里是)。对于那些在过去三年中被冷冻在石墨中的人,要点如下:

无服务器计算是一种云计算模式,允许您部署特定的功能/服务,而无需考虑底层硬件、操作系统甚至容器:计算是根据需要进行的,您只需为功能实际运行的时间付费。

无服务器功能由云提供商根据需要进行管理、运行和水平扩展,使开发人员能够自由地专注于业务逻辑,而不是部署/管理应用层。

AWS Lambdas 可以在 cron 上或通过几个“触发器”(队列中的新消息、s3 中的对象创建、通过 API 网关的 http 请求等)来调用。),允许复杂的转换链和基于事件的管道。虽然使用 AWS 控制台来手动部署和管理 lambda 函数是完全可能的,但我们发现使用部署框架将使您的项目保持整洁、自包含和自动版本控制。

在这个项目中,所需的基础设施简单得令人尴尬(只有一个函数),它被捕获在serverless.yml文件中(env 变量有合理的默认值,但是可以随意使用您的名称/资源)。函数名为预测,函数定义在handler.py文件中;最后,“触发器”是一个 http GET 请求,因此对 /predict 路由的调用将被路由到我们的函数。如果您对命名约定、目的地的 AWS 区域和分段满意,我们离工作端点就差两个简单的命令了。首先,我们需要确保项目中的vendored文件夹(或者任何你想用的名字:确保文件夹在那里!)包含该项目的依赖项(在 included requirements.txt中列出);打开终端,将 cd 放入项目文件夹,然后键入:

pip install -t vendored/ -r requirements.txt

(请注意,在我们的例子中,依赖项是纯 Python,所以不需要担心 Linux 兼容的二进制文件;然而,作为使用 lambdas 时的一般最佳实践,您应该有一个合适的系统,比如这个系统,以确保您为 AWS 容器上传正确的依赖项!)

最后,(在安装了无服务器的情况下),只需在终端中键入:

serverless deploy

无服务器将我们的函数部署到我们选择的 AWS 数据中心,并且自动为我们设置 API 网关,这样一个新的公共 URL 将可用,并且该 URL 将把所有的 /predict 调用路由到该函数。完成后(由于需要创建所有资源,第一次部署会多花一点时间),您将得到类似如下的输出:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Serverless successful deployment output in the terminal.

为了确保一切按预期运行,打开浏览器并测试一个示例 GET 调用,例如:

https://YOUR-LAMDBA-URL/predict?features=-0.4629,4.496,6.59,2.0

其中YOUR-LAMBDA-URL是在上面的部署中创建的 URL。您应该会收到类似如下的响应:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Testing runtime prediction with a GET call directly from the browser.

恭喜你:你的大数据模型现在可以通过你的微服务获得了!通过交换模型文件(或者甚至用更多的处理程序/代码开关同时部署多个模型),您现在已经准备好使用这个模板并在不到一分钟的时间内部署任何决策树。

杂项注释和最终想法

“如果我们有数据,让我们看看数据。如果我们只有意见,那就用我的吧。”—吉姆·巴克斯代尔

像往常一样,我们设法保持教程的要点清晰简洁。我们忽略了一系列主题,因此下面是一个列表,按照笔记和临别感想的随机顺序,列出了我们在使用微服务服务大数据时所学到的内容。

  • 虽然“正式保证”Spark 序列化模型将被服务正确评估,但我们在谨慎方面犯了错误,并为主要功能添加了一些非常简单的单元测试:在 Tooso 时,我们通常利用 pytest 来完成这些任务,我们鼓励您也这样做!
  • 可能有人会说,整个语言映射的事情是太多了:给定 Spark 模型文件的特定结构(即多行、缩进格式),将一个 txt 文件逐行翻译成一个 py 文件比形式语义简单得多!这确实是真的,我们在 playground 文件夹中为喜欢这种实用解决方案的读者提供了一个 10 分钟的脚本:虽然比 repo 的其余部分测试得更少,但代码是不言自明的,可以很容易地改进成一个可靠的转换工具,以生成 py 文件来“嵌入”特定的 Spark 决策树。如上所述,DSL 方法更有趣,也更通用:如果 Spark 模型彻底改变了序列化格式,一种新的 lark 语法就足以让原则性方法适应。
  • 有人可能会说,整个语言映射的东西太少了:既然语言翻译如此有趣,为什么不加入一些机器学习呢?事实证明,深度学习最近通过 Seq2Seq models 等实现了一些令人印象深刻的翻译改进:一个想法可能是完全抛弃语义方法,用神经网络的方式来面对问题,即通过产生 Spark 模型和 Python 程序对,并训练 NN 来猜测映射函数。虽然这个看起来确实很有趣,但是我们想要一个更快的方法在两种格式之间转换;此外,在其他领域的类似尝试强调了一个不小的挑战:由于 Seq2Seq 人工语言输出有时几乎是正确的,我们如何说服我们的计算机运行看起来像 Python 但实际上不是 Python 的代码?
  • 当运行决策树时,我们很容易选择在内存中维护和遍历该树;虽然这对于我们的目的来说很方便,但它不是唯一的(甚至可能不是最好的)选项。即使不考虑编译解析树,一个简单的选择是将模型持久化到 py 文件中:我们可以将解析树转换成 Python 函数,并在端点被调用时加载/执行后者。现在,我们让读者去探索这种可能性和其他可能性!
  • 我们的 lark 语法读起来相当简单,但有些难看:我们喜欢设置 lark,但我们没有时间去超越对可用选项的直接掌握,所以我们只是直接寻找一些易于共享和使用的东西(例如,整个语法建立在instructionsfull_comparison之间的递归关系上,这样比较可能包含 if/else 块,其内容本身可能是 if/else 块)。这里有很大的改进空间:只要记住,通过改变语法,树遍历函数将需要相应地调整。
  • 对现有设置的一个简单扩展是使用 s3 作为共享卷来存储模型(和语法)。如果您的 Spark 管道将日常训练的模型序列化为例如my-s3-bucket/YYYYMMDD/model.txt,那么 lambda 可以通过使用 env 变量从my-s3-bucket中读取,以通过YYYYMMDD命名约定指定哪个模型是需要的。

作为最后的临别笔记,应该清楚的是,这些想法更多的是最终解决方案的草图,而不是准备投入生产的完整服务(在家里尝试一下,但可能还不是在办公室)。

撇开书呆子的兴趣不谈,这篇文章的总体理念是支持某种“数据科学家的自助式开发”:根据我们在 Tooso 和类似公司的经验,对于快节奏的分布式团队来说,创造/发明/破坏东西的人拥有快速、廉价(AWS lambda 对于前 100 万个请求 T10 是免费的)的低开销工具来自己构建复杂的数据管道是至关重要的,至少在开发阶段是如此。

但是,如果你非常喜欢这些想法,以至于想要将它们生产化,你至少应该考虑以下改进:进行一些一般的类重构以更好地抽象功能,压缩 lambda 部署中的文本文件,在类/端点级别引入适当的错误处理,考虑内存中与持久模型解释(如上所述),提高测试覆盖率,在查询时检查端点参数的一致性(例如,检查所提供的特性是否与训练好的决策树所期望的相匹配),等等。

编码快乐!

再见,太空牛仔

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果你想要一些其他的无服务器的灵感,查看一下我们关于如何建立一个网络分析平台的帖子或者我们关于服务 ML 模型的 T2 教程。

请在此分享您的反馈和意见,或在jacopo . taglia bue @ tooso . ai告诉我们您的大数据故事。

别忘了在 LinkedinTwitterInstagram 上获取来自 Tooso 的最新消息。

感谢

感谢 Tooso 联合创始人、来自 Makersight 的 Luca Bigon、Davide Romano 和 Matt McKinney 对这篇博文之前的草稿提出的有益评论:所有剩下的错误显然完全是我自己的。

从生物学到人工智能:感知机

原文:https://towardsdatascience.com/from-biology-to-ai-the-perceptron-81abfdc788bf?source=collection_archive---------20-----------------------

Python 中受生物启发的线性分类器

创造能像人类一样行动和推理的机器是一项长期的任务。虽然近年来人工智能(AI)和机器学习取得了很多进展,但一些基础工作在 60 多年前就已经奠定了。这些早期概念的灵感来自于生物神经网络(如人脑)的工作原理。1943 年,麦卡洛克和皮茨发表了一篇论文,描述了基于“全有或全无”活动特征的(人工)神经元在网络中的关系。这种“全有或全无”的特征是指生物神经元要么对刺激做出反应,要么保持沉默,没有中间状态。对这种行为的直接观察可以在人脑的微电极记录中看到。在这篇关于人工神经网络的初步论文之后,Frank Rosenblatt 于 1957 年发表了一篇题为“感知机——一种感知和识别自动机”的论文。感知器是一种受监督的线性分类器,它使用可调权重将输入向量分配给一个类别。与 1943 年麦卡洛克和皮茨的论文类似,感知机背后的想法是模拟生物神经元的计算来创造一个可以学习的代理。下面我们将看看感知器背后的思想,以及如何用 Python 代码实现它。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Hardware implementation of the Perceptron (Mark I)

这个想法

你的大脑包含数十亿个神经元,每个神经元都可以被视为一个处理单元,它整合输入并根据阈值标准创建二进制响应。在生物学术语中,输入是在神经元树突处的膜去极化,其向体细胞传播。如果去极化足够强,神经元将通过产生动作电位作出反应,动作电位将沿着轴突传播。在轴突末梢,神经递质将被释放到突触间隙中,这将使下游神经元的树突去极化。此过程的更详细描述可在这里找到。现在真正的线索是生物神经元网络可以学习如何对其输入做出反应。这种特性的术语是可塑性,正是这种特性使得静态软件和能够适应其环境的智能代理有所不同。然而,1943 年麦卡洛克和皮茨的论文并没有解决这个问题,而是关注神经元之间的关系。另一方面,感知器为可塑性问题提供了一个优雅的解决方案:权重。感知器的每个输入都乘以一个权重,然后将结果相加。因此,通过改变输入的权重,我们可以改变感知器的反应。下图给出了感知器如何工作的示意图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 1: Schematic outline of the Perceptron

在图 1 的左侧,输入表示为 x1、x2、x3…xn。每个输入乘以权重 w0,w1,w2,… wn。在这个乘法步骤之后,结果被累加并通过激活函数。在感知器的情况下,激活函数通过 亥维塞阶跃函数 类似于生物神经元的“全有或全无”特性。这意味着任何≤0 的值将被转换为 0,而任何值> 0 将变为 1。我们可以把上面的也写成:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其中 w 是权重向量, x 是输入向量, b 是偏差项。在图 1 中,我们已经将偏差作为 1(红色方块)包含在输入向量中,并作为 w0 包含在权重向量中。在这种情况下,我们只需要计算输入和权重向量的点积。但仍有一个问题:我们如何调整权重?毕竟这就是感知机的学习方式。思考这个问题的一种方式如下。我们的感知器应该根据输入做出二进制决定(0 或 1)。假设我们有两个数据点,一个属于类 1,另一个属于类 0,感知器必须学习每个数据点的类。下面的图 2 显示了该任务。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 2: Geometrical interpretation

从图 2 中我们可以看到,这个问题可以被视为寻找一个决策边界,也称为超平面(红色虚线),它将两个组分开。红色虚线以上的一切都是 0 类,超平面以下的一切都是 1 类。超平面由垂直于它的权重向量 w’定义(红色实线向量)。因此,计算输入向量与权重向量的点积并将结果传递给激活函数将给出输入的分类。因此,如果我们看看数据点 1,我们也可以将其绘制为一个向量,并垂直于它绘制另一个超平面(黄色实线)。接下来,查看输入向量 2,我们可以再次绘制一个垂直于它的超平面(蓝色实线)。由于分隔两组的超平面需要垂直于我们正在寻找的权重向量,从图 2 中可以明显看出,w’必须位于黄色和蓝色超平面之间(标记为“用于 x 的范围】)。因此,按照上述内容,我们可以实现如下学习规则。

首先,我们将权重向量中的所有值设置为零,包括偏差项。在二维输入的情况下,如图 2 所示,这意味着: w = [0 0 0]。然后,我们将偏差 1 添加到第一个输入向量,得到 X(1) = [1,x1,x2]。现在我们计算 X1 和 w 的点积。这个计算的结果是 0。通过激活函数传递 0 会将 X1 分类为 0 类,这是正确的。因此不需要更新 w 。对 X(2)做同样的事情也会得到类 0,这是错误的,因此我们需要通过以下学习规则更新 w :

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这种情况下,这意味着从正确的类(1)中减去我们的结果(类 0),将结果乘以当前输入向量,并将其添加到 w 。这将导致:w=【1 x1,x2】。如果有更多的数据点,我们将对每个输入向量继续这一过程,并且随着每次迭代,我们将更接近描述线性分离我们两组的超平面的权重向量。为了测试这一点,我们接下来将用 Python 代码实现感知器。

实施

为了开发我们的感知器算法,我们将使用通过 scikit-learn 生成的玩具数据。我们将使用 NumPy 实现所有其他功能。包含本文所有代码的完整 Jupyter 笔记本可以在这里找到。下面的代码将创建并可视化我们的玩具数据集。

# Import libraries 
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
import numpy as np# Generate dataset
X, Y = make_blobs(n_features=2, centers=2, n_samples=1000, random_state=18)# Visualize dataset
fig, ax = plt.subplots(1, 1, figsize=(5, 5))
ax.scatter(X[:, 0], X[:, 1], c=Y)
ax.set_title('ground truth', fontsize=20)
plt.show()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Figure 3: Data for testing the Perceptron algorithm.

图 3 显示了我们刚刚创建的两个集群,正如我们可以看到的,它们可以被一个超平面线性分离,这是感知器工作的先决条件。接下来,我们需要将偏置项添加到输入向量中,并用零初始化权重向量。

# Add a bias to the X1 vector
X_bias = np.ones([X.shape[0], 3])
X_bias[:, 1:3] = X# Initialize weight vector with zeros
w = np.zeros([3, 1])

好了,现在我们都准备好编码感知器算法了。从下面的代码中我们可以看到,这是一个非常简单和优雅的算法。因为不能保证感知器一遍就收敛,所以我们会在不断应用学习规则的同时,将所有训练数据连续 10 次馈入感知器,只是为了确保这一点。

# Define the activation function
def activation(x):
    return 1 if x >= 1 else 0# Apply Perceptron learning rule
for _ in range(10):
    for i in range(X_bias.shape[0]):
        y = activation(w.transpose().dot(X_bias[i, :])) # Update weights
        w = w + ((Y[i] - y) * X_bias[i, :]).reshape(w.shape[0], 1)

让我们来看看结果。下面的动画形象地展示了感知器是如何搜索一个分离两个聚类的超平面的。正如我们所看到的,它最终提出了一个解决方案,其中一个 1 类数据点位于超平面上。这个解决方案实际上是正确的,因为我们在前面的激活函数中指定:return 1 if x >= 1 else 0如果您感兴趣,您可以使用下面的激活函数重新运行上面的代码,看看结果如何变化:return 0 if x <= 0 else 1

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结论

最后,在我们结束对以上的一些思考之前。正如我们看到的,感知器算法是一种实现监督线性分类器的简单方法。然而,它也有缺点。例如,当组不是线性可分时,它不起作用。此外,它是一个在线算法,这意味着我们一次只能传递一个训练示例,如果我们有一个更大的数据集,训练过程会很慢。尽管有这些限制,感知器实际上是一个重要的概念,启动了第一次人工智能炒作。具有讽刺意味的是,几年后,当它无法实现关于它的重大承诺时,它也结束了它。

如果你想要这个项目的完整代码,你可以在这里找到它。当然,你也可以在 Twitter 上关注我,或者通过 LinkedIn 联系我。

[## 阿克卡斯滕/感知器

在 GitHub 上创建一个帐户,为 akcarsten/Perceptron 的开发做出贡献。

github.com](https://github.com/akcarsten/Perceptron/blob/master/perceptron.ipynb)

从脑电波到具有深度学习的机器人运动:导论。

原文:https://towardsdatascience.com/from-brain-waves-to-arm-movements-with-deep-learning-an-introduction-3c2a8b535ece?source=collection_archive---------5-----------------------

用神经网络可视化和解码大脑活动。

你可以在这个在线合作笔记本中找到这篇文章的所有代码,你可以直接在你的浏览器上运行它。这里是 GitHub 回购

在推特上关注我的工作更新和更多:【https://twitter.com/normandipalo

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

神经系统是一个极其复杂的结构。在你的全身,超过十万公里长的神经连接着你的脊髓和大脑。这个“网格”传输控制每个动作的电脉冲。每一个命令都来自你的大脑,一个更神奇的神经元结构,它通过电激活信号进行交流。理解和解释脑电模式是神经科学家和神经生物学家最大的梦想之一,但事实证明这是一项极具挑战性的任务。

一种记录大脑活动的非侵入性方法是脑电图(EEG) 。这是一种允许使用放置在患者头皮上的电极来记录脑电压波动的技术。通常,大约 30 个这样的电极被放置在头皮周围,允许记录脑电波的整体活动。总之,大脑活动和 EEG 信号之间的关系是复杂的,除了特定的实验室测试之外,对其了解甚少。因此,一个巨大的挑战是学习如何“解码”,从某种意义上说,这些脑电图扫描,可以允许控制机器人假肢和其他设备使用非侵入式脑机接口(BCI)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Example of brain waves recorded with EEG. CC BY-SA 2.0, https://commons.wikimedia.org/w/index.php?curid=845554

作为强数据驱动的学科,深度学习最近在相关模式识别任务中的突破,创造了一种使用神经网络分析这些电信号的新方法。在这篇文章中,我们将看到这个主题的介绍:我们将阅读由 Kaggle 竞赛提供的脑电图数据,该竞赛旨在检测哪些脑电图模式对应于特定的手臂和手势,如抓住或举起物体。在用不同的方式对数据进行预处理之后,我们将设计一个神经网络来执行这种分类。我也将展示一些大脑活动的数据可视化,以给出我们正在处理的数据的一个总体概念。该研究领域的最终目标是开发负担得起且有用的假肢装置,通过用大脑控制假肢,帮助截肢者重新获得轻松完成基本任务的能力。类似的技术也可以应用于读取肌肉电激活,从而通过分析激活的肌肉来解码一个人试图执行的运动类型。

你可以在这个在线合作笔记本中找到这篇文章的所有代码,你可以直接在你的浏览器上运行它。下面是 GitHub 回购

数据简介

如果你有一个 Kaggle 帐户你可以在这里免费下载数据。正如您将看到的,该数据仅由几个组成。csv 文件。这些文件分别是:

  • 用作模型输入的 EEG 数据,由放置在患者头皮上的 32 个电极记录。数据以 500 赫兹的频率记录。
  • 测试人员试图实现的运动的逐帧标签,在 6 个可能的标签中。

这些数据是通过记录不同人类测试者执行简单动作(如抓取和举起物体)时的脑电图来收集的。因此,数据集被分成不同的剧集,但也有不同的主题。我们将在稍后的准确度预测中看到,脑电波可能是非常个人化的,因为一个模型可以非常准确地预测同一个人在看不见的情节中的意图,但是如果训练不够多样,在对新测试人员做同样的事情时可能会有困难。

因此,目标是创建一个神经网络,该网络将 EEG 读数作为输入,并输出测试者试图实现的这 6 个可能动作的概率分布。由于“无动作”不是一个可能的类,我们可以将其添加为一个类,或者将所有可能的输出设置为 0 到 1 之间的值,并使用阈值来决定是否检测到该动作。如果每个动作都低于阈值,我们就认为它没有动作。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Position of electrodes, source: https://www.kaggle.com/c/grasp-and-lift-eeg-detection/data

我制作了这些电极活动的动画数据可视化。由于采样频率相当高(500 Hz),我使用了一个简单的 3 步低通滤波器来平滑数据,我用前 100 帧创建了一个动画,大约 1/5 秒。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Activations of the 32 electrodes in the first 1/5 of second.

我们还可以将时间数据可视化为 2D 热图,其中纵轴是时间(从顶部开始向下),横轴表示 32 个电极。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

EEG temporal heatmap. (time starts from top and goes down)

这也非常有用,因为正如我们将看到的,它将允许我们使用时空卷积

数据预处理

这些原始数据应该进行预处理,以适应学习阶段。例如,与所执行的动作的相对低的变化率相比,EEG 的非常高的采样频率会导致许多问题:数据变化非常快,但是动作实际上保持不变,因此波动几乎可以被认为是噪声。此外,时态模型会接收大量快速变化的数据,而分类输出从不改变。

第一个可能的步骤是用低通滤波器对数据进行滤波。即使简单的移动平均也是可行的:通过这种方式,我们减轻了数据的高频变化,同时保留了更有用的低频结构,因为我们将分类的运动具有非常低的变化频率(最多 1Hz)。之后,我们可以对数据进行二次采样,即我们可以每 10、100 等只保留一个数据点。这也有助于减少时间维度,降低数据的相关性,在某种意义上使其更加时间稀疏。

可以采用许多其他预处理技术,但是为了简单起见,我们可以在这里停下来,开始设计我们的神经网络。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

神经网络设计和实验

处理时态数据时,我们首先想到的架构之一是递归神经网络。这些网络具有动态结构,因此内部状态允许它们对时间数据进行编码,因此它们也基于过去的输入来计算输出。我在 Keras 设计了一个 LSTM 网络,用时序结构给它输入训练数据。结果很好,但在这个特殊的例子中,我更感兴趣的是展示一个常用于图像的卷积神经网络如何能够很好地处理时态数据。

如前所述,在某种意义上,我们实际上是在处理时空数据:上面显示的热图的垂直轴代表时间演变,而水平轴显示各种电极,并且接近的电极几乎总是在人类头皮上空间上接近。这意味着我们实际上可以用卷积提取有用特征:2D 核可以对时间和空间中的模式进行编码。想象一个 3x3 卷积核:它能够在热图中描绘的矩阵上,通过对三个不同的时间步长(3 个核行)以及三个不同的电极(3 个核列)进行加权求和来提取特征。因此,具有许多内核的 CNN 可以发现电极的激活如何在有限的时间周期内相对于期望的运动而变化的特征

我在 Keras 中实现了一个简单的 CNN 来检查它在这个数据集上的性能。你可以在这个在线合作笔记本中找到这篇文章的所有代码,你可以直接在你的浏览器上运行它。下面是 GitHub 回购

import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.layers import Embedding
from keras.layers import LSTM, CuDNNLSTM, BatchNormalization, Conv2D, Flatten, MaxPooling2D, Dropout
from keras.optimizers import Adammodel = Sequential()
#model.add(CuDNNLSTM(128, input_shape = (time_steps//subsample, 32)))
model.add(Conv2D(filters = 64, kernel_size = (7,7), padding = "same", activation = "relu", input_shape = (time_steps//subsample, 32, 1)))
model.add(BatchNormalization())
#model.add(MaxPooling2D(pool_size = (3,3)))
model.add(Conv2D(filters = 64, kernel_size = (5,5), padding = "same", activation = "relu", input_shape = (time_steps//subsample, 32, 1)))
model.add(BatchNormalization())
#model.add(MaxPooling2D(pool_size = (3,3)))
model.add(Conv2D(filters = 64, kernel_size = (3,3), padding = "same", activation = "relu", input_shape = (time_steps//subsample, 32, 1)))
model.add(BatchNormalization())
#model.add(MaxPooling2D(pool_size = (3,3)))
model.add(Flatten())
#model.add(Dropout(0.2))
model.add(Dense(32, activation = "relu"))
model.add(BatchNormalization())
# model.add(Dropout(0.2))
model.add(Dense(6, activation = "sigmoid"))adam = Adam(lr = 0.001)model.compile(optimizer = adam, loss = "categorical_crossentropy", metrics = ["accuracy"])model.summary()

为了检查我们模型的性能,正如 Kaggle 竞赛中所建议的,我们检查了 AUC 分数。如果你不熟悉 AUC 是什么,我建议这个清晰直观的解释。您可以在在线笔记本中自行查看,通过快速培训阶段,我们可以达到 0.85 左右的 AUC 分数。

通过训练不同的神经网络架构以及预处理技术等,可以实现许多改进,但这种概念的介绍性证明显示了神经网络从这种数据中学习的显著能力。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结论

在这篇文章中,我们介绍了脑电图的脑电信号,这是一种非侵入性和相对简单的记录用户头皮有用信号的方法。我们看到了一些数据的直观可视化,以及如何使用神经网络从中提取运动意图等特征。我相信,由于深度学习,更广泛的各种数据科学技术,平台和逐年增长的竞赛,这个领域(机器人假体,脑机接口)将有一个深刻的推动。

这些技术的影响将是巨大的。拥有可以以自然方式控制的低成本假体可以极大地改善数百万人的生活。

我建议你去看看symbion 项目,这是一个最近开始的项目,一些有才华的人试图拼凑一个低成本、智能手臂假体,可以通过肌肉激活来控制,以真正实现这种设备的大众化。

在推特上关注我的工作更新和更多:https://twitter.com/normandipalo

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从业务问题到数据科学任务

原文:https://towardsdatascience.com/from-business-question-to-data-science-task-55a49f471a0c?source=collection_archive---------15-----------------------

数据科学任务的六种类型

每一个分析的开始,都应该有一个问题。在商业世界中,这是一个典型的与商业运作、战略或产品相关的问题。作为一名数据科学家,我的工作是将问题转化为数据科学任务。听起来很简单,但确实至关重要,因为要解决的特定数据科学任务定义了可以从数据和分析中得出的结论。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我在数据分析&洞察部门工作,在我的 Meetup 简介中,我说*“我试图将数据转化为洞察”,在我的工作日,我经常大声说“我们需要创造(可操作的)洞察,并以数据为导向”——但这实际上意味着什么呢?这是我的数据哲学系列的第一部分,我试图剖析并理解“将数据转化为见解”*的实际含义。

数据科学任务的六种类型

Jeffery T. Leek 和 Roger D. Peng 在" 中定义的问题是什么? “六种日益复杂的数据科学任务:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这篇文章中,我省略了“机械的”数据科学任务,因为它在日常数据科学问题和任务中很少出现(至少在我的日常工作中我从未遇到过)。

描述性和探索性数据分析

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

What is the number of active users per month? Is there a seasonal trend in the number of active users?

第一个例题是描述性问题。目标是获得现有数据样本的摘要。第二个示例问题是探索性问题,任务是总结,但也是探索潜在的相关性和趋势。通常,它的目标是处理数据,形成新的想法和假设,这些想法和假设可能会导致新的数据收集和实验。描述性和探索性任务中使用的方法范围从五数字汇总到与探索性数据分析相关的更复杂的方法(由约翰·图基大力推广)。对于示例描述性问题,我们将计算每月活跃用户的平均数量
(可能已经有了置信区间);对于示例探索性问题,我们将从时间序列图开始。

推理数据分析

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Is the user activity really different between customers that bought the product in May vs. June?

在推理问题的情况下,任务是量化观察到的模式是否可能超出现有的数据样本。统计推断
包括,例如统计假设检验。对于上面的示例问题,我们可以使用零假设进行统计测试,假设两个月之间的活动相同,使用替代假设假设活动不同。假设零假设为真,测试计算结果的可能性。如果非常小(即 p 值小于
预定义的显著性水平),我们拒绝零假设,并认为存在显著差异

推断性数据分析是我们开始产生可操作见解的地方,因为我们确保结果在数据样本之外有效,并且结果不是偶然的。然而,重要的是要理解,显著的差异并不一定意味着与业务相关的差异。人们还应该调查影响的大小,看看这种差异是否真的对业务有明显的影响。这被称为实用或
临床意义
并且很可能是未来博客文章的一部分。

预测数据分析

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Which of our users are most likely to churn?

推理数据分析可在群体层面(例如,在您的所有客户中)产生可操作的见解。如果问题是为个人发现可操作的见解,那么任务就是预测性数据分析。在这样的任务中,给定一组其他特征(自变量),我们预测个体的一个特征(因变量)。要为示例预测性问题构建预测模型,我们需要一个数据样本,该数据样本具有描述客户是否流失(是/否)的目标特征“流失”,以及一组描述客户行为(产品活动、客户服务呼叫等)的描述性特征。).给定来自搅动用户和活跃用户的例子,我们可以任务建模为二元分类问题

一个成功的预测模型(通过定义的绩效衡量指标来衡量)会为特定的个人产生可操作的洞察力。因此,如果模型表明某个特定客户可能会流失,我们应该定义一个行动来防止流失。不幸的是,这个模型并没有告诉我们应该采取什么行动——最佳行动是你需要在实验中找到的。在这种情况下,通常不容易正式评估业务影响,整体成功是我们构建预测模型的好坏与触发行动的好坏的结合。如果我们还想估计最优行动,那么这个任务就叫做规定性分析,这也是未来博客文章的主题。

因果数据分析

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Why are our users churning?

因果推理是关于“为什么”这个问题的 —理解描述我们业务或特定业务流程的特征之间的因果关系。在因果数据分析中,我们希望找出如果一个特征被改变,另一个特征会发生什么:平均起来,特征之间的关系的方向和大小是什么。在我们的示例问题中,我们可以(应该)问一个更详细的问题,例如,“用户流失是因为我们展示了太多的广告吗?”。为了回答这样一个问题,我们可以利用我们已有的观察数据的统计模型,或者进行特定的随机实验并收集实验数据来明确回答这个问题。第二个选项是当您执行 A/B 测试时会发生什么。这也是我们可以做的来回答我们的示例问题:进行 A/B 测试,其中一组用户看到较少的广告,并监控两组用户之间的流失率。

随机数据分析是这篇博文中描述的五个数据分析中最困难的任务。然而,如果做得好,它会产生最清晰的可操作的洞察力,因为我们实际上了解我们特征之间的因果关系。显然,因果推理的背后有更多的东西,我计划在以后的博客中写更多。现在,永远不要忘记
cum hoc ergo proper hoc”:相关性并不意味着因果关系!

从买方角色到数据科学中的职业角色

原文:https://towardsdatascience.com/from-buyer-personas-to-career-personas-in-data-science-f677873f2e02?source=collection_archive---------9-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

image credit: BRIDGEi2i.com

场景 :班加罗尔一个新办公室里一个不太大的会议室。

时间戳 : 17 年前。

人物:一群背景和教育程度各异的年轻人:统计学家、计量经济学家、经理、顾问、投资银行家和信用评级师。

:作为第一批开始证明围绕“分析”的宣传是真实的公司之一,每个人都有在数据行业留下印记的远大梦想。

:梦想是伟大的,但对于这个新的、尚未定义的行业,什么构成了职业成长和职业道路?

听起来像一本新书的开场白?

当我们加入分析行业时,这是我们许多人的现实,当时用数据解决问题尚未开始其爆炸性的旅程。今天,随着越来越多的人接受数据科学的力量,年轻人蜂拥加入这一职业,这个问题仍然被提出。

如果我从事分析,我可以期待什么样的职业?

时髦的词语和天花乱坠的宣传给那些纠结于如何建立深度和广度的年轻人制造了更多的困惑;是选择早期专业化还是尝试直到他们找到自己的定位。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

image credit: BRIDGEi2i.com

嗯,我想通过这篇文章回答的是,在分析领域的职业生涯与你看待任何其他职业选择的方式没有任何不同。它始于吉姆·科林斯经典著作《从优秀到卓越》中讨论的基本原则(刺猬原则)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

image credit: BRIDGEi2i.com

上图中的交叉点就是你在职业生涯中想要达到的位置。

关于数据科学家的工作以及他或她需要具备的独角兽式技能组合,已经有很多文章。在我看来,并不是所有的数据科学专业人员都需要具备所有这些技能;事实上,他们不能。

然而,这个职业需要一套多学科的技能,最适合解决商业问题,而不仅仅是那些看起来像是彼此克隆的人。

作为分析专家,我们习惯于创建买家角色来更好地了解我们的客户,并细分适合他们的产品。让我们在这里应用同样的逻辑。

我将在分析领域创建四个职业角色——四个完全不同的人,他们拥有不同的技能,在行业中有着非常成功的职业生涯。就像电影里说的那样,与你的老板或前任老板的任何相似之处纯属巧合。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

image credit: BRIDGEi2i.com

四个角色。四种不同的选择。

你认为他们在开始职业生涯时知道自己最终会选择哪个方向吗?

大概不会。

他们是否拥有与独角兽数据科学家相同的技能?

肯定不是。

相反,他们所拥有的是:

  • 理解和解决问题的强烈好奇心
  • 愿意学习、忘却、再学习和帮助
  • 倾向于扮演重要的角色,而不是担心指定
  • 增加接触,发现自己的优势
  • 导师和更广泛的网络来探索新的机会

他们找到了自己的路。

正如我们为不同的买家角色设计不同的优惠一样,并非所有的分析工作都是一样的。这个行业有跨越多个角色的角色。那么,为什么我们只是试图创造克隆?是的,随着这个行业如此活跃,发展速度如此之快,我们将很快看到新的角色演变,从“商业模式破坏者”到“梦想设计师”,再到“全脑营销者”。

所以,祝你们所有在这个领域刚刚开始职业生涯的人,也祝那些目前正处于十字路口、决定角色的人一切顺利。

正如一幅著名的漫画所说:

你不能呆在森林的角落里等着别人来找你。有时候你必须去找他们。

——小熊维尼

在其中一个角色中认出你自己?让我知道这是否有助于你思考你的分析职业选择。我很想听听你的想法。

(本文最早出现在 BRIDGEi2i 博客 上,作者是 Prithvijit Roy,bridge i2i Analytics Solutions)**

如果你喜欢这篇文章,请给它一个掌声,并留下评论,以便它达到更多的专业人士和有志之士!

从经典的人工智能技术到深度强化学习

原文:https://towardsdatascience.com/from-classic-ai-techniques-to-deep-learning-753d20cf8578?source=collection_archive---------3-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

建造能够从例子、经验甚至从人类水平的另一台机器学习的机器是解决 AI 的主要目标。换句话说,这个目标就是创造一台通过图灵测试的机器:当一个人与它互动时,对于这个人来说,他不可能断定他是在与一个人互动还是与一台机器互动。

深度学习的基本算法是在 20 世纪中期开发的。自那以后,该领域作为随机运筹学和计算机科学的一个理论分支得到了发展,但没有任何突破性的应用。但是,在过去的 20 年里,大数据集、特别标记的数据和使用图形处理器单元的计算机能力的增强之间的协同作用,这些算法已经在更复杂的技术、技术和推理逻辑中得到发展,能够实现几个目标,如降低语音识别中的单词错误率;在一场图像识别比赛中降低错误率[Krizhevsky 等人 2012]并在围棋中击败一名人类冠军[Silver 等人 2016]。吴恩达将这一成功归因于深度神经网络正确学习复杂函数的能力,以及其与输入数据成比例增长的性能。

如今,每个人都可以使用机器学习来创建一些有趣的项目,例如,在石油和天然气行业:

[## 石油和天然气工程项目中的数据科学。

探索性数据分析

towardsdatascience.com](/datascience-in-oil-and-gas-engineering-projects-daace6e6c7f)

或者享受探索泰坦尼克号事故数据的乐趣:

[## 泰坦尼克号数据集的特征工程和算法精度

机器学习最流行的数据集之一对应于泰坦尼克号事故

towardsdatascience.com](/feature-engineering-and-algorithm-accuracy-for-the-titanic-dataset-5891cfa5a4ac)

*然而,深度学习是一种机器学习,它允许由多个处理层组成的计算模型学习具有多个抽象级别的数据表示。【le Cun et al 2015】*要理解这项技术,了解机器学习的主要技术很重要:

机器学习技术分为两种:监督学习,它训练一个模型,该模型以已知数据集(一个带标签的训练集)作为输入,并生成一个可以预测新数据未来输出的模型。无监督学习获取数据集(未标记)并在数据中寻找模式或内在结构,它通常作为聚类数据工作。一些最重要的机器学习技术在表 1 中进行了分类。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Table 1. Some machine learning techniques

如果您想更详细地了解这些技术,请查看下一篇文章,在这篇文章中,我用图形和简单的代码解释了它们:

[## 监督学习算法:解释和简单代码

监督学习算法采用一组已知的输入数据(学习集)和已知的数据响应(学习集)

towardsdatascience.com](/supervised-learning-algorithms-explanaition-and-simple-code-4fbd1276f8aa)

此外,强化学习问题涉及学习从经验中最大化数字奖励信号,也就是说,如何将步骤映射到行动(或创建策略)以最大化奖励效用。这种类型的机器学习不从标记数据的训练集中学习,它从与其环境的交互中学习。它尝试几种途径以最大化长期积累的报酬,也叫效用。强化学习的特点是:学习系统的行动影响其后来的输入,它没有直接的指示,如采取什么行动,以及行动的后果,包括奖励信号,发挥了长时间[萨顿和巴尔托 1998]。

利用高效算法进行无监督或有监督的知识发现 特征学习

深度学习是一种基于 20 世纪中期开发的一些基本算法的机器学习。其中大多数用于神经网络,下一节我们将展示一些最重要的机器学习算法。

机器学习中最强大的技术之一是神经网络,因为它可以在不同类型的机器学习的补充中实现,如接下来的会议所示。受人类大脑的启发,神经生理学家沃伦麦卡洛克和逻辑学家沃尔特皮茨提出了一种神经网络,它由高度连接的功能网络组成,这些功能网络映射了从输入到所需输出的路径。这是第一种数学方法。通过迭代修改连接的权重来训练网络。[M .沃伦,W .皮尔茨 1943 年]

神经网络具有从复杂或不精确的数据中获取意义的非凡能力,可用于提取模式和检测太复杂而无法被人类或其他计算机技术注意到的趋势。一个经过训练的神经网络可以被认为是它所分析的信息类别中的“专家”。然后,可以使用该专家对感兴趣的新情况进行预测,并回答假设问题。”【梅林等人,2002 年】

同样受到神经科学的启发,Rosenblatt[Rosenblatt et al f . 1958]开发了感知器,这是一种用于学习二进制分类器的算法,它将每个神经元的输出映射为 0 或 1;它采用输入向量 **x,**权重向量 w 并评估标量积是否超过阈值 u,即如果 wx-u>0 则为 f(x) = 1,否则为 0。在简单的层神经网络中,这种算法不是很有用,因为二进制分类是有限的。

另一方面,强化学习算法是从动态规划原理发展而来的。动态规划是一组可以解决所有类型的马尔可夫决策过程的算法。[贝尔曼 1957 年动态规划] MDP 是在随机情况下建模决策的数学模型。它们通常用图来表示,其中节点是状态,线是从一个状态到另一个状态的动作,从每个状态开始,每个动作都有一定的概率独立于过去的状态或动作而发生。每个新状态给出一个奖励(正面或负面)。解决 MDP 问题意味着建立一个使所有奖励总和最大化的政策。如果处于某一状态的概率不是 100%,问题就变成了部分可观测 MDP (POMDP)

贝尔曼首先提出了一个可以解决这个问题的方程。[1957 Bellman]这个递归公式提供了遵循期望最高回报的特定政策的效用。解这个方程意味着找到最优策略,这个问题很难解决,因为这个方程涉及一个最大化函数,它是不可求导的。这个问题使得强化学习领域没有任何相关的进展,直到 1989 年 Watkins 提出了 Q 学习算法[Watkins,1989。它通过计算状态对行为的量来解决问题。(莎莎)

最后利用时间差分(TD)学习算法保证解的收敛性。它是由 R. S. Sutton 在 1988 年提出。[Sutton et al 1988]自从他第一次使用它以来,它已经成为解决强化学习问题的参考。它确保大多数国家的参与,有助于解决伴随勘探-开采困境而来的挑战。

推理技术与深度学习的整合

当神经网络发展到不止一层时,深度学习就开始了。在几层神经元中工作只是走向深度学习和数据挖掘的第一步。在这一部分,我们将揭示第一部分的技术是如何集成到多层神经网络中的,它们共同开发了深度学习的基础。

最初,感知器被认为是解决一层神经网络,它作为一个一维分类器。这种技术在例如语音或图像分类中不是很有用,因为该技术必须对输入的不相关变化不敏感,例如照片的方向、照明、缩放,但是它们应该对区分图像和另一个图像(例如狼和狗)的细节敏感。

当多层感知器(MLP)在 1986 年由 Rumelhart 用一种称为梯度下降反向传播技术开发出来时,感知器开始只在多层网络中有用。反向传播是算法的集合,旨在分配正确的权重,使神经网络在学习中具有较低的误差。反向传播中最重要的方法之一是随机梯度下降(SGD),这是一种算法,旨在使用微积分概念作为偏导数的链规则来最小化错误率[Rumelhart 等人,1986]。在该技术中,目标相对于神经元的输入的导数可以通过相对于该神经元的输出(即下一个神经元的输入)反向计算来计算。该技术传播所有导数或梯度,从顶部输出开始,一直到底部,然后直接计算每个链接的相应权重。

自 MLP 和 SGD 以来,在解决神经网络方面没有太多的进展,直到 1997 年提出了另一种称为长短期记忆 LSTM 的反向传播方法[Hochreiter et al 1997],它缩短了正常的梯度下降法,并引入了递归网络的概念来学习长范围的依赖性。它倾斜得更快,解决了以前从未解决过的复杂的人工长时间滞后的任务。

在深度学习论文中,LeCun 解释了其对深度学习形成的重要性:“长期短期记忆(LSTM)网络使用特殊的隐藏单元,其自然行为是长时间记忆输入。一个称为存储单元的特殊单元的作用就像一个累加器或门控漏神经元:它在下一个时间步长与自己有一个权重为 1 的连接,因此它复制自己的实值状态并累积外部信号,但这种自我连接受到另一个单元的乘法门控,该单元学会决定何时清除存储器的内容【LeCun 等,Nature 2015】,

LSTM 网络可以训练某种类型的网络,称为递归神经网络(RNN),可以为涉及顺序输入的任务进行训练,如语音和语言[Graves et al 2013]。RNN 在明年非常有用,但它没有解决深度学习的问题。

科学家还开发了另一种更容易训练的网络,这意味着它需要更少的例子来获得神经元之间连接的正确权重,并且它还可以进行更好的分类。这种网络被称为卷积神经网络(CNN ),其特征在于相邻层之间具有完全连通性。它首先出现在[Lecun et al 1989]中,应用于手写邮政编码识别。作者解释了 CNN 中的卷积层和池层是如何直接受到视觉神经科学中细胞的经典概念的启发。CNN 是发展计算机视觉的第一步。

结合神经网络和强化学习的系统是深度强化学习(DRL)的基础。在这种情况下,处于状态的代理使用深度神经网络来学习策略;根据这个策略,代理在环境中采取行动,并从特定的状态中获得奖励。奖励供给神经网络,它产生一个更好的政策。这是在一篇著名的论文《用深度强化学习玩雅达利》(playing Atari with deep reinforcement learning)[Mnih,V. et al 2013]中开发和应用的,在这篇论文中,他们学习一台机器直接从像素开始玩雅达利游戏,经过训练,这台机器输出了优秀的结果。

后来,AlhpaGo 团队开发了一个深度强化学习系统,使用了本次会议中引用的所有技术(LSTM,美国有线电视新闻网,RNN),创建了一个能够学习玩围棋的人工智能系统,被训练观察专家,被训练与自己对弈,并最终击败世界冠军 Lee Sedol。这是人工智能的一个突破,因为由于游戏的复杂性,科学家认为让一台机器赢得这场游戏需要更多年的时间。[西尔弗等人,2016 年]

感谢阅读!!!

如果你想继续阅读这样的故事,你可以在这里订阅!

我喜欢与贝叶斯网络一起工作:它们允许人类学习和机器学习协同工作,即贝叶斯网络可以从人类和人工智能的组合中开发出来。除了跨越理论和数据之间的界限,查看下一个帖子来了解更多信息:

[## 贝叶斯思维导论:从贝叶斯定理到贝叶斯网络

假设世界上存在一种非常罕见的疾病。你患这种疾病的几率只有千分之一。你想要…

towardsdatascience.com](/will-you-become-a-zombie-if-a-99-accuracy-test-result-positive-3da371f5134)

参考书目

1。贝尔曼河(1957 年)。一个马尔可夫决策过程(编号 P-1066)。兰德公司圣莫尼卡加州。

2。贝尔曼(1957 年)。动态编程。新泽西州普林斯顿:普林斯顿大学出版社。

3。Bottou,L. (2014 年)。从机器学习到机器推理。机器学习,94 (2),133–149 页。

4。Ciresan 博士,Meier,u .,& Schmidhuber,J. (2012 年)。用于图像分类的多列深度神经网络。计算机视觉和模式识别(CVPR)(第 3642-3649 页)。

5。F. Vernadat,企业现代化技术:业务流程的应用,收款管理,经济学,1999 年

6。GONZALES N .:对“项目成熟度评估流程的实施:在汽车上的应用”的贡献,博士论文,2009 年 12 月 3 日

7。Graves,a .,Mohamed,A.-r .,& Hinton,G. (2013 年)。基于深度递归神经网络的语音识别。声学、语音和信号处理(icassp),2013 年 ieee 国际会议。

8。赫布,国防部长(1949 年)。行为的组织。威利。

9。辛顿,G. E .,达扬,p .,弗雷,B. J .,&尼尔,R. M. (1995 年)。无监督神经网络的唤醒-睡眠算法。科学,268 (5214),1158–61。

10。Juang,B. H .,& Rabiner,L. R. (1990 年)。语音识别的隐马尔可夫模型。技术计量,33 (3),251–272。

11。Krizhevsky,a .,Sutskever,I .,& Hinton,G. E. (2012 年)。基于深度卷积神经网络的图像网分类。神经信息处理系统进展 25(第 1097-1105 页)。

12。LeCun,y . beng io,& Hinton,G. (2015)。深度学习。自然,521,436–444。

13。LeCun,y .,Boser,b .,Denker,J. S .,Henderson,d .,Howard,R. E .,Hubbard,w .,& Jackel,L. D. (1989)。反向传播算法在手写邮政编码识别中的应用。神经计算,1,541–551。

14。勒昆,y .,博图,l .,本吉奥,y .,& H

国家能源研究所,P. (1998 年)。基于梯度的学习在文档识别中的应用。IEEE 会议录,86 (11),2278–2323

15。利特曼博士(1994 年)。马尔可夫博弈作为多主体强化学习的框架。《第十一届机器学习国际会议论文集》(第 157 卷,第 157–163 页)。

16。麦卡洛克,沃伦;沃尔特·皮茨(1943)。“神经活动中固有的思想逻辑演算”。数学生物物理学通报。5 (4): 115–133.

17。麦卡洛克,沃伦;沃尔特·皮茨(1943)。“神经活动中固有的思想逻辑演算”。数学生物物理学通报。5 (4): 115–133.

18。非线性动力系统的建模、模拟和控制。泰勒和弗朗西斯,伦敦(2002 年)

19。Mnih,v .,Kavukcuoglu,k .,Silver,d .,Graves,a .,Antonoglou,I .,Wierstra,d .,& Riedmiller,M. (2013 年)。用深度强化学习玩雅达利。arXiv 预印本 arXiv:1312.5602。

20。罗森布拉特,F. (1958)。感知器:大脑中信息存储和组织的概率模型。心理评论,65,386–408 页。

21。鲁梅尔哈特,丁顿,g .&。通过反向传播误差学习表征。自然,323 (9),533{536。

22。S. Hochreiter 和 J. Schmidhuber。长短期记忆。神经计算,9(8):1735–1780,1997。

23。西尔弗,d .,黄,a,,C. J .,盖兹,a .,西弗尔,l .,德里斯切,G. V. D .。。哈萨比斯博士(2016)。用深度神经网络和树搜索掌握围棋。自然,529 (7585),484–489。

24。萨顿,R. S. (1988)。学会用时差法预测。马赫。学习。, 39.

25。萨顿,R. S .,&巴尔托,A. G. (1998)。强化学习:导论(第 1 卷第 1 号)。剑桥:麻省理工学院出版社。

26。沃特金斯,c . j . c . h .(1989),从延迟奖励中学习。博士论文,剑桥大学。

从数据分析师到数据科学家

原文:https://towardsdatascience.com/from-data-analyst-to-data-scientist-f67a724ea265?source=collection_archive---------3-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Source: Matterport mask RCNN

一个人如何从数据分析师转型为数据科学家?

  1. LinkedIn 网站。登录。
  2. 点击“编辑我的个人资料”。
  3. 找到“数据分析师”这几个字,换成“数据科学家”。

搞定了。哇,那很容易。

不幸的是,生活没那么简单。在这里,我们承认,要从或多或少的数据中发掘洞察力,需要付出艰苦的努力。

有很多关于从数据科学起步的好文章(例如这里的和这里的),但是关于从数据分析师转型的文章却很少。

在开始之前,我有必要尝试一下这两个角色的定义。

数据分析师收集、处理结构化数据并应用统计算法,以获得收益并改进决策。

一个数据科学家有类似的目标,但也有强大的处理大量非结构化数据的技能,可能接近实时处理。他们发现重要的信息,并能够对来自各种来源的数据进行清理、处理和运行高级算法。他们有很强的讲故事和想象技巧。

我经常遇到有才华的分析师,他们渴望开始他们的数据科学之旅,却因缺乏机会和不确定从哪里开始而沮丧。这促使我写了这篇文章。

为什么要成为数据科学家?

呃,事实上有很多原因…

影响 —产生巨大商业利益的潜力。一个被高层倾听并帮助塑造未来方向的机会。

精通— 在一个快速发展的领域中,有无数迷人的问题需要通过各种方法来解决。例如,建立一个图像识别器或文本分类器来识别社交媒体上的有毒评论。

相关性——有人预测人工智能最终会取代我们的工作。一种安全的方法是让 it 部门创造自动化,而不是等待自己被自动化。

报酬/机会— 乘坐大游艇四处旅行,在按摩浴缸里喝香槟。也许不会,但是薪水会相对较高。好的数据科学家很少,需求量很大;让那成为你,生活应该是美好的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Data science — loads to learn (left) , robots taking our jobs (middle) and good pay but remember that The Wolf a Wall Street ended in tears! (right)

我已经是数据科学家了吗?

大多数分析师都有良好的基础,但需要多年的努力来发展技能,以便在复杂的结构和/或大型数据集上全面应用尖端方法。也就是说,不需要很长时间就可以开始取得成功,甚至达到超出我们早期预期的水平。

那么,我们在朝着什么技能努力呢?这个问题可能没有正确的答案,但是一个复杂的数据科学项目可能有一个包含许多元素的复杂管道。在数据科学发展的最初几年,人们可能会期望至少触及以下合理的部分:

数据科学语言 — Python/R

关系数据库 — MySQL、Postgress

非关系数据库 — MongoDB

机器学习模型 —例如,回归、提升树 SVM、NNs

图形 — Neo4J,GraphX

分布式计算 — Hadoop、Spark

— GCP/AWS/Azure

API 交互 — OAuth,Rest

数据可视化和 Webapps — D3,RShiny

专业领域— 自然语言处理、光学字符识别和计算机视觉

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Boosted Trees models are popular in data science competitions

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

RShiny dashboards can be an effective way to develop an interactive means for others to explore data.

获得这些技能需要很多时间(可能比你的学位课程还要长)。即使是世界上最优秀的人也还有很多东西要学。然而,我们总是可以知道更多,不应该担心我们有局限性。如果我们每天都能变得更好一点,我们都有潜力在某一天达到相当高的技能水平。

决心和坚韧会比我们原始的智力更好地为我们服务。

行动(或活动、袭击)计划

在做其他事情之前,我们需要一些基本技能:

  1. 从正确的哲学开始。十年前,等待数周时间被送去上数据软件课程可能是可以接受的。那些日子早已过去。到处都有奇妙的材料。让学习持续不断。不断练习技能。
  2. 学习一门语言,发展你的数学技能——Python 和/或 R 是大多数人的起点。在像 CourseraUdemy 这样的网站上有大量的免费培训。许多 Python 用户喜欢使用 AnacondaJupyter 笔记本。很多 R 用户喜欢 R Studio 。在数字方面,吴恩达机器学习课程斯坦福神经网络课程都非常棒,学习起来非常愉快。
  3. 解决问题——最好是你工作场所的真实问题,与商业专家和数据工程师一起工作。这是最好的端到端开发形式。
  4. 进入ka ggle竞赛 — Kaggle 任务被划分范围和清理,但是没有比和其他几千人一起做一个具有挑战性的问题更好的方法来提高建模技能了。不要担心等级。从操场比赛开始,然后从那里开始。每个人都有起点,试一试吧。
  5. 了解该领域的领导者在说什么 —有些人喜欢称之为“数据科学的摇滚明星”。这个小组做出了令人着迷的贡献,非常值得你花时间去做。留意像杰弗里·辛顿、吴恩达、扬·勒昆、雷切尔·托马斯和杰瑞米·霍华德这样的人。
  6. 使用有效的工作方式——一旦奠定了基础,就开始使用版本控制系统来改进你的工作流程,例如 GitHub 来部署和维护代码。考虑集装箱化的码头工人
  7. 有效沟通——我们需要能够推销我们的作品。高管们喜欢闪亮的演示,所以一定要朝着你能在关键演示上展示的东西努力。

Lots of great materials on youtube. Andrew Ng’s state of artificial intelligence is fascinating.

Twitter can be another useful medium. Learn from the best such as Rachel Thomas.

获得正确的设置

即使拥有世界上所有的技能,如果你的组织没有合适的工具和环境,那么等待你的将是一场艰苦的斗争。很可能总是有我们无法控制的因素,所以我们需要考虑我们能够影响什么。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 迁移到正确的团队 —最简单的计划。大多数大中型组织都至少有一个小型数据科学团队。加入它。
  2. 与合适的人合作 —如果不可能快速跳槽,那么就创造一个机会,与你认识的知识最渊博的数据科学家一起工作。例如,发现一个可以自动化的问题,然后与专家合作,而不是委托他们去做。
  3. 支持合适的工具和环境—组织并不总是确定是否以及如何投资数据科学工具。他们需要担心传统分析交付的繁忙计划。安全和审计都需要时间来发展,所以他们只会听到有明显好处的强有力的业务案例。抓住机会支持适当的环境、工具和培训。
  4. 开发清晰的用例 —了解您的业务以及如何应用数据科学。用一个小的概念证明将两者联系起来。利用成功来支持获得更多工具和环境的案例。
  5. 与懂得比你多的有才能的人一起工作— 成为拥有你不具备的技能的高技能多元化团队的一员。你不仅会获得更多,还会潜移默化地学到他们的一些知识。

结论

现在是开始行动的最佳时机。今天就开始学习,尽快着手解决一个真正的问题。将没有回头路。坚持不懈,用你的成就给自己惊喜。珍惜这个机会。

从特征分解到行列式:带有直观例子的机器学习基础数学第 3/3 部分

原文:https://towardsdatascience.com/from-eigendecomposition-to-determinant-fundamental-mathematics-for-machine-learning-with-1b6b449a82c6?source=collection_archive---------13-----------------------

为了理解机器学习算法的数学,特别是深度学习算法,从基础到更高级建立数学概念是必不可少的。不幸的是,数学理论在许多情况下太难/抽象/枯燥,难以消化。想象你正在吃一个比萨饼,喝一杯可乐总是更容易和更有趣。

这篇文章的目的是为基础数学理论提供直观的例子使学习体验更加愉快和难忘,那就是鸡翅配啤酒,薯条配番茄酱,里脊配葡萄酒。

包含 3 门课程的机器学习基础数学课程组织如下:

从标量到张量:带有直观例子的机器学习基础数学第 1/3 部分

  • 什么是标量、向量、矩阵和张量?
  • 标量、向量和矩阵之间的加法
  • 标量、向量和矩阵之间的乘法
  • 单位矩阵和逆矩阵
  • 对角矩阵和对称矩阵

从范数到正交:机器学习的基础数学与直观示例第 2/3 部分

  • 向量的 1-范数,2-范数,最大范数
  • 正交和标准正交向量
  • 正交矩阵

从特征分解到行列式:带有直观例子的机器学习基础数学第 3/3 部分

  • 矩阵的特征分解:特征值和特征向量
  • 跟踪运算符
  • 方阵的行列式

在本文中,我们将通过直观的例子,从特征分解到行列式来浏览第 3/3 部分**。**

矩阵的特征分解:特征值和特征向量

为什么我们需要分解?如果我们想发现事物的本质,分解是一种有效而实用的方法。假设你刚交了一个新朋友,把他/她分解成以下四个组成部分,可以帮助你迅速对具体的人建立更深入的了解。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

同样的数学方法。一个整数可以分解成质因数,比如 20 = 2 * 2 * 5,也就是说 20 不能被 3 整除,20 的任何整数倍都会被 5 整除。

特征分解是一种将矩阵分解成一组特征向量和特征值的方法。非零向量 v 是方阵 A 的特征向量,如果它满足特征值方程:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其中 λ 是一个标量,称为向量 v 对应的特征值。

矩阵 A 的特征分解由下式给出

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其中 V 为方阵,其第 I 列为矩阵 A 的第 I 个特征向量,diag(λ)为对角元素为对应特征值的对角矩阵。

例如,一个真实的矩阵:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

可以通过非奇异矩阵 V 的乘法分解成对角矩阵:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上述两个向量方程可以由单个向量方程表示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

通过将 λv 移至左侧,我们可以得到

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

其中向量 V 非零,因为矩阵 V 是非奇异的。因此,

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

根据行列式矩阵的定义,我们可以有:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

将解放回到上面的向量方程中:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

解方程,我们有

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

因此矩阵进行本征分解所需的矩阵为:**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

举个例子,

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

跟踪运算符

线性代数中,方阵的迹被定义为主对角线上元素的和:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比如有一个 33 的矩阵 一个*

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传****外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

trace 运算符的一些基本属性如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

更一般地,轨迹对于将最后一个因子移动到第一个位置是不变的,这被称为循环置换,即,

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

方阵的行列式

什么是行列式?为什么我们需要了解如何计算矩阵的行列式?行列式的值在机器学习中有什么意义?

表示为 det( A )的方阵的行列式是可以从矩阵的元素中计算出来的值。对于一个 2*2 矩阵,它的行列式是:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于 3*3 矩阵,行列式定义为

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在 4*4 矩阵的情况下,行列式为

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo credit to Wikipedia

行列式等于一个矩阵的所有特征值的乘积,我们可以用行列式把一个矩阵映射成一个实标量。您可以使用 numpy.linalg.det 来计算数组的行列式。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

scipy

行列式是机器学习算法中一个重要的数学概念,例如广泛使用的降维解决方案:主成分分析(PCA)。正如我们所知,一个矩阵可以被视为空间的线性变换,其行列式的值可以被认为是用这个矩阵变换空间时得到的乘法变化**,可以是旋转、缩放或方向变化等。**

恭喜你!您已经完成了第三部分,也是最后一部分机器学习的基础数学和直观示例**。**

“哪里有数字,哪里就有美。”—普罗克洛斯

基础数学理论的美妙之处在于它们永远不会过时。十年后的 2028 年,软件开发人员和数据科学家可能不会再使用 Python 或 TensorFlow 了。但标量还是标量,矩阵还是矩阵,张量还是张量。矩阵求逆的充分必要条件和现在一样。基础数学能够经受时间的考验。你可以在这个系列中投资一周或一个月。幸运的是,收获是你可以终身应用的知识和技能,因为“数学是一种思维方式。”

报名参加🦞:的 Udemy 课程

具有机器学习和统计的推荐系统

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

https://www.udemy.com/course/recommender-system-with-machine-learning-and-statistics/?referralCode=178D030EF728F966D62D

从探索到生产——弥合深度学习的部署差距(第 1 部分)

原文:https://towardsdatascience.com/from-exploration-to-production-bridging-the-deployment-gap-for-deep-learning-8b59a5e1c819?source=collection_archive---------7-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这是关于深度学习模型探索、翻译和部署的两个博客系列的第一部分。两者都涉及许多技术,如 PyTorch、TensorFlow、TensorFlow Serving、Docker、ONNX、NNEF、GraphPipe 和 Flask。我们将协调这些技术,使用更具挑战性但不太受欢迎的 EMNIST 数据集来解决图像分类的任务。第一部分介绍 EMNIST,我们用 PyTorch 开发和训练模型,用开放的神经网络交换格式 ONNX 翻译它们,并通过 GraphPipe 服务它们。第二部分介绍 TensorFlow 服务和 Docker,以及一种相当业余的方法,在这种方法中,我们构建了一个服务于我们模型的简单 web 应用程序。你可以在 GitHub 上找到所有相关的源代码。在这里你可以找到第二部分。

弥合差距,迈向人工智能驱动的社会

吴恩达是人工智能摇滚明星。作为斯坦福大学的教授,Coursera 和 deeplearning.ai 的联合创始人,他极大地推动了人工智能教育和应用。他可以被认为是这个领域学生最多的老师,这为他赢得了很大的权威。由此,他创造了人工智能这个术语,称之为点燃新工业革命的新电力。但是,与这种说法的轻松形成对比的是,将电力从实验室输送到数百万家庭和工厂需要付出巨大的努力。它需要人力、大量投资和切实可行的解决方案来将其从理论付诸实践,并使之成为大众的一件理所当然的事情。吴恩达也知道这件事。

回到艾的类比,情况是相似的。在人工智能方面有无数的研究,在医疗保健、交通运输或商业方面也有越来越多的实际应用——仅举几例。然而,大多数人仍然远远没有积极地将人工智能视为日常生活的一部分。可能有政治、社会或文化因素减缓适应。公平地说,当我们谈论人工智能时,我们也需要更精确地了解我们的意思。狭义人工智能和广义人工智能之间的区别表明,我们还没有越过许多人实际谈论人工智能时所指的那一点。

不管怎样,为了解决缺乏大众参与和理解的问题,我们需要 让人工智能更容易接近。在他在 2017 年人工智能前沿会议上的演讲中,吴恩达分享了他对人工智能社会的愿景,以及为人们提供所有工具来实现这一愿景的必要性。在我看来,这与更好地弥合勘探和生产之间的差距是齐头并进的。我指的是从概念和开发阶段到部署的机器学习模型的步骤。模型部署赋予模型生命,使它们对大众来说是可访问的,并允许我们看到它们的真实性能。按照吴恩达的类比,我们可以将人工智能的探索-翻译-部署与电力的产生-运输-消耗进行比较。为了让人们能够做到这一点并弥合差距,我决定写一篇博客,整合从探索到部署神经网络模型的不同技术。

使用 PyTorch 的 EMNIST 图像分类模型,使用 ONNX 的翻译,使用 GraphPipe 的部署

在这个从探索到生产的教程中,我们将使用神经网络解决一个监督学习任务,并通过 web 服务提供预测。我们将其分为以下 4 个步骤:

  • 数据探索
  • 模型开发
  • 模型翻译
  • 模型部署

从探索阶段开始,我将首先介绍 EMNIST 数据集并概述其特征。其次,我们继续构建和探索神经网络,通过为图像分配正确的数字和字符标签来学习输入和输出之间的正确映射。几次迭代将很快为我们提供令人满意的精度水平。请注意:我不会在这里详细讨论数据科学主题,因为这不是这篇博客的重点,所以数据和模型探索将是相当肤浅的,进一步的模型调整留给你。在第三步中,是时候离开实验室卷起袖子了:我们将模型转换成独立于框架的表示。在最后一部分,我们导入这个表示,将它转换成一个可部署的模型,并配置推理接口,使它对用户可用。

数据探索:EMNIST 数据集

手写数字的 MNIST 数据集是数据科学事实上的 Hello World (在 Iris flower 数据和 Boston pricing 之间)。 EMNIST 由美国国家标准与技术研究所(NIST)提供。它通过手写字符(大写和小写)的图像来扩展数字。28x28 像素和单一颜色通道(灰度)的图像具有与 MNIST 相同的格式。整个数据集包含来自 62 个类别(10 个数字、26 个小写字符和 26 个大写字符)的 814,255 个图像。对于那些对更多细节感兴趣的人,可以看看 2017 年相应的论文。由于其易于访问、有限的大小和易于掌握的结构,MNIST 已经成为各种深度学习教程的真正普及点。然而,在我看来,它也被过度使用了。因此,我决定对这篇博文的实用部分更进一步,它离现有内容不太远,但足以增加一些多样性。

NIST 以两种不同的格式提供 EMNIST 数据集:二进制和 Matlab。我决定继续使用 Matlab 格式,如果你喜欢走同样的路,欢迎你使用合适的装载机。读取图像和标签为我们提供了 697 932 个训练和 116 323 个测试示例,这几乎是我们在这里保留的 6:1 训练-测试分割。下面,您可以从数据集中看到一些示例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

EMNIST 带来的一个问题是高度不平衡的阶级分布。所有这 10 个数字构成了训练和测试数据集中大约一半的实例。在信件内部,也有两方面的巨大不平衡。首先,跨越大写和小写字母。这尤其适用于英语中一些最常用的字母,如 esto 。第二,在大写字母和小写字母之间有很大的不平衡,这反映了语言中不同的使用频率。然而,还有一个好的方面:字母份额在整个训练和测试数据分布中几乎保持不变。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这种不平衡的数据会妨碍分类模型正确地学习正确的模式-标签匹配。有很多方法可以预测这一点,各有利弊。我们可以对类进行缩减采样以实现均匀分布。我们可以通过复制代表性不足的类实例或创建合成样本来增加数据的采样。但是,我们也可以调整稍后的训练损失计算,使得未被充分代表的类获得更高的权重,以便分类错误同等地影响损失,而不管它们的潜在频率。但是,按照我的说法,这不应该是我们关心的问题。

模型探索:使用 PyTorch 开发神经网络模型

根据我们对数据的第一印象,我们可以开始探索有用的模型。这通常是一个迭代过程,包括建立一个模型,训练它,并评估它在我们的测试数据上的性能,以估计它的泛化能力。然后,我们选择最好的一个(或多个)并将其投入生产。

关于我们如何在数据科学中失败的简短说明

这个过程也包括很多失败,如果你失败得快,学得也快,这绝对没问题。因此,我一般区分三种失败:

  • 技术的
  • 数学的
  • 性能方面

技术失败是由于 API 的不正确使用导致了不可编译的模型或运行时错误。例如,在神经网络中实现一个完全连接的层,我们必须定义该层的权重矩阵期望的单元数和输出单元数。如果我们现在将该层堆叠在不满足定义的维度的输入层之上,则模型定义过程或实例化将导致错误。这种类型的问题通常很简单,或多或少容易检测和纠正。它专注于我们脑海中的模型的现有概念的实现。

数学识别和修复失败会变得更加复杂。由于高偏差和/或高方差而表现出一般预测质量的模型大多属于这一类。这意味着一个模型被正确地定义并成功地在训练数据上运行——从技术的角度来看——但会导致不合逻辑或完全糟糕的结果,因为该模型没有学习到从输入到输出数据的适当映射。我们可以将这些问题归因于不利的超参数或不适当的模型架构。例如,我们可以选择一个过高的学习率,并看到我们的损失函数大幅振荡,而不是收敛。这类问题通常涉及更深入的原因分析,有时需要大量的反复试验。他们的解决方案从经验、领域知识和对理论基础的扎实理解中受益匪浅。

性能方面的失败是达不到我们期望的车型的特征。这些期望可以是面向质量或效率的,并且与分类准确度、假阳性的可容忍量有关,但是也与训练持续时间、模型复杂性或关于后来的可扩展性的推断时间有关。在这个失败的最高阶段,我们看到的模型在技术上是正确的,并成功地从我们的数据中学习。但是我们仍然对他们学习的内容和方式不满意。例如,我们可以在图像上训练浅层神经网络来正确地对它们进行分类,并且我们的模型以 60%的分类精度收敛。因此,我们可能对其结果不满意,并可能增加模型的复杂性以提高准确性。

选择正确的深度学习框架

正如我们所看到的,一个模型需要通过不同的质量关。一般来说,需要多次迭代来驱动我们的方法通过它们。特别是对于初学者,我因此建议使用支持快速失败和学习的框架,以及促进我们理解为什么失败。当我开始构建我的第一个神经网络时,TensorFlow 的版本是 1.0。现在我们正在接近 2.0 版本。它是最广泛采用的深度学习框架,具有强大的社区,并由 Google 支持。我已经习惯了用它来解决问题的有时相当不自然的方式。与之相反的是,PyTorch 已经成为一个强大的竞争对手,得到了社区和脸书的大力支持。TensorFlow 是一个成熟的框架,具有一些有用的功能,如用于可视化的 TensorBoard 和用于模型部署和生产的 TensorFlow,但它也有一点静态图形范例的缺点,这会减慢失败和学习的速度。在这里,PyTorch 更好地集成了 Python 数据科学生态系统,而是使用了一种动态图形范式,让您可以轻松快速地探索变量并对故障做出响应。然而,它缺少一些功能和成熟性,而且人们还必须提到,TensorFlow 正以其急切的执行模式预测动态图,该模式宣布将成为“2.0 的核心功能”。我把这篇博客作为一个机会来更加熟悉 PyTorch,特别是探索我们如何从不同的世界中获得最大的收益。为此,我将把重点放在 TensorFlow 和 PyTorch 这两个最重要的框架上,并避免比较其他框架,如 CNTK 或 Caffee。

PyTorch 中的神经网络建模

回到 EMNIST 和我们的数字和字母分类问题:
在本节中,我们构建了两个不同的模型,并在 EMNIST 训练数据集上对它们进行训练。首先,一个简单的线性模型将输入与输出单元完全连接起来,并对输出单元应用 softmax 函数来预测与最高输出值相关的类。其次,我们通过添加两个也完全相互连接的隐藏层来增加这个浅层神经网络的深度。作为损失函数,我们使用平均交叉熵。为了反向传播损失并执行梯度更新,我们使用 Adam 优化器,该优化器在随机梯度下降中对逐渐减小的学习速率使用自适应动量。此外,我们使用每个具有 128 个图像的小批量,并且训练五个时期。在看到我的 JuPyter 笔记本内核芯片有将近 100 GB 的压缩内存后,我决定不使用所有测试实例进行评估,而是随机抽取 5%的子集用于每个评估步骤。然而,我们应该使用整个测试数据集,并在训练后分批评估,以获得对两个模型的泛化能力的更可靠的感知。参考这个笔记本的代码,自己试试。

线性模型

首先,我们加载 EMNIST 数据集,并为后面的训练过程设置一些信息变量:

接下来,我们从 NumPy 数组中轻松地创建 PyTorch 张量作为基本数据构建块。此外,我们将灰度图像的像素值归一化为单位间隔,并将它们展平。在 PyTorch 中,我们不必为分类任务对标签进行一次性编码。这是 PyTorch 内部处理的。这里我们唯一需要注意的是以整数格式提供它们:

现在,我们将线性模型定义为一个继承自torch.nn.Module的新类。我们通常在构造函数中定义模型,并覆盖forward方法。在训练期间,我们向它传递输入数据,它执行正向传播并返回输出层的结果。这是 PyTorch 中一个模型的最小配置,具有简单的可扩展性,我们将在第二个模型中看到:

在我们建立模型之后,我们创建一个模型实例并定义损失函数(最小化的标准)。此外,我们通过为优化过程传递模型参数和适当的学习率来设置 Adam 优化器:

为了控制总的训练持续时间,我们定义了历元的数量,即训练数据的完整遍数,以及适当的批量大小。为了在整个训练过程中跟踪和可视化模型性能,我们还提供了一些保持训练和测试数据集的损失和准确性的列表。最后,我们定义评估的频率:

现在,我们可以建立一个贯穿各时期和批次的训练程序。每次迭代,我们从训练数据中抽取一批,重置之前累积的梯度,执行向前传递以获得预测,并计算由预测和真实值之间的偏差导致的损失。我们通过调用它的backward()函数来反向传播这个损失,并执行相应地调整网络参数的参数更新。可选地,我们采用当前模型,并将其应用于测试数据进行评估。现在我们都准备好开始训练程序了。

下面是我们从中得到的:测试准确率收敛到 68%左右。通常,我们现在会进入一些更深层次的错误分析,例如,通过参考混淆矩阵来识别哪些类别的模型是特别错误的,或者通过根据它们的逆频率来调整我们的损失函数加权代表不足的类别。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为了说明从 PyTorch 中现有的模型定义进行扩展是多么容易,我宁愿通过添加两个隐藏层来将现有的架构扩展到深度神经网络。没有一个体面的讨论是什么构成了 DNNs 实际上是深的,让我们去做它,简单地调整一下我们的网络。然而,如果你想有所准备,请咨询古德菲勒、本吉奥和库维尔这里

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

深度神经网络

一旦我们设置了周围的参数和跟踪能力,交换或调整模型是相当容易的。我们可以在现有的基础上定义更多的类,或者按照上面已经显示的结构定义全新的模型。在这里,我们通过扩展层数以及定义将这些层相互连接的操作来类似地定义 DNN。这里,我们应用指数线性单位函数来激活隐藏层的逻辑。

最后,我们观察 DNN,以达到更准确的线性模型分类结果。当然,我们坚持使用更精确的模型,因为它在测试数据集上表现得更好,大约有 78%的精确度。这种性能作为泛化能力的代理,我们希望使用我们期望在新数据上很好地泛化的模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不言而喻,这些结果远非真正令人满意和严谨。相反,它们用于说明目的。我们可以用层次模型结构扩展我们的方法,首先区分数字和大小写字母,然后再进行识别。我们也可以转向使用卷积神经网络。然而,这里的重点不是模型调整,而是更好地将探索与生产联系起来。因此,我们在这一点上完成了模型开发,并继续进行模型转换。

模型转换:使用 ONNX——开放式神经网络交换格式

在模型探索和选择之后,我们不得不考虑如何将模型投入生产。部署依赖于框架的模型可能具有挑战性。一般来说,有两种范例可以在更高的层次上实现这一点:一方面,可以使用用于建模和训练的框架,例如通过实现嵌入前向传播的 web 服务。另一方面,人们可以跨越框架边界,混合使用各种技术。我个人更喜欢使用不同世界的精华,并希望说服你也这样做——通过轻松和一些指导。话虽如此,让我们跨越鸿沟,超越界限。

首先,我们阐述了在生产中部署机器学习模型的一些标准:

  • 高性能和可扩展性
  • 灵活性
  • 互通
  • 到期日

该解决方案需要处理请求的并发性和频率,并在传输、预处理、前向传播和后处理方面高速处理这些请求。如果资源耗尽,还需要快速适应传入的请求,特别是在容错(可靠性)方面。灵活性是指语言支持、配置和模型处理。互操作性涉及以最少的努力支持多种框架和格式。最后,如果没有满足某些标准,那么成熟度从一开始就可以获得回报。成熟促进采纳,从而促进讨论、解决问题以及想法的多样性和数量。这使得从新事物开始变得更容易。然而,如果解决方案在某些点上已经非常好了,这并不重要,因为在开始时,很少有人采用它。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

https://onnx.ai/

开放式神经网络交换格式(ONNX)

ONNX 代表 开放神经网络交换格式 ,号称是“可互换 AI 模型的新开放生态系统”。它提供了一种标准格式来表示深度学习模型,并通过在框架之间轻松共享模型来实现互操作性。它由亚马逊、脸书和微软支持,自 2017 年以来一直存在。ONNX 格式定义了计算图形模型。在他们的 GitHub 页面上有很多关于从不同框架导出和导入的教程。Caffee2,微软认知工具包,MXNet,PyTorch 原生支持 ONNX。还有用于 TensorFlowCoreML 的连接器。随着 TensorFlow 2.0 公告指出“交换格式的标准化”,我们也可能希望 TensorFlow 很快就能原生支持 ONNX。然而,在 GitHub 正在进行的讨论中,我们可以看到一些官员犹豫不决的反应。总的来说,ONNX 可以被视为 PMML预测模型标记语言(PMML) 的现代、可访问和专注于深度学习的继任者,用于以框架非特定的方式表示预测模型和数据转换。

幸运的是,PyTorch 已经集成了 ONNX,因此提供了功能来将模型导出为 ONNX protobuf 格式。因此,我们用torch.onnx.export导出我们的模型,并向它传递模型、保存它的路径和示例输入。由于模型导出本身通过跟踪工作,我们需要提供这个示例输入。这意味着调用导出会触发模型使用该输入执行向前传递,并记录参与计算输出的操作符的踪迹。因此,该示例也可以是随机数据,但是需要与我们为模型输入指定的形状相匹配。最后,我们还可以指定模型参数的名称。现在,我们可以将其应用于训练好的深度神经网络dnn_model以获得输出文件:

模型部署:高效模型服务器实现的 GraphPipe 和 Docker

Oracle 最近发布了 GraphPipe 来“简化机器学习模型部署,并将其与特定于框架的模型实现分离。”GraphPipe 的机器学习传输规范使用了谷歌的 flatbuffers 。它为 TensorFlow、caffee2 和 ONNX 提供参考模型服务器,并为 Go、Java 和 Python 提供客户端实现。集成 ONNX 支持扩展了它对更多深度学习框架的支持。尽管它接受 ONNX 作为独立于框架的模型格式,但 GraphPipe 使用特定于框架的模型服务器。通过调整模型服务器配置和标准化客户端-服务器通信,GraphPipe 在服务器效率和性能方面表现出色。各个模型服务器嵌入到他们网站上提供的 Docker 容器中。ONNX 模型服务器接受 ONNX 模型以及 caffee2 NetDef 格式的模型。TensorFlow 模型服务器处理 TensorFlow 模型、SavedModel 和 GraphDef 格式。以下是 GraphPipe 如何处理请求的总结:

本质上,GraphPipe 请求的行为类似于 TensorFlow-serving predict 请求,但是使用 flatbuffers 作为消息格式。Flatbuffers 类似于 google protocol buffers,具有避免在反序列化步骤中进行内存复制的额外好处。flatbuffer 定义提供包括输入张量、输入名称和输出名称的请求消息。GraphPipe 远程模型接受请求消息,并为每个请求的输出名称返回一个张量。远程模型还必须提供关于它所支持的输入和输出的类型和形状的元数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

ONNX 和 GraphPipe 并不是促进互操作性和部署简易性的唯一技术。几乎在 GraphPipe 发布的同时,Khronos Group 发布了其神经网络交换格式(NNEF) 作为支持互操作性的新标准。此外,使用Glow——一个用于神经网络硬件加速器的编译器,有了另一种将不同框架的模型转换成通用标准的方法。请随意检查它们,不要忘记分享您的经验。在这篇博文中,我们现在将集中讨论 ONNX 和 GraphPipe,然后回到实际部分。说到这里,让我们回到我们的 EMNIST 图像分类模型,并通过 GraphPipe 提供它。代码可以参考这款 JuPyter 笔记本

首先,确保你的机器上安装了 Docker。其次,用docker pull sleepsonthefloor/graphpipe-onnx:cpudocker pull sleepsonthefloor/graphpipe-tf:cpu拉动 graphpipe-tfgraphpipe-onnx 容器图像。第三,使用pip install graphpipe 安装 GraphPipe 客户端来测试我们的模型。更多信息,请参考用户指南。这些参考资料使用简单,让我们可以通过运行的模型服务器快速提供深度学习模型。我们继续使用 ONNX 模型,并使用端口 9000 从存储库的根目录启动我们的模型服务器。为此,我们必须首先创建value-inputs,这是使用 graphpipe-onnx 服务模型所需的。不幸的是,用户指南中关于如何设置value_inputs.json的信息非常少:

--value-inputs string value_inputs.json for the model. Accepts local file or http(s) url.

然而,我们可以遵循示例性 Squeezenet 输入的结构,假设外部列表描述每个请求的批量大小,内部列表保存输入维度:

{"data_0": [1, [1, 3, 227, 227]]}
{"flattened_rescaled_img_28x28": [1, [1, 784]]}

现在可以用下面的命令启动模型服务器了:

docker run -it — rm \
 -v “$PWD/models:/models/” \
 -p 9000:9000 \
 sleepsonthefloor/graphpipe-onnx:cpu \
 — value-inputs=/models/dnn_model_pt.value_inputs.json \
 — model=../models/dnn_model_pt.onnx \
 — listen=0.0.0.0:9000

不幸的是,我们失败了,并显示以下日志消息(有关完整的日志,请参阅笔记本):

terminate called after throwing an instance of ‘caffe2::EnforceNotMet’
 what(): [enforce fail at tensor.h:147] values.size() == size_. 784 vs 1229312

这似乎是一些张量形状没有按照预期设置。然而,如果没有 Caffee2 的相关知识,这可能很难调试。因此,我们尝试直接从 GitHub 加载两个资源(dnn_model_pt.value_inputs.jsondnn_model_pt.onnx),但也失败了。尽管 Squeezenet 的例子起了作用,但是在 GraphPipe 中,试图在我们自己的 ONNX 模型中复制这个例子是一个很大的麻烦。然而,随着 graphpipe-tf 成为 TensorFlow 模型服务器,似乎有了一条出路。多亏了 ONNX,我们可以轻松地从 ONNX-model 中生成 TensorFlow 模型导出,并尝试通过 GraphPipe 服务于该模型。因此,我们只需安装 ONNX TensorFlow 连接器。因此,让我们再试一次:

将 ONNX 模型转换成 TensorFlow protobuf 后,我们用以下代码启动 Docker 容器:

docker run -it — rm \
 -v “$PWD/models:/models/” \
 -p 9000:9000 \
 sleepsonthefloor/graphpipe-tf:cpu \
 — model=/models/dnn_model_tf.pb \
 — listen=0.0.0.0:9000

为我们的终端带来以下内容:

INFO[0000] Starting graphpipe-tf version 1.0.0.10.f235920 (built from sha f235920)
INFO[0000] Model hash is ‘e3ee2541642a8ef855d49ba387cee37d5678901f95e8aa0d3ed9a355cf464fb2’ 
INFO[0000] Using default inputs [flattened_rescaled_img_28x28:0] 
INFO[0000] Using default outputs [Softmax:0] 
INFO[0000] Listening on ‘0.0.0.0:9000

现在看起来好多了。尽管最初有些困难,但我们只用了几行代码就快速部署了我们的模型。这就是为什么我们现在想知道我们部署的行为是否与我们训练的行为相似。

因此,我们最终使用一些针对容器化模型服务器的 REST 接口的测试数据查询来验证部署。为此,我们使用已经安装的 GraphPipe 客户端实现:

Predicted Label / True Label: 2 == z ? — False !
Predicted Label / True Label: r == r ? — True !
Predicted Label / True Label: 3 == 3 ? — True !
Predicted Label / True Label: h == h ? — True !
Predicted Label / True Label: 2 == 2 ? — True !
Predicted Label / True Label: j == j ? — True !
Predicted Label / True Label: 5 == 5 ? — True !
Predicted Label / True Label: 2 == 2 ? — True !
Predicted Label / True Label: 7 == 7 ? — True !
Predicted Label / True Label: 8 == 8 ? — True !

这是后端发生的情况:

…
INFO[0113] Request for / took 773.621µs 
INFO[0113] Request for / took 859.584µs 
INFO[0113] Request for / took 810.67µs 
…

太好了,我们的模型充满活力,能够快速响应请求,并显示出与训练时相似的准确性。请随意尝试更多的例子来证明一些不那么可疑的统计意义;-)

我们现在在哪里,下次去哪?

有很多东西要读,但希望也有很多东西要学。这是我从这项工作中得到的,我希望你能分享经验或提供更多反馈:

  • PyTorch 在易用性方面表现出色,并且本身支持 ONNX 互操作性,尽管它缺乏集成的部署解决方案。
  • TensorFlow 在成熟度和效率方面表现出色,我们希望它也能在互操作性方面表现出色,使 ONNX 支持成为必然。
  • ONNX 是一个令人信服的促进模型互操作性的中介。我希望看到它在未来集成更多的连接器,比如 onnx-tf
  • GraphPipe 既有用又简洁,但也有一些初期问题。TensorFlow 的集成在盒子的右边工作,而 ONNX 模型不是这种情况。

如果你准备继续,在这里找到第二部。感谢阅读、鼓掌、分享,不要忘记注意差距

感谢我的同事 弗洛里安·威廉 、简·本德和迈克尔·廷普兰提供的宝贵反馈。

从探索到生产——弥合深度学习的部署差距(第二部分)

原文:https://towardsdatascience.com/from-exploration-to-production-bridging-the-deployment-gap-for-deep-learning-part-2-9e33cc8dfe5e?source=collection_archive---------7-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这是关于深度学习模型探索、翻译和部署的两个博客系列的第二部分。两者都涉及到很多技术,比如 PyTorch、TensorFlow、TensorFlow Serving、Docker、ONNX、NNEF、GraphPipe、Flask 。我们将协调这些技术,使用更具挑战性但不太受欢迎的 EMNIST 数据集来解决图像分类的任务。在第一部分中,我们介绍了 EMNIST,使用 PyTorch 开发和训练模型,使用开放神经网络交换格式(ONNX)翻译它们,并通过 GraphPipe 服务它们。

本部分通过添加两种额外的模型部署方法来结束本系列。TensorFlow Serving 和 Docker 以及一种相当业余的方法,在这种方法中,我们构建了一个服务于我们模型的简单 web 应用程序。这两个部署都将提供 REST API 来调用预测。你会在 GitHub 上找到所有相关的源代码。如果您喜欢从头开始,请在这里找到关于数据科学的第部分。

我们将使用我们在第一部分中生成的来自 PyTorch 和 TensorFlow 的经过训练的模型文件。你可以在 GitHub 上的models文件夹中找到它们。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

模型部署:TensorFlow 服务和 Docker

这确实是我们第二次在这个系列中使用 TensorFlow 服务。我们第一次使用它是作为 GraphPipe 的一部分,它提供了参考模型服务器和调整模型服务器配置。我们现在不使用元框架,而是直接转向 TensorFlow。参考这个 JuPyter 笔记本按照步骤去体验深度学习模型部署的另一种方式。

第一步,我们必须加载我们的 ONNX 模型,并使用 ONNX TensorFlow 连接器创建它的 TensorFlow 表示:

接下来,我们定义加载模型的路径,并创建一个SavedModelBuilder。这个实例是生成路径和创建模型的 protobuf 导出所必需的。在 TensorFlow 服务术语中,该特定保存路径也称为

为了给我们的模型构建一个合适的签名(某种类型的接口),让我们回顾一下模型由什么组成:

External Input: ['flattened_rescaled_img_28x28']
External Output: ['softmax_probabilities']{'weight_1': <tf.Tensor 'Const:0' shape=(512, 784) dtype=float32>,
 'bias_1': <tf.Tensor 'Const_1:0' shape=(512,) dtype=float32>,
 'weight_2': <tf.Tensor 'Const_2:0' shape=(256, 512) dtype=float32>,
 'bias_2': <tf.Tensor 'Const_3:0' shape=(256,) dtype=float32>,
 'weight_3': <tf.Tensor 'Const_4:0' shape=(62, 256) dtype=float32>,
 'bias_3': <tf.Tensor 'Const_5:0' shape=(62,) dtype=float32>,
 'flattened_rescaled_img_28x28': <tf.Tensor 'flattened_rescaled_img_28x28:0' shape=(1, 784) dtype=float32>,
 '7': <tf.Tensor 'add:0' shape=(1, 512) dtype=float32>,
 '8': <tf.Tensor 'add_1:0' shape=(1, 512) dtype=float32>,
 '9': <tf.Tensor 'add_2:0' shape=(1, 256) dtype=float32>,
 '10': <tf.Tensor 'add_3:0' shape=(1, 256) dtype=float32>,
 '11': <tf.Tensor 'add_4:0' shape=(1, 62) dtype=float32>,
 'softmax_probabilities': <tf.Tensor 'Softmax:0' shape=(1, 62) dtype=float32>}

我们可以识别三个完全连接的层以及我们的输入和输出张量。后者是入口和出口,特别重要的是构建所谓的签名定义。这些签名定义了服务环境和我们的模型本身之间的接口。这是模型部署的第一步,接下来是在 Docker 中启动服务器并进行适当的部署测试。

签名定义构建

在本节中,我们将创建适当的签名(分类和预测)并将它们添加到模型图中。之后,我们使用我们的SavedModelBuilder实例进行实际的导出

为了创建合适的签名,我们必须从输入和输出张量中推断出TensorInfo对象。TensorInfo对象是类 JSON 对象,包含Tensor名称数据类型形状。我们简单地获取输入和输出张量的引用,并使用build_tensor_info为它们创建TensorInfo对象:

应用于output_tensor,我们得到output_tensor_info并看到张量持有与我们的 62 个不同 EMNIST 标签相关的维度 1 x 62 的 softmax 激活:

name: "Softmax:0"
dtype: DT_FLOAT
tensor_shape {
  dim {
    size: 1
  }
  dim {
    size: 62
  }
}

现在,我们已经准备好构建分类和预测签名,如下所示。它们只是将TensorInfo对象与适当的名称和方法名的声明结合起来:

定义后的prediction_signature看起来像这样:

inputs {
  key: "images"
  value {
    name: "flattened_rescaled_img_28x28:0"
    dtype: DT_FLOAT
    tensor_shape {
      dim {
        size: 1
      }
      dim {
        size: 784
      }
    }
  }
}
outputs {
  key: "scores"
  value {
    name: "Softmax:0"
    dtype: DT_FLOAT
    tensor_shape {
      dim {
        size: 1
      }
      dim {
        size: 62
      }
    }
  }
}
method_name: "tensorflow/serving/predict"

最后,我们将两个签名添加到模型中,并执行导出:

我们现在可以找到类似于包括元数据(签名)的序列化模型图定义的saved_model.pb。此外,我们的构建器添加了包含序列化图形变量的文件夹variables。不幸的是,签名构建过程增加了额外的复杂性。说实话,我还没得到它的效用。毕竟,人们也可以使用张量名称本身,而不需要任何额外的包装。但是,如果您想尝试一下,可以在相关 TensorFlow 文档中找到更多信息。

通过 Docker 容器中的 TensorFlow 服务模型

嘿,看起来我们刚刚创建了一个可服务的,它是 TensorFlow 为客户用来执行计算的对象提供语音服务。是时候真正为可服务对象服务了。但是,TensorFlow 中的服务一般是如何工作的?简而言之,TensorFlow Serving 由下图中描述的五个组件组成: ServablesLoadersSourcesManagerCore 。它们一起工作如下:我们运行一个模型服务器,告诉管理器它应该监听的,以便它可以探索新的服务对象。在我们的例子中,我们使用一个文件系统。当我们将一个模型保存到那个文件系统时,通知管理器关于一个新检测到的可服务的,这使得它成为期望的版本。源提供了一个加载器,它告诉管理器加载模型所需的资源。管理器同时处理请求,决定是否以及何时加载模型。根据版本策略,它可以卸载旧版本或保留旧版本。成功加载模型后,管理器可以开始服务客户端请求,将句柄返回到非常新的可服务或其他版本,如果客户端明确请求的话。客户端可以使用 gRPCREST 发送推理查询。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

https://www.tensorflow.org/serving/overview

到目前为止,一切顺利——让我们再练习一次:安装 Docker 后,我们用docker pull tensorflow/serving提取 TF 服务容器映像,并简单地用下面的命令启动模型服务器:

docker run -p 8501:8501 --name emnist_model \
--mount type=bind,source=$(pwd)/../models/tf_emnist,target=/models/tf_emnist \
-e MODEL_NAME=tf_emnist -t tensorflow/serving &

这将启动 dockerized 模型服务器,并将其端口 8501 发布到我们主机上的同一个服务器。这个端口为我们的模型提供了一个 REST API。此外,我们将目录( source )挂载到容器( target )中,在那里我们喜欢保存我们的 servables。因此,每次我们导出较新的模型版本时,TF serving 都会在容器中识别它们并触发加载过程。我们现在可以直接看到服务进程以及由核心、管理器和加载器完成的任务。

2018-10-13 13:38:15.518130: I tensorflow_serving/model_servers/server.cc:82] Building single TensorFlow model file config:  model_name: tf_emnist model_base_path: /models/tf_emnist
2018-10-13 13:38:15.518416: I tensorflow_serving/model_servers/server_core.cc:462] Adding/updating models.
2018-10-13 13:38:15.518455: I tensorflow_serving/model_servers/server_core.cc:517]  (Re-)adding model: tf_emnist
2018-10-13 13:38:15.638251: I tensorflow_serving/core/basic_manager.cc:739] Successfully reserved resources to load servable {name: tf_emnist version: 1}
2018-10-13 13:38:15.638370: I tensorflow_serving/core/loader_harness.cc:66] Approving load for servable version {name: tf_emnist version: 1}
2018-10-13 13:38:15.638411: I tensorflow_serving/core/loader_harness.cc:74] Loading servable version {name: tf_emnist version: 1}
2018-10-13 13:38:15.639975: I external/org_tensorflow/tensorflow/contrib/session_bundle/bundle_shim.cc:360] Attempting to load native SavedModelBundle in bundle-shim from: /models/tf_emnist/1
2018-10-13 13:38:15.641451: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:31] Reading SavedModel from: /models/tf_emnist/1
2018-10-13 13:38:15.659090: I external/org_tensorflow/tensorflow/cc/saved_model/reader.cc:54] Reading meta graph with tags { serve }
2018-10-13 13:38:15.660035: I external/org_tensorflow/tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2018-10-13 13:38:15.672728: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:162] Restoring SavedModel bundle.
2018-10-13 13:38:15.673671: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:172] The specified SavedModel has no variables; no checkpoints were restored. File does not exist: /models/tf_emnist/1/variables/variables.index
2018-10-13 13:38:15.673710: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:138] Running MainOp with key saved_model_main_op on SavedModel bundle.
2018-10-13 13:38:15.677101: I external/org_tensorflow/tensorflow/cc/saved_model/loader.cc:259] SavedModel load for tags { serve }; Status: success. Took 35653 microseconds.
2018-10-13 13:38:15.678135: I tensorflow_serving/servables/tensorflow/saved_model_warmup.cc:83] No warmup data file found at /models/tf_emnist/1/assets.extra/tf_serving_warmup_requests
2018-10-13 13:38:15.684767: I tensorflow_serving/core/loader_harness.cc:86] Successfully loaded servable version {name: tf_emnist version: 1}
2018-10-13 13:38:15.686409: I tensorflow_serving/model_servers/server.cc:285] Running gRPC ModelServer at 0.0.0.0:8500 ...
[warn] getaddrinfo: address family for nodename not supported
2018-10-13 13:38:15.686843: I tensorflow_serving/model_servers/server.cc:301] Exporting HTTP/REST API at:localhost:8501 ...
[evhttp_server.cc : 235] RAW: Entering the event loop ...

测试模型服务器

再次测试的时候到了!让我们对我们的模型服务器使用一些测试图像,并评估它们的分类准确性。此时,使用我们的预测签名中定义的输入和输出定义将是直观的。然而,这并不是那么简单,我们创建了一个用instances注释的数据有效负载作为我们的 POST 请求的输入,并接收一个响应对象,我们需要用predictions处理它的内容:

在我们的 1000 个测试例子中,我们最终得到的准确率为 78.3% ,这与我们的训练结果一致。最后让我们看看下面的一些例子。我们可以发现该模型很难区分大写的 O0 ,这一点都不容易。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

模型部署:Flask Webservice

在本节中,我们将转向我们的最终部署方法。因此,我们在一个简单的 web 服务中嵌入了模型推理,并构建了一个允许用户上传图像进行分类的极简前端。为此,我们使用了 Flask ,这是一个简洁的 Python web 开发框架,基于 Werkzeug 和 Jinja2。我们将在包本身中实现模块emnist_dl2prod.emnist_webserver,但是你可以参考这个 JuPyter 笔记本获得更多信息。

本节包括三个部分:

  1. 构建模型包装类
  2. 实现 web 服务和前端
  3. 运行并测试我们自己的 EMNIST 网络服务器

1.构建模型包装类

我们从下面的模型包装类开始。为了创建一个新的实例,我们必须提供之前使用SavedModelBuilder保存的模型的路径。这里,我们使用tf.saved_model的加载器功能来加载和恢复我们的模型。我们还创建了一个会话,在这个会话中,我们恢复了构成我们的SavedModel的图形定义和变量。此外,模型类还实现了一个run方法,以便稍后轻松执行单个实例或批量推理。此方法只是对展平和规范化的图像数据(浮点值在 0 和 1 之间)运行会话,并返回所有 62 个类的 softmax 激活。

2.实现 web 服务和前端

接下来,我们转向 Flask 和一些 HTML,因为我们将简单的 REST webservice 与极简前端相结合,以上传图像并可视化分类结果。首先,我们创建两个 HTML 文件,img_upload.htmlresult.html。第一个页面实现了一个图像上传界面和一个按钮来提交图像数据,这在内部触发了预处理和分类过程。后一个文件类似于显示上传图像本身的模板,当然也显示分类结果。结果是检测到的(最有可能的)类以及我们的模型得出的 softmax 分数。让我们仔细看看这中间发生了什么。上传图片时,上传页面触发以下重定向:url_for('process_img_upload')。此重定向通过后请求提供了以下方法:

emnist_result是一个字典,我们用它来最终用适当的值呈现我们的结果页面。这也需要临时保存上传的图像并检查文件类型是否正确。在后一部分,我们使用skimage读取图像,直接产生一个 NumPy 数组——数据科学家的宠儿。然后,我们对图像数组进行预处理(归一化+展平)和分类,简单地调用我们的模型包装器实例的run作为classify_img的一部分。这将返回 softmax 激活值,并将最高激活的索引映射到适当的标签。最后,我们通过向字典添加 softmax 值和标签来完成我们的请求结果,并调用show_emnist_result来呈现结果页面。

除了我们的前端展示,我们还实现了一个方法,用一个适当的响应对象来回答 POST 请求,而不是呈现任何 HTML 模板:

3.测试和性能评估

又到了收获我们劳动果实的时候了。我们启动我们的网络服务器,让我们处理一些例子。您可以使用python emnist_webserver.py或使用随软件包安装的命令emnist-webservice来启动它。无论哪种方式,您都应该在终端中显示类似于以下内容的内容:

[2018-10-14 11:07:26] INFO:__main__:Set up temporary media folder for webserver: /Users/mkurovski/Python/emnist_dl2prod/src/emnist_dl2prod/tmp_flask_media
 * Serving Flask app "emnist_webserver" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
[2018-10-14 11:07:26] INFO:werkzeug: * Running on [http://0.0.0.0:5000/](http://0.0.0.0:5000/) (Press CTRL+C to quit)

太好了!让我们去参观一下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为了方便测试,您可以在中找到包含 10 个字符的文件夹test_images。试几个吧!我们选择一个图像并点击Get Result,然后“瞧”,我们在 softmax 激活中看到 e99.74% 的概率。在后端,我们收到了进一步的确认,表明一切都按预期进行:

[14/Oct/2018 11:11:26] "POST /emnist/result HTTP/1.1" 200 -
[14/Oct/2018 11:11:26] "GET /emnist/img_upload/img_upload_1539508286216.png HTTP/1.1" 200 -

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在相关的 JuPyter 笔记本中,您将看到我们后面的实现的一些示例,我们也想在这里尝试一下。出于评估和测试的目的,您可以将eval_serving_performance作为emnist_dl2prod.utils的一部分。该方法从测试或训练数据中创建一定量的请求,将它们发送到指定的端点,并评估响应的准确性及其时间。我们将在下一部分更详细地讨论它。这里,让我们在刚刚创建的终端上尝试一下:

这将一些结果可视化,并告诉我们请求的平均准确性:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Accuracy on 1000 test images: 77.60%

77.6% —耶!这看起来与我们的训练经验非常一致。
太好了!我们实现了自己的 web 服务,成功地证实了我们在生产中的培训结果。到了决赛的时候了——所有这些方法在定性和定量意义上如何相互比较?

结论:比较不同部署的吞吐量和预测准确性

这是我关于深度学习模型探索、翻译和制作的综合博客系列的最后一部分。借助 Docker、TensorFlow、GraphPipe、PyTorch、ONNX 和 Flask 等众多技术,我们构建了从勘探到生产的桥梁。所有的方法都是从 PyTorch 探索和 ONNX 翻译开始的。它们的不同之处在于我们部署每个解决方案的方式。我们从 GraphPipe 和 Docker 开始提供一个处理 REST 调用的简短包装器。我们继续使用 TensorFlow 在 Docker 容器中提供服务。这有点冗长和复杂。最后,我们使用 Flask 构建了自己的 web 服务器,并嵌入了模型推理调用。我们还将最后一种方法与极简前端相结合。这是最冗长的,但也是最容易理解的部署方式。然而,我不建议将它用于大规模生产系统,它有助于捕捉模型推理、客户端-服务器通信和前端如何相互连接。现在,让我们看看这些方法在定性和定量方面是如何相互比较的。

首先,让我们从易用性实现努力的角度来看一下定性。在我看来,Flask 是最简单的方法 GraphPipe 紧随其后。服务 ONNX 模型的 GraphPipe 中的一些意外故障导致了问题。然而,转移到 TensorFlow 很容易地解决了我们当时的问题。使用 TensorFlow 服务,事情会变得有点复杂,因此它在这方面占据第三位。就我们的实现程度而言,GraphPipe 是明显的赢家,只需要很少的代码来部署我们的模型。TensorFlow 服务需要多一点,但仍然做得很好。签名的定义在这里增加了一些冗长。Flask 紧随其后,因为它比 GraphPipe 花费更多的精力,这对于构建自己的解决方案来说似乎是不言而喻的。

但是,作为数据科学家和工程师,我们更感兴趣的是仅仅作为直觉的数字。因此,我还对这些部署在给定请求吞吐量的情况下如何进行比较以及它们是否返回一致的结果感兴趣。参见这款 JuPyter 笔记本进行对比。我在一个只有一个 CPU 的谷歌云计算实例上测试了所有解决方案。然而,为了避免糟糕的网络连接导致的测量偏差,我在这里展示了本地托管每个服务的结果。我们涵盖了各种场景:发送单个实例请求和批处理请求,每个都有 128 个示例。对于这两个场景,我们使用单个客户端线程,没有异步请求,以保持与 Oracle 评估 GraphPipe 的方式一致。然后,我们计算在一致的持续时间内成功请求的数量,并获得每秒的吞吐量作为性能指标。参见emnist_dl2prod.utils:eval_throughput了解我们吞吐量测试的实施。需要注意的是,不同设置下的绝对数字可能会有所不同。然而,这不应该是我们关心的问题,因为我们更感兴趣的是这些方法如何相互比较而不是它们各自的绝对性能。因此,让我们来看看**单实例请求吞吐量。**我们清楚地看到 TensorFlow 的服务性能优于 GraphPipe 和 Flask,每秒处理超过 200 个单实例请求,其中 GraphPipe 和 Flask 分别超过大约 150 个和 125 个。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果我们研究使用的批处理推理案例,并且顺序已经改变,差异会变得更大。GraphPipe 显然脱颖而出,在相同时间内,它提供的图片数量大约是 TensorFlow 的三倍。TensorFlow 服务在处理请求方面排名第二,比 Flask 服务高出约 70-80%。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这与甲骨文的说法相当一致。然而,在我们的例子中,震级并没有变得那么极端。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

https://oracle.github.io/graphpipe/#/guide/user-guide/performance

总之,在批量推断方面,GraphPipe 比 Flask 和 TensorFlow 要快得多。然而,TensorFlow 服务明显优于单个实例推理,这一点值得注意。如果我们不批量处理传入的请求并为其提供 GraphPipe,我们最好继续使用 TensorFlow 服务。但是,如果我们的问题允许,或者如果我们可以批量处理传入的请求,我们最好使用 GraphPipe。

观点

哇,这是很多,我希望你仍然喜欢它。请你自己尝试一下,分享一下你的经验,让我们试着介意一下探索和制作之间的差距。有大量的技术支持我们,甚至更多的技术将会出现。特别是,我预计 ONNX 将成为深度学习框架不可或缺的一部分,GraphPipe 将超越其目前的地位。有了这些和其他的贡献,我们可以让事情变得更容易生产,让人工智能通过改变人们的生活来为人们服务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值