TowardsDataScience 博客中文翻译 2020(一百六十九)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

使用 Unsplash API 为应用注入活力

原文:https://towardsdatascience.com/breathe-some-life-in-to-power-apps-with-the-unsplash-api-450bb9473f1b?source=collection_archive---------45-----------------------

如何在 Microsoft Power Automate(又名 Flow)中使用 REST APIs 向您的 SharePoint 列表中添加随机但非常漂亮的图片

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

山顶上的新加坡樟宜机场。好照片让东西看起来更好。卡米尔·塔托尔在 Unsplash 上拍摄的照片

看 Power 应用教程有点像看草生长。油漆干燥时。当你等着水壶烧开的时候。令人失望的是,你的“带按钮的 SharePoint 列表”看起来是如此乏味,这足以让任何人去喝锁定的杜松子酒和滋补品。

不要烦恼。我们可以偷别人的照片,让他们看起来很漂亮。

电力应用程序很难看

下面是 SharePoint 的经典无个性画布应用。

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

评分一个为什么大家都觉得 Power Apps 很垃圾的例子(对不起微软)。它们只是看起来很单调。来自微软的教程来自 SharePoint 的画布应用

不要误解我的意思,微软发布 Power 应用程序的速度比任何人了解它们的速度都快。他们可以做的事情并不缺乏,你可以延伸他们的长度。问题是,它们永远不会像你直接使用网络应用程序时那样好看(只要看看那些花哨的引导主题

好吧,一个快速解决办法是添加一些图像,所以让我们开始从互联网的许多摄影师抢夺他们。

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

游戏计划

SharePoint 列表图片字段

从微软教程中获取 SharePoint 列表,并添加一个“图片”类型的列。

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

添加图片栏。有时候,列名的灵感来之不易。

添加或更新列表中的项目时,用户需要输入 URL 和可选文本字段。该字段的一个经典用例是使用它来存储您刚刚用 Power Apps 相机控件放下的冰淇淋的图像 URL。

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

“图片”类型的 SharePoint 列表字段需要 URL

将非屏蔽 URL 放入列表

这个想法是,我们从 Unsplash 获得这些带有一些搜索参数的 URL。这将是很好的,如果这些是随机的(不要只是想一遍又一遍地相同的图片),如果它自动完成。

在微软的世界里,用 Power Automate 实现自动化是最容易的。计划是这样的。

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

使用 Power Automate 的更明亮、更令人兴奋的 Power 应用程序的计划

1 - 创造权力自动化流程。

当我们创建列表项时触发。

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

当我们在枯燥的应用程序 SharePoint 列表中创建新项目时,就会触发 Flow。

2 - 获得不光彩的形象。

使用 SharePoint 项目的标题从 Unsplash 中检索照片的图像 URL。

un splash 文档相当全面,可能有点让人不知所措。下面是一个使用 HTTP 连接器(注意这是一个高级连接器)搜索与 SharePoint 列表项相关的图片的示例。

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

Client-ID 后面的 xxxxx 应该替换为您的 Unsplash 应用程序访问密钥。为此,你需要在 Unsplash 上建立一个开发者账户,并注册一个应用程序。

3 - 解析 Unsplash API 返回的 JSON。

当我们更新 SharePoint 列表时,解析 JSON 允许使用响应中的字段。

Power Automate 可以通过“从样本生成”按钮为您找出 JSON 结构。将 Unsplash 响应的主体传递给该步骤的内容。

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

Generate from sample 将让 Power Automate 从示例响应中为您猜测模式。运行一个测试,从上面的 HTTP 请求中获得一个示例响应,或者使用API 文档响应(但是去掉注释)

用于响应 Unsplash HTTP 请求的 JSON 模式在这里的 GitHub 上。这需要根据 Power Automate 自动生成的模式进行修改,以便允许字段为空(例如,Unsplash 遗漏了 Instagram 关注者的数量)。通过为 JSON 模式中的每个值提供两种类型的数组(例如[“string “,” null”],而不仅仅是" string "),每个字段都可以为空。做一个查找和替换,否则,你会在那里很长一段时间。

4 - 使用 SharePoint REST API 请求 SharePoint 列表属性“ListItemEntityTypeFullName”。

恼人的是,你不能在 Power Automate 中直接访问 SharePoint 列表“图片”字段。它们只是没有出现在更新 SharePoint 项目步骤中。

没事的。我们可以使用 SharePoint REST API 来更新列表项,这里有更多的文档来解释 SharePoint API 是如何工作的。

我们可以使用 Power Automate 中的 SharePoint HTTP 请求步骤来访问 SharePoint API,与一般的 HTTP 请求不同,这不是一个高级连接器。在这一步中,我们需要一个对列表的属性的 GET 请求。不要忘记解析这个返回的 JSON。

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

获取 SharePoint BoringAppList 的 ListItemEntityTypeFullName 属性

5 - 更新 SharePoint 列表项目图片字段

SharePoint HTTP 请求再次提供了帮助。这一次发送了一个 POST 请求,将我们之前响应中的 Unsplash URL 粘贴到创建/修改的项目的图片字段中。

该请求中的标头非常重要。正文需要从 SharePoint 检索的 ListItemEntityTypeFullName 属性和从 Unsplash 检索的 URL。这里使用了小的URL(400 x400 ),照片描述放在 SharePoint 图像的可选文本中。

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

将请求发送到 SharePoint API,该 API 将取消屏蔽 URL 放入列表项中

一些副本和过去的友好位在 GitHub 的

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

计划来了!

不那么无聊的应用程序

正如你所看到的,一些图片会产生很大的不同。就我个人而言,我迫不及待地想记录我的下一个冰淇淋。

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

从 Unsplash 添加随机图片带来了一点色彩,并可能赢得那些讨厌的用户。在 Wise Technical,我们也制作适当的网络应用程序和数据平台,以最大限度地提高其商业效益。伸出手来!https://www.wisetechltd.com/

值得注意的琐事

  • 在 Unsplash API 上,每小时只能收到 50 个请求
  • 不要将 Sharepoint 项目更新的 POST 请求中的内容类型设置为 application/json(根据文档),而是将其设置为“application/JSON;odata=verbose "

布伦特福德足球俱乐部:足球中的金钱故事

原文:https://towardsdatascience.com/brentford-fc-the-moneyball-story-in-football-9726619d0d1a?source=collection_archive---------18-----------------------

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

UnsplashFancy claim的照片

2020 年 8 月 5 日,布伦特福德踏上温布利体育场的草皮,在足球最丰富的比赛中迎战富勒姆。这是他们自二战后联赛恢复后退出以来最接近英格兰足球顶级联赛的一次。由于富勒姆边后卫乔·布莱恩的梅开二度,他们输掉了比赛,但这标志着一个过程的高潮,这个过程始于五年前他们升上英冠的时候。从那时起,接下来是一个谨慎的计划和执行,非常依赖数据。

从晋级者到中等俱乐部

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

自晋级以来的每轮布伦特福德联赛排名。

布伦特福德在冠军联赛中最引人注目的方面是他们从未卷入降级战。对于一支被提升的球队来说,在获得提升后的前几个赛季的大部分时间里都处于积分榜的下半部分是很常见的。但除了一次,布伦特福德从未在联赛中期到后期跌入红区。

布伦特福德的另一个独特之处是,在最初的几个比赛周之后,他们在一个赛季中的进展曲线几乎总是在上升。除了 2015-16 年,他们在 35-40 游戏周的范围内急剧下降,他们的蠕虫一直在上升。

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

布伦特福德的联赛成绩与 2014-15 赛季和 2015-16 赛季的升班马相比。

为了证明布伦特福德的进步是独一无二的,我们来看看 2014-15 和 2015-16 赛季的晋级者在锦标赛中的表现。除了几个赛季之外,布伦特福德在所有赛季中都超过了他们。

在这段时间里,一些球队也降级了,包括一个降级的俱乐部,然后升级,又降级。然而,狼队在 2017-18 赛季赢得了联赛冠军,这伴随着大量的支出。

让我们看看布伦特福德这些年的开销。

转移活动

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

布伦特福德自从获得晋级冠军后的转会活动。

看过布伦特福德在锦标赛中的表现后,如果他们认为这是在一些重大支出后发生的,那也不会受到指责。这是一个动词。除了 2014-15 赛季布伦特福德重返锦标赛获得第五名之外,布伦特福德一直通过转会活动创造利润。

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

布伦特福德最大的出售资产。上赛季英超联赛的前四名。

经过三年的谨慎销售和支出,俱乐部在联赛中获得了一些稳定性,之后他们在 2018 年创造了创纪录的 3146 万英镑,其中 19 年他们在同一赛季用 590 万英镑购买球员。因此董事会认为是时候挑战英超联赛了!许多球员来到格里芬公园参加 2019-20 赛季。但是你猜怎么着?即使在支出之后,他们也产生了一些利润。这是一些计划和执行。

英超回归的裂缝

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

布伦特福德在 2019-20 EFL 锦标赛中最活跃的足球运动员。

上赛季布伦特福德联赛中最活跃的 11 名球员让你对托马斯·弗兰克喜欢他的球队如何运作有一个公平的想法。大卫·拉亚是无可争议的一号门将,这是理所当然的。如果不是他在斯旺西的点球扑救,布伦特福德可能会在一周前出价 aideu 实现英超梦想。

弗兰克更喜欢传统的后防线,让平诺克和扬松组成防守组合,这样里科·亨利和亨里克·达尔斯加德就可以跑到侧翼。克里斯蒂安·诺尔高、马蒂亚斯·延森和约什·达席尔瓦组成了三人中场核心。

Benrahma 说,Bryan Mbeumo 和 Ollie Watkins 组成了他们著名的三前锋,我将在本文的稍后部分谈到。

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

2019–20 EFL 锦标赛每 90 分钟进球+助攻-点球(最少 2000 分钟上场时间)排名前几位的球员。

托马斯·弗兰克喜欢他的球队进攻和得分。这显示了他的三名前锋是如何相互支持并取得进球的。宝马突击队的本拉赫马、姆布莫和沃特金斯都在名单中占据显著位置,出场时间也很长。

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

2019-20 EFL 锦标赛顶级前锋线(至少打 1000 分钟)。

宝马前锋 3 在上个赛季为布伦特福德贡献了近 60 个进球,远远超过了其他球队的前锋线。这是在布伦特福德在本赛季早些时候将他们 2018-19 赛季的领先前锋尼尔·穆佩卖给布莱顿之后。姆伯莫在 2019-20 赛季开始时刚刚抵达。本·拉赫玛一年前就到了。front 3 在短时间内建立起来的凝聚力是惊人的。数据可能是布伦特福德当初购买它们的原因,但数据无法让合作关系产生共鸣,不是吗?

“我只知道一件事——当我们下个赛季开始时,我们将再次拥有一支非常强大的队伍,我们已经准备好了。”

作为一家出售俱乐部有它的麻烦,但这是布伦特福德屡试不爽的方式。如果布伦特福德在众多英超俱乐部的传言和联系中成功留住前锋奥利·沃特金斯和边锋赛义德·本拉赫马,人们将会非常惊讶。但布伦特福德最近的历史表明,托马斯·弗兰克在季后赛 1-2 输给富勒姆后的话不应该被忽视。

本文大部分数据收集自***【fbref.com】stats bomb****。使用WebHarvy工具从****【transfermarkt.co.in】中刮出转账相关数据。在使用Tableau进行可视化之前,收集的原始数据在Python***中进行预处理。

这里是相关知识库的链接:https://github.com/PritamGuha31/Brentford-Analysis

供需缺口对按需交付意味着什么?

原文:https://towardsdatascience.com/bridging-supply-demand-gaps-in-last-mile-delivery-companies-geospatially-657a98bb1e01?source=collection_archive---------61-----------------------

地理空间分析和洞察

根据您的需求和供应在不同地区的表现,本地化您的匹配算法

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

注意:在阅读本文之前,我强烈建议您阅读本系列的第一部分,其中包括了供需分析的基础知识:

[## 微移动公司如何在地理空间上提高资产利用率

这里有一个很好的问题,可以写在便利贴上,放在你的桌子上:“我们现在有什么资产是不…

blog.locale.ai](https://blog.locale.ai/how-micro-mobility-companies-can-increase-asset-utilization-geospatially/)

如今,在我们的手机上点食物、杂货、香烟甚至酒已经成为一种常态。如果你像我一样,你可能会在一天中最奇怪的时间点所有的东西!

对于按需公司(又名“X 的优步”),这主要是一个三方市场,匹配需求和供应是业务的核心,也是极具挑战性的。此外,现实世界引入了比模型中更多的变异,导致了更为严酷的结果。

当供需缺口存在时,我们要么失去订单,要么我们的骑手闲置——这两者都会导致亏损。但是,是什么导致了这些差距的存在呢?这可能是需求、供给或两者共同作用的结果。

案例 1:需求

订单丢失

由于骑手不在或他们出现在错误的位置而导致您随着时间的推移而丢失的订单数量。

订单速度

当你失去订单时,订单速度是怎样的?也就是说你的订单比平时多了还是少了?

案例 2:供应

闲散的骑手

闲置的乘客数量以及他们由于错误的位置或较少的需求而没有被利用的时间。

**注意:空闲是一个时间点属性。因此,在进行历史分析时,我们需要分析指标“空闲会话时间”。

可用总供应量

当骑手空闲时,总骑手的可用性是什么样的?可用骑手的数量是增加了还是减少了?在对此进行历史分析时,我们需要分析指标*“总会话时间”。*

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

收到的订单与闲置供应。

解读差距的原因

在试图弥合差距之前,我们首先需要理解它们为什么会发生。如果订单丢失,可能是由于以下原因:

没有骑手

  • **错误的地点:**如果我们失去了订单,这可能意味着骑手不在,这意味着他们要么都很忙,要么在错误的地点闲着。
  • **供应过剩:**还有一种情况,我们满足了所有的需求,但却有过剩的闲置人员。或许有必要分析一下总供应量。

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

供需缺口。来源:Locale.ai

订单频率在下降

如果你在那天和那个时间收到订单的频率比平常少,那意味着你需要深入了解为什么会发生这种情况。

  • **类型:**是所有类型的订单还是只有某一种订单?举例来说,是不是只有 A 类的订单量在下降?
  • **生命周期:**在订单流程中,是否有一个特定的步骤会导致大量订单的减少?例如,结账系统或支付网关是否存在一些挑战,导致用户无法完成订单?

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

Locale.ai:监控供需缺口

订单未被分配

可能会有订单进来,但没有分配给骑手。如果发生这种情况,您使用的分配(或匹配)算法可能有问题。在这些情况下,最好向组织内部的相关人员提出这个问题。

在三方市场中,有时商店或餐馆可能会有分配问题。我自己也经历过很多因为问题出在餐厅而无法收到订单的情况。

要深入了解如何对商店或餐馆等静态位置进行分析,请查看:

[## 在地理空间上优化静态定位的性能

对于一个公司来说,静态位置是他们的业务实体,不会移动久而久之。例如,对于一个…

blog.locale.ai](https://blog.locale.ai/optimizing-the-performance-of-static-locations-geospatially/)

骑手们不接受命令

假设订单被分配给骑手,但他们不接受订单。这可能是由多种原因造成的。

  • **距离:**他们不接受订单是因为取货距离很远吗?
  • **区域:**他们不接受订单是因为他们不想前往提货地点吗?
  • **支付:**他们取消是因为用户的支付方式不可取吗?

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

供需缺口和重新定位

骑手们正在取消订单

通常,我们都有过骑手在接受订单后取消订单的经历——尤其是一旦他们知道了交货地点。

  • **距离:**他们取消订单是因为距离卸货点很远吗?
  • **区域:**他们取消订单是因为他们不想前往卸货地点吗?
  • **始发地-目的地:**是不是既不是始发地也不是目的地,而是路线?在这种情况下,大的激励措施也往往不起作用,因为骑手们只是不想穿越这些区域。

城市通常有隐形的墙,骑车人不愿意越过。这些墙在哪里?他们在一天中的什么时候最突出?

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

流动。来源

如前所述,供需匹配不仅仅是现在正在发生的事情。是关于**流的。**下一个需求会在哪里,它在不同的日子和不同的时间会如何变化?

理解最后一公里配送公司的流程非常重要。接下来哪个领域最有可能获得需求?离车手现在的位置有多远?

例如,对于一家最后一英里配送公司,研究流程表明,配送伙伴开始向市中心移动,到了晚上,他们开始搬出去,因为他们大多数人住在郊区。但他们需要向内发展,因为这是他们获得订单最多的地区。

外部洞察力

  • **兴趣点:**另一个非常有趣的分析是分析供需如何受到不同兴趣点的影响,如学校、大学、商场或旅游目的地。
  • **外部事件:**分析不同的外部事件(如下雨、大型音乐会、体育比赛、抗议活动)如何影响贵公司的需求和供应也是很有见地的。
  • **群组:**群组是一组表现相似的用户、骑手或自行车。在不同的时间,我会失去什么样的用户和订单
  • 星期几?什么样的车友大部分时间都很闲?

关于 Locale.ai

Locale 是一个位置分析平台,这意味着我们可以将所有数据库和格式的原始纬度数据转换为有意义的见解,以便决策者可以就其地面运营做出非常精确的数据驱动型决策。

网络分析工具已经利用点击流数据帮助你改善了这些指标。然而,对于在地面上有移动资产的公司来说,不从地理空间的角度看问题是非常有害的!

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

区域设置:工作流模块

场所 ,我们正在创建通过地理空间分析提高单位经济性、每次交付成本和利用率的公司范例。如果你是一名增长型经理,希望提高用户的获取、保留和转化,请在此处联系我进行演示或通过LinkedInTwitter联系我。

原贴 此处

类似阅读:

* [## Carto vs Kepler vs Locale:哪个产品用于地理空间分析?

Carto、Kepler.gl 和 Locale 是公司在分析中用来做出地面决策的三个工具

blog.locale.ai](https://blog.locale.ai/carto-vs-kepler-vs-locale-which-product-to-use-for-geospatial-analytics-2/) [## 如何使用位置分析提高用户获取和转化

一家基于应用程序的送货公司可以随时随地将用户通过应用程序订购的任何东西送到用户的位置…

blog.locale.ai](https://blog.locale.ai/how-to-improve-user-acquisition-conversion-using-location-analytics/)*

弥合遗传学和神经网络之间的鸿沟

原文:https://towardsdatascience.com/bridging-the-gap-between-genetics-and-neural-networks-4fdb91032f4b?source=collection_archive---------36-----------------------

基于遗传数据构建和分析神经网络

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

融合神经网络与 DNA 双螺旋(对齐)的轶事——作者绘制

我最近进行了基因序列的研究工作。关于这个问题,占据我头脑的主要问题是:“对于这个目的,哪一个最简单的建议神经网络与遗传数据最兼容?”在查阅了大量文献后,我发现与这个主题相关的最*【脚踏实地】而又最引人入胜的工作发生在yo shua beng io 的实验室。这篇名为*饮食网:脂肪基因组学的瘦参数 及其的论文主要目标是将 3450 个个体的基因序列分为 26 个种族。那篇论文启发了我,在这里我想解释一下构建神经网络来解决这类问题的基础。理解这个博客,不需要生物学的背景知识;我将尝试涵盖大部分必要的部分,直接进入计算部分。

动机

我们正面临着充满挑战的时代:新型冠状病毒 T21 病毒让我们对强大的自然力量束手无策。通过学习新工具:获得关于基因组数据的直觉,并探索哪些机器学习方法可以最好地概括这些数据;我希望我们可以联手起来,为更好的日子做出改变,或者至少使用神经网络令人难以置信的智能来做一些事情,除了开发娱乐应用程序,而是拯救我们的生活甚至我们的星球。

为什么我觉得遗传学如此吸引人?

你的基因不仅揭示了你的生物信息,还通过代表哪些主要部分存活了下来,揭示了你祖先的遗传历史。

换句话说,它是你家族的生物进化编码,甚至更多,根据达尔文进化论,有机生物(植物、动物等)集合的整体。)都有相同的遗传原理。

直觉

让我带您浏览其他类型的数据,如图像和句子,以了解基因数据的独特性。一方面,图像是具有相邻关系的二维数据(或者对于体积是三维的)。句子是多达大约一千个值的一维向量,具有通过无监督方式训练的句子的层级性质。

另一方面,遗传序列是至少几十万个值的一维向量(序列),在邻居之间没有明确定义的关系,并且远离具有预先训练的模型集。

因此,在图像处理中非常流行的 G aussian 平滑滤波器在这里是不相关的,以及视觉中所有预训练的模型(I mageNet, V GG,Res net*…*)和自然语言处理(W ord2Vec,

为什么说是挑战?

想象一个由成千上万个基因样本组成的数据库。你需要找到一种方法,能够很好地泛化(准确率 90%以上)千万种组合的输入数据。神经网络可能是一个很好的选择,因为它以一种其他“经典”算法所缺少的方式利用完全连接的单元的能力,如 PCA、SVM、决策树,这些算法不单独管理数据。然而,构建最简单的网络体系结构需要在第一层的权重中有数千万个以上的自由参数。降维(避免过多的自由参数)是面对这个问题的一种方法;我们将在本博客稍后讨论它。

生物背景

为了把事情搞清楚,并且不对这个论坛的主要目的造成困难,我在这里只提出这个博客中需要的生物部分的一个高层次的观点。不用说,我们非常欢迎你进一步探索这些生物学话题。

什么是基因序列?

DNA 分子是由字母 A、C、G、t 代表的四种碱基组成的序列。序列的特定部分(即使位于远处)与表型相关。例如,最近的一项研究:“一场与可能来自蝙蝠的新型冠状病毒相关的肺炎爆发” 表明 ACE2 基因可能是新型冠状病毒病毒的宿主受体(表型)。这个例子和许多其他例子显著地展示了仅基于你的 DNA 就可以获得的有价值的信息(罪犯检测、匹配大麻品种、营养和个性化药物)。

什么是 SNP 基因型?

如今,我们比以往任何时候都更接近于获得几乎全部的人类基因序列。然而,我们还远远没有涵盖它的全部。单核苷酸多态性 SNPs 是基因组序列中特定的基因型位置,一般表示为 RS 【数字】。不同的人群有不同的序列不变量,但在家庭中可能是相同的(因此亚洲人看起来与欧洲人不同)。SNP 序列的分析将是贯穿本博客其余部分的关键点。

方法

在本节中,我描述了数据和两个主要的网络架构(以及另一个具有改进参数的网络,以克服机器学习中的一些主要问题)以及一些技术提示…

数据

相对于其他数据类型,医疗数据集很难找到,主要是由于隐私限制。有鉴于此, 1000 基因组计划 通过发布 3450 个人类 DNA 样本的公共可用数据集,即 26 个全球人口中每个人口的 315,000 个 SNP,实现了显著突破。下图显示了从 1000 个基因组数据中得出的直方图,描述了每个群体(种族)中个体的频率;每个群体的平均样本数约为 133 个遗传样本。

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

1000 个基因组人口分布(种族)

降维

如上所述,减少模型中自由参数的数量是首选(在我们的例子中,我们正在处理大约 3000 万个参数)。所提出的实现这一点的方法使用了另一个辅助网络,其位于输入每类直方图的判别网络之上(以无监督的方式计算的嵌入矩阵)。该网络的输出初始化判别网络的第一层的权重。嵌入矩阵是每个群体的归一化基因型直方图,其大小为 SNPs X [4x26],其中 4 代表{00,01,11,NA}(双等位基因),26 代表类别数(群体)。

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

生成每类直方图

下面描述这种嵌入矩阵的实现。

无论如何,这是他们的解决方案;我的解决方案是减少隐藏单元层的数量(参见架构部分)。我将这种新架构称为改进模型,它的一个好处是克服过拟合,这将在后面的结果部分讨论。

建筑

这篇博客比较了两个主要的网络。两个网络都由两个完全连接的隐藏层和一个 softmax 层组成,但第二个(见下图)包括一个辅助网络,它预测 d 判别网络的自由参数。a 辅助网络将 e 嵌入 m 矩阵作为输入,然后返回判别网络的第一个矩阵的权重(图 1)。

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

图 1:两个有区别的模型,无(上)和有辅助网络(下)。由作者绘制。注意辅助网络的嵌入维数是 10K(解释如下)。

在图 2 中可以看到该架构的详细描述:在每个完全连接的层之前,需要一个批规范,后面跟随着一个丢弃层。

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

图 2:内部网络架构

实施

我在 Pytorch 中从头开始写了这部作品的全部代码,它可以在公共 GitHub 资源库中找到,命名为“人类基因组”。以下是我认为与本论坛最相关的一些要点。

  1. 管理数据结构

为了获得客观的结果,我们生成五个折叠,每个实验一个,最后计算统计变量。

  • 分裂和洗牌

我们将 3.5K 样本分为训练(60%)、验证(20%)和测试(20%)。像往常一样,我们随机打乱数据并对值进行归一化:

**mu = x.mean(axis=0)
sigma = x.std(axis=0)
train[0] = (train[0] — mu[None, :]) / sigma[None, :]
valid[0] = (valid[0] — mu[None, :]) / sigma[None, :]
test[0] = (test[0] — mu[None, :]) / sigma[None, :]**

2。降维

生成嵌入矩阵分两步进行:第一步通过bincount() 生成每类基因型的直方图,第二步归一化该直方图。结果是维数减少了大约十个数量级。

**for i in range(n_features):
    if i % 5000 == 0:
        print("processing snp no: ", i)
    for j in range(n_targets):
        # generate for each snp , a histogram of four bins, one for each allel's option
        embed[i, j*n_genotypes: j*n_genotypes + n_genotypes] += \
            np.bincount(genome[i, labels == j].astype('int32'), minlength=n_genotypes)# normalizing the result for each class
        embed[i, j*n_genotypes: j*n_genotypes + n_genotypes] /= \
            embed[i, j*n_genotypes: j*n_genotypes + n_genotypes].sum()**

以下是特定 SNP 的每个类别的直方图示例:

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

特定 SNP 的标准化每类直方图

3。连接网络

两个网络(辅助网络和判别网络)都有独立的计算图,没有以任何方式链接。包含损失的区别网络的计算图不具有关于损失和嵌入张量之间的依赖性的信息。一种解决方案可以是用判别网的梯度值手动设置嵌入张量的梯度值,并在嵌入网上调用 torch . autograded . backward(),因为在嵌入网的计算图中,张量之间的依赖关系是已知的。

训练循环是:

  • 嵌入网中的正向传球
  • 设置有嵌入值的判别网络中第一个隐层的权重
  • 椎间盘网中的向前传球
  • 嵌入网和区别网中的后向
  • 更新参数

判别模型的第一个隐藏层中,我们用辅助网络(即嵌入层)的输出初始化其 3000 万个权重

**with torch.no_grad():
    self.hidden_1.weight.copy_(embedding)**

前进传球:

**embedding = emb_model(feat_emb) *# forward pass in embedding net*discrim_model.hidden_1.weight.data = embedding  
embedding.grad = discrim_model.hidden_1.weight.grad**

优化器应该更新两个网络的参数:

**params = list(discrim_model.parameters()) + list(emb_model.parameters())
optimizer = torch.optim.Adam(params**,** lr=learning_rate)**

向后传递:

因为我们设置了嵌入网的计算图,所以嵌入网和判别网之间的依赖关系是已知的。

**loss.backward(retain_graph=True) *# compute the gradient of the weights of the hidden layer in the embedding net* 
torch.autograd.backward(emb**,** emb.grad) # *backpropagation in the embedding net***

4。培训课程

丹尼尔·戈多伊在他的博客中解释了培训过程,我想根据我们与小批量的工作扩大他的工作范围。

  • 迷你批次和时代

函数:loss_fn(y**,** yhat)返回输入 y 中每个元素与目标 yhat 之间的均方误差(平方 L2 范数)。因为我们想要计算损失,我们需要将该值乘以批次大小,然后汇总每个小批次的所有返回值。

**train_loss += loss * batch_size**

最后,每个时期包含来自最后部分的累积值。因此,为了得到损失,我们需要除以该循环中的小批量数量。

**test_loss = test_loss / len(test_minibatches)**

我强烈建议您使用 提前停止 ,其基本原理是根据验证损失自动决定何时停止训练并保存最佳的最后模型结果。

框架

以下是一些我觉得有用(而且免费)的酷工具:

  • 神经网络库

**我必须提到使用 Pytorch 作为最好的神经网络库的好处,从我的经验来看,与许多其他人相比,它在许多方面都是最好的。论文: “深度学习即服务框架的比较测量研究” 对框架进行了实证分析: TensorFlow、Caffe、Torch、Theano

  • 云上培训

您将受益于在云上训练您的模型并节省时间。 Ashwin De Silva 在他的博客中描述了你如何在本地工作,提交并推送至你的 GitHub 库,在上提交并运行你的培训。在我看来,花时间和精力用不同的参数来编写一些测试是值得的,比如隐藏单元的数量、丢弃值等等。

结果

回顾过去,我在分析结果的过程中经历了数据科学家中的一些已知困难,并发现与您分享,为您提供开发此类网络的动态行为的真实证据非常重要。在调查您的网络性能时,我发现以下言论是主要特征:

  • 失败

让我们从损失函数开始:这是网络性能的"面包和黄油",随着时间的推移呈指数下降。此外,很好地概括了的模型保持了类似于训练损失的验证损失。原因很简单:模型在处理看不见的数据时会返回更高的损失值。如果你遇到不同的情况,你的模型很可能是过度拟合过度拟合的解决方案可以是以下的一种或组合:首先是降低隐藏层的单元或移除层以减少自由参数的数量。正如我们上面讨论的,我们的改进的网络以及辅助的网络,为了这个问题前来救援。其他可能的解决方案是增加下降值或正则化Mazid Osseni ,在他的博客中,解释了不同类型的正则化方法和实现。图 3 显示了在处理所谓的 过拟合 问题之前(左图)和之后(右图)我的网络的更简单版本的损失函数。

我的解决方案是降低隐藏单元的大小(从 100 到 50 个单元)和增加第一层的下降值(从 0.5 到 0.8)。

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

图 3:没有(左)和有(右)辅助网络时的损失函数(橙色表示训练,蓝色表示验证)

  • 准确(性)

在每个体系结构中计算测试精度。令人惊讶的是,似乎克服过拟合或减少自由参数的数量并不能保证更高的精度。图 4 显示了三种架构的测试精度:请注意,尽管存在过拟合问题,但精度更高。

这种模型的第一层的自由参数的数量大约是特征(SNP)的数量×第一层的数量(~ 300kx100)。现在,我们使用一个辅助网络来预测那 300kx100 个自由参数。这个辅助网络将特征嵌入作为输入,这是每个特征 SNP 在患者中取值的向量的一些任意变换。问题是这种嵌入看起来像什么。如果我们遵循本文中考虑的嵌入,我们将对每类直方图进行 4x26 维嵌入,x 100 是第一层的数字单元。

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

图 4:测试精度(批量:64)和第一层的自由参数个数。

  • 批量大小

测试不同批量的性能是一项有趣的任务。沈世爱,在他的博客中,调查了批量大小对训练动态的影响。根据总的训练时间,可能因为数据的多样性,批量大小与训练时间成反比(图 6)。出于同样的原因,损耗与批量成正比(图 5)。

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

图 5:损失函数——不同批量的训练和验证(虚线)

  • 培训时间

图 6 清楚地示出了在训练时间方面使用不同批量大小的行为,两种架构具有相同的效果:更大的批量大小在统计上更有效,但是不能确保通用性。阅读论文: “训练更长,泛化更好:缩小神经网络大批量训练中的泛化差距” 了解更多关于泛化现象以及使用大批量保持训练时间完整的同时提高泛化性能的方法。

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

图 6:不同批量的总训练时间

注意改变架构对训练时间的影响(图 7)。在 1500 万个自由参数的情况下,训练时间明显低于辅助网络。

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

图 7:三种架构的纪元时间(批量:64)

  • 替代机器学习方法

我还将改进模型的性能与决策树方法进行了比较,特别是数据科学领域常用的光梯度增强机器。然而,在错误分类错误方面,性能超出了我们的极限(更多细节请参见附录)。

讨论

哪个是最好的型号?(一千美元问题)

在这篇博客中,我描述了两个主要网络:有和没有辅助网络,以及一个具有改进参数的附加网络。参数预测网络的好处是,当输入是非常高维度时,如在遗传序列中,它大大减少了模型第一层中自由参数的数量。

我展示了改变基本网络的参数如何在过度拟合方面产生更好的泛化能力。我在公开可用的 1000 个基因组数据集上验证了这些网络的方法,解决了基于 SNP 数据的祖先预测任务。这项工作证明了神经网络模型在处理样本数量与其高维度不匹配的任务方面的潜力,如 DNA 测序。

鉴于祖先预测任务中所达到的高准确度,我相信神经网络技术可以改进遗传数据分析中的标准实践。我希望这些技术能让我们解决更具挑战性的基因关联研究。

感谢

感谢卡米尔·罗什福尔-布朗热(蒙特利尔大学)在实施过程中给了我一些很好的建议。

对于那些想知道我有哪台计算机的人:我想说一些关于我的 MacBook Pro 的好话,16 GB 的内存,英特尔酷睿 i7 让我能够完成如此惊人的任务,给我留下了那些令人满意的培训时间(见结果部分),以及整个“计算机实验室”的体验(在冠状病毒*关闭期间在家工作)。*

附录

使用决策树的结果

除了我在这篇博客中强调的神经网络方法,我想提一下我使用梯度提升决策树 s 的体验结果。可以在这个 GitHub 资源库中找到实现。该算法的参数是:

**params = {
'task': 'train',
'boosting_type': 'gbdt',
'num_class': 26,
'objective': 'multiclass',
'metric': 'multi_logloss',
'num_threads': 36,
'zero_as_missing': True,
'verbose': 1
}**

结果表明,决策树的分类误差较高,解释原因超出了博客的范围。

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

图 8:使用决策树和神经网络的误差比较

关闭

亲爱的读者,感谢你阅读这篇博客;你的任何想法都将非常感谢;请随时给我发邮件(miritrope@gmail.com)或 Linkedin

弥合纸质地图和技术之间的差距

原文:https://towardsdatascience.com/bridging-the-gap-between-paper-maps-and-technology-363a19c2aa50?source=collection_archive---------55-----------------------

用现代网络和移动框架为学习地理的旧方法注入新的活力

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

为什么 Mapcaso

本质上,我喜欢地理。在过去的几年里,我一直在努力寻找一种方法,将老派的展开和使用地图的触觉乐趣带到电子时代。在纸质地图上画出旅行计划,或者标出路线,或者只是在风景中寻找图案,都会带来某种满足感。这个概念始于我想帮助孩子们学习地理,并通过在地图上画画来获得一点乐趣。我记得小时候,老师给了我们一张地图的轮廓,并让我们用颜色标出该国哪些地方有铁、棉花等资源。被生产出来。这对我的空间思考能力有很大的影响。

几经周折后,我开发了一个应用程序,将画画的欲望与我们最近获得的缩放和平移的本能(以及将表情符号应用于一切事物)结合起来😂). Mapcaso 是一个基于地图的学习平台,面向所有年龄段的孩子。它帮助孩子们通过在地图上涂鸦来学习地理和探索世界。成年人也可以玩得很开心,参加小测验,标记旅行计划,徒步旅行路线,或其他一百万的事情。

客户端应用、框架和库

我首先构建了一个客户端 SPA 应用程序。我选择的框架是 VueJS 。我真的很喜欢它快速构建原型的能力,我知道与其他 SPA 框架如 AngularReactJS 相比,它在开发人员生态系统和支持方面享有很高的声誉。对于地图框架,我知道我需要一个清晰的底图,具有良好的细节和熟悉感,这促使我选择了谷歌地图。我想要先进的绘图工具和更灵活的地图库,允许添加插件和其他图层类型。我选择带着小叶子跑。我还开发了 web 应用 responsive(这将在以后带来显著的回报),并使用了谷歌的材料设计框架和指南,使其易于为各种受众和设备所用。

空间数据库

有各种各样的数据库支持空间功能,如关系空间中的 OracleSQL ServerPostgreSQL 。Cassandra 、 CouchDB 和其他一些 NoSQL 数据库选项也可以,但是我决定使用 MongoDB 。我也不想花费大量时间来托管和准备扩展我的数据库基础架构。 mLab 似乎是自然的选择:它是 MongoDB 的数据库即服务平台。此外,MongoDB 与 GeoJSON(我用来存储和提供空间数据的格式)配合得很好。

服务器 API

在我用过的众多服务器端编程语言中,C#。Net 有严格的、强类型的支持,这在您编写可能被各种实体使用的强大 API 代码时非常有用。我唯一不喜欢的是。Net 应用程序过去需要在 Windows 服务器上运行。但值得庆幸的是,微软在过去几年里在拥抱 Linux 方面取得了惊人的进步,并推出了。Net Core 支持在 Windows 和 Linux 服务器上托管。这使得它成为开发 Mapcaso 的 API 的最佳选择。我使用亚马逊的 S3 服务来托管静态图片和其他静态资产。我还需要任务调度来管理发送用户简讯、运行数据库维护等等。为此,我依赖于 T21 自动气象站。

部署和托管

容器化使得跨不同环境的部署变得非常容易,并提供了应用程序良好的稳定性和可用性。Docker 和 Kubernetes 是最受欢迎的两个。但是 Visual Studio 有内置的 Docker 支持,所以我使用了 Docker 容器。最后,我在 Docker 容器中部署了我的 web 应用程序和 API,并通过亚马逊的 ECS 托管它们。整个过程帮助我了解了很多关于 DevOps 的知识,我非常尊重那些夜以继日保持应用程序平稳运行的工程师。

混合移动应用

在我有了最低可行产品后,我想转向移动。我是一个开发团队:所以构建一次并使用相同的代码库来部署移动应用程序是有意义的。幸运的是,我已经开发了我的 web 应用程序,可以很好地与桌面、平板电脑和各种手机屏幕兼容。我使用了 Cordova,这是一个用 HTML、CSS&JS 构建移动应用的包装器。我用 Cordova 包装了我的 VueJS 客户端项目,经过一些 Android 和 iOS 构建的努力,我能够成功地构建两个平台。然后我注册了谷歌和苹果的开发者项目,并在他们的应用商店上发布了 Mapcaso 应用。

结束语

构建和维护这个应用程序对我来说是一次很好的学习经历,我觉得这个应用程序的功能将成为广大受众传统教育的补充。尤其是现在,当许多孩子远程上课和在家学习时,我认为 Mapcaso 可以成为一种有趣和免费的方式,创造性地吸引您的孩子。虽然您可以保持内容的私密性,但您也可以通过在平台和社交媒体上创建和共享涂鸦和新的测验内容来回馈 Mapcaso 社区:帮助他人更多地了解您的国家、州或我们的世界!

让我们不要忘记,即使在这些艰难的时刻,这个世界也是一个巨大而神奇的地方。我们可以让我们的思想在虚拟的世界中漫游,变得有创造力并在线联系!

谷歌 Play 商店获得免费的 Android 应用程序

苹果商店下载获得免费的 iOS 应用程序

在脚本模式下,将您的 TensorFlow 培训带到 AWS Sagemaker

原文:https://towardsdatascience.com/bring-your-tensorflow-training-to-aws-sagemaker-with-script-mode-aba9e73aa36b?source=collection_archive---------37-----------------------

使用 Sagemaker 脚本模式节省深度学习计算成本!

介绍

我会尽量让这篇文章简单明了。首先,我们先从这种方法的一些利弊谈起。

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

Artem Sapegin 在 Unsplash 上拍摄的照片

优点:

  • 允许您以更低的成本运行您的培训工作!为什么?因为你可以仅仅为了编码而启动一个非常廉价的实例;然后,您可以有一个单独的 GPU 实例,它只在训练期间启动,然后在您的训练代码运行完毕后关闭。这意味着你只在模型训练中消耗 GPU 时间,而不是在你编码的时候!

CONS:

  • 任何事情都是一种交换,很少有新的优势没有新的劣势。在这种情况下,缺点是我们需要学习一些新的技能。假设你正在运行一个本地培训任务,你想把它带到 Sagemaker (也许你想在一个更大的 GPU 上运行),你想利用这个方法来降低成本,那么你将需要编写更多的代码来让这个方法工作。你可能还需要了解线路和事物是如何一起工作的。

您可以在一个代码更改较少的笔记本实例中运行您的培训,但是您的作业不会自动关闭*(因为您在笔记本实例中执行所有操作)*。所以这是一个权衡。要在笔记本实例中运行您的作业,请参见步骤 1 中的链接。

步骤 1:开始使用 Amazon Sagemaker

如果你以前从未使用过 Amazon Sagemaker 或 S3,我推荐你阅读我在 Amazon Sagemaker 上的第一篇文章,我会一步一步地向你展示如何简单地将数据加载到 S3 并运行一个笔记本实例。你可以在这里找到文章的链接

步骤 2:启动一个廉价的笔记本实例。

当你遵循第一步的文章,你将会做一件不同的事情。我们将启动一个廉价的 CPU 实例,例如类似于 ml.t3.medium 的东西,而不是用 GPU 启动一个笔记本实例。

[## 亚马逊 SageMaker 定价-亚马逊网络服务(AWS)

有了亚马逊 SageMaker,你只需为你使用的东西付费。构建、培训和部署 ML 模型的费用由…

aws.amazon.com](https://aws.amazon.com/sagemaker/pricing/)

第 3 步:创建一个培训脚本,打开一个新的笔记本并运行您的作业。

一旦运行了一个廉价的笔记本实例,并且访问了 Jupyter,您将创建一个新的 python 脚本并打开一个新的 Jupyter 笔记本。

  1. 训练脚本-这个 python 文件是您将拥有训练代码的地方。
  2. 朱庇特笔记本——这将是我们的训练指挥官。这个笔记本是要告诉 Sagemaker 我们的训练代码在哪里,我们的训练数据在哪里,模型训练要什么样的机器。

朱庇特笔记本代码

这个笔记本可以很短,这取决于你想让它有多复杂。同样,这个笔记本将作为我们的训练指挥官。我在 GitHub 上有代码,你可以在这里查看。在这篇文章中,我将强调一些基础知识。

首先,我们需要从 SAGEMAKER 导入 TensorFlow。这是非常不同的,因为我们不是导入普通的 TensorFlow,而是导入一个允许我们启动 TensorFlow 容器进行训练的对象(即云中包含 TensorFlow 的容器)。

**from** **sagemaker.tensorflow** **import** TensorFlow

接下来是代码的核心。这是我们为培训工作指定一切的地方。

参数入口点指向我们的训练脚本。在这种情况下,我的训练脚本名为 jigsaw_train1_aws2.py ,位于我的训练笔记本的工作目录中。

参数 train_instance_type 接受一个字符串,该字符串标识我们想要训练什么类型的实例。在本例中,我指定了一个包含 GPU 的 ml.p2.xlarge 实例。

参数 output_path 表示我希望我的所有输出被转储到哪里。我指着我在 S3 的一个地点。(这将在我们的培训脚本中再次出现)

参数 train_instance_count 指定我们需要多少训练实例。在这种情况下,我只需要 1 ,因为我们没有使用分布式代码,例如 Horovod。

参数 framework_version 指定我们想要 TensorFlow 的哪个版本。(注意,Sagemaker 可能不支持 TensorFlow 的最新版本,所以请注意您指定的版本,并且不要太新;或者如果是,那就支持)

参数 script_mode 接受一个布尔值,在本例中为 True ,因为我们正在提供我们的训练代码。

estimator = TensorFlow(entry_point='jigsaw_train1_aws2.py',
                       train_instance_type='ml.p2.xlarge',
                       output_path="s3://jigsaw-toxic-mjy-output",
                       train_instance_count=1,
                       role=sagemaker.get_execution_role(), 
                       framework_version='1.11.0',
                       py_version='py3',
                       script_mode=**True**)

然后,如果我们想要提交我们的培训作业,我们只需要运行估算器。作为估算器的输入,我已经包含了一个关键字为“*data”*的字典,对应的值是一个包含我的数据存储在其中的 S3 位置的字符串。

data_s3 = 's3://jigsaw-toxic-mjy/'
inputs = {'data':data_s3}
estimator.fit(inputs)

在我们运行这个之前,我们需要确保我们的训练脚本已经准备好了。让我们快速回顾一下我们的培训脚本。

培训脚本代码

你可以在 GitHub 这里阅读我的完整训练脚本代码示例。我不打算回顾这篇文章中的所有内容,只回顾要点。

首先,我们需要能够访问我们的数据。我们使用 argparse 来获取我们在 estimator.fit(inputs) 期间传递的数据目录。我们可以将数据目录与我们在 S3 获得的训练数据的名称连接起来。一旦我们有了这个字符串,我们就可以像往常一样使用 pandas 来读取我们的数据。

import argparse
import pandas as pd
import osparser = argparse.ArgumentParser()parser.add_argument('--data', type=str, default=os.environ.get('SM_CHANNEL_DATA'))args, _ = parser.parse_known_args()data_dir = args.datadf = pd.read_csv(os.path.join(data_dir, 'train.csv'))

接下来,我们可以像平常一样运行我们的训练代码了!

最后,如果我们想要保存任何信息,我们需要将它保存到 TensorFlow 容器知道的特定目录中。那个位置是 /opt/ml/model/ 。保存到这个目录的任何东西,都将被保存到我们在 Jupyter 代码中指定的输出路径。

data_location = “/opt/ml/model/submission.csv” submission.to_csv(data_location, index=False)

结束了!

就是这样!一旦您准备好培训脚本,您就可以从头到尾运行您的 Jupyter 笔记本,并观看您的培训工作开始!

再说一次,当你完成后,我会删除一切!这包括你的 S3 桶,你的实例,一切;因为如果你把所有这些工作都放在 AWS 上,即使你不再运行任何东西,也要花钱!

你可以在 GitHub 这里找到我自己的脚本模式培训工作的例子。这个 repo 包含我的笔记本实例中的代码,因此,它是我的笔记本实例的快照。希望人们发现这是有益和快乐的学习!😄

带来深度神经网络杀死尖塔

原文:https://towardsdatascience.com/bringing-deep-neural-networks-to-slay-the-spire-a2971d5a5115?source=collection_archive---------13-----------------------

内部 AI

用 Keras 和 TensorFlow 预测战斗结果和评估卡片

斩杀尖塔是我最喜欢的视频游戏之一,结合了盗贼般的地牢爬虫和甲板建筑的元素。刚刚在大学最后一年完成了一门深度学习课程,我认为 Slay the Spire 将是我第一个机器学习项目的一个很好的平台。

甲板建造是一个很难解决的问题

选择将哪些牌添加到你的牌组中是《杀死塔尖》中最重要的战略决策之一。玩家需要添加好牌,移除坏牌,升级重要牌,以提高他们的牌组,并在一次运行中击败越来越难对付的敌人和老板。在不同的情况下决定最好的牌加入你的牌组是非常困难的,世界上最好的玩家仍然一直在努力知道什么是正确的选择。

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

各种敌人在斩杀尖塔。图片来源:斩杀尖塔不和

为了进一步增加评估哪张牌更适合加入你的牌组的问题,不同的牌对不同的敌人表现更好。通常情况下,攻击所有敌人的牌在与多个敌人的战斗中比与单个敌人的战斗中更好。此外,在整个游戏过程中,一副牌中的牌相对于其他牌的强度是变化的。例如,平庸的攻击卡通常是玩家在游戏早期艰苦战斗中的主要伤害来源,因此,相当有价值。然而,当玩家获得更好的伤害源时,这些相同的牌相对于玩家牌组中的其他牌要差得多。

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

可玩角色:铁甲,沉默,叛变,守望者。图片来源:斩杀尖塔不和

每个可玩的角色都有一套不同的 75 张独特的卡片,这些卡片可以以多种方式组合,创造出各种各样的牌组和玩法。如果玩家将一张牌添加到他们的牌组中,根据战斗中减少的平均伤害来评估这张牌,是一种相对于这些牌组创建牌组的公正方法。向玩家提供这个指标有助于他们在每个决策节点做出最佳选择。

介绍 Slay-I

Slay-I 是在 Steam Workshop 上提供的一个 mod,它可以预测你在 Slay the Spire 的战斗中会受到多少伤害,并根据战斗中减少的平均伤害来评估添加、升级和移除牌。这包括战后卡片选择,玩家可以从 3 张卡片中选择 1 张加入他们的卡片组,在营火和活动中升级卡片,在商店和活动中移除卡片。

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

预测这场战斗中受到的伤害与实际受到的伤害。作者图片

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

评估向牌组中添加一张新牌。作者图片

高级概述

Slay-I 的核心是一个模型,它根据玩家的卡片、玩家的遗物、玩家正在战斗的敌人以及其他一些特征来预测战斗中受到的伤害。接下来,我将解释这个模型如何用于评估卡片。

在训练和部署 Slay-I 模型时使用了三个主要组件:

  1. 将运行历史文件转化为训练样本的 Python 脚本( GitHub repo
  2. Google Colab 上的 Python 脚本,使用 Keras 和 TensorFlow 建立和训练神经网络( Colab 笔记本)
  3. Java mod 运行训练有素的模型,斩杀 Spire 玩家可以下载并运行他们的游戏( Steam Link )

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

作者的形象

创建培训示例

任何机器学习项目中最不性感的部分几乎总是数据预处理。但这很重要!

实验了运行历史文件的两个不同的数据集。第一个数据集来自于 Jorbs ,一个 YouTuber 和 Twitch streamer,被广泛认为是最好的 Slay the Spire 玩家之一。第二组数据来自 Spire Logs 网站,玩家可以上传他们的跑步数据并查看分析。

运行历史文件具有类似事件的格式:

// Example Run History File
{
  "damage_taken":[
    {"damage":7,"enemies":"2 Louse","floor":1,"turns":2},
    ...
  ],
  "campfire_choices":[
    {"data": "Combust", "floor": 6, "key": "SMITH"},
    ...
  ],
  "card_choices":[
    {"picked": "Clothesline", "floor":1, ...},
    ...
  ],
  "event_choices":[
    {"cards_removed":["Strike_R"], "floor": 22, ...},
    ...
  ],
  "items_purged":["Pain", ...]
  ...
}

单个训练样本是一轮比赛中一场比赛的数据。这些数据包括玩家牌组中的牌、玩家的遗物、玩家正在战斗的敌人以及其他特征。通过遍历运行历史文件的类似事件的格式来逐层重建运行,从而创建训练样本。

// Training sample
{
    "cards": [
        "Strike_R",
        "Strike_R",
        "Defend_R",
        "Defend_R",
        "Clothesline",
        "Iron Wave",
        "True Grit",
        ...
    ],
    "relics": [
        "Burning Blood",
        "Pen Nib",
        ...
    ],
    "max_hp": 82,
    "entering_hp": 82,
    "ascension": 20,
    "enemies": "Lots of Slimes",
    "potion_used": false,
    "damage_taken": 14 // Y-value used in training
}

经过处理后,Jorbs 数据集产生了 2 000 个训练样本,Spire Logs 数据集产生了 325 000 个训练样本。

编码输入

现在的问题是,如何对训练样本进行编码,以传入神经网络。max_hpentering_hpascensionpotion_used已经是数字(或布尔)。enemies是一个热编码。

使用改进的 one hot 方法对cardsrelics进行编码。每张牌都有一个热点编码,然后将热点向量相加,计算出每副牌中有多少张。同样的过程被用于文物。

注:升级卡被视为完全不同的卡。

# Used for cards vector and relics vector
def encode_list(list_to_encode, category):
  np_array = np.array(list_to_encode)
  encoder = OneHotEncoder(categories=[category], sparse=False)
  n_by_1 = np_array.reshape(len(np_array), 1)
  onehot_encoded = encoder.fit_transform(n_by_1)
  summed = np.sum(onehot_encoded, axis=0)
  return summed

编码后的cardsrelicsenemies和其他特征被连接成一个单一的向量以提供给模型。

np.concatenate((cards, relics, encounter, num_and_bool_data))

使用MaxAbsScaler对输入进行缩放,因此在缩放过程中不会丢失稀疏性。

max_abs_scaler = MaxAbsScaler()
X_train_maxabs = max_abs_scaler.fit_transform(x_train)
X_test_maxabs = max_abs_scaler.transform(x_test)

输出(战斗中受到的伤害)上限为-100 和+100,除以 100 可以将输出调整为-1 到 1 之间的值。

构建和训练模型

Keras 让构建深度神经网络变得轻而易举。添加脱层有助于减少过拟合。如果你想自己构建和训练模型,可以在这里找到 Google Colab 笔记本。

model = tf.keras.models.Sequential([
  tf.keras.layers.Dense(400, input_shape=(970,), activation='relu'),
  tf.keras.layers.Dropout(.2),
  tf.keras.layers.Dense(40, activation='relu'),
  tf.keras.layers.Dropout(.1),
  tf.keras.layers.Dense(1)
])model.compile(
  optimizer=keras.optimizers.RMSprop(learning_rate=.001),
  loss='mean_absolute_error'
)history = model.fit(X_train, Y_train, batch_size=32, epochs=5, validation_split=0.2)

使用平均绝对误差(MAE)作为损失函数有两个主要原因:

  1. 在数据集上,MAE 比均方误差(MSE)具有更低的验证损失。
  2. MAE 代表预测的平均误差。例如:“在这场战斗中,你将损失 7 HP +/- X HP”,其中 X 是平均绝对误差乘以 100。

评估模型

损失* 100 =平均损失误差

Jorbs 模型统计

  • 培训损失= 0.0718
  • 验证损失= 0.0767
  • 测试损耗= .0878

这意味着模型平均在战斗结果的+/- 9 HP 范围内。

Spire 日志统计

  • 培训损失= 0.0584
  • 验证损失= 0.0705
  • 测试损耗= 0.0679

这意味着模型平均在战斗结果的+/- 7 HP 范围内。

**更大的数据集有 23%更好的测试损失!**有趣的是,在 Spire Logs 数据上训练的模型,在使用 Jorbs 数据作为测试数据时(0.0758),比只在 Jorbs 数据上训练的模型(0.0878)有更好的测试损失。

关于统计的想法

  1. 由于游戏固有的随机性(有时称为 RNG ),多次使用相同的卡片和遗物进行相同的战斗可能会有许多不同的结果。这使得数据本身就有噪声,模型需要大量数据来弥补噪声。
  2. 对于 Jorbs 模型,没有足够的数据(970 个参数只有 2000 个训练样本)来弥补数据中的噪音。
  3. 根据 Jorbs 数据训练的模型预测的值非常接近 0。这可能是因为乔伯斯是一个非常优秀的玩家,他在很多战斗中只受到很少的伤害(或者治疗)。对于一般玩家来说,这不是一个准确的样本。

模型的后续步骤

模型有过度拟合的问题。一些可能的解决方案包括:

  1. 为卡片、遗物和敌人使用嵌入层。嵌入层可用于学习卡片之间的关系,并将卡片映射到向量。
  2. 获取更多(和多样化的)数据。

部署模型

Slay the Spire 是用 Java 8 开发的,所以在游戏中使用了 Java TensorFlow 2.x 绑定来部署训练好的模型。玩家可以下载并运行这个模型,看看这个模型如何预测他们在战斗中的表现!

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

模型预测在这场战斗中受到 5 点伤害。作者图片

评估卡片

现在我们有了一个模型,可以预测一套卡和遗物在不同的战斗中的表现,我们可以使用这些信息来评估一张卡有多好。卡牌是通过每场战斗的平均伤害来评估的,游戏中更重要的战斗(老板和精英)的权重更大。这是通过在行动中的每一场比赛中将该副牌与添加了该牌的副牌进行比较来完成的。

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

根据战斗中受到的平均伤害来评估牌。作者图片

同样的过程适用于评估移除卡和升级卡。

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

卡移除屏幕。正值表示要移除的牌是好的。作者图片

承认

感谢 Spire Logs 和 Jorbs 提供您的数据集。同时也要对 Spire #modding 社区的不和谐大声疾呼(特别是 Gk,他帮助了 mod 的用户界面)。如果你发现了一个 bug 或者有兴趣贡献的话,项目每个部分的所有代码都在 GitHub 上。

将非技术用户引入 JupyterHub

原文:https://towardsdatascience.com/bringing-non-technical-users-into-jupyterhub-a7f9acf83571?source=collection_archive---------30-----------------------

扩展 JupyterHub,以便同事和客户可以与您的笔记本电脑的用户友好的安全版本进行交互

Jupyter notebooks 是一种交互式探索和开发数据科学模型的简单方法。 JupyterHub 是一个可以在 web 服务器上配置的独立项目,允许组织集中管理一个托管多个 Jupyter 笔记本环境的服务器,每个数据科学团队成员一个或多个。除了标准化用户开发环境和减轻个体数据科学家的维护负担,JupyterHub 还提供了一个认证框架——例如,基于企业电子邮件帐户实现单点登录访问。

总是有办法与其他团队成员共享文件系统,但 JupyterHub 通常被视为组织数据科学家实验的一种方式——非技术同事不会被邀请。也许一名数据科学家通过笔记本电脑与一名客户交谈,而他们都在看着同一个屏幕。也许有时,最有可能是不幸的是,一个非技术用户得到一个 JupyterHub 帐户,上面有在笔记本上 shift+enter 的指令,这样他们就可以自己研究结果…

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

手拿笔记本的非技术同事应接不暇……(照片由来自 PexelsPixabay 拍摄)

打开 JupyterHub

过去几年的新项目让 JupyterHub 做得更多。本文描述了如何将其他免费开源项目引入到您的 JupyterHub 中,使其成为一个有用的工具,以安全、自动化和用户友好的方式展示您的笔记本成果。

至关重要的是,如果您或您的 IT 部门拥有配置 JupyterHub 的资源,那么您只需要扩展配置就可以引入这个额外的功能。

我们努力实现的工作流程:

  • 数据科学家编写了一个 Jupyter 笔记本,可能会显示基于模型的不同输入的交互式图表
  • 当准备好分享时,他们点击几个按钮,旋转他们的笔记本的独立克隆,以用户友好的仪表板风格运行(即,查看者看不到代码,或者需要按 shift+enter!)
  • 任何可以访问 JupyterHub 的非技术用户(例如通过他们的公司 Google 电子邮件)都可以安全地查看仪表板并与之交互
  • 同时,数据科学家可以不受阻碍地继续使用他们的原始笔记本

为 JupyterHub 带来这种魔力的关键技术是 Voila ,这是 Jupyter 服务器的用户友好版本,它隐藏了代码单元,并将笔记本作为 web 应用程序运行。

其他一些默默无闻的开源项目也有助于实现这一点,所有的胶水都被一个新的叫做仪表盘的 JupyterHub 扩展混合在一起。

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

JupyterHub 主页上的标志

配置 JupyterHub

有三种主要方法可以为您的组织在服务器上安装 JupyerHub:

  • 在 Kubernetes 集群上,通过 Zero-to-JupyterHub 提供的方法—这种重量级的方法目前还不能支持这里描述的仪表板设置。
  • 通过最小的 JupyterHub(TLJH)——一种在单台机器上设置和配置 JupyterHub 的标准化方法。这有一个很好的命令行工具,可以轻松地设置 HTTPS 证书和其他配置,但对您的服务器有一些重要的基本要求。
  • 自己在一台服务器上安装。让 JupyterHub 在任何基于 Linux 的服务器上运行相对容易,但是你必须安装你自己的 HTTPS 证书,并找到一种方法来监督 JupyterHub 服务器进程。

我们将主要假设您正在使用 TLJH,但是您自己的手动安装步骤将是相似的。

TLJH 的初始安装和设置在 TLJH 的安装文档中针对各种云提供商(或您自己的服务器)进行了描述。

码头工人的重要性

Docker 是一项真正的革命性技术,它允许我们将每个 Jupyter 笔记本服务器作为一个独立的(轻量级)虚拟机来运行,这样我们就不需要担心 JupyterHub 进程本身或我们的多个用户的服务器相互冲突。

这种虚拟化可以在没有 Docker 的情况下建立——事实上,默认的 TLJH 安装在服务器上本地构建了精心构建的进程隔离。从 Dashboard 的角度来看,Docker 的真正天才之处是能够轻松地指示 Docker 拍摄 Jupyter 环境的快照,以便我们可以立即旋转它的新克隆,除了这一次使用用户友好的 Voila 前端而不是常规的 Jupyter 界面来启动它。

我们需要指示 JupyterHub 使用“DockerSpawner”启动新的独立 Jupyter 服务器。

如果你的 TLJH 安装还没有运行 Docker,请查看这里的说明

更新:最新版本的 ContainDS 不需要 Docker! 无对接器安装说明在此

安装容器仪表板

到目前为止,一切都给了我们一个标准的最小 JupyterHub 设置。

最后的配置步骤是安装 ContainDS 仪表板。这为 JupyterHub 添加了一个额外的“仪表板”菜单,您可以在其中创建或查看其他用户制作的仪表板。

SSH 到您的服务器,如果不在那里,运行:

sudo /opt/tljh/hub/bin/python3 -m pip install cdsdashboards

添加一个额外的配置片段,告诉 TLJH 加载仪表板片段:

sudo vi /opt/tljh/config/jupyterhub_config.d/cdsdashboards.py

将以下内容粘贴到 vi 编辑器中:

c.JupyterHub.allow_named_servers = True

from cdsdashboards.app import CDS_TEMPLATE_PATHSfrom cdsdashboards.hubextension import cds_extra_handlers

c.JupyterHub.template_paths = CDS_TEMPLATE_PATHS
c.JupyterHub.extra_handlers = cds_extra_handlersc.CDSDashboardsConfig.builder_class = 'cdsdashboards.builder.dockerbuilder.DockerBuilder'

(如果不熟悉 vi 文本编辑器:启动时,按‘I’进入插入模式;粘贴文本;按 escape 键,然后键入’:wq '和 enter 键来编写文件并退出。)

要试用并检查您的 JupyterHub 是否正常工作:

sudo tljh-config reload

从 web 浏览器访问您的 JupyterHub 安装,并看到它仍然像预期的那样运行。

构建仪表板

在您的 JupyterHub 中,点击“我的服务器”以访问您的 Jupyter 笔记本电脑服务器。创建你想要制作和分享的任何原型或可视化。为了跟随这个教程,你可以在这里找到一个简单的例子粘贴到你的笔记本单元格或者只是上传为一个 ipynb 文件。

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

我们在朱庇特笔记本上的代码

当您准备好分享时,点击返回“控制面板”,然后进入新的“仪表板”菜单:

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

空仪表板屏幕

点击“新仪表板”并填写屏幕:

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

新的仪表板屏幕

最重要的事情是输入一个名称,然后选择您正在工作的 Jupyter 服务器克隆到仪表板中。在这种情况下,只有我们的“默认服务器”可供选择。

您将看到 ContainDS 构建了新的仪表板。准备就绪后,您可以点击它,查看您闪亮的全新用户友好型仪表盘:

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

瞧,笔记本的版本

让你的非技术同事参与进来

创建仪表板的过程很简单,但是当您的非技术同事或客户亲眼看到您的工作时,这种设置的真正威力会大放异彩——而不是让他们阅读您的代码!

当另一个用户登录到 JupyterHub 并点击仪表板菜单时,他们将能够看到其他用户创建的所有仪表板。查看“来自其他人的仪表板”下的“图表”仪表板:

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

另一个用户访问我们的仪表板

其他用户可以点击进入仪表板,并以用户友好的形式与它进行交互,这一切都是安全的,并且不必在您的代码中按 shift+enter 键,甚至看不到任何内容!

这一切是如何运作的

在幕后,ContainDS Dashboards 使用 Docker 将原始的 Jupyter 服务器克隆为“映像”。然后,它启动了一个基于该图像的新服务器,只不过这次是通过 Voila 的服务器而不是常规的 Jupyter 服务器来运行。

无论哪个用户拥有仪表板,都可以在其主页上看到服务器的仪表板版本:

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

显示仪表板服务器的扩展主页

如果他们停止和/或删除它,这很好。如果任何其他用户尝试再次查看仪表板,将会启动一个新的仪表板服务器。

就 JupyterHub 而言,dashboard 服务器只是另一个 Jupyter 服务器,它现在独立于您原来的 Jupyter 服务器运行。这意味着您可以返回并对笔记本电脑进行更改,而不会影响仪表板。而且仪表盘的用户不会影响你原来的笔记本。

ContainDS Dashboards 配置中的选项允许您隐藏 dashboard 服务器列表,因此您的用户无需担心它们。

结论

这里的一切都建立在成熟的技术之上——最著名的是 Jupyter 笔记本和 JupyterHub。这意味着您或您的 IT 部门可以轻松访问这里描述的基础架构的核心。

最近的一些发展使得这个仪表板解决方案成为可能: Voila 本身,以及一个名为 jhsingle-native-proxy 的小项目,它提供了围绕 Voila 的 Jupyter-Hub 认证。当然,包含了仪表盘将所有东西联系在一起。

在基于项目的数据科学团队中,每个数据科学家可能最适合在他们自己的 Jupyter 环境中解决问题。通常,使用破坏性的临时流程将结果转移到 web 服务器或其他部署系统,以便非技术客户或同事可以充分欣赏笔记本电脑中演示的模型。

我希望这种生产安全可靠的笔记本“仪表板”版本的新能力将使数据科学家与非技术利益相关者的交流变得愉快和丰富。能够自动和即时地做到这一点意味着分享结果不需要等到项目的最后——然后变成一个漫长而痛苦的过程,危及结果本身的可靠性。

将可靠的数据和人工智能带到云端:与 Databricks 的 Matei Zaharia 的问答

原文:https://towardsdatascience.com/bringing-reliable-data-and-ai-to-the-cloud-a-conversation-with-databricks-matei-zaharia-25e950e96c4a?source=collection_archive---------31-----------------------

Matei Zaharia 关于人工智能、云计算和数据可靠性的采访

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

图片由陈琦烨Unsplash 上提供。

说你的公司是数据驱动的是一回事。从数据中获得有意义的见解是另一回事。

问问马泰·扎哈里亚阿帕奇火花的原创者就知道了。自 2010 年由 Matei 和加州大学伯克利分校的 AMPLab 首次发布以来,Apache Spark 已成为世界领先的开源集群计算框架之一,为数据团队提供了一种更快、更有效的方法来处理和协作大规模数据分析。

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

图片由 Matei Zaharia 提供。

凭借 Databricks ,Matei 和他的团队通过构建一个平台,帮助数据团队更有效地管理他们的管道和生成 ML 模型,将他们对可扩展、可靠数据的愿景带到了云。毕竟,正如马泰所言:“你的人工智能只取决于你输入的数据。”

我们与 Matei 坐下来讨论 Apache Spark 背后的灵感,数据工程和分析领域在过去十年中的发展,以及为什么数据可靠性是业界最关心的问题。

你在 2010 年作为加州大学伯克利分校的一名研究人员发布了 Spark,从那时起,它已经成为现代数据堆栈中使用最广泛的技术之一。最初是什么激发了你的团队开发这个项目?

马泰·扎哈里亚(MZ): 十年前,人们对使用大型数据集进行分析很感兴趣,但你通常必须是一名软件工程师,并具备 Java 或其他编程语言的知识才能为他们编写应用程序。在 Apache Spark 之前,有 MapReduce 和 Hadoop 作为处理和生成大数据集的开源实现,但我在伯克利的 AMPLab 的团队希望找到一种方法,使数据处理更容易被全职软件工程师以外的用户使用,如数据分析师和数据科学家。

具体来说,对于数据科学家来说,我们构建的第一个功能之一是 SQL 引擎开销,它允许用户将 SQL 与可以用另一种编程语言(如 Python)编写的函数相结合。

Apache Spark 的另一个早期目标是通过设计模块化的编程接口,让用户可以轻松地使用现有的开源库来设置大数据计算,以便用户可以轻松地在一个应用程序中组合多个库。这导致了数百个为 Spark 构建的开源包。

是什么鼓励你和你在加州大学伯克利分校的团队将你的研究项目转化为企业数据团队的解决方案?

在研究项目的早期,有一些技术公司对使用 Apache Spark 感兴趣,例如 Yahoo!,该公司雇佣了当时使用 Hadoop 的最大团队之一,以及几家初创公司。因此,我们很高兴看到我们是否能够支持他们的需求,并通过这种合作,产生新的研究问题的想法,因为它仍然是一个如此新的空间。

因此,我们在早期花了很多时间让 Apache Spark 对企业可用。然后,在 2013 年,这个项目的核心研究团队正在完成我们的博士学位,我们希望继续研究这项技术。我们认为,以可持续和易于使用的方式将它提供给许多人的最佳方式是通过云,于是 Databricks 诞生了。

七年后,你的预见完全正确。2020 年,越来越多的数据团队将采用云来构建他们的数据平台。企业数据团队在设计他们的数据堆栈时应该记住什么?

首先,考虑你希望谁访问你的数据平台是很重要的。谁将访问 it 中产生的东西,围绕这一点,您需要什么样的治理工具?如果您没有权限实际使用数据,或者如果您不得不要求另一个团队编写数据工程作业,而不仅仅是运行一个简单的 SQL 命令,那么您就不能轻松地访问现有数据或与公司的其他利益相关者共享结果,这就会成为一个问题。

另一个问题是:您的数据可用性目标是什么?无论你只是构建一个简单的报告或机器学习模型,还是介于两者之间的任何东西,你都希望它们随着时间的推移不断更新。理想情况下,您不会花费大量时间来解决应用程序的停机问题。

因此,在设计平台时,评估满足公司数据用户的数据可用性需求所需的特性是非常重要的。这就是 数据可观察性 的用武之地。

过去,你说过 “人工智能只和你输入的数据一样好。” 我完全同意。你能详细说明一下吗?

我甚至可以说,人工智能或机器学习真的应该被称为类似“数据外推”的东西,因为这基本上是机器学习算法的定义:以某种方式从已知数据中进行归纳,通常使用某种统计模型。所以当你这么说的时候,我想很明显你输入的数据是最重要的元素,对吗?

如今,越来越多的人工智能研究被发表,强调运行这个或那个新模型需要多么少的代码。如果你为训练模型所做的一切都是标准的,那么这意味着你放入这个模型的数据是非常重要的。为此,需要考虑数据准确性和可靠性的几个重要方面。

例如,你输入的数据是正确的吗?它可能是不正确的,因为你收集它的方式,也可能是因为软件中的错误。问题是,当你生产,你知道,1tb 的数据或 1pb 的数据放入这些培训应用程序之一时,你经常必须逐个检查所有这些数据,看它们是否有效。

同样,您输入的数据是否涵盖了足够多样的条件,或者您是否遗漏了模型需要良好运行的关键现实条件?

为此,数据团队可以采取哪些步骤来获得高度可靠的数据?

在高层次上,我见过一些不同的方法,所有这些方法都可以结合使用。其中之一很简单,只需要一个模式和对将要进入表或报告的数据类型的期望。例如,在 Databricks 平台中,我们使用的主要存储格式是一种叫做 Delta Lake 的东西,它基本上是 Apache Parquet 的一个功能更丰富的版本,在您的表上有版本控制和事务。我们还可以强制实施将哪种数据放入表中的模式。

我见过的另一种数据质量方法是运行作业,在数据产生后检查数据并发出警报。理想情况下,您需要一个非常容易生成自定义检查的界面,并且您可以集中查看正在发生的事情,就像您的数据健康状况的单一窗格。

我要注意的最后一点与你如何设计你的数据管道有关。基本上,数据复制、ETL 和传输步骤越少,您的系统就越有可能可靠,因为出错的地方就越少。例如,您可以获取一个 Delta Lake 表,将其视为一个流,并拥有列出了更改的作业,这样您就不需要将更改复制到消息总线中。您还可以使用 Tableau 这样的商业智能工具直接查询这些表,这样就不必将数据复制到其他系统中进行可视化和报告。

数据可靠性是一个发展非常迅速的领域,我知道蒙特卡洛在这里做了很多有趣的事情。

当你联合创立 Databricks 的时候,云技术还处于萌芽状态。现在,许多最好的数据公司都在构建云。是什么导致了现代基于云的数据堆栈的兴起?

我认为这是一个时机和易于采用的问题。对于大多数企业来说,云使得大规模采用技术变得更加容易。有了云,您可以自己购买、安装和运行高度可靠的数据堆栈,而无需昂贵的设置和管理成本。

管理是维护数据管道最困难的部分之一,但是有了云数据仓库和数据湖,它就内置了。所以有了云服务,你买的不仅仅是一堆你必须安装在服务器上的光盘。您的管理质量直接影响到您在其上构建关键应用程序的可能性。如果你的某样东西每个周末都要停机维护,而且必须停机一周才能升级,你就不太可能想用它。

另一方面,如果你有云供应商正在管理的东西,有超高可用性的东西,那么你实际上可以构建这些更关键的应用程序。最后,在云上,供应商向客户发布更新并获得即时反馈也要快得多。

这意味着云供应商必须非常擅长在不中断工作负载的情况下实时更新一些东西,但对于用户来说,这基本上意味着您可以更快地获得更好的软件:想象一下,您现在可以访问软件,而您在未来一两年内只能从本地供应商那里获得这些软件。

这些是云产品在市场上取得成功的重要因素。

了解更多关于 马泰的研究阿帕奇 Spark、 Databricks**

有兴趣了解更多关于数据可靠性的知识吗?向 巴尔摩西 以及 蒙特卡洛 团队伸出援手。

本文由Molly Vorwerck共同撰写。

通过音乐可视化将歌曲带入生活

原文:https://towardsdatascience.com/bringing-songs-to-life-through-music-visualization-8beee9573b7b?source=collection_archive---------34-----------------------

使用 p5.js 库将低音、高音和中音能量映射到动态视觉组件

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

去年秋天,当我在哥本哈根留学的时候,我遇到了这个设计师,他正在用 Javascript 做很多很酷的可视化项目。聊了几句,我就完全被他的创作世界吸进去了。我被他在 Instagram 上分享音乐可视化的帖子迷住了,我最终掉进了一个兔子洞,这让我发现了许多其他做类似工作的创意天才。我给自己做了一个记录,总有一天我会回到这个灵感的源泉,用我自己的项目来弄脏我的手。

在我们开始之前,让我先澄清一下我在创意公寓里的挣扎。我没有天马行空的想象力——我的艺术品味很大程度上局限于那些看起来令人满意、或许有点催眠的几何设计。因此,毫无疑问,弄清楚从哪里开始是这个项目最困难的部分。

奇怪的是,我这个项目的主要灵感来自电视节目这就是我们。无可否认,这是一部相当感人的戏剧——请不要因为我看了它就对我评头论足。然而,有一件事我并不羞于承认,那就是我是悉达多·科斯拉为该剧原创配乐的超级粉丝。我认为他是一位杰出的作曲家,有时我会在晚上反复播放他的音乐来哄我入睡。我想进一步探索这些曲目,看看我是否能创造一个视觉组件,可以像音频一样舒缓。

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

悉达多·科斯拉和中的几个场景这就是我们,来源: NPR

P5.js 库

第一步是熟悉 p5 Javascript 库。p5.js 是一个专门为艺术家、设计师、教育工作者和初学者定制的库,目的是使 Javascript 更容易被希望实现不同类型的应用程序的程序员访问。

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

p5.js 主页

我仔细阅读了大量的例子,以找出如何处理音频。首先,我摆弄了一下声音频谱,看看音频被映射到某种视觉的基本例子。然后,我了解了一个名为 getEnergy() 的函数,它返回特定频率下的能量(体积)数量,或者两个频率之间的平均能量数量。此外,预定义的频率范围(“低音”、“中低音”、“中低音”和“高音”)可以传递到函数中。唯一的规定是必须首先调用 analyze() 函数,因为 getEnergy() 函数依赖于来自该函数调用的分析频率数据。

音频→视频

我的项目的频率提取代码非常简单:

var fft = new **p5**.**FFT**();
fft.**analyze**();
var bass = fft.**getEnergy**("bass");
var treble = fft.**getEnergy**("treble");
var mid = fft.**getEnergy**("mid");

将音频映射到视觉组件需要大量的角度和数学上的反复试验。最后,我使用鼠标定位来指定可视化中多边形的线段数和半径。

pieces = **map**(mouseX, 0, width, 4, 8);
radius = **map**(mouseY, 0, height, windowHeight / 4, windowHeight/2);

然后,我为线段制作了一些贴图和缩放变量。

var map_mid = **map**(mid, 0, 255, -radius, radius);
var scale_mid = **map**(mid, 0, 255, 1, 1.5);var map_treble = **map**(treble, 0, 255, -radius, radius);
var scale_treble = **map**(treble, 0, 255, 1, 1.5);var map_bass = **map**(bass, 0, 255, -100, 800);
var scale_bass = **map**(bass, 0, 255, 0, 0.8);

最后,我编写了一个 for 循环来定义低音、中音和高音多边形环,它们将旋转到整首歌的音频频率。

这段代码的结果可以在下面的视频中看到。

附加功能

预装轨道

我选择使用这是我们原声带中的歌曲“杰克在 AA”的一个主要原因是因为我碰巧在我的电脑上有它的 MP3,可以很容易地上传到可视化中。我希望能够可视化其他歌曲,所以我实现了一个预加载的轨道功能,允许您单击数字键来切换正在播放的轨道。附加曲目选项(不包括预载为 0 号曲目的“AA 中的插孔”)包括:

  1. 我想去的地方
  2. 露天看台-狂野的心
  3. 设计师-熊猫
  4. 拉赫曼-发自内心再保险
  5. 哈利德-眩晕
  6. Shakey Graves -家族和属
  7. 蒙福之子乐团-我会等的
  8. 特拉维斯·斯科特,房间里最高的
  9. 玻璃动物,丹泽尔·库里-东京漂流

这些曲目代表了各种各样的流派。事实上,在不访问粗略的、充满病毒的、可能是非法的网站的情况下获取 MP3 文件是一个相当大的挑战。也就是说,如果你有一个. mp3,你可以选择上传自己的歌曲。wav 或者。ogg 文件。

调色板切换

可视化的着色非常简单。四种颜色的阵列用于组成调色板。四种颜色按以下顺序给出:[(背景),(低音),(中音),(高音)]。

为了允许颜色切换,我提出了总共 5 个调色板(红色、橙色、绿色、蓝色和紫色),然后添加了一个简单的按键监听器来遍历调色板。按下“Enter”键以及双击都会触发此功能。

切换播放/暂停

您可以通过点击“空格键”或点击左下角的切换按钮来暂停或播放曲目。

例子

在上面的演示中,我们看到歌曲“我想去的地方”被形象化了。这首歌有一个典型的快节奏,每当频率根据节拍变化时,多边形的频繁收缩就反映了这一点。在每一拍中按下“输入”键也是非常令人满意的,因为颜色的变化使视觉化感觉非常有活力,就像你在迪斯科舞厅或夜总会看到的一样。

玻璃动物和丹泽尔·库里的歌曲《东京漂移》是我最近最喜欢的一首歌。我的好朋友不久前把它发给了我,我不明白这种炒作是怎么回事,但每次听它,我都会更加欣赏它。我在上面的视频中录制了一段可视化片段,主要是因为这首歌的介绍很吸引人。由于在歌曲的前几秒钟没有很多音频通道同时混合在一起,每个半令人毛骨悚然的声音都与一些视觉成分直接相关。然后,在 0 点 27 分,有一个巨大的节拍下降,完全将你吸入轨道的其余部分。节拍在整首歌中相当突出,其意义体现在视频中浅蓝色所代表的每个节拍脉动的大小上。

与未来相关的愿望

  • 自动从一些音乐流媒体服务中提取新音乐,以便我(和其他人)可以访问这个可视化应用程序来聆听和体验新音乐。
  • 根据歌曲或艺术家开发更具创造性的音乐可视化,而不是几何图形。
  • 制作一个以更优雅的方式运行这些代码的移动应用程序(这个 web 应用程序中的一些组件有点简单)。
  • 建立一个持续产生音乐的 GAN。

结束语

源代码可以在这里找到:

[## sejaldua/音乐-即

使用 P5.js 库探索音乐可视化

github.com](https://github.com/sejaldua/music-viz)

这只是我第一个使用 Javascript 的音乐可视化项目。我肯定打算继续改进这个项目,我也希望转向其他有趣的应用程序和与音乐相关的开发工具。如果你想给我任何反馈或灵感,请通过 sejaldua@gmail.com 或我的网站联系我。

感谢您的阅读!

广播 PySpark 累加器

原文:https://towardsdatascience.com/broadcasting-pyspark-accumulators-343104c18c44?source=collection_archive---------43-----------------------

以及如何管理它们

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

照片由格雷戈·拉科齐Unsplash 上拍摄

在这篇文章中,我将讨论一个有趣的模式,用一个方便的广播。在进入更多细节之前,让我们回顾一下什么是火花累加器。

一种可以累加的共享变量,即有一个可交换的和相关的“加”操作。Spark 集群上的工作任务可以使用+=操作符将值添加到累加器中,但是只有驱动程序才允许使用[**value**](https://spark.apache.org/docs/2.3.1/api/python/pyspark.html#pyspark.Accumulator.value)来访问它的值。来自工人的更新自动传播到驱动程序。

来源:https://spark . Apache . org/docs/2 . 3 . 1/API/python/py spark . html # py spark。蓄能器

累加器的三大戒律

  1. 累加器只能用于交换和结合的“加法”运算。对于任何其他操作,我们必须使用自定义实现。稍后会详细介绍。
  2. 可以在工作任务上“更新”累加器,但该任务不能访问其值。
  3. 累加器可以在驱动程序上更新和访问。

几行代码抵得上千言万语

让我们看一个简单的累加器例子

在上面的示例代码中, cnt 是在全局级别上定义的。 add_items 方法将输入 x 加到 cnt 上。 add_items 方法后来应用于 global_accumulator 方法中 rdd 的每一项。这是累加器的典型用法,最后对 global_accumulator 的调用将输出 6,这是 1、2 和 3 的总和。请注意,我们需要将 cnt 定义为全局变量,否则各种方法都无法访问它,并且它将是未定义的。

那是什么问题…

现在,为了激发对广播累加器的需求,让我们将代码分成几个文件,这就是模块化代码库中的代码。

global _ accumulator _ module从另一个模块 accumulator_process 中调用 process_data 方法(代码如下)。

如果我们执行global _ accumulator _ module,那么它会失败并出现以下错误。

NameError: name ‘cnt’ is not defined

问题是 Python 中的全局变量对于一个模块来说是全局的。

Python 中的全局变量是模块的全局变量,而不是所有模块的全局变量。(与 C 不同,C 中的全局变量在所有实现文件中都是相同的,除非您显式地将其设为静态。).如果从导入的模块中需要真正的全局变量,可以在导入模块的属性中设置这些变量。

来源:https://www . tutorialspoint . com/Explain-the-visibility-of-global-variables-in-imported-modules-in-Python

那么,如何让一个全局变量在模块间可用呢?Python 医生有一些想法。

在单个程序中跨模块共享信息的规范方法是创建一个特殊的模块(通常称为 config 或 cfg)。只需在应用程序的所有模块中导入配置模块;然后,该模块就可以作为全局名称使用了。因为每个模块只有一个实例,所以对模块对象的任何更改都会在任何地方得到反映。例如:

配置文件:

x = 0*# x 配置设置的默认值*

mod.py:

导入配置
config.x = 1

main.py:

导入配置
导入模式
打印(config.x)

注意,出于同样的原因,使用模块也是实现单例设计模式的基础。

来源:https://docs.python.org/3/faq/programming.html?highlight = global # how-do-I-share-global-variables-cross-modules

虽然这不适用于 PySpark,原因是每个 worker 节点上有不同的 module 实例。因此需要累加器,因为共享变量的典型方式在 Spark 中不起作用。

广播累加器

在这种情况下, broadcast_accumulator 方法调用 accumulator_process 模块中的process _ data _ accumulator方法,累加器 acc

这里实际发生的是,我们向 worker 节点发送一个对象引用 acc 。这样我们就不必定义它为全局。

现在我将讨论累加器的两个定制:

  1. 将静态值与累加器一起广播
  2. 广播多个累加器

过滤累加器

在此示例中,FilterAccumulator 类保存项目列表。如果在过程方法中传递的项目不在项目列表中,则更新累加器 acc 。如代码所示, initcount 应该在驱动程序上执行,而进程应该在 worker 节点上执行。执行上述操作得到的值为 4,这是正确的结果。

多个累加器

在本例中,我们有两个累加器 sumnum ,分别累加项目的值和项目的数量。同样,如代码所示, init意味着应该在驱动程序上执行,而在 worker 节点上处理。虽然平均值可以使用其他本机 spark 方法获得,但这是一个如何使用单个类管理多个累加器而不将其声明为全局的示例(这在模块化代码中不起作用)。

结论

希望现在已经很清楚如何使用类和广播来管理累加器,而不是声明为全局的。我希望在将来发布如何创建非整型和浮点型的累加器,因为 Spark 允许自定义累加器。

用 Python 实现布朗运动

原文:https://towardsdatascience.com/brownian-motion-with-python-9083ebc46ff0?source=collection_archive---------4-----------------------

我们展示了如何使用简单的 Python 代码来模拟布朗运动,这是应用广泛的最著名的随机过程。

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

图片来源: Pixabay(免费商业使用)

免责声明:本文的灵感来源于 佐治亚理工学院在线分析硕士(OMSA) 项目学习资料。我很自豪能继续这个优秀的在线硕士项目。你也可以在这里查看详情。

什么是布朗运动?

物理起源和属性

B 它是由粒子与流体中快速运动的分子(由于内部热能而被激发)的随机碰撞产生的。前述流体应该处于所谓的热平衡,在那里不存在优先流动方向(与各种运输现象相反)。

发现和早期解释

布朗运动是以苏格兰植物学家罗伯特·布朗·T21 的名字命名的,他在 1827 年通过显微镜观察浸泡在水中的花粉时首次描述了这一现象。

长期以来,科学界对此并不重视。然后,在 1905 年,一个 26 岁的瑞士专利办事员通过借助热力学定律分析现象,改变了物理世界。

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

图片来源:维基百科

阿尔伯特·爱因斯坦发表了一篇开创性的论文****,其中他模拟了花粉的运动,受单个水分子的影响,并取决于液体的热能。虽然这篇论文相对来说不如他 1905 年的其他论文出名,但它是他被引用最多的出版物之一。事实上,爱因斯坦对布朗运动的解释是第一个从数学角度证明分子存在的有力证据。****

你可以阅读这篇令人愉快的文章,纪念爱因斯坦论文发表 100 周年。

作为随机过程的布朗运动

多体相互作用

多体相互作用,产生了复杂而美丽的布朗运动模式,无法通过解释分子详细运动的第一原理模型来解决。因此,只有应用于分子群体的概率宏观模型才能用来描述它。

这是布朗运动描述背后的推理主要是作为一个现代形式的纯粹随机过程。几乎所有的实际应用也采用这种方法。

维纳过程

美国数学家诺伯特·维纳首先分析了一维布朗运动的数学性质。由此产生的形式是一个实值连续时间随机过程,称为维纳过程

它是最著名的随机过程之一,具有吸引人的性质,如平稳性独立增量。因此,它在广泛的领域中发现了频繁的应用,包括纯数学和应用数学,定量金融,经济建模,量子物理,甚至进化生物学。

常见应用

布朗运动的概念和数学模型在现代数学中起着至关重要的作用,如扩散过程 。维纳过程也用于表示白噪声高斯过程的积分,该过程通常充当电气和电子工程中无处不在的噪声模型。同样的想法也适用于滤波器设计中的模型噪声和误差以及控制理论中的随机/未知力。****

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

噪声信号(来源: Pixabay )

量子物理中,借助布朗运动研究与福克-普朗克朗之万方程相关的扩散现象。它也是量子力学的严格路径积分公式形成的基础。例如,使用费曼-卡奇公式,著名的薛定谔方程的解可以用维纳过程来表示。物理宇宙学中的永恒膨胀模型,灵感来自布朗运动动力学。

金融和计量经济学建模的世界里,布朗运动拥有神话般的地位。它在几乎所有主要的金融数学理论中都占有显著的地位。特别是著名的 布莱克-斯科尔斯 期权定价模型,为此迈伦·斯克尔斯获得 1997 年诺贝尔经济学奖,就依赖于这种形式主义。

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

量化金融大量使用布朗运动(来源: Pixabay )

Python 实现

一个相当简单的等式

按照布朗运动动力学生成数据点的核心方程相当简单,

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

**其中 ***【易】*可以是一个基本的随机过程如随机游走或来自正态分布的样本。

一门Brownian

实现 的 Jupyter 笔记本可以在这里 找到。

在下面的 Python 代码中,我们用一些有用的方法定义了一个类Brownian,

  • gen_random_walk():从随机行走过程生成运动
  • gen_normal():从正态分布绘制生成运动
  • stock_price():使用所谓的‘几何布朗运动’公式来模拟股票价格
class Brownian():
    """
    A Brownian motion class constructor
    """
    def __init__(self,x0=0):
        """
        Init class
        """
        assert (type(x0)==float or type(x0)==int or x0 is None), "Expect a float or None for the initial value"

        self.x0 = float(x0)

    def gen_random_walk(self,n_step=100):
        """
        Generate motion by random walk

        Arguments:
            n_step: Number of steps

        Returns:
            A NumPy array with `n_steps` points
        """
        # Warning about the small number of steps
        if n_step < 30:
            print("WARNING! The number of steps is small. It may not generate a good stochastic process sequence!")

        w = np.ones(n_step)*self.x0

        for i in range(1,n_step):
            # Sampling from the Normal distribution with probability 1/2
            yi = np.random.choice([1,-1])
            # Weiner process
            w[i] = w[i-1]+(yi/np.sqrt(n_step))

        return w

    def gen_normal(self,n_step=100):
        """
        Generate motion by drawing from the Normal distribution

        Arguments:
            n_step: Number of steps

        Returns:
            A NumPy array with `n_steps` points
        """
        if n_step < 30:
            print("WARNING! The number of steps is small. It may not generate a good stochastic process sequence!")

        w = np.ones(n_step)*self.x0

        for i in range(1,n_step):
            # Sampling from the Normal distribution
            yi = np.random.normal()
            # Weiner process
            w[i] = w[i-1]+(yi/np.sqrt(n_step))

        return w

    def stock_price(
                    self,
                    s0=100,
                    mu=0.2,
                    sigma=0.68,
                    deltaT=52,
                    dt=0.1
                    ):
        """
        Models a stock price S(t) using the Weiner process W(t) as
        `S(t) = S(0).exp{(mu-(sigma^2/2).t)+sigma.W(t)}`

        Arguments:
            s0: Iniital stock price, default 100
            mu: 'Drift' of the stock (upwards or downwards), default 1
            sigma: 'Volatility' of the stock, default 1
            deltaT: The time period for which the future prices are computed, default 52 (as in 52 weeks)
            dt (optional): The granularity of the time-period, default 0.1

        Returns:
            s: A NumPy array with the simulated stock prices over the time-period deltaT
        """
        n_step = int(deltaT/dt)
        time_vector = np.linspace(0,deltaT,num=n_step)
        # Stock variation
        stock_var = (mu-(sigma**2/2))*time_vector
        # Forcefully set the initial value to zero for the stock price simulation
        self.x0=0
        # Weiner process (calls the `gen_normal` method)
        weiner_process = sigma*self.gen_normal(n_step)
        # Add two time series, take exponent, and multiply by the initial stock price
        s = s0*(np.exp(stock_var+weiner_process))

        return s

初始值为零并使用随机行走的过程

我们可以使用一个基本的随机过程,如 随机行走 ,来生成布朗运动的数据点。

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

随机漫步(图片来源:维基百科)

b = Brownian()for i in range(4):
    plt.plot(b.gen_random_walk(1000))
plt.show()

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

初始值为 20 并使用正态分布的过程

我们可以从正态分布中得出布朗运动数据。

b = Brownian(20)for i in range(4):
    plt.plot(b.gen_normal(1000))
plt.show()

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

股票价格模拟

我们在类中实现了几何布朗运动模型作为一种方法。

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

股票价格的几何布朗运动模型

在演示中,我们模拟了 52 个时间段的多个场景(假设一年有 52 周)。注意,所有的股票价格都从同一点开始,但是沿着不同的轨迹随机变化。

请注意,动态由基础正态分布的均值和方差参数控制。这在某种程度上模仿了股票的增长趋势和“波动性”。

例如,具有正增长趋势的股票将具有正的含义。对于这个特定的模拟,选择均值(μ)为 0.2,选择标准差(方差的平方根)为 0.68。

我们首先为绘图定义一个效用函数。

def plot_stock_price(mu,sigma):
    """
    Plots stock price for multiple scenarios
    """
    plt.figure(figsize=(9,4))
    for i in range(5):
        plt.plot(b.stock_price(mu=mu,
                               sigma=sigma,
                               dt=0.1))
    plt.legend(['Scenario-'+str(i) for i in range(1,6)],
               loc='upper left')
    plt.hlines(y=100,xmin=0,xmax=520,
               linestyle='--',color='k')
    plt.show()

请注意,尽管这些情景看起来足够随机,但它们有下降趋势。这是因为即使是正平均值,我们也有稍高的利差或波动性。

plot_stock_price(mu=0.2,sigma=0.7)

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

波动性的微小变化

我们用稍微小一点的波动性(但是和以前一样的均值)再次模拟股票价格,这次得到了完全不同的结果。趋势看起来是中性的,即一些情景显示股价在 52 周后上涨,而一些情景显示股价下跌。

plot_stock_price(mu=0.2,sigma=0.65)

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

进一步降低波动性

如果我们降低波动性,甚至更多,我们会得到一个明显的积极趋势。

plot_stock_price(mu=0.2,sigma=0.6)

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

二维绘图

在下面的例子中,我们展示了一个二维布朗运动,很像流体介质中实际悬浮的粒子所经历的运动。

b1 = Brownian()
b2 = Brownian()

x = b1.gen_normal(1000)
y = b2.gen_normal(1000)

plt.plot(x,y,c='b')
xmax,xmin,ymax,ymin = x.max(),x.min(),y.max(),y.min()
scale_factor = 1.25
xmax,xmin,ymax,ymin = xmax*scale_factor,xmin*scale_factor,ymax*scale_factor,ymin*scale_factor
plt.xlim(xmin,xmax)
plt.ylim(ymin,ymax)
plt.show()

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

摘要

我们展示了如何生成随机数据集对应于布朗运动在一维和二维。我们还展示了这一思想在使用几何布朗运动模型的股票价格模拟中的应用。

对于这个重要的随机过程,拥有一个现成的 Python 实现是极其重要的,因为它在各种实际应用程序中无处不在。

例如,数据科学从业者在分析定量金融或物理模型时,可以很容易地将这种实现与他们的随机过程模型相集成。

同样,Jupyter 实现 的笔记本可以在这里 找到。欢迎读者根据自己的需求来叉和扩展。

A lso,你可以查看作者的 GitHub 知识库获取机器学习和数据科学方面的代码、思想和资源。如果你和我一样,对人工智能/机器学习/数据科学充满热情,请随时在 LinkedIn 上添加我在 Twitter 上关注我

** [## Tirthajyoti Sarkar - Sr .首席工程师-半导体、人工智能、机器学习- ON…

通过写作使数据科学/ML 概念易于理解:https://medium.com/@tirthajyoti 开源和有趣…

www.linkedin.com](https://www.linkedin.com/in/tirthajyoti-sarkar-2127aa7/)**

NLP 数据科学家不会告诉你的残酷事实

原文:https://towardsdatascience.com/brutal-truths-that-nlp-data-scientists-will-not-tell-you-7f387de66cd5?source=collection_archive---------5-----------------------

由数据科学家分享

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

答根据 Tractica 的报告,人工智能 NLP 软件市场预计将从 2016 年的1.36 亿美元增长到 2025 年的 54 亿美元**。这大约是 10 年增长 40 倍!**

另一方面,计算语言学协会(ACL),杂志计算语言学的发起者一直在举行年会,吸引了数十位 NLP 科学家提交他们的作品。仅 2019 年提交的科学论文就比 ACL 2018 年增加了 75%

你可能会想——嘣!我要努力工作,在不久的将来成为一名 NLP 数据科学家!我爱 NLP!

这是否意味着你应该进入这个领域,只是因为它的光明前景?

事情是这样的。你所读到的一切都表明 NLP 的未来是光明的,它会很棒。然而,你不应该在不知道 NLP 数据科学家在做什么的情况下进入这个领域。我希望你能充分了解实际情况,以便你能更好地决定是否进入 NLP 领域。

在这篇文章中,我将与你分享作为一名 NLP 数据科学家的真相。

什么是 NLP?

简而言之,它涉及对人类自然语言和语音进行分析的计算技术

嗯嗯…这是什么意思?🤔

这意味着你要处理不同形式的文本。我跟大家分享一下一个 NLP 数据科学家时不时会面临的一些情况。

情况 1

我们来看看下面的推文。

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

想象你正在分析这篇文章。你的目标是理解课文的意思。比方说,你认为主语是“我的裤子”,动词是“失踪”。那么,你从这条推文中得到了什么?

“裤子不见了。”…??!

这显然不能代表推文的意思吧?

情况 2

现在,假设您正在执行基于方面的情感分析。基于方面分析包括情绪(正面或负面)和目标(观点)。

例如,“餐馆提供的服务很好”。这里,方面是“服务”,情绪是“积极的”。

为什么这很重要?这是因为餐馆的老板不仅知道顾客的体验很好,而且他们提供的服务也很棒。

假设您在数据集中看到了这篇评论。

这个真空吸尘器真的很烂。

这里的主题是真空吸尘器,但情绪应该是什么?“糟透了”这个词通常代表一种负面情绪,但你可以看到当它和吸尘器搭配在一起时,这个意思可能会发生变化。

真空吸尘器通过产生吸力来清洁。当你说它真的很烂的时候,你是在描述这台吸尘器很好用,不是吗?

情况 3

让事情变得更复杂。考虑下面这个问题。

嘿老弟,去哪里吃好吃的啊?

这句话的意思是食物很好吃吗?不,这实际上只是一个问题。

情况 4

另一种情况是,当你在处理文本时,你不知道它是什么意思。例如,你懂英语、汉语和马来语。但是,贵公司正在进行日语文本分类项目。所以,当你在试图理解你的模型出了什么问题的时候,你会很难受。

解决方案之一可能是使用谷歌翻译将句子转换成你知道的语言。然而,谷歌翻译并不完美。有些情况下,提供的翻译没有意义,你需要咨询你的母语是日语的人。

情况 5

此外,假设您正在进行文本分类任务。目标是检测商品名称是属于葡萄酒还是果汁。

也许你正在考虑使用关键字列表作为一项功能。在你花了几个小时找到一些有用的关键字来区分这两个类别之后,你会想到:

首先,您决定为每个类创建一组关键字列表。例如,葡萄酒类的关键字列表是[‘葡萄酒’,‘葡萄汁’],而果汁类的关键字列表是[‘果汁’]。如果在项目名称中找到关键字列表中的元素,那么该元素将作为一个特征被输入到模型中。

然而,您的模型的性能结果低于 90%的准确性的基准。

你该怎么办?你耐心地检查每一个错误分类的测试数据。当你发现葡萄酒有许多错别字时,你感到震惊:wne,wyne 等等。因此,您必须更新列表或对您的训练数据集执行一些错别字检查,以期提高准确性。

然而,这并不是故事的结尾。准确度确实提高了,但是您仍然对结果不满意。同样,你盯着错误分类的数据,找出这个有趣的项目名称:

“由发酵的葡萄汁制成的黑皮诺”

你从标题中提取的关键字是“果汁”,因此你的模型将其归类为果汁类,这是错误的!黑皮诺是红酒,因此它应该被归类为葡萄酒!

结论

文字既有趣又恶心。因此,大多数时候,NLP 数据科学家会看着数据,挠你的头,试图想办法让你的模型理解上下文。

因此,如果你认为 NLP 数据科学家只是打个电话。在 sklearn 中 fit(),你应该马上改变方向。

如果你只能从这篇文章中得到一样东西,那就是这个。

你应该期待你 80%的时间,不管你是在执行分析、特征工程、模型改进,还是在查看文本数据。因此,请确保您很好地理解您的数据,并能预见未来可能发生的一些潜在情况。

最终想法

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

恭喜你!你一直读到文章结束。我希望我没有降低你成为 NLP 数据科学家的兴趣。我写这篇文章的目的只是为了帮助你在进入 NLP 领域之前更好地理解一些重要的信息。

当然,这只是我的 2 美分,我欢迎你在下面发表评论,分享你作为 NLP 数据科学家的个人经验!🤗

让我引用一句话来结束这篇文章。

我知道你已经听过一千遍了。但这是真的——努力是有回报的。如果你想变好,你必须练习,练习,再练习。如果你不喜欢什么,那就不要做。—雷·布雷德伯里

关于作者

低伟鸿是 Shopee 的数据科学家。他的经验更多地涉及抓取网站,创建数据管道,以及实施机器学习模型来解决业务问题。

他提供爬行服务,可以为你提供你需要的准确和干净的数据。你可以访问这个网站查看他的作品集,也可以联系他获取抓取服务

你可以在 LinkedInMedium 上和他联系。

蛮力翻筋斗问题

原文:https://towardsdatascience.com/brute-forcing-the-cartpole-problem-4d04c9c34b12?source=collection_archive---------43-----------------------

用穷举法快速解决横竿问题。

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

基地图片由穆罕默德·贾希尔上刷屏

翻筋斗问题是强化学习中一个突出的基准问题,它在 OpenAI 的健身房中的实现最为人所知。也是他们排行榜上最受欢迎的s;这很有道理,是经典控制中比较容易出现的问题之一。但是这有多简单呢?

目前,一个解决方案需要在 100 集内平均平衡 195 步(或更多)。请记住,每集在 200 步后结束,因此解决方案确实需要有一定的稳定性。

一段时间以来,我一直认为在 200 步内保持平衡太容易了。因此,为了证实我的怀疑,我强行解决了这个问题。

如果你想了解我使用的所有代码,请随意在这里查看:https://github . com/Adam price 97/Control/blob/master/bruteforcecartepole . ipynb

在密码学中,暴力攻击首先计算所有可能的密码字符串。然后,它反复应用这些密码,直到找到正确的密码。为了在控制中使用类似的方法,我们需要生成一系列的策略来控制横向拉杆。这对于连续的状态空间是不可能的,所以我们必须将状态空间离散化。

小车问题有 4 个观察值:“小车位置”、“小车速度”、“极角”和“极速度”。我们将完全忽略“推车位置”和“推车速度”,200 个时间步不足以让推车移动足够远来结束这一集。这给我们留下了“极角”和“极速度”,它们都将被“离散化”到 3 个独立的箱中,创建 9 种可能的环境状态。

掷骰子问题只有 2 个动作,因此有 9 个状态,我们有 512 个(2⁹)确定性贪婪策略的极限。我们现在需要的是生成这些策略的方法,然后我们可以尝试使用蛮力来解决:

在每个状态-动作对中,购物车将向左或向右移动(0 或 1)。因此,为了创建策略,我们只需为从 0 到 511 的每个数字生成二进制数。然后,字符串被重新整形,形成一个 3×3 的矩阵,以便于流水线操作。

完全评估每个策略的计算成本很高,因此,首先,我们对问题运行每个策略一次,并跟踪得分高于 195 的策略。

当我们运行这个脚本时,我们发现最初的 512 个策略中有 34 个是潜在的解决方案。为了进一步检查它们,我们需要运行这些潜在的解决方案 100 集,并平均它们的性能。

当我们运行时,我们在 39.1 秒内找到了 8 个解决方案。所以,我们有它。我们成功地暴力破解了翻筋斗问题!

这显然是一个解决控制问题的糟糕方法。我们发现的解决方案是非常不稳定的,没有一个能够平衡极点超过 300 个时间步。为了找到更好的解决方案,我们需要在状态空间中使用更多的桶,鉴于这种方法的二次复杂性,尝试这种方法是非常愚蠢的。

然而,我们已经找到了有效的解决办法。作为一个基准问题,这是对 cartpole 的谴责吗?我不这么认为。问题可能仍然很难,你只需要更长时间地平衡杆子。将平均奖励提高到 490,上限为 500,可能会使这种暴力方法变得多余。

另外,基准甚至需要有难度吗?求解 cartpole 的算法通常通过在求解环境之前所需的集数来进行比较。这种强力算法需要 512 次非评估迭代,这将是健身房排行榜上的最后一次…

编辑:在这篇文章的结尾,我声称:

将平均奖励提高到 490 分,上限为 500 分,可能会让这种暴力方法变得多余。

事实证明我错了。这个笔记本有这样的证明:https://github . com/Adam price 97/Control/blob/master/bruteforcecartepole 2 . ipynb

事实上,这种方法可以在合理的时间框架内解决 500 个步骤。

气泡图,为什么和如何

原文:https://towardsdatascience.com/bubble-charts-why-how-f96d2c86d167?source=collection_archive---------22-----------------------

用泡泡讲故事

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

图片由来自 Unsplash 的 Braedon McLeod 提供

**又名:**泡泡图,泡泡图

原因:气泡图用于确定至少三个数值变量 是否相关或共享某种模式。在特殊情况下,它们可以用来显示一段时间内的趋势或比较分类变量。它们被认为是散点图的自然延伸,其中的点被气泡或圆盘所取代。

如何:针对一对数值变量(A,B)的每次观察绘制一个气泡或圆盘,在笛卡尔坐标系中,根据变量 A 的值水平定位圆盘,根据变量 B 垂直定位圆盘。第三个数值变量通过气泡的区域表示。您甚至可以在不同的气泡中使用不同的颜色来合并第四个数据集(D:数字或分类)。

这个故事是从这些数据点产生的形状以及气泡或圆盘的相对大小的差异来叙述的。对于不同的类别,必须有适当的图例,用颜色和某种类型的刻度来表示,以便我们推断出气泡大小所表示的数值。

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

图 1:气泡图的示意图。该图形是由 Seaborn 开发的。

上图显示了变量 A 和变量 b 之间的直接(正)关系。位置(60,225)所示的磁盘显然是一个异常值。通过关键字 bbox_to_anchor ,分类变量的图例和用于推断第三个变量数值的标度位于图表之外。使用此关键字,您可以更好地控制手动图例的放置;我强烈建议把它放在右上方的位置(Marplotlib.org,#1)。

就像散点图一样,可以在气泡图中找到数据集的三个重要特征:1 .- 离群值,与数据集中所有其他数据非常不同并且似乎不符合相同模式的数据。这些异常值可能代表有价值的分析信息;2.-gap,不包含数据的区间。数据之间差距的可视化证明了解释其存在的深入分析的合理性;3.- 聚类,孤立的数据气泡组,也值得对其在图表中出现的原因进行具体分析。以前,必须验证异常值、缺口或聚类的存在不是由于数据收集方法中的错误。

下面的气泡图描述了世界各地区发育迟缓获得基本卫生服务的患病率。研究表明,恶劣的卫生条件导致儿童发育迟缓,发育迟缓儿童的大脑神经元连接比正常儿童少。随着技术正在取代常规工作,对高级认知技能和更强适应性的需求正在上升,即使在发展中国家也是如此。但是,发育不良的儿童在未来劳动力市场所需的技能方面将处于劣势。图表左上角黄色气泡的出现表明,撒哈拉以南非洲地区构成了一个明显的国家集群,那里有数百万儿童在没有未来基本生活技能的情况下成长。由于圆盘的大小与该地区的人口相对应,该图还显示了为南亚数百万儿童带来安全卫生设施的迫切需要(世界银行,2018 年,#2)。

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

图 2:世界各区域阻碍获得基本卫生服务的发育迟缓的普遍程度。来源:世界银行,2018 年。

最著名的泡泡图属于汉斯·罗斯林的 TED 演讲。罗斯林(1948-2017)是瑞典医生和统计学家,卡罗林斯卡医学院国际卫生教授。在他的 TED 演讲中,他将巨大的数据集转化成关于世界、经济和人类未来的视觉故事。我强烈推荐看他 2006 年的第一个视频:“你见过的最好的统计”(#3)和 2013 年的“神话之河”(#4)。

温馨提示&警告( &!!)**

当我们想要显示三个或四个变量之间的关系**而不是它们的确切值时,气泡图是合适的。例如,在业务中,您可以通过在气泡图中可视化不同业务备选方案之间的成本、价值和风险等维度的关系来做出投资决策。

!!你应该经常验证第三个或第四个变量的增加是否会改善故事的讲述。如果没有,尝试切换到更简单的替代表示,如散点图。

!!气泡图的主要缺点在于数字变量之间的比较非常困难,因为我们用两种不同的尺度来表示它们:位置和大小。人类的大脑很容易识别位置,但是区域却很难比较。

!!永远记住,圆盘的面积与半径不成正比,而是与其平方成正比。

**笛卡尔平面 x-y 不一定要从(0,0)开始。你必须根据你的数据所能讲述的最好的故事来选择你的坐标系的原点(见图 4)。

!!与散点图不同,气泡图不会随着数据点数量的增加而改善。相反,每条信息都迫使观众计算相应气泡的大小,如果我们添加颜色来显示一些分类变量,这将变得更加复杂。虽然我们很容易掌握气泡大小的差异,但并不是每个人都会立刻联想到圆盘面积与半径的平方成正比。

!!它们不应用于表示零或负值,因为没有负或零区域。如果这种表示是必不可少的,建议使用实心圆表示正值,空心圆表示负值。在得出这种表示法之前,一定要分析备选方案,就像一种颜色的正值和一种非常不同的颜色的负值(蓝色对红色,如下图所示)。另一种方法是在一个坐标轴上定位带有负值的变量。**永远记住,在气泡图中不小心使用负值可能会让观众困惑。**例如,100 的圆和-100 的圆大小相同。

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

图 3:负值、零值和正值的建议表示。使用 Publisher 2010 制作的图表。

气泡数量的增加可能会导致拥塞和重叠**。在这种情况下,应该使用可视化工具提供的半透明替代品。当然,存在一定程度的重叠,超过这一程度,观众可能会感到困惑,尤其是在图表中有大量气泡或密集的气泡群时。此时,建议使用更简单的可视化替代方案。

**要用气泡图显示一段时间内的趋势,您必须将时间作为一个变量放在横轴上。另一种方法是使用某种动画,就像汉斯·罗斯林在他的 TED 演讲中所做的那样。

!!以“逻辑”大小显示整个图形的需要不允许很好地比较磁盘中的大小差异。因此,它们之间的微小差异不容易显现出来。

用气泡讲故事:白葡萄酒的品质

2017 年,全球生产了 2.5 亿百升葡萄酒。西班牙是世界葡萄酒销售的领导者,2018 年为 2280 万百升(西班牙葡萄酒市场观察站,2019)。紧随西班牙之后的是意大利(2140 万),法国(1540 万),智利(980 万)和澳大利亚(8)。不过从人均摄入来看,葡萄牙是世界领先的国家。葡萄牙人每年人均消费超过 51 升,是西班牙人的两倍。

葡萄酒是食品和饮料行业的一个特例,因为专家意见,尤其是所谓的大师的意见,通过在消费者中产生原型或质量模型,对葡萄酒市场产生了重大影响。对葡萄酒质量的感知与产品的特性有关。葡萄酒的感官特性(香气、味道、颜色、风味或触觉)由评委、专家或葡萄酒专业人士作为一个单一的多维属性在一个标尺上进行评估,该标尺在左端和右端具有“低质量”和“高质量”锚。

由于普通的葡萄酒消费者缺乏专家和专业人士的知识和经验,因此能够建立量化参数来帮助消费者做出购买一瓶葡萄酒的决定是很重要的。

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

图片由来自 Unsplash 的 Blake Barlow 提供

一个有趣的 Kaggle 竞赛是关于葡萄酒质量探索和分析葡萄牙“Vinho Verde”葡萄酒的红色和白色变种。

数据可在 https://archive.ics.uci.edu/ml/datasets/Wine+Quality获得,包括 1500 种白葡萄酒和 1500 种红葡萄酒的 11 种化学和物理特性。该项目的目的是评估以下哪些化学或物理特性影响葡萄酒的质量:固定酸度、挥发性酸度、柠檬酸、残糖、氯化物、游离二氧化硫、总二氧化硫、密度、pH 值、硫酸盐和酒精。这组葡萄酒由三位专家评估,他们为每种葡萄酒提供了 0(差)到 10(优)之间的质量分数。

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

表 1:葡萄酒数据集的前五条记录。

在研究结束时,还不清楚是什么区分了低质量的葡萄酒和中等质量的葡萄酒,只是根据一些化学性质区分了高质量葡萄酒的细微差异。一个重要的限制是数据集中缺少大量的低质量葡萄酒。总之,很明显,特定葡萄酒的质量是各种化学性质复杂结合的结果。

尽管如此,我们还是决定恢复该文件,并使用一些数据可视化技术来提供关于这样一个复杂主题的一些知识。考虑到质量是我们研究对象的基本属性,经过多次试验和大量图表,我们得出了以下气泡图:

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

图 4:葡萄牙“Vinho Verde”葡萄酒的质量、酒精、残糖和游离二氧化硫之间的关系。该图形是由 Seaborn 开发的。

横轴上表示的酒精**,是指葡萄酒的酒精等级。这个参数是由许多因素决定的:葡萄的品种、收获的时间、随后发生的发酵过程以及随后的处理。**

每升葡萄汁中含有大约 200 克糖,是葡萄糖和果糖的混合物。发酵时,糖大部分消失,留下酿酒师所谓的残余糖**。葡萄酒中残留的糖分通常是发酵中断的结果(酵母死亡或无法消耗剩余的糖分)。酒瓶标签通常会标明残糖量。**

葡萄酒行业使用二氧化硫的抗氧化和抗菌特性,防止颜色变化,尤其是在白葡萄酒中。由于消费者中不良反应的逐渐记录,二氧化硫的使用已经成为一个有争议的问题,消费者可能对二氧化硫的存在有轻度过敏(因此,在标签上指示其用途已经成为一些葡萄酒法规的一部分)。

图 4 中显示的气泡图清楚地表明,高品质的葡萄牙“Vinho Verde”葡萄酒(由绿色和蓝色圆盘表示)的酒精等级在 12%和 14 %之间,残糖水平低于 15 g/l。该图还表明,二氧化硫水平(由圆盘区域表示)对最终产品的质量没有相关影响。

所以,下次你买一瓶酒时,试着记录下酒精含量、残糖量和游离二氧化硫水平。虽然这不是一件容易的事情,但是通过数字尺度来量化葡萄酒的质量。通过这种方式,你将了解最适合你口味的化学参数。尽情享受吧!!

如果你对这篇文章感兴趣,请阅读我以前的:

簇状和重叠条形图,为什么和如何

** [## 簇状和重叠条形图

为什么和如何

towardsdatascience.com](/clustered-overlapped-bar-charts-94f1db93778e)

堆积条形图,为什么和如何,讲故事和警告

[## 堆积条形图,为什么和如何

讲故事和警告

towardsdatascience.com](/stacked-bar-graphs-why-how-f1b68a7454b7)

参考文献

1:https://matplotlib . org/3 . 2 . 2/tutorials/intermediate/legend _ guide . html #

2:https://www . world bank . org/en/news/feature/2018/12/21/year-in-review-2018-in-14 图表

3:https://www . ted . com/talks/Hans _ rosling _ the _ best _ stats _ you _ ve _ ever _ seen/抄本?language=es#t-67035

第四名:https://www.youtube.com/watch?v=lYpX4l2UeZg**

Matplotlib 中的气泡图

原文:https://towardsdatascience.com/bubble-plots-in-matplotlib-3f0b3927d8f9?source=collection_archive---------8-----------------------

通过使用 Python 的 Matplotlib 库的例子学习绘制气泡图

气泡图是散点图的改进版本。在散点图中,有两个维度 x 和 y。在气泡图中,有三个维度 x、y 和 z。其中第三个维度 z 表示权重。这样,气泡图比二维散点图在视觉上提供了更多的信息。

数据准备

对于本教程,我将使用包含加拿大移民信息的数据集。它有 1980 年至 2013 年的数据,包括来自 195 个国家的移民人数。导入必要的包和数据集:

import numpy as np  
import pandas as pd 
df = pd.read_excel('[https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/DV0101EN/labs/Data_Files/Canada.xlsx'](https://s3-api.us-geo.objectstorage.softlayer.net/cf-courses-data/CognitiveClass/DV0101EN/labs/Data_Files/Canada.xlsx'),
                       sheet_name='Canada by Citizenship',
                       skiprows=range(20),
                       skipfooter=2)

数据集太大。所以,我不能在这里显示截图。让我们看看列的名称。

df.columns#Output:
Index([    'Type', 'Coverage',   'OdName',     'AREA', 'AreaName',      'REG',
        'RegName',      'DEV',  'DevName',       1980,       1981,       1982,
             1983,       1984,       1985,       1986,       1987,       1988,
             1989,       1990,       1991,       1992,       1993,       1994,
             1995,       1996,       1997,       1998,       1999,       2000,
             2001,       2002,       2003,       2004,       2005,       2006,
             2007,       2008,       2009,       2010,       2011,       2012,
             2013],
      dtype='object')

我们不会用到很多列。我只是删除了这些列,并将国家的名称(’ OdName ')设置为索引。

df = df.drop(columns = ['Type', 'Coverage', 'AREA', 'AreaName',      'REG', 'RegName', 'DEV', 'DevName',]).set_index('OdName')
df.head()

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

这个练习我选择了爱尔兰和巴西的数据。没有什么特别的原因。我随机选择了他们。

Ireland = df.loc['Ireland']
Brazil = df.loc['Brazil']

标准化数据

有几种不同的方法来标准化数据。我们将数据标准化,使数据处于相似的范围内。爱尔兰和巴西移民数据的范围不同。我需要把它们带到从 0 到 1 的范围。我只是用爱尔兰数据除以爱尔兰数据系列的最大值。我对巴西的数据序列做了同样的处理。

i_normal = Ireland / Ireland.max()
b_normal = Brazil / Brazil.max()

我们将绘制爱尔兰和巴西的数据。把这些年列在清单上会很有用。

years = list(range(1980, 2014))

制作气泡图

为了看出区别,我们先画散点图。

import matplotlib.pyplot as plt
plt.figure(figsize=(14, 8))
plt.scatter(years, Ireland, color='blue')
plt.scatter(years, Brazil, color='orange')
plt.xlabel("Years", size=14)
plt.ylabel("Number of immigrants", size=14)
plt.show()

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

现在,画出气泡图。我们必须输入我们之前定义的大小。

plt.figure(figsize=(12, 8))
plt.scatter(years, Brazil, 
                  color='darkblue', 
                 alpha=0.5,
                 s = b_normal * 2000)plt.scatter(years, Ireland, 
                  color='purple', 
                 alpha=0.5,
                 s = i_normal * 2000,
                 )
plt.xlabel("Years", size=14)
plt.ylabel("Number of immigrants", size=14)

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

我们可以通过气泡的大小来了解移民的数量。泡沫越小,移民人数越少。

我们也可以把这块地做成彩色的。为了使它更有意义,我们需要对数据序列进行排序。你很快就会明白原因。

c_br = sorted(Brazil)
c_fr = sorted(France)

现在我们将传递这些值来改变颜色。

plt.figure(figsize=(12, 8))
plt.scatter(years, Brazil, 
                  c=c_br,
                 alpha=0.5,
                 s = b_normal * 2000)plt.scatter(years, Ireland, 
                  c=c_fr,
                 alpha=0.5,
                 s = i_normal * 2000,
                 )
plt.xlabel("Years", size=14)
plt.ylabel("Number of immigrants", size=14)

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

现在我们增加了另一个维度,颜色。颜色随着移民的数量而变化。但是当我们画两个变量的时候,就没那么好了。因为在这个过程中,我们没有明确地定义单个变量的颜色。但是当我们在 y 轴上画一个变量时,它做得很好。让我们画出每年来自巴西的移民人数,看看这些年的趋势。

plt.figure(figsize=(12, 8))
plt.scatter(years, Brazil, 
                  c=c_br,
                 alpha=0.5,
                 s = b_normal * 2000)
plt.xlabel("Years", size=14)
plt.ylabel("Number of immigrants of Brazil", size=14)

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

我敢肯定,你可以在这里非常清楚地看到颜色随着移民数量的变化。

这就是 Matplotlib 中的气泡图。我希望它有帮助。

这是另一个很酷的可视化教程:

[## 使用 Python 的 Matplotlib 的华夫饼图表

如何使用 Matplotlib 库在 Python 中绘制华夫饼图表

towardsdatascience.com](/waffle-charts-using-pythons-matplotlib-94252689a701)

推荐阅读:

Matplotlib 中的基本绘图:Python 中的可视化

用 Python 中的单变量和多变量图表和绘图理解数据

如何在 Python 中呈现多个变量之间的关系

Numpy 中 1D、2D 和 3D 数组的索引和切片

熊猫数据透视表数据分析

用于数据建模的探索性数据分析

用于边界框注释的预算自动化

原文:https://towardsdatascience.com/budget-automation-for-bounding-box-annotation-500a76b4deb7?source=collection_archive---------31-----------------------

实践教程

了解如何使用 TensorFlow.js 加速数据注记

介绍👋

最初发布于 bitsy.ai

数据收集和准备是每个机器学习应用的基础。你以前听说过:“垃圾输入,垃圾输出”,指的是算法纠正不准确、质量差或有偏见的输入数据的能力有限。

高质量标注数据的成本促使工具/平台的家庭工业加速数据标注过程。除了 SaaS/本地创业生态系统,每个主要的云提供商(AWS、微软、谷歌)在过去两年都推出了自动化数据标签产品。可以理解的是,开发这些服务时通常会考虑到高级/企业用户、功能和价位。

在有限的预算下,我是不是只能手工给的所有东西贴标签?

好消息。稍加努力,你就可以为你自己或一个小团队自动化边界框注释。在这篇博文中,我将向您展示我用来快速原型化 3D 打印故障检测模型的自动化技术。

您将学习如何:

  1. 为人类贴标机创建详细的说明
  2. 训练制导模型
  3. 使用 Microsoft VoTT (可视对象标记工具)和 TensorFlow.js 自动标注边界框

图为:自定义 TensorFlow 模型在微软 VoTT(可视对象标记工具)中自动标注一个视频帧。

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

自定义张量流模型在 Microsoft VoTT(可视对象标记工具)中自动注释视频帧。图片作者。

第一遍注释🏷

如果您是从没有标签的地方开始,您确实需要硬着头皮手工注释一些数据。为注释决策创建书面指南和评估标准,需要手动标记至少几百个示例。

从源代码安装 VoTT(视觉对象跟踪工具)

Microsoft VoTT 是一个开源工具,用于用边界框(对象检测)和多边形(分割)来注释图像和视频。我使用 VoTT 是因为它:

  • 支持多种导出格式
  • 可以作为 web 应用程序托管
  • 让我从 TensorFlow.js 模型预填充边界框建议

安装先决条件:

  • NodeJS (>= 10.x)和 NPM。我推荐 NVM (节点版本管理器)来管理 NodeJS 安装和环境。

克隆 VoTT repo 并从源安装:

$ git clone https://github.com/microsoft/VoTT 
$ cd VoTT 
$ npm ci 
$ npm i @tensorflow/tfjs@2.7.0 
$ npm start

要使用较新的 ops,必须升级 TensorFlow.js 包。

参考使用 VoTT 创建新项目并设置数据连接。

寻找数据集?试试谷歌的数据集搜索

手动标记一些示例

您需要手动标记的图像数量取决于问题领域,从几十个图像到几千个图像。我通过以下方式为我的问题(检测 3D 打印缺陷)获得了合理的结果:

  • 5 个标签(分布如下)
  • 67 个打印延时视频,每秒采样 3 帧
  • 浏览了 6 248 张图片
  • 在 3,215 幅图像上绘制了 9,004 个边界框,平均每幅图像 3 个边界框。
  • 八小时,分几天完成。我在没有早晨通勤的情况下赶上了我一直忽略的播客。

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

VoTT(视觉对象跟踪工具)提供的数据集统计。图片作者。

编写注释指南

当这个任务还历历在目时,花点时间写下清晰的指南(如下例),以保持标签的一致性,并涵盖常见的边缘情况。请随意使用我的指示作为你自己的模板。

边界框注释指南

概念

2-3 句话介绍任务/概念

该数据集包含失败的 3D 打印作业的延时视频。图像是按时间顺序排列的。您的任务是在所有可识别的像素周围画出紧密的方框,以匹配打印缺陷或对象。

标签

id、文本名称、标签和边缘案例的书面描述、正面和负面示例

  • 标签应该从 0 还是 1 开始?
  • 0 是否为背景/未知类保留?

0 背景

1 个喷嘴

打印喷嘴是一个金属物体,它挤出热丝。

如果喷嘴被部分遮挡,围绕整个对象(包括遮挡的像素)绘制一个边界框。

如果喷嘴完全堵塞,不要贴标签。

2 个木筏

“筏”是围绕印刷品前几层的薄轮廓。

如果筏子被部分遮挡(通常被印迹遮挡),在整个筏子周围画一个边界框。

3 打印

正在打印的对象。如果要打印多个对象或多个部分,请在每个不同的对象周围画一个边框。

4 附着力

5 根意大利面条

指导方针

  • 输入格式
  • 标签格式
  • 每帧 1 个还是多个对象?
  • 每个对象“实例”有 1 个还是多个盒子?
  • 盒子是紧的还是松的?
  • 标签反射(镜子,水)?

用 AutoML 训练制导模型🤖

AutoML(自动机器学习)是一种属于“强力”算法类别的技术。基于云的 AutoML 平台是一个很好的工具,用来验证你的问题可以应该用机器学习来解决。

即使你计划训练一个模型,也要考虑先把 AutoML 模型放在客户面前。尽早收集客户反馈,并将这些信息整合到定制模型的开发中。一些见解的例子…

  • 客户对误报不敏感(通过短信报告缺陷,但打印没问题)。
  • 大多数客户喜欢印刷进度的可视化更新,即使检测机不正确。
  • 令人惊讶的是,一些客户报告的假阳性引起了安全感。

我使用了谷歌云自动视觉 Edge(物体检测),我选择它是因为:

  • S 支持模型导出到 TensorFlow Lite、TensorFlow.js 和 ops,兼容 Edge TPU、ARM 和 NVIDIA 硬件加速。
  • 披露:我是一名谷歌开发专家🤓

从 VoTT 导出数据集

在项目的导出设置中,选择 CSV 提供程序。选中“包括图像”,保存配置,然后导出数据。如果您要导出数千幅图像,这将需要几分钟时间。休息一下!

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

VoTT 导出设置。图片作者。

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

从 VoTT 导出的文件。图片作者。

检查和预处理数据

如果提供了两个顶点,AutoML Vision 需要以下格式的 CSV 数据:

SET,gs://path/to/img,label,x_min,y_min,,,x_max,y_max

坐标必须是相对于图像尺寸的**,落在范围【0,1】内。**

Github Gist 中提供的代码

import pandas as pd

# load VoTT CSV export
# notice: coordinates are absolute
df = pd.read_csv('/path/to/vott-csv-export/{project name}-export.csv')
df.head()

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

图片作者。

import cv2

base_path = '/path/to/vott-csv-export/'

LOG_INTERVAL=2000

# convert absolute coordinates to relative coordinates in [0, 1] range
for index, row in df.iterrows():
    if index % LOG_INTERVAL == 0:
        print(f'finished {index} / {len(df)}')
    filename = row['image_path'].split('/')[-1]
    img = cv2.imread(f'{base_path}{filename}')
    height, width, channels = img.shape
    df.at[index, 'x1_n'] = row['x1'] / width
    df.at[index, 'x2_n']= row['x2'] / width  
    df.at[index, 'y1_n'] = row['y1'] / height
    df.at[index, 'y2_n'] = row['y2'] / height

# replace relative image paths with a Google Storage bucket path
df['set'] = 'UNASSIGNED'
df['gs_path'] = df['image'] + 'gs://bucket-name/path/to/upload'

# write CSV with columns expected by AutoML Vision
# the "none" columns are required for boxes defined by 2 vertices
df['none'] = ''
df.to_csv('/home/leigh/datasets/spaghetti/labeled/vott-csv-export/spaghetti_v1-normalized-export.csv', 
    columns=['set', 'image_path', 'label', 'x1_n', 'y1_n', 'none', 'none', 'x2_n', 'y2_n', 'none', 'none'],
    index=False
    )

有关更多信息,请参考准备您的培训数据

上传数据

将数据上传到谷歌云存储桶。**注意:**如果您正在创建一个新的时段,AutoML Vision exports 在后面的步骤中要求目标时段在 us-central-1 地区。

  • 新来 GCP 吗?在开始设置项目和认证之前,遵循中的步骤。
  • 安装 gsutil
  • gsutil rsync -r /path/to/vott-csv-export gs://your-bucket-name/vott-csv-export/

将数据导入 AutoML Vision

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

图片作者。

数据导入时休息一下!👏

在训练之前,对导入的数据进行全面检查,并验证标签是否正确。

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

3D 打印的“筏”是一次性的支撑结构。图片作者。

火车模型

AutoML 的价格体系是基于**节点小时,**与“挂钟”或运行时间不同。我的一个批评是,提前为培训工作定价需要一些额外的努力。

AutoML Vision 定价(美元价格如下所示)因功能而异,不同的定价表适用于:

  • 云托管分类和对象检测—3.15 美元/节点小时,75.6 美元/ 24 小时
  • 边缘(分类)-4.95 美元/节点小时,118.80 美元/ 24 小时
  • 边缘(物体检测)——18.00 美元/节点小时,432 美元/ 24 小时

如果这些价格超出了您项目的预算,我将在未来的帖子中介绍我如何使用 TensorFlow 的对象检测 API 训练模型。关注或订阅我的简讯以获得出版通知。

对于这个特殊的问题(检测 3D 打印缺陷),我看到了使用我的数据集大小的推荐训练时间(24 节点小时)的合理结果。深入到单个标签,“喷嘴”检测的表现明显比其他标签差。

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

所有标签的指标。图片作者。

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

“喷嘴”标签的指标。图片作者。

左:所有标签的精度/召回曲线。右图:“喷嘴”的精度/召回曲线

经过更仔细的检查,我发现高的假阳性率显著影响了模型的精度分数。精度是真阳性/(真阳性+假阳性)之和。我很兴奋地发现了一些例子,在这些例子中,我没有在地面真实数据中标注喷嘴。

🤯即使我在第一次贴标签的过程中变得草率,指导模型已经足够好来捕捉这些错误。哇!如果我不得不手动标记这些数据的整体,它将充满错误。

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

我的模型自信地在这些图像中检测到“喷嘴”物体,由于人为错误标记地面真实数据,这些物体被评为“假阳性”。图片作者。

使用 TensorFlow.js 自动标注 VoTT🤖

下一节将向您展示如何使用自定义 TensorFlow.js 模型来建议具有 VoTT“主动学习”功能的边界框。

“主动学习”使用 TensorFlow.js 模型在帧上执行推理,应用非最大抑制,并为每个检测到的对象绘制最佳框建议。

导出 TensorFlow.js 模型

模型训练完成后,您可以在“测试和使用”选项卡中导出 TensorFlow.js 包。该模型将导出到一个存储桶中(目标桶必须在美国中部-1 地区)。

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

谷歌云自动视觉边缘导出。图片作者。

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

谷歌云自动视觉边缘导出。图片作者。

创建 classes.json 文件

我手动修复了这个。AutoML Vision Edge 导出新行分隔的标签文件。VoTT 要求的格式如下。标签索引必须从 1!

[{"id":1,"displayName":"nozzle"}, ... ]

修补 VoTT 以修复 TensorFlow 1.x -> 2.x 错误

VoTT 自带@tensorflow/tfjs 的 v1。AutoML Vision Edge 模型使用需要更新版本的操作系统(如 AddV2)。我用以下补丁修复了几个小问题:

  • 模型需要 float32 输入
  • 使用较新的 TF . image . nonmaxsupressionasync()fn
diff --git a/src/providers/activeLearning/objectDetection.ts b/src/providers/activeLearning/objectDetection.ts
index 196db45..a8dff06 100755
--- a/src/providers/activeLearning/objectDetection.ts
+++ b/src/providers/activeLearning/objectDetection.ts
@@ -151,6 +151,8 @@ export class ObjectDetection {
         const batched = tf.tidy(() => {
             if (!(img instanceof tf.Tensor)) {
                 img = tf.browser.fromPixels(img);
+                // model requires float32 input
+                img = tf.cast(img, 'float32');
             }
             // Reshape to a single-element batch so we can pass it to executeAsync.
             return img.expandDims(0);
@@ -166,7 +168,8 @@ export class ObjectDetection {
         const result = await this.model.executeAsync(batched) as tf.Tensor[];

         const scores = result[0].dataSync() as Float32Array;
-        const boxes = result[1].dataSync() as Float32Array;
+        // tf.image.nonMaxSepressionAsync() expects tf.Tensor as input
+        const boxes = result[1].dataSync()

         // clean the webgl tensors
         batched.dispose();
@@ -177,10 +180,8 @@ export class ObjectDetection {
         const prevBackend = tf.getBackend();
         // run post process in cpu
         tf.setBackend("cpu");
-        const indexTensor = tf.tidy(() => {
-            const boxes2 = tf.tensor2d(boxes, [result[1].shape[1], result[1].shape[3]]);
-            return tf.image.nonMaxSuppression(boxes2, maxScores, maxNumBoxes, 0.5, 0.5);
-        });
+        const boxes2d = tf.tensor2d(boxes, [result[1].shape[0], result[1].shape[1]]);
+        const indexTensor = await tf.image.nonMaxSuppressionAsync(boxes2d, maxScores, maxNumBoxes, 0.5, 0.5);

         const indexes = indexTensor.dataSync() as Float32Array;
         indexTensor.dispose();
@@ -188,7 +189,9 @@ export class ObjectDetection {
         // restore previous backend
         tf.setBackend(prevBackend);

-        return this.buildDetectedObjects(width, height, boxes, maxScores, indexes, classes);
+        // _.buildDetectedObjects expects Float32Array input
+        const fboxes = boxes as Float32Array
+        return this.buildDetectedObjects(width, height, fboxes, maxScores, indexes, classes);
     }

自动包围盒建议✨

  • 修补 VoTT 后运行npm start
  • 在“主动学习”选项卡中,配置“模型路径”以指向您的 TensorFlow.js 导出。我建议启用“自动检测”功能,否则你必须手动按 ctrl/cmd+d 来对每一帧执行检测。

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

微软 VoTT 主动学习配置。图片作者。

包扎

您刚刚学习了如何将几个小时和几百美元用于自动边界框注释工作流。作为一个额外的奖励,指导模型可以适用于原型甚至是初始生产运行。我希望这能为你的下一个物体探测项目节省一点时间/精力!

与其他云产品相比,AutoML 产品价格昂贵——但它们远不如从零开始开发一个可比较的模型或甚至使用重量转移学习这样的资源密集型产品

你目前正在使用物体探测器解决问题吗?请在下面的评论中告诉我更多关于你的理念和方法。

订阅我的时事通讯@ bitsy.ai 获取更多关于 Raspberry Pi、Arduino 和其他小型设备的 ML 应用的技巧、教程和详细文章。我目前正在为 Octoprint 打造一个隐私优先的 3D 打印监控插件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值