TowardsDataScience-博客中文翻译-2020-一百三十三-

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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

你的网站是否泄露了敏感信息?

原文:https://towardsdatascience.com/xs-leaks-is-your-website-leaking-the-sensitive-information-c190eff5d548?source=collection_archive---------56-----------------------

对于导致用户信息泄露的 XSLeaks(跨站点泄露)缺乏关注

来源

大多数开发人员都熟悉并了解这些安全漏洞【XSS】(跨站脚本)、【CSRF】(跨站请求伪造)或 SQL 注入,但对可能导致用户信息泄露的 XSLeaks(跨站泄漏)却缺乏关注。在这篇博客中,我将对它做一个简单的介绍。

什么是 XSLeaks?

XSLeaks 是一类漏洞,第三方恶意网站能够发送请求或将用户重定向到目标服务,然后测量侧信道信号(例如,响应时间、浏览器中的静态资源缓存、HTTP 响应状态代码、响应内容等)..)来基于这样的副信道信号推断和收集关于用户的信息。

现实世界举例:你在看我的博客,如果我知道你是谁呢??

2013 年,有一个报告的错误允许网站使用脸书来检测访问者是否是特定的人。脸书徽章的预览图像是基于当时用户的脸书 ID 动态生成的。如果用户 1234567 已经登录,图像将类似于图 1。如果其他用户试图加载用户 1234567 的徽章图像,则会加载脸书徽标图像,而不是个人资料图像(图 2)。基本上,只有用户自己可以查看他们的个人资料徽章预览。

图一。有效的登录用户。

图二。无效的登录用户。

尽管脸书已经很好地屏蔽了姓名和电子邮件地址的信息,但它仍然泄露了用户身份。黑客可以使用 JavaScript 悄悄加载预定义用户 id 列表的配置文件出价预览,然后检查响应图像的高度和宽度,以了解特定用户正在查看他们的页面。

如果上面的例子对你来说已经相当过时了,2018 年年中还有另一个报告的 bug 。汤姆·安东尼发现了一种可以达到类似结果的方法。今天,与 2013 年相比,大多数脸书后端端点都受到了很好的保护,它们加载了access-control-allow-originx-frame-options 标头,以防止恶意网站使用 XHR 请求、iframe、图像标签等嵌入和调查 FB 内容。然而,Tom 发现一个 api(以用户 ID 作为参数)为匹配用户和非匹配用户提供了不同的content-type。然后,他使用了一个简单的 JavaScript 脚本,该脚本将获取一个用户 id 列表,并生成许多带有等同于端点的srcscript标签。script标签当然会失败,但是由于响应内容类型的不同,它们会以不同的方式失败,并且可以通过onloadonerror事件处理程序检测到。此外,该端点似乎没有任何速率限制,他可以在一分钟内检查数千个 id。

如果上述漏洞没有被修复,人们可能会利用它们来跟踪特定的人(比如老板、前女友、名人..)阅读他们的博客,或者他们可以根据访问者显示不同的内容。更多关于 XS 泄露攻击的真实例子可以在这里找到。

怎么防守?

web 应用程序的本质通常会导致大量暴露在 web 中的端点暴露用户的敏感数据,并且浏览器实现使网站很容易受到 XSLeak 攻击。幸运的是,XSLeak 已经引起了浏览器制造商的注意,并且有一些机制可以避免它。

X-帧-选项

使用X-Frame-Options: DENY会导致任何在框架中加载页面的尝试失败。它不仅能防御点击劫持,还能帮助防御 XSLeaks。如果页面需要嵌入到其他站点(广告、小部件等等),那么页面中包含的信息应该尽可能的稳定和可预测。

same site cookie

在某些情况下,恶意网站可以删除受攻击网站的特定资源的缓存,迫使浏览器再次呈现这些信息,并检查浏览器是否确实缓存了最初删除的资源。这使得攻击者能够判断网站是否加载了特定的资源(如图像、脚本或样式表),从而识别用户或泄露用户的一些信息。

严格的同站点 cookies 有助于避免上述情况,因为它将用户手动键入 URL、单击书签或单击当前站点的链接所生成的请求与其他网站发起的请求区分开来。

你可以参考这个链接了解更多关于这种攻击的细节。

获取元数据请求头

现代浏览器实现了 sec fetch 头,为服务器提供了更多的关于请求被触发的原因/位置的上下文。这些信息帮助服务器基于测试一组先决条件快速拒绝请求。

例如,由img元素生成的请求将导致包含以下 HTTP 请求头的请求:

Sec-Fetch-Dest: image
Sec-Fetch-Mode: no-cors
Sec-Fetch-Site: cross-site

服务器可以对端点实施策略检查,并使用Sec-Fetch-Dest快速拒绝非图像内容的请求。

结论

XSLeak 攻击领域的研究正在进行中,我相信在接下来的几年里会有更多的技术出现。作为一名开发者,重要的是要意识到这个问题有多严重,并开始更加注意保护你的网站免受这种攻击。

参考资料:

  1. https://ports wigger . net/research/xs-leak-leaking-ids-using-focus
  2. https://github.com/xsleaks/xsleaks/wiki/Defenses
  3. http://patorjk . com/blog/2013/03/01/Facebook-user-identificati on-bug/
  4. https://www . tomanthony . co . uk/blog/Facebook-bug-confirm-user-identities/
  5. https://ports wigger . net/daily-swig/new-xs-leak-techniques-reveal-fresh-ways-to-expose-user-information
  6. https://medium . com/bugbountywriteup/cross-site-content-and-status-types-leakage-ef 2 dab 0a 492
  7. https://scarybestsecurity . blogspot . com/2009/12/cross-domain-search-timing . html

用户参与度的突然下降

原文:https://towardsdatascience.com/yammer-investigating-a-sudden-drop-in-user-engagement-7c9c4093c038?source=collection_archive---------11-----------------------

使用产品分析、数据可视化和数据科学方法来调查 Yammer 用户参与度的下降

自由股票Unsplash 上的照片

免责声明:我不为 Yammer 工作,这是一个公开的数据案例研究,我用叙述的形式写它是为了让这个案例研究更吸引人。

这是周一的早晨……你端着一杯咖啡坐在桌前——眼睛几乎没有睁开。突然,产品主管拍了拍你的肩膀,把他的笔记本电脑摔在你的桌子上。

“我们的周参与度怎么会在一个月内下降 21%?!"

Sighhhhhhh

你掰着手指头,放下你的咖啡——“让我看看”。

嗯……乍一看,从 7 月 28 日开始,我们的每周参与水平一直在稳步下降。在 Yammer,我们将“参与”定义为与产品进行“服务器调用”(也就是用户点击了什么)的任何交互。

一般来说,大多数公司将用户参与度视为其产品整体增长和健康的主要 KPI(关键绩效指标)之一。

对于那些没有听说过我们的人来说, Yammer 是一个面向企业的社交网络(类似于脸书的 Workplace)。员工可以发送消息、搜索内部网、共享文档和发布更新。

诊断问题

在花太多时间诊断 KPI 变化的根本原因之前,我首先检查一下这个心理清单,以确保根本原因不是由非产品因素引起的,如广告、bug、错误等。

图片作者:Richard Yang

时间:时间是一个很好的考虑因素,因为不规则趋势在绘制时更容易发现。以下是最常见的与时间相关的数据问题:

  • 这种参与度的下降是突然的还是逐渐的?⟶:如果是突然的,那么请与工程团队一起检查是否进行了任何部署,如果是渐进的,那么可能与用户行为的变化有关。
  • 这是一次性事件还是经常发生的问题?⟶:一次性问题可能是由技术问题或营销活动引起的,而重复性问题可能是由行为变化引起的。
  • 我们会在一天中的特定时间或一周中的特定日子看到下降更明显吗?局限于特定时间或日期的⟶下降可能表明存在技术问题,例如通常在周末发生的数据刷新失败。

地区:考虑地区参与度很重要,因为公司在测试新产品或地区互联网审查/法律限制使用时,可能会在特定地区推出功能。要问的一些问题是:

  • 我们看到的参与度下降是局限于某个特定地区,还是分布在全球各地?由于消费者行为的文化差异,某些功能在特定地区可能表现得更好或更差。
  • 随着参与度的下降,该地区的互联网审查法律最近有什么变化吗?

其他功能/产品:在同一个空间内保持其他产品/功能的常规标签对于识别公司层面的潜在变化非常有用。要问的一些问题是:

  • 其他功能或产品的参与度是否也出现了类似的下降?⟶:如果这种下降在其他产品和功能中普遍存在,那么这个问题将会是一个更大的问题,需要多个团队参与调查。
  • 生态系统中的其他类似功能或产品的参与度是否成比例增加?⟶用户可能会转向使用不同的产品或功能来满足他们的用例,导致 Yammer 的分食。

平台:根据用户使用 Yammer 的平台,UX 显示和 ENG 发布流程有所不同,如果问题是技术性的且仅限于某个特定平台,您可以缩小范围。一些常见的问题是:

  • 我们是否看到跨特定平台(即移动、桌面、平板)还是跨所有平台?
  • 衰落是 android 还是 iOS 或者其他操作系统特有的?

行业/竞争对手:跟踪 Yammer 在行业中的表现并了解总体趋势对于市场空间意识非常有用。竞争对手的信息可能很难获得,但我们仍然可以利用新闻文章、谷歌趋势搜索和第三方数据来获得高层次的见解。

谷歌趋势搜索 Yammer 与顶级竞争对手的比较

损坏的特征/跟踪代码:也有可能某些特征或跟踪代码损坏,从而影响事件的记录方式。用户在与应用程序交互时触发的事件的映射层次结构对于确定用户离开的位置非常重要。

僵尸工具和搜索爬虫引擎:大多数主要网站都有来自僵尸工具的高活跃度,但是很难确定由僵尸工具触发的事件。高流量网站也由搜索引擎优化引导,搜索引擎索引的变化会导致流量的显著变化。

重大事件:一次性事件也有可能导致人员涌入或参与度大幅下降,如假期、成功的活动和负面新闻。

数据的约束

在这个案例研究中,我们唯一可以操作的数据集是:时间、地区、平台和事件跟踪。如果您想查看用于分析的源数据和代码,请查看下面的嵌入式笔记本链接:

[## nbviewer 笔记本

看看这个 Jupyter 笔记本!

nbviewer.jupyter.org](https://nbviewer.jupyter.org/github/JodiZhang/Yammer-Case-Study/blob/392955b5c34d4611179c7ec0396b5131287c197c/Drop in User Engagement/Yammer Case Study - Drop in User Engagement.ipynb)

*注意所有的 Plotly 图表都是交互的,可以点击拖拽放大图表或者点击图例中的类别进行过滤。

假设

潜在原因 1

  • 根据上面的图表,周六和周日的参与率最低这是有道理的,因为 Yammer 主要用于工作。
  • 当按一天中的时间(基于 24 小时制)检查参与度时,看起来上午 9 点是用户与 Yammer 交互最频繁的时候,而一天中的其他时间并不突出。
  • 由于参与度的下降是在几个月的时间内逐渐发生的,并且不局限于某一天或某一时间,因此我们可以假设原因不太可能是一次性服务器/技术中断或数据更新失败。

潜在原因 2

  • 因为 Yammer 被多个地区使用,所以最好根据用户数量来分析前 5 个地区。
  • 从上图中可以看出,美国的活跃用户下降幅度最大,而其他地区的下降幅度较小。
  • 如果有任何新的发布或者产品升级只局限于某个州,与其他团队一起快速检查将是非常有用的。

潜在原因 3

  • Yammer 中的事件(动作)分为以下几类:登录事件、消息事件、搜索事件和注册漏斗事件。
  • 从上图中可以清楚地看到,用户能够在注册漏斗中导航,但其他活动的参与度有所下降。

  • 增长率或激活率是所有公司密切跟踪的指标,因为这意味着 Yammer 为新客户提供了预期的价值。
  • 根据上面的图表,增长率保持正常,因为它继续在工作日保持高水平,在周末保持低水平。
  • 在没有注册(增长)问题的情况下,参与度的下降可以被认为是来自老用户/现有用户。

潜在原因 4 :由于缺乏老用户的支持,参与度下降

  • 做一个群组分析是追踪任何用户群的最常见的方法之一。从长远来看,它有助于为用户描绘一幅关于 Yammer 产品有效性的更好的画面。
  • 按年龄对用户进行细分后,很明显,那些在 5 月 1 日前 10 周以上注册的用户,参与度会随着时间的推移而下降。单独观察每一组,随着时间的推移,他们的参与度也会下降。
  • 由于该问题与成熟用户有关,因此该问题不太可能与营销流量或机器人和搜索爬虫的一次性高峰有关,后者可能会导致不可持续的参与闪电战。
  • 该产品有一个“粘性的问题,因为随着时间的推移,我们的用户似乎越来越不喜欢我们的产品。

潜在原因 5 :由于我们的每周摘要电子邮件未能达到预期目的而导致参与度下降。

  • 为了吸引和重新吸引用户,Yammer 每周都会发送摘要邮件和重新吸引邮件。
  • 根据上面的图表,每周发送的电子邮件数量和每周打开的电子邮件数量一直在增加,但每周点击率大幅下降,而每周重新参与度指标正常。

  • 即使打开率在增加,点击率的降低也可能意味着每周摘要电子邮件内容与用户不够相关,或者预期的用户动作不够明确。如果 CTR 为 0,则表明按钮或功能损坏。

潜在原因 6

  • 如上图所示,使用手机的用户的参与度下降更为明显
  • 这可能是由于 Yammer 的移动应用程序最近的变化或发布

  • 为了更好地理解,在不同的操作系统之间比较相同的指标是有用的,因为每个操作系统的应用程序都有不同的代码版本
  • 看起来不管什么操作系统,通过手机访问 Yammer 的用户越来越少参与
  • 这种情况让我认为,随着时间的推移,留住 Yammer 手机用户存在问题,这可能是由于 UX 的设计问题或功能失调导致的不满。

结论

从我们的分析中,我们可以推断,长期访问 Yammer 的移动用户会因为可用性问题或不相关的内容而逐渐脱离。尽管电子邮件打开率相对较高,但我们从每周摘要中观察到的点击率要低得多。这可能意味着我们的电子邮件内容存在问题,例如相关性或质量。

鉴于用户参与度下降的多种不同假设,我会与其他学科,如工程、设计、营销和产品,讨论验证策略。验证策略包括 AB 测试、功能回滚和区域划分。

学习使用的技术

  • 自从我用 SQL 开始我的数据之旅以来,我用 SQL 做连接和聚合要比 Pandas 舒服得多。我决定使用 SQLite 进行所有更复杂的数据操作,并发现大部分功能和语法与 MySQL 相同。在我的用例中,主要的区别在于的日期和时间函数。如果 SQL 语法是您首选的语言,我建议个人使用 SQLite 来查询数据框。
  • 我使用 Plotly 的 Python 图形库来实现所有的可视化和交互式图表/图形。我喜欢交互式组件:悬停、单击和拖动以放大元素和 Plotly 图表的简单布局。与 Matplotlib、Seaborn 和 Bokeh 相比,这是我更喜欢的可视化库。我发现很难在网上找到关于如何绘制某些图形的案例具体示例,所以我不确定我是否以最有效的方式绘制了折线图和条形图——希望听到一些关于所写代码的反馈。
  • Plotly 的交互图表也不能在 GitHub 中渲染。如果你想保留你的图表来分享你的 Jupyter 笔记本/实验室中的分析,我推荐使用 nbviewer 来渲染你发布的笔记本。

你可以在这里找到原案:https://mode.com/sql-tutorial/a-drop-in-user-engagement/

使用 OpenCV,TensorFlow,MNIST,在 Python 中检测 Yatzy 评分表

原文:https://towardsdatascience.com/yatzy-score-sheet-detection-in-python-using-opencv-tensorflow-mnist-97ce685d80e0?source=collection_archive---------11-----------------------

完整的实现与代码部分的图像处理和 CNN 模型训练

Yatzy 评分表 iOS 应用程序

自从几年前我开始玩 yatzy(真的,有点上瘾)以来,我一直希望我们有机会玩 Yatzy 而不需要物理分数表。我发现了一些应用程序,但没有一个真正好用或有趣的。在发布了一个简单的 yatzy 分数跟踪应用程序后,我的工程头脑开始发挥扫描 yatzy 分数表的想法。我意识到,对于部署的计算机视觉任务来说,这可能是一个合理范围内的好任务。它还将包括机器学习,在那里你必须考虑更多的事情,而不仅仅是在 测试 集上获得最佳准确度。您必须部署您的模型,让您的生产数据符合模型等等。在这篇文章中,我将介绍这个项目的各个步骤,包括从 RGB 图像中识别 yatzy 评分表,并对手写输入的数字进行分类。代码是使用 OpenCV 和 TensorFlow 用 Python 写的。

第 1 部分:识别 Yatzy 表

这种分类/检测任务的一种(强力)方法是将我们所有的轮廓传递给 TensorFlow CNN 模型进行预测,并训练它能够从手写数字中分离噪声。然而,这将意味着我们可能不得不将大量的噪声传递给我们的模型进行预处理和预测。对于我们的模型来说,这不是一个微不足道的任务,因为我们不知道这些数字相对于图像应该有多大。我们也不知道这些轮廓属于什么样的细胞(点)?这就是为什么我们开始识别 yatzy 表,并“减去”网格,以确保我们只(希望)发送数字到分类器。为了识别任意工作表,我们需要定义定义任意工作表的规则。我对常规工作表使用的规则是:

  • 19 行数。
  • 网格中的每个任意单元格具有相似的尺寸,即不同单元格的高度宽度相同。

识别网格的步骤:

  1. 将 RGB 图像转换为单通道二值图像。

RGB 到二进制图像

步骤 1 的代码

2.识别最大的轮廓(具有相似强度的连接点)

最大轮廓。第二步

3.根据可以用一个矩形表示的最小面积对图像轮廓进行旋转。

在步骤 3 中旋转之前,最大轮廓的最小旋转矩形区域

步骤 2 和 3 的代码

步骤 2 和 3 的代码

4.对二进制图像执行形态学操作,以便在新的二进制图像上绘制垂直和水平线条,表示 yatzy 网格。有关绘制的线条,请参见下图。

步骤 4 之后,绘制了垂直水平线的二进制图像

步骤 4 的代码,识别 yatzy 网格

步骤 4 的代码

5.识别 yatzy 网格中的每个 Yatzy 单元格,并按照最左上角的位置对它们进行列排序 (x,y) 。我们通过在步骤 4 的二进制图像上使用 findContours 来实现,该图像只包含水平/垂直线条。

参见调用上述代码的完整 generate_yatzy_sheet 函数。

调用步骤 1–5 的函数

以上要点的完整源代码可从 这里 获得

第二部分。手写数字训练

MNIST 是一个包含 70 000 张 28x28 图像和手写数字的数据集。35,000 个来自高中生,35,000 个来自人口普查局员工,分成 60,000 个用于训练图像,10,000 个用于测试各自的组。

来自 MNIST 数据集的样本图像

MNIST 图像的尺寸为 28×28 像素,是黑白的,带有一些灰度,这是标准化算法(高斯等)使用的反走样技术的结果。手写数字包含在一个 20×20 的边界框中,具有保留的纵横比。然后,通过在每个侧面图像上引入 4 个像素的填充,将 20x20 的盒子转换为 28x28 的容器。然后,通过计算质心并将其平移到这个 CoM 点,该数字在 28×28 像素的图像中居中。质心实际上是 x 轴和 y 轴上的白色像素平均值。(我们稍后将模仿这些步骤进行产量预测)

对于训练,我们使用 CNN 架构。如果你不熟悉 CNN,我推荐你在这里阅读更多相关内容。

INPUT -> CONV3-32 -> RELU -> CONV3-32 -> RELU -> CONV3-32 -> RELU -> POOL -> DROPOUT -> FC -> RELU -> DROPOUT -> SOFTMAX

下面的代码用于为模型定型。请注意我们是如何去除高斯反走样并将图像转换为二进制图像的。我们这样做是因为我们不知道在 MNIST 使用的精确算法来创建反锯齿效果。否则,我们的生产数据将与培训设置不匹配。我们可以执行一个新的高斯反走样效果后,我们把它变成二进制,但是在测试后,我没有注意到高斯过滤器的任何性能改善。

转换成二进制图像后的来自 MNIST 的样本图像

训练我们的卷积神经网络的全部代码。

训练卷积神经网络

最后,我们打印 train/val 损失和 train/val 精度,以衡量我们的模型在不同时期的表现。看起来没问题,合理的验证指标很好地遵循了培训。

CNN 模型的度量

把它放在一起

现在,当我们拥有数组格式的 yatzy 网格和 CNN 模型时,我们可以开始用 yatzy 单元绘制数字轮廓位置,并通过感兴趣区域(ROI)进行预测。

  1. 阅读张量流模型
  2. 从 RGB 图像生成任意图片
  3. 使用生成的 Yatzy 表(没有任何网格)来查找数字的轮廓
  4. 将 ROI 预处理为张量流模型的正确格式。(轮班等)

5.通过 ROI 进行预测

最终结果包含附加到每个轮廓的相应分类数字。(注意我们的模型如何(直观地)将 A 和 B 解释为 4 和 8)

带分类数字的任意网格

这都是为了这个 python 实现。在 Yatzy 评分表中运行的代码被移植到 Objective C++并进行优化(例如,跳过一些重复的操作,以便在整个 python 程序中保持不同的图像版本)。因为我们知道这些数字属于哪个 yatzy 单元格,所以我们可以使用它在应用程序屏幕“预览工作表”中显示工作表,并选择保存工作表。请注意,有些单元格的背景颜色为红色,这表明我们的 CNN 模型对预测的数字是正确的有多大把握(在 0-1.0 之间)。然后,用户能够手动验证和更新那些具有错误预测的数字。

这篇文章的完整源代码可以在的 Github repo 中找到

Yellowbrick —通过可视化分析您的机器学习模型

原文:https://towardsdatascience.com/yellowbrick-analyze-your-machine-learning-model-with-visualizations-f2c65ab2e229?source=collection_archive---------43-----------------------

用于机器学习可视化的 Python 库

Joshua Hoehne 在 Unsplash 上拍摄的照片

Yellowbrick 是一个 Python 机器学习可视化库。它本质上是建立在 Scikit-learn 和 Matplotlib 之上的。Yellowbrick 提供了信息丰富的可视化,以更好地评估机器学习模型。这也有助于模型选择的过程。

这个帖子更多的是 Yellowbrick 的实际应用。我们将快速构建一个基本的分类模型,然后使用 Yellowbrick 工具来评估我们的模型。我们可以把它分成两部分:

  1. 创建机器学习模型
  2. 黄砖时间!

创建机器学习模型

任务是预测银行客户的流失。流失预测是机器学习领域的一个常见用例。如果你不熟悉这个术语,churn 的意思是“离开公司”。对于一个企业来说,了解客户可能流失的原因和时间是非常重要的。

我们将使用的数据集可从 Kaggle 上的这里获得。这篇文章的重点是评估分类器性能的可视化。因此,实际的模型构建部分将会快速而简洁。

让我们从导入依赖项开始。

import numpy as np
import pandas as pdimport matplotlib.pyplot as plt
%matplotlib inlineimport yellowbrick

我们将数据集读入熊猫数据帧,并删除多余的特征。

df_churn = pd.read_csv("/content/Churn_Modelling.csv")df_churn.drop(['RowNumber', 'CustomerId', 'Surname'], axis=1, inplace=True)df_churn.head()

“退出”栏表示客户流失。

流失数据集通常是不平衡的。类别 0(非流失)的数量明显多于类别 1(流失)的数量。这种不平衡会对模型的性能产生负面影响。因此,最好消除这种不平衡。

有不同的方法来使用它作为解决方案。我们可以进行过采样(增加少数类的观测值)或欠采样(减少多数类的观测值)。

最常见的一种是 SMOTE (合成少数过采样技术)。SMOTE 算法创建与现有样本相似的新样本。它采用两个或更多相似的观察值,并通过一次改变一个属性来创建一个综合观察值。

在使用 SMOTE 算法之前,我们需要将类别转换成数值。

gender = {'Female':0, 'Male':1}
country = {'France':0, 'Germany':1, 'Spain':2}df_churn['Gender'].replace(gender, inplace=True)
df_churn['Geography'].replace(country, inplace=True)

我们来确认一下阶级不平衡:

df_churn['Exited'].value_counts()
0    7963 
1    2037 
Name: Exited, dtype: int64

正类(流失)的数量大约比负类(非流失)的数量高 4 倍。

X = df_churn.drop('Exited', axis=1)
y = df_churn['Exited']from imblearn.over_sampling import SMOTE
sm = SMOTE(random_state=42)
X_resampled, y_resampled = sm.fit_resample(X, y)print(pd.Series(y_resampled).value_counts())
1    7963 
0    7963 
dtype: int64

现在正反类数量相等。训练模型之前的最后一步是将数据集分成训练和测试子集。

from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X_resampled, y_resampled, test_size=0.2)

是时候创建一个模型并训练它了。我将使用随机森林算法。

from sklearn.ensemble import RandomForestClassifierrf = RandomForestClassifier(max_depth=11, n_estimators=260)
rf.fit(X_train, y_train)from sklearn.metrics import accuracy_score
y_pred = rf.predict(X_train)
y_test_pred = rf.predict(X_test)
train_acc = accuracy_score(y_pred, y_train)
test_acc = accuracy_score(y_test_pred, y_test)print(f'Train accuracy is {train_acc}. Test accuracy is {test_acc}')

黄砖时间!

在分类任务中,尤其是在存在类别不平衡的情况下,准确度不是评估度量的最优选择。例如,预测正面类别(客户流失=1)比预测负面类别更重要,因为我们想确定客户是否会流失。我们可以承受对负类的错误预测

一种分别检查正负类预测的方法是混淆矩阵。

from yellowbrick.classifier import ConfusionMatrixplt.figure()
plt.title("Confusion Matrix", fontsize=18)
plt.xlabel("Predicted Class", fontsize=16)
plt.ylabel("True Class", fontsize=15)cm = ConfusionMatrix(rf, classes=[0,1], size=(400,400),
fontsize=15, cmap='GnBu')cm.fit(X_train, y_train)
cm.score(X_test, y_test)

在正类中,我们有 1419 个正确的预测和 213 个错误的预测。我们也可以通过将百分比参数设置为真来显示百分比,而不是数字。

该模型在负类上表现更好,这不是我们想要的。实现这一点的一个方法是告诉模型“正类(1)比负类(0)更重要”。使用我们的随机森林分类器,可以通过 class_weight 参数来实现。

评估分类模型性能的另一个工具是 ROC(接收机工作特性)曲线和 AOC(曲线下面积)。

ROC 曲线通过组合所有阈值的混淆矩阵总结了性能。 AUC 将 ROC 曲线转化为二元分类器性能的数字表示。AUC 是 ROC 曲线下的面积,取 0 到 1 之间的值。AUC 表示一个模型在区分正类和负类方面有多成功。

from yellowbrick.classifier import ROCAUCplt.figure(figsize=(10,6))
plt.title("ROC Curve and AUC", fontsize=18)
plt.xlabel("False Positive Rate", fontsize=16)
plt.ylabel("True Positive Rate", fontsize=16)visualizer = ROCAUC(rf, classes=["Not-churned", "Churned"])
visualizer.fit(X_train, y_train)
visualizer.score(X_test, y_test)plt.legend()

ROC 曲线概述了不同阈值下的模型性能。AUC 是介于(0,0)和(1,1)之间的 ROC 曲线下的面积,可以使用积分来计算。AUC 基本上汇总了模型在所有阈值的表现。AUC 的最佳可能值是 1,这表示一个完美的分类器。如果所有的预测都是错误的,则 AUC 为零。

当涉及到不平衡数据集时,精度召回通常是评价指标的选择。

精度的焦点是正面预测。它表明有多少积极的预测是正确的。

召回的重点是实际正课。它表示模型能够正确预测的阳性类别的数量。

注意:我们不能试图同时最大化精确度和召回率,因为它们之间有一个平衡。提高精度会降低召回率,反之亦然。我们可以根据任务来最大化精确度或回忆。

Yellowbrick 还提供了精度-召回曲线,显示了精度和召回之间的权衡。

from yellowbrick.classifier import PrecisionRecallCurveplt.figure(figsize=(10,6))
plt.title("Precision-Recall Curve", fontsize=18)
plt.xlabel("Recall", fontsize=16)
plt.ylabel("Precision", fontsize=16)viz = PrecisionRecallCurve(rf)
viz.fit(X_train, y_train)
viz.score(X_test, y_test)
plt.legend(loc='lower right', fontsize=12)

在某个时间点之后,提高召回率会导致准确率显著下降。

Yellowbrick 还提供了以下可视化功能,这些功能在评估分类模型时非常有用:

  • 分类报告
  • 类别预测误差
  • 辨别阈值(仅用于二元分类)

在评估模型的过程中使用信息可视化将为您提供许多见解。它将引导你以一种有效的方式改进你的模型。

不要只看数字,试着用不同的方法来评估,从而改进你的模型。

感谢您的阅读。如果您有任何反馈,请告诉我。

Yelp 餐厅推荐系统——数据科学顶点项目

原文:https://towardsdatascience.com/yelp-restaurant-recommendation-system-capstone-project-264fe7a7dea1?source=collection_archive---------9-----------------------

深入了解我参加数据科学训练营并为我的顶点项目构建餐厅推荐系统的经历。

卢克·切瑟Unsplash 上拍摄的照片

个人反思:

在过去的 3 个月里,我有机会在新加坡完成了大会的数据科学沉浸式训练营。编码训练营的性质意味着这是一次具有陡峭学习曲线的激烈体验,涵盖机器学习主题,如特征工程、决策树、自然语言处理和深度学习神经网络,所有这些都在短短的 12 周内!尽管如此,这次经历还是丰富了我的人生,因为它给了我日复一日用 Python 编程的机会,完成了编程任务,也为我的作品集做了个人数据科学项目。凭借在这次训练营中获得的技能,我现在真的有信心以全职职业身份进入数据科学领域。

回顾过去的几个月,这个训练营让我对端到端数据科学流程有了深刻的理解,并熟悉了数据分析和数据建模所需的编程语言和工具。在训练营即将结束时,每个学生都有机会参与一个个人顶点项目,展示我们在 12 周内学到的所有数据科学概念和技术。在这篇文章中,我将解释我的顶点项目以及我着手构建数据科学模型的端到端流程。

美食餐厅推荐系统

食客集体Unsplash 上的照片

对于我的顶点项目,我想建造一些对人们日常生活有意义的东西。这最终导致我建立了一个推荐系统模型,它可以根据其他人对餐馆的评论向人们推荐他们位置附近的餐馆,利用情感分析,这可能会改善你在 Deliveroo、GrabFood 和 FoodPanda 等常见食品交付应用程序上看到的推荐建议。

作者图片

出于这个数据科学项目的目的,我在其上构建模型的数据集来自 Yelp 数据集,该数据集已经公开用于个人、教育和学术目的。由于这个数据集的巨大规模,我决定将我的工作集中在多伦多市的餐馆评论数据上,因为与这个数据集中的其他 9 个城市相比,它有最多的评论。这给我留下了从 2015 年到 2019 年总共5471 家餐厅44485 名用户253050 条餐厅评论的数据。

解释性数据分析

作者图片

使用 Python 中的 Plotly 包,我能够创建多伦多市餐馆的地理可视化。大多数餐馆生意都集中在多伦多市中心,这是主要的中央商业区。

在各种餐馆类别中,排名前五的类别是:夜生活、酒吧、咖啡&茶、快餐和早餐&早午餐。

作者图片

对于每条餐厅评论,每个用户都给出了 1-5 分的评分,表示他们光顾餐厅的总体体验。评论评分的分布向左倾斜,平均而言,给出较高评分的用户比给出较低评分的用户多。

负面(左)和正面(右)评论的文字云,图片由作者提供

自然语言处理

利用每个 Yelp 用户留下的文本评论,我能够通过整合他们文本评论的情感分析为每个用户创建新的评分。情绪分析是确定用户的态度或情绪(无论是积极还是消极或者中立)的过程。

Textblob 的极性得分能够给我一个分数,表明一个陈述在从-1(负)到 1(正)的范围内有多积极或消极。此外,我还使用了 VADER(效价感知词典和情感推理机),这是一个基于词典和规则的情感分析工具,专门针对社交媒体中表达的情感。 VADER 的综合得分也显示了一个陈述的积极或消极程度,范围从-1(非常消极)到 1(非常积极)。

通过合并这些量化的情感分数,我能够为每个用户创建一个范围在[0,6]内的超级分数,更好地反映他们访问餐馆的整体体验,并使用该分数作为我的推荐模型的基础。

计算用户超级分数的公式,按作者排序的图像

话题造型

为了进一步理解我的评论数据中的文本,我使用了潜在狄利克雷分配(LDA),主题建模的一个例子,将文档中的文本分类到特定的主题。LDA 建立每文档主题模型和每主题单词模型,建模为狄利克雷分布

共 5 个主题的主题建模(LDA ),图片由作者提供

作者图片

在执行 LDA 之后,我能够创建几个主导主题,这些主题可以让我对人们在 Yelp 评论中谈论的主题类型产生有趣的见解。具体来说,来自我的 LDA 情节的主题 3、4 和 5 创建了将评论与特定食物烹饪相关联的主题(西方、甜点、亚洲)。将不同的评论分配给不同的主导主题将允许我建立一个基于内容的推荐模型,根据相似的偏好向用户推荐餐馆。

基于位置的推荐系统

作者图片

为了解决最初的用户冷启动问题,我决定使用一个简单的解决方案,通过位置邻近数据向新用户推荐餐馆。知道一个人在决定寻找新餐馆时的地理位置,我们可以使用基于位置的推荐系统来推荐他/她附近的餐馆。通过为用户提供方便的初始推荐,我们可以吸引他/她开始使用我们的应用程序,然后根据他/她的初始偏好推荐其他餐厅。

根据地理位置对餐馆进行分组的一种方法是使用 K-Means 聚类算法。 K-Means 算法预测用户所在的聚类,并从中抽取出前 10 家餐厅推荐给他。

多伦多的餐馆根据地理位置的远近分成 10 类,图片由作者提供

案例分析

例如,我们有一个新用户,他刚刚参观了皇家安大略博物馆。他想吃顿饭,但不确定他家附近有什么好餐馆。通过将他的经度和纬度坐标输入到我们的模型中,我们可以向他推荐他所在位置附近的 10 家高评级餐厅,并让他有兴趣作为用户使用我们的推荐应用程序。

作者图片

协作和基于内容的过滤

约翰·施诺布里奇在 Unsplash 上的照片

一旦我们让新用户开始使用我们的应用程序,我们可以通过以下 4 个步骤来改进我们的模型推荐:接受反馈,重新训练模型,对预测评级进行排序,返回最高的预测推荐。

对于我的协同过滤推荐模型,它的工作原理是搜索一大群人,找到与特定用户口味相似的一小群用户。它查看他们喜欢的餐馆,并将它们组合起来,创建一个推荐餐馆的排名列表。我创建物品-物品矩阵的 3 个主要步骤包括:

  1. 超级评分数据透视表,用于创建用户-项目矩阵
*# Creating the Matrix by using the Pivot Table Function* toronto_restaurant_rating = toronto_data.pivot_table(index = 'user_id', columns = 'name', values = 'super_score')toronto_restaurant_rating.head()

作者图片

2。截断奇异值分解

谈到矩阵分解技术,截断奇异值分解(SVD) 是一种常用的方法,可将矩阵 M 分解为三个矩阵 U、σ和 v。与常规 SVD 不同,截断 SVD 可产生一种分解,其中可针对多个截断指定列数。例如,给定一个(n x n)矩阵,截断 SVD 生成指定列数的矩阵,而 SVD 输出 n 列矩阵。截断 SVD 可以处理稀疏矩阵以生成特征矩阵,而主成分分析将对整个矩阵进行操作以输出协方差矩阵。

*# Converting the reconstructed matrix back to a Pandas dataframe*

cf_preds_df = pd.DataFrame(all_user_predicted_ratings, columns = toronto_restaurant_rating.columns, index=user_ids).transpose()

cf_preds_df

作者图片

3。基于余弦相似度创建基于项目的矩阵

*# Creating Item-Item Matrix based on Cosine Similarity*

item_item_matrix = cosine_similarity(cf_preds_df)item_item_matrix= pd.DataFrame(item_item_matrix, columns=cf_preds_df.index, index = cf_preds_df.index)item_item_matrix

作者图片

对于这个推荐模型,所有用户必须输入的是他们以前喜欢访问的一个餐馆名称到模型中,它将根据与该特定餐馆的最高余弦相似性得分生成 10 个最推荐餐馆的列表。

*# Top 10 Recommended Restaurants that people should visit if they had previously visited Pai Northern Thai Kitchen*

restaurant_recommendations = cf_recommender('Pai Northern Thai Kitchen')restaurant_recommendations = pd.DataFrame(data = restaurant_recommendations)restaurant_recommendations

作者图片

对于我的基于内容的推荐模型,它的工作原理是根据相似的餐馆类别和主导话题关键词向用户推荐餐馆,从而推荐符合用户偏好的餐馆。我创建物品-物品矩阵的 3 个主要步骤包括:

  1. 为每家餐厅创造一袋单词
*# Creating Bag of Words*

toronto_final['bag_of_words'] = ''
columns = toronto_final.columns
**for** index, row **in** toronto_final.iterrows():
    words = ''
    **for** col **in** columns:
            words = words + ' '.join(row[col])+ ' '
    row['bag_of_words'] = words

toronto_final.drop(columns = [col **for** col **in** toronto_final.columns **if** col!= 'bag_of_words'], inplace = **True**)

toronto_final.head()

作者图片

2。计数矢量器

CountVectorizer 将文本文档的集合转换为令牌计数的向量。此外,它支持在生成矢量表示之前对文本数据进行预处理。

*# instantiating and generating the count matrix*
count = CountVectorizer()
count_matrix = count.fit_transform(toronto_final['bag_of_words'])

*# creating a Series for the restaurant names so they are associated to an ordered numerical*
*# list I will use later to match the indexes*
indices = pd.Series(toronto_final.index)
indices[:5]

作者图片

3。创建余弦相似矩阵

*# generating the cosine similarity matrix*cosine_sim = cosine_similarity(count_matrix, count_matrix)cosine_sim

作者图片

同样,对于这种推荐模型,用户只需输入他们以前喜欢去的餐馆名称到模型中,它将基于相似的分类和主导主题关键字生成 10 个最推荐餐馆的列表。

*# Top 10 Recommended Restaurants that people should visit if they had previously visited Pai Northern Thai Kitchen*content_based_recommendations('Pai Northern Thai Kitchen')

作者图片

对新加坡 F&B 部门的申请

照片由 Ethan HuUnsplash 上拍摄

在今年早些时候的断路器时期,由于缺乏顾客和订单,许多不太知名的餐馆都在这段时间里苦苦挣扎。

随着新加坡在 2020 年底缓慢进入第三阶段,更多的人将会以 5-8 人为一组,经常去镇上的餐馆。

因此,我的推荐模型可以为他们提供一个替代食物推荐系统,它可以推荐其他顾客评价很高的鲜为人知的当地餐馆。

为了帮助这样的餐馆,我未来需要的是当地餐馆企业和评论数据来训练我的推荐模型。

然而,我的模型也有一些限制。随着未来时间的推移,我可以探索其他方面来改进我的模型。其中包括:

  1. 在情感分析和主题建模中使用二元语法和三元语法。
  2. 结合深度学习&神经网络架构进行协同过滤。
  3. 图论应用于基于位置的系统,以优化旅行和交付路线。

最后的话

Denys NevozhaiUnsplash 上拍摄的照片

如果你已经走了这么远,我想真诚地感谢你花时间阅读我的文章。随着我进入商业和技术领域,我希望探索更多数据科学的趋势主题,这些主题可以用于改善人们的日常生活。

如果您想了解更多关于我未来的帖子,请在我继续我的数据科学之旅时在 Medium 上关注我!

Chipotle 如何重新赢得顾客?

原文:https://towardsdatascience.com/yelp-review-analysis-for-chipotle-with-natural-language-processing-bf4b3e5db140?source=collection_archive---------42-----------------------

针对 Chipotle 的 Yelp 评论分析,包含情感分析、词云和主题建模

Pixabay 上的 dolvita108 拍摄的照片

这是我们团队(黄尧晰杰克叶浩浩李玉婷)在 UC Davis MSBA 项目机器学习课上的最后一个项目。python 编码的逐步指导已经在 Github 分享:https://Github . com/cryyystal/Analysis-of-Yelp-Review-for-Chipotle-Mexican-Grill

概观

近年来,Chipotle 一直在流失顾客,在竞争激烈的快速休闲餐饮行业表现不佳。它尝试了许多方法来改善客户体验和重新赢得客户,如建立新的安全协议和引入数字订购渠道,如在线和移动应用程序订购。随着 Chipotle 采用越来越现代化的战略,我们推荐一种数据驱动的方法来帮助它改善业务。在这个项目中,我们使用几个自然语言处理工具来分析 Yelp 上的评论,以发现需要改进的地方并相应地提出建议。

Chipotle 项目的主要组成部分:

  • 应用 Textblob 计算每个评论的情感极性。
  • 分别绘制正面和负面评论的词云,看看哪些词在正面或负面评论中频繁出现。
  • 使用 LDA Mallet 进行主题建模,从所有评论中提取六个主题,并计算每个主题的平均情感得分。画一个雷达图,说明哪些题目是 Chipotle 的优势,哪些是它的劣势。
  • 做词语情绪的时间序列分析,通过它我们看到“line”“burrito”等重要词语在正面或负面评论中出现频率的月度变化。基于此,我们可以检测到 Chipotle 关键业务的痛点。

基于我们的分析,我们在原料质量、等待时间和数字订购方面为 Chipotle 提供了四点建议。第一个是提高原料的新鲜度和质量,以重获战略优势。第二个是调查供应链,看看如何提高其蛋白质的质量和味道,特别是鸡肉。第三个是调查其最重要的产品墨西哥卷饼的质量,该产品的正面评价越来越少。最后,Chipotle 应该改进在线订购系统和手机 app,以便更好地解决等待时间问题,改善客户的购买体验。

数据源

Yelp 在 Yelp 挑战数据集中提供了一个全面的数据集,包括所有的商家信息,如地址、提示、评论和评论者。我们合并“业务”表和“评论”表,并提取 Chipotle 的信息。总共有 9590 条关于 Chipotle 的评论。

数据集链接:https://www.yelp.com/dataset/challenge

自然语言处理分析

a)探索性数据分析

我们计算了 Chipotle 自 2006 年以来的每月平均评论星级,发现它随着时间的推移逐渐下降:回到 2010 年,平均评论星级约为 4.0,但现在约为 3.0(图 1)

图表 1

图表 2 显示了不同恒星的数量和比例如何随时间变化。随着时间的推移,5 星和 1 星评论在数量和比例上都有所增加,其中 1 星评论增加更为显著。这可能是图 1 中平均星级逐渐下降的主要原因。

图表 2

b)文本预处理

在 EDA 之后,我们做了一些文本预处理来提高 NLP 模型的性能,包括:

  • 文本去压缩。例如,将“不会”替换为“不会”,将“\ ve”替换为“有”,将“\ d”替换为“会”。
  • 把所有东西都变成小写。
  • 使用 NLTK 库删除停用词。停用词是非常常见的词,如“如果”、“但是”、“我们”、“他”、“她”和“他们”。我们通常可以在不改变文本语义的情况下删除这些单词。
  • 删除空格和标点符号。经过上述处理后,可能会有一些空格混在文字中,所以我们需要去除这些空格。此外,我们也删除标点符号,如“,”。?!:“且只留言。
  • 使用 NLTK 词干的单词词条化。词汇化是将一个单词的不同屈折形式组合在一起的过程,这样它们就可以作为一个项目进行分析。例如,在词汇化之后,“哭”就是“哭”。

文本预处理前后的评论比较如下:

以前

"I'm a regular at chipotle in California, this is my first visit to this chipotle on s.las Vegas strip.this is pretty new place I think, I took a veggie bowl in which the rice was undone and the fajitas were all burnt, the quantity offered was less than usual. I'm very unhappy with this place."

在...之后

'regular chipotle california first visit chipotle s la vega strip this pretty new place think took veggie bowl rice undone fajitas burnt quantity offered le usual unhappy place'

c)情感分析

我们使用 Textblob 为每个评论分配一个情感分数,以衡量评论的积极程度或消极程度。如果情绪得分大于 0,则评论为正,反之,则评论为负。从图表 3 中,我们可以看到正面评价是负面评价的两倍。

图表 3

绘制图表 4 以查看评论星级和情感分数之间的关系。显然,随着星级的增加,平均情绪得分也增加。然而,对于 1 星评价,它们可能是正面的或负面的,但对于 4 星和 5 星评价,它们基本上是正面的。

图表 4

d)词云

我们先用词云看看评论的全貌。我们分别为正面评价和负面评价画一个词云,看看区别。我们删除了在正面和负面评论中出现频率非常高的词,包括“chipotle”、“burrito”和“place”,因为它们在两个图中都非常大。我们可以看到,正面评价中最大的词是“肉”、“工作人员”、“服务”,而负面评价中最大的词是“行”和“鸡”。顾客喜欢 Chipotle 的肉,但鸡肉似乎不是这样。尽管 Chipotle 的队伍可能有点长,顾客可能要等一会儿,但他们对 Chipotle 的员工和服务感到满意。

图表 5

图表 6

e)主题建模

考虑到评论的大背景,我们使用主题建模,特别是通过 Mallet (LdaMallet)的潜在 Dirichlet 分配,从所有单词中提取关键主题。然后,我们衡量每个主题的情感得分,看看 Chipotle 在哪些方面做得好,哪些方面做得差。

我们画一个六边形,每个分数加 0.1,让对比更清晰。我们可以从图表 7 中看到,与成分相关的主题(新鲜度/成分/质量)得分最高,与 Chipotle 的“新鲜度”和“完整性”的价值观相呼应。与环境相关的主题(位置/干净/漂亮/友好)获得第二高。与排队相关的话题(时间/排队/等待/长时间/在线)、与食物相关的话题(肉/鸡肉/薯条/米饭/鳄梨酱/牛排/生菜)、与服务相关的话题(服务/员工/糟糕)、与支付相关的话题(支付/经理/收银员)得分较低。

图表 7

我们将每个评论分配给占该评论比例最大的主题,并计算一段时间内所有六个主题的平均情绪得分。为了更清楚地看到 4 个得分较低的主题的趋势,我们绘制了图表,将它们与成分相关的主题(新鲜度/成分/质量)进行比较。我们发现,线路相关话题(时间/线路/等待/时长/在线)的平均情绪得分在 2013 年之前在 0.1 左右浮动,2013 年显著下降,之后在 0 左右浮动(图 8)。

图表 8

f)时间序列情感分析

利用时间序列方法,我们将感兴趣词(WOI)的情感变化与每月的星级变化一起可视化。我们首先定义衡量词语情感的标准:

像词云一样,我们根据 WOI 在正面/负面评论中的出现频率来确定其情绪。我们将这种情况正常化,因为评论的总数每月都在变化。因此,该指标测量在任一情绪类别的评论中 WOI 的归一化频率。如附录 1.1 所示,正面评价和负面评价都是随着时间的推移逐渐增加的。我们还决定只分析 2012 年之后的评论,因为 2012 年之前的评论太少了(附录 1.1)。我们使用三种方法来解释我们的可视化指标。

1.正面评价中 WOI 出现率下降

如果一个词曾经有很高的阳性率,我们可以说它是企业的强项。正比率的下降表明餐厅正在失去这方面的优势。根据图 9,Chipotle 应该调查其菜单项的新鲜度及其墨西哥卷饼产品的质量。

图表 9

2.负面评论中 WOI 出现率增加

负面评价出现率较高的 WOI 表明 Chipotle 在这方面可能表现不佳。从图表 10 可以看出,“线”的出现率从 2012 年开始增加,从 2015 年开始减少。这一下降反映了 Chipotle 在 2014 年推出了其移动订购应用,旨在减少 line。因此,我们可以推断,Chipotle 通过数字订购缩短顾客等待时间的策略是成功的。展望未来,Chipotle 应该继续推行这一举措。

图表 10

3.两种综述中 WOI 发生率的比较

如果 WOI 在正面评论中的出现率高于负面评论,则它是正面情绪。我们将“伟大”视为基线(附录 1.2)。因此,当一个中立的 WOI 在正面评论中的出现率高于负面评论时,它可以被视为该业务的一个积极方面。反之亦然。图表 11 显示“在线”和“应用程序”都是中性词,但在负面评价中的出现率始终高于正面评价。这表明 Chipotle 在数字商务渠道中表现不佳。它需要改进其移动订购应用程序和在线订购系统,以增强客户的购买体验。

图表 11

推荐

根据我们的分析结果,我们在配料质量、等待时间和数字订购方面向 Chipotle 提出了建议。

从主题建模中,我们发现与配料相关的主题(新鲜/配料/质量)具有最高的情感得分,这与 Chipotle 提供完整新鲜食品的战略优势相一致。然而,随着时间的推移,通过可视化关键词“新鲜”的情绪,我们发现“新鲜”正在慢慢消失在积极的评论中。这表明,从消费者的角度来看,Chipotle 正在失去其在采购新鲜食材方面的优势。因此,Chipotle 应该调查其原料的新鲜度和质量,以重新获得战略优势。另一方面,我们建议 Chipotle 调查其供应链,看看如何提高其蛋白质的质量和口味,特别是鸡肉,根据词云,它在负面评论中出现得非常频繁。就其菜单项而言,Chipotle 还需要调查其最重要的产品墨西哥卷饼的当前质量,这种产品在正面评价中越来越少。也可以对墨西哥卷饼做一些市场调查,看看为什么墨西哥卷饼正在失去对顾客的吸引力。

另一方面,等待时间和排队显然是 Chipotle 的一个问题。主题建模和词云都表明,“线”是顾客对 Chipotle 负面情绪的一大贡献因素。为了解决这一问题,Chipotle 寻求在线订购和移动应用程序订购等数字渠道。如情感分析所示,等待时间问题因 2014 年引入移动应用程序订购而得到改善。然而,这还不够。我们发现“在线”和“应用程序”在顾客评论中的负面影响更大,表明顾客对 Chipotle 的数字订购体验不满意。有鉴于此,Chipotle 需要改进其在线订购系统和移动应用程序,以便更好地解决等待时间问题,并改善客户的购买体验。

是的,你可以在网上成为一名数据科学家。以下是方法。

原文:https://towardsdatascience.com/yes-you-can-become-a-data-scientist-online-heres-how-dc73c7faae0f?source=collection_archive---------12-----------------------

在线学习的专业数据科学家指导您在家开始数据科学生涯

维多利亚·希斯在Unsplash【1】上拍摄的照片。

目录

  1. 介绍
  2. 在线课程
  3. 在线学位
  4. 业余的
  5. 摘要
  6. 参考

介绍

几篇文章强调了通过在线课程或学位的方式在数据科学领域取得成功是多么困难和牵强。既然你正在读这篇文章,也许你对自学和在线学习的成功也有一些信念。虽然数据科学似乎是一个新兴的领域,但它已经存在了很长时间,比大多数人意识到的要长。想想谷歌搜索引擎——它利用自然语言处理(NLP),这是数据科学的一个方面。

数据科学可以分为在数据分析、机器学习、人工智能、数据工程、软件工程、统计学和 AB 测试领域学习和工作的人。这些领域中的大多数(如果不是全部的话)都以某种方式涉及到了数据科学。学习数据科学最重要的部分是学习如何解决问题。传统统计学和现代数据科学的主要区别是自动化。假设 2000 年你在 Excel 或 SAS 中进行回归分析,现在有什么不同?现在,在学习数据科学时,有优先考虑的编程语言。Python 可能是自动化传统统计的最重要的工具。为了配合 Python,有几个库或包使数据科学变得更容易和更有效——sk learn、numpy 和 pandas。这些被证明在 20 世纪 90 年代从研究人员和科学家那里得到了相似或精确的原理,但现在被加速到几乎即时的结果、推论和预测。在全球疫情期间,办公室和面对面的机构都停摆了,现在是在线学习的最佳时机,这是前所未有的。

以下是如何成为一名成功的在线数据科学家的几个例子——来自一名在线学习的专业数据科学家。

在线课程

刘易斯·基冈——Skillscouter.com 在Unsplash【2】上的照片。

Coursera【3】——一个提供广泛课程和专业以及证书的在线平台。这个项目是由约翰霍普金斯大学开办的。你将学到很多技能,包括:

  • GitHub、机器学习、R 编程、回归分析、数据科学、Rstudio、数据分析、调试、数据操作、正则表达式(REGEX)、数据清理和聚类分析。

该计划显示,约 43%的人开始了新的职业生涯,19%的人在完成课程后获得了加薪或晋升。建议在 11 个月左右的时间内,成功完成这项训练,大约需要 7 个小时/周。因为它是在线的,所以它在 10 个专业化方面非常灵活,包括:

  • 数据科学家的工具箱、R 编程、获取和清理数据、探索性数据分析、Reprfodcle 研究、统计推断、回归模型、实用机器学习、开发数据产品和数据科学顶点。

Coursera 的程序是免费的——用于阅读和查看课程内容;然而,如果你想要完成工作的证书,那么你必须付费(也有经济资助)。完成这个专业,得到学习教授的批准,并得到 LinkedIn 等公司的认可,Coursera 是开始你的数据科学职业生涯的一个很好的方式。

Udemy【4】。Coursera 主要专注于一个中心项目,而 Udemy 则提供各种各样的数据科学课程。从机器学习到 Python,这些课程都很便宜,而且可以更加专业化。Udemy 的好处包括:

  • 无尽的视频
  • 文章
  • 可下载资源
  • 终身访问
  • 手机和电视接入
  • 结业证书

近 300 万名学生已经从 Udemy 学习,无论是从零开始,还是增强或转换他们的职业生涯到完全专注于数据科学。

梅蒂斯【5】。本次培训完全专注于 Kaplan 的数据科学,Kaplan 是一家声誉卓著的机构。Metis 强调是校友,对这个平台赞不绝口。从已建立的公司和创业公司,他们证明了他们的学生确实找到了成功。他们在脸书、Airbnb、IMB、Spotify、苹果和 BuzzFeed 等公司工作。为了使用他们的在线平台,而不是面对面的训练营,他们有一个名为“在线直播”的项目。

该计划的优势:

  • 从著名的数据科学指导中学习
  • 实时指令
  • 与其他同学互动协作

Metis 是一个混合选项,提供在线学习;不需要参加校园学习的在线训练营。

在线学位

照片由 Honey Yanibel Minaya CruzUnsplash【6】上拍摄。

更昂贵的选择是传统上从大学获得学位——但在现代意义上,是在线获得。这可能是一种风险更大的小型课程选择,因为你很可能会花费数千美元,但在劳动力中更专业。大学不计其数,大多是为了硕士。

最全面的列表可以在这里【7】找到。该网站包括:顶级学校、在线项目、相关学位、职业、在线课程、资源、训练营和大约 2U。一定要研究你的选择,因为这项投资会更贵,但从长远来看对你帮助最大。

我的故事:我参加了南方卫理公会大学(SMU)【8】在线学习,获得了数据科学硕士学位。我非常喜欢这个节目。通过网上学习,我可以在晚上继续我现在的工作和研究。这些课程都是实时的,你可以在一个晚上把它们堆在一起,也可以把它们分散到一周。我能够与来自世界各地不同背景的同学合作;项目的多样性非常突出。与我的现场本科学习相比,我能够更有效地应用我在网上学到的大部分知识。我在 Indeed 开始了我的正式分析职业生涯,然后搬到了 HomeAway (Vrbo),现在在 ScaleFactor 担任数据科学家。我从网上学习中获得了大部分经验。大多数学生从零开始学习数据科学,有些人在这个项目中不知道编码。在网上大学课程结束时,我的大多数朋友的职业生涯都发生了积极的变化。例如,学生从会计或技术支持职位转向专门的数据科学家,而我从分析化学转向数据科学。

业余的

社区。在线学习空间有一个大得惊人的社区。因为社交媒体在不断发展和增加,已经出现了几种形式的课外学习方式。现在有很多数据科学会议是在线的,而不是面对面的。有些被录制下来,也可以在网上观看。有了 Zoom 和其他会议平台,成为更大社区的一部分变得前所未有的容易和容易。

一些其他的学习方法是 Skillshare 和 YouTube。Skillshare 比传统的在线课程更加个性化,YouTube 上有数千个数据科学家的视频,他们热衷于教授各种技能,无论是用 Python 还是 R 编程,还是用 Airflow 和 GitHub 等工具弥合数据科学和生产机器学习之间的差距。

摘要

越来越多的职业开始于在线学习,数据科学也不例外。随着在家工作也变得越来越受欢迎,在线认证或经验越来越受到重视,有了新的获得在线学习成功的途径。我几乎所有的数据科学知识都是在网上学到的,无论是来自 SMU,一些 YouTube 视频,甚至是来自《走向数据科学》的教程。

读完我的文章后,我希望你会发现自己也有动力在家开始或加强你的数据科学事业。

参考

[1]由维多利亚·希斯Unsplash 上拍摄的照片,(2018)

[2]刘易斯·基冈-Skillscouter.com 在 Unsplash 上拍摄的照片(2020)

[3] Coursera ,(2020)

[4] Udemy ,(2020)

[5] 梅蒂斯,(2020)

[6]Honey Yanibel Minaya Cruz 在 Unsplash 上拍摄的照片,(2018)

[7] 2U 公司, mastersindatascience ,(2020)

[8]SMU(2020 年)

另一个是端到端时间序列项目教程

原文:https://towardsdatascience.com/yet-another-an-end-to-end-time-series-project-tutorial-37390bcea38e?source=collection_archive---------13-----------------------

来源:unsplash.com

时间序列分析是经典数据科学领域最常见同时也是最需要的任务之一。你可以在任何地方观察到这种类型的数据:股票和金融交易、物联网产生的数据、线上和线下零售销售,甚至是医疗记录,如心率、EKG、脑电图和核磁共振成像。

在这篇文章中,我用一些例子详细描述了从零开始执行一个时序项目的一般方法。首先,来自数据科学领域的新手分析师和项目经理可能会认为这些内容很有用,但是如果你是一个有点顽固的分析师,我相信你也会很高兴看到一些有趣的想法。

整个项目的代码GitHub资源库上可用

来源: memegenerator

时间序列预测是分析师或数据科学家在面对这类数据时试图解决的最常见问题。此外,发展中的物联网领域产生了异常检测任务,然而,在本文中,我们将详细介绍为未来预测而创建的序列模型。

在使用时间序列下的现代机器学习模型之前,考虑它们的一些基本概念非常重要:

  • 机器学习模型没有时间意识
  • 用于 ML 模型的观测值是独立的并且是均匀分布的
  • 信息存储在历史数据中,指示未来时间序列行为的信号
  • 基于树的算法不能预测趋势,也就是说,它们不能外推

注意,你不会在这里发现任何经典统计学和计量经济学模型的提及。这里只描述机器学习算法。当使用了足够的机器学习模型数据时,你在计量经济学模型的超参数选择上花费的时间是不合理的,这是有原因的。

时序项目的总体时间表

根据我的经验,序列分析项目已经通过类似的经典机器学习项目场景实现了。但是,在探索性数据分析和特征生成部分存在重要差异。

下面,我列举了时间序列分析项目中的一般阶段及其描述。

问题定义或目标设定 —项目的第一阶段是进一步执行的基础。在这一阶段,项目经理、数据科学团队或分析师会见代表内部部门或外部客户的业务负责人。在本次会议中,遵循以下清单非常重要:

  • 描述在项目过程中应该解决什么样的业务问题,以及它存在的原因
  • 定义可用数据和文档的整个范围,其中描述了数据生成的来源和方法
  • 定义预测范围的持续时间及其离散性(每小时、每天、每周等)
  • 与业务负责人和来自数据科学团队的人员一起,为模型质量的未来估计及其目标值定义一个关键指标,这些分析师将尝试达到该指标。

探索性数据分析(EDA)——这是所有数据科学项目的一个共同阶段,分析师面对一个新的数据集,并试图对其进行调查。此外,他们还试图评估其特征,如缺失值、数据中平稳值或趋势值分布的存在性等。

数据预处理和特征生成——任何机器学习项目的基本阶段,在这里你必须特别有创造力。在这个阶段,数据科学家生成预测器,这些预测器将成为未来模型的基础。模型的准确性和泛化能力也取决于这些特征。此外,我们不应该跳过模型预测的标准化或规范化步骤。粗略地说,整套功能可分为 3 大类:

  • shift—这种技术在时间序列模型中经常使用。主要的一点是,历史数据点包括关于未来时间点行为的信息。
  • 数学与统计特点 —关键思想与上一个相同,但这里我们要计算历史数据点之间的差异、标准差、最大值、最小值等统计量。
  • 领域知识 —传统上,它是最有用和最有价值的信息,但是提取起来非常复杂。可能存在只有领域专家才熟悉的外部附加数据或特殊统计数据。例如,如果您处理零售交易数据,关于营销活动的信息可能对您的模型非常重要。

培训 —这是一个简单明了的过程。但是,在模型训练期间,您应该始终考虑交叉验证。当您处理时间序列数据时,请确保选择相关类型的交叉验证。最后,不要忘记在这个阶段结束时查看模型准确性。

验证 —为您的模型提供从未见过的新信息,并评估它们的价值。这是对你的模型的碰撞测试。如果您观察到训练和测试的准确性之间的显著差异,很可能它们是过度拟合的,或者在测试数据中遇到了全新的信息。

基线——当您完成第一次训练——测试迭代时,您会得到一个基线。之后,您的目标是通过调整超参数跳过基线精度。

选择——通常你没有足够的时间为你的整套模型设置超参数,所以在第一次训练测试迭代后,你可能会选择最好的一个,然后努力提高它的质量。

整形 —一个基本的项目阶段,在这个阶段,你在调整你的模型的超参数下工作,目的是提高它的预测质量。顺便说一下,创建管道是获得模型超参数的最佳估计值的有效方法。

上线 —因此,在这一步中,我们有了一个足够准确的模型,它适用于企业主。这意味着是时候将我们的模型投入生产环境了。在这一步之前,你的模型可能只能在你的 Jupyter 笔记本上运行,但用户无法使用。为了最大限度地从你的工作中获取价值,你应该把模型放在一个有界面的环境中。这可能是任何人的软件的一部分,或者您也可以使用 Flask/Django,甚至集成到商业智能应用程序中,如 Tableau、QlikSense 或 Power BI。

请允许我忽略某些细节,跳过项目的第一步,尽管这是项目成功的关键因素,并专注于其他方面。

在进一步的解释中,我使用了 Kaggle 数据集,该数据集由 2014 年至 2019 年期间收集的 60 万笔交易数据组成,显示了销售日期和时间、药品品牌名称和销售数量,从个体药店的销售点系统导出。从数据集中选择的一组药物被分为以下解剖治疗化学(ATC)分类系统类别。

探索性数据分析(EDA)

初步数据分析是任何数据科学项目的重要组成部分。使用时间序列有 3 种主要的数据浏览类型:

  • 通过完整性和一致性检查数据质量-
  • 视觉分析
  • 统计分析

数据质量和结构

df.info()

因此,从 Kaggle 得到的数据包含两种类型的变量:float64、int64 和没有 NaN/missing 值。很有可能你永远也不会在现实世界中遇到如此清晰的数据。

df.head()

  • M01AB —抗炎和抗风湿产品、非类固醇、醋酸衍生物和相关物质
  • M01AE —抗炎和抗风湿产品、非类固醇、丙酸衍生物
  • N02BA——其他止痛药和退烧药、水杨酸及其衍生物
  • N02BE——其他止痛剂和退烧药、吡唑啉酮和苯胺
  • N05B —精神药物、抗焦虑药
  • N05C —精神药物、安眠药和镇静剂
  • R03 —治疗阻塞性气道疾病的药物
  • R06 —全身使用的抗组胺药
df.describe()

您可以看到中值和平均值(50%)非常接近,这意味着没有很多异常值。否则,存在,以查看 75%平铺和最大值之间的范围。
让我们算一算我们有多少离群值,它们在哪里。

视觉分析

看那个!所有这些都包括异常值。
按照统计学术语,离群值被定义为那些超出 3 IQR 的值。

作为探索性数据分析的一部分,有时查看关联矩阵对未来的模型调整或进一步的数据探索非常有用。
上图中,深色代表正相关,浅色代表负相关。例如,如果您想使用线性回归,您必须考虑删除相关变量以提高预测准确性。
在我们的例子中,我们可以看到相关类别(N05B、N05C 和 N02BA、N02BE)之间的弱相关性,以及 M01AE、N02BA 代码之间的有趣关联。进一步分析的目标可能是确定其中的原因。

统计分析

在这部分研究中,我们希望估计几个重要的统计参数:

趋势 —有序时间序列中单向的长期运动。

季节性 —是一系列具有特定重复间隔的事件,例如每月或每年。在大多数情况下,我们试图检测季节性,以消除季节性成分,并提取有关的额外信息,目的是提高模型的性能。注意,不要把季节性和周期性混淆。

很容易看出抗组胺药和止痛剂产品的销售有明显的季节性。另外,乍一看,数据看起来很稳定。
让我们通过应用 Dickey-Fuller 检验来确定一个时间序列是否平稳

平稳性 —指时间序列的统计特性不随时间变化。完成对该属性的研究是很重要的,因为如果将来的统计属性不会有很大的不同,那么将来的值可以很容易地预测。迪基-富勒检验或学生的 t 检验可用于观察平稳性。然而,请记住趋势和季节性显然会使数据不稳定,但对于周期来说就不清楚了。统计时间序列算法对此至关重要,如果数据不符合平稳性,就会失败。机器学习方法也受益于数据中更清晰的信号。

你可以看到我们已经将数据频率从每天一次改为每月一次
,这使得数据更具可读性,我们可以看到除了一个市场之外的所有市场都具有季节性
,同时,你可以看到 2015 年心理市场的销售数量如何增加,然后急剧下降
除季节性之外的呼吸道疾病市场的销售包括改善趋势
顺便说一下,你可能已经注意到迪基-富勒测试的 p 值图表的标题:

  • 当 p 值> 0,且数据不稳定时。
  • 否则,p 值= 0,零假设被拒绝,该过程被认为是平稳的。

自相关 —表示一段时间内原始时间序列和滞后时间序列之间的相似程度。这是执行回归分析的一个重要部分,因为回归模型假设数据没有自相关,否则不应该期望模型的高质量。

来演示。plot_pacf 函数起作用我们取的数据带有季节性。
如果自相关值接近 0,则意味着滞后观测值之间不相关。同时,值接近 1 或-1 的偏相关表明时间序列的滞后观测值之间存在很强的正相关或负相关。
蓝色阴影区域表示置信区间的边界。如果偏相关值超出了这个置信区间区域,那么可以假设观察到的偏相关值在统计上是显著的。

请注意,每日数值与最近的观察值高度相关,否则在月图上,您可以注意到与去年同月的显著相关性。

数据预处理和特征生成

一旦我们完成了探索性数据分析并检测到数据缺陷,就有时间为下一步构建数据集。

有 3 种广泛分布的方法可以更清晰地处理数据,以便进一步预测:

  • 应用 box-cox 变换稳定色散
  • 微分,或者换句话说,移动到相邻观测值的成对差异
  • 季节差异

提示

  • 如果数据集包含负观测值,则 box-cox 变换不可用,但是您可以为整个数据集添加正常数值并应用变换。
  • 在大多数情况下,box-cox 变换不会强烈影响预测的质量,反而会影响预测的范围。
  • 差异化有助于走出季节性和趋势性。除此之外,它还可以多次使用。
  • 两种区分方法可以一起使用,但是如果时间序列具有明显的季节性,最好从季节性区分开始

在我们实现了整个数据集的平稳性之后,是时候进入要素生成部分了。在那里,我们将创建预测器,作为模型的基础。

举例来说,我使用了多个滞后值、分类特征、时间周期和线性回归。实际上,现在试着比我更有创造力,根据你的领域知识生成有价值的特性,显著提高预测的准确性。

在特征生成的最后阶段,不要错过在管道中添加数据标准化的步骤。

培训

在迷人的探索性分析和严格的预处理之后,我们准备开始训练模型。

正如我上面提到的,当有足够的观测数据可用,并且您能够使用机器学习算法时,设置 ARMA、ARIMA、SARIMA 等统计模型的参数是不值得的。

因此,让我们同时训练几个模型,并通过 MAE 查看它们的质量,并在图表上强调错误线的部分,这些将展示模型失败的地方。

让我来说一说我们如何监控预测的偏差。有许多指标允许跟踪回归模型的性能,但是最流行的是:

MSE (均方差)——关注预测模型的多方向误差,但同时对异常值敏感,且由于缺乏与原始误差直接可比的可能性,解释复杂。

RMSE (均方根误差)—为了提高解释能力,我们能够采用平方根,并将完成值称为均方根误差,但它仍然对不良预测点敏感。在捕捉到一些不好的点之后,即使一个好的性能回归模型也会显示出很高的误差值。

MAE (平均绝对误差)——由于计算偏差的绝对值,我们能够最小化预测中坏点的影响。

MAPE (平均绝对百分比误差) 是相对性能指标之一,允许跨不同数据集比较模型的有效性,即使具有不同的观察范围。该指标的主要限制是,当数据集包含任何真实实例的零值时,不能使用它。

R 平方(决定系数) 显示模型对真实点的解释程度。定义域的取值范围为 0 到 1,越接近 1,实际观察值就越接近模型线。请注意,系数的缺点是当模型中加入额外的变量时,它的值会增长,即使这些变量并不显著。因此,R 平方不能用于比较变量数量不同的模型。

测试

在迭代的最后一步,我们想要比较预测值和我们的模型在项目的先前阶段从未见过的真实实例。遵循模型失败时的精确度和位置。如果您检测到在训练和测试数据集上计算的所选性能指标的级别之间存在显著差异,这将意味着您的模型过度拟合。要修复它,您应该自定义模型参数。

结论

本文描述了用机器学习算法建立预测模型的一般方法,并给出了第一次迭代的例子。然而,为了达到高质量的预测并为业务用户提取最大价值,在您的进一步迭代中,我建议将重点放在调整模型超参数、开发管道并将其置于生产环境中。

又一个“臭名昭著”的预测

原文:https://towardsdatascience.com/yet-another-notorious-prediction-a5b9d18cc710?source=collection_archive---------35-----------------------

Unsplashattendee拍照

预测一场战斗有多难?

作为一个普通的 MMA 粉丝,我的社交媒体上充斥着关于即将到来的康纳“臭名昭著”麦格雷戈对唐纳德“牛仔”塞罗恩比赛的帖子和文章链接。在 Lianne 和 Justin 在《走向数据科学》的文章中看到这个话题,我仍然感到惊讶。读了那篇文章后,我开始思考如何为这场比赛建立一个更好的预测。

数据

使用 www.fightprior.com 上共享的代码,我搜集了麦格雷戈、塞罗纳和他们来自 Sherdog.com的对手的 MMA 比赛历史,得到了 15000 场比赛的结果。

来自 sherdog.com

即使是一个普通的粉丝也知道“风格决定战斗”Sherdog 的数据显示了战斗是如何决定的,但几乎没有关于战士们如何赢得和输掉比赛的信息。我们能做什么来表现风格?进入福克斯体育 UFC 统计页面。

来自 foxsports.com

逆转(REV)、提交(SUB)、击倒(TD)和击打(STR)的次数是量化拳手风格的一种方式。但是这个数据有两个问题:这个表只有 139 名战士在收集的比赛历史中的数据,并且只有当前的生命统计数据。

例如,Sherdog 报告康纳的第一场比赛是由 TKO 通过罢工战胜加里莫里斯(2008 年 3 月)。但是在这场比赛中,康纳(大概)在他的职业生涯中没有任何表现。为了正确估计总打击模型对获胜概率的影响,我们希望第一场比赛的这些统计为零,然后对于 McGregor 的第二场比赛,我们希望包括第一场比赛的打击。相反,我们只有截至 2020 年 1 月的终身总罢工。

使用寿命总计来构建模型会在旧匹配的记录中产生来自未来的泄漏。后果是严重的:模型的成功预测可能被夸大了,并且这些统计数据之间的真实关系(如果有的话)成功的机会没有显示在数据中。

所以,在现实生活中,这些数据并不适合使用。但是对于一个没有错误负面影响的预测来说,看看它的表现可能会很有趣。

模型

Lianne 和 Justin 的文章报道了一个改进的 Elo 评级过程,并估计 McGregor 获胜的概率为 82%。我们的首要任务是用更小的数据集来验证这个结果。

PlayerRatings 包包含多个 Elo 评级变化。要捕捉评级随时间的完整演变,需要一个循环,如下所示:

结果与 Lianne 和 Justin 的工作方向一致,显示 McGregor 的评级在 2013 年超过 Cerrone。最终的评分是麦格雷戈 2550 分,赛罗内 2451 分,这意味着麦格雷戈获胜的概率是 64%。

这个预测有多好?我们可以从整个历史中获取赛前评级,并查看他们正确预测比赛结果的频率。下面的代码生成适当的评级列,并合并到 Fox Sports 的职业统计数据中,以创建最终的分析表。

这建立了大约 55%的正确预测的基线性能。对于增强模型,我们将通过 mgcv 包使用一个逻辑游戏。R 代码很简单:

gratia 包的 draw()函数从 GAM 生成平滑的 ggplot2 图表。

gratia::draw()显示了 GAM 估计的响应

有趣的是,收视率的差异(diffRate)给出了一个线性关系。。。据推测,逻辑链接负责这个驱动程序的非线性。敲除的差异(KDdiff)显示了与方向适当的结果的非常复杂的关系。每个拳击手获胜的双变量平滑显示,如果每个拳击手以相似的获胜次数进入拳击场,对战斗的结果几乎没有影响。

在训练样本上,该模型正确预测匹配的概率为 62%。并且在保持上做得更好,准确率为 63%,比单独的 Elo 评级提高了 15%。

这有点令人失望,甚至在承认它可能比现实更好之前,因为每个战士都使用了一生的统计数据。

最终预测

完成所有这些后,我们可以收集代表 McGregor-Cerrone 比赛的数据,并了解到玩家仍然喜欢“臭名昭著”(McGregor 获胜的概率为 62%)。这是两个模型在不同的数据上使用不同的方法显示麦格雷戈可能会赢。寻找第三个预测,让我们考虑一下公布的投注赔率。

照片由希瑟·吉尔Unsplash 上拍摄

麦格雷戈目前的下注线(截至 2020 年 1 月 13 日)是-325。将其转换为赔率,然后转换为概率,这相当于预测麦格雷戈的胜率约为 75%。

我很惊讶这些赔率对‘臭名昭著’如此有利。由于麦格雷戈已经离开拳击台很长一段时间(自 2018 年 10 月以来),Cerrone 很活跃(尽管经历了两连败),而且比赛重量更重(Cerrone 是两者中较大的一个),我认为“牛仔”有很大的机会获胜。考虑到游戏数据的问题和 Elo 评分显示的表现不足,我觉得这两个模型都不可信。我相信赌注已经被麦格雷戈在媒体上的过度表现动摇了。

我要选 Cerrone。

用 Python 构建收益率曲线

原文:https://towardsdatascience.com/yield-curve-building-in-python-8d7974a6e7e3?source=collection_archive---------7-----------------------

利用互换利率和 B 样条函数构建英镑互换期限结构

图片来自 Pixabay

收益率曲线的三个主要驱动因素

  1. 未来利率变化的市场预期
  2. 风险溢价
  3. 凸度偏差

从概念上讲,很容易将利率期限结构分解成这三个部分。

在现实中,司机在时间上是动态的,永远无法直接观察到。这使得现实世界的曲线形状更难解释,甚至可以让最好的生产模型变得陈旧。

任何有用分析的前提是知道曲线在哪里。

在流动性市场中,构建合适的曲线只需要很少的参数。通过在从经销商处的双向价格中可观察到的持续更新的价格之间进行插值,来处理繁重的工作。

在流动性差的市场,价格流干涸了。可观察到的市场价格变得稀缺,规模缩小,买卖盘扩大。这些低确定性时期可以成就或摧毁交易商、基金经理和交易算法。在这种情况下,拥有一个好的收益率曲线模型的潜在好处尤其大。

离开一会儿。推理统计学和数据挖掘(包括机器学习)的基础思想是,可以从样本数据中得出潜在过程的有意义的结论。一个被忽视但重要的子问题是在给定小样本的情况下提取推断。

将这个统计子问题与有利可图的金融建模任务相结合,这篇文章给出了以下结果:

1)使用 Python

对英镑(GBP)互换利率期限结构进行简单的 B 样条构造 2)过度拟合和领域主导的参数选择
3)不同市场条件下的压力测试

数据和方法

2020 年 1 月 30 日,英格兰银行货币政策委员会投票(7-2)维持英国利率不变。就在第二天,英国终止了欧盟成员资格。

ICE 交换率数据集

远离正常的市场环境,这使得英镑利率成为一个有趣的分析资产类别。注意,收益率曲线反转在曲线的前面。

给定 2020 年 1 月 30 日采样的英镑掉期利率数据(通过 ICE fixing),目标是构建完整的掉期利率期限结构。也就是说,为 3 个月到 30 年之间的任何期限构建一个互换利率。

ICE 的掉期利率数据通常从 1 年期开始,但是由于 1 年期掉期缺乏流动性,因此没有公布。因此,我增加了 3 个月和 6 个月的伦敦银行同业拆放利率,丰富了数据集。单位为百分比。

由于我使用了 Libor 和复合利率(来自互换),在这一点上零利率应该是自举的。然而,我们的目标是探索 B 样条回归,所以我选择不规范约定。它产生了一组更有趣的拟合点。

澄清一下,我没有预测利率。使用经济/社会/其他跨市场指标预测利率是另一回事。我们的目标是构建一幅市场描绘曲线的图画,而不是曲线应该在哪里(跳过有效市场假说)。

截至 2020 年 1 月 30 日的英国互换利率(来源:ICE)

来源: Ice 掉期利率Libor 利率

英镑互换期限结构的 b 样条构造

一个阶 M 的样条函数是输入变量中的一个次 M-1 的分段多项式。多项式块相遇的输入空间的值被称为节点。纽结以非递减顺序排序,当不同时,多项式段的第一个 M-2 导数在每个纽结上连续

任何样条函数都可以表示为同一分区上相同次数的基样条(B 样条)的唯一线性组合。我使用最小二乘法进行回归,以使模型符合扩充输入空间上的交换率数据集。以下是 B 样条曲线设置:

#B-spline Settings
M = 4
knots = [7.25,15.5,22.75]

没有太多的设置。

订单

4 阶样条函数对应于 3 次幂的多项式。4 阶样条俗称三次样条。三次样条是最低阶的样条,其纽结不连续性对于人眼是不可见的。光滑函数可以用局部多项式的更高次幂来实现,但是很少有理由超越三次样条。

绳结

我选择了三次样条与开放统一节点。这是一个结序列,其中内部结在输入域上等距分布,并在计算样条的域的边界处填充了额外的 M 个重复结。

这是第一个曲线构造的结果。

基于截至 2020 年 1 月 30 日的英国互换利率数据构建 b 样条曲线

b 样条 Python 代码

SciPy python 库提供了有用的函数来实现和评估一组样条函数。不过我自己实现了德布尔的除法差分算法。

遵照其他 ML 模型对象的结构,我构建了一个。fit() 函数对从返回的矩阵描述的样条使用最小二乘回归。build_spline_mat()

最后一步是。predict() 函数,在给定原始输入空间中的 x 值的情况下,填充插值,交换高音。

到目前为止…

鉴于英国利率数据,全球形势似乎得到了相对较好的描述。然而,曲线短端速率的可变性导致了该样条设置的一些局部问题。

虽然安装简单,但这离完工还很远。我现在介绍一个好的模型必须符合的关键标准,以及在不同市场条件下稳定性的潜在扩展。

什么构成了好的曲线?

判断施工方法质量的标准很短。

1)我能否将输入市场利率复制为构建曲线的输出?

2)曲线的稳定性如何?

第一次尝试没有成功。

曲线构建从一组观察到的市场价格开始,并且必须将这些价格恢复为输出。在其他回归实例中,这将是一个主要的过度拟合问题。但是根据定义,过度拟合假设数据表现出随机误差,这与有效市场假说相反——在给定当前信息的情况下,价格总是公平的。不管怎样,这种情况需要一个描述性模型,而不是预测性模型。

在这种情况下,样条线是一个完美的选择。它们允许输入之间的灵活插值。这种灵活性由样条线的顺序、域节点向量平滑控制。

平滑是一种正则化技术,与任何其他技术一样,它牺牲训练精度以支持系数的较低方差。这里,正则化反对我们的目标,所以我没有实现任何平滑。

回想一下,三次 b 样条的阶数是 4。我没有改变。这让我有了结的选择。

结选择

由于节点向量被填充,节点选择减少到拾取内部节点。一些研究论文深入研究最优节点选择,但这在很大程度上是领域不可知的。对于这个分析,我想通过领域知识来激发内部结的选择。

掉期交易通常被曲线各部分的驱动因素所分割。这种分割可能如下所示:

0y-2y

2y-6y

6y-12y

12y+

我使用了相关的结序列[2.5,6.5,12.5], kv3 ,作为下面一组结向量的一部分。

# interior knot vectors
kv1 = [7.25, 15.5, 22.75]
kv2 = [3.5, 7.5, 13.5]
kv3 = [2.5, 6.5, 12.5]

注意, kv2 分割域以确保每个区间内输入的均匀分布。

具有 3 个可选节点序列的 b 样条构造

如你所见——也好不到哪里去。我扔掉了结向量 kv1-kv3 。由于拟合的困难在于曲线的短端,我想也许纽结序列应该通过增加利率波动的已知区域的自由度来确定。我在这个区域添加了更多的结,并制作了序列 k4 — k6

3 种不同的打结顺序

然而,随着更多的迭代,我得到了一个额外的序列 k7 (只有 4 个内部结),我放弃了 k4

捕捉到转折点的 3 个结序列

所有三个模型都满足第一个标准。这种差异出现在收益率曲线反转前端的转折点。

在这个阶段很难说哪种特定的结构是最好的。在 600 万到 2000 万年期之间没有任何价格的情况下,选择变成了宏观经济观点的函数。尤其是对英国央行(BoE)基本利率在整个 2020 年的预期。基本利率目前为 0.75%。kv7 是唯一一条不考虑任何加息因素的曲线。我选了 kv7 。回想一下,这些数据点是在 1 月份的英国央行会议之前公布的。

这是一个简化的模型,没有使用短期英镑期货。实际上,交易所交易产品与场外交易(OTC)产品一起使用,正是为了弥补这种类型的不确定性。

关于标准 2。

‘曲线稳定性’是什么意思?

鉴于曲线的长、中和短端具有相关但根本不同的波动来源,输入空间的局部变化应仅转化为构建曲线的局部变化。

使用纽结序列 k7 ,我提出了代表不同市场情景的四种扰动情景。我对扰动变化的局部差异不感兴趣,而是对曲线未变化部分的差异感兴趣。

应用于输入速率的 4 组凸起如表中所示。

希望 GIF 原谅我无耻的 PyCharm 截图。

场景 0

好消息是曲线的形状保持不变。

有趣的是,在输入的均匀 +1 个基点(bp)移动后,看到构建曲线的非均匀平移。这表明结之间的曲率发生了变化,因此高阶多项式的系数发生了变化,而不仅仅是常数项发生了变化。

这确实有风险管理的含义,但也是最简单的论点——如果 7y8y 互换利率下跌了 1bp,为什么 7.5y 点的变动不应该是 1bp?

不应该。但是,每一种模式都是一种取舍。在这里,它是针对高阶差异的曲线的重要部分的行为。

场景 1

前期利率上涨。曲线的 2y+部分没有移动。前途无量。

场景二

这是一个转移视线的场景。如果曲线输入错误,曲线会如何反应?在这里,10 年期利率比基准利率低了 5 个基点。

我对结果有两种想法。

1)我很高兴看到错误没有完全破坏曲线。

2)它对输入错误几乎太有弹性了。如果不仔细检查输入,我根本不知道有错误。我想这取决于你的风格。好斗 vs 偏执 —你的选择。

场景 3

多头抛售。曲线的短端没有移动。10y-15y 区域中的一些小曲率调整。总而言之,扎实。

裁决和延期

一开始是一个关于 B 样条的小项目,后来发展到更深入地研究结的选择,作为市场驱动因素的一个功能,并在不同的市场条件下对曲线稳定性进行压力测试。

我发现了一种 B 样条表示,当传递一组输入和输入空间的域启发分区时,会返回一种结构,这种结构足够灵活,既能冲击市场价格,又能在本地适应输入市场价格的波动。

不幸的是,结的选择过程是低效的。几乎没有时间来迭代纽结序列。我很有兴趣看到一个固定的结序列在一整天的市场运动中的准确性。第二个扩展将是探索最佳结的选择。我还想探索作为买卖价差代理的标准误差带,并在这样做时比较 MLE 和 Bootstrapped 方法。

我的代码在 GitHub 上,欢迎你尝试这些想法。

事实是,这只是构建收益率曲线的众多方法之一。我在下面留了一个阅读部分,介绍替代方法和扩展。

我的故事

虽然我的学术背景是数学和统计学,但我的就业背景是交易利率期权。19 年 10 月,我离开了交易行业,去探索创业和数据科学的交集。我对推荐系统、健身数据、金融市场、人类记忆和自动化感兴趣。

如果你们有共同的兴趣或者只是想取得联系,请在下面或者在 LinkedIn 上给我留言。在过去的 9 个月里,我还写了一系列关于统计数据主题的文章中的

进一步阅读

  1. 机器学习中的 B 样条,Andre S. Douzette
  2. 构建收益率曲线的方法,Hagan,West
  3. 课程笔记,卡内基梅隆大学高级数据分析
  4. 在 Factset 建立互换曲线,戴维斯,刘
  5. 如何选择绳结,MathWorks

YOLO 使简单:解读《你只看一次》一文

原文:https://towardsdatascience.com/yolo-made-simple-interpreting-the-you-only-look-once-paper-55f72886ab73?source=collection_archive---------18-----------------------

浏览论文中的实质细节和经常被忽视的事实,并简单解释。

YOLO:你只看一次——来源来源:卡内尔斯在 pixabay

与最先进的 R-CNN 模型不同,“YOLO:统一的实时对象检测”或“YOLOv1”提供了一种端到端的对象检测和分类解决方案。这意味着我们可以训练单个模型直接从输入图像进行检测和分类,并且是完全可微分的。对象检测的传统方法的例子是在图像的不同部分上以不同的比例运行分类器。整洁,对不对?!你所需要的只是一个分类器。

听起来很简单,在一张图像上运行数百次分类器来定位对象是非常低效的。但 YOLOv1 处理得很巧妙。它通过图像的单次向前传递进行检测和分类,并实时运行。因此得名“你只看一次”。我们将详细研究论文中描述的所有内容。

介绍

作者将 YOLO 的工作比作人类的感知。我们,人类,看一眼一个场景,立刻就能对现在的情况,在哪里,谁在做什么有个大概的了解,还有更多。人类的视觉皮层很神奇吧?YOLOv1 通过将对象检测和分类问题视为回归,一次性预测图像中存在哪些对象以及它们的位置。简单地说,你给 YOLO 模型一个图像,它通过一堆层,最终输出将是类预测和边界框坐标。在这里,作者简明扼要地将 YOLO 的工作定义为

直接从图像像素到包围盒坐标和类别概率。

YOLO 的物体探测方法

YOLO 通过使用一个优雅的过程来处理物体检测,将图像分成一个由 S x S 细胞组成的网格。而 YOLO 将输入限制为正方形图像。

S×S 网格

如果对象的中心落在特定的单元内,则每个单元产生对象的类别和边界预测。这种方法是强大的,因为它使 YOLO 能够检测图像中的多个对象,并同时对它们进行分类。然而,将图像划分成更多的单元将产生更细粒度的预测。网格中的每个单元负责预测边界框参数、对象存在的置信度和类别概率。最终的边界框预测由框中心的 x 和 y 坐标、sqrt(宽度)、sqrt(高度)和对象概率得分组成。

注意:YOLOv1 预测边界框相对于图像的宽度和高度的平方根。原因在 损失功能 一节下面解释。

如果有 20 个类( C =20),则单元格的输出为【x,y, w, h,对象概率, C1,C2,C3,…。,C20 。上述概率是条件类概率。为了澄清,它是给定对象存在于单元中,对象属于特定类的概率。当然,单元格网格中的每个单元格都预测类似的项目列表。

但是还有一件事。在 YOLOv1 中,每个单元格预测的不是一个而是 B 边界框。而这些包围盒每一个都有[x,y, w, h,物体概率]。然而,YOLO 只对每个像元预测一次类别概率,而不考虑边界框的数量。因此,每个单元的输出现在有更多的项目。举例说明,如果 B =2、 C =20,则输出增长为[x1,y1, w1, h1,obj。prob1,x2,y2, w2, h2,obj。C1,C2,…,C20 。

对于在具有 20 个类别的 PASCAL VOC 上的检测,它预测 7×7 的单元网格,每个单元具有 2 个边界框。考虑到所有单元格的预测,输出形状将是一个立方体,其尺寸为( 7 x 7 x 30 )。由于 C =20,两个边界框贡献了 10 项,并且类别概率有 20 项。这加起来就是三十,这就解释了第三次元中的“”30”。

解读 YOLO 的产量预测

边界框中心的 x 和 y 坐标相对于该网格单元的左上角,而不是相对于图像的左上角。每个单元格预测相对于其位置的坐标,这些坐标作为单元格位置的偏移量。

照片由 Charis GegelmanUnsplash 上拍摄

如果我们将图像分成 3 x 3 个网格单元,如上图所示,对象的中心落在中心网格单元内。而如果我们再假设每个网格单元的宽度和高度都是 A、 的话,那么对象中心的坐标就是( 0.6A、0.6A )相对于单元的左上角。模型预测的坐标值在 01 之间,是 A. 的一个分数,因此,坐标( 0.6,0.6 )表示 A 的长度向右的60%这些坐标可以相对于整个图像进行转换,因为我们知道哪个单元预测了盒子及其相对坐标。******

对象中心相对于图像的坐标

对于上面的例子,盒子相对于图像的中心是 (A+0.6A,A+0.6A)。* 原 A 加到 0.6A* 是单元格左上角到图像左上角的距离。因此,总和给出了盒子中心相对于整个图像的坐标。但是边界框的高度和宽度是相对于整个图像预测的。对于上面的“猫”的例子,边界框的高度几乎是图像高度的三分之二。并且该框的宽度是图像宽度的三分之一。*

因此,YOLO 将宽度和高度预测为图像的宽度(【W)和高度()分别为1/32/3。因此宽度和高度预测意味着 √( 0.33W), √( 0.66H)。** 最后,一个物体的概率也表示为一个介于 01 之间的数。该对象概率乘以预测框与地面真实值的交集(IoU)以给出 置信度得分 。IoU 是一个分数,它表明预测框与实际框重叠的程度。其值也在分别表示无重叠和完全重叠的 01 之间。**

置信度得分 1 表示 100%置信度,0T5,0%置信度。该值越高,单元格越确信有对象存在。这个置信度得分乘以条件类概率,以产生给定类存在的概率得分。****

最终预测的包围盒参数应该是( 0.6,0.6,0.33,0.66,1 )表示(x,y,width,height,obj。prob)。

网络架构

YOLOv1 架构来源:https://arxiv.org/pdf/1506.02640.pdf本文作者拥有这张图片。我只是用它来说明他们的工作!

自 YOLOv1 于 2015 年问世以来,它遵循了典型的卷积架构,但创新了预测输出的方式。它有 24 个卷积层,4 个最大池层和两个全连接层,一个有4096 个** 神经元,另一个有1470 个 神经元。该模型接收尺寸为 448 x 448 的输入彩色图像,用于对象检测。正如我们之前看到的,YOLOv1 预测了来自其最终完全连接层的 长方体 输出。那是用1470 个 神经元将最后一个全连接层的输出重塑成一个(7×7×30)长方体为帕斯卡 VOC。显式地,我们可以看到最后一层有1470 个 神经元,因为它需要被重塑为7 x 7 x 30 = 1470。**

特征提取器由不同滤波器大小的卷积层构建,其中一些卷积层之后是后续的最大池层,用于空间缩减。平常的东西!在 YOLO 模型中,只有第一个卷积层有 7 x 7 滤镜。其他的都有 3 x 3 滤镜网络不仅仅使用交替 3 x 3 卷积和最大池层数,而是使用 1 x 1 卷积。

作者提到他们的架构受到了引入了 Inception 模块的 GoogLeNet 的启发。

我们的网络架构受 GoogLeNet 图像分类模型的启发

但与 GoogLeNet 不同,YOLOv1 不使用 inception 块。相反,在应用大量的3×3过滤器之后,它使用1×1卷积来减少特征图的通道深度。 1 x 1 滤镜有一个非常小的感受域(只有一个像素),但它们主要用于减少 3 x 3 卷积层之后各层的计算负载。此外,它们有助于在不改变感受野的情况下引入非线性。

不太明白?我们将详细研究为什么它是有益的。

1 x 1 卷积

1×1卷积的概念是在闵等人的论文网络中的网络中介绍的,这里看一下论文

注意:以下示例解释了带有卷积层的小模型的 1 x 1 卷积。不要把这个示例模型与 YOLO 的建筑混淆

例如,考虑大小为 (100,100,3) 的输入图像被馈送到具有零填充的 128 个滤波器的3×3卷积层。我们零填充以产生与输入【100,100】相同空间维度的输出特征图。为了简单起见,我们忽略批次维度。每个滤波器与输入图像卷积后产生一个 (100,100,1) 输出特征图。由于我们有 128 个这样的滤波器,滤波器输出附加到信道维度以产生形状为 (100,100,128) 的输出。这一层的权重大小应该是 (3,3,3,128) 也就是(filter_x_size,filter_y_size,input_channels,filter _ number)。

目前为止还好(只是正常卷积!).

现在,如果我们再次将这个输出馈送到下一个具有 128 个滤波器的3×3卷积层,它的权重将必须是 (3,3,128,128)。

你现在明白了吗?第一层只有 3456 个参数(3x3x3x128 = 3,456)。但是,由于第二层对 128 个通道的输入进行操作,因此它有多达 147,456 个参数(3x3x128x128=147,456)!现在想想后续层会有多少参数?为了减少这种爆炸效应,在将第一卷积层的 (100,100,128) 输出馈送到下一层之前,应用 1 x 1 卷积。

(100,100,128) 应用 32 个1×1滤波器,将通道深度减少到 (100,100,32)。 现在,下一个 3 x 3 卷积层的参数将是 (3,3,32,128) 。参数的数量从 147456 个减少到 36864 个 (3x3x32x128) 。除此之外, 1 x 1 卷积层有 128x32=4096 个参数。现在总共只有 40,960 个参数,少了 3.6 倍!

YOLOv1 模型在两个完全连接的层之间使用了一个压差,以防止过度拟合。但它没有使用任何其他技术,如批量标准化可以加速训练。

既然我们已经看到了什么是 1 x 1 卷积,让我们继续讨论网络的其他内容。

培养

我们在开始时看到,网络有 24 个卷积层、4 个最大池层和 2 个光纤通道层。

跳到这里来学习

如何建立一个简单的卷积神经网络,在 kaggle 数据集上训练并达到 99.9%的准确率!

作者在 ImageNet 数据集上以 224 x 224 的输入分辨率预训练了前二十个卷积层。它的分辨率只有 YOLOv1 的检测输入的一半,即 448 x 448。这显然是因为 ImageNet 图像的大小为 224 x 224。

我们在 ImageNet 分类任务中以一半的分辨率(224 × 224 输入图像)预训练卷积层,然后将分辨率提高一倍用于检测——yolo v1 作者

由于只有前 20 个卷积层用于迁移学习,它可以对任何分辨率的输入图像进行操作。

预训练有助于卷积滤波器从 ImageNet 数据集学习模式。由于它包含了属于一千多个类别的大量图像,卷积层可以学习许多有用的特征。预训练和迁移学习为 YOLO 检测提供了很好的性能提升。

对于预训练,我们使用图中的前 20 个卷积层,随后是一个平均池层和一个全连接层——yolov 1 作者

在 ImageNet 上进行预训练后,移除平均池和完全连接的预测层。它们被四个 3 x 3 卷积层和两个全连接层取代。

注意:仅对于使用 S=7,B=2 的 PASCAL VOC 数据集,输出尺寸为 7 x 7 x 30。如果任何一个参数 S (网格单元数 S x S), B 或数据集中的类数发生变化,这个输出形状也会发生变化。

这些级联卷积和最大池层将特征图的空间维度从 448 x 448 减少到所需的 7 x 7 大小

除了最终完全连接的层之外,网络中的所有层都使用“Leaky-Relu”激活功能。并且最后一层具有线性激活。

Leaky-Relu 的数学表达式

Leaky-relu 的图形与整流线性单元(relu)略有不同。看一看!

Leaky-Relu 激活函数图

需要注意的一件重要事情是最终层的输出。正如我们之前提到的,它有一个 线性激活 ,它的输出被整形形成一个7×7×30张量。最后,YOLOv1 模型在 PASCAL VOC 数据集上训练了 135 个时期。作者采用的一些训练技巧如下。

在整个训练过程中,我们使用的批量大小为 64,动量为 0.9,衰减为 0.0005。对于第一个时期,我们将学习率从 103 慢慢提高到 102。我们继续用 102 训练 75 个周期,然后 10^−3 训练 30 个周期,最后 10^−4 训练 30 个周期。

损失函数

YOLO 的损失函数可能看起来吓人,但它非常简单。使用的损失称为 平方和损失 ,用于 YOLOv1 中的所有任务。作者引用说,优化平方和比对数似然更容易。但是他们也提到它有一些缺点。

平方和误差同等地衡量定位误差和分类误差。而且,由于图像中的许多网格单元不包含任何对象,平方和误差试图使这些单元的置信度得分为零。这意味着他们的损失将主导梯度,它不会让模型收敛。为了解决这个问题,作者引入了参数 λcoordλnoobj。

这两个参数对损失函数中的不同项进行加权,以保持无对象像元造成的损失较低。并且也更加权衡坐标损失。

YOLOv1 的损失函数来源:https://arxiv.org/pdf/1506.02640.pdf再次声明,作者拥有这张图片。我只是用它来说明他们的工作!

让我们把它分解一下,了解损失中的每一项是什么意思。

定位误差

定位误差

第一项计算预测坐标和地面真实坐标之间的平方和损失。对所有单元格中的所有边界框都这样做。得到的和乘以 λcoord。 作者用值 5 为 λcoord。" 1 obj I,j"项表示在第 i 行和第 j 列单元格中存在一个对象。**

第二项计算预测高度和宽度的平方和损失。该模型预测宽度和高度的平方根,而不是直接预测它们的值。这样做是为了缓解作者提到的某个问题。

平方和误差同样对大盒子和小盒子中的误差进行加权。我们的误差度量应该反映大盒子中的小偏差不如小盒子中的小偏差重要。为了部分解决这个问题,我们预测边界框宽度和高度的平方根,而不是直接预测宽度和高度

假设有两个地面实况箱,高度分别为 10.2 和 2.2。在这个例子中,我们不考虑盒子的宽度。假设模型预测的身高是 10.1 和 2.1。现在根据损失项,较大的盒子误差为( 10.1- 10.2),较大的盒子误差为( 2.1- 2.2)。你可以看到损失值分别是 10^-4 的 2.4 倍和 10^-3 的 1.16 倍。如您所见,预测高度和宽度的平方根在较小的框中更重视小误差。

分类误差

分类误差

其中的第一项计算每个像元中每个边界框的预测置信度得分和基本事实之间的误差平方和。这个误差项对应于物体所在单元的误差。因此使用了术语“1 obj I,j*** ”。***

类似地,第二项计算不包含任何对象的像元的平方和误差。术语“ 1 noobj i,j ”表示第I列和第 j 行单元格中没有对象。这个总和由 λnoobj 项加权,以使这个损失更小。作者将 λnoobj 赋值为 0.5。

最后一项计算类别概率的相同损失。它对每个像元中的所有类进行迭代,并计算损失平方和。这个损失项还有“1 obj I,j** ”。这意味着没有任何对象的单元不会造成分类损失。****

结束了

我希望这篇文章能让你深入了解 YOLO 的工作。如果你发现任何错误,请在评论中报告。勘误表,如果有的话,确实是无意的。

参考

  1. ****你只看一次:统一的,实时的物体检测:【https://arxiv.org/abs/1506.02640 ****
  2. 网络中的网络https://arxiv.org/abs/1312.4400

**最初发表于https://hackerstreak.com

YOLO V3 解释道

原文:https://towardsdatascience.com/yolo-v3-explained-ff5b850390f?source=collection_archive---------3-----------------------

Yolo-V3 检测。图片来源: Uri Almog Instagram

在本帖中,我们将讨论 YOLO 探测网络及其版本 1、2,尤其是版本 3。

2016 年 Redmon,Divvala,Girschick 和法尔哈迪以一篇题为: 你只看一次:统一的、实时的物体检测 的论文对物体检测进行了革命。在论文中,他们介绍了一种新的对象检测方法——将特征提取和对象定位统一到单个整体块中。此外,本地化和分类负责人也进行了整合。他们的单级架构,命名为 YOLO (你只看一次)导致了非常快的推理时间。在 Titan X GPU 上,448x448 像素图像的帧速率为 45 fps(每幅图像 0.022 秒),同时实现了最先进的 mAP (平均精度)。更小且稍不精确的网络版本达到了 150 fps。这种新方法,加上基于轻量级谷歌 MobileNet 主干的其他检测器,使边缘设备上的检测网络和其他 CV 任务的愿景(双关语)更加接近现实。原来的 YOLO 项目可以在这里找到

顺便说一下,Redmon 似乎是一个非常丰富多彩的家伙。他的 YOLO 项目网站可以在这里找到。

检查我在上一篇文章中展示的 GluonCV 模型动物园图,可以看到经过 GluonCV 训练的不同版本的 YOLO-V3 (红点)达到了极好的精确度,仅次于慢得多的 fast-RCNN。

检测器性能图表。代表性架构。图表数据取自 GluonCV 模型动物园。图表创建者:Uri Almog

YOLO 背后的想法是这样的:没有需要彼此同步的分类/检测模块,也没有像以前的 2 阶段检测器那样的重复区域提议循环(见我在 上的帖子,早期的物体检测器 ,如 RCNN)。它基本上是一路向下的卷积(偶尔有 maxpool 层)。一个单一的整体网络需要处理特征提取、盒子回归和分类,而不是裁剪出一个物体的高概率区域,并将它们提供给一个找到盒子的网络。以前的模型有两个输出图层-一个用于类概率分布,一个用于盒预测,而这里的单个输出图层包含不同要素的所有内容。

约洛-V1 建筑

约罗-V1 是第一次出现一级探测器的概念。该架构采用了(BN)和leaky ReLU activations,这在当时是比较新的。我不打算详细介绍 V1,因为它已经相当过时,并且缺少一些后来引入的强大功能。

约洛-V2 建筑

约罗-V2 包含 22 个卷积和 5 个最大池运算。要素地图高度代表空间分辨率。125 个特征的输出用于具有 20 个类和 5 个锚点的 VOC PASCAL 数据集。来源:尤里·阿尔莫格

在约洛-V2 版本中,作者们除了其他改动之外,还删除了末尾的全连接层。这使得该架构真正独立于分辨率(即网络参数可以适合任何输入分辨率)。这并不一定意味着网络在任何分辨率下都能表现良好。在训练期间采用了分辨率增强程序。雷德蒙创造了多种版本的约罗-V2,包括更小、更快(和更不精确)的版本,像 蒂尼-约罗-V2 等。

Tiny-Yolo-V2 的架构非常简单,因为它没有像它的兄弟姐妹那样奇怪的旁路和重新排列操作。微型版本只是一个漂亮的、长长的卷积和最大池链。

描述这些架构的配置文件可以在 darknet github 的 cfg 部分找到。

YOLO-V3 架构

ResNetFPN (特征金字塔网络)架构的启发, YOLO-V3 特征提取器 ,称为 Darknet-53 (它有 52 个卷积)包含跳过连接(像 ResNet)和 3 个预测头(像 FPN)——每个都以不同的空间压缩处理图像。

YOLO-V3 架构。来源:尤里·阿尔莫格

像它的前身一样,Yolo-V3 在各种输入分辨率下都有良好的性能。在 GluonCV 的 model zoo 中,你可以找到几个检查点:每一个都有不同的输入分辨率,但事实上存储在这些检查点中的网络参数是相同的。在 COCO-2017 验证集上使用输入分辨率 608x608 进行测试,Yolo-V3 的 mAP 得分为 37(平均平均精度)。这个分数与 GluonCV 的训练版Faster-RCNN-ResNet 50*(一种以 ResNet-50 为主干的 Faster-RCNN 架构)相同,但快了 17 倍。在模型动物园中,速度足以与 Yolo-V3 (Mobilenet-SSD 架构)竞争唯一检测器的 mAP 得分为 30 及以下。*

特色金字塔网(FPN):在两个婚礼上跳舞

特征金字塔(Feature-Pyramid)是由 FAIR (脸书人工智能研究所)在 2017 年开发的一种拓扑结构,其中特征地图在空间维度上逐渐减小(这是通常的情况),但后来特征地图再次扩展,并与之前具有相应大小的特征地图连接在一起。重复该过程,并且将每个连接的特征图馈送到单独的检测头。

特征金字塔网络。来源:尤里·阿尔莫格

参考上面的 YOLO-V3 图示,FPN 拓扑允许 YOLO-V3 学习不同大小的对象:与其他检测块相比,19x19 检测块具有更宽的上下文和更差的分辨率,因此它专门用于检测大对象,而 76x76 检测块专门用于检测小对象。每个探测头都有一套独立的锚定标尺。

Yolo-V3 探测不同大小的物体。来源:尤里·阿尔莫格摄影

SSD (单次检测器)架构不同,在该架构中,38×38 和 76×76 块将仅接收来自特征提取器中间的高分辨率、部分处理的激活(图中顶部的两个箭头),在 FPN 架构中,这些特征在特征提取器的末端与低分辨率、完全处理的特征连接在一起。

这使得网络能够在两个婚礼上跳舞,正如他们在意第绪语中所说的那样,并利用高度处理但窄上下文特征和部分处理但宽上下文特征来进行预测。

YOLO-V3 的输出方案与 V2 相同,并且不同于旧的 V1。

YOLO-V2/V3 输出方案——单层击穿:

YOLO V2 和 YOLO V3 输出层。Wout 和 Hout 是输出要素地图的空间维度。对于每个锚点,特征按描述的顺序排列。来源:尤里·阿尔莫格

输出图层的要素地图中的每个像元都预测了 Yolo-V3 的 3 个盒子和 YOLO-V2 的 5 个盒子-每个锚点一个盒子。每个箱式预测包括:

  1. 框中心偏移的 2 个值(在 x 和 y 方向,相对于单元格中心),
  2. 2 值框尺寸刻度(在 x 和 y 方向,相对于锚点尺寸),
  3. 1 个客观分数值(0 到 1 之间),
  4. 类分数的类数值(介于 0 和 1 之间)。

(准确的说,盒子大小值是‘残差值’。在后处理中,它们用于通过以下方式计算盒子宽度

box_width = anchor_width * exp(剩余值 _of_box_width))

上面的 YOLO-V2 图解是为 20 类 VOC PASCAL 数据集设计的,有 5 个锚点。125 个要素的输出排列如下:每个空间像元有 125 个版本。要素 0 是对象性分数,要素 1–2 是盒子的 x 和 y 比例,要素 3–4 是盒子中心的 x 和 y 偏移(相对于像元坐标本身),而要素 5–24 是 20 类分数。所有这些——为了第一个主播。特征 25-49 重复相同的特征分配-这一次使用第二个锚,以此类推。注意,锚尺寸不直接在特征中表示,但是那些特征中的比例值传递到后处理,并且被分配有用于盒解码的相应锚比例。

对象性 是一个新概念,值得在几个段落中进行讨论。现在让我们把它想象成网络的置信度,即某个对象存在于给定的盒子中,并且假设盒子中存在一个对象,则类得分是 条件概率 (即假设 x 类的概率在这个盒子中存在一个对象)。因此,每个类别的总置信度得分是客观性类别得分的乘积。

然后,网络的输出经过 NMS 和一个置信度阈值,给出最终的预测,正如我在关于 探测器基础 的帖子中所解释的。

为什么 YOLO 比以前的架构表现更好?

如果说我在研究 YOLO 和它的小版本时学到了什么的话,那就是外表可能会骗人:YOLO 的拓扑结构如此小而简单,它能有多复杂呢?好吧。使它能够具有如此简单的结构,或者更准确地说是紧凑的损失函数是非常复杂的。正是失去赋予了这些特征意义。因此,一个精心制作的损失函数可以将大量信息打包到一个小的要素地图中。

在下一节,我们将讨论 YOLO 损失函数的最重要的特征。

YOLO 培训和流失机制

这一部分是基于我对 Darknet 框架(Redmon 开发的框架)的训练流所做的研究,当时我正在进行该框架的独立 TensorFlow 实现。

输入分辨率增强

作为一个 全卷积网络——不像以前的检测器那样包含用于分类任务的全连接层——它可以处理任何大小的输入图像。但是,由于不同的输入分辨率会产生不同的网络参数,因此使用 分辨率增强来训练网络: 作者使用了 384x384 和 672x672 像素之间的 10 个输入分辨率步长,每隔几个训练批次随机交替,使网络能够推广其对不同分辨率的预测。

损失系数—分而治之

损失函数对不同的盒子进行不同的处理。

正如我在上一篇文章中解释的那样,网络输出层中的每个空间单元预测多个盒子(在 YOLO-V3 中有 3 个,在以前的版本中有 5 个)——所有的盒子都以那个单元为中心,通过一种叫做 的机制锚定

每个盒预测的 YOLO 损失由以下项组成:

  1. 坐标丢失 —由于盒子预测没有完全覆盖对象,
  2. 对象丢失 —由于错误的盒对象 IoU 预测,
  3. 分类损失 —由于对正确类别的预测为‘1’而对该框中的对象的所有其他类别的预测为‘0’的偏差。
  4. 这是一个特殊的损失,我们将在下面两节详细阐述。

YOLO-V1 损失函数。λ是损耗系数。前 3 行是“最佳盒子”(在每个空间单元中最佳捕获 GT 对象的盒子)造成的损失,而第 4 行是由于没有捕获对象的盒子造成的损失。在 YOLO V2 和 V3 中,直接的宽度和高度预测以及平方根被替换为剩余比例预测,以使损失参数与相对比例误差而不是绝对比例误差成比例。

一个盒子预测的质量是通过它的 IoU (交集/并集)与它试图预测的对象(更准确地说,是与它的基础真值盒子)来衡量的。IoU 值的范围从 0(框完全错过对象)到 1.0(完美匹配)。

对于每个空间像元,对于位于该像元中心的每个框预测,损失函数会找到对象位于该像元中心的具有最佳 IoU 的框。这种区分 最佳盒子 和所有其他盒子的机制是 YOLO 损失的核心。

最佳框 和它们本身导致坐标损失(由于与对象不完全匹配)和分类损失(由于分类错误)。这推动了与那些盒子相关联的网络参数,以改进盒子的规模和位置,以及分类。这些盒子还会导致信心丧失——我们将立即对此进行解释。所有其他盒子只招致信任损失

失去目标——知道自己的价值

每一个框预测都与一个称为“客观的预测相关联。它出现在像 RCNN 这样的以前的检测器中的地方,即区域提议包含对象的置信度,因为它乘以 lass 分数以给出绝对的类置信度。然而,与预期相反——该预测实际上是一个 IoU 预测——即网络 认为 盒子覆盖物体的程度。目标损失项教导网络预测正确的 IoU ,而坐标损失教导网络预测更好的盒子(最终将 IoU 推向 1.0)。所有的盒预测都会造成对象损失,但只有每个空间像元中的最佳拟合盒也会造成坐标和分类损失。

为什么我们需要客观损失?

在推理中,我们通常有多个盒子,每个盒子有不同的覆盖范围。我们希望后处理算法选择以最精确的方式覆盖对象的盒子。我们还想选择对对象给出正确类别预测的盒子。算法怎么知道选哪个盒子?

首先,对象性告诉我们覆盖率有多好——所以对象性非常小的盒子(<0.005) are discarded and don’t even make it to the NMS block (see explanation in 我之前的帖子)。这有助于消除大约 90%的盒子,它们只是架构的工件,而不是真正的检测(当然,这取决于任务和数据。如果您的任务是检测装满瓶盖的盒子中的瓶盖,那么您可以预期有大量的实际检测)。

抑制 NMS 时的多框检测结果。客观性分数告诉 NMS 哪些盒子要保留,哪些要丢弃。来源:乌里阿尔莫摄影

第二,NMS 是为每个类分别做的,所以类的分数是由盒子的对象性来衡量的,以便进行有意义的比较。如果我们有两个高度重叠的框,第一个框的对象性为 0.9,人员概率为 0.8(加权分数为 0.72),第二个框的对象性为 0.5,人员概率为 0.3(加权分数为 0.15),则第一个框将持续存在,第二个框将在 NMS 中消失,因为第一个框的对象性使其更值得信任。

为什么“最佳包厢”在培训期间会受到不同的对待?

我没有看到 Redmon 对这个问题的任何解释,但我的直觉是这样的:想想一位教授,她有以下策略:在第一次作业中,她寻找表现好的学生,并努力检查和评分他们的作业,以便他们能在该科目中表现出色。为了集中注意力,她懒得批改成绩不太好的学生的作业。相反,她给他们一个机会,让他们在下一次作业中在另一个科目上表现出色。

只推最好的盒子来提高覆盖率和档次的原因是专注。我们希望培训能够很好地融合。网络有丰富的参数,所有参数都有大量的工作要做,所以不要急于一次优化所有参数。试图推动所有盒子的参数来捕捉相同的对象——奖励所有盒子近似捕捉相同的对象——可能会导致损失景观中非常长且嘈杂的轨迹,或者更糟的是——陷入次优最小值(因为它们可能无法很好地学习检测具有不同特征的对象,但会陷入局部最小值,而无法学习不同的行为)。最好是利用一些盒子的相对成功,只推动它们在这种类型的对象中成功,同时让与不太成功的对象相对应的参数探索其他选项(以一种将很快解释的方式)。

另一方面,我们希望所有的盒子都经历对象性损失——为什么?我们希望所有的盒子——包括坏盒子——能够学会辨别它们是好是坏,即使他们在一生中(或至少在训练中)没有学到任何东西——因为 NMS 依赖于它(即使如此——YOLO 给‘最好的盒子’比其他盒子更高的物体损失系数)。

收缩损失——利用与探索

我称之为 锚收缩 的一个有趣机制在论文中没有明确提到,但我在代码中发现了它。每一个盒预测都会导致与其原始锚形状和位置的偏差成比例的小损失。在第一个训练时期,这种作用微弱但稳定地持续,之后损失系数预定消失。

虽然这个损失项是非零的,但它产生一个弱力,使每个盒预测收缩回其锚形式。

收缩损失:在训练期间,将两个盒子与以它们的单元为中心的物体(鸟)进行比较。红盒子具有最好的 IoU,并且将贡献坐标损失和分类损失,这将推动它更好地覆盖鸟并预测其类别。蓝色盒子将被推回到它的锚形,这可能使它处于更好的位置来捕捉毛虫。来源:乌里阿尔莫格摄影

这个巧妙的机制具有以下效果:没有成功捕获对象的盒子(那些不包括在上面提到的“最佳盒子”组中的盒子)被推回到它们的原始锚形状。由于锚被设计为捕捉数据集中的对象的最佳先验,所以该动作增加了与那些盒子相关联的权重在未来尝试中生成更多成功盒子的机会。同时,成功的盒子(“最佳盒子”组)也经历了这种损失!但是坐标和分类损失要大得多(它们的系数更大),并且它们支配着与那些框相关联的参数的移动方向

在几个时期之后,假设网络已经学会相当好地预测盒子,并且锚收缩停止允许网络参数在实际基础上微调。

我以前的帖子:

什么是神经网络?

【数学与人工智能】实际问题

感知器

训练神经网络简单解释

深度学习的物体检测— RCNN、锚点、非最大抑制

使用 Keras 进行 YOLO v3 目标检测

原文:https://towardsdatascience.com/yolo-v3-object-detection-with-keras-461d2cfccef6?source=collection_archive---------12-----------------------

图片由作者说明

用 Keras 实现简单解释 YOLO v3

视频由 YOLO 作者,
约瑟夫·雷德蒙

关于 YOLO v3 算法

“你只看一次”(YOLO)是一种对象检测算法,以其高准确性而闻名,同时由于其速度检测,它也能够实时运行。与之前的算法不同,第三个版本通过简单地改变模型的大小,在不需要重新训练的情况下,促进了速度和准确性之间的有效折衷。

在我们开始用 YOLO v3 实现对象检测之前,我们需要下载预训练模型权重。下载这个可能需要一段时间,所以你可以在等待的时候准备你的咖啡。YOLO v3 是用 c 语言的开源神经网络 DarkNet framework 编写的,这让我一开始就感到很害怕。

但值得庆幸的是,这段代码受到了 experiencor 的 keras-yolo3 projec 的强烈启发,它使用 keras 执行 YOLO v3 模型。在整个实现过程中,我将在 Google Colab 上运行它。此外,我们将使用这些可爱的狗图像进行对象检测。

照片由 Alvan NeeUnsplash 上拍摄

所以让我们把手弄脏吧!!

第一步:

跳到第一步,下面是必要的库和依赖项。

第二步:

接下来,**WeightReader** 类用于解析“yolov3。权重”文件并将模型权重加载到内存中。

第三步:

YOLO v3 使用了新的网络来执行特征提取,不可否认,与 YOLO v2 相比,它的规模更大。这个网络被称为 Darknet-53,因为整个网络由 53 个具有快捷连接的卷积层组成 (Redmon &法尔哈迪,2018)

YOLO v3 网络有 53 个卷积层(雷德蒙&法尔哈迪,2018)

因此,下面的代码由几个组件组成,它们是:

  • **_conv_block**用于构建卷积层的函数
  • **make_yolov3_model**用于创建卷积层并将其堆叠在一起作为一个整体的功能。

第四步:

接下来,下面的代码解释如下:

  • 定义 YOLO v3 模型
  • 加载您之前下载的预训练重量
  • 使用 Keras save函数并指定文件名保存模型

第四步:

该步骤包括将预测输出解码成边界框

YOLO v3 预测的输出是难以解释的数组列表的形式。因为 YOLO v3 是多尺度检测,所以它被解码成(13,13,225)、(26,26,225)和(52,52,225)形状的三个不同尺度

解码前的 YOLOv3 预测输出片段

  • **decode_netout**函数用于将预测输出解码成方框

简而言之,这就是**decode_netout**函数的工作方式,如下图所示:

图片由作者说明

第五步:

缩放和拉伸解码后的框以适合原始图像形状

第六步:网络输出解码后,不会直接对物体显示平滑预测。解码后的盒子产生了几个重叠的盒子。从下图可以看出,模型已经检测到图像中有三只狗。然而,它仅仅是一个物体上重叠的盒子,在这个例子中是可爱的柯基。

因此,发生非最大抑制(NMS)来滤除以便获得正确的框

  • **bbox_iou**函数用于通过获取两个盒子的**_interval_overlap**来计算 IOU(交集/并集)

图片来自 DeepLearning.ai 课程

  • **do_nms** 功能用于执行 NMS

一般来说,NMS 是这样表演的:

  1. 选择得分最高的方框。
  2. 计算此框与其他框的区间重叠,省略重叠明显的框(iou >= iou_threshold)。
  3. 重复步骤 1 并重复,直到没有比当前选择的盒子分数更低的盒子。

这将忽略与所选框有大量重叠的所有框。只剩下“正确”框。

  • **get_boxes**函数用于获取通过 NMS 滤波器选择的盒子
  • **draw_boxes**函数用于使用matplotlib.patches.Rectangle类给输入图像绘制一个矩形框

第七步:

我们即将结束 YOLO v3 的实施。在这一步,我们必须声明几个配置,它们是:

  • **anchors** : 根据对 COCO 数据集中对象大小的分析精心选择。
  • **class_threshold**:检测对象的概率阈值
  • **labels**:COCO 数据集中的类标签

第七步:

最后,YOLO 模型准备进行预测,下面的代码允许用户输入图像来检测对象。

输出:

结论

总之,YOLOv3 是一个强大的对象检测模型,以快速检测和准确预测而闻名。在本文结束时,我真的希望这篇文章能让你更好地理解 YOLO 算法的工作原理,并在 Keras 中实现它。完整的代码可以在 GitHub 上找到。

此外,在我的整个旅程中,我想对 Huynh Ngoc AnhJason Brownlee 大声疾呼,深入了解 YOLOv3 的工作原理并将其应用到 Keras 中。另外,你可以在这里找到 YOLOv3 论文。

参考

[## 深入了解 YOLO v3:初学者指南

针对初学者的 TensorFlow 2 中 YOLO v3 的详细回顾和实践。

towardsdatascience.com](/dive-really-deep-into-yolo-v3-a-beginners-guide-9e3d2666280e) [## experiencor/Keras-yolo3

要安装依赖项,请运行 pip install -r requirements.txt,为了让 GPU 工作,请确保您已经安装了…

github.com](https://github.com/experiencor/keras-yolo3) [## 如何在 Keras 中使用 YOLOv3 执行对象检测-机器学习掌握

目标检测是计算机视觉中的一项任务,涉及识别一个或多个目标的存在、位置和类型

machinelearningmastery.com](https://machinelearningmastery.com/how-to-perform-object-detection-with-yolov3-in-keras/)

YOLO v4:物体检测的最佳速度和精确度

原文:https://towardsdatascience.com/yolo-v4-optimal-speed-accuracy-for-object-detection-79896ed47b50?source=collection_archive---------1-----------------------

实时目标探测模型综述

YOLO v3 演示,摘自视频

你只看一次( YOLO )是一系列快速准确的一级物体探测器。最近, YOLO v4 论文发布,显示了与其他物体探测器相比非常好的结果。

更新 1 :增加了一个 colab 演示

目录

  1. 简介
  2. 物体探测器的一般架构
  3. 袋赠品&袋特价
  4. YOLO v4 设计
  5. 汇总 BoF 和 BoS 使用的
  6. 附加改进
  7. Colab 演示
  8. 最后一句话

介绍

大多数现代精确模型需要许多 GPU 来进行大规模小批量的训练,而用一个 GPU 来进行训练会使训练变得非常缓慢和不切实际。YOLO v4 通过制作一个对象检测器来解决这个问题,该对象检测器可以在单个 GPU 上以较小的小批量进行训练。这使得用单个 1080 Ti 或 2080 Ti GPU 训练超快速和精确的物体检测器成为可能。

YOLO v4 在 MS COCO 数据集上以实时速度获得了最先进的结果,在 Tesla V100 上以 65 FPS 运行的 AP 为 43.5 %。相当有趣的结果!为了实现这些结果,他们结合了一些特征,如加权剩余连接(WRC)、跨阶段部分连接(CSP)、交叉小批量归一化(CmBN)、自我对抗训练(SAT)和 Mish 激活、镶嵌数据增强、DropBlock 正则化和 CIoU 损失。这些被称为通用特征,因为它们应该独立于计算机视觉任务、数据集和模型工作良好。我们将在后面讨论这些特性。

分别提高约洛夫 3 的 AP 和 FPS 10%和 12%[5]

注意:落在浅蓝色区域的模型被认为是实时物体探测器(+30 FPS)

我们可以看到,EfficientDet D4-D3 比 YOLO v4 模型实现了更好的 AP,但它们以< 30 FPS on a V100 GPU. On the other hand, YOLO is able to run at a much higher speed (> 60 FPS 的速度运行,具有非常好的准确性。

物体检测器的一般结构

虽然 YOLO 是一级检测器,但也有像 R-CNN、快速 R-CNN 和更快 R-CNN 这样的两级检测器,它们准确但速度慢。我们将把重点放在前者上。让我们来看看现代一级物体探测器的主要组成部分。

摘自 YOLO v4 论文,来源

毅力

使用 ResNetDenseNetVGG 等模型作为特征提取器。它们在 ImageNet 等图像分类数据集上进行了预训练,然后在检测数据集上进行了微调。事实证明,随着网络变得更深(更多层),这些网络产生具有更高语义的不同级别的特征,对于物体检测网络的后面部分是有用的。

脖子

这些额外的层位于脊椎和头部之间。它们用于提取脊柱不同阶段的不同特征图。颈部可以是例如 FPN[ 1 ]、帕内特[ 2 ]、双 FPN[ 3 ]等。例如,YOLOv3 使用 FPN 从主干中提取不同尺度的特征。

金字塔网络(FPN)有什么特点?

使用自上而下的路径和横向连接增强标准卷积网络,以便网络从单分辨率输入图像中高效构建丰富的多尺度特征金字塔[ 4 ]

用于目标检测的特征金字塔网络[ 1

每个横向连接将从自下而上路径到自上而下路径的特征图合并,产生不同的金字塔等级。在合并特征地图之前,先前的金字塔等级在 FPN[ 1 ]中被上采样 2 倍,因此它们具有相同的空间大小。然后将分类/回归网络(头部)应用于金字塔的每一层,以便帮助检测不同大小的对象。

这种特征金字塔网络的思想可以应用于不同的主干模型,作为一个例子,最初的 FPN[ 1 ]论文使用了 ResNets。还有很多以不同方式整合 FPN 的模块,比如 SFAM [ 7 、ASFF [ 9 、比 FPN[ 3

四种类型的要素金字塔。SFAM[ 7 ]模块是(d)

图像 (a) 显示了如何在单触发检测器架构(SSD)中从主干提取特征。上图还显示了其他三种不同类型的金字塔网络,但它们背后的理念是相同的,因为它们有助于:

缓解由对象实例之间的比例变化引起的问题[ 3 ]。

ASFF[ 9 ]和比 FPN[ 3 ]也是有趣的 FPN 类型,并显示出有趣的结果,但我们在这里将跳过它们。

这是一个负责实际执行包围盒检测部分(分类和回归)的网络。单个输出可能看起来像(取决于实现):4 个描述预测边界框的值( x,y,h,w )和 k 类的概率+ 1(额外一个用于背景)。对象检测器基于锚的,如 YOLO,将头部网络应用于每个锚盒。其他流行的基于锚的一级探测器有:单炮探测器 6 和 retina net4

下图结合了上述三个模块。

原始图像来自 RetinaNet[ 4 ]纸张

一袋赠品 &一袋特价商品

YOLO v4 论文的作者[ 5 ]区分了两类用于提高物体检测器精度的方法。他们分析了两个类别中的不同方法,以实现具有良好准确性的快速运算速度的神经网络。这两个类别是:

一袋赠品 (BoF):

在不增加推理代价的情况下,使目标检测器获得更高精度的方法。这些方法只是改变了培训策略或者只是增加了培训成本。[ 5

BoF 的一个例子是数据扩充,增加了模型的泛化能力。要做到这一点,我们可以做照片度量失真,如:改变亮度,饱和度,对比度和噪声,或者我们可以做图像的几何失真,如旋转,裁剪等。这些技术是 BoF 的一个明显的例子,它们有助于检测机的准确性!

几何扭曲的例子,来源

注意:对于物体检测任务,边界框也应该应用相同的变换

还有其他一些增强图像的有趣技术,比如剪切 [ 8 ],它在训练过程中随机屏蔽输入的方形区域。这表明改进了 CNN 的鲁棒性和性能。同样,随机擦除 [ 10 ]选择图像中的矩形区域,用随机值擦除其像素。

对象检测的随机擦除示例,来源

免费赠品的其他背面是用于避免过拟合的正则化技术,如: DropOutDropConnectDropBlock13 。这最后一个实际上在 CNN 中显示了非常好的结果,并且在 YOLO v4 主干中使用。

来自 DropBlock paper[ 13

随机删除激活(b)不利于删除语义信息,因为附近的激活包含密切相关的信息。相反,通过丢弃连续区域,它可以移除某些语义信息(例如,头或脚)并强制剩余单元学习用于分类输入图像的其他特征。

回归网络的成本函数也适用于该类别。传统的做法是应用均方误差对坐标进行回归。

如论文中所述,这将这些点视为独立变量,但不考虑对象本身的完整性。为了改善这一点,已经提出了 IoU[ 12 ]损失,其考虑了预测边界框(BBox)和地面真实边界框的面积。这个想法被 GIoU loss [ 11 进一步改进,除了覆盖区域之外还包括了一个物体的形状和方位。另一方面,还引入了 CIoU loss ,它考虑了重叠面积、中心点之间的距离和纵横比。YOLO v4 使用 CIoU 损失作为边界框的损失,主要是因为与提到的其他方法相比,它导致更快的收敛和更好的性能。

注意:可能引起混淆的一件事是,尽管许多模型使用 MSE 来计算 BBox 回归损失,但它们使用 IoU 作为度量,而不是如上所述的损失函数。

下图比较了具有不同 IoU 损耗的同一型号:

损失比较,来源

我们可以注意到 CIoU 比 GIoU 表现得更好。这些检测来自更快的 R-CNN (Ren 等人,2015 年),其在相同的 MS COCO 数据集上训练,具有 GIoU 和 CIoU 损失。

特价包 (BoS) :

那些插件模块和后处理方法,只是少量增加了推理成本,却能显著提高物体检测的准确性[ 5 ]

如论文中所述,这类模块/方法通常涉及:引入注意机制(挤压-激发空间 注意模块),扩大模型感受野,增强特征整合能力等。

用于改善感受野的常见模块有 SPPASPPRFB (YOLO v4 使用 SPP )。

此外,细胞神经网络的注意模块主要分为通道注意,如挤压和激发(SE)[ 15 ],和空间注意,如空间注意模块(SAM)[ 16 。后者有时更受青睐的一个原因是,se 在 GPU 上增加了 10%的推理速度,这是不可取的。事实上,YOLO v4 考虑了 SAM[16]模块,但并不完全像最初在这篇论文中发表的那样。请注意以下几点:

原始空间注意模块[16]

给定特征映射 F’,最初的实现沿着通道轴执行平均池和最大池操作,然后将它们连接起来。然后应用卷积层(以 sigmoid 为激活函数)生成注意图( Ms ),应用于原F’

YOLO v4 修改的空间注意模块,来源[5]

另一方面,YOLO v4 修改的 SAM 不应用最大池和平均池,而是F’通过一个 conv。层(使用 sigmoid 激活),然后乘以原始特征图(F’)。

我们之前讨论过的 SFAM[ 7 ]、ASFF[ 9 ]和比 FPN[ 3 ]等特征金字塔也属于这一类 BoS,激活功能也是如此。自从 ReLU 问世以来,它的变种很多,像 LReLU,PReLU,ReLU6。像 ReLU6 和 hard-Swish 这样的激活是专门为用于在嵌入式设备上进行推理的量子化网络设计的,就像在谷歌珊瑚边缘 TPU 中一样。

另一方面,YOLO v4 在主干中使用了大量的 Mish [ 14 ]激活函数。看一看图表:

米什公式

来源[ 14 ]

这个激活函数显示了非常有希望的结果。例如,与带有 Swish 和 ReLU 的相同网络相比,使用带有 Mish(在 CIFAR-100 数据集上)的挤压激励网络[ 15 ]导致 Top-1 测试精度分别增加0.494%1.671% 。[ 14 ]

你可以检查这个 desmos ,它包含了一些其他的激活功能。

YOLO v4 设计

到目前为止,我们已经讨论了用于提高模型精度的方法和对象检测器的不同部分(脊柱、颈部、头部)。现在让我们谈谈在新 YOLO 使用什么。

  • 主干:使用 CSPDarknet53 作为 GPU 版本的特征提取器模型。对于 VPU(视觉处理单元),他们考虑使用 efficient net-lite—mix net—ghost net 或 MobileNetV3。我们现在将重点放在 GPU 版本上。

下表显示了 GPU 版本的不同主干

来源[ 5

某些主干更适合于分类而不是检测。例如,CSPDarknet53 在检测对象方面比 CSPResNext50 更好,CSPResNext50 在图像分类方面比 CSPDarknet53 更好。如论文中所述,用于对象检测的主干模型需要更大的输入网络尺寸,以更好地检测小对象,并需要更多的层,以获得更高的感受域。

  • 瓶颈:他们使用空间金字塔池(SPP)和路径聚合网络(PAN)。后者与最初的 PAN 不同,而是一个修改版本,用一个 concat 代替了加法。插图显示了这一点:

来源[ 5 ]

最初在 PAN 纸中,在将 N4 的尺寸减小到与 P5 具有相同的空间尺寸之后,他们将这个新的减小尺寸的 N4 与 P5 相加。这种情况在𝑃𝑖+1 和𝑁𝑖的各个层面上重复出现,从而产生了𝑁𝑖+1.在 YOLO v4 中不是用每个𝑃𝑖+1 加上𝑁𝑖,而是用串联它们(如上图所示)

路径聚合网络(PAN)源[ 2

查看 SPP 模块,它基本上在 1919512 的特征图上执行最大池化,具有不同的内核大小 s k = { 5,9,13}和“相同的”填充(以保持相同的空间大小)。四个相应的特征地图然后被连接以形成 19192048 的体积。这增加了颈部感受野,从而提高了模型的准确性,而推理时间的增加可以忽略不计。

在 yolov4.cfg 中观察到的 SPP

如果你想可视化yolo 中使用的不同图层,如上图所示,我推荐使用这个工具(网络/桌面版本都可以),然后用它打开 yolov4.cfg

  • :和 YOLO v3 用的一样。

YOLO 头适用于不同的规模

这些探头应用于网络的不同规模,用于检测不同大小的物体。因为(80 个 + 1 个对象 + 4 个坐标 ) * 3 个锚,所以通道数为 255。

使用的 BoF 和 BoS 汇总

YOLO v4 的主干网和检测器中使用的 BoF 和 BoS 的不同模块/方法可以总结如下:

其他改进

该论文的作者介绍了一种新的数据增强方法,称为“马赛克”。基本上,这将训练数据集的 4 幅图像组合在一幅图像中。通过现在这样做:

批量标准化从每层上的 4 个不同图像计算激活统计[ 5

因此,它大大减少了选择一个大的小批量训练的需要。检查下图,显示新的增强方法。

来自[ 5 ]的镶嵌数据增强

示例:用于车牌检测的马赛克增强

他们也使用自我对抗训练 (SAT),分两个前进后退阶段进行。在第一阶段,神经网络改变原始图像而不是网络权重。通过这种方式,神经网络对自身进行对抗性攻击,改变原始图像以制造图像上没有所需对象的假象。在第二阶段,训练神经网络以正常方式检测该修改图像上的对象。[ 5

Colab 演示

我做了一个 Colab 来测试 YOLO v4 &你自己视频的小版本。这使用了在可可小姐身上训练的模型。你可以看一看这里

结论

这篇文章中提到了许多有趣的想法,可以更详细地解释,但我希望主要概念是清楚的。

更多细节可在文件中找到。如果你想在自己的数据集上训练它,可以查看一下官方回购

YOLO v4 在实时对象检测方面取得了最先进的结果(43.5% AP),并且能够在 V100 GPU 上以 65 FPS 的速度运行。如果你想要更低的精度,但更高的 FPS,请在官方回购处查看新的 Yolo v4 微型版本。

参考

[1] 用于目标检测的特征金字塔网络

[2] 路径聚合网络实例分割

[3] EfficientDet:可扩展且高效的对象检测

[4] 密集物体检测的焦点损失

[5] YOLOv4:物体检测的最佳速度和精度

[6] 单发多盒探测器(SSD)

【7】基于多级特征金字塔网络的单镜头目标检测器

[8] 改进了带有断流器的卷积神经网络的正则化

[9] 学习空间融合用于单次拍摄对象检测

[10] 随机擦除数据增强

[11] 并集上的广义交集:包围盒回归的度量和损失

[12] UnitBox:一个先进的物体探测网络

【13】drop block:卷积网络的正则化方法

[14] Mish:一个自正则化的非单调神经激活函数

[15] 压缩和激励网络

[16] CBAM:卷积块注意模块

YOLO v4 还是 YOLO v5 还是 PP-YOLO?

原文:https://towardsdatascience.com/yolo-v4-or-yolo-v5-or-pp-yolo-dad8e40f7109?source=collection_archive---------0-----------------------

2020 年 YOLO 会发布哪些新电影?它们有什么不同?我应该使用哪一个?

对象检测是一项计算机视觉任务,涉及预测一个或多个对象的存在,以及它们的类别和边界框。YOLO(你只看一次)是一个先进的对象检测器,可以实时执行对象检测具有良好的准确性。

YOLO 物体检测(图片作者

前三个 YOLO 版本分别于 2016 年、2017 年和 2018 年发布。然而,在 2020 年,在仅仅几个月的时间内,YOLO 的三个主要版本已经发布,命名为 YOLO v4,YOLO v5 和 PP-YOLO。YOLO v5 的发布甚至在机器学习界引起了争议。

此外,这在那些将要开始他们的机器学习项目的人的头脑中造成了一个困境。在本文中,我们将讨论这些新的 YOLO 版本的原因,同时强调它们的原创性、原创性、性能和主要改进,帮助人们为他们的项目选择最合适的版本。

YOLO 是如何进化的

YOLO 于 2016 年首次推出,由于其能够以更高的精度实时检测物体,因此是物体检测研究的里程碑。

它是由华盛顿大学毕业生约瑟夫·雷德蒙提出的。描述 YOLO 的论文在 2016 年计算机视觉和模式识别大会(CVPR)上获得了 OpenCV 人民选择奖

约瑟夫·雷德蒙的 YOLO 版本

  1. 版本 1
    ' 你只看一次:统一、实时的物体检测 ' (2016)
  2. 版本 2
    ' YOLO9000:更好更快更强 ' (2017)
  3. 版本 3
    ' YOLOv3:增量改进 ' (2018)

YOLO v2 可以以 40–90 FPS 的速度处理图像,而 YOLO v3 允许我们在速度和准确性之间轻松权衡,只需改变模型大小,无需任何重新培训。

在 VOC 2007 和 COCO 数据集上 YOLO 的表现(来源:pjreddie.com

主要的 YOLO 实施

Redmon 的 YOLO 主要实现基于 Darknet ,这是一个用 C 和 CUDA 编写的开源神经网络框架。暗网设置网络的底层架构,并用作训练 YOLO 的框架。这个实现是由 Redmon 自己介绍的,它速度快,易于安装,支持 CPU 和 GPU 计算。

后来,Ultralytics LLC 的 Glenn Jocher 为 YOLO v3 推出了一个 PyTorch 翻译

v3 之后没有 YOLO 更新?

YOLO 很快就在计算机视觉界出名了,因为它的速度非常快,精确度也很高。然而,在 2020 年 2 月,YOLO 的创造者 Joseph Redmon 宣布他已经停止了计算机视觉的研究!他还表示,这是由于对其工作的潜在负面影响的一些担忧。

来自 Redmon 的公告(来源:twitter.com)

这导致了一些热门的社区讨论,并提出了一个重要的问题:将来会有任何 YOLO 更新吗?

YOLO v4

雷德蒙的退出并不是 YOLO 的终结。重温计算机视觉社区中的许多人,第四代 YOLO 已于 2020 年 4 月发布。Alexey Bochkovskiy 等人在一篇名为' YOLOv4:物体检测的最佳速度和精度 ' 的论文中介绍了这一点。

此外,Redmon 的工作由 Alexey 在库的分支中继续。YOLO v4 被认为是用于物体检测的最快和最准确的实时模型。

YOLO v4 的主要改进

YOLO v4 受到了最先进的 BoF(一袋免费赠品)和几个 BoS(一袋特价商品)的影响。BoF 提高了检测器的准确性,而不增加推理时间。它们只会增加培训成本。另一方面,BoS 增加了少量的推理成本,但是它们显著地提高了目标检测的准确性。

YOLO v4 性能

YOLO v4 也基于 Darknet,并在 COCO 数据集上获得了 43.5%的 AP 值,在 Tesla V100 上获得了 65 FPS 的实时速度,在速度和准确性方面击败了最快和最准确的检测器。

与 YOLO v3 相比,AP 和 FPS 分别增加了 10%和 12%。

YOLO v4 的速度和准确性(来源: YOLO v4 论文

Redmon 对 YOLO 作者身份的回应

2020 年 4 月 24 日,Redmon 的原始 github 帐户的自述文件更新了一个链接,指向 Alexey 的分叉知识库和 YOLO v4 论文。Redmon 也在推特上写道:

Redmon 对 YOLO 作者身份的回应(来源:【twitter.com】T2)

YOLO v5

在 YOLO v4 发布后,仅仅两个月的时间内,YOLO 的另一个版本——YOLO V5 也发布了!作者是 Glenn Jocher,他已经因为创建了流行的 YOLO v3 的 PyTorch 实现而在社区中闻名。

2020 年 6 月 9 日,Jocher 声明他的 YOLO v5 实现是公开发布的,并推荐在新项目中使用。然而,在最初发布这个新版本时,他并没有发表一篇论文。

YOLO v5 的主要改进

YOLO v5 不同于所有其他以前的版本,因为这是 PyTorch 实现,而不是从原始 Darknet 派生出来的。与 YOLO v4 相同,YOLO v5 有一个 CSP 主干和 PA-NET 颈部。主要改进包括镶嵌数据增强和自动学习边界框锚。

机器学习社区的争议

YOLO v5 的发布备受关注,在机器学习社区平台引起了热烈讨论。这主要是由于 Roboflow 团队发表的一篇关于 YOLO v5 的文章中的几个事实。

这篇题为“YOLOv5 在这里”的文章于 2020 年 6 月 10 日发表在 Roboflow 博客上,陈述了几个重要的事实。以下是约瑟夫·尼尔森和雅各布·索拉维茨在的博客文章中的一些引言。

“运行特斯拉 P100,我们看到每幅图像的推理时间高达 0.007 秒,这意味着每秒 140 帧(FPS)!相比之下,YOLO v4 在转换到同一个 Ultralytics PyTorch 库后实现了 50 FPS。”

“YOLO v5 很小。具体来说,YOLO v5 的权重文件是 27 兆字节。我们的 YOLO v4(使用 Darknet 架构)的权重文件是 244 兆字节。YOLO v5 比 YOLO v4 小了近 90%。”

所以,据说 YOLO 的 v5 比 YOLO 的 v4 速度更快,重量更轻,而精度却和 YOLO 的 v4 基准相当。但是社区提出的主要问题是:这些基准是准确的和可重复的吗?

反应

《YOLO》v4 的作者阿列克谢对所有这些比较的方式并不满意。他回答了 github 中提出的几个问题,提到了那些比较的问题,特别是批量大小。

Roboflow 和 YOLO v5 的开发者也对黑客新闻社区的问题做出了积极回应,并于 6 月 14 日在 Roboflow 博客上发表了一篇文章,描述了他们如何比较这两个版本。

PP-YOLO

PP-YOLO 已于 2020 年 7 月通过向龙等人题为 PP-YOLO:对象检测器的有效和高效实现的论文引入,它基于 PaddlePaddle(并行分布式深度学习),这是一个开源的深度学习平台,最初由百度科学家开发。

PP-YOLO 是一种新颖的模式吗?

PP-YOLO 基于 YOLO v3 模型。该论文明确指出,PP-YOLO 的目标是实现一种具有相对平衡的有效性和效率的对象检测器,可以直接应用于实际应用场景,而不是提出一种新的检测模型。

值得注意的变化包括将 YOLO v3 的 Darknet53 主干替换为 ResNet 主干,并将训练批量从 64 增加到 192(在 8 个 GPU 上为 24 的小批量)。

聚丙烯-YOLO 性能

根据该论文,PP-YOLO 可以实现 45.2% COCO 数据集的地图,这超过了 YOLO v4 的 43.5%。在批量为 1 的 V100 上测试时,PP-YOLO 可以达到 72.9 FPS 的推理速度,也高于 YOLO v4 的 65 FPS。

PP-YOLO 的作者推测 tensorRT 在 ResNet 模型上比 Darknet 更好的优化是这种性能改善背后的主要原因。

PP-YOLO 的速度和准确性(来源: PP-YOLO 回购)

最后的话

在本文中,我们讨论了 YOLO 发展的重要里程碑以及 2020 年许多新 YOLO 版本背后的故事,同时强调了这些最新 YOLO 版本的主要改进和性能。总之,YOLO v4 是这种先进的物体检测器的最新的基于暗网的实现。它还有一篇阿列克谢·博奇科夫斯基(Alexey Bochkovskiy)发表的基准论文。另一方面,YOLO v5 是 Ultralytics 的新 PyTorch 实施方案,当以较大批量进行测试时,据说它比大多数检测器具有更高的干扰速度。然而,在撰写本文时,还没有针对 YOLO v5 发表的同行评审论文。PP-YOLO 是另一个基于深度学习框架 PaddlePaddle 的新 YOLO 升级版,它改进了 YOLO v3 模型,以在有效性和效率之间获得更好的平衡。我们讨论的事实,比如每个版本的架构、改进和性能,将有助于为特定项目选择最合适的 YOLO 版本。继续学习!

参考

[1]约瑟夫·雷德蒙的官网

[2]发表论文 YOLO v1YOLO v2YOLO v3YOLO v4PP-YOLO

[3]Redmon 的原版 YOLO 、Alexey 的 YOLO v4 、Jocher 的 YOLO v5 和向龙的 PP-YOLO 的 Github 库。

[4]“约洛夫 5 在这里”和“回应关于约洛夫 5 的争议”约瑟夫·尼尔森和雅各布·索拉维茨在 Roboflow 博客上的博文。

[5] " YOLO 回来了!第 4 版拥有更高的速度和准确性”syncedreview.com 上发表的黑卡蒂的文章

YOLOv5 来了!

原文:https://towardsdatascience.com/yolo-v5-is-here-b668ce2a4908?source=collection_archive---------8-----------------------

使用定制数据集& YOLOV5 进行大象检测器训练

来源:https://pjreddie.com/

Y OLO " 你只看一次"是 AI 工程师最流行、最喜欢的算法之一。它一直是实时对象检测的首选。

YOLO 出现至今,因为它的第一个版本。让我们简单讨论一下 YOLO 的早期版本,然后我们将直接进入训练部分。

以前的 YOLO 版本

YOLO v1 于 2016 年 5 月由 Joseph Redmon 以论文“你只看一次:统一的实时对象检测推出这是实时物体检测领域最大的进步之一。

2017 年 12 月,约瑟夫用纸推出了另一个版本的 YOLO“yolo 9000:更好、更快、更强”它也被称为 YOLO 9000。

一年后的 2018 年 4 月,最受欢迎和稳定的 YOLO 版本推出。约瑟夫这次有了一个合作伙伴,他们用纸“ YOLOv3:增量改进”发布了 YOLOv3。

最后,在 2020 年 4 月,Alexey Bochkovskiy 用论文介绍了 yolov 4 "yolov 4:物体检测的最佳速度和精度 " Alexey 不是以前版本的 YOLO 的官方作者,但 Joseph 和 Ali 从 YOLO 后退了一步,必须有人来处理这个时代。

YOLOv4 引入了一些令人震惊的新东西,它以很高的利润超过了 YOLOv3,而且与 EfficientDet 系列相比,它的平均精度也很高。

来源: YOLOv4 论文

几天后的 2020 年 6 月 9 日,仅仅四天前,另一位非官方作者 Glenn Jocher 发布了 YOLOv5。关于“YOLOv5”这个名字和其他东西的选择有很多争议。格伦推出了基于 PyTorch 的 YOLOv5 版本,并进行了出色的改进。因此,他还没有发布任何官方文件。

这个版本是相当惊人的,超越了所有以前的版本,并以更高的 FPS 接近 EfficientDet AP。你可以注意到下图。

来源:https://github.com/ultralytics

如需进一步比较,请访问 https://blog.roboflow.ai/yolov4-versus-yolov5/的。

在自定义数据集上训练 YOLOv5

该部分包括如下所列的多个步骤,

  1. 正在准备数据集
  2. 环境设置
  3. 配置/修改文件和目录结构
  4. 培养
  5. 推理
  6. 结果

本教程的代码可以在的这个 GitHub 资源库中找到。

正在准备数据集

一旦获得了 YOLO 格式的标注数据集,就可以开始工作了。

在本教程中,我们将使用来自开放图像数据集的大象检测数据集。

要获得带标签的数据集,你可以搜索开源数据集,或者你可以从网上抓取图片,并使用像 LabelImg 这样的工具对其进行注释。

注意:你的注释格式应该是 YOLO 格式。

确保您将注释和图像保存在同一个目录中。

然后生成训练、测试和验证 txt 文件,为此只需复制图像文件并将路径粘贴到 txt 文件中。最佳实践是将 70%的数据保存在定型集中,20%保存在验证集中,10 %保存在测试集中。

对于本教程,我将使用这个训练测试验证 txt 文件。

此外,我还添加了一个带标签的数据集,这里是,images 目录包含所有图像,txt 目录包含所有注释。

环境设置

需要注意的重要一点是,您将需要 PyTorch 版本≥ 1.5、Python 版本 3.7 和 CUDA 版本 10.2。

使用 pip 或 requirement.txt 文件可以很容易地安装下面的依赖项。

numpy==1.17
scipy==1.4.1
cudatoolkit==10.2.89
opencv-python
torch==1.5
torchvision==0.6.0
matplotlib
pycocotools
tqdm
pillow
tensorboard
pyyaml

注:本教程我用的是 ubuntu 16.04。

一旦成功安装了所有的依赖项,就可以继续前进了。

配置/修改文件和目录结构

要训练 YOLOv5 模型,您需要执行一些步骤。

首先,从 YOLOv5 的克隆存储库开始。如果你正在学习本教程,你可以从这里开始克隆。你可以从官方回购克隆,也可以在这里形成。

第二,修改你需要添加的 YAML 文件来描述你的数据集参数。请参考以下 YAML 文件,并根据您的需要进行相应的修改。

# here you need to specify the files train, test and validation txt # files created in step 1.
train: /self/elephant_dataset/train_elephant.txt
val: /self/elephant_dataset/val_elephant.txt
test: /self/elephant_dataset/test_elephant.txt# number of classes in your dataset
nc: 1# class names
names: ['Elephant']

我们稍后将使用该文件来训练模型。

培养

为了训练约洛夫 5,格伦提出了 4 个版本。

  1. yolov5-s 这是一个小版本
  2. yolov5-m 这是一个中等版本
  3. yolov5-l 这是一个大版本
  4. yolov5-x 是一个特大号版本

你可以在这里看到他们的对比。

在训练时,你可以通过 YAML 文件来选择这些模型中的任何一个。所有的 YAML 文件都在这里。

现在一切都配置好了,我们准备训练我们的 YOLOv5 模型!

转到目录,使用下面的命令开始训练。

python train.py --img 640 --batch 8 --epochs 30 --data ./data/elephant.yaml --cfg ./models/yolov5s.yaml --weights '' --device 0
  • — img:输入图像的大小
  • —批次:批次大小
  • -时期:时期的数量
  • —数据:在步骤 3 中创建的 YAML 文件
  • cfg:模型选择 YAML 文件。我在本教程中选择了“s”。
  • —权重:应用迁移学习的权重文件,您可以在此处找到它们
  • —设备:选择训练设备,“0”代表 GPU,“cpu”代表 CPU。

该命令将立即开始模型训练。我已经决定训练 30 个纪元的模型。

训练完成后,模型将保存在您的“权重”目录中,生成的矩阵图如下。

来源:https://github.com/mihir135

正如我们所看到的,这个模型被训练得非常好,mAP@0.5 几乎是 0.78,非常好!

推理

现在模型已经训练好了,让我们在一些图像上测试它的性能。

要运行模型推理,请使用以下命令。

python detect.py --source sample_img/  --weights weights/best.pt --conf 0.4
  • —来源:输入图像目录或单个图像路径或视频路径
  • -权重:训练模型路径
  • — conf:置信度阈值

这将处理输入并将输出存储在您的推理目录中。

结果

在这里,我附上一些来自训练有素的模型推理输出图像。

来源:https://github.com/mihir135/yolov5

很棒吧!

你可以在这里找到训练有素的大象探测器。

你可以从这里下载并探索本教程的代码。

如果您有任何疑问,可以在回复部分发表评论。

我的 GitHub 或者 LinkedIn

特别感谢 Mayur Patel 的贡献与合作。

任何反馈或建议将不胜感激。

Yolo v5 物体检测教程

原文:https://towardsdatascience.com/yolo-v5-object-detection-tutorial-2e607b9013ef?source=collection_archive---------2-----------------------

如何建立和训练一个 Yolo v5 物体检测模型?

Yolo v5 物体检测教程。斯蒂芬·科斯马在 Unsplash 上拍摄的照片

物体检测是人工智能中的一项任务,重点是检测图像中的物体。Yolo V5 是目前最好的物体检测模型之一。这种深度神经网络的伟大之处在于,它非常容易在您自己的定制数据集上重新训练网络。

在本文中,我将介绍如何训练 Yolo V5 对象检测模型。我将把重点放在如何快速轻松地开始上,而不是调优模型的超参数。

使用预训练的 Yolo V5 模型的对象检测示例。原文来源知识共享 归属-共享 4.0 国际

你可以跟着满满的笔记本过来。

如何训练一个定制的 Yolo V5 车型?

要训练自定义 Yolo V5 模型,请遵循以下步骤:

  1. 设置您的环境
  2. 设置数据和目录
  3. 设置配置 YAML 文件
  4. 训练模型以学习如何检测物体
  5. 使用您的定制 Yolo V5 模型来检测测试数据上的对象

1.如何设置您的环境来训练 Yolo V5 对象检测模型?

要训练一个 Yolo V5 模型,需要从网上下载一些东西。

在笔记本电脑中,最简单的方法是直接从笔记本电脑中使用终端命令下载并设置您的环境,如下所示:

  • 从 GitHub 克隆 yolo V5 存储库

这将在您的机器上创建一个名为' yolov5 '的文件夹。该文件夹将包含您进一步需要的所有内容,包括模型的预训练权重和特定的目录结构。

  • 安装 pytorch 和其他必需的包

Yolo V5 运行在 Torch 上,有时安装起来可能会很复杂。如果你在这里挣扎,你可以移动到 Kaggle 或 Colab 笔记本:这些通常对这个安装很好。

2.如何设置用于训练 Yolo V5 对象检测模型的数据和目录?

Yolo V5 需要一套非常特殊的数据文件夹才能工作。

Yolo V5 目录结构

您需要在与您的 yolov5 文件夹相同的层次上创建一个名为 data 的文件夹。在这个数据文件夹中你需要创建一个图像文件夹和一个标签文件夹。在每一个文件夹中,您都为训练数据和验证数据创建了一个文件夹。

用于训练 Yolo V5 模型的目录树

如果文件没有放在正确的目录中,您以后可能会遇到错误。

Yolo V5 数据格式

图像

图像必须直接放在图像文件夹中。数据/图像/训练文件夹中的训练图像和数据/图像/有效文件夹中的验证图像。图像的名称必须是带有. jpg(或其他格式)的唯一名称。

标签

标签必须在数据/标签/序列/数据/标签/有效中。标签文件的名称必须与图像名称相同,但带有“.”。txt“而不是”。jpg”。

边界框必须作为每行一个边界框列出,该行上有:

  • 边界框中对象的类别号(如果只有一个类别,则始终为 0)
  • 以宽度表示的边界框的标准化中心像素
  • 以高度表示的边界框的标准化中心像素
  • 边框的标准化宽度
  • 边框的标准化高度

标准化是通过将像素数除以图像的总像素数来完成的。因此,在大小为(100,100)的图片上,宽度为 30×40 的像素(10,20)上的边界框将被标准化为(0.1,0.2,0.3,0.4)。

标签文件的行数是一幅图像中边界框的数量。标签文件的数量就是图像的数量。

一个名为“00333207”的训练图像的标签的提取。

3.如何配置用于训练 Yolo V5 对象检测模型的 YAML 文件?

要开始训练一个 Yolo V5 模型,你需要两个 YAML 文件。

第一个 YAML 规定:

  • 你的训练数据在哪里,
  • 你的验证数据在哪里,
  • 您想要检测的类别(对象类型)的数量,
  • 以及与这些类别相对应的名称。

这个 YAML 看起来像这样:

第二个 YAML 是指定整个模型,但是对于开始,我建议只改变第一行," nc 【T21 "),以得到正确的类数。

您可以将这些 YAML 文件放在任何您想要的地方,因为您稍后将引用完整的路径。

4.如何训练自己定制的 YoloV5 模型?

训练是使用 train.py 终端命令完成的,您可以从笔记本中执行该命令。

您可以指定多个超参数,例如批次大小、时期数和图像大小。然后,指定我们刚刚在上面创建的两个 yaml 文件的位置。您还需要指定一个名称,这对以后查找结果很重要。

运行这一行将在 yolov5 中创建一个子文件夹,其中包含这个训练模型的权重,您可以在第 5 步中重用它。

这些文件夹将始终创建在同一个目录中:yolov 5/runs/exp0 _ your name/…

当您重新运行“train”命令时,Exp0 将增加到 exp1 等。

5.如何使用您定制的 Yolo V5 模型对新数据进行对象检测?

现在是最后一个阶段,你需要检测看不见的照片上的物体。这是使用终端命令 detect.py 完成的,它将生成一个包含输出的新文件夹。您可以生成带有边框的图片,也可以生成带有边框位置的文本文件。

这是按如下方式完成的:

然后你可以在文件夹 yolov5/inference/output/中找到你的输出。会有带注释的图片和。带有预测边界框的 txt 文件。

我希望这篇教程有用,感谢阅读!

YOLO——你只能看一次

原文:https://towardsdatascience.com/yolo-you-only-look-once-3dbdbb608ec4?source=collection_archive---------2-----------------------

一种实时目标检测系统的算法

介绍

我们借助眼睛看到一切,它捕捉框架中的信息,并将其发送到我们的大脑,以解码并从中得出有意义的推论。听起来很简单,对吧?我们只是看着,就能理解我们正在看的所有物体是什么,它们是如何放置的,以及关于它们的大量其他信息。但是大脑的处理能力是无与伦比的。

图片来源:维克多·弗雷塔斯,Unsplash.com

大脑这种有趣的能力让研究人员想到,如果我们能把这种能力赋予一台机器,会怎么样呢?有了这个,机器的任务将会变得简单得多,一旦它能够识别它周围的物体,它就能更好地与它们互动,这就是改进机器的全部目的,使它们对人类更友好,使它们更像人类。

在这个过程中,有一个很大的障碍。我们如何让机器识别一个物体?这就是计算机视觉领域的起源,我们称之为“物体检测”。对象检测是计算机视觉和图像处理的一个领域,它处理各种类型的对象(如人、书、椅子、汽车、公共汽车等)的检测。)在数字捕获的图像或视频中。

这个领域进一步划分为子领域,如人脸检测、活动识别、图像注释等等。目标检测在许多重要领域都有应用,如自动驾驶汽车、机器人、视频监控、目标跟踪等。

挑战

1.可变数量的对象

目标检测是对图像中数量可变的目标进行定位和分类的问题。重要的是【变量】部分。要检测的对象的数量可能因图像而异。因此,与此相关的主要问题是,在机器学习模型中,我们通常需要用固定大小的向量来表示数据。由于我们事先不知道图像中对象的数量,因此我们不知道输出的正确数量,并且我们可能需要一些后处理,这增加了复杂性。

2.多种空间比例和纵横比

图像中的对象具有多种空间比例和长宽比,可能有一些对象覆盖了图像的大部分,但也有一些我们可能想要找到,但只有十几个像素(或图像的很小一部分)。即使是相同的物体,在不同的图像中也会有不同的比例。这些不同尺寸的物体给追踪它们带来了困难。一些算法为此使用了滑动窗口的概念,但是这是非常低效的。

3.建模

进行目标检测需要同时解决两种方法-目标检测和目标定位。我们不仅想对物体进行分类,还想在图像中找到它的位置。为了解决这些问题,大多数研究使用多任务损失函数来惩罚误分类错误和定位错误。由于损失函数的这种双重性,很多时候它在两方面都表现不佳。

4.有限的数据

当前可用于对象检测的有限数量的注释数据是该过程中的另一个障碍。对象检测数据集通常包含大约十几到一百个类别的注释示例,而图像分类数据集可以包括多达 100,000 个类别。为每个类收集基本事实标签和边界框仍然是一项非常繁琐的任务。

5.实时检测的速度

对象检测算法不仅需要准确地预测对象的类别及其位置,还需要以令人难以置信的速度完成所有这些工作,以满足视频处理的实时需求。通常,一个视频以大约 24 帧/秒的速度拍摄,建立一个可以达到这种帧率的算法是一项非常困难的任务。

各种方法

我们考虑了对象检测领域的一些主要挑战,它们意味着什么以及它们如何影响过程。现在,我们先来看看一些试图解决这些挑战的模型,然后再揭晓其中的最佳模型——YOLO 算法。

1.快速 R-CNN

快速 R-CNN 是 R-CNN 的改进版本,但它存在多级流水线环境、空间和时间开销大、对象检测速度慢等缺点。为了消除它们,快速 R-CNN 引入了一种新的结构。

快速 R-CNN 架构,来源:快速 R-CNN

它将整个图像与对象建议一起作为输入。最初,该算法在输入图像上运行 CNN,并通过使用各种 conv 和最大汇集层来形成特征地图。之后,对于每个对象提议,感兴趣区域(RoI)汇集层提取固定长度的特征向量,并将其输入到全连接(FC)层。这一层进一步分支成两个输出层:一层为每个类以及“背景”类产生 SoftMax 概率,另一层为每个类输出四个实数,这四个实数定义了该特定类的边界框。

2.单触发多盒探测器(SSD)

SSD 工作在自由向前卷积层的方法上,该方法输出固定大小的边界框集合以及要出现在这些边界框中的对象类实例的分数。它还使用非最大抑制来产生最终决策。

SSD 架构,来源: SSD:单次多盒探测器

固态硬盘的架构非常简单。模型中的初始层是用于图像分类的标准 ConvNet 层,用他们的术语来说就是基本网络,在这个基本网络的基础上,他们然后添加一些辅助层来产生检测,同时牢记多尺度特征地图、默认框和纵横比。

3.视网膜网

Retina-Net 是一个单一的统一网络,由一个主干网络和两个特定任务的子网组成。主干负责计算整个输入图像上的 conv 特征图,并且是脱离自卷积网络。第一子网对骨干网输出进行分类;第二个子网执行卷积包围盒回归。

视网膜网络架构,来源:密集物体探测的焦点损失

它在前馈 ResNet 架构之上使用特征金字塔网络(FPN)主干来生成丰富的多尺度卷积特征金字塔,然后将其馈送到两个子网,其中一个对锚盒进行分类,另一个执行从锚盒到地面真实锚盒的回归。

YOLO 算法

到目前为止,我们已经看到了一些非常著名且性能良好的对象检测架构。所有这些算法都解决了本文开头提到的一些问题,但是没有解决最重要的一个问题——实时目标检测的速度。

YOLO 算法在我们讨论的所有参数上都给出了更好的性能,并且具有实时使用的高 fps。YOLO 算法是一种基于回归的算法,它不是选择图像中感兴趣的部分,而是在算法的一次运行中预测整个图像的类别和包围盒。

为了理解 YOLO 算法,首先我们需要理解实际预测的是什么。最终,我们的目标是预测对象的类别和指定对象位置的包围盒。每个边界框可以用四个描述符来描述:

  1. 盒子中心( bx,by )
  2. 宽度( bw )
  3. 高度( bh )
  4. 对应于对象类别的值 c

与此同时,我们预测一个实数 pc ,它是在边界框中有一个对象的概率。

YOLO 不会在输入图像中搜索可能包含对象的感兴趣区域,而是将图像分割成单元,通常是 19x19 的网格。然后,每个单元负责预测 K 个边界框。

这里我们取 K=5,预测 80 类的可能性

只有当锚定框的中心坐标位于特定单元中时,才认为对象位于该单元中。由于这一特性,中心坐标总是相对于单元计算,而高度和宽度是相对于整个图像尺寸计算的。

在前向传播的一个过程中,YOLO 确定单元包含某个类的概率。同样的等式是:

存在某个“c”类对象的概率

具有最大概率的类被选择并分配给特定的格网单元。对于图像中存在的所有网格单元,发生类似的过程。

计算上述类别概率后,图像可能如下所示:

这显示了预测每个网格单元的类概率之前和之后的情况。预测类别概率后,下一步是非最大值抑制,它有助于算法去除不必要的锚框,就像你在下图中看到的,有许多基于类别概率计算的锚框。

锚箱

为了解决这个问题,非最大值抑制通过执行 IoU(并集上的交集)来消除非常接近的边界框,其中 IoU 具有最高的类概率。

IoU 操作

它计算所有边界框的 IoU 值,分别对应于具有最高分类概率的边界框,然后它拒绝 IoU 值大于阈值的边界框。它表示这两个边界框覆盖了相同的对象,但是另一个覆盖相同对象的概率很低,因此被排除。

一旦完成,算法找到具有下一个最高类概率的包围盒,并进行相同的过程,直到我们剩下所有不同的包围盒。

非最大抑制之前和之后

在这之后,我们几乎所有的工作都完成了,算法最终输出所需的向量,显示各个类的边界框的细节。该算法的整体架构如下所示:

YOLO 架构,来源:你只看一次:统一的,实时的物体检测

此外,该算法最重要的参数,其损失函数如下所示。YOLO 同时获知它预测的所有四个参数(如上所述)。

YOLO 损失函数,来源:你只看一次:统一的,实时的物体检测

所以这都是关于 YOLO 算法的。我们讨论了对象检测的所有方面以及我们在该领域面临的挑战。然后,我们看到了一些试图解决这些挑战的算法,但在最关键的实时检测(fps 速度)方面失败了。然后,我们研究了 YOLO 算法,它在面临的挑战方面优于所有其他模型,它的快速性可以在实时对象检测中很好地工作,遵循回归方法。

算法仍在改进中。我们目前有四代 YOLO 算法,从 v1 到 v4,还有一个稍微小一点的版本 YOLO-tiny,它是专门设计来实现令人难以置信的 220fps 的高速度。

我希望我能够清楚你对算法和物体检测相关概念的理解。如果你觉得这篇文章信息丰富,你可以在未来关注我更多这样的文章。快乐学习!

YOLO:你只看一次|物体探测

原文:https://towardsdatascience.com/yolo-you-only-look-once-f05c054a06b4?source=collection_archive---------16-----------------------

人工智能

深度学习卷积神经网络(CNN)

照片由克莱门特·HUnsplash 上拍摄

“嘿,我们的朋友在跳崖,要来吗?人只能活一次!”

“不,我只要看一眼就知道我没在做。”

你可能已经习惯了这句话【YOLO:你只能活一次】。但是,这实际上不是本文的主题。我说的是《YOLO:你只看一次》

这是一个非常聪明的算法,它非常擅长检测给定图像或视频中的对象。事实上,它只需要看一次。

它是如何工作的?

神经网络

神经网络为 YOLO 提供动力,它们是一种特殊类型的计算机算法。因为它们是模仿我们的大脑而命名的,所以它们被设计用来检测模式(就像我们的大脑一样!).

YOLO 本身是一个卷积神经网络(CNN),这是一种神经网络,非常擅长检测图像中的模式(以及扩展对象等)。

神经网络层

神经网络是由层组成的,CNN 大多是由卷积层组成的(因此得名)。这就像在图像上滑动滤镜,每一层都越来越复杂。这是一个形象化的例子:

图片来自斯坦福(不再在那里举办)

这里的过滤器是我们用来相乘的数字。基本上,我们查看图像的一部分,应用滤波器,并对结果求和以获得卷积特征。如果我们认为图像是灰度的,那么每个数字就是像素的亮度。

早期的图层可能会滑过旨在寻找边缘、拐角和形状的过滤器,但后期的图层可能会检测更复杂的特征,如肢体、面部和整个对象。这是一个边缘检测卷积网络。

照片来自丹尼·布里兹KDNuggets

以及输入和输出图像:

照片来自丹尼·布里兹KDNuggets

照片来自丹尼·布里兹KDNuggets

池层

池化要简单得多,也类似于卷积。池化不是检测要素,而是通过减小网络的空间大小来减轻网络的负载。

图片来自王新惠

基本上,它减少了卷积层的输入大小,通常有两种方法:

Max Pooling
Max Pooling 是第一种,在图像的每个单元格中取最大的数字。

平均池化 第二种类型的池化,其中你对图像的每个单元格中的所有数字进行平均。

激活层

激活层是神经网络的关键。在每一步,我们必须定义输出,它将是下一步的输入(或者是最后的实际输出)。

图片来自 GumGum

YOLO 使用 ReLU(整流线性单位)。ReLU 激活用于每个卷积步骤,而不是池化步骤,因为它们只是为了减轻负载。基本上,ReLU 通过修改输出来工作,所以任何小于 0 的都变成零,其他的都是原始输出(基本上不改变任何东西)

图上关系的可视化。“x”是 ReLU 的输入,而“y”是 ReLU 的输出。(来源:费尔南多·德·梅尔·帕尔多)

整个 YOLO 网络看起来像这样。

别急,这个你不需要完全理解!(来源: MDPI )

这就是 YOLO 成为 CNN 的原因。CNN 非常擅长图像分类(弄清楚一个物体是什么),但这只是问题的一半。

算出物体在哪里呢?

虽然我们已经介绍了如何对物体进行分类,但是我们还希望能够知道这些物体在图像中的位置。

YOLO 首先将一幅给定的图像或一帧视频分成 N 个方块。然后,每个网格单元检测其中的对象,并预测多个边界框以及这些框的置信度得分(边界框只是预测对象的位置并在其周围放置一个框)。

之后,它会根据训练数据,获得足够高的置信度分数,从而可能是一个对象,并预测该对象是什么。这意味着只有在给定一个对象数据集后,才能检测到带有 YOLO 的对象。

视觉表现。(边界框越粗,越精确。)(来源: Pj Reddy )

这允许你检测物体,并预测它们是什么!

我的实现

我决定创建一个 YOLO 的实现,它可以预测机场场景中的不同物体!

我发现了 YOLO 可可数据集,这是一个预制的数据集,适用于检测一般物体,如行李箱、人、汽车、滑板等。这让我轻松多了。

在对所有东西进行编程之后,在 YOLO 学习了数据集之后,YOLO 能够制作这张图片。

我的图像

用例

YOLO 也有一些使用案例,在这些案例中,YOLO 真的非常有用!以下是一些例子:

回收利用

YOLO 可以用于回收工厂,帮助控制机器人和垃圾分类。既然 YOLO 如此擅长探测物体,我们可以训练它在回收设施中对废物进行分类

自动驾驶汽车

YOLO 在自动驾驶汽车中特别有用,事实上今天已经用于检测汽车、人和交通灯了!它允许完全自主控制!

嫌疑人检测

这有点牵强,但 YOLO 可以通过找出潜在的嫌疑人来协助警方调查。这对于低质量的录音等非常有帮助!

图片来自我

所以,这就是 YOLO 物体探测!它可能是同类算法中最好和最高效的,它有很多机会。这只是一个表面的解释,我希望我已经教了你足够的东西,让你能够用你的好奇心推动你走得更远!

如果你喜欢阅读这篇文章,或者有任何建议或问题,请留言告诉我。您可以在 LinkedIn、 或我的 网站 上找到我,了解我的最新工作和更新,或者直接联系我的 邮箱

Yolo 2 解释道

原文:https://towardsdatascience.com/yolo2-walkthrough-with-examples-e40452ca265f?source=collection_archive---------2-----------------------

实现和可视化

Yolo 是该领域最成功的目标检测算法之一,以其闪电般的速度和相当高的精度而闻名。与需要多次特征提取的逐区域检测对象的其他区域提议框架相比,输入图像在 Yolo 中被处理一次。在本教程中,我们将一窥 Yolo2 的代码。

RCNN 网络

对于那些想一步一步运行代码而不是看评论的人,可以看看我在 GitHub 上的补充回购!repo 有几个教程涵盖了 Yolo 的所有方面,还有一个现成的库供您使用!

[## zzx victor/YOLO _ 解释

Yolo 是一个完全卷积的模型,与许多其他扫描检测算法不同,它在…

github.com](https://github.com/zzxvictor/YOLO_Explained)

Yolo 输出格式

要理解 Yolo2 是如何工作的,关键是要理解 Yolo 架构是什么样子的。Yolo2 使用 VGG 风格的 CNN 称为黑暗网络作为特征提取器。请注意,DarkNet 是各种网络的保护伞,人们使用不同的变体来提高速度或准确性。

图一。yolo2 中作为特征提取器的暗网

如你所见,yolo 的输出与我们之前看到的完全不同。图像中有 416 x 416 像素,但输出是 13 x 13。我们究竟如何解释这些结果?

让我们暂时把 Yolo 放在一边,想想我们如何在一条路径上进行物体检测?这是我天真的解决方案:

Suppose we have a network that takes an input image of size, say 416 x 416 x3, and there are 20 classes in the dataset.For every pixel in the image, we can predict a box with the following layout(Figure 2). The model output has shape 416 x 416 x22

图二。天真的方法

Yolo 被设计成快速准确。因此,预测每个像素一个盒子是不理想的(两个相邻的像素可能属于一个对象)。发明 YOLO 的极客们去工作,想出了一个更好的主意

优化 1 —减少预测箱数

我们将一幅图像分成 S×S 个网格,并预测每个 网格的 个盒子,而不是预测每个像素一个盒子。

With this optimization, the output can be reduced to something like 13 x 13 x 5*22, if we predict 5 boxes per grid. This is a significant drop in box numbers

图 3。约洛

优化 2 —用于过滤掉低置信度预测的对象分数

除了分类概率之外,Yolo 还引入了一个对象分数。对象分数是对一个对象是否出现在预测框中的估计(它不关心什么对象,那是类概率的工作)。如果一个预测具有较低的对象分数,它将在后处理中被丢弃。也就是说,边界框应该像这样

图 4。更好的方法

With this optimization, the output will have shape 13 x 13 x 5 * (3+20)

优化 3 —根据数据集量身定制

图 5,不同尺寸和比例的锚盒。高盒子适合人类等物体,而宽盒子适合公共汽车和自行车等物体

Yolo 没有预测整个图像中盒子的绝对大小,而是引入了所谓的锚盒,这是一个预定义的盒子列表,最匹配所需的对象(给定基本事实,运行 K 均值聚类)。预测框相对于锚点进行缩放。更具体地说:

  1. 预测盒子中心(图 6 中的 tx 和 ty)w . r . t 其网格左上角的网格宽度和高度缩放。
  2. 根据锚盒 (pw 和 ph)预测盒 的宽度(tw)和高度(th)

图 6。 Yolo2 中的锚盒

最终格式

现在你知道 YOLO 预测每个网格有几个边界框,而不是只有一个。输出形状类似于 13 x 13 x NUM_ANCHOR X (BOX INFO ),其中最后一个维度看起来就像简单方法的升级版。

图 6。yolo 格式

*With all optimizations, Yolo output can be interprated as:
for every grid:
    for every anchor box: (with different aspect ratios and sizes)
        predict a box
Thus, yolo output has shape 13 x 13 x 5 x 25, which is reshaped in practice into 13 x 13 x 125*

图 7。验证分析

边界框的原始输出

现在我们明白 Yolo 2 的格式了。下一步是如何从原始张量中提取盒子。你确定我们不能用所有 13 x 13 x 5 的盒子吗?在这一节中,我们将看到如何从原始输出张量中提取信息。

*Let's assume the output Y has shape 2 x 2 x 2*6, meaning there are two anchors per grid and one class in the dataset. 
Assume Y[0,1,0,:] = [0, 0, 0.4, 0.4, 0, 0.5]. This defines the red box in figure 8\. But how to decode it?*

图 8

步骤 1-提取框坐标

让我们来看看这些信息

*[0, 0, 0.4,  0.4, 0, 0.5] = 
[tx,  ty,  tw,  th,  obj score,  class prob.]
Please refer to figure 6*

我们需要将相对坐标 tx,ty 转换为图像比例坐标 bx,by,对于 tw 和 th 也是如此。下面是如何在 tensorflow 2 中实现的

*After this step the red box coordinate is converted from:
[0, 0, 0.5, 0.5] to 
[0.5, 1.5, 1.13, 0.75], meaning it's (0.5 grid height, 1.5 grid width) from the top left image corner and the box has size (1.13 grid height, 0.75 grid width)*

现在我们有了预测的盒子在网格尺度上的坐标和它的大小,很容易计算它的角的坐标(图 8 中紫色和绿色的点)。我们做这一步是因为用它的角而不是它的中心和宽度/高度 来表示一个盒子是标准的

要获得绿色和紫色点的坐标,我们需要:

*green dot = boxXY - boxWH / 2
purple dot = boxXY + boxWH /2 
(Please note that the top left corner has smaller cordinates in images)*

在这之后,我们用(32,32)乘以坐标,这样边界框现在就是图像比例了。例如,(0,0)表示左上角,(1,1)表示右下角,(0.5,0.5)表示图像中心

第 2 步—过滤掉低质量的盒子

对于每个网格和每个定位框,yolo 预测一个边界框。在我们的例子中,这意味着预测了 13 * 13 * 5 个盒子。可以想象,并不是所有的框都是准确的。其中一些可能是假阳性(无对象),一些是预测同一对象(太多重叠)。为了获得最终结果,我们需要:

*Filter out boxes with low confidence (object score)
Filter out boxes that overlaps too much (two boxes have high IOU)*

魔法时间

就是这样!这些是您解码 yolo 输出所需的唯一脚本。让我们来看看结果:

图 9

阅读脚本可能会非常混乱,这就是我强烈建议你检查一下回购并在 Google Colab 或你的本地计算机上运行它。

非常感谢您的阅读!在未来的教程中,我将讨论加载训练数据和转移学习!

MATLAB 中 ONNX 模型的 YOLOv2 物体检测

原文:https://towardsdatascience.com/yolov2-object-detection-from-onnx-model-in-matlab-3bb25568aa15?source=collection_archive---------28-----------------------

我如何在 MATLAB 中导入微小的 YOLOv2 ONNX 模型,并重新训练网络来检测自定义数据集上的对象

图片由恩布里-里德尔的机器人小组提供

数据集

RoboSub 是由 RoboNation 举办的一项比赛,学生们建造一个自主水下航行器来执行模拟搜索&救援任务。基本任务是识别和避开水下物体。

这篇报道所用的图像数据由位于的 Embry-Riddle 的 RoboSub 团队的机器人协会提供。这些图像是在他们的训练过程中用安装在水下机器人上的实时摄像机拍摄的。完整的数据集可以从谷歌硬盘下载。

数据准备

所有图像的大小都被调整为(416 x 416 x 3)并被分成训练、测试和验证三个文件夹。然后使用 MATLAB 中 地面真实贴标机应用 中的自定义自动化算法对图像进行贴标。要了解更多关于完整标记过程的信息,请参考此 YouTube 视频

来自地面实况贴标机 app 的数据以 地面实况 数据对象的形式导出到 MATLAB 中。然后使用函数objectDetectorTrainingData将其进一步转换为表格 详细代码文件位于这里

注意:下载数据并运行数据预处理 脚本,然后继续下一步

进口和培训

本节将介绍导入 ONNX 模型的步骤,然后根据数据集的类别执行迁移学习。

第一步:从 onnx 模型动物园导入 微小的 YOLOv2 onnx 模型

文件被下载并存储为文件夹中的 model.onnx

*modelFile = **fullfile**('Utilities','model.onnx');*

importONNXNetwork函数从 onnx 导入预先训练好的网络。作为函数参数,我传递了 modelFile'OutputLayerType"

*net = **importONNXNetwork**(modelFile,'OutputLayerType','regression');*

导入的 tiny YOLOv2 模型是一个共 34 层的网络,结合了: 输入图像,8 组卷积,batchnorm,激活合并 层,最后一层为 卷积 8 层。我使用 analyzeNetwork 函数可视化了网络架构。

***analyzeNetwork**(net);*

使用网络分析器可视化导入的 YOLOv2 Onnx 模型。(图片由 Neha Goel 提供)

第二步:根据训练数据计算待检测的班级数锚箱

在这个项目中,我有 4 个类/对象:导航门,绿色浮标,红色浮标和黄色浮标。**

*numClasses = size(trainingData,2)-1;*

使用聚类方法计算锚盒。下面的详细过程在这里链接

*Anchors = [43 59
    18 22
    23 29
    84 109];*

第三步:重新设计并组装 YOLOv2 网络。

然后,我根据要检测的类重新设计了导入的网络。我用函数yolov 2 layers实现了它。* 它在提取图层的末端添加了一个 YOLOv2 网络。*

该函数的参数如下:

  1. 输入大小:给网络的最小输入大小。这里我给了(128 x 128 x 3)。
  2. 在上述步骤 2 中计算的等级 ( numClasses )和锚的数量
  3. 从上述步骤 1 导入的网络 ( net)
  4. 特征提取层:从该层提取的特征作为输入给 YOLOv2 目标检测子网络。您可以指定除全连接层之外的任何网络层。这里我使用了 activation4 命名层的导入网络 net
*lgraph = **yolov2Layers**([128 128 3], numClasses, Anchors, net, 'activation4');*

下图显示了新网络的样子。观察特征层激活 4* 后添加在末端的yolov 2 层的高亮子网络。*

***analyzeNetwork**(lgraph);*

添加 yolov 2 图层后可视化修改后的网络(图片由 Neha Goel 提供)

第四步:训练新网络。

基于数据集的大小,我用求解器训练了网络——随机梯度下降 100 个时期,初始学习率为 0.001,小批量为 10。考虑到数据的大小以及调整时期和小批量的大小,我执行了较低的学习速率,以便有更多的时间进行训练。我用来选择选项的文件是:训练选项

*options = **trainingOptions**('sgdm', ...
"LearnRateSchedule","piecewise", ...
'LearnRateDropFactor',0.5,...
"LearnRateDropPeriod",5,...
'Verbose' ,true, 'MiniBatchSize',10,'MaxEpochs',100, ...
'Shuffle','every-epoch', 'VerboseFrequency',50, ...
'DispatchInBackgrpund',true,...
'ExecutionEnvironment','auto');*

然后我用trainyolov 2 object detector函数来训练我的网络。**

**[detectorTinyYolo2, info] = **trainYOLOv2ObjectDetector**(trainingData, lgraph,options);**

评估&结果

一旦我有了训练好的网络,我就按照下面的步骤在测试数据上评估它的性能。

步骤 1: 创建一个表来保存结果,并初始化一个可部署的视频播放器来查看图像流。

**results = **table**('Size',[height(TestData) 3],...
'VariableTypes',{'cell','cell','cell'},...
'VariableNames',{'Boxes','Scores', 'Labels'});depVideoPlayer = **vision.DeployableVideoPlayer**;**

步骤 2: 遍历测试集中的所有图像。

**for i = 1:height(**TestData**)
    *% Read the image*
    I = imread(TestData.imageFilename{i});

    *% Run the detector.*
    [bboxes,scores,labels] = detect(detectorTinyYolo2,I); if ~isempty(bboxes)
         I = **insertObjectAnnotation**(I,'Rectangle',bboxes,cellstr(labels))       

         depVideoPlayer(I);
         pause(0.1);
    else
         depVideoPlayer(I);
    end *% Collect the results in the results table*
    results.Boxes{i} = floor(bboxes);
    results.Scores{i} = scores;
    results.Labels{i} = labels;
endthreshold =0.3;
expectedResults = TestData;**

使用可部署的视频播放器,通过测试数据图像循环显示网络检测。(图片由 Neha Goel 提供)

****第三步:评估精度指标。

我使用evaluateDetectionPrecision函数来计算数据点,以便使用给定的输入参数和阈值绘制精度-召回曲线。

**[ap, recall, precision] = **evaluateDetectionPrecision**(results, expectedResults(:,2:end),threshold);**

绘制每个类的精度指标。

**plot(recall{1,1},precision{1,1},'g-','LineWidth',2, "DisplayName",'greenBuoy');
hold on;
plot(recall{2,1},precision{2,1},'b-','LineWidth',2, "DisplayName",'navGate');
hold on;
plot(recall{3,1},precision{3,1},'r-','LineWidth',2, "DisplayName",'redBuoy');
hold on;
plot(recall{4,1},precision{4,1},'y-','LineWidth',2, "DisplayName",'yellowBuoy');
hold off;xlabel('Recall');
ylabel('Precision');
title(sprintf('Average Precision = %.2f\n', ap)
legend('Location', 'best');
legend('boxoff');**

图片由 Neha Goel 提供

步骤 4 :评估目标检测的缺失率指标。

使用函数evaluateDetectionMissRateI计算结果的对数平均缺失率,与地面数据和数据点进行比较。**

**[am,fppi,missRate] = **evaluateDetectionMissRate**(results, expectedResults(:,2:end),threshold);**

将每个类别的日志未命中率度量标绘为每个图像的误报率。

**loglog(fppi{1,1}, missRate{1,1},'-g','LineWidth',2, "DisplayName",'greenBuoy');
hold on;
loglog(fppi{2,1}, missRate{2,1}, 'b','LineWidth',2,"DisplayName",'navGate');
hold on;
loglog(fppi{3,1}, missRate{3,1},'-r','LineWidth',2, "DisplayName",'redBuoy');
hold on;
loglog(fppi{4,1}, missRate{4,1},'-y','LineWidth',2, "DisplayName",'yellowBuoy');
hold off;xlabel('False Positives Per Image');
ylabel('Log Average Miss Rate');
title(sprintf('Log Average Miss Rate = %.2f\n', am))
legend('Location', 'best');
legend('boxoff');**

图片由 Neha Goel 提供

正如所观察到的,由于不平衡的等级,对于“ navGate ”等级来说,度量更加准确。人们可以使用过采样和欠采样技术来解决类别的不平衡。

结束语

这个故事的主要目的是介绍一种导入 onnx 模型并在 MATLAB 中重新训练定制数据的方法。你可以在这里观看这个故事的视频

作为下一步的一部分,我在 NVIDIA Jetson 上部署了这个网络,并在直播摄像机上检测了对象。要了解整个项目的更多信息,可以查看这个 GitHub 资源库:https://GitHub . com/mathworks-robotics/deep-learning-for-object-detection-yolov 2

Google Colab 上的 YOLOv3 PyTorch

原文:https://towardsdatascience.com/yolov3-pytorch-on-google-colab-c4a79eeecdea?source=collection_archive---------27-----------------------

在浏览器上进行对象检测视频处理

对于计算机视觉爱好者来说, YOLO (你只看一次)是一个非常流行的实时物体检测概念,因为它非常快,性能很好。

在这篇文章中,我将分享处理视频的代码,以获得 Google Colab 中每个对象的边界框

我们不会讨论 YOLO 的概念或架构,因为媒体上已经有很多好文章对此进行了阐述。这里我们只讨论功能码

我们开始吧

照片由瓦希德·赫内Unsplash 上拍摄

你可以试试这个谷歌眼镜。

我们从 Ultralytics 的一个写得很好并且我最喜欢的 git hub repo 开始。尽管回购已经包含如何使用 YOLOv3 处理视频,只是运行python detect.py --source file.mp4我想分解并尝试简化代码,只是删除几个不必要的行,我添加了如何在 Google Colab / Jupyter 笔记本上显示处理后的视频

准备 YoloV3 和 LoadModel

首先克隆 Ultralytics YoloV3 存储库,然后导入公共包和 repo 函数

设置参数解析器,初始化设备(CPU / CUDA),初始化 YOLO 模型,然后加载权重。

我们使用的是YOLOv3-spp-ultralytics权重,回购公司称其在平均精度上远远优于其他 YOLOv3

函数torch_utils.select_device()将自动寻找可用的 GPU,除非输入'cpu'

对象Darknet在 PyTorch 上初始化 YOLOv3 架构,权重需要使用预先训练的权重加载(我们现在不想训练模型)

视频上预测对象检测

接下来,我们将读取视频文件,并用对象边界框重写视频。接下来的 3 GitHub Gist 是最后会用到的函数predict_one_video的一部分。

我们正在用 MP4 格式写新视频,它在vid_writer上明确声明。而fpswidthheight根据原始视频使用

开始循环视频上的每一帧以获得预测。

此型号的图像尺寸为 416。一个名为letterbox的函数正在调整图像的大小,并对图像进行填充,因此宽度或高度中的一个变为 416,另一个小于 416,但仍能被 32 整除

第二部分是我们将图像转换成 RGB 格式,并将通道放入第一维(C,H,W)。将图像数据放入设备(GPU 或 CPU)并将像素从0-255缩放到0-1。在我们将图像放入模型之前,我们使用函数img.unsqeeze(0),因为我们必须将图像重新格式化为 4 维(N,C,H,W),其中 N 是图像的数量,在本例中为 1。

在对图像进行预处理后,我们把它放入模型中得到预测盒。但是预测有很多盒子,所以我们需要non-maximum suppression来过滤和合并盒子。

非最大抑制(NMS)。图像来源

绘制边界框和标签,然后编写视频

我们在 NMS 之后循环所有的预测(pred)来绘制盒子,但是图像已经被调整到 416 像素,我们需要使用函数scale_coords将其缩放回原始大小,然后我们使用函数plot_one_box来绘制盒子

在 Colab 上显示视频

视频在函数predict_one_video上被写成 Mp4 格式,保存为 Mp4 后我们压缩成h264,这样视频就可以直接在 Google Colab / Jupyter 上播放了。

显示原始视频

我们使用宽度为 400 像素的IPython.display.HTML显示视频。使用二进制读取视频

压缩并显示处理过的视频

OpenCV video writer 的输出是一个 Mp4 视频,其大小是原始视频的 3 倍,并且不能使用相同的方式在 Google Colab 上显示,解决方案之一是我们进行压缩(来源

我们使用ffmpeg -i {save_path} -vcodec libx264 {compressed_path}将 Mp4 视频压缩为 h264

结果

左边是原始视频,右边是使用这些代码处理的

试试你自己的视频

到 GitHub 上的 Google Colab 文件这里

  1. 将您的视频上传到input_video文件夹
  2. 只运行最后一个单元格(预测和显示视频)

来源

感谢您的阅读,希望对您有所帮助

接下来的故事:

  • Yolov3 在 Google Colab 上使用网络摄像头
  • Yolov3 训练手检测
  • Yolov3 训练安全帽

干杯!!!

Google Colab 上的 YOLOv3 PyTorch 流媒体

原文:https://towardsdatascience.com/yolov3-pytorch-streaming-on-google-colab-16f4fe72e7b?source=collection_archive---------12-----------------------

使用 Google Colab 在您的浏览器上进行网络摄像头流对象检测

YOLO (你只看一次)在计算机视觉和深度学习方面最大的突破之一是能够实时处理高精度的物体检测。

在非 GPU 计算机上使用 YOLO 完全是一种痛苦,幸运的是谷歌实验室来拯救我们了!!!每台能够打开 Google Chome 浏览器的电脑都足以使用 Google 的免费 GPU(其他浏览器也可以,但推荐使用 Chome)。

Google Colab 里有我之前关于 YOLO 的文章:
YOLOv3 视频处理

我们不会讨论 YOLO 的概念或架构,因为媒体上已经有很多好文章对此进行了阐述。

这里要讨论的:
1。使用 JavaScript 将我们的网络摄像头连接到 Google Colab。使用 YOLO 从网络摄像头上的图像中获取对象检测边界框
3。将预测的边界框放入我们的实时网络摄像头显示

工作流程

我们旅程的结果会是这样的

你可以在这个 Google Colab 中亲身体验

让我们开始行动吧

1.使用 JavaScript 将我们的网络摄像头连接到 Google Colab

在 Google Colab 中连接网络摄像头的功能

基本上有两个函数我们需要用到:start_inputtake_photo

当运行start_input时,我们打开网络摄像头(确保你允许你的浏览器/ Google Colab 打开你的摄像头),然后提供画布来放置网络摄像头捕捉到的一切,并显示给我们的 Google Colab 输出。

我们可以通过改变captureCanvas.widthcaptureCanvas.height来调整画布的大小。

take_photo返回包含要在 YOLO 处理的图像(以字节为单位)的 JavaScript 对象,我们将在下一节看到。

最突出显示的输入take_photo**img_data**,这是一个图像,我们希望覆盖在我们的网络摄像头图像上。在我们的例子中,它是边界框的图像。这将在最后一节讨论。

这是我们如何在 Google Colab 中打开网络摄像头,停止捕捉只需点击输出底部的红色文本。

2.从网络摄像头上的图像中使用 YOLO 获得对象检测边界框

首先,我们必须处理来自take_photo函数的 JavaScript 输出,我们将其命名为js_reply,以获得数组格式的图像。

我们是这样做的,我们把它从一个字节格式解码,然后转换成一个数组。

现在我们有了一个已经符合 YOLO 模型的图像。

其次,我们从 ultralytics 制备 YOLO 回购

上面的代码包含克隆 repo从 ultralytics 加载预训练模型

然后我们从 YOLO 模型中产生边界框,但是这次我们没有直接把它画到输入图像中,而是把边界框画到一个 RGBA 格式的空白画布中。png),所以我们可以得到一个没有背景的包围盒的图像。

画布的结果大概是这样的。没有背景就查一下。

3.将预测的边界框放入我们的实时网络摄像头显示

在我们得到预测结果后,我们需要做的最后一件事就是把结果直接放到我们的网络视频中。

要通过take_photo函数中的img_data参数将其放回我们的 JavaScript 东西’中,我们需要将预测结果转换/编码为字节格式。这是怎么回事:

到目前为止,我们已经有了几个函数,让我们按照使用的顺序再回顾一下:

  1. start_input - >打开网络摄像头并显示网络摄像头
  2. take_photo - >从网络摄像头获取图像并覆盖边框
  3. js_reply_to_image - >将 JS 输出的图像转换成数组
  4. get_drawing_array - >从图像数组中获取预测的包围盒
  5. drawing_array_to_bytes - >将预测包围盒转换成字节

然后,我们重新运行我们的网络摄像头,使用所有这 5 个功能:

这里可以看到,起初img_data是一个空字符串(''),然后在每次迭代中,它将被替换为drawing_bytes。这就是我们的边界框如何出现在 Google Colab 的摄像头输出上方。

来源

谢谢你到目前为止阅读:D

如果你想在 Google Colab 中亲自尝试,请点击链接

希望这篇文章有帮助

干杯!!!

YOLOv3 与 EfficientDet 的最新物体检测

原文:https://towardsdatascience.com/yolov3-versus-efficientdet-for-state-of-the-art-object-detection-2c80f617c76b?source=collection_archive---------26-----------------------

众所周知,YOLOv3 是一个令人难以置信的高性能、最先进的模型架构:快速、准确、可靠。那么,“街区的新成员”EfficientDet 相比如何呢?请注意:我们还在博客上发布了 约洛夫 3 vs EfficientDet

如果没有剧透,我们对这些结果感到惊讶。

我们的范围

在本文中,我们比较了两种最先进的图像检测模型——efficient det 和 YOLOv3 的建模方法、训练时间、模型大小、推理时间和下游性能。这两个模型都是用易于使用的、实用的实现来实现的,任何开发人员都可以部署这些实现。要了解如何训练这些模型,请参见我们关于如何训练 EfficientDet 的教程和关于如何训练 YOLOv3教程。这两个实现都在 PyTorch 中,并导出可以移植到应用程序中进行推理的权重。

  • 对于您的自定义数据集,您只需要更改两行代码,其中您的数据集被导入到 COCO json for EfficientDet 和 yolo v3 Darknet for yolo v3 py torch 实现中。
  • 如果您愿意:直接跳到比较 YOLOv3 和 EfficientDet 的 Colab 笔记本
  • 当我们写这篇文章时,YOLOv4 已经发布,我们将在以后的文章中比较 YOLOv4 和 EfficientDet。

推理在我的笔记本上运行,用于血细胞检测(ED —绿色红细胞,YOLO —黄色红细胞)

免责声明:我们的工作超越了学术同行评议的界限。它旨在快速衡量这些模型在今天的生产计算机视觉环境中部署的可行性,并提供一个可以在 Colab 笔记本上使用的实际实现。在理想的部署条件下,可以更精确地测量诸如推理时间之类的东西,并进行更适当的配置。

EfficientDet 简介

EfficientDet 最近作为图像检测的最新模型而广受欢迎,因为它相对于其他图像检测模型而言既高效又快速。此前, YOLOv3 一直是图像检测的首选型号。

EfficientDet 在速度和准确性方面都很出色(来源)

在用于图像检测的 COCO 数据集上,相对于模型大小,EfficientDet 被示出在对等模型中具有最佳性能。(参见我们之前的帖子全面的分解效率测试。)COCO 包含 80 个对象类,跨越一系列视觉语义,被认为是图像检测任务的黄金标准。这个想法是——如果模型能够掌握 COCO,那么它将很好地推广到新的图像检测任务,只要为新任务提供适量的监督数据。

在这篇文章中,我们对 COCO 概括假设进行了测试,我们发现这两个模型在概括新任务方面都做得很好。我们在识别棋子和识别红/白细胞的任务上测试了这两个模型。我们提供了它们在训练时间、模型大小、推理时间和映射方面的性能比较。

EfficientDet 和 YOLOv3 模型架构

YOLO 做出了最初的贡献,将目标检测问题构建为一个两步问题,将边界框空间分离为一个回归问题,然后将这些边界框标记分类到预期的类别标签中。事实证明,这种方法对于近实时进行图像检测预测非常有效。在随后的迭代中,训练框架、数据集输入和检测规模在 YOLO、YOLOv2 和 YOLOv3 中得到了改进(当我们写这些代码时,YOLOv4 也在写!).

EfficientDet 保留了作为边界框回归和类标签分类的任务框架,但仔细实现了网络的特定区域。首先,对于卷积神经网络主干,EfficientDet 使用 EfficientNet,这是由 Google Brain 团队构建的最先进的 ConvNet。第二,EfficientDet 使用神经架构搜索来准确地找出如何组合 EfficientNet 特征层。第三,EfficientDet 论文研究了如何通过搜索有效地缩放网络的每个部分(ConvNet 的大小、特征融合层数、输入分辨率和类/箱网络)。请点击此处查看我们对 EfficientDet 模型的深入讨论摘要。

评估任务

我们在计算机视觉中识别棋子和计算机视觉中识别红/白血球的背景下评估这两个模型。(两个数据集都在 Roboflow 上公开托管。)象棋数据集包含大约 300 幅图像和 3000 个注释。血细胞数据集包含大约 400 幅图像和 5000 个类别注释。

对于每个模型,数据都以两种格式从 Roboflow 导入(数据上传后),即针对 EfficientDet 的 COCO JSON 和针对 YOLOV3 PyTorch 实现模型的 YOLOv3 Darknet。Roboflow 使得接收这些数据下载链接和输入到模型的 train/val/test 数据目录变得非常容易。这使您可以直接进行培训和研究,而不必担心数据操作和清理。

训练时间对比

为了在国际象棋上训练每个模型,我们通过模型传递数据集 100 个时期。基于验证集的改进,我们选定了 100 个纪元来完成这项任务。我们发现,在我们的实现中,EfficientDet 的训练速度(18.3 分钟)略快于 YOLOv3 (24.5 分钟)。这是有希望的,因为围绕 EfficientDet 的软件库将继续改进,并且这种初始训练时间领先将随着时间的推移而下降。

为了在血细胞上训练每个模型,我们通过模型传递数据集 100 个时期。我们发现 EfficientDet 比 YOLOv3 稍快。

对于您的自定义数据集,历元的数量会有所不同,我们鼓励您寻找最佳点来训练这些模型进行比较。

训练时间结果图表

模型尺寸比较

我们根据权重的文件大小来比较每个模型的大小。鉴于 EfficientDet-D0 包含的参数(400 万)比 yolov 3(6500 万)少得多,我们预计它的文件大小会更小。我们的模型实现以的形式输出经过训练的权重。pth 和。onnx 代表效率检测器。效率检测点。以下是生成的模型文件大小:

模型尺寸结果的图表

为了存储,EfficientDet-D0 真的很小——这是,包括efficient net conv net 主干。

推理时间比较

推理在我的笔记本上运行棋子标记(ED —灰色白棋,YOLO —褐色白棋)

为了度量推理,我们试图缩小到每个实现的确切部分,该部分将网络输入和推理带到网络输出。这有望消除一些关于如何处理图像和保存推断注释的偏见。也就是说,我们再次期望 EfficientDet 实现会随着模型的流行和实现的改进而改进。我们通过推理来传递我们的测试集,并测量每幅图像的推理时间。然后,我们平均推断时间,以创建一个稳定的估计。结果如下:

推理时间结果图

推理时间比我们预期的更接近,但是 EfficientDet 仍然是明显的赢家。同样,我们预计随着实现的改进,这一差距将会扩大。

准确度比较

为了估计模型的可比准确性,我们计算了两个数据集的测试集的地图度量。该图评估模型在所有置信度值上的性能,允许模型随着置信度的降低而在精确度和召回率之间进行权衡。这里我们绘制了象棋和血细胞任务的地图。

这里的要点是,这两个模型在国际象棋上表现都非常出色,YOLOv3 略胜一筹。然而,随着性能在 90%以上,这可能是注释中绘制的边距有多宽的假象。对于血细胞,EfficientDet 略胜 yolov 3——两种模型都很好地完成了任务。

结论🏆

我们发现 EfficientDet 的实际实现在训练时间、模型大小、推理时间和准确性方面在两个自定义图像检测任务上优于 YOLOv3。我们在一个 YOLOv3 与 EfficienDet 笔记本中实现了这些测试,您可以很快将其用于您自己的用例。🚀

Google Colab 上的 YOLOv4:轻松训练你的自定义数据集(交通标志)

原文:https://towardsdatascience.com/yolov4-in-google-colab-train-your-custom-dataset-traffic-signs-with-ease-3243ca91c81d?source=collection_archive---------2-----------------------

使用 YOLOv4 在 Google Colab 上训练您的自定义数据集的有效而简单的方法!

来源图片由汉斯·阿德里安·伯麦在 Unsplash 上提供

用 YOLOv4 检测交通标志

概述

一.导言

前阵子我用 Google Colab 提供的免费 GPU 写了一篇用自定义数据集(枪械检测)训练 YOLOv3 的教程。在发布教程后,许多人发邮件给我,询问他们在培训过程中面临的问题。我注意到的是,这些问题中的大部分来自于修改不适当的层架构、在不正确的目录路径中运行单元或者缺少一个/一些必需的配置步骤。我也意识到设置过程可能需要时间,而且经常会很混乱。

出于这些原因,我提出了一种新的方法,其中大多数设置步骤都是通过 python 脚本自动完成的(Colab 允许您直接在其环境中修改和运行 python 脚本)。有了这个新的程序,你唯一需要在本地执行的事情就是按照 YOLO 格式准备你的自定义数据集,而所有的剩余部分将在 Colab 环境中执行。

二。为什么是 YOLOv4?

YOLOv4 由阿列克谢·博奇科夫斯基(Alexey Bochkovskiy)、钱和廖宏远(Hong-Yuan Mark Liao)开发。它于 2020 年 4 月发布,并被称为当时最先进的实时物体探测器之一。根据其论文,YOLOv4 比 YOLOv3 快 12%,准确 10%。YOLOV4 的新架构以 CSPDarknet54 为骨干构建,提升了 CNN 的学习能力。此外,通用特征的实现包括加权剩余连接(WRC)、跨阶段部分连接(CSP)、跨小批量归一化(CmBN)、自我对抗训练(SAT)和 Mish 激活,帮助 YOLOv4 获得了非常令人印象深刻的结果。想了解更多关于 YOLOv4 的细节,可以参考原文这里。[1]

三。数据集准备

为了能够用 YOLOv4 训练我们的定制数据集,我们的数据集必须遵循 YOLO 格式。数据集中的每幅图像都会与一个相关联。txt 同名文件,其中包含的对象类及其坐标遵循以下语法: <对象类><宽度> <高度>

有很多开源的 GUI 工具可以帮助你轻松地从图像生成标签文件,比如 Yolo_labelOpenLabelingYolo_markBBox-Label-Tool 等。只需简单地拖放你的鼠标来创建一个包围你的对象,然后工具会自动生成标签文件。

带有开放标签的 YOLO 格式图像标签(来源

接下来,你需要创建 3 个文件:classes . namestrain . txttest.txtclasses . names包含以下格式的对象名称:

*object1_name
object2_name
object3_name
...objectn_name*

确保您的 <对象类> 的索引来自标签文件 。txt 是对应于你的类名的索引,例如object 1 _ name,object2_name,object 3 _ name 分别是 0,1,2****

train.txttest.txt 包含您的训练图像和测试图像的文件路径。其思想是将数据集分为训练集和测试集,以便在训练集上训练模型,并在测试集上验证模型。如果你的训练集中的损失很高,这意味着你的模型不适合,你将需要训练更长时间。如果训练集的损失较低,测试集的损失较高,这意味着您的模型过度拟合,您需要添加更多数据。根据数据集中图像的数量,可以从总数据集中提取大约 5%(小数据集)到 30%(大数据集)的验证集。这两个文件的格式语法与data/*相同。*****

在本教程中,我将使用来自 KaggleYOLO 格式的交通标志数据集。您不必现在下载它,因为我们稍后会直接从 Colab 环境下载它。它的一些图像和标签的例子如下所示(注意,一个图像可以有多个对象):

**00058.txt: 3 0.5919117647058824 0.518125 0.027941176470588237 0.05125 00011.txt: 0 0.5477941176470589 0.46 0.03676470588235294 0.075 1 0.5477941176470589 0.379375 0.051470588235294115 0.09625 00334.txt: 0 0.25441176470588234 0.59375 0.033823529411764704 0.0575 0 0.5724264705882353 0.566875 0.027205882352941177 0.04625 00136.txt: 1 0.6150735294117647 0.52375 0.030147058823529412 0.045**

总之,我们将在本教程中使用的交通标志数据集是:

**|- ts/
|   |- 00000.jpg|   |- 00000.txt
|   |- ...
|- classes.names
|- train.txt
|- test.txt**

四。与 Colab 一起培训

对于已经熟悉 Colab 的人来说,你可以直接跳到我的 Colab 笔记本这里开始摆弄它。但是,请确保您通过选择运行时- >更改运行时类型>硬件加速器** > GPU、创建目录yolov 4 _ weight/backup在您的 Google Drivemount Drive with Colab environment**。****

如前所述,我实施了一些修改,帮助培训过程更加简单明了:

  • **assert 函数**:检查您是否在正确的目录路径下运行单元格的函数。如果你在错误的目录,它会提示你应该在哪个目录。如果你不知道如何改变目录,请参考 Linux 终端 中的这个 cd 命令。
  • ****darknet _ for _ colab:darknet 文件夹,专门修改以适应 Colab 环境(不需要修改 MAKEFILE)。
  • yolov4_config.py :利用 Colab 上的直接 python 编辑特性,您现在只需双击 yolov4_config.py 并编辑它即可定义训练参数(图 1 )。比如我会设置我的类=4 (我们的交通标志数据集有 4 个类) max_batches=8000 (训练迭代次数) batch=64 (一批样本数) subdivisions=16 (一批 mini_batches 数)等。你可以参考本页找到更多关于每个参数含义的细节。**

图 1:在 yolov4_config.py 中编辑 YOLOv4 架构及其训练参数

  • yolov4 _ setup . py(cell[6]):一个 python 脚本,它根据 yolov4_config.py. 中用户输入的参数自动生成 yolo v4 架构配置文件(yolo v4 _ custom _ train . CFGyolo v4 _ custom _ test . CFG)

下面的笔记本演示了 Colab 上 YOLOv4 培训程序的流程。我会推荐你看一下我的 Colab 笔记本看看你应该期待的每个电池的输出是什么样的。

虽然我确实定义了我的 max_batches=8000 ,但是在 2000 次迭代之后,精度和训练结果的损失都没有太大的改善(图 2 )。如果使用更多的类或更难学习的数据集进行训练,迭代次数可能会增加。确保您通过双击文件【chart.png】来监控损失和准确性,或者只是简单地查看来自输出单元的训练统计。

图 2:2000 次迭代后的训练结果

动词 (verb 的缩写)用 YOLOv4 预测

获得训练权重后,有几种方法可以用第三方框架部署 YOLOv4,包括 OpenCVKerasPytorch 等。然而,这些超出了本教程的范围。您可以使用用于训练过程的相同 Colab 工作空间来预测图像或视频(图 3 和图 4 )。单元格 13 和 15** 分别为您提供了预测图像和视频的明确方法。默认情况下,预测图像保存在predictions.jpg,而预测视频将保存在output.mp4。**

图 3:用 YOLOv4 预测图像

用 YOLOv4 预测视频流中的交通标志

不及物动词结论

本教程介绍了一种新的方法,允许您在 Google Colab 上使用 YOLOv4 轻松训练您的自定义数据集。所有与神经网络架构和训练参数相关的修改都是自动化的,可以在 Colab 环境中执行,同时集成单元测试以调试常见的编译错误。****

然而,我想指出的是,使用自动化工具是有代价的。事实上,你不知道背后发生了什么可能会令人不安,尤其是那些想对 YOLOv4 架构有更好的直觉的人。既然如此,你可以参考 YOLOv4 的原 GitHub 资源库或者阅读我在 Colab 上训练 YOLOv3 的文章。

资源

在 Colab 笔记本上训练 yolov 4

colab 知识库的暗网

交通标志检测的 YOLOv4 权重(2000 次迭代)

YOLO 格式的交通标志数据集

参考

[1] Bochkovskiy,Alexey,钱,和廖宏远." YOLOv4:物体探测的最佳速度和精确度."arXiv 预印本 arXiv:2004.10934 (2020)。

YOLOv4 —打造更好模型的十大策略

原文:https://towardsdatascience.com/yolov4-ten-tactics-to-build-a-better-model-4c46869626a6?source=collection_archive---------15-----------------------

用这些建议改善你的 YOLOv4 训练流程——请注意:我们也在我们的博客上发布了 YOLOv4 战术

(引用

YOLO v4 模型是目前用于训练定制对象检测器的最佳架构之一,并且暗网库的能力是巨大的。在本帖中,我们讨论并实现了 YOLO v4 中的十个高级策略,这样你就可以从你的自定义数据集构建最佳的对象检测模型。

注意:此讨论假设您已经培训过 YOLO v4。首先,查看我们的培训指南 YOLOv4 。这里的高级战术将建立在基础训练流程的基础上。

YOLO v4 高级战术路线图:

  • 收集更多数据
  • 图像预处理和增强
  • 图像输入分辨率大小
  • 何时使用预训练砝码
  • 选择模型大小和架构
  • 从之前的训练中吸取经验
  • 训练后选择最佳模型
  • 跟踪您的模型评估
  • 导出您的模型
  • 优化推理时间

本教程中的资源:

1)收集更多数据

改进对象检测模型的最佳方式是收集更多的代表性数据,YOLO v4 也不能逃避这一事实。正如特斯拉的人工智能高级总监 Andrej Karpathy 在解释特斯拉如何教汽车停止时所说:

“你的数据集是活的,你的标注说明一直在变。你需要一直管理和改变你的数据集。”

2) YOLOv4 图像预处理和增强

收集和标注更多数据的成本很高。幸运的是,有一些自动的方法可以通过增强来改善你的训练集的范围和规模。YOLO v4 培训管道会自动进行增强(参见这篇关于 YOLO v4 中数据增强的文章),但是您可能需要考虑在 Roboflow 中添加额外的增强。

图像预处理也是另一个重要的步骤,以确保您的图像是正确的图像分辨率大小,并且您已经标准化了一些方面,如类本体灰度对比度

要做出的最重要的预处理决定是图像输入分辨率。

3) YOLOv4 输入分辨率大小

输入分辨率决定了将传递到模型中进行学习和预测的像素数。大像素分辨率提高了准确性,但代价是训练和推理时间变慢。较大的像素分辨率可以帮助您的模型检测小对象。

YOLO 模型的像素分辨率必须是 32 的倍数。可供选择的标准分辨率尺寸为 416x416。

如果在 Roboflow 中管理数据集,可以通过调整大小预处理步骤选择数据集输入分辨率大小。

robof flow中调整图像大小

重要提示:为了确保您的输入分辨率大小能够传递到您的 YOLOv4 模型,您必须调整模型配置文件。在cfg文件夹中你指定你的型号配置,在这里修改widthheight

[net] batch=64 subdivisions=8 # Training #width=512 #height=512 width=608 height=608 channels=3 momentum=0.949 decay=0.0005 angle=0 saturation = 1.5 exposure = 1.5 hue=.1

在 YOLOv4 模型 cfg 文件中更改宽度和高度

[net] 
batch=64 
subdivisions=8 
*# Training* 
*#width=512* 
*#height=512* 
width=608 
height=608 
channels=3 
momentum=0.949 
decay=0.0005 
angle=0 
saturation = 1.5 
exposure = 1.5 
hue=.1

4)何时使用预训练的 YOLOv4 砝码

要开始在 YOLOv4 上训练,我们通常会下载预训练的重量:

!wget [https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.conv.137](https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.conv.137)

并且在训练期间从这个预先训练的检查点开始:

!./darknet detector train data/obj.data cfg/custom-yolov4-detector.cfg yolov4.conv.137 -dont_show -map

这些权重已经在 COCO 数据集上进行了预训练,该数据集包括人、自行车和汽车等常见对象。一般来说,从预训练的重量开始是一个好主意,特别是如果你认为你的物体与 COCO 中的物体相似。

但是,如果你的任务明显比 COCO 困难(航拍、文档等。),你可能会从零开始训练中受益。

!./darknet detector train data/obj.data cfg/custom-yolov4-detector.cfg -dont_show -map

当然,对两者都进行实验总是有利的,并且根据经验来看哪一个最适合你的模型。

5)选择模型大小和架构

YOLOv4 有两种口味 YOLOv4YOLOv4-tiny

不同型号性能和推理速度对比(yolov 4-tiny发布)

如果推理速度是你的最终目标,较小的模型可能会感兴趣。通过改进数据集,可能会降低精确度。

从 YOLOv4 转 YOLOv4-tiny 是车型配置的问题。您可以尝试中间配置来构建一个定制的 YOLO 模型。为此,查看cfg文件夹,尝试改变网络架构和层。如果你的对象形状与 COCO 数据集有很大不同,你可以考虑实现自定义锚框。这是非常高级的战术!

[yolo] 
mask = 0,1,2 
anchors = 12, 16, 19, 36, 40, 28, 36, 75, 76, 55, 72, 146, 142
classes=80 
num=9 
jitter=.3 
ignore_thresh = .7 
truth_thresh = 1 
scale_x_y = 1.2 
iou_thresh=0.213 
cls_normalizer=1.0 
iou_normalizer=0.07 
iou_loss=ciou 
nms_kind=greedynms 
beta_nms=0.6 
max_delta=5

6)从之前的 YOLOv4 训练中恢复

在 Darknet 框架中训练您的 YOLOv4 模型可能需要一段时间。定期保存模型非常重要。您可以通过调用之前训练跑步重量的训练来恢复训练,如下所示:

!./darknet detector train data/obj.data cfg/custom-yolov4-detector.cfg [YOUR WEIGHTS HERE] -dont_show -map

确保权重是用相同的配置文件训练的,并且是在相同版本的 Darknet 框架下训练的!

就像预训练的权重一样,您可以从以前的训练中学习,并将您的模型从其他数据集中获得的知识应用到新的数据集中。

7)训练后选择最佳的 YOLOv4 模型

暗网模型权重保存在backup文件夹中,每 1000 次迭代自动保存。Darknet 会自动为你保存最好的型号,扩展名为 _ *best.weights* 。这是基于您的验证集的性能。 Darknet 还会用扩展功能_last.weights保存你训练跑步的最后重量。

8)跟踪您的 YOLOv4 型号评估

当您在数据集和 YOLOv4 建模中进行各种调整时,跟踪您的结果会很有用,这样您就可以看到哪种技术组合最适合您的数据集。

Darknet 将输出一个平均精度分数,这是在您决定哪个模型最适合您的数据时要跟踪的主要指标。另一个需要考虑的重要指标是推理的速度。

9)导出您的 YOLOv4 模型

一旦你有了一个训练好的模型,它将会是暗网.weights格式。您可能希望将其转换为新的格式进行部署。

YOLOv4 Darknet 型号转换指南:

10)优化 YOLOv4 推理时间

加快你的模型推断时间的首要方法是使用 YOLOv4-tiny 这样的小一点的模型。通过硬件选择,如 GPU 或使用 VPU 上的 OpenVino 进行推断,可以进一步提高推断时间。对于 GPU 推断,建议用yolov 4 tensort 框架部署。

结论

恭喜你!现在,您有十种新的高级策略来最大限度地利用 YOLO v4 来创建对象检测器,从而为您的自定义数据集建模。

一如既往,快乐训练。

原载于 2020 年 11 月 13 日 https://blog.roboflow.com

YOLOv5 与更快的 RCNN 相比。谁赢了?

原文:https://towardsdatascience.com/yolov5-compared-to-faster-rcnn-who-wins-a771cd6c9fb4?source=collection_archive---------2-----------------------

用数据做很酷的事情!

介绍

深度学习社区正在热烈讨论 YOLO v5。这篇博客最近介绍了 YOLOv5 以 140 FPS 的速度进行最先进的物体检测。这立即引起了黑客新闻、Reddit 甚至 Github 的广泛讨论,但不是因为它的推理速度。两个突出的问题是——该模型是否应该被称为 YOLO,以及速度基准测试结果是否准确和可重复。如果你对 Roboflow 的回答感兴趣,你可以在这里找到。

抛开所有争议不谈,YOLOv5 看起来是一款很有前途的车型。因此,我将其与最好的两级检测器之一——更快的 RCNN 进行了比较。为了进行这种比较,我从不同的背景下拍摄了 3 个视频,并并排运行了 2 个模型。我的评估包括对结果质量和推理速度的观察。所以让我们开始吧!

YOLOv5 型号

YOLOv5 的实现是在 Pytorch 中完成的,这与以前使用 DarkNet 框架的开发形成了对比。这使得理解、培训和部署该模型变得更加容易。没有与 YOLO-v5 一起发布的文件。我的理解是,在建筑上它与 YOLO-v4 非常相似。一个不同之处可能是使用跨级局部网络(CSP) 来降低计算成本。目前还不清楚 YOLO-v5 是否比 YOLO-v4 运行得更快,但是我更喜欢 Pytorch 的实现,我很惊讶用这个模型训练是如此的容易。我个人的推理经历也是天衣无缝的。

此次发布的 YOLOv5 包括五种不同型号尺寸:YOLOv5s(最小)、YOLOv5m、YOLOv5l、YOLOv5x(最大)。这些模型的推理速度和平均精度(mAP)如下:

来自 UltraLytics 回购的 YOLO v5 统计数据

使用 YOLO-v5 进行推理

第一步是克隆 YOLO V5 的回购协议。安装所有要求。我使用 Pytorch 1.5,代码运行没有任何问题。

您可以使用以下工具下载不同预训练 COCO 型号的所有重量:

bash weights/download_weights.sh

要在视频上运行推理,您必须传递视频的路径和您想要使用的模型的权重。如果没有设置 weights 参数,那么默认情况下代码在 YOLO 小型模型上运行。我使用的示例参数如下:

python detect.py --source video/MOT20-01-raw-cut1.mp4 --output video_out/ --weights weights/yolov5s.pt --conf-thres 0.4

输出视频将保存在输出文件夹中

使用 YOLO-v5 进行培训

我个人还没有在自定义数据集上尝试使用 YOLO-v5 进行训练,但 Roboflow 在 Youtube 上分享了一个很好的分步指南这里

快速 RCNN 模型

对于更快的 RCNN 模型,我使用了来自 Tensorflow 对象检测的预训练模型。tensor flow Object Detection shares COCO 针对各种主干预训练了更快的 RCNN。对于这个博客,我使用了 Fatser RCNN ResNet 50 主干。这个报告分享了一个很好的教程,关于如何使用他们的预训练模型进行推理。

YOLOv5 模型与快速 RCNN 的比较

考虑到对自动驾驶汽车行业的重要性,我选择的第一个场景是街道驾驶场景。这两个模型的结果分享如下:

基于驾驶视频评估的 YOLOv5 车型

在驾驶视频上评估更快的 RCNN

YOLO 模型似乎更擅长检测较小的物体——在这种情况下是交通灯,并且还能够在汽车距离较远时(即较小时)检测到汽车。

YOLO v5 small 的运行速度(端到端包括读取视频、运行模型和将结果保存到文件)— 52.8 FPS!

运行速度更快的 RCNN ResNet 50(端到端,包括读取视频、运行模型和将结果保存到文件)—21.7 FPS

这些结果是在 NVIDIA 1080 Ti 上评估的。

到目前为止,YOLO v5 似乎比更快的 RCNN 好

YOLO v5 和更快的 RCNN 比较 1

下一个视频是 youtube 上的一个篮球比赛视频。两种模型的结果如下:

篮球视频上的 YOLO v5

篮球视频上更快的 RCNN ResNet 50

更快的 RCNN 模型是在 60%的阈值下运行的,有人可能会说它是在用一个人的标签来吸引人群,但我更喜欢 YOLO 的结果。两种型号在 abc 徽标上都有假阳性。

我还感到失望的是,尽管运动球在 COCO 中是一个类别,但两者都未能检测到篮球。他们现在的记录是:

YOLO v5 和更快的 RCNN 比较 2

对于最终的视频,我从 MOT 数据集中选择了一个室内拥挤的场景。这是一个具有挑战性的视频,光线较弱,距离较远,人群密集。两个模型的结果如下所示。

YOLO v5 模型在 MOT 数据集的室内拥挤场景上进行测试

基于 MOT 数据集的室内拥挤场景快速 RCNN 模型测试

这很有意思。我想说,这两种模型都很难检测到远处走进走廊的人。这可能是因为光线不足和物体较小。当人群靠近摄像机时,两者都能捕捉到重叠的人群。

YOLO v5 和更快的 RCNN 比较 2

结论

两种车型的最终对比表明,YOLO v5 在运行速度上具有明显的优势。小 YOLO v5 模型运行速度快 2.5 倍,同时在检测更小的物体方面管理更好的性能。结果也更清晰,几乎没有重叠框。 Ultralytics 在他们的 YOLO v5 开源模型上做得非常出色,该模型易于训练和运行推理。

这篇博客还展示了计算机视觉物体检测向更快更准确的模型发展的新趋势。

如果你尝试过 YOLOv5,请在下面的评论中分享你的体验。

深度学习分析,我们非常热衷于使用机器学习来解决现实世界的问题。我们已经帮助许多企业部署了创新的基于人工智能的解决方案。如果您看到合作的机会,请通过我们的网站这里联系我们。

参考

  • YOLO v5
  • 更快的 RCNN
  • YOLO v4

如果你问这个问题,你是在告诉别人你是一个 Python 初学者。

原文:https://towardsdatascience.com/you-are-telling-people-that-you-are-a-python-beginner-if-you-ask-this-question-fe35514ca091?source=collection_archive---------1-----------------------

几天前我在 Reddit 上浏览“learnpython”的 sub 时,看到一个 Redditor 又问了这个问题。虽然网上有太多关于这个问题的回答和解释,但是很多初学者还是不了解,犯错误。这是一个问题

“= =”和“是”有什么区别?

Rohit 农民Unsplash 上拍摄的照片

”和“is”都是 Python 中的操作符(链接到 Python 中的操作符页面)。对于初学者来说,他们可能会把“a == b”解释为“a 等于 b”,“a 是 b”解释为,嗯,“a 是 b”。大概这就是新手在 Python 中混淆“”和“是”的原因吧。

我想在深入讨论之前先展示一些使用“==”和“是”的例子。

>>> a = 5
>>> b = 5
>>> a == b
True
>>> a is b
True

简单吧?a == ba is b都返回True。然后再看下一个例子。

>>> a = 1000
>>> b = 1000
>>> a == b
True
>>> a is b
False

WTF?!?从第一个例子到第二个例子的唯一变化是 a 和 b 的值从 5 到 1000。但是“==”和“是”之间的结果已经不同了。去下一个。

>>> a = []
>>> b = []
>>> a == b
True
>>> a is b
False

这里是最后一个例子,如果你仍然没有被击垮的话。

>>> a = 1000
>>> b = 1000
>>> a == b
True
>>> a is b
False
>>> a = b 
>>> a == b
True
>>> a is b
True

”的官方运算是相等,而“是”的运算是相同。您使用“”来比较两个对象的值。“a == b”应该解释为“a 的值是否等于 b 的值”。在上面的所有例子中,a 的值总是等于 b 的值(即使对于空列表例子)。因此“a == b”总是正确的。

在解释身份之前,我需要先介绍一下id函数。你可以用id功能得到一个物体的身份。这种身份是唯一的,并且在整个时间内都是不变的。你可以认为这是这个对象的地址。如果两个对象具有相同的标识,它们的值也必须相同。

>>> id(a)
2047616

运算符“是”是比较两个对象的身份是否相同。“a 是 b”是指“a 的身份与 b 的身份相同”。

一旦你知道了“==”和“是”的实际含义,我们就可以开始深入上面的例子了。

首先是第一个和第二个例子的不同结果。显示不同结果的原因是 Python 存储了一个从-5 到 256 的整数数组列表,每个整数都有一个固定的标识。当你在这个范围内给一个整型变量赋值时,Python 会把这个变量的标识赋值为数组列表中整型变量的标识。结果,对于第一个例子,由于 a 和 b 的身份都是从数组列表中获得的,所以它们的身份当然是相同的,因此a is b为真。

>>> a = 5
>>> id(a)
1450375152
>>> b = 5
>>> id(b)
1450375152

但是一旦这个变量的值落在这个范围之外,由于 Python 内部没有具有该值的对象,因此 Python 将为这个变量创建一个新的标识,并将该值赋给这个变量。如前所述,每个创造物的身份都是独一无二的,因此即使两个变量的值相同,它们的身份也不会相等。这就是为什么第二个例子中的a is b是假的

>>> a = 1000
>>> id(a)
12728608
>>> b = 1000
>>> id(b)
13620208

(额外:如果你打开两个控制台,如果值仍然在范围内,你会得到相同的身份。但是当然,如果该值落在范围之外,情况就不是这样了。)

一旦你理解了第一个和第二个例子之间的区别,就很容易理解第三个例子的结果。因为 Python 不存储“空列表”对象,所以 Python 创建了一个新对象并赋予值“空列表”。无论两个列表是空的还是有相同的元素,结果都是一样的。

>>> a = [1,10,100,1000]
>>> b = [1,10,100,1000]
>>> a == b 
True
>>> a is b
False
>>> id(a)
12578024
>>> id(b)
12578056

最后,我们来看最后一个例子。第二个和最后一个例子的唯一区别是多了一行代码a = b。然而这一行代码改变了变量a的命运。下面的结果告诉你为什么。

>>> a = 1000
>>> b = 2000
>>> id(a)
2047616
>>> id(b)
5034992
>>> a = b
>>> id(a)
5034992
>>> id(b)
5034992
>>> a
2000
>>> b
2000

如你所见,a = b之后,a的身份变成了b的身份。a = bb的身份分配给a。因此ab具有相同的身份,因此a的值现在与b的值相同,都是 2000。

最后一个例子告诉你一个重要的信息,你可能会不经意地改变一个对象的值,特别是当这个对象是一个列表的时候。

>>> a = [1,2,3]
>>> id(a)
5237992
>>> b = a
>>> id(b)
5237992
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]

从上面的例子来看,因为ab都有相同的标识,所以它们的值必须相同。因此在将新元素添加到a之后,b的值也将受到影响。为了防止这种情况,如果您想将值从一个对象复制到另一个对象,而不引用相同的标识,那么一劳永逸的方法是使用模块copy ( 链接到 Python 文档)中的deepcopy。对于列表,也可以通过b = a[:]来执行。

>>> import copy
>>> a = [1,2,3]
>>> b= copy.deepcopy(a)
>>> id(a)
39785256
>>> id(b)
5237992

使用[:]将元素复制到一个新变量

>>> a = [1,2,3]
>>> id(a)
39785256
>>> b = a[:]
>>> id(b)
23850216
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3]

我希望现在你能明白这两者之间的区别,你不会因为问这个问题而再次成为初学者。

你年轻健康:你应该担心心血管疾病吗?

原文:https://towardsdatascience.com/you-are-young-and-healthy-should-you-worry-about-cardiovascular-disease-cd8764382d50?source=collection_archive---------58-----------------------

简介

Y 你可能知道你身边的人死于心脏病。但是这种疾病只发生在老年人和油炸食品爱好者身上——这可能是你的想法。

我直到中年才需要检查胆固醇。我还太年轻,不用担心心脏病。正是我在做这个项目之前所想的。

照片由 igorstevanovicShutterstock 拍摄

该项目包括对年龄从 29 岁到 65 岁的 70,000 名患者的病历数据集(来源: Kaggle )的分析。所有数据集值都是在体检时收集的。每个记录具有 11 个特征,包括客观特征(如年龄、体重、身高)、检查特征(如胆固醇、血糖、血压)和主观特征(患者是否进行体力活动)。

我进行这个项目的动机是想看看我对自己的心脏健康到底了解多少,并验证通常的假设,尤其是那些关于年轻人和健康人免受疾病风险的假设。

1。关于心血管疾病风险,检查特征(如胆固醇和葡萄糖)能告诉我们什么?

胆固醇水平分为 3 级:1 级—正常,2 级—高于正常,3 级—远高于正常。

我们确实认为血液中胆固醇含量越高,患病风险就越高。

但是这是如何量化的,与心血管疾病的确切关系是什么?

70 000 名患者的记录数据集显示,心血管疾病的风险随着胆固醇水平的升高而显著增加,无论我们的年龄如何,这都是事实。

在下图中,按年龄范围划分的患病人口比例用红色条表示。

图 1:不同胆固醇水平下患病(红色)和非患病(蓝色)的比例

值得注意的是,如果胆固醇水平超过正常阈值,年轻人患这种疾病的风险是正常人的两倍。即使胆固醇水平最低,也有 25%的人受到影响。

此外,同样的胆固醇水平使老年人更容易患心血管疾病。

至于血糖水平,趋势略有不同,如下图所示。葡萄糖分为 3 类:1-正常,2-高于正常,3-远高于正常。

图 2:不同胆固醇水平下患病(红色)和非患病(蓝色)的比例

当血糖水平从正常升至高于正常时,我们观察到患病风险显著增加。然而,如果达到最高的葡萄糖水平,这就不再正确,特别是在最年轻的时候,趋势往往是相反的方向——这真的令人惊讶。

在这一部分中,更有趣的是找出具有最小心血管疾病风险的最佳量化胆固醇和葡萄糖水平。遗憾的是,所提供的数据集中没有这些信息。

2。血压正常的人没有心血管风险吗?

高血压是最常见的心血管风险因素。但是,血压正常的人应该被警告有患病的风险吗?

关于血压需要知道的几件事:血压记录在两个数字下,例如:120/80 毫米汞柱。

  • 第一个数字是收缩压,它表示心脏跳动时血液对动脉壁施加的压力。
  • 第二个数字是舒张压,它表示心脏在两次跳动之间休息时,血液对动脉壁施加的压力。

低于 120/80 毫米汞柱的血压值被认为在正常范围内。

下图显示了正常血压(低于 120/80 毫米汞柱)患者中患病(橙色柱)和非患病(绿色柱)的比例,按不同的年龄范围分类。两个比例之和为 1。

图 3:血压正常的人是否没有风险?

从这个数字中我们可以注意到的第一件事是,在每个年龄段,大多数人都是健康的——这是个好消息。

接下来是坏消息:健康人的比例没有保持不变,而是随着年龄的增长而下降,尽管他们的血压正常。

即使是最年轻的人也不能完全避免心血管疾病的风险,因为他们中有 15%的人被诊断患有疾病。当人们在 55 岁到 65 岁之间时,这种风险会高三倍(45%)。

3。患心血管疾病风险最低的身高比的正确体重是多少?

我们确实听说了很多关于身体质量指数(身体质量指数),一个将体重与身高联系起来的关键指数,以及如何保持健康的身体质量指数。

我想知道关于避免心血管风险的最佳身体质量指数范围的数据是什么。具体来说,身体质量指数用于根据数值范围将一个人分类为体重不足、正常体重、超重或肥胖。

  • 正常体重总是有帮助吗?
  • 超重总是不好吗?
  • 体重过轻有助于预防心血管疾病吗?

这些是我想回答的问题。

下图显示了不同年龄范围和身体质量指数类别的非患病人群与患病人群的比例差异。

在特定的身体质量指数范围内,每当患病人数少于患病人数时,就会显示绿色条,而红色条则显示相反的情况。

图 4:什么是正确的身体质量指数?

看来体重不足真的很突出!它总是位列身体质量指数最佳类别的前 2 名。然而,随着年龄的增长,它的积极影响变得不那么重要。

请注意,虽然健康的体重似乎对年轻人和中年人有帮助,但对最年长的人来说就不再是这样了。

超重总是不好吗?不完全是。如果你还年轻,你仍然有机会避免心血管疾病的风险。相反,如果你在 55 岁到 65 岁之间,你应该多注意你的体重。

你可能想知道你的身体质量指数范围是什么?看看这个美国卫生部人类服务部的计算器。

[## 计算你的身体质量指数标准身体质量指数计算器

标准体重指数计算器。

www.nhlbi.nih.gov](https://www.nhlbi.nih.gov/health/educational/lose_wt/BMI/bmicalc.htm)

4。体育活动对超重人群预防心血管疾病风险有帮助吗?

从上面我们可以看出,超重的人应该比正常和体重不足的人多加小心。如果他们练习体育,事情会改变吗?

在这一部分,我将深入探讨身体活动对超重和肥胖人群心血管风险的影响。

在所提供的数据集中,有 62%的超重和肥胖者,其中 82%进行体育锻炼。

下图显示了非患病人群和患病人群在运动时(绿条)和不运动时(红条)的比例差异,按身体质量指数分类,范围从超重到非常严重的肥胖。

图 5:运动对超重的人有帮助吗?

图表中几乎所有的柱状图都是负数,这意味着超重和肥胖的人更容易患心血管疾病。

请注意,无论如何,如果患者进行体育锻炼,患病的几率会降低,在每个身体质量指数类别中,看到红色和绿色条之间的差异。

在活跃人群中(用绿色条表示),如果重度肥胖和中度肥胖设法将他们的身体质量指数降低一个范围,他们易受攻击的风险就会显著降低。

结论

我们快速浏览了心血管疾病风险如何随不同因素而变化,包括检查因素(如胆固醇、葡萄糖、血压)、客观因素(身体质量指数)和主观因素(身体活动)。我们看到:

  • 心血管疾病风险随着年龄增长,而其他因素保持不变。
  • 没有高血压,人们无论如何都应该关心心血管风险,因为没有人能完全避免高血压,即使是最年轻的人。
  • 瘦人比超重的有更多机会避免心血管疾病。
  • 运动确实有助于超重的人,尤其是如果他们成功降低了身体质量指数。

你觉得怎么样?

至于我,我认为像我以前那样依赖假设对我的健康是危险的。最好开始锻炼。

照片由 brucemarsUnsplash 上拍摄

这篇博文无意让你担心自己的健康。它只是提出了一种数据驱动的方法,以更好地了解这种非常常见的疾病,并与您分享一些有用的见解。

值得注意的是,根据世界卫生组织(世卫组织)的数据,心血管疾病是全球头号死亡原因,每年夺走 1790 万条生命。

关于您的医疗保健的任何决定,请咨询您的医生。

这里只介绍关键的发现。要了解更多细节,请查看我的 GitHub 回购

编者注: 迈向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家,这篇文章的观点不应被解释为专业建议。

你可以用 SQL 在熊猫里做任何事情

原文:https://towardsdatascience.com/you-can-do-everything-in-pandas-with-sql-354adb30fbf9?source=collection_archive---------8-----------------------

来源: Unsplash

有时候,你应该

Pandas 是数据科学家可以使用的最有用的工具之一。它提供了几个方便的功能来提取信息。不幸的是,使用 Pandas 需要将数据加载到 DataFrames 中,这对于处理大量数据来说不是很好——大量数据在一家需要这种数据操作技能的公司中很常见。

如果您要下载一个完整的大规模数据集(可能将其存储为. csv 文件),您至少需要花几分钟时间等待文件完成下载并被 Pandas 转换为数据帧。最重要的是,您执行的任何操作都将很慢,因为 Pandas 在处理这些海量数据时有困难,需要遍历每一行。

更好的解决方案?首先用 SQL 查询数据库——它可能运行的本地高效处理语言——然后下载一个精简的数据集,如果必要的话,使用 Pandas 来操作它设计用来处理的较小规模的表。虽然 SQL 对大型数据库非常有效,但它不能取代 Panda 与其他库和 Python 语言的绘图集成的价值。

然而,在我们只需要找到数字答案的情况下,比如一件物品的平均成本,或者有多少员工收到佣金,但时薪不超过 40 美元,那么(通常)根本不需要接触熊猫和 Python 环境。

虽然大多数人对 SQL 的了解只停留在SELECT * FROM table WHERE id = ‘Bob’阶段,但是人们会对 SQL 提供的功能感到惊讶。

作为一个例子,我们将使用由 w3schools 提供的 SQL Tryit 编辑器数据库。这个网站允许你在一个虚构的数据库上运行 SQL 查询。Customers 表(您可以在右侧面板中看到完整的表列表)包含 7 列数字和文本数据:

假设我们想要以“姓名居住在地址,城市”的形式发送一个准备好的声明。这很简单:双管操作符||充当连接。然后,我们可以添加列值和字符串,并使用AS将结果保存在别名或结果的列名下。

注意,由于我们额外指定了Country=’Mexico’,我们的结果是墨西哥境内的所有地址和城市。这种类型的操作在 Python 中会更加困难,也不太容易实现。

请注意,并非所有数据库都支持相同的语法。本文使用 PostgreSQL 的语法,尽管讨论的每个操作都有 DB2、Oracle、MySQL 和 SQL Server 数据库中的操作,有时使用相同的语法,有时使用不同的语法。StackOverflow 或者 Google 可以帮你找到这些数据库特有的关键词。

假设在Products表中,我们想将产品分成三个价格区间:CheapRegularExpensive,分别表示价格低于 12 美元、介于 12 美元和 21 美元之间以及高于 21 美元。

没问题!关键词CASE会有所帮助。这个关键字的作用类似于 Python 等其他语言中的 if/else if/else 语句。

CASE关键字使用语法WHEN condition THEN value。当多个WHEN堆叠在一起时,它们会呈现“else-if”关系。最后,如果条件不满足,可以添加一个ELSE value。最后,编写END来表示CASE语句的结束,结果通过AS Bucket保存(别名)到一个名为 Bucket 的列。

这也可以用速度慢得多的.apply()在熊猫身上实现。

假设我们想从Products中随机抽取 5 行。虽然没有直接的方法可以做到这一点,但是我们可以通过使用ORDER BYLIMIT关键字来获得创造性。ORDER BY按一定格式对数据进行排序;例如,使用ORDER BY Price ASC将对数据进行排序,使价格以升序排列。使用DESC使用降序,而ORDER BY通过按字母顺序排序来处理字符串。

ORDER BY random()对数据随机排序,LIMIT x返回所选数据子集中的前 x 行。这样,从数据中随机选择五行(*表示所有列)。

注意:不幸的是,SQL Tryit 编辑器不支持 random(),但是真实的数据库支持(或者使用一个变体,比如rand())。

就像这个随机采样的任务一样,大多数 SQL 都是将几个简单的命令(如SELECT等)链接在一起,并将它们与内置函数集成在一起,以产生惊人复杂的结果。

此外,SQL 提供了您可能需要的所有统计函数。从MIN()MAX()COUNT()SUM()AVG()ASIN()(反正弦),一切就绪。您可以使用标准偏差等度量标准的包扩展,或者使用现有的默认函数自己创建它们,这一点也不难做到。

这些都是标准任务——但更令人惊奇的是,SQL 是一种图灵完全语言。简单地说,你可以用 Python 或 C++,用 SQL 来表示一个程序,通过建立你自己的复杂的内存系统和使用 SQL 的元素,比如函数,if/else,递归等等。您可以查看一些有趣的图灵完全 SQL here演示。这样做的主要目的不是鼓励您将 SQL 作为一种操作性语言来使用,而是为了证明 SQL 可以做比您想象的更多的事情。

在 SQL 中,我们还可以做很多我们没有讨论过的事情:

  • 指定您自己的自定义函数,就像您在 Python 或 C++中声明函数一样。例如,这些可以用于解析 IP 地址。
  • 使用递归创建复杂的循环和带有WITH关键字的数据生成。
  • 按子串对字符串列进行排序。
  • 在多个表之间执行复杂的连接。
  • 使用 SQL 生成 SQL(自动化任务)。
  • 使用统计模型生成预测。
  • 创建直方图。
  • 构建树形结构(包括叶、分支、根节点)。

的确,使用 SQL 可以比使用 Pandas 做更多的事情。也就是说,通常额外的功能是不必要的。您应该使用 SQL 的主要原因是,它是为处理自定义环境中的大量数据而构建的,而数据帧不是。

一般来说,SQL 是一种简单但有时非常混乱的语言,它通常应该用于减少数据的大小,直到它在 Pandas 的较小环境中变得更易于管理。

要点

  • 熊猫不擅长处理大数据,它的功能都可以用 SQL 来完成。然而,Pandas 的价值来自于它与其他绘图库、机器学习库和 Python 语言的集成。
  • 目标通常应该是使用 SQL 将大型数据集缩小到与任务更相关的数据集,然后在 Python 环境中处理它,使用 Pandas 的数据帧作为存储的基础。
  • 不要害怕接触 SQL 来处理大数据问题。如上所述,SQL 的语法很简单,几乎就是将简单的命令链接在一起以产生更复杂的结果。如果你对结果有一个清晰的愿景,你可以用 SQL 实现它。
  • SQL 能做的比大多数人意识到的要多得多。

[## 面向数据科学家的 SQL,在 6 分钟或更短时间内完成

任何数据科学简历的必备技能

medium.com](https://medium.com/analytics-vidhya/sql-for-data-scientists-in-6-minutes-or-less-6e11a377751f)

在 5 分钟内建立面罩检测模型

原文:https://towardsdatascience.com/you-can-do-it-too-build-face-mask-detection-model-in-5-minutes-727d83497a8c?source=collection_archive---------40-----------------------

使用可教机器

Unsplash视觉的照片

A 你难道不厌倦人们告诉你,如果你想成为一名数据科学家,你需要非常擅长数学吗?然后你看到你认识的一个数学/统计不如你的人在 Linkedin 上吹嘘他的机器学习技能。

你可以学习机器学习上的所有初学者项目,但当你想自己做一些事情时,你无法实现它,因为没有训练数据或你没有带 GPU?然后最终你对这个领域失去了兴趣,因为你体内的火因为缺乏动力而失去了它的力量。

我们都经历过。

被困住了太糟糕了。我明白了。你需要燃料来提升你的动力水平。

当你向世界展示你自己抽象想法的最终产品时,没有什么比这更令人兴奋的了。这里的意图不是给你另一个初学者教程“如何制作这个和那个令人敬畏的机器学习模型”,而是让你体验成功的滋味。

我向您保证,您可以在不到 5 分钟的时间内构建面具检测模型,而无需一行代码。归功于谷歌的可教机器。但是编码不是必须被称为机器学习工程师或者数据科学家吗?

不,更多的是关于你如何使用数据。它被称为“数据科学”而不是“编码科学”是有原因的。

究竟什么是可教机器?

Teachable Machine 是一个基于网络的工具,使得创建 machine 学习模型变得快速、简单,并且每个人都可以访问。- 可示教机器

可教机器允许任何人基于以下内容构建模型:

  • 形象
  • 声音的
  • 姿势

图片由作者在 Canva 制作

为什么只有可教的?你就不能用训练前的模型吗?

绝对的!预先训练的模型从一开始就是好的和有效的。这就是为什么 Teachable 使用由谷歌支持的预训练模型来训练你的模型。

但更特别的是训练数据。Teachable 使您能够使用网络摄像头为图像和姿势模型创建自己的数据,并使用外部麦克风为音频模型创建数据。就这样?

绝对不是。它是由 GPU 计算支持的训练,你也可以通过点击一个按钮轻松地看到现场训练的表现。培训结束后,您可以同样顺利地导出模型,这样您就可以用它来做一些事情。

建立人脸面具检测模型的先决条件:

占用你 5 分钟时间。

循序渐进指南:

作者在 Canva 制作的图像

第 1 步-开始:

请转到可示教机器并点击get started

当你试图在人脸上建立面具检测时,很明显模型需要图像作为训练数据。因此,让我们继续操作并选择图像项目。

满足你的好奇心——你可以尝试使用 pose project,看看模型与 image project 相比表现如何。所涉及的步骤基本相同,所以你可以按照这里的指南。

点击图像项目,为下一步做好准备

步骤 2-生成训练样本:

建立模型最重要的是训练数据。如前所述,如果你想用 Teachable 建立一个模型,你不必太担心训练数据。

您可以本地磁盘或 Google Drive** 上传**数据,如果您已经有了本地磁盘或 Google Drive,或者您也可以使用网络摄像头自己创建数据。

我完全推荐在这个项目中使用你的网络摄像头,因为你会体验到这样做的便利。

点击添加类别,您可以创建任意数量的标签。

对于这个项目,我们需要两个类

  1. 面具
  2. 没有面具

按作者生成培训数据

点击类名来改变它们。

接下来,点击网络摄像头按钮并按住录制生成图像。生成每个类大约 110 个图像,这应该足够这个项目。

戴上面具,左右移动头部,使其能够识别来自不同方向的图像,为面具类生成图像。

取下掩膜,对无掩膜类进行拍照。

就这样,你得到了带标签的训练数据。

第三步——培训模式:

只需点击Training即可开始模型的训练。

你可以在参数 Epochs,批量大小,学习率上做些调整。

Teachable 的一个很酷的功能是你可以通过点击引擎盖下的来查看你的模型是如何被训练的。

使用默认设置和每个类别的 110 幅图像,模型通常只需不到一分钟就可以完成训练。

作者的培训模型图像

第 4 步—检查结果:

作者的模型输出检查

恭喜你!用于在不到 5 分钟的时间内训练一个令人敬畏的复杂机器学习模型。

是时候享受模型的乐趣并检查结果如何了。

您可以从模型输出 Gif 中看到,这两个类都产生了非常令人满意的结果。

模型能够识别我脸上的面具,当我把面具放在我的额头上时,它像预期的那样识别为无面具。

如果需要,您现在可以导出模型并在教学平台之外使用它。

结论:

如果像人工智能、机器学习、高级统计学这些高保真词汇吓到你了?不要担心,你所要做的就是从小处着手,选择像这样的项目,因为它们有点燃火花的力量,给你肾上腺素,让你继续前进,达到最终目标。

试一试,让我知道你是否用它做了什么有趣的项目。

你可以在不知道所有事情的情况下找到一份数据科学的工作

原文:https://towardsdatascience.com/you-can-get-a-job-in-data-science-without-knowing-everything-e3550f2b7426?source=collection_archive---------6-----------------------

你可能很容易陷入一个陷阱,即你对数据科学的了解不足以找到一份工作,但通常这只是一个表象。

数据科学可能是一个非常模糊和令人生畏的话题。如果你在谷歌或 Reddit 论坛上搜索,你可能会很快被存在的大量信息淹没。其中一部分原因是因为从“商业分析师”到“机器学习科学家”的大量角色都属于这一范畴。它也是该领域相对较新且不断变化的进步的产物。对于那些即将毕业或希望开始数据科学职业生涯的人来说,这可能是势不可挡的,在许多情况下,甚至是失败的。

虽然看起来许多公司都在要求入门级职位的所有技能和能力,但事实上,不知道所有事情也可以开始工作。

作为 A 型的人,我总是追求完美,结果往往是“失败”。当我开始学习“数据科学”时,我想知道每个主题的一切,这通常使我很难深入任何主题。我不断问自己“有更好的选择吗?”当我开始一个项目或一个在线课程时。作为一名年轻的、有抱负的数据科学家,我想做最好的选择,这样公司才会注意到我。这不仅事与愿违,还浪费了我本可以用来学习新技能的大量时间。

所以我给任何进入这个领域的人的第一条建议是选择一个起点,并坚持下去。有更好的地方吗?也许吧。但是你最好开始一条路线,而不是不断地试图选择一条。

照片由马库斯·斯皮斯克Unsplash 拍摄

回到我的背景。在我大学期间,我换了 4-5 次专业,实际上直到最后一年我才接触到数据科学。我开始专注于计算机科学,最终转型,因为我发现数据科学是数学和编程之间的一个很好的平衡。进入大四时,我名下的数据科学实习、工作经验和项目都为零。我花了一年时间专注于我的课程,并试图从每个项目中获得最大收益,而不是把我自己的个人项目堆在上面。一遍又一遍地重复做简单的项目帮助我熟悉了探索性分析、数据可视化和将结果转化为实际意义的基本步骤。

对于我的顶点项目,我选择将重点放在使用神经网络进行基因组分析上。设置相对简单,但提供了对一种机器学习技术的大量接触,而不是试图同时学习所有技术。当然,最终我会继续学习决策树、支持向量机和随机森林,但是花更多的时间学习一种方法的来龙去脉让我对神经网络如何工作以及如何将它们应用到实际问题中有了更深刻的理解。

因此,我的第二条建议是选择一个主题作为重点,而不是试图在简历中塞满流行词汇。花一两天的时间研究一个主题可能会让你对很多东西都知之甚少,而不是对少数几个有深刻的理解。

最后是实际申请工作的过程。提醒一下,我仍然没有数据科学方面的工作经验,但现在有几个基本项目要谈。我发出了很多申请(我怎么强调“很多”都不为过),并有幸获得了几次面试机会。最终,我在塔吉特百货公司做了一名数据分析师。

自从开始我的角色,我已经能够应用我在大学里获得的许多技能,同时也学习了一大堆新的技能。很多时候,我学习一项技能是因为在工作中遇到了问题,而不是简单地寻找“下一个伟大的数据科学主题”。大多数时候,我仍然觉得自己知之甚少。Reddit 和数据科学博客的世界仍然让人觉得每个人都知道一切(显然这不是真的)。

所以对于那些觉得自己不够资格或者知道得不够多的人来说…

  1. 你可能知道很多。
  2. 你将在工作中学到比在学校更多的东西。
  3. 没有人知道一切,如果他们说他们知道,他们在撒谎。

有趣的是,这里有一堆我简历上没有的技能,这些技能似乎成为了很多职位的必备条件:

  • SQL(说真的)
  • Hadoop
  • 火花
  • 云计算
  • 数据管道
  • Postgres,MongoDB,MySQL 等等…
  • 任何训练营或在线课程的认证
  • 码头工人

你可以通过这些 YouTube 视频了解 GPT 3 号

原文:https://towardsdatascience.com/you-can-understand-gpt-3-with-these-youtube-videos-6a30887c928b?source=collection_archive---------36-----------------------

GPT-3,作者图片

回顾

通过这些 YouTube 视频,在不到 3 分钟的时间里了解 GPT 3 号

GPT 3 是当前人工智能行业的热门话题。社区对其解决基于文本的任务的潜力和应用感到惊讶;而其他人则认为这只是典型的媒体驱动的人工智能炒作。

无论你支持哪一个阵营,至少对 GPT 协议-3 有一个基本的了解是至关重要的。

为了获得一些信息,我通读了一些总结 GPT-3 主要方面的文章。现在,我浏览了 YouTube 上的几个视频,这些视频很好地展示了 GPT-3,足以在最初的三分钟内理解语言模型。

下面是四个 YouTube 视频,我相信会让你对 GPT 3 有基本到中等程度的了解,并在这个过程中,学习一两件关于语言建模和变形金刚的事情。

GPT-3——用通俗的语言解释。

难度:容易

时长:4 分 57 秒

回顾

主持人提供了 GPT-3 的简要说明,并对 GPT-3 中的参数数量与其他语言模型参数(包括旧版本的 GPT)进行了比较。

我欣赏使用可视化图表来传达关键信息,并补充短片中的要点。

更不用说,视频中还有 GPT-3 生成的文本和应用程序的示例。

该频道主持人避免使用技术术语来解释 GPT-3,这使得这个简短的视频容易为普通观众所理解。

你可能不需要有机器学习的经验或任何技术背景,就可以获得一些关于 GPT-3 及其早期应用的坚实基础知识。

该视频不仅提到了 GPT-3 的优点。有一个关于 GPT-3 语言模型缺点的陈述,并提供了一个例子。

GPT-3——用通俗的语言解释。

OpenAI 的新语言生成器:GPT-3 |这个 AI 从单词中生成代码、网站、歌曲&

难度:容易

时长:6 分钟

回顾

这段视频非常简洁,但演示者确实提供了 GPT 3 号的简要背景。

我之所以包括这个视频,是因为它增加了几个应用程序,显示了如何利用 GPT-3 来完成各种任务。视频的一半只是展示了用 GPT-3 构建的应用程序。

OpenAI 的新语言生成器:GPT-3 |这个 AI 从单词中生成代码、网站、歌曲&

GPT3:一个更大的语言模型——计算机爱好者

难度:中等

时长:26 分钟

回顾

该视频中的主持人详细介绍了新 GPT 协议和语言模型的其他方面,如培训方法、未来潜力、改进等。

我很欣赏演示者后退一步谈论 GPT-2 的事实。这样做是为了让观众了解 GPT-3 给人工智能社区带来的进步和改进的水平。

还有一个关于 OpenAI 构建一个健壮语言模型的策略的一般观点的论述,该策略是利用一个具有大量权重参数的模型架构,并在空前数量的文本上进行训练。

这个视频可能不适合所有人,因为主持人使用了技术术语,这些术语在整个视频中没有解释。这个特定的 GPT 3 视频的观众可能是具有自然语言处理和语言建模基本背景的人。

此外,还包含一些短片,介绍了通过实施和培训新 GPT 协议而实现的潜在改进空间。

主持人的对话确实让观众了解了语言建模研究工作开始采取的总体策略,即“越大越好”。

我发现有用的一个关键点是,它包含了对 GPT-3 研究论文的浏览,对论文中包含的人因准确性评估报告的结果进行了总结和解释。这一点很重要,因为它向观众提供了 GPT 3 号性能的背景。

主持人对观众进行了一项实验,观众必须猜测哪首诗是 GPT 3 号创作的,哪首是人类创作的。视频最后给出了答案。

一般来说,视频的前半部分涵盖了 GPT 3 号所需的基本信息,后半部分探索了其他领域,如应用、计算机资源、创造力、潜力和未来用途。

GPT3:一个更大的语言模型——计算机爱好者

GPT-3:语言模型是一次性学习者(论文解释)

难度:中等难度

时长:1 小时 4 分钟

回顾

Yannic Kilcher 的这段精彩视频用一个小时解释了 GPT 3 号研究论文中的内容。

没有多少 YouTuber 花了大量时间来深入解释 GPT-3 和提出迄今为止最大的语言模型的研究论文。

对 GPT-3 的具体技术内容感兴趣的机器学习从业者会发现这个视频很有用。

视频中介绍的论文中使用的技术术语有简要的解释,但这个视频不适合胆小的人。

对于那些不熟悉机器学习方法来解决语言建模的人来说,你可能会发现自己在一些外部资源之间来回穿梭,解释视频和研究论文中使用的技术术语。

Yannic 的 GPT-3 视频详细介绍了与 GPT-3 和语言建模相关的主题,如培训和评估方法、使用的数据集、变压器架构、上下文学习、GPT-3 模型的大小变化、一次性学习、少量学习等。

这个视频信息丰富,在整个视频过程中,你可能需要一支笔和纸。

GPT-3:语言模型是一次性学习者(论文解释

[## 有助于您了解 GPT-3 的文章

增强你对最新炒作的人工智能模型:GPT 3 的了解

towardsdatascience.com](/articles-that-will-help-you-understand-gpt-3-610dedc37859) [## 根据吴恩达的观点,如何在机器学习的职业生涯中导航

了解如何在机器学习领域取得成功

towardsdatascience.com](/how-to-navigate-a-career-in-machine-learning-according-to-andrew-ng-stanford-lectures-9e10f09047f0)

深度学习的 SAR 去斑不需要清晰的图像

原文:https://towardsdatascience.com/you-do-not-need-clean-images-for-sar-despeckling-with-deep-learning-fe9c44350b69?source=collection_archive---------47-----------------------

Speckle2Void 是如何学会停止担忧,爱上噪音的

来自 TerraSAR-X 的噪声 SAR 图像。

当想到卫星图像时,我们大多数人都会想到光学图像,即传感器捕捉地球反射的太阳光线形成的图片。但是光学图像并不是故事的全部!

合成孔径雷达(SAR)是一种基于主动照明的替代成像技术。基本上,卫星发送一束电磁波,并监听它从地面的反射。巧妙的处理技术将发射的波形与接收到的波形进行比较,可以生成一幅图像,显示地面是如何反射波的。合成孔径雷达必须被视为光学仪器的补充,因为它提供了光学仪器所不具备的能力。例如,合成孔径雷达可以看穿云层,因为它工作在电磁波谱的微波范围内,所以它不能被恶劣的天气所阻止。

然而,SAR 图像比它们的光学对应物呈现出更多的噪声,而且这不是普通的噪声。这种特殊的噪声称为 散斑 ,是 SAR 等所有相干成像系统所共有的。一个常用的模型认为散斑是一种倍增扰动,与真实地面反射率无关。

由于斑点是一种非常严重的干扰,并且限制了诸如目标检测或土地覆盖分类等任务的性能,因此去斑点算法已经被研究了将近 40 年。今天,深度学习承诺了新一代算法,可以利用卷积神经网络(CNN)强大的表示能力,以更忠实的方式恢复底层地面反射率。

我的地面真理在哪里?

CNN 的监督训练已被证明在解决包括去噪在内的各种问题方面非常强大,但它从根本上受到对地面真实数据的需求的限制。这对于我们的 SAR 去斑目标来说是一个关键问题,因为干净的 SAR 图像根本不存在。

早期的方法通过在光学图像或广泛用于图像识别的数据集(例如 ImageNet)上模拟散斑来绕过这个问题。这允许具有图像的噪声版本和相应的地面真相。

然而,这不是最佳的,因为 SAR 图像的特征可能与常规图像的特征显著不同。这在训练中使用的数据和将应用该算法的真实数据之间产生了一个域间隙,并且它导致了降低去斑点图像质量的伪像。下图显示了一个简单的 CNN 在合成数据上以这种监督方式训练的例子。我们可以看到一些区域过于平滑,而其他区域则呈现出卡通般的特征。

**

左:嘈杂的图像,右:监督 CNN 去噪。请注意由于使用合成斑点数据进行训练而产生的伪像。来自 https://arxiv.org/abs/2007.02075的数字

斑点状 2

在过去的一年里,深度学习社区在无监督的情况下解决去噪问题方面取得了重大进展。像 Noise2NoiseNoise2VoidNoise2Self 等方法设计了不需要清晰图像的自我监督方法。一些方法,如 Noise2Noise(及其对 SAR 图像的扩展)需要同一场景的多种实现,这可能很难获取、注册和适应变化。另一方面 Laine 等人设计了一个贝叶斯框架,允许从单个噪声图像进行自我监督训练。 Speckle2Void 将该框架引入遥感领域,解决了 SAR 去斑时出现的一些问题。

建筑

Speckle2Void 架构。图来自https://arxiv.org/abs/2007.02075

Speckle2Void 依赖于盲点 CNN,即特殊类型的 CNN,在与我们当前想要去噪的像素相对应的感受野中有一个洞。想法是网络应该从感受野预测干净像素的值。这是因为如果噪声是空间不相关的,就不可能预测像素的噪声分量。感受域中的洞是需要的,以确保像素本身被排除在这一操作之外,否则,它将平凡地复制自己的值。这是通过合适的架构实现的,如图所示,该架构使用标准卷积层,但对图像的旋转版本进行移位,以将感受野的扩展限制在一个方向。

训练和去噪

训练和去噪程序。图来自https://arxiv.org/abs/2007.02075

在解释训练和去噪如何工作之前,我们必须介绍用于描述噪声和给定感受野的干净图像像素的条件分布的贝叶斯模型。实际上,训练的整个目标是让 CNN 学会如何处理感受野,以返回最适合噪声观察的干净像素分布的参数值。

噪声是倍增的,并且遵循伽马分布;给定感受野的图像像素遵循逆伽马分布,其参数由 CNN 估计。最后,这意味着观察到的噪声数据遵循称为 G0 的著名分布,该分布被认为是异质 SAR 图像的良好模型。

在训练期间,p(y)的对数被最小化,以让 CNN 学习如何使用感受野来产生最适合噪声数据的干净图像分布的参数。在测试期间,使用贝叶斯后验分布的平均值计算去噪图像,即:

你的斑点真的不相关吗?

虽然许多 SAR 图像模型通常假设散斑在空间上不相关,但在现实生活中这通常是不正确的,因为 SAR 聚焦系统的传递函数引入了一些相关性。这对于 Speckle2Void 是不利的,因为 CNN 可以找到一种方法来利用噪声中的相关性来复制它,从而降低去噪性能。这个问题可以用两种方法来解决:
1。通过使用诸如 Argenti 等人的技术去相关散斑;2
。用更大的盲点!盲点的宽度应该被调制以匹配散斑过程的自相关宽度。

结果

我们可以看到 Speckle2Void 是如何在保留图像细节的同时强烈抑制斑点噪声的。关键的是,它没有引入监督训练中观察到的那种伪影,因为它学习了如何直接从真实的 SAR 图像中提取相关特征。

**

左:有噪声的图像,右:用斑点 2 去噪。数字来自https://arxiv.org/abs/2007.02075

结论

对于自监督方法来说,这是一个激动人心的时刻,越来越多的应用开始受益于直接使用真实数据,即使在没有监督信号的情况下。Speckle2Void 证明了即使无法观察到清晰的图像,也可以学习一种有效的 SAR 图像去斑算法。

你不需要总是在熊猫的行列中循环!

原文:https://towardsdatascience.com/you-dont-always-have-to-loop-through-rows-in-pandas-22a970b347ac?source=collection_archive---------8-----------------------

计算机编程语言

用向量化解决方案看一下“for 循环”的替代方案。

由@ siscadraws 创建(Instagram 句柄)

我用熊猫已经有一段时间了,但我并不总是正确地使用它。我执行计算或编辑数据的直观方法倾向于从这个问题开始:

我如何循环遍历(迭代)我的数据帧来做 INSERT_ANY_TASK_HERE

迭代数据帧中的行可能有效。事实上,我写了一整篇关于如何逐行编辑你在熊猫中的数据。

我这样做的原因是因为我有一个多层计算,对于我来说,我无法解决如何不循环。我有多个条件,其中一个条件涉及获取一个列值,该列值具有数据帧中另一个列的名称,该列将用于计算。

迭代数据帧是我能想到的解决这个问题的唯一方法。但是这不应该是你在和熊猫一起工作时总是采用的方法。

事实上,Pandas 甚至有一个红色的警告告诉你不应该迭代数据帧。

遍历 pandas 对象一般都是。在许多情况下,不需要手动迭代这些行,并且可以通过矢量化解决方案来避免:许多操作可以使用内置方法或 NumPy 函数、(布尔)索引来执行。

大多数时候,您可以使用一个矢量化解决方案来执行您的熊猫操作。矢量化不是使用“for 循环”类型的操作,即一次遍历一组数据中的一个值,而是实现一个解决方案,一次遍历一组值。在 Pandas 中,这意味着不是逐行计算,而是在整个数据帧上执行操作。

这里的重点不仅仅是代码在非循环解决方案下运行的速度,而是创建可读的代码,最大程度地利用 Pandas。

现在,让我们通过几个例子来帮助重新构建最初的思考过程,从“我如何循环通过一个数据帧?”真正的问题是“我如何用熊猫的工具进行计算?”。

我们将要使用的数据来自于 Kaggle 的一个动物穿越用户回顾数据集。我们将导入数据并创建两个数据帧,一个称为“旧”,另一个称为“新”。然后,为了开始了解 for 循环的替代解决方案的基础,我们将使用 for 循环和矢量化解决方案执行一些操作,并比较代码。(要理解下面 for 循环代码背后的逻辑,请查看我之前的一篇文章,因为它已经对这个主题有了深入的解释。)

import pandas as pdold = pd.read_csv('user_reviews.csv')
new = pd.read_csv('user_reviews.csv')

熊猫矢量化解决方案介绍

实现“如果-那么-否则”

让我们创建一个名为“qualitative _ rating”的新列。这样,我们可以创建一些宽泛的类别,将每个用户评论标记为“差”、“好”和“好”。“坏”评论是指“等级”低于 5 的评论。一篇好的评论将会是任何“等级”大于 5 的评论。任何“等级”等于 5 的评论都将是“好的”。

要使用 for 循环实现这一点,代码如下所示:

# if then elif else (old)# create new column 
old['qualitative_rating'] = ''# assign 'qualitative_rating' based on 'grade' with loop
for index in old.index:
    if old.loc[index, 'grade'] < 5:
        old.loc[index, 'qualitative_rating'] = 'bad'
    elif old.loc[index, 'grade'] == 5:
        old.loc[index, 'qualitative_rating'] = 'ok'
    elif old.loc[index, 'grade'] > 5:
        old.loc[index, 'qualitative_rating'] = 'good'

代码很容易阅读,但是花了 7 行 2.26 秒完成了 3000 行。

相反,更好的解决方案应该是这样的:

# if then elif else (new)# create new column
new['qualitative_rating'] = ''# assign 'qualitative_rating' based on 'grade' with .loc
new.loc[new.grade < 5, 'qualitative_rating'] = 'bad'
new.loc[new.grade == 5, 'qualitative_rating'] = 'ok'
new.loc[new.grade > 5, 'qualitative_rating'] = 'good'

这一次,添加定性评级的代码仅由 3 行代码组成,仅用了 68 毫秒。“我也用过了。loc”data frame 函数,但这一次,我“恰当地”使用了它。我的意思是,我没有使用循环的“如果-否则”解决方案,而是直接从“如果-否则”中分配“坏”、“好”和“好”的定性评级。loc”选择。

计算列值的长度

我们的下一个新列“len_text”将显示每个评论的字符数,因此我们可以比较数据集中不同评论的长度。

要使用 for 循环实现这一点,代码如下所示:

# create column based on other column (old)# create new column
old['len_text'] = ''# calculate length of column value with loop
for index in old.index:
    old.loc[index, 'len_text'] = len(old.loc[index, 'text'])

同样,2 行 2.23 秒对于这个计算来说并不算长。但是,我们可以使用只需要一行的解决方案,而不是遍历每一行来查找长度:

# create column based on other column (new)# create new column
new['len_text'] = ''# calculate length of column value by converting to str
new['len_text'] = new['text'].str.len()

这里,我们获取一个现有列的值,将它们转换成字符串,然后使用“.len()"来获取每个字符串中的字符数。这个解决方案只花了 40 毫秒运行。

基于多个条件和现有列值创建新列

现在让我们创建一个名为“super_category”的新列。在这里,我们将确定人们是否有资格成为“超级审阅者”,或者在这种情况下,他们的审阅长度是否大于 1000 个字符。如果评论“等级”大于或等于 9,我们还会将超级评论者标记为“超级粉丝”,如果评论“等级”小于或等于 1,则标记为“超级讨厌者”。其他人都将被归类为“正常”。

用 for 循环实现这一点将如下所示:

# new column based on multiple conditions (old)# create new column
old['super_category'] = ''# set multiple conditions and assign reviewer category with loop
for index in old.index:
    if old.loc[index, 'grade'] >= 9 and old.loc[index, 'len_text'] >= 1000:
        old.loc[index, 'super_category'] = 'super fan'
    elif old.loc[index, 'grade'] <= 1 and old.loc[index, 'len_text'] >= 1000:
        old.loc[index, 'super_category'] = 'super hater'
    else:
        old.loc[index, 'super_category'] = 'normal'

这是可行的,但是让我们把它分成两半:

# new column based on multiple conditions (new)# create new column
new['super_category'] = 'normal'# set multiple conditions and assign reviewer category with .loc
new.loc[(new['grade'] == 10) & (new['len_text'] >= 1000), 'super_category'] = 'super fan'
new.loc[(new['grade'] <= 1) & (new['len_text'] >= 1000), 'super_category'] = 'super hater'

这里,我们在我们的内部使用了“&”操作符。loc "函数来同时实现这两个条件。矢量化解决方案在 63 毫秒内完成,这再次明显快于循环方法,后者需要 2.23 秒。

这些是一些基本的操作,用来扩展现有的数据和一些我们自己定制的分析。是的,我们可以用循环做任何事情,你甚至可以看到相同的结构应用于许多不同的操作。但是 Pandas 自带了很多内置方法,专门用于我们经常需要执行的操作。

经历这些帮助我重新训练我的大脑,不要总是将 for 循环作为寻找更好的方法来完成各种操作的解决方案。

我希望它能帮助你做同样的事情!

你不必赢得一场 Kaggle 比赛来展示你的数据科学能力!

原文:https://towardsdatascience.com/you-dont-have-to-win-a-kaggle-competition-to-showcase-your-data-science-ability-2852a77b6d8c?source=collection_archive---------45-----------------------

(图片由作者提供)

我曾经坚持认为只有 Kaggle 比赛的获胜者才能展示他们的背景,现在我发现 Kaggle 的每个新人都可以在没有像样的排行榜的情况下展示他们的努力!

我们可以用我们的作品在 Kaggle 比赛中做什么?获得一个体面的排名,并可能获得大量奖励,这个答案对一些天才来说可能听起来不错。但是你不够聪明怎么办?这场比赛会完全没有意义吗?肯定没有! Kaggle 作为数据科学家和机器学习爱好者的最大社区,不仅是为了排名和金钱,也是一个提高我们数据科学/建模技术的完美平台。

在文章的其余部分,我将介绍一种方法来展示你在 Kaggle 比赛中所做的事情,这是一个非常有用的组合,尤其是当你未能在排行榜上排名第一时,更重要的是给你的面试官留下深刻印象!

我要讲的是哪个比赛?

我最近参加了由萨斯喀彻温大学主办的 全球小麦检测 ,该项目旨在帮助农民在他们的田地里做出管理决策时评估健康和成熟度。该竞赛鼓励候选人尽可能提高图像中小麦籽粒的检测精度。直到编辑完这篇文章,本次比赛的№1 候选队伍已经取得了 0.7772 的成绩,这是比赛开展前的巨大飞跃,因为首发笔记本的成绩只有 0.66 左右。其截止日期为 2020 年 8 月 4 日。所以,如果你对计算机视觉感兴趣或者想赢得一些钱(一等奖 8000 美元!),你绝对没有理由错过!

全球小麦检测竞赛主页(图片由作者提供)

开始之前

如果你没有耐心通读整页(跟我一样:),现在就可以通过,直接去我的 GitHub repo:

https://github . com/MemphisMeng/global-wheat-detection-we B- app

现在让我们来谈谈这个项目所需的依赖关系:

  1. 细流
  2. 相册
  3. matplotlib
  4. numpy
  5. opencv-python
  6. 熊猫
  7. 枕头
  8. scipy

如果您不熟悉以上任何一个,请随意点击超链接并参考它们各自的文档。

最后一件值得注意的事情是,我将要建立的是一个面向 JPG 图像的麦穗检测器。换句话说,我会让模型告诉你一个图像中有多少个麦穗,它们位于哪里,只要你在应用中上传一个。

我们来编码吧!

首先,为了利用我在上一节中提到的所有库,需要做的就是简单地导入它们中的每一个:

**import** numpy **as** np
**import** pandas **as** pd
**import** re
**from** PIL **import** Image
**import** albumentations **as** A
**from** albumentations.pytorch.transforms **import** ToTensorV2
**import** torch
**import** torchvision
**from** torchvision.models.detection.faster_rcnn **import** FastRCNNPredictor
**import** streamlit **as** st
**from** torch.utils.data **import** DataLoader, Dataset
**from** matplotlib **import** pyplot **as** plt
**import** cv2

为了处理每一张上传的图片,我把它看作一个数据集,方便以后涉及 PyTorch 的操作。

**class** WheatTestDataset(Dataset):

    **def** __init__(self, image, transforms=**None**):
        super().__init__()
        self.transforms = transforms
        self.image = [image]

    **def** __getitem__(self, index):
        image = cv2.cvtColor(np.asarray(self.image[index]), cv2.COLOR_BGR2RGB).astype(np.float32)
        *# st.write('image', image)
        # image = np.asarray(self.image[index]).astype(np.float32)* image /= 255.0

        **if** self.transforms:
            sample = {
                **'image'**: image,
            }
            sample = self.transforms(**sample)
            image = sample[**'image'**]

        **return** np.asarray(image)

    **def** __len__(self) -> int:
        **return** len(self.image)*# Albumentations* **def** get_test_transform():
    **return** A.Compose([
        *# A.Resize(512, 512),* ToTensorV2(p=1.0)
    ])

**def** collate_fn(batch):
    **return** tuple(zip(*batch))

因此,我们可以这样加载图像:

test_dataset = WheatTestDataset(image, get_test_transform())
test_data_loader = DataLoader(
    test_dataset,
    batch_size=1,
    shuffle=**False**,
    num_workers=4,
    drop_last=**False**,
    collate_fn=collate_fn
)

之后,我还需要加载或配置神经网络模型。为了方便起见,我只是加载了基于 FasterRCNN 的预训练模型,你也可以在这里下载。因此,建模部分看起来像:

WEIGHTS_FILE = **'fasterrcnn_resnet50_fpn_best.pth' # downloaded weights** *# load a model; pre-trained on COCO* model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=**False**, pretrained_backbone=**False**)
device = torch.device(**'cuda'**) **if** torch.cuda.is_available() **else** torch.device(**'cpu'**)
num_classes = 2  *# 1 class (wheat) + background
# get number of input features for the classifier* in_features = model.roi_heads.box_predictor.cls_score.in_features
*# replace the pre-trained head with a new one* model.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)
*# Load the trained weights* model.load_state_dict(torch.load(WEIGHTS_FILE, map_location=device))
model.eval()

接下来,应该在网页上添加一些必要的元素:

st.header(**"""
WELCOME TO GLOBAL WHEAT HEAD CHALLENGE!
"""**)
st.subheader(**'Please open this website with Google Chrome.'**)
uploaded_file = st.file_uploader(**"Choose an image... (jpg only)"**, type=**"jpg"**)
confidence_threshold = st.number_input(**'Please specify the confidence of a wheat head'**)
button = st.button(**'Confirm'**)

最后,我们可以直接使用我们的模型来检测项目:

detection_threshold = confidence_threshold **or** 0.5
results = []
outputs = **None** images = **None

if** button **and** uploaded_file **is not None**:
    image = Image.open(uploaded_file)
    st.image(image, caption=**'Uploaded Image'**, use_column_width=**True**)
    st.write(**""**)
    st.write(**"Detecting..."**)
    test_dataset = WheatTestDataset(image, get_test_transform())
    test_data_loader = DataLoader(
        test_dataset,
        batch_size=1,
        shuffle=**False**,
        num_workers=4,
        drop_last=**False**,
        collate_fn=collate_fn
    )

    **for** images **in** test_data_loader:
        images = torch.Tensor([images[0][0], images[1][0], images[2][0]])
        images = torch.reshape(images, (3, 1024, 1024))
        images = (images,)
        images = list(image.to(device) **for** image **in** images)
        outputs = model(images)

        **for** i, image **in** enumerate(images):
            boxes = outputs[i][**'boxes'**].data.cpu().numpy()
            scores = outputs[i][**'scores'**].data.cpu().numpy()

            boxes = boxes[scores >= detection_threshold].astype(np.int32)
            scores = scores[scores >= detection_threshold]

            boxes[:, 2] = boxes[:, 2] - boxes[:, 0]
            boxes[:, 3] = boxes[:, 3] - boxes[:, 1]

            **for** j **in** zip(boxes, scores):
                result = {
                    **'Detected Boxes'**: **"{} {} {} {}"**.format(j[0][0], j[0][1], j[0][2], j[0][3]),
                    **'Confidence%'**: j[1]
                }
                results.append(result)

**if** len(results) != 0:
    *# print out results* sample = images[0].permute(1, 2, 0).cpu().numpy()
    boxes = outputs[0][**'boxes'**].data.cpu().numpy()
    scores = outputs[0][**'scores'**].data.cpu().numpy()
    boxes = boxes[scores >= detection_threshold].astype(np.int32)
    fig, ax = plt.subplots(1, 1, figsize=(32, 16))
    **for** box **in** boxes:
        x1, y1, x2, y2 = box
        sample = cv2.rectangle(img=sample,
                               pt1=(x1, y1),
                               pt2=(x2, y2),
                               color=(0, 0, 255), thickness=3)
    ax.set_axis_off()
    st.image(cv2.UMat.get(sample), clamp=**True**)
    st.write(**"# Results"**)
    st.dataframe(pd.DataFrame(results))
**else**:
    st.write(**""**)
    st.write(**"""
    No wheat heads detected in the image!
    """**)

所以现在这个 web app 是在本地端完成的,所以当你在终端输入streamlit run app.py的时候,你就可以在本地主机上访问和测试程序。

下一步是什么?

既然我们已经开发了这个检测工具,如果我们能与任何需要它的人分享它,那将是完美的。因此,将其部署为任何人都可以随时查看的 web 应用程序绝对是一个不错的选择。各种企业开发的 web 服务有一堆,现在我就以 Google 云平台为例。谷歌云平台( GCP )是谷歌提供的一套网络服务,包括一套管理工具和一系列模块化云服务。这一次,我们主要需要使用它的容器化和 GPU 服务。

我实现这一部分的策略与 Moez Ali 发表的这篇帖子中的任务 4 基本相同。需要注意的是,由于我们的项目使用 PyTorch 作为框架来配置神经网络模型,因此从 docker hub 导入已建立的 docker 映像总是更好,而不是要求主机在 requirements.txt 中安装。该选项的最大好处是它有效地节省了机器的内存空间。因此,完整的 docker 文件如下所示:

FROM pytorch/pytorch:1.4-cuda10.1-cudnn7-runtime
RUN pip install virtualenv
ENV VIRTUAL_ENV=/venv
RUN virtualenv venv -p python3
ENV PATH="VIRTUAL_ENV/bin:$PATH"WORKDIR /app
ADD . /app# Install dependencies
RUN apt update
RUN apt-get install -y libglib2.0-0 libsm6 libxrender1 libxext6
RUN pip install -r requirements.txt# copying all files over
COPY . /app# Expose port 
ENV PORT 8501# cmd to launch app when container is run
CMD streamlit run app.py# streamlit-specific commands for config
ENV LC_ALL=C.UTF-8
ENV LANG=C.UTF-8
RUN mkdir -p /root/.streamlit
RUN bash -c 'echo -e "\
[general]\n\
email = \"\"\n\
" > /root/.streamlit/credentials.toml'RUN bash -c 'echo -e "\
[server]\n\
enableCORS = false\n\
" > /root/.streamlit/config.toml'

干得好!

现在我们已经成功地将该项目部署到 GCP,然后任何对你的工作感兴趣的人都可以从中得到乐趣。

网络应用网址:http://35.188.98.72/(图片由作者提供)

思想

我写这篇文章是因为我最近受到一个人的启发,他问我这个行业可以用我的 Kaggle 项目做什么。我曾经陷入这样一个陷阱:除非你在 Kaggle 上有一个像样的个人资料,否则你将无法找到一份数据科学的工作。这并没有错,虽然没有人可以定义你的体面。而那个人的话让我更多的为行业考虑,这应该是一个有志的数据科学家找工作应该具备的“体面”。

所以我努力发展自己的方式来展示我在 Kaggle 上所做的事情,试图让每个人都理解我的项目,并说服他们我的项目对他们的业务有价值,即使他们没有 IT 背景。把一个项目包装成一个网络应用程序,让每个人都能享受其中的乐趣,这是我现在最好的选择。

这是我的第一篇关于媒介的文章,如果你喜欢,请给我一个掌声,因为这将是你对我最大的鼓励。未来,我将发表更多文章,分享我的数据科学之路。所以有兴趣的请跟我来!

参考文献:

[1] Moez Ali在 Google Kubernetes 引擎上部署使用 Streamlit 和 PyCaret 构建的机器学习应用

[2]https://www . ka ggle . com/pesti peti/py torch-starter-fasterr CNN-推论

你不知道你不知道什么

原文:https://towardsdatascience.com/you-dont-know-what-you-don-t-know-3e20de7dceb8?source=collection_archive---------56-----------------------

这是对年轻且快速发展的数据挖掘领域(也称为从数据中发现知识,或简称为 KDD)的介绍。它侧重于从各种应用程序的数据中发现有趣模式的基本数据挖掘概念和技术。

来源: Pixabay

我们今天看到的世界拥有自动化的数据收集工具、数据库系统、万维网和计算机化的社会。这导致了数据的爆炸式增长,从百万兆字节增长到百万兆字节。

我们淹没在数据的海洋中,却渴望知识。

我们的新时代为我们提供了巨大的速度、数量和各种各样的数据。我们有更便宜的技术,移动计算,社交网络,云计算引发了这场数据风暴。

这些就是传统方法逐渐消失的原因,我们需要一些像数据挖掘这样的新方法来处理新时代的数据。

什么是数据挖掘?

数据挖掘是从海量数据源中发现新颖、有效、有用和可理解的模式和模型的迭代和交互过程。

打破数据挖掘的定义。

什么是知识发现?

从海量数据库中产生知识的整个过程称为 KD。这是一个比数据挖掘更复杂的过程。数据挖掘是知识发现的一个步骤,它处理数据中模式的识别。

让我们来分解一下 KD 的过程。

第一步。学习应用领域

我们应该预先了解我们将要发现知识的应用领域。据观察,具有先验知识有助于从数据中更好地产生洞察力。

第二步。数据清理

一旦我们从仓库中获得了数据,我们就需要去除噪声和不一致的数据。在知识发现过程中,可能要花费高达 60%的精力。

第三步。数据选择

我们创建一个数据集,从数据库中检索与分析任务相关的数据。

第四步。数据简化和转换

在这里,我们通过执行汇总或聚合操作,将数据转换并整合成适合挖掘的形式。我们找到有用的特征,进行维数或变量缩减,并使用不变表示。

第五步。数据挖掘技术

这是一个应用智能方法提取数据模式的重要过程。方法可以是总结、分类、回归、关联或聚类。

第六步。模式评估

我们基于兴趣度来识别和分离代表知识的真正有趣的模式。

第七步。知识展示

可视化和知识表示技术用于向用户或利益相关者呈现挖掘出的知识。

KD 和 DM 中涉及的步骤是 KD 的步骤之一(来源:elsevier.com)

可以挖掘哪些类型的数据?

数据挖掘可以应用于任何类型的数据,只要这些数据对目标应用程序有意义。挖掘应用最基本的数据形式是数据库数据数据仓库数据、事务数据。

数据库数据

数据库系统,也称为数据库管理系统( DBMS ),由一组相互关联的数据组成,称为数据库。

关系数据库是表的集合,每个表都被赋予一个惟一的名称。每个表都由一组包含大型元组集的属性组成。关系表中的每个元组代表一个由唯一键标识并由一组属性值描述的对象。

一个关于电子技术的关系数据库(来源:elsevier.com

数据仓库

假设一家成功的国际公司在世界各地都有分支机构。每个分支机构都有自己的一套数据库。公司总裁要求您提供一份公司第三季度每个分公司每个产品类型的销售分析。

为了便于决策,数据仓库中的数据是围绕主要主题组织的。

数据仓库的框架(来源:elsevier.com)

交易数据

通常,事务数据库中的每个记录都捕获一个事务,例如客户的购买、机票预订或用户对网页的点击。交易通常包括唯一的交易标识号( trans ID )和组成交易的物品列表,例如在交易中购买的物品。

使用的技术?

作为一个高度应用驱动的领域,数据挖掘结合了许多来自其他领域的技术,例如

KD 流程中使用的技术(来源:elsevier.com)

统计数字

统计学研究数据的收集、分析、解释和表达,与数据挖掘有着内在的联系。它包括对描述统计学、推断统计学或预测统计学以及统计假设检验的研究。

机器学习

机器学习研究计算机如何基于数据进行学习(或提高性能)。众所周知,它包括有监督学习、无监督学习、强化学习。

DM 中的重大问题?

数据挖掘是一个动态和快速发展的领域,具有很大的优势。这些问题中的许多在最近的数据挖掘研究和开发中已经得到了一定程度的解决,现在被认为是数据挖掘的需求,其他的仍处于研究阶段。

采矿方法

数据挖掘和知识发现涉及在多维空间中挖掘各种新的知识,处理数据的噪声、不确定性和不完整性。这似乎是一个两行的问题,但比我们能想到的更复杂。因此它们仍处于发展阶段。

此外,数据挖掘是一项跨学科的工作,因此我们需要许多领域的先验知识来解决问题。

用户交互

用户在数据挖掘过程中扮演着重要的角色。有趣的研究领域包括如何与数据挖掘系统交互,如何在挖掘中结合用户的背景知识,以及如何可视化和理解数据挖掘结果。

这还包括对挖掘数据的生动和灵活的表示,以便发现的知识可以被人类容易地理解和直接使用。

效率和可扩展性

在比较数据挖掘算法时,总是要考虑效率和可伸缩性。随着数据量的持续增长,这两个因素变得尤为重要。

让我们来欣赏…

数据挖掘和知识发现是理解数据和生成可供人类使用的模式的广泛方式。这也是一个反复的过程。我们需要多次思考、应用、评估,才能知道自己不知道的东西。

你不需要工作来获得数据科学经验

原文:https://towardsdatascience.com/you-dont-need-a-job-to-get-data-science-experience-26af4fd4c200?source=collection_archive---------12-----------------------

把硬币翻转过来

代替&在 Unsplash 上取景摄影

鉴于我目前的情况——最近被裁员了——我一直在考虑我是否真的想要另一个永久的角色,但这一次是作为一名数据科学家而不是机器学习工程师,或者我是否有能力独自成为一名自由职业者/承包商。

然而,重要的是我要不断发展我的技能,我知道在讨论个人发展时,现实世界的经验有多重要。

人们经常问的问题是“我如何在没有经验的情况下找到一份数据科学的工作?”然而,我想如果我能把这个问题反过来,我不仅可以发展我的技能,接触真实世界的数据科学,我还可以在这个过程中让自己更容易被雇佣。因此,这个问题的反过来应该是:

“没有工作,我如何获得数据科学家的经验?”

自愿参军

我知道这很难,但志愿者的职位比实习职位更容易获得,而且这是一种提高你就业能力的万全之策,尤其是如果你没有经验的话。当然,如果你有更重要的事情要做,比如要供养家庭、抵押贷款等,那么你可能需要做些兼职来补充,以确保你履行自己的职责。

成为一名志愿数据科学家也凸显了你性格中极其重要的技能,如承诺、主动性和强烈的职业道德——在一天结束时,你不会从别人可能赚取 6 位数收入的角色中获得任何经济上的满足——这些都是对潜在雇主有吸引力的非常宝贵的特质。

此外,从我整个八月份的志愿服务经历来看,我认为志愿服务有助于培养很多可转移的技能,例如团队合作、自信、时间管理、适应性、沟通和组织能力。

建立你的关系网

我觉得我好像在每篇帖子里都喋喋不休地说要建立一个社交网络,但是说实话,这真的很重要。

当你缺乏经验时,你认识的人和你知道的东西一样重要。

我一次又一次地提到,我通过我的关系网获得了我的第一份技术工作,我通过我的关系网获得了我的第一个志愿者角色,不管我下一步决定做什么,我确信我的关系网将发挥重要作用。我的关系网一直是推动我在这个领域前进的动力,因此我个人非常重视建立它。

如果你不确定如何在数据科学领域建立自己的关系网,你可能想要阅读关于最重要的数据科学项目的

[## 最重要的数据科学项目

每个数据科学家都必须做的项目

towardsdatascience.com](/the-most-important-data-science-project-458d016ef8a6)

如果你在上大学,在毕业前充分利用你的人脉。如果你已经被雇佣了,问问他们是否知道有人需要帮忙处理他们的数据,因为你想在休息时间提高你的技能。

社交媒体使得建立和维护专业网络变得极其容易。你所要做的就是始终在场——无论是为开源做贡献,还是仅仅参与他人的帖子,或者两者兼而有之。在场!

强调你拥有的技能

我认为 LinkedIn 上做得非常好的人有阿布舍克·塔库尔凯特·斯特拉赫尼苏珊·沃什

专注于你拥有的技能,这并不是说你不应该发展其他技能,但你会觉得你好像一直在追求,因为数据科学是一个很大的领域,总会有你不知道的东西。

使用职位描述作为对比来确定你所拥有的使你可以被雇佣的技能是一个好主意。

最近,我与一位在数据科学领域有丰富经验的非常有用的招聘人员交谈,他问我“你是哪种类型的数据科学家?”。起初,我被难住了,所以他给出了足球中不同类型前锋的比喻;在足球中,有些前锋喜欢持球带球,有些前锋喜欢跑在防守队员后面,有些前锋喜欢把两者结合起来,等等。

了解你是哪种类型的数据科学家,或者你愿意帮助强调你所拥有的技能!

你是一个强调机器学习的数据科学家吗?

你是强调深度学习的数据科学家吗?

你是一个强调数据清理的数据科学家吗?

你关注 NLP 吗?

你是一名强调数据可视化的数据科学家吗?

在我看来,拥有一项你可以强调的技能会让你从其他数据科学中脱颖而出,但这并不是不了解其他领域的理由——从事 NLP 的人可能会从学习计算机视觉中受益。

包裹

工作显然是积累经验的最佳方式,尤其是如果你周围有经验丰富的数据科学家。决定独自出去积累经验绝对是一个更艰难的选择,因此我不建议那些不愿意努力走这条路的人这么做。另一方面,我相信主动获取自己的经验从长远来看会产生更好的回报——如果做得正确的话——这绝对是愿意为自己的发展投入精力的人应该做的。

让我们在 LinkedIn 上继续这个对话…

[## Kurtis Pykes -人工智能作家-走向数据科学| LinkedIn

在世界上最大的职业社区 LinkedIn 上查看 Kurtis Pykes 的个人资料。Kurtis 有一个工作列在他们的…

www.linkedin.com](https://www.linkedin.com/in/kurtispykes/)

你不需要钱来创造一个深度学习环境

原文:https://towardsdatascience.com/you-dont-need-money-to-create-a-deep-learning-environment-2c2d01cee9fb?source=collection_archive---------41-----------------------

也不需要任何硬件,这一切都归功于“云”

照片由 Unsplash 上的 Jp Valery

介绍

如果你想直接开始训练复杂的模型,并成为一名认真的深度学习实践者,你将需要一件东西: 硬件 。具体来说,一个强大的 GPU ( 图形处理单元)就是你想要的 。相信我,我从未见过头脑简单的人只用一个 CPU 训练一个相当复杂的程序。然而,除非你口袋里有很多现金,否则访问哪怕一个 GPU 都不容易,也不便宜,更不用说有足够计算能力或内存来满足你的需求的 GPU 了。让我们严肃点,我们都希望拥有世界上所有的钱来生产多台 RTX 2080 Ti 以满足我们自己的需求。**

预算紧张但又想追求深度学习怎么办?见鬼,如果你现在没有现金,你会怎么办?不要担心:有些地方可以免费开始,在那里你可以开始模型实验,并获得(尽管有限)一个完全成熟的 GPU。如果你的口袋空空如也,却不知道从哪里开始,这里有一些选项供你选择,所有这些都将为你提供一个 Jupyter(笔记本或实验室)环境来开始创建你的项目。

它将如何工作? 一些提供商会将您的定制环境的副本存储到他们的服务器中(也称为 )。其他人总是在每次启动时加载一个“通用”的环境,同时非常方便地安装额外的软件包。

在我们开始之前,这里有一些值得注意的趋势,你一定要记住:

  • 你肯定需要一个互联网连接(废话!)
  • 大多数(如果不是全部)选项通过每周更新配额和/或在长时间单次运行后自动关闭来限制您的 GPU 使用
  • 其中一些将允许您“升级”您的云硬件。

话不多说,这里有一些 GPU 实例的最佳免费选项,可以启动您的深度学习实验!

注意 : 由于下面的所有选择都提供了一个相当不错的 GPU 开始,我将更多地关注每个提供的功能,而不是 GPU 的性能和统计。

图纸空间梯度

提供的 GPU:Nvidia Quadro p 5000、Nvidia Quadro M4000

最大运行时间(每次运行): 6 小时

显著特性:持久存储、基本容器、部署&项目定制/选项、出色的用户体验

在我个人看来, Gradient 的产品似乎是我尝试过的其他产品中最完美的。事实上, Gradient 直到 2019 年 10 月才向其用户提供免费层/选项,当时他们宣布了该服务。考虑到这一点,为什么前一点是这样的就不是巧合了。

Gradient 提供的一些更受欢迎的“基本容器”,每个容器都带有不同的预装物品或配置。

渐变提供了许多独特的功能。首先,它允许用户选择一个预先制作的环境设置(名为“基本容器”),该环境设置预装了一个特定的深度学习框架。比手动安装必要的包或者一开始就处理太多要好得多。

你通过 Paperspace 控制台访问你的笔记本( Paperspace 有除 Gradient 之外的服务),它最近获得了 40% 的性能提升。因此,浏览用户界面和笔记本(一旦加载)是一种非常愉快的体验。有了它的自由层,你一次只能运行一个笔记本,你运行的每个笔记本都有它自己的磁盘空间量,在多次运行后保持不变(尽管不清楚你被限制了多少空间)。此外,您只能在每台笔记本电脑之间共享最多 5 GB 的数据集、模型参数、输出等数据。,称为持久存储

另一个需要注意的细节: 与其替代品不同,Gradient 的基本容器 中的大部分(如果不是全部的话)没有添加 Jupyter 笔记本或 lab 的自己的“味道”,这意味着您将有一个可以说是 更干净和更快的体验 在 Paperspace 控制台上工作。

以下是在 Paperspace 控制台下运行笔记本的样子。

Gradient 还允许你上传自己的模型进行训练,以及通过他们的 CLI 或 GitHub repo 打造新的深度学习项目。

如果你决定升级,Gradient 提供了大量不同价格的云 GPU 供你选择。此外,您还可以使用其他功能,例如取消 6 小时自动关机限制、增加永久存储空间,或者取消 1 台笔记本电脑的限制。

我对在自由层上运行 Gradient 的唯一不满是启动一个笔记本实例需要很长时间,尽管 Paperspace 声称性能有所提高。有时候,渐变告诉我,在打开笔记本之前,我必须等待。我相信这些是强加的限制,把免费用户和升级用户区分开来;尽管如此,对于许多开始尝试深度学习的人来说, Paperspace Gradient 是最好的免费选项之一。

谷歌联合实验室

提供的 GPU:英伟达特斯拉 K80,英伟达特斯拉 T4,英伟达特斯拉 P100 (:如果你很)**

最大运行时间(每次运行): 12 小时

显著特点: Google Drive & GitHub 集成,易于使用&运行,(优越)摩纳哥编辑/Intellisense

在我使用 Paperspace Gradient 之前,Colaboratory 是我在云 GPU 上制作和运行 Jupyter 笔记本的首选。Colab 由谷歌开发,一直是机器/深度学习爱好者和初学者的免费资源。最近他们在今年早些时候发布了 Colab Pro,这给了它的购买者一些便利的额外津贴,我们将在后面讨论。

Colab 比其他公司有更多的优势。例如,在 GPU 上制作笔记本和运行模型非常容易上手。如果你曾经使用过谷歌的工具套件(比如谷歌文档、工作表和幻灯片),那么制作和编辑 Colab 笔记本也有类似的感觉。另一个小但令人惊讶的细节是在笔记本单元中整合了摩纳哥编辑器智能感知。基本上,它与 Visual Studio 代码中使用的编辑器/intellisense 是相同的,我也经常使用和喜欢它(这可能是我偏爱 Colab 的原因)😛).

Colab 和摩纳哥智能感知在行动!

Colab 与 Google Drive 的深度集成,在我看来是一把双刃剑。一方面,你可以把一个数据集放到你的硬盘上,并且可以在你所有的 Colab 笔记本上访问,这很好。然而,这要求没有任何持久存储,这意味着每次运行笔记本的新实例时,你都必须用代码片段从驱动器加载数据和/或文件。此外,事实上,Colab 通常依赖硬盘来永久存储数据,这意味着您正在为您的设置*增加一层复杂性;简单地升级到 Colab Pro 并不意味着你会获得额外的存储空间,反之亦然。*

另一个小的,但值得注意的不便是 Colab 实际上重新映射了几乎所有的标准 Jupyter 键盘布局,似乎没有任何理由。😵**

Colab Pro 声称给用户 优先访问 更高端的 GPU,如 T4 和 P100。优先接入不一定是接入。你可以最终支付价格标签,只获得“普通”K80 GPU,或者你可以成为一名免费用户,幸运地获得一个笔记本电脑实例的更好设备。 无论如何,Colab 本身就是一个坚实的选择,可以通过免费的云 GPU 开始实践深度学习。

Kaggle 笔记本

GPU 提供:英伟达特斯拉 P100

最大运行时间(每次运行/每周): 9 小时/ 30 小时

显著特点:庞大的数据集目录,轻松导入 Kaggle 数据集,强大的社区支持&

Kaggle 字面上无需介绍。Kaggle 本身拥有大量数据集,你可以在那里的笔记本上轻松浏览和使用。Kaggle 成立于 2010 年,目前是谷歌的子公司。与列表中的其他人不同,Kaggle 没有需要付费的更高等级;每个使用 Kaggle 的人都是免费的。

Kaggle 的数据集目录,有一个投票系统。

Kaggle 最引人注目的特征之一是其庞大的数据集目录。它们涉及许多主题,从视频游戏新冠肺炎数据。更好的是:将这些数据导入 Kaggle 上的笔记本非常快速简单。此外,Kaggle 非常适合满足您的竞争优势,因为它允许举办正式的数据科学竞赛,以获得疯狂的奖项——这是一种将深度学习应用于现实世界场景的好方法。

每个使用 Kaggle 笔记本的人都可以使用特斯拉 P100 作为他们的 GPU 。笔记本界面是 Jupyter 笔记本的一种高度定制的风格,以适应 Kaggle 的主题。你可以将你的笔记本分享给 Kaggle 社区,有趣的是,Kaggle 中的大多数实体都有笔记本投票系统。谈到社区,从我的经验来看,这里的人们即使在比赛期间也非常乐于助人。见鬼,Kaggle 本身也提供编程和数据科学教程*,称为“课程”。*

Kaggle 笔记本的标准界面。请注意,黑暗模式是可用的。如果你对标题感兴趣,看这里

然而,我发现 Kaggle 最大的问题是笔记本界面。正如我所说的,Kaggle 给他们的笔记本添加了味道(或主题),以适应他们浅蓝色的材料配色方案。这对我来说是一个问题,因为它导致笔记本变得非常笨重,从长远来看处理起来很痛苦。且不说它破坏了 Jupyter 的一些功能: Shift+Tab 键盘快捷键,调出函数参数和文档,甚至不能正常工作!Kaggle 笔记本也有一个提交“功能”,这比不提交更令人头疼。如果你重新加载你的页面,有可能你所有的工作都回到起点。最后,根据我使用 Kaggle 笔记本的经验,与 Colab 或 Gradient 相比,让笔记本保持运行是不可靠的。

尽管有这些不便,如果你开始修补机器/深度学习模型,并希望有一个好的社区,Kaggle 仍然是一个显而易见的好选择。

结论

如果你现金不足,或者不愿意提前支付开始追求深度学习,有一些选项可以让你获得一个像样的 GPU 来增强你的模型训练等等。如果你本能地跳到这里,这里有一些选择:

  • 图纸空间梯度
  • 谷歌联合实验室
  • Kaggle 笔记本

每一种都有各自的优缺点,但最终,我推荐从 Gradient 开始,因为它的整体抛光,巨大的部署定制,以及一旦需要更好的 GPU 时平滑的升级过程。从那里,我会推荐 Colab 的简单性和智能感知,或者 Kaggle 的社区和数据集。无论你选择哪家提供商,祝你的深度学习&数据科学事业好运!

掌握量子计算不需要成为数学家

原文:https://towardsdatascience.com/you-dont-need-to-be-a-mathematician-to-master-quantum-computing-161026af8878?source=collection_archive---------10-----------------------

作为程序员,你会做得很好

本文是本书的一部分: 用 Python 实践量子机器学习

关于量子计算的科学论文和教科书充满了数学公式。甚至关于量子计算的博客帖子也充斥着数学术语。它从你遇到的第一个概念开始。量子叠加:

作为一个非数学家,这个公式可能已经太多了。如果你不熟悉使用的狄拉克-符号(|ψ⟩),或者如果你不习惯使用向量,那么这样一个公式就像埃及象形文字一样好:

作者弗兰克·齐克特的图片

不要误解我。数学是描述技术概念的好方法。数学是一种简洁而精确的语言。相比之下,我们的自然语言,比如英语,既冗长又不精确。解释一小群数学公式需要一整本书的自然语言。

但是我们大多数人理解自然语言的能力远远强于数学。我们从小就学习母语,并且每天都在练习。我们甚至用我们的自然语言做梦。不过,我不知道有些人是否会做数学梦。对我们大多数人来说,数学充其量是一门外语。

当我们要学习新的东西时,如果我们使用母语,会更容易。理解这个新概念的含义已经够难的了。如果我们用外语学习,那就更难了。如果不是不可能的话。

当然,数学是量子力学和量子计算的母语,如果你愿意的话。但是为什么我们要只用量子计算自己的语言来教它呢?难道我们不应该试着用一种学习者更容易理解的方式来解释它吗?我会说“绝对”!

用学习者的语言教学并不意味着我们不应该看数学。我们应该!但是,当数学的精确性有助于我们解释事物如何运作时,我们就使用数学。

事实上,数学并不是我们唯一的精确语言。我们有像数学公式一样精确的语言。如今,这些语言对许多人来说几乎是自然而然的了。这些语言是编程语言。

我不是指特定编程语言的语法。相反,我指的是几乎所有编程语言共有的一种思维方式。从 Python 到 Java,从 Javascript 到 Ruby,甚至从 C 到 Cobol。所有这些语言都建立在布尔逻辑的基础上。不管使用什么编程语言,程序员都会大量使用布尔逻辑。

最突出的是布尔逻辑出现在条件语句:if then else

如果在 Python 中是 else

条件语句的if部分是纯布尔逻辑。通常,它包含基本的布尔操作符notandor

如果某个陈述是True,那么它的否定就是False。反之,如果一个语句是False,那么它的否定就是True。如果一个语句由两部分PQ组成,那么如果PTrueQTrue,那么P and Q只是True。但是如果PQTrueP or QTrue

下面是 Python 中布尔逻辑的三个例子。

Python 中的布尔逻辑

not P is False
P and Q is False
P or Q is True
P and not Q is True

虽然 Python 使用这些确切的关键字,但在数学中,符号代表这些运算符:

  • 是指not
  • ∧表示and
  • ∨表示or

如果你不是数学家,这些符号和你在量子机器学习过程中遇到的所有其他符号可能看起来很神秘。但是,虽然用 Python 或 math 描述概念时,概念的表示可能不同,但概念本身是相同的。

理解布尔逻辑不需要成为数学家。实际上,你也不需要成为一名程序员,因为我们甚至可以通过真值表来描述布尔逻辑。

我们有两个变量,PQ。每个变量要么为真(T),要么为假(F)。根据它们的值的组合,我们可以推导出任何布尔语句的值。下图描述了PQnot Pnot Qnot P and not Qnot (not P and not Q)P or Q的真值表。

作者弗兰克·齐克特的图片

这个真值表揭示了P or Q等同于not (not P and not Q)。这种逻辑等价告诉我们,我们甚至不需要运算符or。我们可以用not (not P and not Q)来代替它。

但是P or Q简明易懂。

“如果我们的编程语言中没有 *or* 运算符会怎样?

精明的程序员会编写自己的操作符。

或的重新实现

P | Q | P or Q
--------------
T | T | True
T | F | True
F | T | True
F | F | False

这就是编程的意义所在。程序员编写产生某种行为的函数。他们使用并组合这些函数来创建更多的函数,表现出更复杂的行为。他们编写的整个程序可以归结为一组巧妙组合的函数。程序员用他们的编译器(或解释器)将高级函数翻译成非常基本的布尔逻辑。并且这种基本的布尔逻辑可以使用电气开关来执行。开关和它们的组合被称为门。当我们连接门时,它们形成一个电路。

在不连续的时间间隔内,计算机通过电路发送一个电脉冲。如果我们在适当的时间接收到一个电脉冲,我们将其解释为1(真)。如果我们没有接收到脉冲,我们将其解释为0(假)。

尽管有这个名字,电路并不是循环的。它们是线性的,从左向右读取。让我们来看一个例子,它对应于我们之前看到的布尔函数

下图描绘了not (not P and not Q)的电路图。该电路从左侧接收输入,并将其输出到右侧。

作者弗兰克·齐克特的图片

这种门和电路是任何现代计算机的组成部分。这包括量子计算机。虽然量子力学的世界不同,但量子计算的世界惊人地相似。

不要让你自己被所有的数学公式弄得眼花缭乱。它们是概念的代表。不多也不少。

让我们回到我们的介绍性公式:

这是量子态|ψ⟩(“psi”)的数学符号。虽然经典比特的状态是布尔型的(或者0表示假,或者1表示真),但是量子比特(量子比特)的状态是由α和β加权的量子态|0⟩和|1⟩的叠加。

在这种叠加态下,量子系统既不是0也不是1,除非你去测量。只有当你测量量子位时,状态才会坍缩到01。两个权重(α2)和(β2)的平方表示测量01的概率。α越大,测量到0的概率越高。相应地,β越大,测量到1的概率越高。

这个公式说明了更多的东西。它说量子态是两个重量[α β]的矢量。

矢量是一个有大小和方向的地理对象。如果在坐标系中绘制,向量从中心开始,到向量中数字指定的点结束。

作者弗兰克·齐克特的图片

在 Python 中,向量是一个数组。因此,一个量子位的状态就是数组[alpha, beta]。并且,alphabeta是数值变量。量子态是两个数的数组。

但是由两个数字组成的数组是比布尔值更复杂的数据类型。布尔值为TrueFalse。您可以用简单的运算符转换布尔值,例如notandor。您可以推理真值表中布尔值的转换。

但是你如何转换两个数字的数组呢?你如何解释这种转变?

显而易见的答案是数学。但这不是唯一可能的答案。让我们用 Python 来做吧。

反转量子位状态

----------- Reversed states: ----------
psi: [0.50, 0.87]  result: [0.87, 0.50]
|0>: [1.00, 0.00]  result: [0.00, 1.00]
|1>: [0.00, 1.00]  result: [1.00, 0.00]

我们从三个状态的初始化开始。每个状态都是由两个数字组成的数组。状态psi的值为 1/2 和√3/2(第 4 行)。在这种状态下测量0的概率是(1/2)2=1/4=0.25.测量的概率`1`是(√3/2)2=3/4=0.75.

状态always_0具有值10。在这种状态下测量0的概率是 1^2=1(第 5 行)。测量的概率1是 0^2=0.当我们在这种状态下测量一个量子比特时,我们总是测量为0。状态always_1是各自的对立面。我们一直测量为1(第 6 行)。

接下来,我们创建一个便利函数transform(第 8-9 行)。我告诉过你编写函数使事情变得简单是编程的全部内容吗?这是一个例子。该函数采用量子态的名称(要显示的任意字符串)、state和函数ftransform将初始状态和应用f功能后的状态打印到控制台。

最后,我们创建一个函数reverse_state,我们可以将它输入到transform(第 11-12 行)。reverse_state调用 Python 默认的reversed函数,以相反的顺序返回相同长度的数组。

在输出中,我们可以看到状态数组中的数字交换了位置。这样,测量01的概率分别切换。反转的psi0.75机会测量00.25机会测量1。反转后的always_0与原来的always_1相似。

这只是三种可能的状态。在一种真值表中列出所有可能的状态是不可能的。但是我认为reverse_state函数的行为非常清楚。这是量子计算中 X 门的行为。这是量子态的基本变换之一。

让我们在实践中看看这个门。我们用的是 IBM 的量子计算 SDK Qiskit

测量的量子位

作者弗兰克·齐克特的图片

Qiskit 的基本单元是量子电路。量子电路是量子计算的模型。这个项目,如果你愿意的话。我们的电路由一个量子位组成(第 5 行)。

我们用状态psi(第 8 行)初始化我们的量子位,并对其应用 X-gate(第 11 行)。

Qiskit 提供了Aer包(我们在第 1 行导入的包)。它为模拟量子电路提供了不同的后端。最常见的后端是statevector_simulator(第 14 行)。

execute-函数(也是我们在第 1 行导入的)以指定的backend运行我们的量子电路(qc)。它返回一个job-对象,该对象有一个有用的方法job.result()(第 17 行)。一旦我们的程序完成它,就会返回result对象。

Qiskit 使用 Matplotlib 来提供有用的可视化。简单的直方图就可以了。result对象提供了get_counts方法来获取被执行电路的直方图数据(第 18 行)。

方法plot_histogram返回一个 Jupyter 自动绘制的 Matplotlib 图形(第 19 行)。

我们看到我们有 75%的机会观察到值0,有 25%的机会观察到值1。与初始状态完全相反。

你可以用不同的初始状态运行电路来更好的感受这个门。

一般来说,量子电路与经典电路并无不同。我们可以用图表来表示它们。 QiskitQuantumCircuit类为我们提供了完成这项工作的draw方法。

qc.draw('mpl')

作者弗兰克·齐克特的图片

我们可以看到我们唯一的量子位(q),它与数组[0.5, 0.866]的初始化,以及应用的 X 门。

即使不是数学家,你也已经完成了掌握量子计算的第一步。从概念上理解量子门是经典电路门的量子对等物并不依赖于数学。简单英语和一点点 Python 的结合非常合适。对许多人来说,这种结合更容易实现。

但是,数学仍然是量子计算的重中之重。如果你想对概念有更深的理解,你迟早会遇到数学公式。正如我所说,数学是描述技术概念的一个很好的方式。

让我们来看看 X-gate 的底层数学。别担心,我不指望你成为数学家。尽管如此,对代数(即对数学符号和操作它们的规则的研究)的一点喜爱并没有坏处。

到目前为止,我们使用的是 Python 的内置函数reversed。虽然这很方便,但我们看不出它在内部是如何工作的。让我们使用另一个函数。一个自制函数。

自制反向功能

reversed psi: [0.87, 0.50]

我们定义一个函数adjust_weight(第 1 行)。它需要一个量子stateweights。两者都是包含两项的数组。它将位置0处的值和位置1处的值相乘。它返回这两个乘积的和(第 2 行)。

我们可以用这个功能来反转psi。对于返回单个数字的adjust_weight,我们调用它两次来获得两个项目的数组(第 5 行和第 6 行)。在本例中,我们没有显式创建数组,而是直接将这些值打印到控制台(第 4 行)。

在这两个调用中,我们提供原始的psi作为state参数。在第一次调用中,其结果是反向 psi 的第一个数字,我们提供[0,1]作为weights。这意味着,我们得到了0乘以第一个数字psi1乘以第二个数字psi的和。这个和是原psi的第二个数。

在第二个调用中,其结果是反向 psi 的第二个数字,我们提供[1,0]作为weights。这是第一个数字psi1倍和第二个数字psi0倍。这等于原psi的第一个数字。

有了这些权重,我们有效地交换了psi的数字位置。

在数学中,这是一个矩阵乘法。矩阵 M 和向量 υ 相乘的一般公式为:

ab 是我们用来计算结果向量第一个数的权重。 cd 分别是第二个数字的权重。

数学上,X 门量子算符是矩阵:

让我们将该操作符应用于我们的三个示例性状态:

逆转|0⟩在|1⟩:的结果

逆转|1⟩在|0⟩:的结果

并且,在|ψ⟩应用矩阵也会导致它的反转:

在经典计算中,我们有一小组布尔运算符,它们的行为可以很容易地用真值表来表示。但是在量子计算中,矩阵表示称为门的操作符。我们可以应用无数种可能的矩阵。数学是描述这些运算符的简洁而精确的方法。但是你不需要成为数学家来使用这些运算。

当然,在应用时,最好能理解门的基本数学原理。但更重要的是,你需要了解大门是做什么的。如果你知道 X-gate 是做什么的,你就不需要一直应付数学。

本帖是本书的一部分: 用 Python 动手做量子机器学习

在这里免费获得前三章。

在人工智能领域工作,你不需要成为一名数据科学家

原文:https://towardsdatascience.com/you-dont-need-to-become-a-data-scientist-to-work-in-ai-ce76bcc31444?source=collection_archive---------58-----------------------

我经常被问到这个问题,我如何进入人工智能?

这里有一种方法。

许多人希望从事人工智能工作,大多数人在开始他们的旅程时都渴望成为一名数据科学家。显然是本世纪最性感的工作。他们做的第一件事是参加 Coursera 课程,然后开始参加 Kaggle 竞赛,接着试图找到一份数据科学家的工作。如果这是你,你就是众多中的一个,很难鹤立鸡群。

Ashkan ForouzaniUnsplash 上拍摄

虽然通过 Coursera 课程了解人工智能并不是一个坏主意——你需要自学并成为懂人工智能的人——数据科学只是工作的 5%,许多其他角色已经存在或在未来将变得存在。

所以你还能做什么?

调查你自己的工作或部门

闯入 AI 的一个方法是看你自己的工作。也许你的全部或部分工作可以被人工智能增强或取代。您是否在处理数据,这些数据是否用于决策?甚至像对新客户进行分类这样的小决策也可以通过机器学习来增强。确定这些决策点,并在您的公司内启动一个人工智能项目。你将成为数据科学团队理想的业务利益相关者。

假设你从事营销工作。你可以开始考虑你收集的不同客户的数据。你是如何决定何时联系谁的?你已经在收集谁对你的营销努力有反应的数据了吗?您可以开始构建数据和业务案例的基础。

调查你所在的行业或领域

看看那些已经从事 AI 工作,需要你的技能或行业专业知识的公司。行业和领域知识是人工智能项目成功的关键。在商业方面,人工智能素养有很大的差距,当你在基础知识方面自学完,并能为公司带来所需的领域或行业技能时,你将是一笔巨大的财富。

让我们假设你在能源行业工作。太好了,人工智能在能源领域的应用潜力很大。如果不是现在,许多公司将在未来几年内开始研究人工智能。收集能源领域、预测性维护、能源交易等不同的潜在使用案例。努力理解这些用例,你将成为你自己或竞争对手公司的一笔巨大财富!

这个故事的关键是,坚持你知道的和擅长的,从你擅长的地方增长你的技能。

从业务方面搭建桥梁,这是你成功的地方。

如果你想学习理解机器学习,请这样做。但是没必要逼自己成为数据科学家。事实上,我真的相信在更长远的未来,人工智能中的许多角色将是非数据科学角色。也许这只是需要一些耐心来转换到正确的角色,但这并不意味着现在是开始为此做准备的好时机。

关于我:我是一名分析顾问,也是当地一所商学院“人工智能管理”研究的主任。我的使命是帮助组织利用人工智能创造商业价值,并创造一个数据科学家可以茁壮成长的环境。 在这里报名我的快讯。

你知道 Excel。该学 SQL 了。

原文:https://towardsdatascience.com/you-know-excel-time-to-learn-sql-e77a2b5c8fbb?source=collection_archive---------6-----------------------

奥琳卡·谢尔坚科摄于佩克斯

9 个核心 excel 功能转化为 SQL

随着世界变得越来越由数据驱动,越来越多的专业人士正在更密切地与数据打交道。

在许多情况下,对这个领域的第一次介绍来自 Microsoft Excel 的永恒形式。Vlookups、数据透视表、sumifs 也许给喜欢冒险的人来点 VBA。

但是,就像初露头角的数据分析师、爱好者和探索者开始了解 excel 的神奇和优点一样,他们也开始努力克服它的局限性。

如果你遇到过类似“正在计算:(4 个处理器))”的消息,你可能知道我的意思。对于大型数据集,Excel 会变得相当慢。

Excel 还带来了难以避免的再现性问题,即使对于最细心的用户来说也是如此。这个过程听起来可能很熟悉:接收数据→做一些操作(vlookup、filter、pivot 等。)→接收需要相同处理的更新数据。冲洗,重复。多痛苦啊。

数据库技术有助于减轻这些缺点,因为它将数据从查询和操作中分离出来:

作者创建的图像。由像素完美制作的图标来自www.flaticon.com

SQL 是用于与数据库通信的主要语言,在熟悉 excel 之后学习它是一项很好的技能。

在这篇文章中,我将把一些主要的 excel 用例及函数翻译成 SQL,以帮助学习过程变得更加容易和有形。

1.挑选

在 excel 中:如前所述,数据存储和操作发生在 Excel 的同一个地方。因此,选择数据就像突出显示我们想要的单元格一样简单。

在 SQL 中:我们编写一个查询来从数据库表中“选择”数据。每个表格就像 excel 中的一个数据块,它包含行、列和数据单元格。

对于一个基本的 select 查询,我们需要指定要查询的表的名称和要从该表返回的列的名称。

在 SQL 中,星号表示“所有列”所以我们也可以运行:

select * from mytable;

如果我们大声读出来,我们会说“从我的表中选择恒星”。

2.过滤器

在 Excel 中:我们可以通过选择数据功能区中的过滤器图标,然后使用每列旁边的下拉菜单来过滤数据中的行。

在 SQL: 中,我们在查询中添加了一个“where 子句”,并指定了一个我们想要应用的条件:

与 excel 类似,我们有几个过滤条件选项:

过滤到特定值:

select * from mytable where **column1 = 10**;

用算术运算符过滤:

select * from mytable where **column1 < 10**;

用“in”运算符过滤:

select * from mytable where **column1 in (1,2,3)**;

多条件过滤:

select * from mytable where **column1 > 2 or column2 = "APPROVED";**

我们还可以使用“与/或”逻辑将多个条件嵌套在一起。我们只需要确保遵循操作符优先级并在必要的地方使用括号。

3.分类

在 Excel 中:我们使用数据功能区中的排序图标来应用排序条件。

在 SQL 中:我们在查询中添加了一个“order by”子句,以便按照我们期望的排序顺序返回数据:

请注意,我们可以按照提供的顺序对多个列进行排序。

默认情况下,列按升序排序(最小值优先)。为了改变这一点,我们可以在想要降序排序的每一列后面添加“desc”关键字。

4.条件句(If 语句)

在 Excel 中:我们使用一个“if 语句”。如果我们需要一组以上的条件,我们使用“嵌套 If 语句”

在 SQL 中:我们使用一个“case when”语句。

下面是基本语法:

每个“when/then”对指定一个条件和一个条件为真时返回的值。然后我们添加一个可选的“else”语句来捕捉任何遗漏的条件。最后,我们将结果列命名为。

这比 Excel 可读性强得多,Excel 需要大量的嵌套括号来创建复杂的条件。

5.删除重复项

在 Excel 中:我们选择数据功能区下的“删除重复”选项。然后从工作表中删除重复的值。

在 SQL 中:我们在 select 语句中使用“distinct”关键字:

*select distinct column1, column2 from mytable;*

上面的查询将返回 column1 和 column2 的所有唯一组合,而不更改基础数据。

6.Vlookup /索引匹配

在 Excel 中: Vlookup 和 Index + Match 是将一个数据表中的数据合并到另一个数据表中的两种方法。

在 SQL 中:我们利用了所谓的“连接”——一种基于公共数据点将两个表中的数据组合起来的方法。

下面是基本语法:

该连接有三个主要部分。

首先,我们指定要从每个表中返回哪些列。为了表明我们希望每一列来自哪个表,我们使用以下约定:表名+句点+列名。

第二个,我们指定想要使用的两个表和连接类型。我不会详细介绍不同类型的连接,但如果您想了解更多信息,我建议查看我的连接数据指南(如下)。

第三,我们指出我们想要“连接”的列(两个表之间有共性的数据点)。这就像你传递给 Vlookup 的第一个参数。

* [## 连接数据的初学者指南

左接合。内部联接。外部联接。啊?

towardsdatascience.com](/a-beginners-guide-to-joining-data-935c8e579fb7)

7.聚合(总和、计数、平均值等。)

在 Excel 中:我们将函数添加到一个空单元格中,然后传入我们想要聚合的单元格范围。

在 SQL 中:我们拥有与 excel 相似的聚合函数。我们将列名传递给这些函数,并在 select 子句中调用它们:

select sum(column1), count(column2), avg(column3) from mytable;

有多种功能可供我们执行,其中许多功能与 excel 重叠。

8.条件聚合(sumif、countif、averageif)

在 Excel 中:像“sumif”这样的条件聚合函数允许我们仅对指定条件为真的行执行聚合。

在 SQL 中:我们可以在聚合函数中嵌套一个“case when”。

例如:

select sum(case when column1 > 10 then column2 else 0 end) 
from mytable1;

在这段代码中,首先执行“case when ”,只有当 column1 大于 10 时才返回 column2。然后我们对结果值求和。如果列 1 > 10,这与对列 2 求和是一样的。

也有一些 SQL 版本允许以下语法:

select sum(column2) filter (where column1 > 10)
from mytable1;

9.数据透视表

在 Excel 中:我们可以使用透视表进行多维度的聚合。

在 SQL 中:我们使用一个“groupby”语句。

“groupby”将我们的数据分成不同的组,然后对每个组进行聚合。

例如:

这与将“列 1”和“列 2”添加到数据透视表的行部分,然后对不包含任何缺失值的列进行计数是一样的。

Excel 数据透视表也有一个“列”部分。为了在 SQL 中复制这一点,我们可以在 groupby 中使用条件聚合:

select column1, 
count(case when column2 = “group1” then column2 end) as group1count,
count(case when column2 = “group2” then column2 end) as group2count
from mytable1
group by 1;

结束语

一开始,从电子表格应用程序过渡到“编写代码”会让人感到畏惧。但是如果你有处理数据的经验,那么 SQL 实际上并不比 excel 难,只是有一点不同。

最好的学习方法是获取一些数据并开始练习。编码快乐!

P.S. →如果你想了解更多关于 SQL、Python、数据科学的知识,订阅我的 免费邮件列表 *

你可能不需要气流…然而

原文:https://towardsdatascience.com/you-may-not-need-airflow-yet-a95fec16f07?source=collection_archive---------10-----------------------

TL;DR:气流强劲而灵活,但是很复杂。如果您刚刚开始计划数据任务,您可能希望尝试更定制的解决方案:

使用 4 种不同的服务怎么可能比只使用一种更容易?

Apache Airflow 是数据团队最流行的工作流管理工具之一。全世界有数百家公司用它来安排各种工作。这是一个完全免费的开源项目,通过 python 构建的基础设施提供了惊人的灵活性。

阿帕奇气流

我使用过(有时设置过)各种规模的 Airflow 实例:从优步定制的基于 Airflow 的 Piper 到侧面项目的小型实例,有一个共同的主题:项目变得复杂、快速!Airflow 需要以一种稳定的和生产就绪的方式部署,所有任务都是在 Python 中自定义的,并且在构建任务时有许多注意事项要记住。对于一个不太懂技术的用户来说,仅仅是为了安排一些简单的任务,Airflow 就可能是一个压倒性的系统。

尽管使用一个工具来满足所有不同的计划需求可能很诱人,但这并不总是您的最佳选择。每次出现新的用例时,您最终都会构建定制的解决方案。相反,你应该为你要完成的工作使用最好的工具。在每个用例的设置和维护过程中节省的时间非常值得为您的数据堆栈添加一些工具。

Imgflip

在这篇文章中,我将概述气流的几个用例以及每个用例的替代方案。

声明:本人是booklet . ai创始人之一。

从源提取原始数据到数据仓库

数据团队需要一些东西来完成他们的工作…数据!很多时候,这些不同来源的数据有多个不同的内部和外部来源。要将所有这些数据集中到一个地方,团队需要从所有这些来源提取这些数据,并将它们插入一个位置。这通常是某种数据仓库。

缝合

缝合

对于这一步,全球有许多可靠的工具正在使用。他们定期从一组给定的系统中提取数据,并将结果直接发送到数据仓库。这些系统处理大多数错误,并保持事情顺利运行。管理多个复杂的集成可能会成为维护的噩梦,因此这些工具可以节省大量时间。幸运的是,有一个避免噩梦的选择:

Stitch coins 将自己定位为“一个云优先、开源的快速移动数据平台。”您可以快速连接到数据库和第三方工具,并将数据发送到多个不同的数据仓库。最好的部分:前 500 万行是免费的!Stitch 也可以用几个开源框架来扩展。

在数据仓库中转换数据

一旦数据被加载到数据仓库中,它通常是一团乱麻!每个数据源都有不同的结构,每个数据集都可能用不同的标识符以不同的方式编制索引。为了理解这种混乱,团队需要将所有这些数据转换和连接成一种更好、更简洁、更易于使用的形式。大多数逻辑将直接发生在数据仓库中。

DBT

DBT

将所有这些数据集组合成一种企业可以实际使用的形式的过程可能是一项单调乏味的任务。它已经成为一个如此复杂的领域,以至于分析工程师的特殊角色已经从中脱颖而出。这些是整个行业中常见的一系列问题,现在已经出现了一种工具来专门解决这些问题:

DBT 认为自己是“你的整个分析工程工作流程”,我同意。只需了解 SQL,您就可以快速构建将被完全管理的多个复杂的数据转换作业层。版本控制、测试、文档等等都是为你管理的!云托管版本免费使用。

在数据仓库之外转换数据

有时团队还需要在数据仓库之外转换数据。转换逻辑不能完全在 SQL 内操作怎么办?如果团队需要训练一个机器学习模型怎么办?这些任务可能直接从数据仓库中提取数据,但是实际的任务需要在不同的系统中运行,比如 python。

数据砖块

数据块

大多数基于 python 的定制脚本通常从 Jupyter 笔记本开始。您导入一些包,导入或提取数据,运行一些函数,最后将数据推到其他地方。有时需要更复杂的生产规模的流程,但这种情况很少见。如果您只需要一种简单的方式来运行和安排 python 笔记本,有一个很好的选择:

Databricks 由 Spark 最初的创始人创建。它的主要出名之处是非常容易地旋转火花簇,但它也有很好的笔记本功能。他们提供易于使用的 Python 笔记本,你可以像谷歌文档一样在笔记本中进行协作。一旦开发出适合您的脚本,您就可以安排该笔记本完全在平台内运行。这是一个很好的方法,不用担心代码在哪里运行,并且有一个简单的方法来调度这些任务。他们有一个免费的社区版。

批量评分机器学习模型

如果团队已经建立了一个机器学习模型,该模型的结果应该被发送到一个可以实际帮助业务的地方。这些任务通常涉及连接到现有的机器学习模型,然后将该模型的结果发送到另一个工具,如销售或营销工具。要让一个系统启动并运行,并在正确的时间推出正确的模型结果,这可能是一项极其乏味的任务。

Booklet.ai

Booklet.ai

建立一个机器学习模型已经够难的了,不应该再花 2 个月的时间来定制编码,以将该模型连接到企业可以从中发现价值的地方。这项工作通常需要与第三方系统进行痛苦的集成,更不用说所需的生产级基础设施工作了!幸运的是,有一个解决方案可以为您处理这些任务:

Booklet.ai 连接到现有的 ML 模型,然后允许您快速设置一些东西:一个与非技术用户共享模型的演示,一个简单的 API 端点连接,以及一组连接输入和输出的集成。您可以轻松地从数据仓库设置一个输入查询来对模型进行评分,然后将这些结果发送到您的业务伙伴可能会使用的各种工具。您可以查看将结果发送到对讲机 领先评分模型的演示。 您可以请求访问 Booklet.ai beta ,在那里您的第一个模型将是免费的。

照片由迈克·本纳Unsplash 上拍摄

数据战略在数字化转型过程中的作用

原文:https://towardsdatascience.com/you-need-a-data-strategy-to-steer-your-digital-transformation-journey-7e87484a106b?source=collection_archive---------30-----------------------

丹尼尔·泽维尔摄于佩克斯

数据驱动的组织获得新客户的可能性是其他组织的 23 倍

我住在镇中心,这意味着周六晚上不是很安静(是的,过去式)。所以,上周末我们讨论了我们是多么想念那些喧嚣——来自俱乐部的嗡嗡声,人们在酒吧里跳来跳去,唱歌(或尖叫)和跳舞——人们玩得开心的声音。这让我想知道世界各地的俱乐部是如何适应这些变化的?我的研究让我找到了中国一家名为JD.com的电子商务公司,一些酒类品牌与该公司接洽,他们与一家名为太合音乐集团的音乐公司合作,提供虚拟的夜店体验。他们把音乐直接传到客厅,在网上卖酒并送货上门。

其中一个酒类品牌报告称,与前一天相比,进口白酒销量增长了 70%,威士忌销量增长了 8 倍。即使在中国解除封锁后,这些利润也激励 JD.com 继续经营虚拟娱乐。他们拥有巨大的电子商务基础设施,吸引了酒类品牌与他们合作,他们一起创造了一个新的业务,在这样的低迷时期赚钱。

故事的关键是——为了快速适应变化,创造新的商业模式,在吸引新客户的同时为现有客户提供价值,你需要数字化装备。数字化转型不再是从线下转移到线上或只是升级技术。它是关于利用现代技术平台建立一个灵活、高效、安全和知情的业务,与客户相连,不局限于一个价值链,可以随着时代的变化快速发展。在这个信息时代,仅仅升级产品或工具是不够的。您的数字化转型应该以强大的数据战略为后盾。那么,为什么数据战略在数字化转型中至关重要?让我解释一下。

您需要数据来改善客户体验

数据有助于您了解客户行为,以及他们喜欢如何使用您的产品或服务。它让你更接近你的客户,帮助你调整你的产品以适应他们的需求,并对变化做出更快的反应(像新冠肺炎一样)。如果你仍然依靠直觉来了解客户的脉搏,你注定会在竞争中失败,就像《T2》大片《T3》一样。

你需要数据来照顾你的人

未来的员工不在办公室,远程工作已经成为主流。在某些行业,它提高了员工的满意度和生产率。它让你可以灵活地从世界各地招聘人才,利用全球人才库。当你的员工不在办公室时,能够管理他们可能是一个挑战,因为互动变得虚拟、短暂和稀薄。数据可以帮助你了解你的员工,就像它帮助你了解你的客户一样。它可以帮助你创造一个更好的工作文化,为个人量身定制发展计划,还可以在你的组织内发现未来的领导者。

您需要数据来优化业务流程

数据可以让您了解流程的表现如何,是否随着时间的推移有所改进,是否足够强大,能够在不可预见的情况下生存。数据可以将流程与人员联系起来,确定影响变革的关键因素,并将见解转化为行动。

你需要数据来发现新的价值链

当你了解客户行为时,它会打开新的机会渠道。预测您的客户需求可以帮助您创造新的价值主张,发现潜在客户并创造额外收入。随着时间的推移,对数据进行管理会产生数据储备,这些数据储备可以被货币化,从而增加新的收入来源。

你需要数据来推动创新

人工智能、增强现实和数字孪生等技术为所有行业的创新提供了巨大的机会。然而,如果你不收集和探索与你的业务甚至其他行业相关的数据,你将无法发现可能引领你走向下一个重大机遇的微弱信号。

“世界上大多数人会通过猜测或凭直觉来做决定。他们要么幸运,要么错误。”——苏海尔多什

转变为数据驱动型组织需要什么?

首先,您需要一个与您的业务流程、人员和技术相一致的战略。其次,你的员工必须意识到数据治理的重要性,然后才能跳到 AI 这样的冷端。我的同事 Brian Poore 在本文中解释了原因:数据知识:数据驱动型组织的基础。您需要采用能够提供现代数据平台的正确技术,这些平台应该与您现有的技术体系很好地集成。阅读更多关于为什么你的组织应该更新其数据平台的信息。

如果配备了正确的数据战略,以强大的数据治理为指导,并通过可扩展、安全和一致的技术平台来帮助您监控流程、跟踪成本并最大化投资回报,数据驱动的数字化转型将会成功。

最后的想法

数据在您的组织中无处不在,它将人与流程联系起来,如果管理有效,它将把您的业务与新的机会联系起来。数据驱动的组织更有可能成功,因为它实现了高运营效率,能够快速适应变化,并更快地满足客户需求。因此,如果你正在投资数字化转型,请确保你有一个数据战略来支持它。

现在你可能会说(指的是 JD.com 的故事),如果我们没有基线数据,70%的销售额增长不是一个好的指标。你是对的,但关键是,当不确定性袭来时,酒类品牌没有联系大俱乐部来运作这场秀,他们去了一家电子商务公司,这家公司有数字能力,有数据来支持这样的价值链。

告诉我,你认为虚拟俱乐部是个好主意吗?你会选择虚拟的夜总会,为自己省下拥挤的舞池、长长的队伍和穿错鞋不准入内的保镖吗?
点击阅读更多关于京东的故事

玩电脑视觉永远不会无聊

原文:https://towardsdatascience.com/you-never-get-bored-playing-with-computer-vision-cb93cbd3274a?source=collection_archive---------42-----------------------

…以及如何让 Dino 独立运行而不考虑平台

在本文中,您将学习如何使用 Python 和 MSS 以合适的帧速率录制屏幕。如何用 OpenCV 进行模板匹配和边缘检测?如果你愿意,你可以让你的机器玩游戏。

来源:作者

介绍

我喜欢自动化,有一次我读了由马库斯·雷内·Pae写的关于另一个 python 库 PyAutoGUI评论。这个库允许你通过操作系统输入来操作,比如发出鼠标或键盘事件。Markus 提出的挑战之一是自动化 Google Dino 游戏。我很好奇 PyAutoGUI 是否允许我实时捕捉监视器,找到恐龙,并在需要时进行跳跃?我决定尝试一下,不要拘泥于浏览器实现,所以 Dino 应该运行,不管它是浏览器还是独立的应用程序。在本文的后面,您将发现 PyAutoGUI 在哪些任务中工作得很好,在哪些任务中最好使用其他技术。

我最后用了哪些库来让 Dino 单独运行

简而言之什么是 CV(计算机视觉)和 OpenCV

如今,计算机视觉是一个非常热门的话题。它被用在许多地方,在这些地方,图像或视频应该被处理以备将来使用。例如 Face ID:在了解这是你之前,首先它试图检测一张脸,然后处理图片并要求 ML(机器学习)模型来分类这是不是你。可能是其他人正在尝试解锁您的手机。目前最流行的 CV 库之一是 OpenCV 。根据官方网站:该库拥有超过 2500 种优化算法,其中包括一套全面的经典和最先进的计算机视觉和机器学习算法。OpenCV 是用 C++写的,可以在所有平台上使用,使用 C++、Python 等写的 API。如果你有一个遵循 CUDAOpenCL 标准的 GPU,它会加速你的 GPU 上的计算。

我用 PyAutoGUI 实现游戏自动化的尝试

没有互联网连接的 Chrome 浏览器截图

首先,我实现了一个游戏循环,并试图只使用 PyAutoGUI 来捕捉屏幕,匹配一个模板(在我的情况下,它是一个恐龙),从技术上来说,这是可行的,但是……PyAutoGUI 中的截图并不是为了实时捕捉。所以我得到了两帧之间大约一秒的延迟。因为 Dino 运行速度超过每秒 400 像素,所以太多了。当我的程序按下“跳转”键时,游戏就结束了。我决定指定每次捕获哪个区域来减少延迟,得到的延迟大约是 0.4 秒。更好,但仍然不够。我明白我需要一些别的东西来执行物体检测,所有的计算都应该以至少 30 帧/秒的速度进行。这意味着我需要在 0.03 秒内完成我的计算和所有的副作用。

MSS 跳入游戏

一、什么是 MSS?
根据 docs MSS 是一个使用 ctypes 的纯 python 中的超快速跨平台多截图模块。该 API 易于使用,已经集成了 Numpy 和 OpenCV。我为什么选择 MSS?基本上,如果你想捕捉整个屏幕,MSS 会做得很快,比其他库快得多。如果你需要把你的屏幕投射到某个地方,我会选择这个库。

在尝试了不同的可以提供截图功能的库之后,我了解到它们中的大多数都使用了相同的方法。每次抓取屏幕时,都会重新建立与屏幕资源的“连接”。到目前为止,我没有深入研究这一部分,我只能说我们在重建上花了太多时间。同时,MSS 针对任何操作系统进行了优化。当你抓取一个屏幕时,它使用 XGetImage 方法从已经创建的“连接”到你的屏幕资源这意味着,你可以用with语句初始化 MSS 实例,让你的游戏在那里循环,你会得到更好的性能。

with mss.mss() as sct:
  while True:
    screen = sct.grab(monitor)
    process_image(screen)
    if trigger_to_leave:
      break

是的,就这么简单。这样你抓取一个屏幕的速度可以提高几百倍。在这里,我实现了以 100 帧/秒的速度获取截图,我甚至添加了一个睡眠来减少多余的计算。接下来,我们需要处理图像,分析所有块,并在需要时“跳转”。
我把这个分成两部分:

  1. 在屏幕上找到一只恐龙,并探测一个有“障碍物”的区域
  2. 使用上一步得到的区域,循环抓取,计算到障碍物的距离,并计算速度。

让我们回顾一下这些步骤。

在屏幕上找到一只恐龙,并探测一个有“障碍物”的区域

这一部分在我的 GitHub 上的一个 Jupyter 笔记本中进行了可视化的呈现:https://GitHub . com/dper Yel/run-dino-run/blob/master/search . ipynb

此时我广泛使用 OpenCV 进行图像处理、模板匹配、边缘检测。首先,我消除了图像中的颜色通道,并且通过用cv2.cvtColot(img, cv2.COLOR_BRG2GRAY)变换图像只使用了一个通道。然后我需要消除白天和黑夜的区别。

白天从左边,夜晚从右边

对此我们能做些什么?事实上,有许多方法可以接近,我决定使用一个 Canny 算法来检测边缘,并使用最大和最小阈值的极值。它让我在白天和晚上都能得到几乎相同的画面。

白天从左边,夜晚从右边

当然,如果一幅图像有很多噪声,我需要先模糊它,但在这种特殊情况下,只需找到边缘就足够了。而且我擅长用模板匹配来找迪诺。唯一的事情是模板不会在比赛中缩放。我们的恐龙模板应该取自游戏将要运行的屏幕。或者您可以扩展此功能,并使用模板缩放来执行模板匹配。

通过使用cv2.matchTemplate我得到了匹配的位置。最初你会得到一堆位置,因为当 OpenCV 在源图像上滑动模板时,它会比较这个区域,然后你会得到一个匹配的值。匹配值表示像素匹配的精确程度。在我的例子中,我只寻找 1 个恐龙,这意味着我可以取最高值,并使用映射到该值的位置。

match_res = cv2.matchTemplate(canny_night, dino_bordered_template, cv2.TM_CCOEFF_NORMED)
_, max_val, _, max_loc = cv2.minMaxLoc(match_res)

我的 max_val 平均为 0.81,这意味着我的模板在图像上的匹配率为 81%。好到可以继续。

知道了恐龙的位置,我们就可以突出显示障碍物出现的区域。我选择没有其他噪音只有障碍物可见的部分。需要对仙人掌和鸟类等障碍物进行分组。

蓝色矩形代表我需要在每一帧上查看的区域

需要关注的区域。用边缘检测对图像进行后处理。

要进行分组并不太难,因为本质上,我有一个矩阵(图像),其中每个单元有两个值0255,有点不规范的二进制矩阵。我需要从左边找到至少有一个像素值为255的组的位置。为此,我通过 X 轴在画布上迭代,步长定义了“障碍物”之间的最小距离。每个组代表一个元组,该元组具有距组左侧的位置和宽度。当我找到所有组时,我从左边修剪结果以知道“障碍”的确切边缘。这是简化光流的未来部分所需要的。还值得一提的是,因为步长值是常数,这种方法的复杂性是线性的O(n+k),其中n是画布的宽度,k是“障碍”的数量。这还不算太糟糕,因为我需要对每一帧进行计算,并且关心这里的性能。下面你可以看到分组是如何工作的。

“障碍”如何分组的可视化表示。来源:作者

现在我有一切可以切换到下一步。

通过速度计算使恐龙奔跑和跳跃

找到恐龙并开始游戏循环的运行脚本位于下一个文件:https://github.com/dperyel/run-dino-run/blob/master/run.py

好的,我要说最复杂的部分已经在第一部分完成了。现在我们至少知道了到第一个“障碍”的距离,如果“危险”物体太近,可以使用pyautogui.press('space')。问题是游戏改变了速度。迪诺越跑越快。我的第一个想法是使用光流和 Lucas-Kanade 算法来比较前一帧和当前帧。当我得到像素偏差时,我可以计算速度。它会工作,唯一的事情是我已经有我需要的一切。我的“障碍”组代表了我需要注意的特征,我可以存储前一帧的状态以找到我需要的偏差。 当我避免使用复杂的算法时,我总是感到轻松,并通过做几个“加和减” (-:

通过知道一个速度,找到一个依赖关系是一个数学(或时间)问题,这个依赖关系是你需要从一个“障碍”的距离来触发一个“跳跃”。这是一个结果。

结果,迪诺没日没夜地跑,如果有仙人掌或鸟靠近,它就会跳起来。来源:作者

结论

计算机视觉是许多自动化过程的重要组成部分。正如你在这个小例子中看到的,你甚至可以通过让一台机器找到敏感部分来对一个游戏进行完整的端到端测试。

尝试不同的库来比较性能是一个好主意。在我的例子中,当 PyAutoGUI 仍然用于其他副作用时,MSS 在屏幕捕捉方面是绝对的赢家。

附言:所有源码都放在我的 GitHub 上https://github.com/dperyel/run-dino-run
回购使用 git LFS 存储所有二进制文件。为了让脚本工作,你需要从你的显示器上截取一个assets/dino_crop.png的截图,或者做一个模板缩放(-;
代码可能包含 bug,因为它主要是像概念验证一样完成的。
欢迎在下面评论或提问。

从仪表板到洞察力

原文:https://towardsdatascience.com/you-say-dashboard-i-say-insights-f277a5d89f97?source=collection_archive---------44-----------------------

改变你看待过程改进仪表板的方式并促进其使用的五个原则。

照片由 ETA+Unsplash 上拍摄

你还记得你打开准将 64 的时候吗?你必须连接所有的设备(除非你很幸运有一台专用于此的电视),然后通过磁带阅读器加载游戏,然后等待。等等。等等。等到屏幕上出现什么东西时,才意识到这是一个错误的游戏。

这个故事让我想起了当我看到一些仪表板时的感觉。在这篇文章中,我特别关注过程改进仪表板,这样的仪表板可以用来比较设施、工厂、部门或组织的元素。

我将分享一个好的流程仪表板的五个关键原则。作为仪表板的消费者和生产者,我对它们都进行了测试,到目前为止,它们运行得相当好。

照片由法比奥·布拉克特Unsplash 上拍摄

  1. 从 KPI 转移到评分。

对许多人来说,仪表板意味着关键绩效指标(KPI)。您可以自己决定,也可以从竞争对手那里借用用于基准测试的外部资源。

在我看来,更有价值的是将所有的 KPI 连接在一起,即使用平衡计分卡的方法,创建一个评分机制

就像问一个人"你还记得上学期的所有分数或者你拿到学位时的最终成绩吗?”。他/她可能会回答第二个问题。

因此,关键信息变成了分数,这一过程得到了多少,即从 1 到 10。通过显示分数的来源,用户可以了解所有维度之间的关系,以及应该使用哪个杠杆来提高总分数。

在我们最近创建的仪表板中,我们根据成本效率、团队效率和 ERP 效率来评估部门的效率。如果你有一个适当设置的 ERP,你可以承受一个效率较低的团队;如果你有一个效率较低的 ERP,你必须用你的团队效率来补偿(例如,管理更多的发票、日志条目等)。)但是为了确保您的成本不会增长到最高,您可能还需要考虑如何抵消这种额外的工作(即利用远程位置或外部化以防万一)。

与许多 KPI 相比,分数更容易被人们记住:这是一种简单的方法,只需给出一个数字就可以记住并在几个月内进行比较。如果需要进一步的详细信息,您可以转到详细的 KPI。

卢克·切瑟Unsplash 上拍摄的照片

2。建造耻辱墙/名誉墙。

人类喜欢人类。和数据之类的数据。如果你在仪表板上显示一些绝对值,用户如何理解什么是好的,什么是坏的?

在我看来,关键是要清楚地了解什么是好什么是坏,并使之在整个组织中透明。出乎意料的是,并不是每个人都喜欢透明。

通过透明地展示表现最好和最差的员工,你将获得一个没有借口的环境。这将产生一个健康的竞争环境,用户可以比较来自不同单位的数据,相互学习,自主地努力达到下一个水平。

我经常使用“耻辱墙/名声墙”这种表达方式,因为它就是这样:你不加过滤地展示了好与坏。

亚当·威尔逊Unsplash 上拍摄的照片

3。让用户玩它

给用户决定看什么的权力。启用尽可能多的视图和尽可能多的过滤器。当数据变成信息时,它的美妙之处在于每个人都以不同的方式看待它们。

让用户决定并享受他们的观点。

停止仪表板的扩散,让人们可以自定义他们感兴趣的值。

这在仪表板中建立了更强的信任(因为是用户选择他/她想看的内容),同时也增加了参与度。

简而言之,从推式转向拉式仪表板:让他们可用,让人们玩。就像在 Commodore 64 上,可能只是快一点点:)

马库斯·斯皮斯克在 Unsplash 上的照片

4.将算法民主化。

老年人常说“知识就是力量”。我的回答是“真的吗?”。

除非你创造了一个神奇的算法来拯救世界,否则我很遗憾地告诉你,有很多聪明人可以得到你开发的相同甚至更好的算法。

通过与用户共享仪表盘背后的算法,信任度显著提高

你给他们一个分数,但你如何达到这个分数,以及你如何转换、汇总和评估数据,都必须是透明的。它的副作用是,你可能会受到用户的挑战:关键是在你上线之前要进行多次测试和重新测试,但这也可能是你改进算法甚至达到更好阶段的机会。

照片由克里斯蒂安·休姆Unsplash 上拍摄

5。让它更容易被使用。

用回形针的时候有没有请示过?那你为什么要为仪表板这么做呢?

如果的目的是绘制数据并向用户提供即时结果,则不需要任何指令。我记得当我还是一名计算机程序员时,我们总是玩虚拟游戏:即使你没有参与第一次编码,你也应该能够改变一个程序。这是我们的主要 KPI,看看它是否对用户友好。

试着让它更简单,使用过滤器,颜色编码和空间的明智使用来获得眼睛的焦点。当你有了仪表盘的第一张草图后,去喝杯咖啡。然后用更少的项目重新设计相同的仪表板。尽量浓缩,视觉化。这将比成千上万的直方图更能吸引眼球,并在大脑中留下深刻印象。

这些是我迄今为止用于过程改进仪表板的五个关键原则。值得一试。

“我们相信上帝。所有其他人都必须带数据。”爱德华·戴明,

Luca Condosta(博士)是一名金融专业人士,拥有跨国企业的全球经验。对数据、领导力、战略和人充满热情。两本书的作者(可持续发展报告纳图齐——意大利和声制作人)喜欢寻找和分享故事。

你应该知道这些(常见的)深度学习术语和术语

原文:https://towardsdatascience.com/you-should-be-aware-of-these-common-deep-learning-terms-and-terminologies-26e0522fb88b?source=collection_archive---------39-----------------------

Raphael SchallerUnsplash 拍摄的照片

术语

作为深度/机器学习实践者,你一定会经常遇到的术语词汇表

介绍

我最近浏览了 Juptyter notebook 中展示的一组基于机器学习的项目,并注意到在我参与或审阅的所有笔记本和基于机器学习的项目中,都有一组重复出现的术语和术语。

你可以把这篇文章看作是在机器学习和深度学习中消除一些噪音的一种方式。期望找到你在大多数基于深度学习的项目中必然会遇到的术语和术语的描述和解释。

我涵盖了机器学习项目中与以下主题领域相关的术语和术语的定义:

  1. 数据集
  2. 卷积神经网络架构
  3. 技巧
  4. 超参数

1.数据集

弗兰基·查马基Unsplash 上拍摄的照片

训练数据集:这是我们用来直接训练神经网络的一组数据集。训练数据是指在训练期间暴露给神经网络的数据集分区。

验证数据集:这组数据集在训练中被用来评估网络在不同迭代中的性能。

测试数据集:数据集的这个分区在训练阶段完成后评估我们网络的性能。

2.卷积神经网络

照片由 Alina GrubnyakUnsplash 上拍摄

卷积层:卷积是一个数学术语,描述两组元素之间的点积相乘。在深度学习中,卷积运算作用于卷积层中的过滤器/内核和图像数据阵列。因此,卷积层仅包含滤波器和通过卷积神经网络传递的图像之间的卷积运算。

批量标准化层 :批量标准化是一种技术,通过引入对来自前一层的输入执行操作的附加层来减轻神经网络内不稳定梯度的影响。这些操作对输入值进行标准化和规范化,然后通过缩放和移位操作转换输入值。

下面的 max-pooling 操作有一个 2x2 的窗口,并滑过输入数据,输出内核感受域内像素的平均值。

展平图层:取一个输入图形,将输入图像数据展平成一维数组。

密集层:密集层中嵌入了任意数量的单元/神经元。每个神经元都是一个感知器。

3.技术

马库斯·斯皮斯克在 Unsplash 上拍摄的照片

激活函数%2C%20depending%20on%20input.) :将神经元的结果或信号转化为归一化输出的数学运算。作为神经网络组件的激活函数的目的是在网络中引入非线性。包含激活函数使神经网络具有更大的表示能力和解决复杂的函数。

整流线性单元激活函数(ReLU) :一种对神经元的值结果进行转换的激活函数。ReLU 对来自神经元的值施加的变换由公式 y=max(0,x) 表示。ReLU 激活函数将来自神经元的任何负值钳制为 0,而正值保持不变。这种数学变换的结果被用作当前层的输出,并被用作神经网络内的连续层的输入。

Softmax 激活函数:一种激活函数,用于导出输入向量中一组数字的概率分布。softmax 激活函数的输出是一个向量,其中它的一组值表示一个类或事件发生的概率。向量中的值加起来都是 1。

漏失 : 漏失技术通过随机减少神经网络内互连神经元的数量来工作。在每一个训练步骤中,每个神经元都有可能被遗漏,或者更确切地说,被排除在连接神经元的整理贡献之外。

4.超参数

马尔科·布拉舍维奇在 Unsplash 上拍摄的照片

损失函数:一种量化机器学习模型表现好坏的方法。量化是基于一组输入的输出(成本),这些输入被称为参数值。参数值用于估计预测,而“损失”是预测值和实际值之间的差异。

优化算法:神经网络内的优化器是一种算法实现,它通过最小化损失函数提供的损失值来促进神经网络内的梯度下降过程。为了减少损失,适当地选择网络内的权重值是至关重要的。

学习率:神经网络实现细节的一个组成部分,因为它是一个因子值,决定了网络权值的更新水平。学习率是一种超参数。

Epoch: 这是一个数值,表示网络暴露于训练数据集中所有数据点的次数。

结论

显然,在你从事和完成机器学习项目的过程中,你肯定会遇到更多的术语和术语。

在以后的文章中,我可能会扩展机器学习中经常出现的更复杂的概念。

请随意保存这篇文章或与刚开始学习旅程或职业生涯的机器学习从业者分享。

我希望这篇文章对你有用。

要联系我或找到更多类似本文的内容,请执行以下操作:

  1. 订阅我的 邮箱列表 获取每周简讯
  2. 跟我上
  3. 通过 LinkedIn 联系我

* [## 2020 年(及以后)机器学习从业者创收的 5 种方式

了解如何利用机器学习技能增加收入或创造新的收入来源

towardsdatascience.com](/5-ways-a-machine-learning-practioner-can-generate-income-in-2020-and-beyond-2f541db5f25f) [## 辅助项目在机器学习中的重要性

你和马克·扎克伯格有什么共同点?在这篇文章中找出,以及其他几个原因,为什么…

towardsdatascience.com](/the-importance-of-side-projects-in-machine-learning-edf9836bc93a)*

你不应该仅仅在迭代中使用 purrr

原文:https://towardsdatascience.com/you-should-be-using-purrr-for-more-than-just-iteration-2884a37aba18?source=collection_archive---------33-----------------------

Tidyverse 包中的 3 个函数改进了 R

照片由凯瑟琳·希斯Unsplash 拍摄

purrr 包Tidyverse 的主要支柱之一,在实用性和通用性方面与 dplyr 和管道操作器不相上下。其主要目的之一是将循环的意图与其语法对齐。在编写 for 循环时,不涉及一堆乏味的样板文件——它很少告诉读者循环做了什么——purrr map 可以像简单的英语一样阅读,并且可以整齐地放入管道连接的操作组中。

但这并不是 purrr 所能提供的全部。最长的一段时间,我只用了mapwalk,以及它们的变体。从那以后,我发现了这个包的其他实用程序,它们使处理列表变得轻而易举。

因为这些函数一点也不隐藏,就在文档页面中的显眼位置,我觉得没有早点使用它们有点愚蠢。但是对于程序员来说,太容易陷入相同的例行程序,无意识地遵循“如果它没有坏”的思维模式。因此,为了激起您对 purrr 提供的鲜为人知的工具的兴趣,我选择了几个我最喜欢的工具来分享。我希望这样做会改进您的工作流,让您更加好奇这个 R 包还能提供什么。

避免用“set_names”反斜杠或替换函数

现在,一个实际上是从 rlang 包重新导出的函数,它本身在 base R 中有一个对应的可用版本,这看起来似乎是一个奇怪的起点。但是set_names非常符合 purrr 的基本理念,我认为它是合适的。

在 R 中,从语法上来说,有四种类型的函数。分别是前缀(do_something(argument))中缀** ( +-%>%)替换(setter(x) <- “eggs")特殊(类似if的关键词)。**

事实是,大多数阅读代码的人都非常熟悉前缀和中缀形式,尤其是来自其他语言的形式。虽然任何函数都可以通过使用反斜线以前缀形式编写,但这是 R 的另一个怪癖,在使代码更具可读性方面并没有起到很好的作用。

假设我们有一个字符向量,我们需要它们的字符长度。为了举例,我将使用像这样的简单操作,可能不需要使用列表和 purrr——如果这让您感到困扰,那么想象一下我们正在做一些输出异构数据类型的更复杂的任务。

如果我们希望输出列表的名称是原始字符,我们可以这样做:

注意这个函数是如何很好地适应管道的。这里我利用了这样一个事实,即set_names将默认给一个向量它自己的参数值作为名称。比手工创建一个命名的向量要快得多,也比在单独的一行上使用names(animal_nchars) <- animals漂亮得多。

用“cross”避免嵌套循环

假设我们有两个不同长度的字符向量,我们希望将它们中的元素粘贴到一起,作为另一个字符向量返回。我们可以这样使用嵌套地图:

请注意,这种方法很难阅读,并且需要一些额外的工作来获得一个字符向量。虽然像 map2 和 pmap 这样的工具可以很好地处理相同长度的输入,但是在条件不太整洁的情况下它们就不起作用了。此外,内循环返回长度大于 1 的向量的事实阻止了我们在外循环中使用map_chr

请考虑这种方法:

好多了,你不觉得吗?对于更复杂的函数,如果使用公式的话,我喜欢手动解包..x,只是为了让内容更具可读性。在决定是利用特定语言的速记来节省自己的时间,还是使用更冗长的速记来方便其他人时,总会有一点权衡。

使用“保持”和“压缩”进行过滤

在我的工作场所,我处理大量的空间数据。当跨地理区域迭代时,过程经常因为简单的数据覆盖原因而失败。我发现 compact 函数对于在探索阶段过滤掉这些故障非常有用。

对于更持久的代码,最好明确要丢弃哪些元素,因此使用keep可能是更好的选择,因为它让您指定一个谓词。

r 有多个内置数据集。假设我们想要列出它们的列名,但前提是它们必须以 dataframes 的形式存储。这是可以做到的:

由于内置数据集是 base R 的一个怪癖,以编程方式访问它们有点奇怪,因此使用了get。关于上面的片段,需要注意一些事情:

  • 因为不是所有列出的数据集都被成功检索,所以我使用possiblycompact来过滤掉这些失败。
  • “仅当它们作为数据帧存储时”部分由管道的第 4 行中的keep完成。
  • 注意set_names是如何再次派上用场的,这样在过滤完成后,我们就知道每组列名与哪个数据集相关联。

我在这里仅仅触及了表面,我的例子不可否认地有点做作,但是我希望我至少已经说服了你自己去探究除了使迭代更可读之外,purrr 还能为你做些什么。

当然,伴随着所有伟大的锤子而来的是责任,不要把一切都看成钉子。R 中的列表通常不是保存数据的最佳数据结构选择。如果您可以将事情存储在数据帧中,并使用 dplyr 而不是 purrr 来实现您的目的,那么您应该这样做!

但是对于处理列表的时候,purrr 是一个很好的工具,但是经常没有被充分利用。祝你好运!

你应该成为一名数据科学家。原因如下。

原文:https://towardsdatascience.com/you-should-become-a-data-scientist-heres-why-dbc07c80ebaa?source=collection_archive---------31-----------------------

意见

在不断变化的市场中成为数据科学家的理由

照片由 ThisisEngineering RAEngun splash【1】上拍摄。

目录

  1. 介绍
  2. 数据科学家
  3. 论证
  4. 摘要
  5. 参考

介绍

在过去的 10 年里,数据科学已经成为就业市场的领跑者。尽管一些文章旨在将数据科学视为不再投资的职业,但我在这里告诉你相反的情况。数据科学不仅最近采取了许多形式,而且它也被证明是一份满意度很高的工作。此外,这一领域可以相当有利可图,平均基本工资为107,801 美元【2】。这个数字不包括奖金、股票或其他激励措施,这些都会增加本已很高的基本工资。总而言之,数据科学有着很高的基本工资中位数、巨大的工作满意度和无数的工作机会,确实是一个值得投资和追求的职业和领域。下面,我将详细阐述其中的原因,并提供一些有益的见解。

数据科学家

作者的随机森林数据科学模型中使用的 Python 代码。作者截图[3]。

在我们进行更详细的推理之前,让我们先定义一下职业。根据经验,数据科学家是用自动化统计和算法解决业务问题的人。典型数据科学家的一般工作流程可以概括为:

  • 业务问题陈述制定(与利益相关者会面)
  • 数据集开发 (SQL 拉数据和数据清洗)
  • 探索性数据分析(缺失值、正态性、标记)
  • 基础模型构建(非监督/监督、回归/分类)
  • 模型创建(例如带有超参数调整的随机森林)
  • 结果解释(向利益相关者解释结果)
  • 模型部署(通常交给机器学习工程师)

虽然不同公司之间的工作流程和具体步骤可能会有所不同,但数据科学家的工作描述和日常工作通常都遵循这种格式。既然我们知道了数据科学家通常从事的工作类型,我们现在将给出为什么要成为数据科学家的理由。

论证

蒂姆·莫斯霍尔德在Unsplash【4】上拍摄的照片。

成为数据科学家有很多好处,不成为数据科学家也有一些好处(将在本文后面详述)。主要原因可以归纳为工作满意度、职位空缺、薪资以及所学工具和技能:

工作满意度 —一个著名的来源 Glassdoor 提出了“【2020 年美国最好的工作”[2],其中数据科学家的排名是第三位。然而,工作分层实际上是这个列表中第二高的职位,仅次于战略经理职位。这一评级范围为 1.0 至 5.0,得分为 4.0,数据科学家可以期待在日常工作中获得快乐。

职位空缺 —虽然职位空缺并不是列表中最高的,但仍有相当数量的 6542 个[2]。与软件工程师等职位空缺较高的其他职业相比,你可以获得的数据科学学位数量有限,因此你获得数据科学家职位的可能性仍然很高。

薪资 —在美国十大工作中,只有两个职位的数据科学家底薪最高。有了在线学习,这份高薪完全值得投资。为了更多地了解如何在线成为一名数据科学家,我写了一篇不同的文章,强调在线学习背后的推理[5]:

[## 是的,你可以在网上成为一名数据科学家。以下是方法。

在线学习的专业数据科学家指导您在家开始数据科学生涯

towardsdatascience.com](/yes-you-can-become-a-data-scientist-online-heres-how-dc73c7faae0f)

如果你学习成为一名数据科学家,但没有在数据科学领域找到工作,会发生什么?

学到的工具和技能——这就是推理的这个方面变得重要的地方。学习数据科学时,你会精通与其他领域重叠的技能。其中许多还被列入了十大最佳工作名单。那些相似的职位和他们各自的排名包括[2]:

  • 产品经理— 4 名
  • DevOps 工程师— 5
  • 数据工程师— 6
  • 软件工程师— 7 名
  • 战略经理— 9
  • 业务发展经理— 10

或许成为数据科学家学到的最有价值的技能是解决问题。因此,如果你碰巧很难找到一个适合你的数据科学职位,有大量类似于数据科学的职位可以从你已经学到的技能中获得。重叠技能包括但不限于 SQLPython产品管理、商业智能。其他可能被追求的职位有,其中一些,在美国新闻&世界报道【6】的“ 100 个最好的工作中有所概述:

- Machine Learning Engineer- Statistician- Mathematician- Data Analyst

虽然其中一些立场是相似的,但也有重要的差异,我在另一篇文章[7]中也强调了这一点:

[## 数据科学 vs 机器学习。区别就在这里。

数据科学家和机器学习工程师的主要区别和相同点是什么?阅读以下内容,了解…

towardsdatascience.com](/data-science-vs-machine-learning-heres-the-difference-530883d6de3a)

摘要

It can be scary investing time and money into a career, data science should not be one of them.

正如本文所解释的,有很多理由可以说明你为什么应该成为一名数据科学家。无论您是在寻找下一个重大的职业发展,还是想知道数据科学热潮背后的炒作,我希望这篇文章对您来说既有趣又有价值。感谢您的阅读!

参考

[1]照片由this engineering RAEngUnsplash(2020)上拍摄

[2] Glassdoor 团队,2020 年美国最好的工作,(2020)

[3] M.Przybyla,截屏,(2020 年)

[4]蒂姆·莫斯霍尔德在 Unsplash 上拍摄的照片,(2018)

[5] M.Przybyla,是的,你可以在网上成为一名数据科学家。以下是方法。(2020 年)

[6]《美国新闻与世界报道》, 100 份最佳工作,(2020 年)

[7] M.Przybyla,数据科学 vs 机器学习。区别就在这里。(2020 年)

引导和打包 101

原文:https://towardsdatascience.com/you-should-care-about-bootstrapping-ced0ffff2434?source=collection_archive---------37-----------------------

参数和统计数据应该属于分布,而不是单值!

照片来自免费 pixabay 上的照片

Bootstrapping 方法用于了解统计数据的概率分布,而不是从表面上看。自举的基本原理依赖于使用替换对数据集进行重采样。在这里,我们将看看为什么它的数学工作,以及如何可以用来估计模型参数的情况下,一个简单的线性回归模型。

一些数学

想象一下,我们有一个数据集,它看起来像是xy之间的线性关系,但是当我们观察y的值时,我们这样做是添加了噪声。

y = ax + b + ε

其中ε 取自随机分布 N(0,σ)。

使用最大似然估计,我们可以解析地找到对ab的估计,让我们称这些估计为â。我们不仅可以找到数值的形式,还可以计算估计量的方差。

估计量的方差始终是一个重要的问题,因为它提供了点估计的置信度。在像这样的高斯噪声回归模型的情况下,我们发现估计值â的分布也是高斯分布。这种分布完全由其均值和方差来定义。

在这个简单的线性回归模型中,a的方差是σ /(nσ_x)其中σ_x 是x的方差。

那么我们为什么需要自举呢?

自举的目的也是为参数或统计数据创建置信区间。这是通过假设观察到的数据是真实的数据分布来创建多个新数据集来实现的。这意味着我们可以用该分布中的替换样本来创建新的数据集。这可用于训练模型或计算统计数据,方式与我们通常所做的相同,但不同之处在于,我们会多次重复这一操作,每次都使用新的重采样数据集。

这样做的好处是不需要分析计算参数或统计数据的分布,您可以使用用于拟合模型的不同采样数据集,根据经验简单地计算出分布。

自举起作用有两个主要原因,首先是弱大数定律 (WLLN)和概率收敛

首先,从分布X中抽取的随机变量X_i的 WLLN 状态,随着n趋于无穷大,X_in样本的经验均值将收敛于X ( E(X))的例外。更正式地说:

X̄ = 1/n (X_1 + ... X_n)

X̄ → E(X) as n → ∞

但是,WLLN 假设每个估计都是独立同分布的(iid ),如果使用替换抽样,这一假设将不再成立。如果您有无限量的数据,细分为更小的部分,并使用每个细分来计算参数值,这将是正确的。然而,在极限情况下,随着数据集的大小变大,这两种情况变得等同——根据经验,我们知道它也适用于较小的数据集。

其次,概率的收敛是指样本的经验方差收敛于分布方差(这里很好的展示了)。

这在实践中是如何运作的?

让我们来看一个将最佳拟合的线性线拟合到基本数据集的基本示例。

import numpy as np
import pandas as pd
from scipy import statsx = np.arange(-10,10,0.25)
y = x*2 - 10 + 10*np.random.randn(len(x))
data = np.concatenate((x[:,np.newaxis],y[:,np.newaxis]), axis=1)

不是我们建立我们的引导函数:

def bootstrap(data,n_trials=1000):
    index = np.arange(data.shape[0])
    bootstrap_index = np.random.choice(index,
                                       size=data.shape[0]*n_trials,
                                       replace=True)
    bootstrap_data = np.reshape(data[bootstrap_index,:],
                                (n_trials,*data.shape))
    return bootstrap_data

这个简单的函数假设第一维是与数据点数量相关的维度,即(M x F ),其中 F 是特征的数量。然后,它随机选择 M x n_trials 索引,并返回原始数据的经过整形的采样版本。现在它的形状是 n_trials x M x F。

现在,让我们将最佳拟合的线性线拟合到数据的每个引导版本:

a_hats = []
b_hats = []
sigma_hats = []
for d in bootstrap_data: 
    a_hat, b_hat = stats.linregress(d[:,0],d[:,1])[:2]
    a_hats.append(a_hat)
    b_hats.append(b_hat) sigma_hats.append(np.std(d[:,0]*a_hat + b_hat - d[:,1]))

a_hats = np.array(a_hats)
b_hats = np.array(b_hats)
sigma_hats = np.array(sigma_hats)

现在我们有了模型ŷ = âx + b̂ + N(0,σ_hat)的α和β参数的分布

本例中â, b̂, σ_hat的平均值分别为 2.15、-9.28 和 9.58,相比之下,数据是用值 2、-10 和 10 生成的,因此我们得到了很好的估计,但我们是否在置信区间内呢?每个参数都有 0.20,1.11 和 0.69 的标准偏差,所以我们在平均值的一个标准偏差内!

我们还可以查看参数的分布以及均值和标准差等点统计数据。

â的分布

记得在我们计算出â的理论方差之前,对于这个数据,与我们估计的方差 0.041 相比,这将产生 0.037 的值,考虑到我们不必做任何分析,这还不错!

我们还可以使用â的每个值来进行预测。在预测点中,我们也可以取第 95 和第 5 百分位,并为每个x值绘制它们。

median = np.percentile(predict, 50, axis=0)
upper = np.percentile(predict, 99, axis=0)
lower = np.percentile(predict, 1, axis=0)
df = pd.DataFrame({"y":y},index=x)
ax = pd.DataFrame({"median": median, 
                   "upper":upper, 
                   "lower":lower}
                  ,index=x).plot()
ax = plt.scatter(x=df.index, y=df.y)

所以现在我们可以做出 90%置信区间的预测。如果我们只对â进行单一预测,我们就无法做到这一点。

制袋材料

Bagging 是一个与 bootstrapping 非常相关的概念,它涉及相同的重采样方法来训练多个模型。

bagging 最常见的应用是应用于决策树分类器/回归器。浅层决策树有一个方差问题,因为它们高度依赖于训练它们所用的数据(特征空间中的分裂是在特征之间进行的,并且您进行 spits 的顺序可以极大地改变分类器)。

那么我们该如何应对呢?如果我们用重新采样的数据集训练大量的树,并进行平均预测,那么得到的分类器的总方差会减少。

来自维基百科的随机森林分类器

为了演示这一点,我们可以用 sklearn 训练一个森林和一棵树,并查看结果。

from sklearn.ensemble import RandomForestRegressor
from sklearn.tree import DecisionTreeRegressorforest = RandomForestRegressor(n_estimators=100)
tree = DecisionTreeRegressor()forest.fit(x[:,np.newaxis],y)tree.fit(x[:,np.newaxis],y)x_test = np.arange(-10,10,0.25)
y_test = x*2 - 10 + 10*np.random.randn(len(x))

如果我们在测试集上用一棵树和一个森林进行预测,我们会得到:

我们可以看到,预测的方差如我们所预测的那样大大减少了。

关于打包和引导的精彩讲座,我推荐康奈尔大学的这个讲座。

我们学到了什么?

我们看一下引导的基本概念,以及为什么它是任何数据科学家必备的有用技能。我们希望了解它是如何工作的,我们如何在 Numpy 中实现它,以及我们如何使用它来建模参数的分布,而不是将它们建模为单个值。我们还介绍了 bagging 的概念,以及如何应用它来提高存在方差问题的分类器的性能。

你真的应该学习一下图形数据库。原因如下。

原文:https://towardsdatascience.com/you-should-really-learn-about-graph-databases-heres-why-d03c9d706a3?source=collection_archive---------19-----------------------

苹果 | 谷歌 | SPOTIFY | 其他

丹尼斯·戈斯内尔和马蒂亚斯·布罗意切勒在 TDS 播客

编者按:迈向数据科学播客的“攀登数据科学阶梯”系列由 Jeremie Harris 主持。Jeremie 帮助运营一家名为sharpes minds的数据科学导师初创公司。可以听下面的播客:

在职业生涯中取得成功的一个很好的方法是,对哪些技术在未来会变得重要下好赌注,并投入时间学习它们。如果这听起来像是您想做的事情,那么您肯定应该关注图形数据库。

图形数据库并不是全新的,但随着图形数据(描述事物的互联网络的数据)变得比以往任何时候都更容易获得,它们变得越来越重要。社交媒体、供应链、移动设备跟踪、经济学和许多其他领域正在产生比以往任何时候都多的图表数据,这些数据集中埋藏着许多最大问题的潜在解决方案。

这就是为什么我如此兴奋地与 Denise Gosnell 和 Matthias Broecheler 交谈,他们分别是 DataStax 的首席数据官和首席技术官,DataStax 是一家专门为企业解决数据工程问题的公司。除了他们在 DataStax 使用图形数据库的丰富经验,Denise 和 Matthias 最近还写了一本名为图形数据从业者指南的书,并在本期“走向数据科学”播客中抽出时间讨论了数据工程和图形数据的基础知识。

以下是我最喜欢的外卖:

  • 图形数据的一个奇怪之处在于,在您可以分析它之前,您需要决定您想要使用什么视角来查看它。你是否有兴趣探索单个节点的行为(例如,“我想知道我能否根据给定的人在 LinkedIn 上的联系预测 X”),或者探索整个网络的行为(例如,“LinkedIn 上的一些联系比其他联系更重要吗?”?答案将改变你询问数据的方式,以及你对数据集的看法。Denis 和 Mattias 在他们的书中确定了图表数据的四种不同观点,并在播客中讨论了它们。
  • 您可以对图表数据使用的机器学习算法取决于您对数据集采用的上述四个视角中的哪一个。如果您选择以突出显示特定节点的方式来表示数据,而不是以突出显示节点聚类的方式来表示数据,则不同的预测模型和无监督模型可能适用,也可能不适用。
  • 谈到数据工程,不同的工具在不同的规模下变得有用(并且最终是必要的)。不同工具之间的决策面很难解释,但我们在播客中讨论了这一点。何时使用 SQL vs noSQL,何时应用 Spark 或 Cassandra 等工具取决于您正在处理的数据集的复杂性和大小。
  • 我向 Denise 和 Matthias 询问了一些资源,像我这样的图形数据库新手可以使用这些资源来了解这个主题,他们推荐了 NetworkX ,并使用了来自 Kaggle 的链接预测挑战的数据。

你可以点击这里在 Twitter 上关注丹尼斯,点击这里在 Twitter 上关注马蒂亚斯。另外,你可以在这里找到他们书的 GitHub。

你可以在 Twitter 上关注我。

订阅《走向数据科学》的 月刊 直接在你的邮箱✨里接收我们最好的文章、视频和播客

您应该现在就开始使用 FastAPI

原文:https://towardsdatascience.com/you-should-start-using-fastapi-now-7efb280fec02?source=collection_archive---------2-----------------------

如果您还没有尝试过 FastAPI,现在是时候了

得益于 Flask、Django、Falcon 等优秀的框架,Python 一直是开发轻量级 web 应用程序的热门选择。由于 Python 是机器学习的头号语言,所以它特别方便将模型打包并作为服务公开。

多年来,Flask 一直是这项工作的首选工具,但是如果你还没有听说的话,现在有了一个新的挑战者。 FastAPI 是 Python 的一个相对较新的 web 框架,从它的前辈那里获得灵感,完善它们并修复它们的许多缺陷。它建立在 Starlette 之上,为桌面带来了大量令人敬畏的功能。

最近,它获得了巨大的吸引力,在过去的 8 个月里,我每天都与它一起工作,我可以自信地说,炒作是合理的。如果你还没有尝试过,我想给你五个尝试的理由。

简单而出色的界面

所有的 web 框架都需要在功能和给开发者自由之间取得平衡。姜戈很强大,但非常固执己见。另一方面,Flask 级别很低,足以提供很大的自由度,但是还有很多事情留给用户去做。FastAPI 更像是一个瓶子,但它设法达到了更健康的平衡。

为了给你一个例子,让我们看看如何在 FastAPI 中定义端点。

为了定义模式,它使用 Pydantic,这是另一个很棒的 Python 库,用于数据验证。这在这里很容易做到,但是后台发生了很多事情。验证输入的责任委托给了 FastAPI。如果请求不正确,例如email字段包含一个 int,将返回一个适当的错误代码,而不是应用程序因可怕的内部服务器错误(500)而崩溃。而且几乎是免费的。

这个简单的示例应用程序可以与 uvicorn 一起提供:

uvicorn main:app

现在,应用程序可以接受请求了。在这种情况下,请求应该是这样的

curl -X POST "[http://localhost:8000/login](http://localhost:8000/login)" -H  "accept: application/json" -H  "Content-Type: application/json" -d "{\"email\":\"string\",\"password\":\"string\"}"

锦上添花的是,它使用交互式 Swagger UI 根据 OpenAPI 自动生成文档。

FastAPI 应用程序的 Swagger UI

异步ˌ非同步(asynchronous)

与 Node.js 或 Go 中的框架相比,Python WSGI web 框架的最大缺点之一是无法异步处理请求。自从引入 ASGI 以来,这不再是一个问题,FastAPI 正在充分利用这一点。您所要做的只是用关键字async声明端点,就像这样:

依赖注入

FastAPI 有一个非常酷的方法来管理依赖关系。尽管开发人员没有被强制这样做,但是强烈建议使用内置的注入系统来处理端点中的依赖关系。

举个例子,让我们写一个端点,用户可以在这里对某些文章发表评论。

当端点被调用时,FastAPI 会在运行时自动评估get_database函数,因此您可以根据需要使用返回值。这(至少)有两个很好的理由。

  1. 您可以通过修改app.dependency_overrides字典来全局覆盖依赖关系。这可以使测试变得轻而易举,因为您可以很容易地模仿对象。
  2. 依赖关系(在我们的例子中是get_database)可以执行更复杂的检查,允许您将它们从业务逻辑中分离出来。这大大简化了事情。例如,用户认证可以通过这个轻松实现。

易于与数据库集成

SQL、MongoDB、Redis 或您选择的任何东西,FastAPI 都不会强迫您围绕它们构建应用程序。如果您曾经尝试过使用 Django 处理 MongoDB,您就会知道这有多痛苦。有了 FastAPI,您不需要做额外的工作,将数据库添加到您的堆栈中是尽可能简单的。(或者更准确地说,要完成的工作量将由您选择的数据库决定,而不是由 web 框架增加的复杂性决定。)

但说真的,看看这美景。

瞧啊。我能看见你在打字

pip install fastapi

已经传到你的终端了。

GraphQL 支持

当您处理一个复杂的数据模型时,REST 可能是一个严重的障碍。当前端的微小变化需要更新端点的模式时,这绝对不是好玩的。GraphQL 在这些情况下大放异彩。尽管 GraphQL 支持并不是 Python web 框架中唯一的,但 Graphene 和 FastAPI 可以无缝地协同工作。不需要为 Django 安装任何类似graphene_django的扩展,它本身就可以工作。

+1:优秀的文档

当然,如果没有同样优秀的文档,一个优秀的框架不可能真正闪耀光芒。Django,Flask 和所有其他人在这方面都很出色,但 FastAPI 与他们不相上下。当然,由于它年轻得多,目前还没有关于它的书籍,但这只是时间问题。

如果你想看看 FastAPI 的实际应用,我正好有一个完美的指南给你!我写了一个详细的教程,你可以用 Docker,Docker Compose 和 GitHub Actions 来部署你的机器学习模型!

[## 如何正确地发布和部署您的机器学习模型

FastAPI、Docker 和 GitHub 操作实用指南

towardsdatascience.com](/how-to-properly-ship-and-deploy-your-machine-learning-model-8a8664b763c4)

总而言之,无论你是在寻找一个快速轻量级的框架来服务于你的深度学习模型还是更复杂的东西,FastAPI 都能提供。如果您还没有尝试过,我强烈建议您尝试一下。我很确定你会坚持下去。

如果你喜欢把机器学习概念拆开,理解是什么让它们运转,我们有很多共同点。看看我的博客,我经常在那里发表这样的技术文章!

你应该开始在你想离开的公司处理数据

原文:https://towardsdatascience.com/you-should-start-working-with-data-at-the-company-you-want-to-leave-bd1086e7b18f?source=collection_archive---------12-----------------------

让我告诉你为什么和如何

Al ghazaliUnsplash 上拍摄的照片

如果你是数据科学的新手,“做数据科学”可能对你来说是件大事。你可能认为你需要精心收集的数据,所有数据科学的工具和完美的知识,然后你才能声称你“做数据科学”。但这不是真的。你可以,事实上,你应该尽快开始处理数据。如果你不愿意,你不必称之为“做数据科学”,但与数据打交道只会对你有好处。

在本文中,我将解释为什么将数据作为当前工作的一部分是一个好主意。然后我会给你一些项目的例子来激发你的想象力。最后,我们将了解在您当前公司从事数据科学项目时需要记住的一些事情。

为什么开始做项目这么重要?

首先,通过动手实践,你会学到很多你甚至不知道自己需要的技能。其次,这是向你未来的雇主暗示你是认真的,你对这份工作感兴趣,你会抓住每一个机会提高自己的好方法。

为了学习新技能,任何类型的项目都可以。使用你能得到的数据。来自互联网的简单数据集,你自己的 WhatsApp 聊天记录,你在 Reddit 上找到的数据,什么都可以。抓住机会伸展你处理数据的肌肉。随着游戏的升级,你可以接受更大的挑战。

然而,给潜在雇主留下深刻印象是另一回事。简单的项目展示很难在竞争中领先。在这一点上,你的证据将是项目组合与大量的思想进入他们。创建项目组合是一个非常庞大的主题。在这篇文章中,我想把重点放在专业的投资组合项目上。

但是也许我在这篇文章中提到的对你来说是不可及的,或者你在开发项目时需要更多的支持和指导。然后查看我的课程动手数据科学。除了拿出你的第一个作品集项目,这门课还教你如何开始和完成新项目的框架。这样,你可以更好地利用当前公司的资源,在数据科学领域为自己打造未来。最重要的是,我保证,当你把你的实际技能付诸实践,亲身体验现实生活中的项目时,你会对自己的进步速度印象深刻。

什么是专业作品集项目?

这些是你目前工作中的数据科学项目。正如我在我的文章《给不想从初级职位开始的职业转换者的快速提示》中所说的,你的主要卖点之一是你的职业经验和与他人合作的经验。你需要充分利用这个优势。

专业项目是未来有前途的数据科学家的良好指标,原因有两个:

  • 这表明你感兴趣
  • 这表明当你需要的时候你会掌控一切
  • 这表明你可以在专业的环境中工作
  • 这表明你知道如何制定一个数据科学项目
  • 它显示了主动性

“这听起来很棒,但我无法想象我能在工作中做些什么。”

好吧,你的头衔真的不一定是“数据科学家”或“某个分析师”,因为你可以访问一些数据并使用它们。不管你是在市场营销、设计还是人力资源部门工作,只要你要求,只要不是机密,你就可以得到数据。许多公司还没有充分利用他们远程收集的数据,他们欢迎任何人分析这些数据并从中得出结论的机会。这是一个双赢的局面,因为你可能无法在互联网上找到更好的数据。

让我给你举几个例子。

你的公司销售美容产品(或任何其他零售产品)。索要所有销售的概要。你可以分析数据来寻找趋势,试着看看你是否能预测一个地区每天的销售额。添加一些您自己的特性,看看性能是否会变得更好。你也可以把它带到下一个层次,使用可解释性技术来解释为什么你的模型预测它所预测的。

假设你在一家小型摩托车租赁公司工作。如果你的产品收集数据,你能创建一个模型来预测摩托车坏了多久吗?你能提前预测维护需求吗?

也许你在健身房工作。如果你收集会员的入场数据,你可以匿名,并尝试看看谁更有可能继续出现。这是一个棘手的问题。你不希望使用任何可能导致不道德结果的变量,比如某人的种族或性别。尽管性别在这里可以使用,除非你的公司决定给那些可能会更多露面的人打折。(因为那会是歧视。)你也可以根据季节、时间、天气等因素来预测健身房在某个时间会有多忙。这样做可能更安全。

如果你在一家招聘公司工作,你可以试着了解过去的雇佣情况,看看这些人的个人资料和他们受雇的公司有什么联系。一种选择是建立一个模型,预测一个人和一家公司的契合度。一些安全使用的特征将是教育水平、学校、学位、在行业中的经验年数、个人的一般专业经验年数和资历水平、行业、成熟度和工作列表或公司的其他类似因素。您可能希望留意潜在的代理变量(例如,在同一种族的人生活在同一社区的城市中,邮政编码可能代表种族)。

这些项目不必是开创性的或新颖的。你可以复制已经完成的项目。只要是你自己的工作,并且考虑到你的具体情况,它就是有价值的数据科学工作。

在项目过程中你应该关注什么,在展示这个作品时你应该突出什么?

  • 确保你了解你公司的业务
  • 创建一个你感兴趣的潜在项目的列表,并不是所有的项目都必须是可行的
  • 记下您为最终报告收集数据的过程。获取数据时遇到的困难是数据科学过程的一部分。
  • 清楚地陈述你的目标和方法。随着你的发展,你的方法可能会最终成形。只要确保记下你的决定点和你决定前进的方式。
  • 记下你面临的道德问题。你决定使用的变量,你决定省略的变量以及原因。
  • 谈谈你创造或增加的功能,以及为什么。

提示:除了技术工作之外,数据科学还是一个非常具有创造性和批判性的思维过程。解释你的决定,强调你想出的聪明的解决方案。

要在求职过程中获得额外积分,您可以:

  • 试着安排一个时间向你的团队展示你的工作
  • 试着看看公司里是否有人对你的结果感兴趣,把他们当成你的利益相关者
  • 如果你能让你的公司使用你的结果/模型,那就大大加分了。部署到现实生活中是数据科学管道中最有问题的部分之一。展示实施经验对你来说非常重要。

小贴士:如果你不能完成一个大项目,那就做一个简单的,然后让它实现。在一个公司里部署一个作品总是让人印象深刻。即使这只是一个简单的分析,它也会显示你处理复杂情况并完成任务的能力。

当你从一份不同的职业转行时,获得一份数据科学家工作的秘诀是打出你的职业经验牌。除此之外,如果你有一些在专业环境中完成的数据科学项目,那将是你的一大优势。睁大你的眼睛,竖起你的耳朵,寻找你当前工作中的机会,不要犹豫,四处打听。我相信你会惊讶于你的公司是多么渴望免费进行数据分析。

👉对数据科学领域以及如何开始学习感到困惑? 免费参加数据科学入门迷你课程

你应该试试新的 TensorFlow 的 TextVectorization 图层。

原文:https://towardsdatascience.com/you-should-try-the-new-tensorflows-textvectorization-layer-a80b3c6b00ee?source=collection_archive---------5-----------------------

它是如何工作的,以及为什么你应该在你的 ML 管道中实现它。

本文讨论了一个相当高级的主题,因此如果您仍然是 TensorFlow/NLP 初学者,您可能想要快速浏览一下 TensorFlow 2 快速入门教程 或稍微复习一下wordbembeddings

随着最近发布的 [**Tensorflow 2.1**](https://github.com/tensorflow/tensorflow/releases/tag/v2.1.0),一个新的[**TextVectorization**](https://www.tensorflow.org/api_docs/python/tf/keras/layers/experimental/preprocessing/TextVectorization?version=stable) 层被加入到tf.keras.layers舰队中。

该层具有用于管理 Keras 模型中的文本的基本选项。它将一批字符串(一个样本=一个字符串)转换为记号索引列表(一个样本=整数记号索引的 1D 张量)或密集表示(一个样本=表示关于样本记号的数据的浮点值的 1D 张量)。****

文本矢量化图层数据流概述

每个样本的处理包含以下步骤:

1.标准化每个样本(一般是小写+标点剥离)。

2.将每个样本分割成子串(通常是单词)。

3.子字符串重组为令牌(通常是 ngrams)。

4.索引令牌(将唯一的 int 值与每个令牌相关联)。

5.使用该索引将每个样本转换为整数向量或密集浮点向量。

1️⃣标准化。

在第一步中,数据将经过标准化过程在这一阶段,每个文本样本在进一步处理之前被清理和转换。

你可以用TextVectorization层的**standardize**参数控制标准化步骤。该参数的可能值为:

  • None:这将应用完全没有标准化
  • lower_and_strip_punctuation ( 默认):由于降低和删除标点符号是一种非常常见的技术,你可以传递这个字符串,TextVectorization层将应用这个转换作为它的标准化步骤。
  • Callable:如果你需要更多关于标准化的控制,你可以通过你自己的Callable

如果您已经选择将自己的Callable传递给standardize参数,那么您应该注意以下几点:

  1. 任何Callable都可以传递给这个层,但是如果你想序列化这个对象,你应该只传递注册了 keras serializable 的函数(更多细节见注册 keras serializable )。
  2. 当对standardize使用自定义可调用函数时,可调用函数接收的数据将完全传递给该层。Callable应该返回与输入相同形状的张量。

2️⃣分裂了。

在第二步中,每个文本样本将被分割成子串标记(通常是单词)。

同样,您可以使用**split**参数控制分割行为,该参数可用于TextTokenization层。可能的值有:

  • [None](https://github.com/tensorflow/tensorflow/issues/36071):这应该适用于根本没有分裂
  • whitespace ( default ):对 ASCII 空格进行分割是很常见的,这就是为什么这是该参数的默认值。
  • Callable:如果你喜欢更奇特的分割技术,你可以在这里自由传递你自己的可调用函数,就像standardize参数一样。

和以前一样,作为Callable通过考试也有一些限制:

  1. 任何Callable都可以传递给这个层,但是如果你想序列化这个对象,你应该只传递注册了 keras serializable 的函数(更多细节见注册 keras serializable )。
  2. 当对standardize使用自定义可调用函数时,可调用函数接收的数据将完全传递给该层。Callable应该返回一个与输入相同形状的张量。
  3. 可调用函数接收的数据将挤出第 1 个维。这意味着你的Callable将看到["string to split", "another string to split"],而不是[["string to split"], ["another string to split"]]Callable应该返回一个包含分割记号的第一维张量,所以在这个例子中我们应该返回类似于[["string", "to", "split"], ["another", "string", "to", "split"]的东西。这使得Callable[tf.strings.split()](https://www.tensorflow.org/api_docs/python/tf/strings/split)天生兼容。

3️⃣重组。

在将我们的文本分割成记号后,我们可以决定如何在创建词汇索引前将它们重新组合(T21)。这基本上意味着我们可以决定是保留我们目前得到的所有令牌,还是使用它们的组合。

我们用**ngrams** 参数控制这一步。可能的值有:

  • None:在这种情况下,不会创建任何 ngrams ,只会使用您现在拥有的令牌。
  • 一个int:传递一个整数将创建 ngrams 直到该整数。
  • 一个(int, int)元组:传递一个整数元组将为元组中的指定值创建 ngrams

4️⃣指数。

这一步允许您根据上一步获得的重组标记创建一个词汇表。因此,您可以指定一个max_tokens整数参数来控制该层词汇的最大大小,或者简单地保留默认的**None**值,不为词汇设置上限。****

为了实际构建这个索引,您需要调用层的**adapt** 方法,这将使预处理层的状态适合数据集。这也覆盖了默认的adapt方法,在将输入传递给组合器之前,对输入应用相关的预处理。

如果您想设置自己的词汇(和文档频率,可选,您可以使用set_vocabulary方法。**

该方法直接设置该层的词汇和测向数据,而不是通过“适应”来分析数据集。只要 vocab(以及可选的文档频率)信息已知,就应该使用它。如果词汇数据已经存在于层中,如果“append”设置为 False,此方法将替换它,或者追加到它(如果“append”设置为 True)。

**set_vocabulary**方法采用以下参数:

  • vocab:字符串标记数组。
  • df_data:文档频率数组。仅当层output_modetf-idf时才需要。
  • oov_df_value:词汇外令牌的文档频率。仅当output_modetf-idf时才有必要。在tf-idf模式下追加附加数据时,OOV 数据是可选的;如果提供了 OOV 值,它将覆盖现有的 OOV 值。
  • append:是否覆盖或追加任何现有词汇数据。

5️⃣变换。

最后一步,预处理后的数据被转换并以期望的方式提供。有四种不同的选项可供选择:

  • int:输出整数索引,每个拆分字符串标记一个整数索引。
  • binary:每批输出一个整数数组,大小为vocab_sizemax_tokens,在所有元素中包含1 s ,其中映射到该索引的标记在批处理项中至少存在一次。
  • count:与binary相同,但是 int 数组包含该索引处的令牌在批处理项中出现的次数计数。
  • tf-idf:与binary相同,但是应用 TF-IDF 算法来寻找每个令牌槽中的值。

此外,还有两个其他参数会影响图层的输出形状:**

  • output_sequence_length:仅在int输出模式下有效。如果设置,输出将使其时间维度被填充或截断为精确的output_sequence_length值,从而产生形状为[batch_size, output_sequence_length]的张量,而不管分裂步骤产生了多少记号。默认None
  • pad_to_max_tokens:仅在binarycounttf-idf模式下有效。如果为True,即使词汇表中唯一记号的数量小于 max_tokens,输出也会将其特征轴填充到max_tokens,从而产生一个形状为[batch_size, max_tokens]的张量,与词汇表大小无关。默认为True

设置输出序列长度

设置 pad_to_max_tokens。

********

不同输出模式的总结。

<< Impressive, how do I use it? 🤔 >>

就像任何其他的tf.keras层一样,它的使用非常简单。你所需要做的就是实例化这个层,把它放到你的数据中,然后你就可以把它放到你的模型层堆栈中了。

还是那句话,你真的应该看看官方 TensorFlow 的 team Colab 例子,但简单来说:

< <爽!我应该在生产中使用这个吗?🙄>>****

到目前为止,在基于文本的机器学习模型上工作时,您可能必须决定一个输入预处理策略:这基本上意味着您必须独自完成上面为TextTokenization层定义的所有步骤,根据预处理的数据拟合您的模型,保存它,然后在推理时以某种方式再现预处理步骤,然后将它们传递给服务模型并获得一些预测。

这可以通过一系列不同的方式来完成,从完全在 TensorFlow“外部”实现整个预处理管道,到使用强大的tf.data api。当然,也有方法将您自己的操作包含到导出的图形中,TensorFlow 足够灵活,可以让您实现自己的预处理层,但是如果您想要摇滚,这是一条很长的路要走。

这一层给你的是将任何文本预处理逻辑包含到你的模型中的机会。

通过这样做,您将一致地使用相同的预处理和分析代码,并避免用于训练的数据和提供给生产中的训练模型的数据之间的差异,并从编写一次代码中受益。

但是这里是我们梦想开始和结束的地方。

遗憾的是,没有实现导出包含该层的模型, 还没有

这意味着在生产中使用这一层不是一个好主意,因为你不能导出你的模型,也不能用像 Tensorflow Serving 这样的解决方案来服务它。然而,这一层仍然被标记为实验性的,并且随着未来 TensorFlow 版本的发布,我们很快将有能力导出这一层**

来自未来的更新:【tensor flow 博客 2020–07–27:**

TensorFlow 2.3 增加了对新的 Keras 预处理层 API实验性支持。这些层允许您将预处理逻辑打包到模型中以便于部署——因此您可以发布一个模型,该模型将原始字符串、图像或表中的行作为输入。

更新 2020–07–27:导出文本矢量化图层。

<< Alright, I’m interested anyway, where should I go next? 🤓 >>

你在这篇文章中发现的很多都摘自官方 TensorFlow 文档,里面真的是应有尽有,挖吧。

有关一些一般信息,请参见官方 TensorFlow 2.1 版本,其中您将找到一个笔记本,它将指导您使用TextVectorizationLayer完成一个端到端文本分类示例

想要更多吗?看看这个我作为游乐场创造的 Google Colab 笔记本 !

参考文献。

[ 1 ] 文本矢量化2020.01.20https://www . tensor flow . org/API _ docs/python/TF/keras/layers/experimental/预处理/文本矢量化

与 TFX 一起发展的22020.01.20https://www.tensorflow.org/tfx/guide#developing_with_tfx

(你应该)理解深度学习中的子采样层

原文:https://towardsdatascience.com/you-should-understand-sub-sampling-layers-within-deep-learning-b51016acd551?source=collection_archive---------19-----------------------

说明

平均池,最大池,子采样,下采样,都是你在深度学习中会遇到的短语。本文深入介绍了这些技术的利用和优势。

卷积神经网络(CNN)具有能够对通过网络馈送的图像的仿射变换保持不变的特性。这提供了识别图像中偏移、倾斜或轻微扭曲的图案的能力。

由于 CNN 架构的三个主要属性,引入了仿射不变性的这些特征。

  1. 局部感受野
  2. 共享权重(参数共享)
  3. 空间子采样

在本文中,我们将探索空间子采样,并了解它们在 CNN 架构中的用途和优势。

这篇文章面向所有水平的练习机器学习或更具体地说深度学习的个人。

介绍

子采样是一种被设计用来减少对 CNN 内卷积层产生的特征图内精确定位的依赖的技术。

CNN 内部包含固定维度的内核/过滤器,这些被称为特征检测器。一旦检测到来自图像的特征,关于该特征在图像中的位置的信息实际上可以被忽略,这是有好处的。

事实证明,对特定特征定位的依赖对于构建和开发一个网络是不利的,该网络可以对经历了某种形式的仿射变换的输入数据执行相对较好的操作。我们通常不希望网络学习模式中的权重过于特定于训练数据。

因此,就要素定位而言,重要的信息是要素相对于要素地图中其他要素的相对位置,而不是要素在要素地图中的确切位置。

为了减少对网络内要素精确定位的依赖,需要降低空间分辨率。

空间分辨率的降低仅仅是减少特征图中的像素数量,在这种情况下,这是通过子采样实现的。

通过添加子采样层将子采样合并到 CNN 中,其中该层中的每个单元具有施加在输入(来自前一层的特征图)上的固定大小的感受野,其中对该单元的感受野范围内的像素执行操作,操作的结果成为来自子采样层的输出的新值。

子采样是一种在沿网络移动时对要素地图进行下采样的方法

平均池

平均池是子采样的变体,其中落在子采样层内的单元的感受域内的像素的平均值被作为输出。

下面是平均池的描述。

来自“使用卷积神经网络的迁移学习的应用……”的平均池描述

上面的平均池操作有一个 2x2 的窗口,并滑过输入数据,输出内核感受域内像素的平均值。

下面是一段代码,它利用 TensorFlow 深度学习库来实现一个平均池层。

import tensorflow as tfaverage_pooling = tf.keras.layers.AveragePooling2D( pool_size=(2, 2), strides=None, padding='valid')

我不会深入研究上面代码片段的太多细节,因为这超出了本文的范围。但以下是一些必要的信息:

  • 平均池层是使用“ 平均池 2D ”类的类构造函数创建的。构造函数接受一些参数。
  • 池大小是在落入其中的像素值内执行平均操作的滑动窗口的尺寸。元组(2,2)随后将输入数据分成两半
  • 步距表示每次池化操作评估后池化窗口在输入数据上移动的量。分配给它的值“无”意味着跨距值将采用池大小的默认值。

最大池化

最大池是子采样的变体,其中落入子采样层内的单元的感受域内的像素的最大像素值被作为输出。

下面的 max-pooling 操作有一个 2x2 的窗口,并滑过输入数据,输出内核感受域内的最大像素。

来自“使用卷积神经网络的迁移学习的应用……”的最大池描述

import tensorflow as tf
tf.keras.layers.MaxPool2D(pool_size=(2, 2), strides=None, padding='valid')

案例研究:LeNet-5 CNN 架构

通过观察 LeNet-5 架构中包含的第一个子采样层,我们可以获得更多关于子采样层内部操作的信息。

LeNet-5 CNN 架构

第一个子采样层在上面的图像中由标签' S2 '标识,它是紧接在第一个 conv 层( C1 )之后的层。

从图中我们可以观察到,子采样层产生了六个尺寸为 14x14 的特征地图输出,每个由‘S2’子采样层产生的特征地图对应一个由‘C1’层产生的特征地图。

这是我们通过 LeNet-5 的架构观察到的一种模式,因为其他子采样层产生的特征地图的数量与之前的 conv 层产生的特征地图的数量相等。

层' S2 '使用的子抽样变量是一个平均池。如前所述,在上面给出的实施例中,子采样层内的单元都具有 2x2 的感受域,其随后对应于池大小。当值落在 2x2 池内核中时,内核中四个数字的平均值被用作输出。

当我们继续通过 LeNet-5 内的层时,我们到达第二子采样层' S4,并且这个层比' S2 '具有更多的特征地图,总共 16 个特征地图由' S4' 子采样层输出。

值得注意的是,特征图的尺寸 (5x5) 远小于来自先前 conv 层 (10x10) 的特征图,这是因为当输入数据通过网络前馈时,子采样层平均 (2x2) 池尺寸是其作为输入接收的特征图尺寸的一半。这就是所谓的下采样。

随着我们在网络中移动,特征图尺寸的减小(下采样)使得降低特征图的空间分辨率成为可能。您可能会认为这种技术违反直觉,无法确保特征地图中的特征包含足够详细的模式以供学习。

但是从训练集中的图像中学习内在模式可能是有害的。虽然我们加强并促进了从输入图像中学习模式,但实际上,拥有一个在图像通过网络时学习图像的内在模式的网络将降低网络对其训练阶段未见过的数据的泛化能力。

图像具有多种多样的艺术风格。例如,个人可以用几种不同的方式写出数字'8【T1’;让网络关注训练集中图像的细节模式会对其泛化能力产生负面影响。

最后,作为二次采样的结果,还有一个额外的好处,就是增加了网络内生成的特征地图。

我希望这篇文章对你有用。

要联系我或找到更多类似本文的内容,请执行以下操作:

  1. 订阅我的 YouTube 频道 视频内容即将上线 这里
  2. 跟着我上
  3. 通过 LinkedIn 联系我

所以,你想深入学习,却没有数据?

原文:https://towardsdatascience.com/you-want-to-learn-deep-but-you-dont-have-data-20ef3de8ba4a?source=collection_archive---------37-----------------------

给已知运营商一个尝试!

这就是我们今天要回答的问题:“什么是已知算子学习?”。图片由作者在 CC 4.0 下经许可创作。

我相信你们都喜欢深度学习。一个主要问题是,尽管最酷的深度学习解决方案需要大量数据。它很容易进入数百万的训练样本。特别是,如果您从事医学图像处理工作,您将无法访问如此大的数据集,即使您可以访问,良好的注释可能是一个问题

出于这些原因,我们,当然还有许多其他人,开始寻找不那么渴求数据的方法。特别是,我今天要向你们展示一个新的技巧,我们创造了“已知操作员学习”。这个想法已经存在了很长一段时间,但是被机器学习社区的许多研究人员所反对。让我们先看看这个想法,然后看看一些评论,最后看看一些理论和实验结果,我希望你会觉得有说服力。

已知算子学习使得深度学习和传统方法兼容。图片由作者在 CC 4.0 下通过许可创建。

已知算子学习的主要思想是我们不想学习我们已经知道的东西。这看起来很直观,但通常会触发机器学习专家。今天的范式是“知识在数据中”。如果你结合了先前的知识,那么你本质上是回到了石器时代。

我们在深度学习中观察到的恰恰相反。我们看到许多不同的体系结构正在被探索,最成功的是那些受传统技术或其他方法启发的体系结构,这些方法以某种方式将关于问题的知识编码到体系结构中。也有非常深入的方法,但这些方法也与已知的解决方案有关。所有这些方法都有一个主要缺点,那就是它们需要数百万个带注释的训练样本。

已知算子理论表明,最大误差界限随着网络中包括的每个已知运算而缩小。图片由作者在 CC 4.0 下经许可创作。

最近在自然机器智能发表的一篇论文证实了直觉,即先验知识有助于深度网络的最大误差分析。作者可以证明,每一个新的已知操作的最大误差界都减小了。在已知所有运算的限度内,误差减小到零。包含已知操作的另一个副作用是减少了网络的参数数量,这对所需训练样本的数量非常有利。虽然这些理论上的观察很有趣,但我们仍然需要一些实际的例子来检验这个结果。

CT 扫描仪的投影几何形状通常是经过校准的,并且是众所周知的。上面例子的在线实验环境可以在这里找到。图片由作者在 CC 4.0 下经许可创作。

作为第一个例子,我想强调计算机断层扫描(CT)。在 CT 中,我们通常设计扫描仪,其几何形状是众所周知的。CT 问题本身相当简单,因为它可以表示为一组线性方程,并且求解层析成像问题本质上与对矩阵求逆有关。不过有一个问题是,考虑中的矩阵相当大。对于具有 512 个体素和 512 个投影(每个投影具有 512 个像素)的常见 3-D 问题大小,待求逆的矩阵将需要 65.000 TB 浮点精度的存储。所以,简单的从零开始学习逆矩阵,即使在深度学习的时代,也不是一个可行的方案。

利用已知的算子,我们可以将 CT 重建问题分解成几个步骤,其中许多步骤是由几何定义的。图的下半部分显示了 PYRO-NN 中 CT 重建模型的代码。解析和迭代重建的代码示例见这里。作者在 CC 4.0 下经许可创作的图片。

使用已知的操作符,我们可以有效地解决这个问题。上面的例子表明矩阵求逆可以分解成几个步骤。以上所有步骤都有解析解和稀疏解。然而,这些解决方案仅适用于测量了所有所需数据的情况。结合深度学习和我们对问题的了解,我们现在可以确定第一层中的加权矩阵可能不适合不完整的扫描。因此,我们可以将已知和未知的操作按层排列,甚至可以将经典问题的解决方案用作初始化或预训练。

利用已知的算子学习,我们不仅受益于关于网络结构和较少参数的先验知识,而且我们还能够将权重映射回它们的原始域,以便用经典技术解释它们。图片由作者在 CC 4.0 下经许可创作。

有趣的是,我们不仅可以这样解决问题,还可以将训练好的权重映射回它们原来的解释。如果我们这样做,我们可以看到,初始化后的帕克等人重新训练,以形成右手边的权重。神经网络解决方案显示出与后来由谢弗及其同事提出的一种启发式方法惊人的相似。我们从砝码的配置中了解到,穿过不充分测量区域的射线被放大,以补偿确定性的质量损失。显然,这种方法也可以扩展到迭代技术,正如 Hammernik 等人所展示的。

如果我们没有关于这个问题的确切知识,我们仍然可以重用经典方法的思想,如作者在 CC 4.0 下通过许可创建的傅等人的图像所示。

然而,并不是所有的应用程序都允许像 CT 那样获取如此广泛的先验知识。因此,探索我们是否也可以重新使用经典方法是很有趣的。傅等人。在他们的 Frangi-Net 方法中这样做了。这个网络的灵感来自于弗兰基的血管过滤器。他们甚至证明了像特征值计算这样的操作可以用层来表示。因此,Frangi 过滤器的大部分结构可以重复使用。特别地,卷积层适合于针对特定应用的训练。在他们的结果中,他们可以表明,对少数样本的训练确实改进了方法,并允许更好的血管分割,接近 U-net 的性能。

在 Frangi 滤波器中训练卷积核允许改进血管分割。这个例子的代码可以在网上实验环境这里找到。图片由作者在 CC 4.0 下经许可创作。

到目前为止,我们已经看到,已知的操作符有助于产生可解释的结果,并允许我们用很少的例子来训练经典方法。我们在深度学习中通常面临的另一个大问题是结果不能很好地概括。我们将在最后一个例子中研究这个问题。

将 X 射线投影几何形状重新形成不同的空间配置通常使用逐射线插值来解决。由于 X 射线变换的线性性质,我们也能够将该问题表达为一组线性方程,无需对被扫描物体进行完全重建即可求解。由此产生的解决方案产生了一种新的网络拓扑,可以仅使用合成数据进行训练,如作者通过许可在 CC 4.0 下创建的 Syben 等人的图像所示。

同样,我们来看看医学成像,特别是 X 射线成像。一个典型的问题是 X 射线投影只能在遭受透视失真的投影成像几何结构中获得。特别是在整形外科中,这种位置相关的放大倍数是不理想的,如上图左侧所示。右手侧示出了不受放大影响的平行成像的理想情况。生成的图像以正交投影的形式显示所有内容,其中度量信息得以保留,无需额外的深度校准即可立即测量骨骼和裂缝的大小。

该动画显示了重排过滤器在迭代过程中的变化。左边显示了实际的滤波器配置,中间是一个训练样本和滤波器的当前输出之间的差异,右边是将当前滤波器配置直接应用于拟人幻像图像。这段代码也可以在在线实验环境这里获得。作者在 CC 4.0 下经授权创作的动画。

解决这个问题的现有方法需要对几个投影进行逐射线插值。这样做必然会降低图像的空间分辨率,从而降低其诊断价值。由于两种几何形状都可以表示为矩阵乘法,我们可以求解 x 的锥束投影,并将其代入平行束投影的方程。不幸的是,该解决方案现在有一个大的矩阵求逆,这在正向传递中校准和计算是昂贵的。正如我们在 CT 解决方案中已经观察到的,这个步骤通常可以表示为傅立叶域中的卷积或逐点乘法。因此,我们假设所需的解决方案采用这种形式,并继续为解决问题的新网络定义拓扑。结果令人印象深刻,该滤波器可以仅使用使用噪声和椭圆的合成示例来训练,并直接应用于新数据,例如如上所示的拟人化模型。

在我们基于 GitHub 的 PYRO-NN 代码库中找到更多已知的运算符示例代码。图片由作者在 CC 4.0 下经许可创作。

总之,我认为已知算子学习对于所有应用都是一种有趣的技术,在这些应用中,只有很少的训练数据,并且有众所周知的理论可用。为了集成到深层网络中,允许计算次梯度的任何操作都是合适的。这样,甚至可以使用高度非线性的操作,例如中值滤波器。事实上,已知的操作员学习已经在很长一段时间内呈上升趋势,例如在计算机视觉中,将整个光线跟踪器引入深度网络。我个人希望,已知的算子方法也将有助于提供对深度网络的更好理解,并使它们能够被重用,而不需要迁移学习方法。傅等人的一些初步结果表明这是可能的。因此,我认为这种方法很有趣,可能很适合你在工作中想要解决的问题。现在去我们的在线实验环境中编码,给已知的操作者一个尝试!

如果你喜欢这篇文章,你可以在这里找到更多关于深度学习的教育材料或者看看我的 YouTube 频道。本文在知识共享 4.0 归属许可下发布。

你想学 Rust 但是不知道从哪里开始

原文:https://towardsdatascience.com/you-want-to-learn-rust-but-you-dont-know-where-to-start-fc826402d5ba?source=collection_archive---------5-----------------------

Rust 初学者的完整免费资源

图片作者 @aznhe21

**Table of Contents**[**Introduction**](#e01a)🦀 [Rust Toolchains](#7486)
🦀 [Rust Free Online Books and Resources](#6919)
🦀 [Rust Official Links](#bf5d)
🦀 [Video Tutorials](#8051)
🦀 [Podcast](#6c39)
🦀 [Interactive Learning](#1526)
🦀 [Online Books & Tutorials](#3253)
🦀 [Cheat Sheets](#0a37)
🦀 [Rust Community](#4d09) 
🦀 [Coding Challenge](#7448)
🦀 [Rust IDE Extensions](#06f5)
🦀 [Rust Ecosystem](#eba3)
🦀 [Resource for Intermediate Users](#cedb)[**Conclusion**](#91f4)

介绍

[最新更新:2020 年 9 月 2 日]

Rust 是一种现代系统编程语言,专注于安全性、速度和并发性。

下图来自基准测试游戏,展示了 Rust 相比其他编程语言的速度。你可以在这里找到与 Go 语言的对比

图片来自基准测试游戏

在本文中,您将找到基本的 Rust 工具、最新文档、教程、视频和在线资源。

读完这篇文章后,你可以自己导航,开始以适合你学习风格的方式有效地学习 Rust 编程语言。

当你安装时,你正在安装rustccargorustup等标准工具。因此,在找到所有资源之前,让我们先了解一下 Rust 工具链是做什么的。

图片来自

防锈工具链

工具链是一组帮助语言产生功能代码的工具。它们可以从简单的编译器和链接器程序、附加库、ide 或调试器中提供扩展功能。

rustup

[rustup](https://github.com/rust-lang/rustup)安装 Rust 编程语言,使您能够在稳定版、测试版和夜间版编译器之间轻松切换,并保持更新。

您可以更新 Rust:

$ rustup update

作者快速参考

rustc

rustc是 Rust 编程语言的编译器。编译器获取你的源代码并生成二进制代码,要么是库,要么是可执行文件。您将使用Cargo而不是rustc运行 Rust 程序。

你可以在关于rustc参考中找到更多细节。

货物

图片来自货物册

是锈包经理。Cargo 下载你的 Rust 包的依赖项,编译你的包,制作可分发的包,并上传到 Rust 社区的包注册表 crates.io。

作者快速参考

其他官方工具

  • Clippy 是一种铁锈棉绒。
  • rustfmt 根据样式指南格式化 Rust 代码。

你可以在这个链接中找到官方的工具状态。

免费在线书籍和资源

在尝试其他资源之前,你无法避免使用生锈的编程语言。这是你需要阅读的第一本关于铁锈的完整的书。这本书涵盖了从初学者到高级用户的主题。它用大量的例子和图表解释了所有的细节。

图片来自Rust 编程语言

如果你多从例子中学习 举个例子 就适合你。这是一个可运行的例子集合,展示了各种 Rust 概念和标准库。你可以找到 20 多个例子。

锈由例

您可以在浏览器中编辑和运行 Rust 代码。

Rust by Example 中的代码示例

最后你会发现中级和高级在线资源。

Rust CookbookRust Cookbook是一组简单的例子,展示了使用 Rust 生态系统的板条箱完成常见编程任务的良好实践。

来自铁锈食谱的样本页面

信任官方链接

你可以在 锈官网 上找到很多信息。

一个板条箱是一个 Rust 二进制或库,你可以在 https://crates.io/找到 Rust 社区的板条箱注册表。

包装是提供一组功能的一个或多个板条箱。一个包包含一个 Cargo.toml 文件,该文件描述了如何构建这些板条箱。

铁锈标准库 提供了铁锈标准库文档。

铁锈操场 提供了 craits.io 下载量最高的 100 个板条箱和铁锈食谱中的板条箱。

其他资源

学锈 提供你需要的指南和文档。

你可以在 牛逼锈 按类别找到项目工具库。

黑色金属教材 通过幻灯片展示涵盖了基础知识到高级主题。它提供了示例代码,解释也很简洁。

生锈错误

如果想详细了解 Rust 错误, Rust 编译器错误索引 列举了所有 Rust 错误,并附有实例。

您的终端出错:

Rust 错误消息

Rust 编译器错误索引中的错误详细信息:

错误指数

视频教程

如果你喜欢从视频中学习,那么下面的视频将会帮助你。

播客

Rustacean Station 播客 是一个为 Rust 编程语言创建播客内容的社区项目。

铁锈的非官方吉祥物

互动学习

如果你喜欢边做边学,那么这些是给你的。

Rust 之旅 是一个逐步引导 Rust 编程语言特性的指南。它涵盖了基础知识、基本控制流、基本数据结构类型和泛型类型。

锈之旅

rustlings 有小练习让你习惯读写 Rust 代码。你可以把它和 Rust 编程语言一起使用。

您可以开始练习:

rultlings watch

当你保存文件时,它会自动检查答案并给你反馈。

作者图片

完成一个练习后,您需要删除该行:

// I AM NOT DONE

保存文件后,它将进入下一个练习。

rustlings提供有用的提示,给出文档链接。

作者图片

exercisem是 100%免费的代码练习和指导。它完全是开源的,依赖于成千上万志愿者的贡献。

它将指导你如何在你的计算机上安装它。你不仅可以学习 Rust,还可以学习其他 50 种编程语言。

当你在你的电脑上完成一个编码挑战时,你上传你的解决方案并和一个导师一起检查它。

**** [## 通过将 Python 转换成 Rust 来学习 Rust

Rust 基础入门教程

towardsdatascience.com](/learning-rust-by-converting-python-to-rust-259e735591c6) [## 一个全面的教程,以信任运营商的初学者

方法、相关函数、将 Python 转换成 Rust 等等

towardsdatascience.com](/a-comprehensive-tutorial-to-rust-operators-for-beginners-11554b2c64d4) [## 关于无符号、有符号整数和 Rust 中的造型,你应该知道什么

理解符号和幅度、一的补码和二的补码

towardsdatascience.com](/unsinged-signed-integers-and-casting-in-rust-9a847bfc398f)

在线书籍和教程

备忘单

Rust 社区

博客和时事通讯

我在哪里可以得到帮助?

Rust Discord 有很多活跃成员,其中一个版块是给初学者的。

Rust Discord 初学者部分

Rust 用户论坛 是关于 Rust 编程语言的帮助、讨论和公告。

Rust 用户论坛

stack overflow有超过 16000 个问题。 Shepmaster 是世界上第一家 Rust 咨询公司的联合创始人,他回答了许多 Rust 的问题。

Reddit 的“Rust 编程语言”有 105,000 名成员。

https://www.reddit.com/r/rust/

在 Twitter 上关注的人

#rustlang#learnrust# learningrust
Rust lang
史蒂夫·克拉布尼克
艾丹·霍布森·塞耶斯
阿什莉·威廉姆斯
卡罗尔·尼科尔斯
尼科·马萨基斯
尼克·卡梅隆

Rust 聚会

有很多 Rust Meetup 群 运行在线会议。您也可以在 Rust 社区日历 中找到会议。

编码挑战

  • LeetCode 有很多问题你可以用 Rust 在线解决。
  • exercisem . io在铁锈赛道上有 92 次练习。
  • 球体在线判断 有很多问题你可以挑战。
  • 您参与编写您在 CodinGame 直接在线玩的游戏的代码。你可以用 Rust 写你的代码。

防锈扩展

你可以在这里找到你的编辑器的 Rust 集成。如果你是 VS 代码用户,可以安装 rls-vscode 扩展。

Rust 语言服务器,RLS 提供了一个在后台运行的服务器,为 ide、编辑器和其他工具提供有关 Rust 程序的信息。它支持代码完成,跳转到定义,代码格式化,以及更多的

Rust Lang 编译器团队创建了 rls-2.0 工作组。目标是让用户获得更好的 RLS 体验。

你可以在rust-analyzer中找到它们的实现,rust-analyzer 支持不同的ide

你可以在 找到你的编辑有多支持 Rust 我们(我)DE 了吗?

铁锈生态系统

crates.io 可以找到很多库。这里有一些你可能感兴趣的类别。

Web 框架

根据 Web 框架基准测试,Actix 是最快的框架。有十个活跃的 Rust web 框架。 Actix 火箭 哥谭 种子 等。你可以从 web 框架对比中找到更多信息。

Web 开发

最快的铁锈模板引擎,旗鱼。它声称比车把快 200 倍。

WebAssembly(最新更新:2020 年 6 月 29 日)

如果你对 WebAssembly 感兴趣,那么下面的链接会对你有所帮助。

建立工作关系网

  • 锈官方页面上 联网

嵌入式设备

桌面开发

FLTK 图形用户界面库的 Rust 绑定, fltk-rs 。视频教程这里

数据科学

  • 《数据科学之家》有一系列关于 Rust 和机器学习的播客。
  • Amadeus 在 Rust 中提供了和谐的分布式数据分析。
  • ndarray 相当于 Python 的 numpy。

游戏开发(最新更新,2020 年 7 月 13 日)

终端(最新更新,2020 年 7 月 13 日)

  • 锈官方页面上的 命令行应用
  • Rustbox 是一个提供 API 的库,允许程序员编写基于文本的用户界面。
  • Tui-rs 是一个构建丰富终端用户界面和仪表盘的 Rust 库。
  • termin是一个纯 Rust、无绑定的库,用于低级处理、操作和读取关于终端的信息。
  • Crossterm 是一个纯粹的终端操作库,它使得编写跨平台的基于文本的界面成为可能。
  • Pancurses 是 Rust 的 curses 库,它提供了一个比普通 curses 函数更质朴的界面以方便使用,同时与 curses 保持足够的接近以方便移植。
  • StructOpt 通过定义一个 struct 来解析命令行参数。它结合了clap和自定义派生。
  • 或者命令行参数解析器是一个简单易用、高效且完全可配置的库,用于解析命令行参数。
  • Gtk-rsRust 绑定用于 GTK+ 3CairoGtkSourceView 和其他 GLib 兼容的库。它提供了许多现成的 UI 小部件。

操作系统开发

OSDev,Rust 贴子中的操作系统开发给出了 RustOSDev 工具和库最重要变化的常规概述。

其他语言的 Rust 绑定

[**bindgen**](https://github.com/rust-lang/rust-bindgen)自动生成到 C(和一些 C++)库的 Rust FFI 绑定。

PyO3 包括运行 Rust 二进制中的 Python 代码并与之交互。
玛拉的博客 经历了创建 inline-python 的过程。

你可以在 carates.io 找到更多绑定。

序列化和反序列化

Serde 是一个序列化和反序列化 Rust 数据结构的框架。

序列化采用内存中的数据结构,并将其转换为一系列可以存储和传输的字节。反序列化接受一系列字节,并将其转换为可以以编程方式使用的内存中数据结构。

ORM

Diesel 是 Rust 的一个安全的、可扩展的 ORM 和查询构建器。

中间用户的资源

如果你喜欢冒险,你可以看看下面这些。

新手教程

边做边学

嵌入式系统

结论

有数以百万计的网上资源。希望你找到最合适的学习资源,开始学习 Rust 编程语言。

如果我错过了什么,请让我知道。

通过 成为 会员,获得媒体上所有故事的访问权限。

请订阅。

**** [## Rust-Powered 命令行实用程序可提高您的工作效率

您腰带下的现代快速工具

towardsdatascience.com](/rust-powered-command-line-utilities-to-increase-your-productivity-eea03a4cf83a) [## 7 个强大的 Rust 驱动的命令行工具

适合每个开发人员的现代 Linux 命令

towardsdatascience.com](/awesome-rust-powered-command-line-utilities-b5359c38692)********

你的 AI 会让你尴尬

原文:https://towardsdatascience.com/your-ai-will-embarrass-you-fb17e55a97c2?source=collection_archive---------33-----------------------

去年 1 月的一个周末,两家全球领先的人工智能公司发现自己陷入了令人尴尬的错误。脸书的自动翻译无意中把“***”翻译成了“【Shithole 先生”(缅甸语),而苹果在 Siri 回复关于以色列的查询时提到“犹太复国主义占领国”后招致了批评

我不羡慕相关的公关团队,显然脸书和苹果犯了错误。但这里真正的教训不是关于硅谷偏见或反犹太主义或文化敏感性。是关于 AI 的。具体来说,不要使用人工智能,除非你能容忍令人震惊的令人尴尬的错误。

只要 AI 犯了任何错误,它就会犯令人尴尬的错误。这并不奇怪。对一个人工智能系统来说,动作要么正确,要么不正确。当 Google 相册将你的朋友标记为“朋友”时,这是正确的。其他都不正确。就人工智能而言,其他一切都是同样不正确的。

当然,世界并不完全是这样的。当 Google Photos 错误地将两个黑人标记为“大猩猩”时,其后果比它将一束芭蕉标记为“香蕉”要严重得多。

人工智能设计师当然可以尝试解决这个问题。他们可以给系统一个正确的标签 1 分,一个不正确的标签 0 分,一个引发地缘政治危机的标签负 1000 分。这也许能解决眼前的问题,但从长远来看,这是徒劳的。引发危机的错误是人工智能程序不太可能捕捉到的环境和社会细微差别的产物。

尽管人工智能倾向于产生令人难堪的错误,但它仍然是一个非常有价值的技术家族。因此,值得回顾一下它成功部署的场景。

一个明显的例子是令人尴尬的错误完全可以接受的领域。广告就是一个很好的例子。只要广告平台继续印刷大量淫秽的钱,令人尴尬的错误可以被忽视。当一个网站向你展示一个你已经购买的产品的广告时,这是一个令人尴尬的错误。也许你会把它截图下来,并在推特上向你所有的关注者讲述在线广告商有多愚蠢。但也就到此为止了。就广告商而言,唯一的坏处是他们给你看了一个你不会买的东西的广告。换句话说,尴尬错误的唯一问题是它是一个错误。

在令人尴尬的错误不可接受的情况下,最好的方法是在模型和用户之间提供一层隔离。这就是谷歌最终在前述案例中所做的:他们实施了一个黑客,当它产生像“大猩猩”、“黑猩猩”或“猿”这样的标签时,它会忽略图像识别模型关键的一点是,他们接受了这个模型将继续产生令人尴尬的错误,无论如何尝试修复它,所以他们设计了一个外部过程来改善这些错误。

如果系统不需要完全自动化,一个有效的方法是使用人工智能进行决策支持,而不是作为独立的决策者。这种模式在医疗保健领域可能尤为重要。IBM 的 Watson Health 报告了一些有希望的准确性指标,但它容易犯令人尴尬的危险错误,这破坏了它在医生中的可信度。在的一个令人难忘的例子中,它建议给严重出血的病人服用会加剧出血的药物。如果沃森被更明确地框定为一种工具,通过提出治疗方案供考虑来帮助医生,那么错误可能会更容易容忍。

关于人工智能将如何影响社会,有许多悬而未决的问题。这些问题的答案将取决于系统设计者和消费者如何处理令人尴尬的错误。例如,想象一下,自动驾驶汽车达到了统计上比人类司机更安全的程度,但少数致命事故是由无法解释的故障造成的。乘客会相信一个比人类司机更安全,但也更有可能在人类可以很好处理的情况下坠毁的人工智能吗?时间会证明一切。

人工智能带来了很多好处,毫无疑问,我们将继续看到它在各种各样的环境中使用。但在你决定将人工智能加入你的业务之前,花一点时间考虑一下,你将如何回应你的新工具侮辱中国国丨家丨主丨席。

你的机器学习模型完全指南

原文:https://towardsdatascience.com/your-complete-guide-to-machine-learning-models-403b4716172c?source=collection_archive---------42-----------------------

使用哪种模型,何时使用,为什么?如何调优你的算法?让我们一起投入进去吧!

照片由张秀坤镰刀Unsplash 上拍摄

简介

通常,你通过在互联网上寻找指南来开始你的机器学习研究,这些指南将帮助你——最终——将一个项目带入生活,对吗?

随着时间的推移,你开始意识到有很多东西要学,并开始思考你是否有能力做到。过于困难的教程、不充分的解释、问题;“也许我不够好,”你想。

在故事的结尾,你会准确地认出每一步。我们开始吧!

你今天会学到什么?

  • 如何选择将提供最佳结果的模型;
  • 创建机器学习模型所需的每个过程;
  • 如何准备您的数据:将分类转换为数值,填充空值,等等;
  • 如何创建功能,帮助您自动化您的工作过程,以及更多!

我们将使用 scikit-learn 库。在极简主义的定义中,每个机器学习过程都围绕这个库旋转。点击这里了解更多。

我应该使用哪种机器学习算法?

这是第一个问题,也是最重要的问题。如果选择了不正确的估计量(aka 模型),就会产生错误的推论。这通常取决于您的数据和您想要预测的内容。输出决定了这里的规则。

图片由雷南·洛里科拍摄——中号

回归

如果你需要预测几个数字输出,比如工资,这就需要一个回归估计器。与分类不同,回归估计量根据特征预测不同范围的未知数值。此外,度量标准也不一样。不要忘记。

问题

基于这些特性,会输出多少

试一试算法

技巧

  • 想要快速输出有效结果吗?选择决策树和随机森林,它们永远不会失败。默认参数是一个良好的开端。
  • 没有足够的数据,并希望您的模型能够正确概括?尝试线性回归、最近邻或支持向量机算法。
  • 没有一个像预期的那样有效?尝试使用 RandomizedSearchCV 或 GridSearchCV 调整您的默认参数。

分类

每当你需要预测某样东西是 A 还是 B(直到 Z)时,分类估计器是有用的。像这样的问题:是猫还是浣熊?哪个月更有可能发生?你用一个分类估计器来阐明这些问题。

问题

根据这些特性,会输出哪种类型的

试一试算法

技巧

  • 如果你的数据小于 100,000 个样本(分类样本),那么来自线性模型包的算法是一个好的开始;
  • 想要快速输出有效结果吗?从决策树和随机森林(系综和树包)开始。
  • 没有足够的数据,并希望您的模型能够正确概括?尝试最近邻或支持向量机算法。
  • 没有一个像预期的那样有效?尝试使用 RandomizedSearchCV 或 GridSearchCV 调整您的默认参数。

使聚集

当您需要根据样本的特征将样本分成不同的组合时,聚类算法非常有用。想根据客户的购买历史对他们进行分组吗?使用这种估计器。

问题

基于这些资源,他们如何表现

试一试算法

它们都来自集群包。

技巧

  • 每种方法都可以根据你想做的事情而有所不同,寻找合适的方法。
  • 不知道从哪里开始?试试 KMean 算法。

还有更多

你会注意到有更多的算法用于特殊用途,比如控制和关联等等。如果许多特征根本没有价值,我们使用第一种方法,因此我们清理数据集。其他的都是针对无监督学习和强化学习的,今天就不讨论了。

端到端机器学习模型创建

是时候创建我们的模型了。为了深入理解,请阅读我在代码中的所有主题。

关于我们的数据

我们将使用 UCI 提供的成人人口普查数据集,点击此处在网站上直接查看。背后的原因如下:

  • 有空条目,所以我们需要填充它。
  • 有分类值,所以我们需要将其转换成数字。

这是一个分类问题,我们想预测一个人的年收入是否超过 5 万英镑。我们期望一个布尔输出,如果大于 50K 将触发 true,如果小于 50K 将触发 false。让我们看看我们的数据集是什么样子的。

图片由雷南·洛里科拍摄——中号

1)数据清理

任何机器学习项目的第一步都是准备好你的数据。填充空值,删除未使用的列,等等。这里我想做的第一件事是为列输入正确的名称。

图片由雷南·洛里科拍摄——中号

2)数据争论

现在是时候对我们的数据进行必要的修改了。删除不正确的符号,并将少于两个唯一值的列转换为数字。

图片由雷南·罗利科拍摄——中号

3)探索性数据分析(EDA)

好了,现在我们的数据看起来更友好了。在这个阶段,你需要回答当前出现的疑问。在开始管理您的模型之前,您需要完全了解引擎盖下是什么,所以不要害羞。

图片由雷南·洛里科拍摄——中号

问题 1: 根据性别,年收入高于和低于 5 万英镑的员工的年龄和每周工作时间有什么区别?

图片由雷南·洛里科拍摄——中号

问题 2: 我们的数据分布如何?有离群值?

图片由雷南·洛里科拍摄——中号

问题 3: 工作类型如何影响目标?

图片由雷南·洛里科拍摄——中号

4)数据拆分

是时候了,让我们开始处理数据吧。首先,我们需要创建拆分。更准确地说,是训练和测试。

如果你在做一个复杂的项目,也许需要将你的数据分成训练、验证和测试。这里的不同之处在于,您只是从测试数据中得到推论,并通过使用验证来调整您的模型。我准备了一个函数来帮助你。

5)预处理

在这一阶段,您可以对数据进行任何类型的修改,如规范化、标准化、编码、输入等等。在进入代码之前,让我们看看我将在这里做什么:

  • 首先,我们将创建管道来估算缺失值并对我们的分类特征进行编码;
  • 最后,我将把这些管道放在 ColumnTransformer 中来修改我们的数据;

我已经添加了 LabelEncoder,但是这里没有需要,我们的目标(y)已经被编码了。好,让我们看看它在代码上是什么样子。

别担心,上面的代码什么都不做,我们以后会用到它。

6)基本分数

我们使用基本分数来大致了解我们的模型预测的好坏。在进行下一步之前,我们将删除得分最低的型号。我将使用三种不同的算法来创建模型:

  • 随机森林分类器
  • 近邻分类器
  • 线性 SVC

这是我们的产出。LinearSVC 确实是故意做的不好。图片由雷南·洛里科拍摄——中号

7)指标

每种模型类型都有自己的一套度量标准。它用于输出模型的精度。下面我们来看看最知名的。

  • 回归:回归指标基于平均值,即所有值的总和除以值的个数。最常用的是平均绝对误差(MAE)、均方误差(MSE)、均方根误差(RMSE)和均方根对数误差(RMSLE)。
  • 分类:根据分数,你可以检查你的推论有多少不一致性。一些指标是准确度、精确度、F1 分数、召回率、日志损失和二进制交叉熵。
  • 聚类:肘法大家都知道,但更多的有:剪影系数、高斯混合、贝叶斯信息准则(BIC)比如;

请记住,任何项目都需要它们,但一点也不复杂。如果有疑问,就谷歌一下。

8)超参数调谐

了解了初始模型在基本参数集下的表现后,现在是时候尝试改进您的设置了。我们将使用交叉验证方法,在数据的不同部分测试我们的参数。

a)随机搜索

这里没有什么玄机!你只需调整每个模型参数。最初,我们从 RandomizedSearchCV 开始,它将为每个参数随机选择一个值,并尝试寻找能够提供最佳结果的包。

图片由雷南·洛里科拍摄——中号

请注意,我已经创建了一个字典(第 4 行),它包含参数名,后跟一个可能值的列表。该字典放在 RandomizedSearchCV 的 param_distributions 参数中(第 19 行)。

b) GridSearchCV

根据项目的复杂程度,您需要强制搜索以进行改进。与为每个参数随机选择一个值的随机搜索不同,GridSearchCV 将尝试所有的值。

记住你传入随机搜索的参数多少并不重要,但是这里不能夸大,要注意。

你花在寻找改进上的时间越多,你的模型就变得越好。

在调整和评估您的模型之后,您将获得针对您的问题的最佳参数集。低于预期?试试别的型号。做得很好吗?可能是过拟合问题,下面来看看。

9)欠拟合和过拟合

这是一个额外的部分。你需要知道你的模型会面临什么问题,如何度过。

图片由 scikit-learn

  1. 欠拟合(图 1)意味着你的算法不能很好地处理你的数据。第一个原因是没有足够的数据。此外,如果您的参数相关性不够,也会发生这种情况。来解决?尝试获取更多数据,应用更好的数据辩论,以及特性工程。如果你的模型一直输出不好的结果,也许你的数据不适合你的问题。
  2. 过拟合(图 3) 与上述刚好相反。你的估计值非常符合数据,相信我,这并不好。如果你的模型很好地学习了如何从训练数据中进行推断,你就会对新数据有问题。这通常是因为您已经用相同的数据训练和评估了您的模型,这就是为什么我们将数据集分为训练、验证和测试。
  3. 图 2 是你需要瞄准的目标。非常适合,但也有一些偏差。

10)最终模型

您已经为您的问题选择了最佳算法,学会了如何调整您的参数,并最终学会了如何防止一些问题。我们还讨论了评估模型的指标。很快,到目前为止你学到了很多。现在您可以创建最终的模型,即将投入生产的模型。

就这样,伙计们!

希望你已经喜欢上了这个内容,能够融会贯通的应用你的新知识!如果你想每天坚持学一些有趣的东西,如果你跟着我,我真的会很开心!

另外,你可以查看我的 Github 个人资料。我从事一些数据科学项目已经有一段时间了。所有的关键概念都可以学习和重用!

[## 雷南·洛利科——GitHub

在 GitHub 上注册你自己的个人资料,这是托管代码、管理项目和构建软件的最佳地方…

github.com](https://github.com/renfelo)

你的冠状病毒远程医疗健康应用程序可能被高估了:如何辨别

原文:https://towardsdatascience.com/your-coronavirus-telemedicine-health-app-might-be-overrated-29989a9f7343?source=collection_archive---------62-----------------------

使用合成数据的因果推理教程(第 2 部分)

作者的玻璃板照片。

我们会夸大我们的健康应用程序的有效性,声称它将新型冠状病毒感染的风险降低了 16.9%——而事实上它只会将这种风险降低 3.1%。

但是我们可以重新加权我们现实世界的证据结果,以提供更准确的风险降低估计值 2.3%或 2.2%。

使用合成数据回顾本两部分教程的第 1 部分:

我们的分析目标将是帮助我们模拟世界中的公共卫生当局减少新型冠状病毒(“冠状病毒”)感染。我们相信我们的 数字健康或远程医疗应用 可以帮助预防新的感染;例如,通过促进健康的生活方式选择——特别是在社交距离和就地庇护时——来降低冠状病毒感染的风险。但是要做到这一点,我们需要一个无偏的或统计上一致的(即,更大样本的无偏性)估计,来估计我们将要进行的干预的真实效果。

教程目标:理解因果假设如何改变我们对预测的解释,将它们推向解释。在量化我们的技术解决方案的影响之前,理解为什么需要这样做。

我们将学习:如何识别建模关联和因果效应之间的区别。如何通过 g 公式进行因果推理( Robins,1986Hernán 和 Robins,2006 )和倾向得分加权( Rosenbaum 和 Rubin,1983平野和伊本,2001;伦瑟福德和大卫安,2004 年。

我们将了解混杂因素如何使我们对假设的健康应用干预的潜在效果的估计产生偏差。从我们的合成数据中出现的偏差如下所示。

第一部分中,我们调查了一个合成的真实世界证据(RWE)数据集,该数据集受到最近一个涉及新冠肺炎种族差异的医疗保健案例的启发(加格等人,2020奥布里,2020 年。(合成数据是模拟的,而不是真实的,通常是为了教授或学习分析工具而创建的数据。)

我们学会了如何识别统计对比(如风险差异)和因果效应之间的差异。我们还看到了为什么在我们的分析中,一般来说,陈述因果机制(例如,有向无环图)和控制所有混杂因素(假设我们在我们的数据集中观察到了所有混杂因素)是不够的——正如在解释或预测模型中所做的那样( Shmueli,2010 )。

我们从第 1 部分中了解到,我们需要一种更好的方法来估计真实的总体或平均治疗效果 (ATE)。为了做到这一点,我们运行了一个较小的(n = 9600)随机对照试验(RCT ),其统计功效和证据要求与我们的 RWE 解释模型相同。我们随机将该应用分配给 50%的试验参与者。所有参与者都遵守了他们的治疗任务,该应用程序对感染风险的评估与 RWE 数据集相同。

在第 2 部分中,我们将使用与之前相同的三个个人级别变量来分析这个合成的 RCT 数据集:infection状态、app使用情况和race(为了简单起见,仅使用黑色或白色)。我们还将看到,如果种族真的是应用程序使用对感染风险的唯一混杂因素(即,如果我们观察了所有可能的混杂因素),那么我们可以仅使用我们的 RWE 数据集来估计 ate。这需要理解总期望的定律——一个我们实际上一直在使用的简单直观的概念——我们将在下面回顾。

  • 第 2 部分目标:考虑到种族是影响感染风险的唯一其他因素(即唯一的混杂因素),仅使用观察性 RWE 数据来正确估计应用程序在感染中的使用率。和以前一样,我们将 ATE 指定为用户之间的风险减去非用户之间的风险,或 风险差 (RD)。
  • 我们将学到什么:如何通过分别使用 g 公式(也称为 标准化 )和倾向得分加权来重新加权我们的 RWE 预测和结果,从而估计 ate。g 公式与明珠(2009)后门调整公式密切相关。

我们将用一个使用 RWE 数据报告 ATE 估计值的高级行动计划来结束第 2 部分。

数据集特征

实验(即随机化)RCT 数据在表experimental_rct中。(用附录中的 R 代码生成这个。)

glimpse(experimental_rct)## Observations: 9,600
## Variables: 3
## $ race      <chr> "White", "White", "White", "White", "White", "White", "Whit…
## $ app       <chr> "didn't use app", "didn't use app", "didn't use app", "didn…
## $ infection <chr> "0\. uninfected", "1\. infected", "0\. uninfected", "0\. uninfe…

每个观察值(即行)代表最初易感和未感染的独特个体。变量及其唯一值与第一部分中的相同:

knitr::kable(apply(experimental_rct, 2, unique))

我们的 RCT 数据集有 9600 个观测值。

解释性建模

单变量关联

相关矩阵

dummy_rct <- experimental_rct %>%
  dplyr::mutate(
    race = (race == "White"),
    app = (app == "used app"),
    infection = (infection == "1\. infected")
  )
knitr::kable(round(cor(dummy_rct), 4))

corrplot::corrplot.mixed(cor(dummy_rct))

第一部分中的 RWE 相关矩阵不同,race不再与app相关。这是因为我们随机分配了应用程序的使用。

按应用使用分类的感染(边际模型)

让我们首先检查我们的主要利益关系,就像我们对训练数据所做的那样。

experimental_rct %>%
  ggplot2::ggplot(ggplot2::aes(x = app, fill = infection)) +
  ggplot2::theme_classic() +
  ggplot2::geom_bar(position = "dodge") +
  ggplot2::ggtitle("Infections by App Usage")

df_rct <- with(
  experimental_rct,
  cbind(
    table(app, infection),
    prop.table(table(app, infection), margin = 1) # row proportions
  )
)
rct_rd <- df_rct[2,4] - df_rct[1,4]rct_rd # empirical RD
## [1] -0.03392808knitr::kable(df_rct) # row proportions

与第一部分一样,应用程序用户的感染率较低:只有 11.8%的用户受到感染,相比之下,非用户的感染率为 15.2%。然而,经验 RD 是-0.034,非常接近真实 ATE 的-0.031。这明显小于-0.169 的“错误 ATE 估计值”(即 RWE 抵制经验 RD),该值会误导公共卫生当局对我们的应用程序在减少冠状病毒感染方面的真实有效性的认识。

out_fisher_rct <- with(
  experimental_rct,
  fisher.test(app, infection)
)
out_fisher_rct## 
##  Fisher's Exact Test for Count Data
## 
## data:  app and infection
## p-value = 1.254e-06
## alternative hypothesis: true odds ratio is not equal to 1
## 95 percent confidence interval:
##  0.6623291 0.8415144
## sample estimates:
## odds ratio 
##  0.7466837

此外,有强有力的统计证据(即,统计显著性)表明,感染因应用使用情况而异(p << 0.001). (Note that this corresponds to a two-sided hypothesis test; our RCT hypothesis is one-sided.) Here, the estimated odds of infection for app users were 0.747 (i.e., roughly three quarters) that of non-users, with a 95% confidence interval (CI) of (0.662, 0.842).

out_epi.2by2 <- epiR::epi.2by2(
  with(
    experimental_rct,
    table(app == "didn't use app", infection == "0\. uninfected")
  )
)
out_epi.2by2$res$ARisk.crude.wald / 100##           est       lower       upper
## 1 -0.03392808 -0.04757939 -0.02027677 

The corresponding estimated RD with 95% CI is -0.034 (95% CI: -0.048, -0.02). (Note that this corresponds to a two-sided hypothesis test; our RCT hypothesis is one-sided.) That is, we’re 95% confident that using the app lowered the risk of infection by somewhere between 0.02 and 0.048. Note that this is now a statement about a causal effect, not a statistical association.

We 可能到此为止,因为我们设计了 RCT,以便正确估计 ate。回顾第 1 部分的,ATE 在统计学上是一个边际量,因为它没有考虑(即“被边缘化”)任何其他变量。除了潜在的干预(这里是应用程序使用)之外,还考虑了其他变量(这里是种族)的模型被称为条件模型。

但是在解释模型部分,我们将继续拟合第 1 部分条件模型,该模型包括作为混杂因素的race。在下一部分(因果推断:这是定律),我们将看到如何“汇总”来自该模型的预测,使其等于我们估计的 RD。然后,我们将学习如何使用相同的程序,使用我们的原始 RWE 数据,以统计一致的方式估计 ate。

按种族分列的感染情况

正如在第一部分中,种族似乎与感染联系在一起。

experimental_rct %>%
  ggplot2::ggplot(ggplot2::aes(x = race, fill = infection)) +
  ggplot2::theme_classic() +
  ggplot2::geom_bar(position = "dodge") +
  ggplot2::ggtitle("Infections by Race")

df_rct_race_infection <- with(
  experimental_rct,
  cbind(
    table(race, infection),
    prop.table(table(race, infection), margin = 1) # row proportions
  )
)
knitr::kable(df_rct_race_infection) # row proportions

out_fisher_rct_race_infection <- with(
  experimental_rct,
  fisher.test(race, infection)
)
out_fisher_rct_race_infection## 
##  Fisher's Exact Test for Count Data
## 
## data:  race and infection
## p-value < 2.2e-16
## alternative hypothesis: true odds ratio is not equal to 1
## 95 percent confidence interval:
##  0.1302266 0.1705730
## sample estimates:
## odds ratio 
##  0.1490586

和以前一样,非裔美国人比白人更有可能被感染(按种族划分的应用使用情况)

与我们在第一部分的中的 RWE 发现不同,race不再与app相关。同样,这是因为我们随机化了应用程序的使用。

解释性模型

experimental_rct %>%
  ggplot2::ggplot(ggplot2::aes(x = race, fill = app)) +
  ggplot2::theme_classic() +
  ggplot2::geom_bar(position = "dodge") +
  ggplot2::ggtitle("App Usage by Race")

df_rct_race_app <- with(
  experimental_rct,
  cbind(
    table(race, app),
    prop.table(table(race, app), margin = 1) # row proportions
  )
)
knitr::kable(df_rct_race_app) # row proportions

out_fisher_rct_race_app <- with(
  experimental_rct,
  fisher.test(race, app)
)
out_fisher_rct_race_app## 
##  Fisher's Exact Test for Count Data
## 
## data:  race and app
## p-value = 0.6156
## alternative hypothesis: true odds ratio is not equal to 1
## 95 percent confidence interval:
##  0.917487 1.160591
## sample estimates:
## odds ratio 
##    1.03189 

因果模型

第 1 部分中,回想一下解释模型由因果模型和统计模型组成。因果模型通常被指定为有向无环图(DAG) ( 珀尔,2009 )。我们假设真正的 DAG 是:

应用使用→感染

  1. 种族→感染
  2. 比赛→应用程序使用
  3. 在这里,种族混淆了应用程序使用对感染的影响。
DiagrammeR::grViz("
digraph causal {

  # Nodes
  node [shape = plaintext]
  Z [label = 'Race']
  X [label = 'App \n Usage']
  Y [label = 'Infection']

  # Edges
  edge [color = black,
        arrowhead = vee]
  rankdir = LR
  X -> Y
  Z -> X
  Z -> Y

  # Graph
  graph [overlap = true]
}")

检查样本量

对于每个应用程序的使用和种族组合,我们有足够大的样本来满足我们的第一部分统计功效和证据要求吗?

是的:每个应用程序使用群体中至少有 556 名非裔美国人,同样至少有 1617 名白人。

experimental_rct %>%
  ggplot2::ggplot(ggplot2::aes(x = race, fill = app)) +
  ggplot2::theme_classic() +
  ggplot2::geom_bar(position = "dodge") +
  ggplot2::ggtitle("App Usage by Race")

df_rct_race_app <- with(
  experimental_rct,
  cbind(
    table(race, app),
    prop.table(table(race, app), margin = 1) # row proportions
  )
)
knitr::kable(df_rct_race_app) # row proportions

拟合统计模型

我们拟合我们的 RCT 逻辑模型如下。

在控制种族后,有强有力的统计证据(p << 0.001) for the estimated effect of app usage on infection risk. There is also very strong statistical evidence (p <<< 0.001) for race’s association with infection risk. Specifically, the estimated odds of infection for Whites were exp(-1.909) = 0.148 (95% CI: 0.13, 0.169) times that of African Americans (regardless of app usage).

glm_rct <- glm(
  data = experimental_rct,
  formula = as.factor(infection) ~ app + race,
  family = "binomial"
)
knitr::kable(summary(glm_rct)$coefficients)

The estimated odds of infection for app users were exp(-0.313) = 0.731 (95% CI: 0.645, 0.828) times that of non-users (regardless of race). The corresponding estimated infection risks for app usage by race are:

0.441 for African Americans not using the app

risk_didnt_use_app_black_rct <- plogis(coef(glm_rct) %*% c(1, 0, 0)) risk_used_app_black_rct <- plogis(coef(glm_rct) %*% c(1, 1, 0)) risk_didnt_use_app_white_rct <- plogis(coef(glm_rct) %*% c(1, 0, 1)) risk_used_app_white_rct <- plogis(coef(glm_rct) %*% c(1, 1, 1))
  • 0.365 for African Americans using the app
  • 0.105 for Whites not using the app
  • 0.079 for Whites using the app
  • The estimated RDs by race are:

-0.075 (95% CI: -0.1, -0.047) for African Americans

rct_rd_black <- risk_used_app_black_rct - risk_didnt_use_app_black_rct
rct_rd_white <- risk_used_app_white_rct - risk_didnt_use_app_white_rct
confint_glm_rct <- confint(glm_rct) # 95% CIs: odds ratios of infection
rct_rd_ci_black <- c(
  plogis(confint_glm_rct[, 1] %*% c(1, 1, 0)) - plogis(confint_glm_rct[, 1] %*% c(1, 0, 0)),
  plogis(confint_glm_rct[, 2] %*% c(1, 1, 0)) - plogis(confint_glm_rct[, 2] %*% c(1, 0, 0))
)
rct_rd_ci_white <- c(
  plogis(confint_glm_rct[, 1] %*% c(1, 1, 1)) - plogis(confint_glm_rct[, 1] %*% c(1, 0, 1)),
  plogis(confint_glm_rct[, 2] %*% c(1, 1, 1)) - plogis(confint_glm_rct[, 2] %*% c(1, 0, 1))
) 
  • -0.026 (95% CI: -0.028, -0.02) for Whites
  • Causal Inference: It’s the Law

Rolling Up the Conditional Estimated Risks

随机对照试验

我们可以使用解释模型的估计系数来预测每个人的感染风险。

每个raceapp组合的预测风险为:

experimental_rct_preds <- experimental_rct %>%
  dplyr::mutate(predicted_risk = predict(object = glm_rct, type = "response"))
tbl_estimated_risks_rct <- experimental_rct_preds %>%
  dplyr::select(race, app, predicted_risk) %>%
  dplyr::distinct() %>%
  dplyr::arrange(race, app)

这些预测的风险只是我们之前计算的按种族划分的应用程序使用的估计感染风险。(请注意,虽然在分类中使用了诸如此类的预测概率,但它们不是分类意义上的“预测”。后者只能取“用过的 app”或“没用过的 app”的值,而不是连续概率。预测的风险是通过标准统计的“预测”,而不是机器学习的定义。)

knitr::kable(tbl_estimated_risks_rct)

我们通过对应用程序用户和非用户的种族类别取平均值,将这些估计风险“累积”到应用程序使用水平。

但是我们从这些平均估计风险中计算出的估计研发与我们之前计算出的经验研发完全相同!

tbl_aac_rct <- experimental_rct_preds %>%
  dplyr::group_by(app) %>%
  dplyr::summarize(mean_preds = mean(predicted_risk))
estimated_AAC_rct <- tbl_aac_rct$mean_preds[2] - tbl_aac_rct$mean_preds[1]knitr::kable(tbl_aac_rct)

现实世界的证据

rct_rd # RCT: empirical RD## [1] -0.03392808estimated_AAC_rct # RCT: RD from average estimated risks## [1] -0.03392808

所以我们不能用我们的 RWE 估计风险来做类似的估计吗?

显然不是!发生了什么事?

# RWE: empirical RD
df_rwe_holdout <- with(
  observational_rwe_holdout, # see Part 1 to generate this:
    # https://towardsdatascience.com/coronavirus-telemedicine-and-race-part-1-simulated-real-world-evidence-9971f553194d
  cbind(
    table(app, infection),
    prop.table(table(app, infection), margin = 1) # row proportions
  )
)
rwe_holdout_rd <- df_rwe_holdout[2,4] - df_rwe_holdout[1,4]

# RWE: RD from average estimated risks
observational_rwe_preds <- observational_rwe_holdout %>%
  dplyr::mutate(predicted_risk = predict(object = glm_rwe_holdout, type = "response"))
tbl_estimated_risks_rwe <- observational_rwe_preds %>%
  dplyr::select(race, app, predicted_risk) %>%
  dplyr::distinct() %>%
  dplyr::arrange(race, app)
tbl_aac_rwe <- observational_rwe_preds %>%
  dplyr::group_by(app) %>%
  dplyr::summarize(mean_preds = mean(predicted_risk))
estimated_AAC_rwe <- tbl_aac_rwe$mean_preds[2] - tbl_aac_rwe$mean_preds[1] knitr::kable(tbl_estimated_risks_rwe)

knitr::kable(tbl_aac_rwe)

rwe_holdout_rd # RWE: empirical RD## [1] -0.1693528estimated_AAC_rwe # RWE: RD from average estimated risks## [1] -0.1693528

总期望定律

假设我们测量了两个女人和六个男人的身高:

总体平均值

knitr::kable(tbl_lte_example)

整体平均身高只有 5.364。设 y_i 代表个人的身高 i = 1,…, n ,其中 n = 8。该总平均高度明确计算如下

或者:

总体平均值作为各组成部分的加权平均值

(woman1 + woman2 + man1 + man2 + man3 + man4 + man5 + man6) / 8## [1] 5.364126

但是整体平均身高也是:

换句话说,使用类似于我们之前使用的代码:

((woman1 + woman2) / 2) * (2/8) + ((man1 + man2 + man3 + man4 + man5 + man6) / 6) * (6/8)## [1] 5.364126

总体平均值与分量加权平均值的关系

tbl_lte_example_components <- tbl_lte_example %>%
  dplyr::group_by(gender) %>%
  dplyr::summarize(mean_height = mean(height))
knitr::kable(tbl_lte_example_components)

tbl_lte_example_components[2, 2] * prop.table(table(tbl_lte_example$gender))[2] +
  tbl_lte_example_components[1, 2] * prop.table(table(tbl_lte_example$gender))[1]## mean_height ## 1 5.364126 

女性设 z_i = 1,男性设 z_i = 0。平均身高是:

每种性别的比例是:

上面的计算将这两个成分的平均值相加,但它按各自的成分比例对每个成分的平均值进行加权。因此,这个加权平均值等于总平均高度:

这种等价的说法是 总期望定律 (LTE)的一种表述:总平均值是按各成分比例加权的成分平均值之和。

## [1] "(5.078 * 0.25) + (5.459 * 0.75) = 5.364"## [1] "((woman1 + woman2) / 2) * (2/8) + ((man1 + man2 + man3 + man4 + man5 + man6) / 6) * (6/8) = 5.364"

有关 LTE 的定义,请参见附录。

将 LTE 应用于我们的数据

现实世界的证据:应用程序用户

现在,让我们将 LTE 应用于我们的 RWE 维持数据。为简单起见,我们只看应用程序用户;类似的推理也适用于 app 非用户。

在应用程序用户中,总体估计风险为:

平均估计风险为:

每个种族的比例是:

两个种族类别的平均估计风险的加权平均值等于总估计风险:

最后一个等价关系来自逻辑回归的定义。下面是一些明确做到这一点的代码:

## [1] "(0.077 * 0.952) + (0.365 * 0.048) = 0.09 = 0.09"

与我们以前用来计算经验 RD 的代码相比,我们以前的代码没有明确地对特定种族的平均估计风险进行平均:

observational_rwe_preds %>%
  dplyr::filter(app == "used app") %>%
  dplyr::mutate(
    weight_Black = (race == "Black") * mean(observational_rwe_holdout$race[observational_rwe_holdout$app == "used app"] == "Black"),
    weight_White = (race == "White") * mean(observational_rwe_holdout$race[observational_rwe_holdout$app == "used app"] == "White"),
    predicted_risk_weighted = predicted_risk * (race == "Black") * weight_Black +
      predicted_risk * (race == "White") * weight_White
  ) %>%
  dplyr::group_by(race) %>%
  dplyr::summarize(mean_preds_weighted_rwe = mean(predicted_risk_weighted)) %>%
  dplyr::summarize(sum_mean_preds_weighted_rwe = sum(mean_preds_weighted_rwe))## # A tibble: 1 x 1
##   sum_mean_preds_weighted_rwe
##                         <dbl>
## 1                      0.0905

随机对照试验:应用程序用户

observational_rwe_preds %>%
  dplyr::filter(app == "used app") %>%
  dplyr::summarize(mean_preds = mean(predicted_risk))## # A tibble: 1 x 1
##   mean_preds
##        <dbl>
## 1     0.0905 

现在,让我们将 LTE 应用于 RCT 数据。同样,我们只看应用程序用户。我们将使用完全相同的公式。

在应用程序用户中,总体估计风险为 0.118。平均估计风险为:

白人 0.079

  • 非裔美国人 0.365
  • 每个种族的比例是:

0.863 白色

  • 0.137 非裔美国人
  • 两个种族类别的平均估计风险的加权平均值等于总估计风险:

下面是一些明确做到这一点的代码:

## [1] "(0.079 * 0.863) + (0.365 * 0.137) = 0.118 = 0.118"

你能找出 RWE 和 RCT 的四个相应组件之间的主要区别吗?这种差异开启了 g 公式的关键洞见。

experimental_rct_preds %>%
  dplyr::filter(app == "used app") %>%
  dplyr::mutate(
    weight_Black = (race == "Black") * mean(experimental_rct$race[experimental_rct$app == "used app"] == "Black"),
    weight_White = (race == "White") * mean(experimental_rct$race[experimental_rct$app == "used app"] == "White"),
    predicted_risk_weighted = predicted_risk * (race == "Black") * weight_Black +
      predicted_risk * (race == "White") * weight_White
  ) %>%
  dplyr::group_by(race) %>%
  dplyr::summarize(mean_preds_weighted_rct = mean(predicted_risk_weighted)) %>%
  dplyr::summarize(sum_mean_preds_weighted_rct = sum(mean_preds_weighted_rct))## # A tibble: 1 x 1
##   sum_mean_preds_weighted_rct
##                         <dbl>
## 1                       0.118

G 公式

结果模型

我们假设种族和应用程序使用都会影响感染风险。我们之前 DAG 的相关部分是:

应用使用(X) →感染(Y)

  1. 种族(Z) →感染(Y)
  2. 到目前为止,我们一直在研究这个 DAG 对应的统计模型。在因果推理文献中,这通常被称为结果模型,因为它模拟了结果如何与其输入变量(输入)统计相关。我们的结果模型是作为app使用和race函数的infection风险的逻辑模型。
DiagrammeR::grViz("
digraph causal {

  # Nodes
  node [shape = plaintext]
  X [label = 'App \n Usage \n (X)']
  Z [label = 'Race \n (Z)']
  Y [label = 'Infection \n (Y)']

  # Edges
  edge [color = black,
        arrowhead = vee]
  rankdir = LR
  X -> Y
  Z -> Y

  # Graph
  graph [overlap = true]
}")

g 公式:标准化 RWE 估计

RCT 换人

在 RWE 的数据中,种族影响了应用程序的使用倾向。因此,应用程序用户比非用户更有可能是白人:

然而,在 RCT 的数据中,每个种族在应用程序用户和非用户中的比例非常相似:

knitr::kable(df_rwe_holdout_race_app_colprop) # column proportions

这是因为随机应用程序的使用使得它在统计上独立于种族。因此,特定于应用程序使用的比例接近总体种族比例,即:

knitr::kable(df_rct_race_app_colprop) # column proportions

也就是说,应用程序用户:

所以我们可以为所有的 i 设置 X_i =1,这样我们使用的比赛比例是:

这与从我们之前的代码中删除[experimental_rct$app == "used app"]是一样的,如下所示:

从统计学上来说,这种替代是可以接受的:我们只是用一个统计上一致的真实种族比例估计来替代另一个。但是如果我们用 RWE 的数据做这个会发生什么呢?

(
  experimental_rct_preds %>%
    dplyr::filter(app == "used app") %>%
    dplyr::mutate(
      weight_Black = (race == "Black") * mean(experimental_rct$race == "Black"),
      weight_White = (race == "White") * mean(experimental_rct$race == "White"),
      predicted_risk_weighted = predicted_risk * (race == "Black") * weight_Black +
        predicted_risk * (race == "White") * weight_White
    ) %>%
    dplyr::group_by(race) %>%
    dplyr::summarize(mean_preds_weighted_rct = mean(predicted_risk_weighted)) %>%
    dplyr::summarize(sum_mean_preds_weighted_rct = sum(mean_preds_weighted_rct))
)$sum_mean_preds_weighted_rct## [1] 0.1184267 

RWE 重新加权

使用我们的 RWE 数据集,让我们通过从我们之前的代码中删除[observational_rwe_holdout$app == "used app"],使用总体种族比例而不是特定应用使用比例来重新加权应用用户的平均估计风险,如下所示:

这个数量非常接近我们的 RCT 估计。我们使用以下代码对非用户应用同样的重新加权:

(
  observational_rwe_preds %>%
    dplyr::filter(app == "used app") %>%
    dplyr::mutate(
      weight_Black = (race == "Black") * mean(observational_rwe_holdout$race == "Black"),
      weight_White = (race == "White") * mean(observational_rwe_holdout$race == "White"),
      predicted_risk_weighted = predicted_risk * (race == "Black") * weight_Black +
        predicted_risk * (race == "White") * weight_White
    ) %>%
    dplyr::group_by(race) %>%
    dplyr::summarize(mean_preds_weighted_rwe = mean(predicted_risk_weighted)) %>%
    dplyr::summarize(sum_mean_preds_weighted_rwe = sum(mean_preds_weighted_rwe))
)$sum_mean_preds_weighted_rwe## [1] 0.1176694

我们计算出估计的 RD 为-0.023。相比之下,我们的 RCT 估计研发成本为-0.034。这两个估计值都比我们最初的 RWE 估计值-0.169 更接近真实值-0.031。

tbl_ate_gf <- observational_rwe_preds %>%
  dplyr::mutate(
    predicted_risk = predict(object = glm_rwe_holdout, type = "response"),
    predicted_risk_X1 = predict(
      object = glm_rwe_holdout,
      newdata = observational_rwe_holdout %>%
        dplyr::mutate(app = "used app"),
      type = "response"
    ),
    predicted_risk_X0 = predict(
      object = glm_rwe_holdout,
      newdata = observational_rwe_holdout %>%
        dplyr::mutate(app = "didn't use app"),
      type = "response"
    ),
    gformula_weight = (race == "Black") * mean(observational_rwe_holdout$race == "Black") +
      (race == "White") * mean(observational_rwe_holdout$race == "White"),
    predicted_risk_weighted = predicted_risk * gformula_weight
  ) %>%
  dplyr::group_by(app, race) %>%
  dplyr::summarize(mean_preds_weighted_rwe = mean(predicted_risk_weighted))
estimated_ATE_gf <- (tbl_ate_gf$mean_preds_weighted_rwe[3] + tbl_ate_gf$mean_preds_weighted_rwe[4]) -
  (tbl_ate_gf$mean_preds_weighted_rwe[1] + tbl_ate_gf$mean_preds_weighted_rwe[2])

重新加权过程可以更一般地表述为:

计算每个混杂值组合的比例(即混杂值的经验联合分布)。

  1. 根据步骤 1 中相应的混杂因素比例对估计的平均结果(取决于所有混杂因素)进行加权。
  2. 对于每个潜在的干预组,将这些加权估计值相加。
  3. 这个通用程序被称为 g 公式。 这些标准化总和的对比(如差异、比率)是 ate 的统计一致性估计。

直觉:标准化

这种重新加权的方法为什么有效?这个想法是,我们可以使用 RCT 以统计一致或无偏的方式估计 ate。但是,当我们只有 RWE 的数据时,我们仍然可以复制 RCT 打破混杂因素对潜在干预的影响的方式,从而打破统计关联。

对于每个潜在的干预组,g 公式通过(流行病学术语)RWE 的混杂因素分布标准化为相应 RCT 的混杂因素分布来实现这一点。由于随机化,后者与混杂因素的总体分布相同(即不考虑干预组)。

倾向得分加权

回想一下,在我们的 RWE 数据中,非裔美国人使用该应用程序的可能性低于白人:只有 27.2%的非裔美国人使用该应用程序,而白人的比例为 88.2%。也就是说,非裔美国人使用该应用的倾向为 0.272,而白人为 0.882。

倾向模型

observational_rwe_training %>%
  ggplot2::ggplot(ggplot2::aes(x = race, fill = app)) +
  ggplot2::theme_classic() +
  ggplot2::geom_bar(position = "dodge") +
  ggplot2::ggtitle("App Usage by Race")

knitr::kable(df_rwe_training_race_app) # row proportions

因果和统计模型

我们假设种族会影响应用程序的使用。我们之前 DAG 的相关部分是:

比赛(Z) →应用程序使用(X)

  1. 据说种族会影响应用程序的使用倾向。因此,在因果推理文献中,这种关系的统计模型通常被称为倾向模型。也就是说,它模拟了潜在的干预如何与其输入在统计上相关联。
DiagrammeR::grViz("
digraph causal {

  # Nodes
  node [shape = plaintext]
  Z [label = 'Race \n (Z)']
  X [label = 'App \n Usage \n (X)']

  # Edges
  edge [color = black,
        arrowhead = vee]
  rankdir = LR
  Z -> X

  # Graph
  graph [overlap = true]
}")

作为race函数的app使用的真实模型是在第 1 部分的附录中列出的逻辑模型。使用该应用程序的倾向以使用该应用程序的概率来衡量。在这种因果模型的背景下,这种概率因此被称为倾向得分 ( Rosenbaum 和 Rubin,1983 )。

实际上,我们不会知道这个真实的模型。但是,假设我们已经正确地对其建模,并估计其参数如下:

现在怎么办?

glm_rwe_holdout_ps <- glm(
  data = observational_rwe_holdout,
  formula = as.factor(app) ~ race,
  family = "binomial"
)
knitr::kable(summary(glm_rwe_holdout_ps)$coefficients)

直觉:调查抽样(霍维茨-汤普森权重)

使用我们应用的倾向就像一个选择过程:在这里,“被选择”使用应用取决于种族。

调查抽样 中,这种选择概率被用于概率抽样,以确保调查参与者代表他们被抽样的目标人群。这些概率是在调查设计中指定的,因此是预先完全知道的。

然后,这些选择概率可用于通过其相应选择概率的倒数或倒数对调查应答者的结果进行加权。这种被称为逆概率加权的通用技术提供了对平均结果(即整个目标人群的平均结果)的统计一致性估计。在调查抽样中,总体均值的回归估计量称为霍维茨-汤普森 (HT)估计量(霍维茨和汤普森,1952 )。

直觉上,每个回答者被加权,以代表在决定他们选择概率的因素中相似的个体。为了说明这一点,让我们回顾一下之前关于身高和性别的例子:

假设这八个人是从更大的目标人群(n = 10000)中抽取的小概率样本(n = 514)的一部分。生成目标群体和样本的代码是:

knitr::kable(tbl_lte_example)

在目标人群中(数字来自ourworldindata.org/human-height):

# generate target population
mean_height_women <- 5.21654 # from https://ourworldindata.org/human-height
mean_height_men <- 5.61024 # from https://ourworldindata.org/human-height
n_pop_htw_example <- 10000
sel_prob_women <- 0.01
sel_prob_men <- 0.09
set.seed(2004201426)
tbl_htw_example <- dplyr::tibble(
  gender = rbinom(n = n_pop_htw_example, size = 1, prob = 0.5),
  height = gender * rnorm(n = n_pop_htw_example, mean = mean_height_women, sd = 0.3) +
    (1 - gender) * rnorm(n = n_pop_htw_example, mean = mean_height_men, sd = 0.3),
  selected = gender * rbinom(n = n_pop_htw_example, size = 1, prob = sel_prob_women) +
    (1 - gender) * rbinom(n = n_pop_htw_example, size = 1, prob = sel_prob_men)
)

# select sample
tbl_htw_example_sample <- tbl_htw_example %>%
  dplyr::filter(selected == 1)

女性的平均身高是 5.217 英尺。

  • 男性的平均身高是 5.61 英尺。
  • 女性和男性的分布相当平均:51%是女性。
  • 真实人口平均身高为 5.406。
  • 女性以 0.01 的概率入选我们的样本,男性以 0.09 的概率入选。也就是说,男性被选入样本的可能性是女性的九倍;我们的样本中 90%是男性(n = 464)。因此,样本总体平均身高 5.555 高于真实人口平均身高 5.406。

然而,如果我们按照每个个体各自选择概率的倒数对其进行加权,将这些值相加,然后除以总人口规模,我们会得到加权平均值:

这更接近真实的人口平均身高 5.406。

with(
  tbl_htw_example_sample,
  sum(
    c(
      height[gender == 1] / sel_prob_women,
      height[gender == 0] / sel_prob_men
    )
  )/nrow(tbl_htw_example)
) ## [1] 5.498455

倾向得分:加权 RWE 结果

我们可以应用这样的 HT 估计器来估计 ate。在我们的案例中,在我们的 RWE 数据中有两种类型的“目标人群”:

潜在结果 如果每个人都使用过这个应用程序

  • 如果每个人都没有使用应用程序,潜在结果的人口
  • 每个潜在的结果(尼曼,1923鲁宾,1974Holland,1986 )根据个人的实际 app 使用情况进行观察。另一种未被观察到的潜在结果被称为反事实结果,或简称为反事实

我们根据每个人各自倾向得分的倒数对他们进行加权,将这些值相加,然后除以数据集中的总人数,得到每个应用使用组的加权平均值:

我们计算出估计的 RD 为-0.022。相比之下,我们的 RCT 估计研发成本为-0.034。这两个估计值都比我们最初的 RWE 估计值-0.169 更接近真实值-0.031。

tbl_ate_ps <- observational_rwe_holdout %>%
  dplyr::mutate(
    infection01 = (infection == "1\. infected"),
    app01 = (app == "used app"),
    propensityscore_used_app = predict(object = glm_rwe_holdout_ps, type = "response"),
    propensityscore_didnt_use_app = 1 - propensityscore_used_app
  )
estimated_risk_used_app <- with(
  tbl_ate_ps,
  sum(infection01[app01 == 1] / propensityscore_used_app[app01 == 1]) / nrow(tbl_ate_ps)
)
estimated_risk_didnt_use_app <- with(
  tbl_ate_ps,
  sum(infection01[app01 == 0] / propensityscore_didnt_use_app[app01 == 0]) / nrow(tbl_ate_ps)
)
estimated_ATE_ps <- estimated_risk_used_app - estimated_risk_didnt_use_app

结论和公共卫生影响

没有免费的午餐

我们已经成功应用了两种因果推断方法来估计应用程序使用对感染风险的真实影响。这些方法对于 ATE 来说在统计上是一致的,但是它们依赖于一些关键的假设为真:

没有无法测量的混杂因素:我们已经观察到了所有可能的混杂因素。

  • 正确的模型规范:我们已经正确地指定了因果模型和统计模型。(两者的区别和联系见第 1 部分。)也就是说,它们都正确地形式化了现实中发生的事情。当使用 g 公式时,这种假设适用于结果模型,当使用倾向得分加权时,这种假设适用于倾向模型。
  • 阳性:对于所有观察到的混杂值的每个独特组合(或至少对于所述值的每个粗略但大小合理的独特聚类),每个干预组中至少有一个人。
  • 你可以在 Hernán 和 Robins (2006)Hernán 和 Robins (2020) 以及在 Adam Kelleher 的媒体页了解更多关于这些和其他重要假设的信息。

是什么阻止我们将尽可能多的变量视为潜在的混杂因素(可能在交叉验证模型和变量选择之后)?为什么不应该把他们都纳入统计模型?对此,一个有趣的警告是“M 偏差” ( 丁和米拉特里克斯,2015 )。这是一种特殊类型的对撞机偏差 ( Pearl,2009 )产生于包含一个不是混杂因素的模型输入。争论的焦点是,由于诱导碰撞偏倚,包括这样的非混杂因素会使 ATE 估计有偏倚。

选择,选择

我们决定采用 RWE 解释模型。但是我们应该符合哪种统计模型呢?结果模型,还是倾向模型?我们的选择将在一定程度上取决于我们对拟合任一模型的信心。这个选择将决定我们是使用 g 公式还是倾向得分加权。

如果只有模棱两可的证据支持其中一个而不是另一个呢?或许我们不知道适合哪种模型。在这种情况下,有所谓的“双重稳健”估计器,它们利用了两种模型( Bang 和 Robins,2005 )。之所以这么称呼它们,是因为只有一个模型需要被正确地指定,以便估计器产生 ATE 的统计上一致的估计。

其他方法

至少有三种其他流行的方法能够使用 RWE 数据进行 ATE 估计和推断。

匹配:在这种方法中,一个干预组中的每个个体与另一个干预组中的至少一个其他个体匹配。匹配被指定为两个个体的混杂因素观察值之间的某种程度的相似性。这个想法是,任何留下的变异必须是由于潜在的干预——因此是一个可能的治疗效果。

  • 倾向分数匹配:如果有太多的混杂因素而无法找到好的匹配怎么办?一个得到广泛支持的解决方案是使用个人的倾向分数来匹配相反干预组中的个人,而不是( Hirano and Imbens,2001伦瑟福德和大卫安 M,2004
  • 工具变量:g 公式和倾向得分加权都要求我们已经测量了所有的混杂因素,并且已经将它们包含在我们的统计模型中。如果这不可能呢?假设我们仍然观察到另一个 RWE 变量,它有效地随机化了潜在的干预,没有受到任何混杂因素的影响,否则对我们的结果没有影响。这个变量是一个工具,我们可以用它来计算 ate 的统计一致性估计值(安格里斯特和伊本斯,1995 )。
  • 公共卫生影响

假设我们把【现实世界的证据】经验 RD 误认为是对 ate 的估计。我们不知道的是,在我们的模拟世界中,我们会夸大我们的远程医疗应用程序的有效性,声称它将新型冠状病毒感染的风险降低了 16.9%,而事实上它只会将这种风险降低 3.1%。

但是,我们可以对现实世界的证据结果进行重新加权,以提供 2.3%或 2.2%的更准确的风险降低估计值。

我们以以下高级行动计划结束第 2 部分:

为你的客户报告和解释你的 DAG,以及你的未调整的 ATE 估计。

  1. 调整混杂因素(例如,通过重新加权)。向客户报告并解释调整后的 ATE 评估。
  2. 参考

Angrist JD,Imbens GW。局部平均治疗效果的识别和估计。国家经济研究局;1995 年 2 月 1 日。https://www.nber.org/papers/t0118

总期望定律(续)

我们前面的性别身高例子中的陈述的更一般(抽象)的表达是

其中 E (。)是期望运算符。请注意,变量现在都是大写的,表明它们是随机变量(例如,由于随机抽样)——不像我们的身高性别示例中的小写固定变量。

期望算子取括号内随机变量的期望(即期望值均值)如下:

它将每个可能的值与其对应的概率相乘。

  1. 然后对所有这些进行求和。
  2. 不严格地说,期望运算符计算加权平均值——以概率作为权重。

表达式E(Y|Z)表示条件期望,其中 Y 的期望在给定值 Z 处接管所有 Y 。上面的一般表达式可以简洁地表述为

其中 E_Z (。)指定将括号内的表达式的期望值作为 Z 的所有值。

总期望的定律表示:

也就是说,随机变量 Y 的期望值等于在不同随机变量 Z 条件下 Y 的期望值的期望值,涵盖了 Z 的所有值。

RCT 模拟 R 代码

关于作者

*##### Set simulation parameters**### Preliminaries*
random_seed <- 2004101447
sample_size_observational <- 80000
holdout_proportion <- 0.2
sample_size_experimental <- sample_size_observational * holdout_proportion * 0.6*### Feature distribution*
piZ <- 0.755 / (0.755 + 0.127) *# race (based on U.S. Census)**### Outcome model**# beta0 and betaZ are derived from:*
*#   https://www.cdc.gov/mmwr/volumes/69/wr/mm6915e3.htm*
*#   https://www.npr.org/sections/coronavirus-live-updates/2020/04/08/830030932/cdc-hospital-data-point-to-racial-disparity-in-covid-19-cases*
*#   https://www.washingtonpost.com/news/powerpost/paloma/the-health-202/2020/04/09/the-health-202-los-angeles-is-racing-to-discover-the-true-coronavirus-infection-rate/5e8de70588e0fa101a75e13d/*prInfection <- 0.15
prBlack <- 1 - piZ
prWhite <- piZ
prBlackGivenInfection <- 33 / (33 + 45)
prWhiteGivenInfection <- 1 - prBlackGivenInfection
prInfectionGivenBlack <- prBlackGivenInfection * prInfection / prBlack
prInfectionGivenWhite <- prWhiteGivenInfection * prInfection / prWhitebeta0 <- log(prInfectionGivenBlack / (1 - prInfectionGivenBlack)) *# baseline: infection risk for* *African American**s who don't use app*
betaX <- -0.3
betaZ <- log(prInfectionGivenWhite / (1 - prInfectionGivenWhite)) - beta0 *# average influence of being White on infection risk**### Propensity model: app usage*
alpha0_experimental <- 0 *# randomized controlled trial: 0.5 randomization probability*
alphaZ_experimental <- 0 *# randomized controlled trial: 0.5 randomization probability**##### Generate data.*
set.seed(random_seed + 3)
experimental_rct <- dplyr::tibble(
  race = rbinom(n = sample_size_experimental, size = 1, prob = piZ),
  app = rbinom(n = sample_size_experimental, size = 1, prob = plogis(alpha0_experimental + alphaZ_experimental * race)),
  infection = rbinom(n = sample_size_experimental, size = 1, prob = plogis(beta0 + betaX * app + betaZ * race))
) %>%
  dplyr::mutate(
    race = ifelse(race == 1, "White", ifelse(race == 0, "Black", NA)),
    app = ifelse(app == 1, "used app", ifelse(app == 0, "didn't use app", NA)),
    infection = ifelse(infection == 1, "1\. infected", ifelse(infection == 0, "0\. uninfected", NA))
  ) 

Daza 博士是一名生物统计学家和健康数据科学家,而不是流行病学家,他为个性化(n-of-1)数字健康开发因果推断方法。| ericjdaza.com🇵🇭🇺🇸@埃里克森 t14】linkedin.com/in/ericjdaza|statsof1.org@ stats of@ fsbiostats

版权 2020 埃里克·j·达扎和 Stats-1。保留所有权利。

岗位也可在https://rpubs.com/ericjdaza/602430任职。

编者注: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里

Note from the editors:Towards Data Science is a Medium publication primarily based on the study of data science and machine learning. We are not health professionals or epidemiologists, and the opinions of this article should not be interpreted as professional advice. To learn more about the coronavirus pandemic, you can click here.

您的数据科学之旅从这里开始

原文:https://towardsdatascience.com/your-data-science-journey-kickstarts-here-9aa0253bd182?source=collection_archive---------22-----------------------

完全基于第一手经验的初学者指南

系好安全带。(来自 PexelsKun Fotografi 摄影)

你在这里是因为你一直想开始学习数据科学和机器学习。

你被互联网上所有可用的资源淹没了。

你不确定如何进入这个领域并获得一份工作。然而,你相信自己,想要成功。

几年前我去过那里,现在我整理了一本初学者指南,希望对你有所帮助。这篇指南大约有 2000 字长,但是我可以把它总结成 3 个字。是啊!三个。文字。

学习。

创造。

分享一下。

好了,我说了。但在我们继续之前,对我来说正确的做法是介绍我自己,向你表明我是根据个人经历来说话的。所以在写这篇文章的时候,我是 Trabeya 的机器学习工程师,也是 OpenMined 的导师。完成学士学位后,我作为一名应届毕业生开始从事数据科学领域的工作,尽管许多人建议我先获得硕士学位。相反,我继续做这个指南中的所有事情。

为了充分利用这个指南,我强烈建议你继续阅读直到最后,吸收其中的方法,并创建一个适合你的定制计划。我保证,今天是启动的好日子!

学习

你应该在做其他事情之前开始学习。不要听信那些说在线课程/证书不会让你得到工作的批评家。作为一个初学者,你还将如何获得相关的知识和技能?我们从学习开始,但不会止步于此。所以无论如何,坚持学习。

继续学习!(照片由蒂姆·莫斯霍尔德Unsplash 上拍摄)

但是等等,我该学什么?应该从哪里学起?我理解你的问题,因为我也有过。很多人会声称,除非你掌握了编程、统计学、数据库、机器学习、深度学习、可视化等等,否则你无法成为一名数据科学家。这是完全不正确的,你只需要一个基本的理解就可以开始,掌握它们是一个最终的过程。

眼前的第一个任务是评估你自己——你的优点和缺点。我对数学、编程和数据库相当熟悉,然而,我对统计学知之甚少。在重要的事情上做得不好没关系,关键是首先承认它,并努力做得更好。

不要浪费时间卷入 R 与 Python 的战争,如果你来自统计学/数学相关的背景,选择 R,在其他情况下选择 Python。我选择了 Python,但最终,像许多其他人一样,我两者都用了。

以下是我推荐的一些有用的资源,可以帮助你开始

基础

根据你目前的知识和技能,你可以跳过其中的一些,或者把它作为某种参考资料。

必须做的事

这个想法是为了更快地进入下一个阶段,在那里你将应用你所学的一切。因此,您不必提前完成以下所有课程,但它们是旅途中的必做之事。当你对一些概念感到熟悉时,进入下一阶段,稍后回来继续学习。这将是一个持续的循环。

  • 吴恩达在 YouTube 上的机器学习讲座:我不应该告诉你这个,但这是一个游戏规则的改变者!当你通过这门课程时,你会感觉到慢慢进入数据科学和机器学习。到目前为止,我回到这些讲座去查阅概念!
  • Coursera 上 deeplearning.ai 的深度学习专业化:吴恩达以此开始了深度学习教育的革命。它涵盖了从零开始到高级计算机视觉和 NLP 技术的深度学习中的每个基本概念。第三门课程的内容(构建机器学习项目)只能通过多年在行业和学术界的丰富工作经验来创建。我可以继续谈论这是多么有用!
  • 麻省理工学院计算机科学教育的缺失学期:我刚开始的时候没有这些,我不得不在各种网站上艰难地学习这些。帮你自己一个忙,学学这个,它被称为失踪的学期是有原因的。在这个行业里你需要的东西,没有教过的,这里都会教。

请注意,我只推荐了我曾经使用过并直接受益的资源,所以如果你遇到了其他你曾经直接使用过并受益的初学者资源,请在评论部分删除它。这对我和许多其他人都很有用。很快我会把我过去两年学习的完整课程放在一起,更详细,还有评论,敬请关注!

创造

创造,基本上任何有价值的东西。用你目前掌握的知识和技能可以做的任何事情。我创建了一个简单的日夜分类器,一个对远程工作文化的探索,以及更多。所有这些都非常简单。

创作时间到了!(照片由来自 Pexels蒂姆·莫斯霍尔德拍摄)

理解你需要尽快到达这个阶段是很重要的。初学者常犯的一个错误是试图先掌握几项技能。不要那样做。当你意识到当你创建一个可展示的投资组合的时候,你能从构建项目中学到多少东西时,你会感到惊讶。

以下是我对你能做些什么的一些建议,但这真的取决于你。你需要根据你的兴趣来选择。

  • Kaggle(过去/现在)比赛——这是我开始的地方,具体来说。凭借我仅有的一点知识,以及来自社区的令人难以置信的 Kaggle 笔记本的大量帮助,我做得很好。我并不是想赢得比赛,我只是想把我学到的一点东西应用到比赛中去。实际上,我被一家人工智能初创公司要求向团队展示这一点,结果他们喜欢我的方法,几场面试后——我被录用了。因此,这里有一个建议——前往 Kaggle,挑选任何激发你兴趣的比赛,开始应用你迄今为止学到的任何东西,不要犹豫从公开的 Kaggle 笔记本中寻求帮助。Kaggle 推荐开始最基础的一个就是传统的泰坦尼克号机器从灾难中学习。这是一个很好的起点,有助于你理解完整的机器学习管道。

我第一次参加 Kaggle - Home 信用违约风险竞赛

  • Udacity 项目——这些项目最初是一些 Nanodegrees 的一部分,但在其 GitHub 上开源,所以没有人阻止你浏览这些项目,并完成它们以添加到你的项目组合中。招聘人员喜欢听你如何不遗余力地完成激发你兴趣的项目!在我看来,Udacity 已经掌握了基于项目的学习艺术,完成纳米学位的最佳方式是通过奖学金。时刻关注他们的奖学金页面!
  • Omdena 合作项目 —在现实世界中,数据不会在竞争或存储库中交给你。你需要能够定义问题,收集数据,设计可行的方法,并部署解决方案 Omdena 是一个自下而上的协作平台,初学者到专家的人工智能实践者在这里致力于解决端到端的现实世界问题。在 COVID19 期间,我最近在《T4》中使用人工智能分析家庭暴力和网上骚扰,这种体验是独一无二的。我将继续和他们一起从事更多的伦理项目。申请和简短面试就能直接加入,如果你在这方面需要任何帮助,请联系我

请注意,这些只是帮助您入门,并有意保持简单。一旦你到了那里,我相信你会想出如何自己完成更高级更复杂的项目。让我们进入最后一个阶段,好吗?

分享

分享是游戏规则的改变者。

到现在你已经学会了一些概念,获得了相关的知识和技能,甚至创造了一些你可以引以为豪的东西。但是没有人知道你的能力,除非你和全世界分享。

与世界分享!(图片由来自 PexelsAndrea Piacquadio 拍摄)

有意识地努力分享你的学习和你创建的项目。就我个人而言,当我知道有人会看到这篇文章并可能从中受益时,我学得更好,创作出了更好的作品。

以下是一些基于对我有效的建议。

  • 在 LinkedIn 上分享你的成就并随时更新 LinkedIn 个人资料。招聘人员喜欢看到这一点。
  • 你建立的每个项目,你创建的每个笔记本都应该在你的 GitHub 上。对我来说,它是我创造的一切的集合。(有些人喜欢在 Kaggle 上分享一切,主要是因为这个社区很吸引人,所以也可以自由探索这个选项)
  • 分享可以为社区增加价值的内容。如果你是学生,向你的班级介绍一些有趣的话题。如果你是全职工作——向你的同事展示。在 LinkedIn 或任何你喜欢的平台上分享你的想法也是有效的。还有,尽量做到始终如一。
  • 开始写博客。通过博客分享你的学习、想法和故事。首先,发表一篇文章,带领读者了解你从事的项目。我不是提倡这一点的最佳人选,因为我刚刚起步,但雷切尔·托马斯(Fast.ai 的联合创始人)可以。她说服了我,我会让她告诉你为什么你应该开始写博客。我会把我的第一篇博客文章链接起来,让你知道它有多基础。

[## 远程工作——新标准?

通过数据驱动的分析更好地了解远程工作

towardsdatascience.com](/remote-work-the-new-norm-5d9beb956a85)

如果允许我改变我的旅程,那就是更早地开始分享。我以为我没有做任何有意义的事情来分享,但是我错了。当我开始的时候,许多人赞赏甚至受益。

概述

这是魔法咒语。学习。创造。分享一下。我一步一步,一遍又一遍地做着这一切。你猜怎么着?

你也能做到。等等,你可以做得更好。

当你做对了,你将开始发展相关的技能,并随着时间的推移掌握它们。你将开始无所畏惧地接近任何项目。当你与你的社区分享你的作品时,你将建立一个强大的志同道合的爱好者网络。交流你的作品对你来说并不新鲜。你会在工作中不断进步。一切都会水落石出。

相信我。

作为结束语,我需要你知道一些事情。

开始学习数据科学的方法不止一种,如果其他方法对您有用,我很高兴听到您的介绍并从中学习。如果你想让我写更多这样的话题,请在评论中分享你的反馈。如果我能帮上忙,请随时联系我。我迫不及待地想看到你成功!

作为披露的提示,本文中使用了一些附属链接来分享我使用过的最好的资源,并且没有额外的费用。

如果你想获得更多关于数据科学、有趣的合作和指导的有用见解,可以考虑 加入我的电子邮件好友私人名单

Python Matplotlib 的日常备忘单

原文:https://towardsdatascience.com/your-everyday-cheatsheet-for-pythons-matplotlib-c03345ca390d?source=collection_archive---------13-----------------------

照片由 Unsplash 上的 Jalitha Hewage 拍摄

完整的可视化课程

Matplotlib 是 python 中使用最广泛的可视化工具。它在广泛的环境中得到很好的支持,如 web 应用服务器、图形用户界面工具包、Jupiter notebook 和 iPython notebook、iPython shell。

Matplolib 架构

Matplotlib 有三个主要层:后端层、艺术家层和脚本层。后端层有三个接口类:定义绘图区域的图形画布,知道如何在图形画布上绘制的渲染器,以及处理用户输入(如点击)的事件。美工图层知道如何使用渲染器,在画布上绘制。Matplotlib 图中的所有内容都是艺术家图层的实例。这些记号、标题、标签、情节本身、一切都是艺术家的个人作品。脚本层是一个更轻便的界面,对于日常用途非常有用。在本文中,我将使用脚本层来演示所有的例子,并且我使用了一个 Jupyter 笔记本环境。

如果你阅读这篇文章是为了学习,我建议你自己运行每一段代码。

数据准备

数据准备是任何数据可视化或数据分析项目之前的一项常见任务。因为数据从来不会以你想要的方式出现。我正在使用一个包含加拿大移民信息的数据集。首先导入必要的包和数据集。

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.head()

我跳过了前 20 行和后 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')

我们不打算在本文中使用所有的列。因此,让我们去掉不使用的列,使数据集更小,更易于管理。

df.drop(['AREA','REG','DEV','Type','Coverage'], axis=1, inplace=True)
df.head()

看看这些柱子。列“OdName”实际上是国家名称,“AreaName”是洲,而“RegName”是洲的区域。将列名改为更容易理解的名称。

df.rename(columns={'OdName':'Country', 'AreaName':'Continent', 'RegName':'Region'}, inplace=True)
df.columns#Output:
Index([  'Country', 'Continent',    'Region',   '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')

现在,数据集变得更容易理解了。我们有国家,大洲,地区,设备名称来表示这个国家是发展中国家,还是发达国家。所有年份列都包含该年的移民人数。现在,添加一个“总数”列,显示从 1980 年到 2013 年从每个国家进入加拿大的移民总数。

df['Total'] = df.sum(axis=1)

看,末尾增加了一个新的栏目“总计”。

检查任何列中是否有空值

df.isnull().sum()

它在所有列中显示零 null 值。我总是喜欢设置一个有意义的列作为索引,而不仅仅是一些数字。

将“国家”列设置为索引

df = df.set_index('Country')

这个数据集从一开始就很好很干净。所以这是足够的清洁了。如果我们需要别的东西,我们会边走边做。

绘图练习

在本文中,我们将练习几种不同类型的绘图,如折线图、面积图、饼图、散点图、直方图、条形图。

首先,导入必要的包

%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib as mpl

选择一种风格,这样你就不用太费力去设计情节了。以下是可用的样式类型:

plt.style.available#Output:
['bmh',
 'classic',
 'dark_background',
 'fast',
 'fivethirtyeight',
 'ggplot',
 'grayscale',
 'seaborn-bright',
 'seaborn-colorblind',
 'seaborn-dark-palette',
 'seaborn-dark',
 'seaborn-darkgrid',
 'seaborn-deep',
 'seaborn-muted',
 'seaborn-notebook',
 'seaborn-paper',
 'seaborn-pastel',
 'seaborn-poster',
 'seaborn-talk',
 'seaborn-ticks',
 'seaborn-white',
 'seaborn-whitegrid',
 'seaborn',
 'Solarize_Light2',
 'tableau-colorblind10',
 '_classic_test']

我走的是‘gg plot’风格。你可以随意尝试其他风格。

mpl.style.use(['ggplot'])

线剧情

逐年观察一个国家移民加拿大的趋势是很有用的。列出 1980 年至 2013 年的清单。

years = list(map(int, range(1980, 2014)))

我选择了瑞士来做这个示范。准备瑞士的移民数据和年份。

df.loc['Switzerland', years]

下面是瑞士的部分数据。该出图了。这很简单。在我们准备的数据上调用 plot 函数就可以了。然后添加标题以及 x 轴和 y 轴的标签。

df.loc['Switzerland', years].plot()
plt.title('Immigration from Switzerland')
plt.ylabel('Number of immigrants')
plt.xlabel('Years')
plt.show()

如果要观察几个国家历年的移民趋势来对比那些国家对加拿大的移民趋势呢?这和前面的例子差不多。绘制三个南亚国家印度、巴基斯坦和孟加拉国的移民数量与年份的关系图。

ind_pak_ban = df.loc[['India', 'Pakistan', 'Bangladesh'], years]
ind_pak_ban.head()

看数据的格式。这与上面瑞士的数据不同。如果我们在这个数据帧上调用 plot 函数(ind_pak_ban),它将在 x 轴上绘制每个国家的移民数量,在 y 轴上绘制年份。我们需要改变数据集的格式:

ind_pak_ban.T

这不是整个数据集。只是一部分。看,数据集的格式是如何变化的。现在,它将在 x 轴上绘制年份,在 y 轴上绘制每个国家的移民数量。

ind_pak_ban.T.plot()

我们不必在这里提到这种图,因为默认情况下它绘制的是线图。

饼图

为了演示饼图,我们将绘制每个大陆的移民总数。我们有每个国家的数据。所以,把移民的数量分组,总结一下,每个大洲的移民总数。

cont = df.groupby('Continent', axis=0).sum()

现在,我们有数据显示每个大陆的移民数量。请随意打印此数据帧以查看结果。我没有展示它,因为它在水平方向上太大了,无法在这里展示。我们来画一下。

cont['Total'].plot(kind='pie', figsize=(7,7),
                  autopct='%1.1f%%',
                  shadow=True)
#plt.title('Immigration By Continenets')
plt.axis('equal')
plt.show()

注意,我必须使用' kind '参数。除了线图,所有其他图都需要在 plot 函数中明确提及。我引入了一个新的参数‘figsize ’,它将决定图的大小。

这个饼状图可以理解。但是我们可以通过一点努力来改善它。这次我想选择我自己的颜色和一个开始的角度。

colors = ['lightgreen', 'lightblue', 'pink', 'purple', 'grey', 'gold']
explode=[0.1, 0, 0, 0, 0.1, 0.1]
cont['Total'].plot(kind='pie', figsize=(17, 10),
                  autopct = '%1.1f%%', startangle=90,
                  shadow=True, labels=None, pctdistance=1.12, colors=colors, explode = explode)
plt.axis('equal')plt.legend(labels=cont.index, loc='upper right', fontsize=14)
plt.show()

这个饼状图更好吗?我喜欢它。

箱形图

我们先做一个中国移民人数的方框图。

china = df.loc[['China'], years].T

这是我们的数据。这是方框图。

china.plot(kind='box', figsize=(8, 6))
plt.title('Box plot of Chinese Immigratns')
plt.ylabel('Number of Immigrnts')
plt.show()

如果您需要复习箱线图,请查看这篇文章:

[## 使用直方图和箱线图理解数据,并举例说明

了解如何从直方图和箱线图中提取最多的信息。

towardsdatascience.com](/understanding-the-data-using-histogram-and-boxplot-with-example-425a52b5b8a6)

我们可以在同一块地上画几个箱线图。使用“ind_pak_ban”数据框,绘制印度、巴基斯坦和孟加拉国移民数量的方框图。

ind_pak_ban.T.plot(kind='box', figsize=(8, 7))
plt.title('Box plots of Inian, Pakistan and Bangladesh Immigrants')
plt.ylabel('Number of Immigrants')

散点图

散点图是理解变量之间关系的最佳方式。做一个散点图,看看这些年移民加拿大人数的趋势。

在这个练习中,我将制作一个新的数据框架,其中包含作为索引的年份和每年的移民总数。

totalPerYear = pd.DataFrame(df[years].sum(axis=0))
totalPerYear.head()

我们需要将年份转换成整数。我想稍微润色一下数据框,让它看起来更像样。

totalPerYear.index = map(int, totalPerYear.index)
totalPerYear.reset_index(inplace=True)
totalPerYear.head()

对于散点图,我们需要指定散点图的 x 轴和 y 轴。

totalPerYear.plot(kind='scatter', x = 'year', y='total', figsize=(10, 6), color='darkred')
plt.title('Total Immigration from 1980 - 2013')
plt.xlabel('Year')
plt.ylabel('Number of Immigrants')plt.show()

看起来年份和移民数量之间有线性关系。这些年来,移民的数量呈上升趋势。

面积图

面积图显示了线状图覆盖的面积。对于这个图,我想制作一个包括印度、中国、巴基斯坦和法国信息的数据框架。

top = df.loc[['India', 'China', 'Pakistan', 'France'], years]
top = top.T

数据集准备好了。现在绘图。

colors = ['black', 'green', 'blue', 'red']
top.plot(kind='area', stacked=False,
        figsize=(20, 10), colors=colors)plt.title('Immigration trend from Europe')
plt.ylabel('Number of Immigrants')
plt.xlabel('Years')
plt.show()

如果您想查看各个国家的面积图,记得使用上方的“堆叠”参数。如果未将堆叠参数设置为 False,则该图将如下所示:

未堆叠时,不显示单个变量的面积。它会叠加到前一个上。

柱状图

直方图显示了变量的分布。这里有一个例子:

df[2005].plot(kind='hist', figsize=(8,5))
plt.title('Histogram of Immigration from 195 Countries in 2010') # add a title to the histogram
plt.ylabel('Number of Countries') # add y-label
plt.xlabel('Number of Immigrants') # add x-label
plt.show()

我们做了一个直方图来显示 2005 年数据的分布。该图显示,加拿大大约有 0 到 5000 名来自大多数国家的移民。只有几个国家贡献了 20000 人,还有几个国家送出了 40000 名移民。

让我们使用散点图示例中的“顶部”数据框架,在同一张图中绘制每个国家的移民数量分布。

top.plot.hist()
plt.title('Histogram of Immigration from Some Populous Countries')
plt.ylabel('Number of Years')
plt.xlabel('Number of Immigrants')
plt.show()

在前面的柱状图中,我们看到加拿大有来自几个国家的 20000 和 40000 移民。看起来中国和印度是少数几个国家之一。在该图中,我们看不清楚容器的边缘。让我们改进这个情节。

指定箱数,找出箱边

我将使用 15 个箱子。我在这里引入了一个新的参数,叫做“alpha”。alpha 值决定了颜色的透明度。对于这些类型的重叠图,透明度对于查看每个分布的形状非常重要。

count, bin_edges = np.histogram(top, 15)
top.plot(kind = 'hist', figsize=(14, 6), bins=15, alpha=0.6, 
        xticks=bin_edges, color=colors)

我没有指定颜色。所以,这次出来的颜色不一样。但是看透明度。现在,你可以看到每个分布的形状。

像面积图一样,您也可以制作直方图的堆积图。

top.plot(kind='hist',
          figsize=(12, 6), 
          bins=15,
          xticks=bin_edges,
          color=colors,
          stacked=True,
         )
plt.title('Histogram of Immigration from Some Populous Countries')
plt.ylabel('Number of Years')
plt.xlabel('Number of Immigrants')
plt.show()

条形图

对于柱状图,我将使用每年来自法国的移民数量。

france = df.loc['France', years]
france.plot(kind='bar', figsize = (10, 6))
plt.xlabel('Year') 
plt.ylabel('Number of immigrants') 
plt.title('Immigrants From France')
plt.show()

您可以向条形图添加额外的信息。该图显示了自 1997 年以来十多年的增长趋势。值得一提的是。这可以使用注释功能来完成。

france.plot(kind='bar', figsize = (10, 6))
plt.xlabel('Year') 
plt.ylabel('Number of immigrants') 
plt.title('Immigrants From France')
plt.annotate('Increasing Trend',
            xy = (19, 4500),
            rotation= 23,
            va = 'bottom',
            ha = 'left')
plt.annotate('',
            xy=(29, 5500),
            xytext=(17, 3800),
            xycoords='data',
            arrowprops=dict(arrowstyle='->', connectionstyle='arc3', color='black', lw=1.5))
plt.show()

有时,水平显示条形会更容易理解。在酒吧展示一个标签会更好。让我们开始吧。

france.plot(kind='barh', figsize=(12, 16), color='steelblue')
plt.xlabel('Year') # add to x-label to the plot
plt.ylabel('Number of immigrants') # add y-label to the plot
plt.title('Immigrants From France') # add title to the plot
for index, value in enumerate(france):
    label = format(int(value), ',')
    plt.annotate(label, xy=(value-300, index-0.1), color='white')

plt.show()

不是比上一部好吗?

在本文中,我们学习了 Matplotlib 的基础知识。这将为您提供足够的知识,让您今天就开始使用 Matplotlib 库。

这里的高级可视化技术:

[## Python 中的交互式 Choropleth 地图

学习使用 Python 的叶库轻松开发 Choropleth 地图

towardsdatascience.com](/a-step-by-step-guide-to-interactive-choropleth-map-in-python-681f6bd853ce) [## 在 Python 中生成任意形状的单词云

学习生成一个单词云,设计它的样式并使用自定义形状

towardsdatascience.com](/generate-word-clouds-of-any-shape-in-python-e87f265f6352) [## Python 中的交互式地理空间数据可视化

绘制世界特定地区的地图,在地图上展示活动,并四处导航

towardsdatascience.com](/interactive-geospatial-data-visualization-in-python-490fb41acc00) [## 使用 Python 的 Matplotlib 的华夫饼图表

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

towardsdatascience.com](/waffle-charts-using-pythons-matplotlib-94252689a701) [## Matplotlib 中的气泡图

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

towardsdatascience.com](/bubble-plots-in-matplotlib-3f0b3927d8f9) [## 用于数据建模的探索性数据分析

如何了解数据集,定义因变量和自变量,计算相关系数…

towardsdatascience.com](/exploratory-data-analysis-intro-for-data-modeling-8ff019362371) [## 使用 Pandas Cut 或 Qcut 方法对数据进行分类和分段

当你在寻找一个范围而不是一个确切的数值,一个等级而不是一个分数

towardsdatascience.com](/sort-and-segment-your-data-into-bins-to-get-sorted-ranges-pandas-cut-and-qcut-7785931bbfde)

你花哨的专有人工智能模型对我没有价值

原文:https://towardsdatascience.com/your-fancy-proprietary-ai-model-has-no-value-to-me-2a7d40dfd8ca?source=collection_archive---------47-----------------------

…除非您分享其目标、设计、测试和指标的细节

图片由皮克斯拜的 Gerd Altmann 提供

各地的厂商,请不要告诉我你的机器学习(或者更好的是‘AI’)模型有 99%的准确率。不要告诉我,我们所需要做的就是‘插入你的数据’,然后一些闪亮的魔法就发生了。我不是唯一的一个。最近,31 名科学家对谷歌健康的一项研究提出质疑,因为没有足够的公开证据来确定所提出的人工智能模型的可信度。我们都需要尽自己的一份力量来构建值得信赖的模型,为我们新的先进应用提供动力。被告知是减轻模型风险的第一步。

给我提供背景

当检查内部创建的模型或现成的供应商产品时,我会遵循一些必要的步骤。还有许多其他伟大的问题。请在评论区分享它们。

首先我们要明白,你在幕后做的是不是机器学习。如果你不能告诉我什么类型的模型产生的结果,让你的工程师打电话。

没有上下文,准确性度量是没有价值的。如果你正在为一个儿童动物学应用程序标记鱼的种类,百分之九点九的准确率是非常好的,但如果你正在识别来袭导弹,就没那么好了。

在私下讨论任何指标之前,需要检查以下三个问题。

目标是什么?

  • 你是在促进什么还是阻止什么?

事件发生的频率或罕见程度如何?

  • 给我数据。“非常罕见”不是一个好的回答。

最坏的情况是什么?

  • 如果模型是错的会发生什么,包括假阳性和假阴性。
  • 如果你不知道,你就不了解用例。你有工作要做。

给我提供证据和细节

一旦我理解了这些基础知识,我们就可以进入细节了。

你从哪里得到的训练数据?

  • 如果购买,供应商是谁?
  • 您是否在建模数据的基础上构建模型?
  • 数据是如何收集和准备的?
  • 交易、电话调查、网络应用、电话应用

训练的模型类型:

  • 什么样的模型?
  • 你是如何得到这些特别的模型的?
  • 在做决定时,您是否依赖于特定的平台或架构?

指标:

  • 准确是好的,但不仅仅是准确。请给我看看混淆矩阵。模型哪里做得好,哪里做得不好?
  • 你能告诉我最好的预测吗?我需要验证它们是否“有意义”关联值是多少?有没有可能数据泄露

偏置:

  • 你认为你的训练数据中存在哪些偏见(人口统计、地区、收集方法(iPhone 与 Android)、种族、健康和福利)?如果偏见是不可避免的,你做了什么来减轻它?
  • 您是否通过分析模型实施的结果评估了可能的偏差影响?一个模型可以有绝对“干净”的数据,但仍然会产生意想不到的后果。性别、种族、民族和社会经济地位很容易泄露到数据库中,即使这些列没有被使用。如需详细示例,请阅读 Obermeyer 等人的“剖析用于管理人口健康的算法中的种族偏见”SCIENCE2019 年 10 月 25 日:447–453。它很好地详细说明了选择一个看似合理的优化目标(降低慢性病患者的医疗保健成本)如何导致黑人社区中有价值的健康计划候选人服务不足。

结论

随着机器学习和人工智能工作的快速发展,我们对模型设计和验证透明度的期望也应该快速发展。如果没有能力彻底理解模型及其产生的结果,对所有模型的不信任可能会出现,从而抑制增长和创造力。如果你还没有提问,请开始提问。我们所有的成功都有赖于此。

参考文献

[## 人工智能正在与复制危机搏斗

上个月,《自然》杂志发表了一篇由 31 名科学家撰写的对谷歌健康的一项研究的谴责性回应,该研究似乎…

www.technologyreview.com](https://www.technologyreview.com/2020/11/12/1011944/artificial-intelligence-replication-crisis-science-big-tech-google-deepmind-facebook-openai/?itm_source=parsely-api) [## 人工智能中的透明性和再现性

订阅期刊获得为期 1 年的完整期刊访问权限 199.00 美元,每期仅 3.90 美元所有价格均为净价。增值税…

www.nature.com](https://www.nature.com/articles/s41586-020-2766-y.epdf?sharing_token=esGu0AMNcdnJWDaAaBr3BtRgN0jAjWel9jnR3ZoTv0M3qEeZVaYZS89U0ri_i4YI_lJ0an-lE15Ncv2e1v5F7I2jYVuc7_mR1WrnlDjpWJ6ANzSjO0KJiERmpzE097VzbFgywD7RRHVOYg305JycIUX7UQDWkLlgHtsoU72ppNzneeIGzsSR4Cr5dVRyVtV2UMxm2gs9pA22vydPt_RRBmPUqh6R2UPn-oziFm82hKA%3D&tracking_referrer=www.technologyreview.com) [## 你如何用自己的小方法防止系统性的种族歧视

这里有两种方法可以解决技术和数据科学中的偏见

towardsdatascience.com](/how-you-can-prevent-systemic-racism-in-your-own-small-way-fc33cb57fdde)

“剖析用于管理人口健康的算法中的种族偏见”,作者 Obermeyer 等人SCIENCE2019 年 10 月 25 日:447–453

从不同的角度看你最喜欢的游戏

原文:https://towardsdatascience.com/your-favorite-game-from-a-different-point-of-view-93732173adf7?source=collection_archive---------24-----------------------

使用数据找出赢得神奇宝贝战斗的最可取的特点和特征——并通过这些见解建立最好的团队

完整的 python 代码和探索性数据分析笔记本可以在我的 github 个人资料中找到;

图片来源:【https://i.ytimg.com/vi/QWGGtKgalDo/maxresdefault.jpg

《神奇宝贝》是日本媒体的一个特许经营权,最初名为神奇宝贝红色神奇宝贝绿色,是任天堂最初的游戏男孩的一对视频游戏,由 Game Freak 开发,由任天堂于 1996 年 2 月发布。神奇宝贝自此成为有史以来票房最高的媒体特许经营,特许经营总收入达到 900 亿美元。

神奇宝贝——维基百科文章

神奇宝贝游戏,特别是第一代和第二代的游戏:神奇宝贝红色、蓝色、黄色、金色、银色和水晶对于出生于 90 年代的整代人来说,真的很了不起——包括我自己。这些天,我在 Kaggle 网站上寻找一些数据集,最后我发现了这个帖子,作者给出了包含神奇宝贝和游戏中神奇宝贝战斗数据的数据集,并提出了一个挑战:建立一个模型,能够根据给定的数据预测两个神奇宝贝之间的战斗结果。

把我童年的爱好和现在的爱好融合在一起?听起来不错,所以我同意!

数据集

Kaggle 的 Weedle 洞穴哨所提供了以下数据集:

神奇宝贝数据集 | 800 个输入,12 个特征
该数据集包含了所有发布到第 6 代的神奇宝贝的数据;

# —口袋妖怪指数(与最初的特许经营列表中使用的不同,因为大型进化列在普通形态的口袋妖怪之后);

名字 —口袋妖怪的名字;

类型 1 —口袋妖怪的初级类型;

类型 2 —口袋妖怪的副类型(所有口袋妖怪都有主类型,但不一定有副类型);

HP —生命值基础统计;

攻击 —物理攻击基础统计;

防御 —物理防御基础统计;

Sp。Atk —特攻基础统计;

Sp。Def —特殊防御基础统计;

速度 —速度基础统计;

一代 —这款神奇宝贝属于哪一代的特许经营游戏;

传奇 —表示神奇宝贝是否属于传奇团体;

神奇宝贝数据集的头部

战斗数据集 | 50000 个输入,3 个输入
该数据集包含神奇宝贝战斗的数据,列出了它们的索引( # )所涉及的两个神奇宝贝,以及哪一个以胜利者的身份结束了战斗:

First_Pokemon —训练师 A 的神奇宝贝 # (索引)——(先攻击过的神奇宝贝会一直列为“First _ Pokemon”);

秒 _ 神奇宝贝 —训练师 B 的神奇宝贝 # (索引);

赢得战斗的神奇宝贝的# (指数);

战斗数据集的头部

神奇宝贝的战斗是如何进行的?

在进入探索性数据分析(EDA)之前,理解单个神奇宝贝战斗是如何工作的很重要(也有双重战斗,但数据集上记录的战斗不是这种情况)。

神奇宝贝战斗遵循通常的 RPG 游戏模式:战斗轮流进行,每个参与者每回合可以采取一次行动(不是同时进行),第一个将对手的生命值减少到零的人就是赢家。在特许经营游戏中,行动由神奇宝贝训练师采取,他们可以选择攻击敌人的神奇宝贝,使用一件物品,甚至将自己的神奇宝贝换成团队中的另一个(训练师最多可以携带 6 个神奇宝贝)。

如上所述,衡量谁是赢家的标准是生命值,简称为 HP 。每个神奇宝贝拥有的 HP 的数量由以下等式给出:

来源:https://bulbapedia.bulbagarden.net/wiki/Statistic

给定的数据集仅提供了 HP 基本统计数据(在等式中突出显示)。所有其他变量(个人值: IV ,努力值: EV等级)都是游戏中开发的机制和引擎,不会在分析中考虑,因为没有办法找到数据集中记录的战斗的这些值。然而,如等式所示,总的 HP 与基础统计 HP 成正比。换句话说,基础属性越高,一只神奇宝贝在完全训练后获得的生命值就越高。

为了将对手的生命降至零并赢得战斗,神奇宝贝能够使用战斗招式、这是一种特殊的移动,用于造成伤害、增强属性或对对手甚至环境造成一些影响。在攻击性战斗移动的情况下,会造成一些伤害并降低敌人的生命值,所造成的伤害使用以下等式计算:

资料来源:https://bulbapedia.bulbagarden.net/wiki/Damage

其中:

来源:https://bulbapedia.bulbagarden.net/wiki/Damage

A/D是攻击方神奇宝贝的有效攻击属性与目标神奇宝贝的有效防御属性的比值。“有效”来源于这样一个事实,即有两种类型的伤害:物理的和特殊的(用一个简单的比喻,让我们说它会是类似“魔法”的东西)。对于其中的每一个,特定的统计数据被用于模数因子的计算:
物理移动使用攻击神奇宝贝的攻击统计数据,以及目标的防御统计数据。另一方面,
特殊招式考虑攻击 Sp。攻击状态,目标 Sp。防御属性。

血量类似,这些统计数据由一个等式给出,最终值与各自的基础统计值成正比,这是神奇宝贝数据集中所有神奇宝贝的唯一信息。**

来源:https://bulbapedia.bulbagarden.net/wiki/Statistic

我们用来构建分析的另一条信息是类型因素。长话短说:所有的神奇宝贝都有一个类型,,这是它身体组成的一个基本元素。事实上,每只神奇宝贝都至少有一种类型,但它们也可能有多达两种类型:初级和次级。

每一种类型都与他人有特定的互动,有强的、弱的、中性的或免疫的。同样,每一个战斗招式都关联一个类型,所以这个类型因子显示在伤害等式上就是攻击招式类型* x 目标类型伤害乘数。(不要慌,我们马上就到了)。*

因此,在本次分析中,我们将考虑损伤与模数因子和类型损伤乘数因子的乘积成正比,而模数因子和类型损伤乘数因子是数据集中可用的信息。

听起来不错,对吧?尽管事实上没有所有必要的信息来计算一个完整和完全准确的计算,知道如何计算类型的伤害乘数,至少有足够的信息来建立一些关于神奇宝贝战斗背后的数学好主意。然后,这是下一步!

如何计算类型伤害乘数因子?

现在我们知道了什么是神奇宝贝类型,并且它们对伤害计算非常重要,是时候知道在神奇宝贝世界里有哪些类型了:

图片来源:https://pokemon.fandom.com/wiki/Types

这些类型中的每一种都与所有其他类型有着进攻和防守的关系,这一信息是由 Game Freak 在每一个新一代发布后提供的。我已经在球形图上取了最新的类型图,并创建了一个新的数据框,包含与下图所示完全相同的信息:

神奇宝贝的类型图

这张图表给出了所有类型之间的直接关系,包括进攻型(横向参考)和防守型(纵向参考)。

举个例子: 电型在攻击一个水型时有一个伤害乘数等于 2,攻击一个草型时有 0.5,攻击一个火型时等于 1,最后,攻击一个地型敌人时等于 0。那么,我们可以说,电运动:

  • 对抗类型是否超有效*;*
  • 对抗种类不是很有效;
  • 都是中立对抗火力类型;
  • 不影响地面类型;

给定这四种可能的类型之间的相互作用,以及类型图表,现在可以计算所有神奇宝贝战斗的类型伤害乘数因子,对吗?

还没有!

正如我之前提到的,神奇宝贝有可能有第二类型。事实上,直到日本特许发行的第六代游戏,这是神奇宝贝数据集中包含的数据,只有 48.25%的神奇宝贝只有初级类型。

由于大多数神奇宝贝有两种类型,并且交互因素是累积的,我们需要一种方法来计算多种类型的交互结果。由于战斗数据集没有提供任何关于战斗中采取了哪些行动的信息,我采用一些假设来简化分析:我们将考虑:

  • 神奇宝贝在战斗中只能使用自己类型的战斗招式——例如,一个火* / 如 Charizard 只能使用火招或飞招(战斗招式只有一种类型与之相关);*
  • 神奇宝贝训练师总是会为他们的神奇宝贝选择最好的战斗移动选项(如果适用的话),以便对敌人的神奇宝贝造成尽可能多的伤害。

作者注:神奇宝贝从其他类型而不是自己的类型中了解战斗招式是完全可能和正常的,更有经验的玩家总是选择从可能为他们的弱点提供一些覆盖的类型中教授他们的神奇宝贝招式(神奇宝贝可以同时了解多达 4 个招式)。然而,由于缺乏战斗数据集的信息,该分析不会考虑这一事实;

为了理解如何计算型伤害乘数因子,一个简单的例子可能会有用。

想象一下,两个神奇宝贝训练师相遇并决定通过一场战斗来测试谁是最好的。1 号教练有一把小火龙、,2 号教练有一把舒克尔。假设小火龙有更高的速度统计,训练师#1 将首先采取行动。

注:速度统计用于决定战斗中哪个神奇宝贝先移动。标准规则很简单:最快的先走。除了 HP,之外的其他属性的速度属性由之前显示的相同等式给出,但是使用速度基础属性代替。为了记录在案,在游戏机制中有超越标准速度规则来选择先移动哪些神奇宝贝的规则,例如优先移动或持有物品——然而,这再次不包括在这个分析范围内,因为没有关于这些战斗细节的数据。

计算小火龙对舒克尔攻击的型伤害乘数因子、最佳 A/D 因子比例伤害因子

  • 由于小火龙只有一种招式火,这里没有关于使用哪种招式的选项。它肯定会使用火招;
  • 另一方面, Shuckle 有两种类型: BugRock 。所以有必要考虑招式如何与这两种类型相互作用,并将这些相互作用融合在一起成为一个最终的数字;
  • 使用特殊移动是最好的选择,因为它最终会成为一个更好的模数转换因子;
  • 已知型损伤乘数最佳模数因子,从本文前面给出的完整损伤方程可知输出损伤与这两个数的乘积成正比。

计算舒克尔对小火龙攻击的型伤害乘数因子、最佳 A/D 因子比例伤害因子

  • 从攻击者的角度来看舒克尔,有一个本质的区别:舒克尔有两种类型,所以它的训练者必须决定哪种移动类型是对敌人的小火龙造成尽可能多伤害的最佳选择;
  • 对于舒克,物理攻击是最好的选择——因为物理模数因子高于特殊模数因子

考虑到两种魔法的相互作用,型伤害乘数因子有六个可能的值:

类型优势

  • 4 :两种目标类型对攻击类型都很弱;
  • 2:一个目标的类型是弱的,另一个是中性的攻击;

中性交互

  • 1 :要么两个目标类型对进攻方都是中性,要么一个目标类型对进攻方是强一个弱;

类型缺点

  • 0.5 :一个目标的类型是强,另一个对攻击的类型是中性;
  • 0.25 :两种目标类型对进攻的都很强;
  • 至少有一个目标的类型是攻击性的;

尽管如此,我们现在有了一个好主意,可以分析哪些特征,以便更好地了解哪些是神奇宝贝在战斗中获胜的最重要因素。

然而,没有一个关于战斗的有价值的信息被直接给出,因为神奇宝贝数据集只有个别神奇宝贝的特征,而战斗数据集只告知哪个神奇宝贝在哪里战斗以及哪个是赢家。然后,有必要建立一个 ETL 管道——从所有三个数据集中提取所有必要的信息,通过计算所有有价值的特征来转换数据,以了解战斗胜利者的特征(基于建立在神奇宝贝战斗如何工作的基础上的知识),以及将所有东西加载到一个新的数据集中,我将其命名为神奇宝贝战斗数据集。**

应用于原始数据的 ETL 管道

除了 ETL 管道的完整代码和完整的数据分析,生成的神奇宝贝战斗数据集可在我的 github 个人资料的项目回购中获得。

该新数据集由 35 个特征组成:

First_Pokemon —训练师 A 的神奇宝贝 # (索引)——(先攻击过的神奇宝贝会一直列为“First _ Pokemon”);

秒 _ 神奇宝贝 —训练师 B 的神奇宝贝 # (索引);

赢得战斗的神奇宝贝的赢家# (指数);

基础统计差异 —两个神奇宝贝基础统计的差异( 6 个特性,每个特性一个:HP,攻击,防御,Sp。攻击,Sp。防守,速度);

有效属性差异 —两个神奇宝贝( 8 特性 s)用于伤害计算的有效属性差异,差异:攻击与 HP,攻击与防御,Sp。攻击和 HP,Sp。攻击和 Sp。防守,针对进攻者/目标的两种组合);

A/D 因子 —毁伤方程中使用的有效 A/D 因子( 4 特征),针对攻击者/目标的两种可能性的两种可能的 A/D 因子(物理的和特殊的);

类型伤害乘数 —类型伤害乘数因子( 2 特性,每种攻击方/目标的可能性一个);

比例伤害因子 —最高 A/D 因子和类型伤害乘数因子的乘积( 2 个特性,每个攻击方/目标的可能性一个);

伤害/生命值系数 —比例伤害系数与目标生命值基础值的比率( 2 个特性,攻击者/目标的每种可能性一个);

神奇宝贝类型 —每个神奇宝贝的初级和次级(如果有的话)类型( 4 特性);

传奇神奇宝贝 —表示战斗中任何一只神奇宝贝都是传奇的旗帜( 2 特征);

优先级 —表示基础状态速度最低的神奇宝贝先移动的标志;

神奇宝贝 1 赢了——表示首先出击的神奇宝贝最终赢得战斗的标志(这将用作预测模型的目标变量);

现在,基于这个新数据集,结合来自神奇宝贝数据集的单个神奇宝贝数据,可以执行探索性数据分析,以便更好地了解导致赢得神奇宝贝战斗的最相关因素。

探索性数据分析

这里快速回顾一下:

*-我们知道,通过对敌人的生命值造成伤害直到生命值减为零,战斗就胜利了;

  • 伤害是许多变量的函数,然而与两个因子的乘积成正比: A/D 因子型伤害乘数
  • 模数因子由神奇宝贝有效统计的划分给出,另一方面,它与各自的基础统计直接成比例,这在数据集上对我们是可用的;
  • 型伤害乘数可以用本文前面所示的程序计算;*

因此,给定神奇宝贝的战斗动态和可用的数据,为了赢得战斗,分析了解神奇宝贝最有价值的特征将基于构成伤害的两个因素:基础统计(以及所有可能从中得出的比例因素)和类型互动

基本统计

赢得战斗最重要的属性是什么?一般来说,在你的旅程中使用具有防御特性的神奇宝贝是值得的,还是进攻更有效?

回答这些问题的最好方法,是看看在战斗中获胜的神奇宝贝和被击败的神奇宝贝之间基础统计数据的差异:

赢家和输家之间的基础统计差异分布

这些分布图给了我们一些有价值的信息:

  • 一般来说,这可能是一般的直觉,与对手相比,基础属性更高的神奇宝贝最终会赢得战斗;
  • 更高的进攻基础统计(攻击Sp。攻击似乎比更高的防御属性( HP防御Sp)更相关。防御);
  • 虽然所有其他属性的分布几乎是对称的,只是稍微偏移和向右倾斜,但是速度基础属性是严重向右倾斜的——显示它自己是迄今为止与赢得战斗最相关的基础属性;

这个结果真的很有趣,因为速度统计基本上只用于定义哪个神奇宝贝在回合中先移动。从本文开头的数据解释中,我们可能还记得战斗数据集将最先攻击的放在神奇宝贝#1 中。

然而,神奇宝贝#1 总是比神奇宝贝#2 有更高的速度基础属性是不真实的——这有很多原因:
——我们看的是基础属性,而不是属性本身;
-游戏中有
机制可能会覆盖先发制人的标准速度规则(如优先移动持有物品、物品使用、神奇宝贝开关环境效果)——但在数据集中没有关于这些机制使用的细节;**

然后,在 ETL 管道期间,一个名为 Prio 的功能被创建,以指示速度较低的神奇宝贝首先出击的战斗。

赢家和松散神奇宝贝之间的速度基础统计差异——常规速度规则覆盖分析

再次查看胜利者和失败者神奇宝贝之间的基础属性减法,人们能够看到,除了微小的差异,更高的速度属性仍然更有价值,即使是在基础属性较低的神奇宝贝先移动的战斗中(优先级=真)。**

请注意,在战斗的第一个回合首先出击,并不意味着神奇宝贝#1 已经在所有其他回合首先出击。事实上,数据显示在标准速度规则 下拥有每回合先动的优势是神奇宝贝赢得战斗的最有价值的特征。

因此,数据显示快速进攻神奇宝贝是你在真实的神奇宝贝游戏中进行冒险时团队组成的最佳选择。

这涵盖了我们之前看到的损害等式的一个方面。另一个比例因子型相互作用怎么样?它们如何影响战斗结果?

比例损伤因子和类型相互作用

从基础数据本身来看,进攻特征通常比防守特征更有影响力。但它总是正确的吗?类型交互如何影响它?

正如我们在《神奇宝贝战斗动态》介绍中看到的,无论是从进攻角度还是防守角度来看,共有三种类型的型互动*类别:

  • 型优势-进攻乘数: 4x2x |防守乘数: 0x0.25x0.5 x
  • 中立互动-攻防倍增:1x
  • 型劣势-(进攻乘数:0 x,0.25x0.5x |防守乘数: 2x4x;*

这些互动对战斗的影响有多大?此外,最有价值的统计特征在不同类型的互动场景中会发生变化吗,或者进攻永远是最好的选择?

成功率 x 类型互动

上图显示,类型优势,无论是进攻还是防守,都与更高的胜率直接相关,因为进攻伤害乘数越高,胜率越高,防御胜率越高,反之亦然。

它证实了直觉的想法,即类型交互对战斗的胜利有很强的相关性,因为它们与伤害成正比。然而,在不同类型的互动场景中,它没有说太多关于最有价值的神奇宝贝的特征。

*为了更好地理解有利或不利类型比赛中神奇宝贝特征之间的关系,下面的方框图可能更有用。分别代表胜者神奇宝贝的 A/D 因子比例伤害因子 ( A/D 型伤害乘数)、比例伤害因子与敌人的 HP 基础统计值之比 ( 乘以 50,更贴合剧情);

不同类型匹配时的模数系数

不同类型匹配时的伤害系数和伤害/血量比

这些特征中的大多数都有巨大的异常值,因此有必要应用IQR(IenterQuartileR安歌】方法来消除它们并进行分析。完整的代码和数据预处理方法可在原始项目笔记本上找到。

这些方框图揭示了一些非常有趣的事情:

  • 进攻特点 对于一个神奇宝贝在类型优势* 场景(无论是进攻还是防守)上赢得战斗的**来说,相对于一般情况(整套分析);*
  • 然而,对于型劣势的情况,这是不成立的。事实上,恰恰相反的情况发生了:在这种类型的比赛中,防守特性成为最受欢迎的特性
  • 另一方面,中性相互作用与一般情况非常相似*;*

综合我们目前掌握的所有信息,我们有:
-型优势显著提高了赢得战斗的概率;
-进攻特点在中性和有利型比赛中最有价值;

将这些信息与来自基本统计分析的信息相结合,可以得出以下结论:

最佳的团队组合必须不仅基于快速进攻魔法,还基于具有更高有利数量的魔法类型,或者至少是中立的配对

但是,在这个指标上,哪些类型是最好的呢?

类型匹配

哪种类型提供更多的有利匹配?

开始研究这个问题的最好方法是直接从类型数据集中统计有利和不利类型匹配的数量。

每种类型的类型匹配计数—按进攻和防守交互进行划分

上面的柱状图表明,对所有 18 种神奇宝贝来说,有利的和不利的配对数量甚至都没有接近平衡

如果每种类型的魔法数量平均分布的话,这可能是这个分析需要的唯一的图。但是,这是真的吗?

这是要检查的下一点:

每种类型的神奇宝贝数量

很明显,人们不能直接使用类型匹配计数图作为参考来了解哪些类型可以提供更高的覆盖率,因为每种类型的神奇宝贝数量严重不平衡

因此,与其直接使用有利或不利类型配对的计数,不如使用这些配对所代表的神奇宝贝百分比:

每种比赛类型覆盖的神奇宝贝的百分比——按进攻和防守互动划分

进攻型优势

格斗地面*,是进攻优势配对数最好的类型,各有 5 个有利配对。然而,看看神奇宝贝在有利的进攻比赛中的最高百分比, Ice 是最好的一个,对这个数据集的神奇宝贝的 39.2% 超级有效;*

由于普通类型没有优势,覆盖率也为零( 0% ),是两个度量中最差的类型;

防守型优势

钢铁在两个指标上都是最好的类型,从神奇宝贝的百分比来看 11 防守有利匹配类型匹配 ups 和67.38%*;*

寒冰普通类型只对 1 类型有抗性,然而寒冰*就百分比而言单独在列表中垫底,onlt 4.75% ,因为它只对自己有抗性,而且它是神奇宝贝世界中最稀有的类型(考虑到这些数据集);*

进攻型劣势

在这两个指标上都是最差的类型, 7 不利进攻配合,对神奇宝贝 61.62% 进攻乏力;

龙、鬼、配合数最好,分别对 2 种进攻较弱,而在百分比上独占鳌头,对魔人只有 11.85%* 进攻较弱;*

防御型劣势

摇滚只是不利防守配合计数最差的类型,有 5 的弱点。在看神奇宝贝防御弱点百分比时最底层的类型是:47.5%*;*

电动普通型各只有 1 个弱点。然而,电动在百分比指标上保持最佳位置,仅弱于所有神奇宝贝的6.25%*;*

正如我们已经看到的那样,有利的类型匹配增强了赢得神奇宝贝战斗的概率,当查看每种类型的胜率时,人们期望看到具有最佳匹配百分比的类型作为具有最高胜率的类型,只要战斗数据集是真正随机的,并且在记录的战斗中神奇宝贝类型的频率遵循每种类型神奇宝贝的相同分布

在战斗数据集中输入频率

上面的柱状图表明,在 50.000 次记录的战斗中涉及的神奇宝贝类型遵循每种类型的神奇宝贝的相同分布,这证实了战斗确实是随机选择的,因此人们可能确实直觉地认为上面提到的类型是胜率最高的类型。

每种类型的成功率

在比赛中表现最好的类型,真的是胜率最高的类型吗?

为了验证这一点,我们来看一个柱状图,显示每种类型的成功率。

由于神奇宝贝有初级和次级类型,观察这些特征如何影响胜率也是很有趣的。此外,了解是否有一些类型本身更强大,而其他类型作为补充可能会更好,这可能是有用的。

每种类型的胜率—常规、主要类型和次要类型

每种类型的最佳和最差一般胜率

结果相当令人惊讶:更高的胜率与更高的有利类型匹配百分比并没有很强的相关性。那么,对于一个类型来说,哪一个因素与更高的胜率最相关?

根据此分析的初始想法,如果类型交互不是胜率的影响因素,则应检查基本统计数据。因此,下一步是调查每种类型的平均基础统计,并找出类型是否有一些嵌入的统计特征。

每种类型的平均基础状态

神奇宝贝的类型有一些特定的基础统计特征吗?是否有一些类型更侧重于进攻,而其他类型更侧重于防守?

我们将开始调查每种类型的统计特征,找出每个统计中最好的类型(就平均基础统计而言),并通过柱状图直观地比较它们:

每种类型的平均 HP 基础统计

每种类型的平均攻击基础统计

每种类型的平均防御基础统计

平均 Sp。每种类型的攻击基础统计

平均 Sp。每种防御基础统计

每种类型的平均速度基础统计

每种类型的总平均基础统计

上面这七个柱状图显示了每种类型的平均基础统计值,包括所有的六种统计值 ( 生命值、攻击值、防御值、Sp 值。攻击,Sp。防御和速度,以及总基础统计,这是所有基础统计的总和。

通过视觉检查这些图,找出每种类型的一些基础统计特征或模式并不容易,但是有可能注意到一些真正有趣的事情:具有最高胜率的类型 是具有最高平均速度基础统计的类型,和就胜率而言最差的是平均最慢的类型。它们并不遵循完全相同的顺序,但这是一条重要的线索,有助于确定某个类型具有更高胜率的最重要因素。

胜率 x 每种类型的平均速度基础统计

为了弄清楚每种类型的平均基础统计数据的一些模式,人们可能想要查看不同类型的图,其中可以同时可视化所有六种统计数据的数值。雷达图可能非常适合这个角色。

每种类型的平均基础统计数据—图 1/2

每种类型的平均基础统计数据—图 2/2

上面的雷达图清楚地表明,每种神奇宝贝都有一些统计特征:

  • 例如战斗类型倾向于专注于物理攻击(高平均攻击基础属性,而其他属性较低);
  • 通灵型另一方面有平均高 Sp。攻击Sp。防御基础属性,而其他人则没有那么高;

这些图也更好地说明了一些类型的平均基础统计数据之间的差异。给出的例子:通过比较的雷达图,可以注意到龙的魔法在每一个属性上都比虫的魔法有巨大的优势。

如上所述,很容易注意到更高的平均速度基础统计更高的胜率高度相关,然而,除了这两个等级的顶端和底端由相同的神奇宝贝类型填充这一事实之外,它们出现的顺序也不相同——因此,对于一个类型来说,在战斗中具有高胜率还有一些其他相关因素。

基本数据和类型匹配百分比与胜率的相关性

与战斗胜率最相关的类型特征是:

  • 平均速度基础统计 —相关性:0.96;
  • 平均速度。攻击基础统计 —相关度:0.53;
  • 平均总统计数据 —相关度:0.51;
  • 平均 HP 基础统计 —相关性:0.41;
  • 平均攻击基础统计 —关联度:0.35;
  • 进攻型优势(百分比) —相关性:0.30;

如前所述,最佳团队组合必须不仅基于快速进攻魔法,还必须拥有更高有利数量的魔法类型,或者至少是中立的配对

不过现在已经知道有利的基础统计(特别是速度Sp。攻击HP攻击)和高总基础属性比类型优势更有价值,如果你想在战斗中建立一个高效的神奇宝贝团队。虽然进攻有利型配合也通过数据显示了它的重要性,所以在组队的时候也要注重进攻有利型覆盖

利用从数据中获得的知识建立一个神奇宝贝团队

现在,我们将使用数据分析过程中收集的所有信息来建立一个神奇宝贝团队,寻找赢得战斗的最高效率。

作为第一代神奇宝贝(它带来了CharizardBlastoisevenus aur)可能是大多数人,特别是 90 年代出生的人最值得注意的一个,我将范围仅限于神奇宝贝传说中的神奇宝贝和超级进化都不会被包括在内,因为它们通常比“普通”的神奇宝贝有更高的基础属性。**

基于使用本文提及的所有数据集的探索性数据分析,选择团队成员的标准按优先顺序列出如下:

  • #1 —高速基础统计的神奇宝贝;
  • #2 —具有攻击性特征的神奇宝贝(要么攻击,要么 Sp。攻击);
  • ****# 3—团队中所有神奇宝贝的类型组合应具有广泛的有利进攻类型搭配(应尽量避免重复类型);

和所有神奇宝贝游戏一样,我们的团队将由六只神奇宝贝组成。

神奇宝贝数据集上运行一个简单的查询,我们得到:

我们神奇宝贝团队的最佳候选人

严格遵循既定的标准,一个人最终拥有以下神奇宝贝团队:

化石翼龙-基本统计和类型

胡地-基本统计和类型

奥术——基本属性和类型

耿鬼-基本统计和类型

雷伊布-基本统计和类型

宝石海星-基本统计和类型

该队对 18 种神奇宝贝中的 13 种有有利的进攻配合

形象徽章
类型徽章神奇宝贝精灵

你会在下一次游戏中尝试这支神奇宝贝队伍吗?

所有列入这份名单的神奇宝贝都有稳固的速度基础统计** ( 奥术最差,数值 95 ),也有稳固的进攻基础统计(物理、特殊甚至两者兼而有之——比如奥术),而且没有重叠类型(除了宝石海星的二级类型,它与胡地的重叠),达到了**的标记听起来很有希望,对吧?****

后续步骤

预测神奇宝贝战斗赢家的机器学习模型

由于 Kaggle 帖子的最初的挑战是建立一个机器学习模型,该模型能够预测哪只神奇宝贝将赢得战斗,考虑到两个战斗神奇宝贝,这将是下一步!

我们将使用从这里描述的 ETL 管道中导出的新数据集,以及关于神奇宝贝战斗的所有知识来建模和训练机器学习模型,所有细节将在下一篇文章中全面描述。

此外,一旦模型被完全训练,也将有可能使用数据分析来检查这个神奇宝贝团队的效率

****作者注:对于那边的所有神奇宝贝粉丝来说——重要的是要记住,用于建立这一分析的所有战斗可能都是在游戏战斗中,在一次跑步中记录的,与野生神奇宝贝和 NPC 的战斗(没有关于战斗的起源和来源的信息)。竞技神奇宝贝场景完全不同,不是这里的重点。

你的第一个 Apache Spark ML 模型

原文:https://towardsdatascience.com/your-first-apache-spark-ml-model-d2bb82b599dd?source=collection_archive---------0-----------------------

如何用 Apache Spark 和 Python 构建一个基本的机器学习模型?

Héizel Vázquez 插图

我爱阿帕奇火花。这是我用于机器学习和数据科学的首批框架之一。在过去的几年里,它一直在稳步增长,我们已经接近它的第三个版本。我们预期的变化主要是在查询和流程的优化方面,所以 API 不会有太大的变化。这意味着你在这篇文章中学到的东西会在一段时间内起作用(我们不知道会持续多久,因为生活很微妙)。

这篇文章分为三个部分:

  • Apache Spark 的基础知识
  • 安装和使用 Apache Spark
  • 创建您的第一个 Apache Spark 机器学习模型

前两节中您将看到的许多内容来自我以前写的两篇关于 Apache Spark 的文章:

[## 使用 Apache Spark 进行深度学习—第 1 部分

第一部分全面讨论了如何使用 Apache Spark 进行分布式深度学习。这一部分:什么是火花…

towardsdatascience.com](/deep-learning-with-apache-spark-part-1-6d397c16abd) [## 如何在你的电脑上使用 PySpark

我发现在您的本地上开始使用 Apache Spark(这里将重点介绍 PySpark)有点困难…

towardsdatascience.com](/how-to-use-pyspark-on-your-computer-9c7180075617)

但是是时候更新了:)

Apache Spark 的基础知识

弗里皮克配合伊泽尔·巴斯克斯

几年前,Apache Spark 被其创建者定义为:

大规模数据处理的快速通用引擎。

快速”部分意味着它比以前的方法更快地处理大数据,如经典的 MapReduce。更快的秘密是 Spark 在内存(RAM)上运行,这使得处理速度比在磁盘上快得多。

通用”部分意味着它可以用于多种用途,比如运行分布式 SQL、创建数据管道、将数据摄取到数据库中、运行机器学习算法、处理图形、数据流等等。

现在他们把定义改成了:

Apache Spark 是一个用于大规模数据处理的统一分析引擎。

我们仍然有通用部分,但现在它的范围更广了,有了单词“ unified,”,这是为了解释它可以在数据科学或机器学习工作流中做几乎所有的事情。对于端到端的项目,可以单独使用 Spark 框架。

“大规模”部分意味着这是一个可以完美处理大量数据的框架,我们过去称之为“大数据”(有趣的是事物变化的速度)。

RDD

杰弗里·汤普森的 PySpark 图片。

Apache Spark 的核心抽象和开端是弹性分布式数据集(RDD)。

RDD 是可以并行操作的容错元素集合。您可以在驱动程序中并行化现有集合,或者引用外部存储系统中的数据集来创建它们,例如共享文件系统、HDFS、HBase 或任何提供 Hadoop InputFormat 的数据源。

关于 Spark,有一点非常重要,那就是所有的转换都是惰性的,这意味着它们不会马上计算出结果。相反,Spark 会记住应用于某个基本数据集(如文件)的转换。只有当一个动作需要将结果返回给驱动程序时,才会计算转换。

默认情况下,每次对变换后的 RDD 执行操作时,都会对其进行重新计算。然而,您也可以使用持久化(或缓存)方法在内存中持久化一个 RDD,在这种情况下,Spark 会将元素保留在集群上,以便下次查询时可以更快地访问。还支持在磁盘上持久化 rdd 或跨多个节点复制 rdd。

数据框架

杰弗里·汤普森的 PySpark 图片。

从 Spark 2.0.0 开始,数据帧就是一个被组织成命名列的数据集。它在概念上相当于关系数据库中的一个表或 R/Python 中的一个数据帧,但是在底层有更丰富的优化。

数据帧可以由各种各样的构建,例如:结构化数据文件、Hive 中的表、外部数据库或现有的 rdd。

https://aspgems . com/blog/big-data/migrando-de-pandas-spark-data frames

简而言之,Dataframes API 是 Spark 创造者简化框架中数据处理的方法。它们非常类似于 Pandas 数据帧或 R 数据帧,但有几个优点。首先,它们可以分布在一个集群中,因此可以处理大量数据;其次,它们经过了优化。

这是社区迈出的非常重要的一步。到了 2014 年,用 Spark 搭配 Scala 或者 Java,速度快了很多,整个 Spark 世界都因为性能变成了 Scala。但是有了 DF API,这不再是一个问题,现在您可以在 R、Python、Scala 或 Java 中使用它获得相同的性能。

数据块

负责这种优化的是催化剂。你可以把它想象成一个向导,它会接受你的查询(哦,是的!,您可以在 Spark 中运行类似 SQL 的查询,在 DF 上运行它们,它们也会被并行化)和您的操作,并创建一个优化的计划来分配计算。

数据砖块

过程没那么简单,但是作为程序员的你根本不会注意到。现在它一直在那里帮助你。

在 Spark 3.0 中,我们将获得一种称为“自适应查询执行”(AQE)的东西,它将根据查询执行过程中收集的运行时统计数据来重新优化和调整查询计划。这将对性能产生巨大影响,例如的例子假设我们正在运行查询

SELECT max(i) FROM table GROUP BY column

没有 AQE,Spark 将启动五个任务进行最终聚合:

https://databricks . com/blog/2020/05/29/adaptive-query-execution-speeding-up-spark-SQL-at-runtime . html

但是有了 AQE,Spark 将把这三个小分区合并成一个,因此,最终的聚合现在只需要执行三个任务,而不是五个:

https://databricks . com/blog/2020/05/29/adaptive-query-execution-speeding-up-spark-SQL-at-runtime . html

在这个新版本中,Spark 将解决一个大问题:基于成本的优化。如果你想了解更多,请查看上面两张图片中的链接。

在接下来的会议中,我们将看到更多关于 Spark 及其机器学习(ML)库的内容。

安装和使用 Apache Spark

备注:

  • “$”符号将表示在 shell 中运行(但不要复制该符号)。
  • >>>符号表示 Python 外壳(不要复制符号)。

我们将在本地安装 PySpark,然后使用 Jupyter 来处理它。使用 Spark 还有更多方法,如果你想了解更多,请查看这篇文章。

安装 PySpark

Freepik

PySpark,可以想象,就是 Apache Spark 的 Python API。这是我们使用 Python 与框架交互的方式。安装非常简单。这些是步骤:

  • 在计算机上安装 Java 8 或更高版本。
  • 安装 Python(我推荐>来自 Anaconda 的 Python 3.6)
  • 安装 PySpark:
$ pip3 install pyspark

目前的默认版本是 3.0.0,这是实验性的,但是它应该适用于我们的实验。

要测试您的安装,请转到您的终端,然后打开 Python。然后写:

>>> import pyspark

如果你没有得到一个错误,你就在正确的道路上。要检查 Spark write 的安装版本:

pyspark.__version__

你应该得到‘3 . 0 . 0’。

  • 在 Python 笔记本中测试 Spark:创建一个新的 Jupyter 笔记本,编写和以前一样的内容。如果出现错误,直接从笔记本上安装 PySpark。下面是一款笔记本电脑实现这一功能的要点:

创建您的第一个 Apache Spark ML 模型

免费版

Spark 的机器学习库叫做 MLlib(机器学习库)。它在很大程度上基于 Scikit-learn 关于管道的想法。在本库中,创建 ML 模型的基本概念是:

  • DataFrame:这个 ML API 使用 Spark SQL 中的 DataFrame 作为 ML 数据集,可以保存各种数据类型。例如,数据帧可以具有存储文本、特征向量、真实标签和预测的不同列。
  • 转换器:转换器是一种可以将一个数据帧转换成另一个数据帧的算法。例如,ML 模型是将具有特征的数据帧转换成具有预测的数据帧的转换器。
  • 估计器:估计器是一种算法,它可以适合一个数据帧来产生一个转换器。例如,学习算法是在数据帧上训练并产生模型的估计器
  • 管道:管道将多个转换器和评估器链接在一起,以指定 ML 工作流
  • 参数:所有的转换器和估算器现在共享一个公共的 API 来指定参数。

如果你想知道更多关于 API 和它们如何工作的信息,请查看官方文档

对于这个例子,我们将使用一个非常基本的数据集。泰坦尼克号数据集,希望你们都熟悉这个案例和数据。首先,我们必须下载数据,为此我们使用 Kaggle:

[## 泰坦尼克号:机器从灾难中学习

从这里开始!预测泰坦尼克号上的生存并熟悉 ML 基础知识

www.kaggle.com](https://www.kaggle.com/c/titanic/data)

只需下载“train.csv”文件就可以了:)。

我们将根据乘客的特征来预测其是否幸存。

启动前:确保关闭并停止所有其他 Spark 笔记本。当使用多个 Spark 实例时,Java 有时会报错。

将数据加载到 Spark

为了加载数据,我们使用 Spark DataFrames。它比熊猫稍微复杂一点。不能只做“导入-> read_csv()”。您首先需要启动一个 Spark 会话,来完成该写操作:

from pyspark.sql import SparkSessionspark = SparkSession \
    .builder \
    .appName('Titanic Data') \
    .getOrCreate()

现在如果你写:

spark

在您的笔记本上,您应该会看到:

这意味着您在所有内核(即*)上本地使用 Spark,版本为 3.0.0,会话名称为“Titanic Data”。认为“Spark UI”在你使用 Spark 时会很有用,如果你点击它,你会看到:

我没有时间详细解释 UI,但如果你想了解更多,请告诉我:)。

酷!现在我们已经准备好读取数据了。为此,请编写:

df = (spark.read
          .format("csv")
          .option('header', 'true')
          .load("train.csv"))

就是这样!您已经创建了您的第一个 Spark 数据框架。要查看数据帧的内部,请编写:

df.show(5)

你会得到一些不漂亮但至少有用的东西:

+-----------+--------+------+--------------------+------+---+-----+-----+----------------+-------+-----+--------+
|PassengerId|Survived|Pclass|                Name|   Sex|Age|SibSp|Parch|          Ticket|   Fare|Cabin|Embarked|
+-----------+--------+------+--------------------+------+---+-----+-----+----------------+-------+-----+--------+
|          1|       0|     3|Braund, Mr. Owen ...|  male| 22|    1|    0|       A/5 21171|   7.25| null|       S|
|          2|       1|     1|Cumings, Mrs. Joh...|female| 38|    1|    0|        PC 17599|71.2833|  C85|       C|
|          3|       1|     3|Heikkinen, Miss. ...|female| 26|    0|    0|STON/O2\. 3101282|  7.925| null|       S|
|          4|       1|     1|Futrelle, Mrs. Ja...|female| 35|    1|    0|          113803|   53.1| C123|       S|
|          5|       0|     3|Allen, Mr. Willia...|  male| 35|    0|    0|          373450|   8.05| null|       S|
+-----------+--------+------+--------------------+------+---+-----+-----+----------------+-------+-----+--------+
only showing top 5 rows

是的,我知道,没那么漂亮。使用 Python 的一个好处是,你可以很容易地与熊猫互动。为了以更漂亮的格式显示我们的数据,您可以写:

df.toPandas()

您将获得:

但是小心我的朋友们!!!只有当您处理的数据足够小时,您才能这样做,因为当您执行“toPandas()”时,您将一次获得所有数据,并且数据不会分布在该单元格中。所以它必须适合内存。

检查关于您的数据的信息

有一些基本函数可以从数据集中获取更多信息。在下一段代码中,我加入了基本的代码( - >表示计算的结果):

# How many rows we have
df.count()
-> 891# The names of our columns
df.columns
-> ['PassengerId',
 'Survived',
 'Pclass',
 'Name',
 'Sex',
 'Age',
 'SibSp',
 'Parch',
 'Ticket',
 'Fare',
 'Cabin',
 'Embarked']# Types of our columns
df.dtypes
-> [('PassengerId', 'string'),
 ('Survived', 'string'),
 ('Pclass', 'string'),
 ('Name', 'string'),
 ('Sex', 'string'),
 ('Age', 'string'),
 ('SibSp', 'string'),
 ('Parch', 'string'),
 ('Ticket', 'string'),
 ('Fare', 'string'),
 ('Cabin', 'string'),
 ('Embarked', 'string')]

最后是一些关于我们数据的统计数据:

# Basics stats from our columns
df.describe().toPandas()

数据准备和特征工程

我们从上面的数据探索中注意到的一件事是,所有的列都是字符串类型。但这似乎不对。其中一些应该是数字。所以我们打算让他们出演。此外,由于时间关系,我只选择了几个变量进行建模,因此我们不必处理整个数据集:

from pyspark.sql.functions import coldataset = df.select(col('Survived').cast('float'),
                         col('Pclass').cast('float'),
                         col('Sex'),
                         col('Age').cast('float'),
                         col('Fare').cast('float'),
                         col('Embarked')
                        )dataset.show()

最后,你会得到这个数据集:

+--------+------+------+----+-------+--------+
|Survived|Pclass|   Sex| Age|   Fare|Embarked|
+--------+------+------+----+-------+--------+
|     0.0|   3.0|  male|22.0|   7.25|       S|
|     1.0|   1.0|female|38.0|71.2833|       C|
|     1.0|   3.0|female|26.0|  7.925|       S|
|     1.0|   1.0|female|35.0|   53.1|       S|
|     0.0|   3.0|  male|35.0|   8.05|       S|
|     0.0|   3.0|  male|null| 8.4583|       Q|
|     0.0|   1.0|  male|54.0|51.8625|       S|
|     0.0|   3.0|  male| 2.0| 21.075|       S|
|     1.0|   3.0|female|27.0|11.1333|       S|
|     1.0|   2.0|female|14.0|30.0708|       C|
|     1.0|   3.0|female| 4.0|   16.7|       S|
|     1.0|   1.0|female|58.0|  26.55|       S|
|     0.0|   3.0|  male|20.0|   8.05|       S|
|     0.0|   3.0|  male|39.0| 31.275|       S|
|     0.0|   3.0|female|14.0| 7.8542|       S|
|     1.0|   2.0|female|55.0|   16.0|       S|
|     0.0|   3.0|  male| 2.0| 29.125|       Q|
|     1.0|   2.0|  male|null|   13.0|       S|
|     0.0|   3.0|female|31.0|   18.0|       S|
|     1.0|   3.0|female|null|  7.225|       C|
+--------+------+------+----+-------+--------+

如果我们运行这个:

from pyspark.sql.functions import isnull, when, count, coldataset.select([count(when(isnull(c), c)).alias(c) for c in dataset.columns]).show()

我们得到:

+--------+------+---+---+----+--------+
|Survived|Pclass|Sex|Age|Fare|Embarked|
+--------+------+---+---+----+--------+
|       0|     0|  0|177|   0|       2|
+--------+------+---+---+----+--------+

我们看到在一些列中也有空值,所以我们只消除它们:

dataset = dataset.replace('?', None)\
        .dropna(how='any')

现在,Spark ML 库只处理数字数据。但我们还是想用《性》和《登船》专栏。为此,我们需要对它们进行编码。为此,让我们使用一个叫做 StringIndexer 的东西:

from pyspark.ml.feature import StringIndexerdataset = StringIndexer(
    inputCol='Sex', 
    outputCol='Gender', 
    handleInvalid='keep').fit(dataset).transform(dataset)dataset = StringIndexer(
    inputCol='Embarked', 
    outputCol='Boarded', 
    handleInvalid='keep').fit(dataset).transform(dataset)dataset.show()

如果你这样做,你会得到:

+--------+------+------+----+-------+--------+------+-------+
|Survived|Pclass|   Sex| Age|   Fare|Embarked|Gender|Boarded|
+--------+------+------+----+-------+--------+------+-------+
|     0.0|   3.0|  male|22.0|   7.25|       S|   0.0|    0.0|
|     1.0|   1.0|female|38.0|71.2833|       C|   1.0|    1.0|
|     1.0|   3.0|female|26.0|  7.925|       S|   1.0|    0.0|
|     1.0|   1.0|female|35.0|   53.1|       S|   1.0|    0.0|
|     0.0|   3.0|  male|35.0|   8.05|       S|   0.0|    0.0|
|     0.0|   3.0|  male|null| 8.4583|       Q|   0.0|    2.0|
|     0.0|   1.0|  male|54.0|51.8625|       S|   0.0|    0.0|
|     0.0|   3.0|  male| 2.0| 21.075|       S|   0.0|    0.0|
|     1.0|   3.0|female|27.0|11.1333|       S|   1.0|    0.0|
|     1.0|   2.0|female|14.0|30.0708|       C|   1.0|    1.0|
|     1.0|   3.0|female| 4.0|   16.7|       S|   1.0|    0.0|
|     1.0|   1.0|female|58.0|  26.55|       S|   1.0|    0.0|
|     0.0|   3.0|  male|20.0|   8.05|       S|   0.0|    0.0|
|     0.0|   3.0|  male|39.0| 31.275|       S|   0.0|    0.0|
|     0.0|   3.0|female|14.0| 7.8542|       S|   1.0|    0.0|
|     1.0|   2.0|female|55.0|   16.0|       S|   1.0|    0.0|
|     0.0|   3.0|  male| 2.0| 29.125|       Q|   0.0|    2.0|
|     1.0|   2.0|  male|null|   13.0|       S|   0.0|    0.0|
|     0.0|   3.0|female|31.0|   18.0|       S|   1.0|    0.0|
|     1.0|   3.0|female|null|  7.225|       C|   1.0|    1.0|
+--------+------+------+----+-------+--------+------+-------+
only showing top 20 rows

如您所见,我们创建了两个新列“性别”和“登船”,包含与“性别”和“登船”相同的信息,但现在它们是数字。让我们对数据类型做最后一次检查:

dataset.dtypes-> [('Survived', 'float'),
 ('Pclass', 'float'),
 ('Sex', 'string'),
 ('Age', 'float'),
 ('Fare', 'float'),
 ('Embarked', 'string'),
 ('Gender', 'double'),
 ('Boarded', 'double')]

所以我们想要的所有列都是数字。我们现在必须删除旧列“Sex”和“apolloed ”,因为我们不会使用它们:

# Drop unnecessary columns
dataset = dataset.drop('Sex')
dataset = dataset.drop('Embarked')dataset.show()

您将获得:

+--------+------+----+-------+------+-------+
|Survived|Pclass| Age|   Fare|Gender|Boarded|
+--------+------+----+-------+------+-------+
|     0.0|   3.0|22.0|   7.25|   0.0|    0.0|
|     1.0|   1.0|38.0|71.2833|   1.0|    1.0|
|     1.0|   3.0|26.0|  7.925|   1.0|    0.0|
|     1.0|   1.0|35.0|   53.1|   1.0|    0.0|
|     0.0|   3.0|35.0|   8.05|   0.0|    0.0|
|     0.0|   1.0|54.0|51.8625|   0.0|    0.0|
|     0.0|   3.0| 2.0| 21.075|   0.0|    0.0|
|     1.0|   3.0|27.0|11.1333|   1.0|    0.0|
|     1.0|   2.0|14.0|30.0708|   1.0|    1.0|
|     1.0|   3.0| 4.0|   16.7|   1.0|    0.0|
|     1.0|   1.0|58.0|  26.55|   1.0|    0.0|
|     0.0|   3.0|20.0|   8.05|   0.0|    0.0|
|     0.0|   3.0|39.0| 31.275|   0.0|    0.0|
|     0.0|   3.0|14.0| 7.8542|   1.0|    0.0|
|     1.0|   2.0|55.0|   16.0|   1.0|    0.0|
|     0.0|   3.0| 2.0| 29.125|   0.0|    2.0|
|     0.0|   3.0|31.0|   18.0|   1.0|    0.0|
|     0.0|   2.0|35.0|   26.0|   0.0|    0.0|
|     1.0|   2.0|34.0|   13.0|   0.0|    0.0|
|     1.0|   3.0|15.0| 8.0292|   1.0|    2.0|
+--------+------+----+-------+------+-------+

在进入机器学习部分之前,只剩下一步了。Spark 实际上是用一个列来进行预测的,这个列将所有的特性组合成一个类似列表的结构。例如,如果您具有以下功能:

+--------+------+----+-------+------+-------+
|Survived|Pclass| Age|   Fare|Gender|Boarded|
+--------+------+----+-------+------+-------+
|     0.0|   3.0|22.0|   7.25|   0.0|    0.0|
+--------+------+----+-------+------+-------+

而你要预测“幸存”,就需要把“Pclass”、“年龄”、“票价”、“性别”、“登车”这几列信息组合成一列。我们通常称之为列特性,它应该是这样的:

+--------+------+----+-------+------+-------+----------------------+
|Survived|Pclass| Age|   Fare|Gender|Boarded|    features         |
+--------+------+----+-------+------+-------+----------------------+
|     0.0|   3.0|22.0|   7.25|   0.0|    0.0|[3.0, 22.0, 7.25, 0, 0] |
+--------+------+----+-------+------+-------+----------------------+

正如您所看到的,新的列功能包含了我们所有功能的相同信息,但是是在一个类似列表的对象中。为了在 Spark 中做到这一点,我们使用了 VectorAssembler :

# Assemble all the features with VectorAssemblerrequired_features = ['Pclass',
                    'Age',
                    'Fare',
                    'Gender',
                    'Boarded'
                   ]from pyspark.ml.feature import VectorAssemblerassembler = VectorAssembler(inputCols=required_features, outputCol='features')transformed_data = assembler.transform(dataset)

现在,如果我们检查我们的数据,我们有:

+--------+------+----+-------+------+-------+--------------------+
|Survived|Pclass| Age|   Fare|Gender|Boarded|            features|
+--------+------+----+-------+------+-------+--------------------+
|     0.0|   3.0|22.0|   7.25|   0.0|    0.0|[3.0,22.0,7.25,0....|
|     1.0|   1.0|38.0|71.2833|   1.0|    1.0|[1.0,38.0,71.2833...|
|     1.0|   3.0|26.0|  7.925|   1.0|    0.0|[3.0,26.0,7.92500...|
|     1.0|   1.0|35.0|   53.1|   1.0|    0.0|[1.0,35.0,53.0999...|
|     0.0|   3.0|35.0|   8.05|   0.0|    0.0|[3.0,35.0,8.05000...|
|     0.0|   1.0|54.0|51.8625|   0.0|    0.0|[1.0,54.0,51.8624...|
|     0.0|   3.0| 2.0| 21.075|   0.0|    0.0|[3.0,2.0,21.07500...|
|     1.0|   3.0|27.0|11.1333|   1.0|    0.0|[3.0,27.0,11.1332...|
|     1.0|   2.0|14.0|30.0708|   1.0|    1.0|[2.0,14.0,30.0708...|
|     1.0|   3.0| 4.0|   16.7|   1.0|    0.0|[3.0,4.0,16.70000...|
|     1.0|   1.0|58.0|  26.55|   1.0|    0.0|[1.0,58.0,26.5499...|
|     0.0|   3.0|20.0|   8.05|   0.0|    0.0|[3.0,20.0,8.05000...|
|     0.0|   3.0|39.0| 31.275|   0.0|    0.0|[3.0,39.0,31.2749...|
|     0.0|   3.0|14.0| 7.8542|   1.0|    0.0|[3.0,14.0,7.85419...|
|     1.0|   2.0|55.0|   16.0|   1.0|    0.0|[2.0,55.0,16.0,1....|
|     0.0|   3.0| 2.0| 29.125|   0.0|    2.0|[3.0,2.0,29.125,0...|
|     0.0|   3.0|31.0|   18.0|   1.0|    0.0|[3.0,31.0,18.0,1....|
|     0.0|   2.0|35.0|   26.0|   0.0|    0.0|[2.0,35.0,26.0,0....|
|     1.0|   2.0|34.0|   13.0|   0.0|    0.0|[2.0,34.0,13.0,0....|
|     1.0|   3.0|15.0| 8.0292|   1.0|    2.0|[3.0,15.0,8.02919...|
+--------+------+----+-------+------+-------+--------------------+
only showing top 20 rows

这正是我们想要的。

建模

现在是有趣的部分,对吗?不要!哈哈。建模很重要,但是如果没有前面的步骤,这是不可能的。所以在所有的步骤中享受乐趣:)

在建模之前,让我们按照惯例将训练和测试分开:

(training_data, test_data) = transformed_data.randomSplit([0.8,0.2])

好的。建模。这意味着,在这种情况下,为我们的数据集构建并拟合一个 ML 模型,以预测“幸存”的列和所有其他列。我们将使用一个随机森林分类器。这实际上是一个我们必须适应的估计器

这实际上是最简单的部分:

from pyspark.ml.classification import RandomForestClassifierrf = RandomForestClassifier(labelCol='Survived', 
                            featuresCol='features',
                            maxDepth=5)

现在我们符合这个模型:

model = rf.fit(training_data)

这将给我们一个叫做变压器的东西。最后,我们使用测试数据集预测:

predictions = model.transform(test_data)

就是这样!你做到了。恭喜:)。你的第一个火花 ML 模型。现在让我们看看我们做得有多好。为此,我们将使用一个称为准确度的基本指标:

# Evaluate our model
from pyspark.ml.evaluation import MulticlassClassificationEvaluatorevaluator = MulticlassClassificationEvaluator(
    labelCol='Survived', 
    predictionCol='prediction', 
    metricName='accuracy')

我们要获得我们所做的准确性:

accuracy = evaluator.evaluate(predictions)
print('Test Accuracy = ', accuracy) -> 0.843

我们的基本模型给出了 0.843 的精度。一点也不差:)。

应该注意的是,我们必须做更多的事情来实际构建一个数据科学项目和一个好的 ML 模型,比如交叉验证、特征选择,我们还必须测试更多的模型,等等。

我在 GitHub 中创建了一个 repo,包含了本文的所有代码。您可以在这里找到它:

[## 法维奥巴斯克斯/first_spark_model

你的第一个 Apache Spark 模型:)。通过在…上创建帐户,为 FavioVazquez/first_spark_model 开发做出贡献

github.com](https://github.com/FavioVazquez/first_spark_model)

希望您能从这篇文章中学到一些新东西。我将在这个主题上创造更多,我也将很快与我的公司 Closter 一起推出关于 Spark、Python 和数据科学的课程。你可以通过以下方式联系我:favio [at] closer [dot] net

下期文章再见:)

构建数据科学项目

原文:https://towardsdatascience.com/your-first-end-to-end-deployed-project-machine-learning-part-1-e0cc4c86caa0?source=collection_archive---------61-----------------------

为什么、何时以及如何开始你的第一个数据科学/机器学习项目

UnsplashAltumCode 拍摄的照片

我应该什么时候开始我的第一个项目?

每个数据科学/机器学习的有志者至少会遇到一次的问题是,尽管他们对这个领域相对较新

现在开始我自己的项目是不是太早了?在我开始自己的项目之前,我还需要学习什么?

这个问题的答案因人而异,但一般的经验法则是,一旦你对机器学习的一些基本子主题感到满意,你就可以开始了!永远不会太早。与看别人做同样的事情或阅读相关书籍相比,我们在做一件事情时学得更快,记得更多。

应该选择哪个项目?

选择任何一个你想研究的主题(回归、分类、计算机视觉、自然语言处理等)。),试着为题目想出现实生活中的应用,并制作一个地图,一个粗略的草图,列出你需要采取的所有步骤,让这个想法走出大脑,进入现实世界。

在数据科学职业生涯的早期,您不需要担心您的项目是否有任何现实意义或可能的业务成果。这样做的根本目的是测试你自己的技能,并找到你缺乏知识的领域。

从现在开始,我将带你完成我的第一个数据科学项目,汽车转售价格预测。看一下这个项目的部署版本,以了解您的项目在完成后应该是什么样子。

本文中使用的代码片段摘自我的 GitHub 上的代码。 RESALECARS

开始使用:

以下是您在进行任何数据科学项目时需要遵循的步骤:

  1. 数据收集
  2. 数据预处理
  3. 探索性数据分析
  4. 特征工程
  5. 模型结构
  6. 部署

在本文中,我们将停留在模型构建上。使用 Heroku 和 streamlit 查看 PART-2 进行部署。我将通过上述每一个步骤来预测前面提到的汽车转售价格。

数据收集:

恭喜你!你已经走到这一步了。你有一个你愿意付诸实践的想法。这是你的第一个数据科学创意!现在你必须弄清楚你需要什么数据来建立一个模型。您可以通过两条途径收集数据:

  1. 流行的数据仓库( KaggleUCI 机器学习仓库等。)
  2. Web 报废

我使用 python 库 Selenium 从网站 CarsDirect 收集数据。然而,在这篇文章中,我不会深入探讨 web 报废技术和框架。

数据预处理:

大多数真实世界的数据集都有空值和其他类型的值(我们将在后面讨论),在进一步研究之前,您需要注意这些值。

让我们看看我们的数据集是什么样的,以及在这个数据集中有多少空值

现在我们已经知道哪些列有缺失值,我们可以继续使用各种统计技术(平均值、中值、众数)或其他方法估算这些缺失值,例如创建一个列来指示缺失值,用不同的类别替换缺失值等。

幸运的是,我处理的数据没有丢失值!

探索性数据分析:

统计学在数据科学中的应用被大大低估了。在将数据输入模型之前,我们首先需要了解哪种数据适用于所选的模型。

-连续数据:

我们可以使用 seaborn 和 matplotlib 等可视化工具,这些工具提供了各种各样的绘图,我们可以用它们来可视化我们数据的各个方面。在处理连续数据时,我们可以先绘制直方图、核密度图、散点图,最后是相关矩阵。

-分类数据:

我们可以使用条形图、饼图来显示分类列中每个类/类别的出现频率,从而使分类列可视化。Seaborn 和 matplotlib 都为此提供了漂亮的可视化工具。然而,最简单的方法是直接使用 pandas(它反过来使用 matplotlib)

特征工程:

我们已经获得了我们的数据。我们已经清理了数据。我们知道我们的数据是如何分布的。因此,让我们开始构建一个模型来预先停止在那里!我们还没有到那一步。我们的数据还没有准备好用于模型训练。

固定偏斜度:

并非所有的数据分布都适用于每个模型。打个比方,如果我(一个印度人)去另一个国家(比如中国),我将无法适应他们的食物,也无法以最佳状态工作,因为我习惯了传统的印度餐。线性模型适用于高斯数据,基于树的模型不需要标准化数据,其他不同的模型需要不同种类的数据。最佳做法是从修正偏斜度并将数据转换为高斯分布开始。

该代码片段允许您可视化所有数字数据的分布,并找出数据的偏差程度。

数据的这种偏斜可以通过各种变换来解决,例如:

  1. 对数变换
  2. 博克斯-考克斯变换
  3. 指数变换
  4. 相互转化

创建新列:

这一步没有标准程序。这完全取决于您拥有的数据类型。我将通过举例来详细说明你会在哪里使用它。

  • 实例 1 :假设您有一列分类数据,其中 10%-15%的数据丢失。您不能删除该实例,因为这将大大减少您的数据大小。你是做什么的??创建一个新列,该列的值为 1,其中给定的列不为空,0 表示空,然后使用-1 或“N.A”作为新的类别来估算空值。
  • 实例 2: 假设您有一列连续的数据,比如年龄。您可以进一步使用此列创建一个新列(假设为“成人”),如果年龄为 18 岁,则值为 0,如果年龄≥ 18 岁,则值为 1...

在执行特征工程时,有许多其他方法可以采用,但这是我坚持的主要方法。

在我们开始建模之前,将数据分成测试集和训练集

模型建筑:

我们终于到了。唷!太久了。我们的数据现在可以用于建模了。

对于这个特殊的实例(转售汽车价格回归),我们正在执行的任务是回归。因此,我们将尝试各种回归模型,找出哪种模型能给我们最好的精度/ RMSE,然后构建堆叠模型。

这里我常用的模型有:线性回归、随机森林回归器、梯度推进树、SVM、Lasso、ElasticNet、BayesianRidge、Ridge、LassoLarsIC、Kernel Ridge、XGBoost、LightGBM。很长的名单,不是吗?

为每个模型创建一个参数网格,然后使用随机搜索找到给定模型的理想参数。

下面给出的是梯度推进回归器的代码。这个过程在列表中的每个模型上用不同的参数网格执行。

一旦你知道哪个模型给你最好的准确性,选择所有或/和少数这些,并创建多个集合,以获得最好的输出。

我们现在有了一个好的预测器,好得不能再好了!我们已经从一个想法走了很长的路。我们终于完成了我们的第一个项目!…哦,等等。我们还没有部署模型!

[## 使用 Streamlit 和 Heroku 进行部署

sandeepram3103.medium.com](https://sandeepram3103.medium.com/end-to-end-deployed-project-machine-learning-part-2-43ddb1bc43d0)

谢谢你留下来。我希望这对你有所帮助,如果你觉得这很有用,请鼓掌,如果你有任何与数据科学相关的疑问,请随时联系我。

你在 PyTorch 的第一个神经网络

原文:https://towardsdatascience.com/your-first-neural-network-in-pytorch-725631ae0fc?source=collection_archive---------6-----------------------

让我们把电脑预热一下。

随着深度学习领域日益升温,网络上有太多的高级文章,很容易认为深度学习是只为数学博士保留的高级领域——但让我们证明你错了。

照片由 Aziz AcharkiUnsplash 上拍摄

深度学习领域,至少是实践部分,从未像现在这样容易起步——因为资源的数量在增长,图书馆也在变得更好。

这篇文章的目标读者是那些知道人工神经网络的基础理论但不知道如何编码的人。相信我,事情会比你想象的简单。

这篇文章的结构如下:

  1. 导入和数据集
  2. 训练/测试分割
  3. 定义神经网络模型
  4. 模特培训
  5. 模型评估
  6. 结论

这看起来很多,但是我保证——如果你安装了必要的库,你最多可以在 10 分钟内读完,如果你决定跟随代码,15 分钟就可以了。

读完这篇文章后,你将对如何在 PyTorch 库中实现一个人工神经网络算法来对以前看不见的数据进行预测有一个基本的想法。

请记住,这篇文章并没有涵盖高级的内容,因为这些内容将会出现在后面的文章中。所以事不宜迟,我们开始吧。

导入和数据集

对于这个简单的例子,我们将只使用几个库:

  • Pandas:用于数据加载和操作
  • Scikit-learn:用于列车测试分割
  • Matplotlib:用于数据可视化
  • PyTorch:用于模型训练

如果您只想复制/粘贴,以下是导入内容:

import torch
import torch.nn as nn
import torch.nn.functional as F
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split

至于数据集,虹膜数据集,可以在这个 URL 上找到。下面介绍如何在熊猫中直接导入:

iris = pd.read_csv('[https://raw.githubusercontent.com/pandas-dev/pandas/master/pandas/tests/data/iris.csv](https://raw.githubusercontent.com/pandas-dev/pandas/master/pandas/tests/data/iris.csv')')
iris.head()

前几行看起来像这样:

我们现在要做的是将Name列中的值更改或重新映射为数字——比如说0, 1, 2。下面是如何做到这一点:

mappings = {
   'Iris-setosa': 0,
   'Iris-versicolor': 1,
   'Iris-virginica': 2
}iris['Name'] = iris['Name'].apply(lambda x: mappings[x])

执行上面的代码会产生以下数据帧:

也就是说我们可以继续了。

训练/测试分割

在本节中,我们将使用Scikit-Learn库来进行训练/测试分割。之后,我们将把分割数据从Numpy arrays转换到PyTorch tensors

让我们看看怎么做。

首先,我们需要将虹膜数据集分为特征目标 —或者 X 和 y。列Name将是目标变量,其他所有内容都将是特征(或预测值)。

我也将使用一个随机的种子,所以你能够复制我的结果。代码如下:

X = iris.drop('Name', axis=1).values
y = iris['Name'].valuesX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)X_train = torch.FloatTensor(X_train)
X_test = torch.FloatTensor(X_test)
y_train = torch.LongTensor(y_train)
y_test = torch.LongTensor(y_test)

如果您现在检查从X_train开始的前 3 行,您会得到这样的结果:

同样适用于y_train:

我们现在已经具备了创建神经网络所需的一切——让我们在下一节开始吧。

定义神经网络模型

至于模型的架构,会很简单。让我们看看网络将如何构建:

  1. 全连通层 ( 4 输入特征(X 中的特征数), 16 输出特征(任意))
  2. 全连通层 ( 16 输入特征(来自上一层的输出特征数), 12 输出特征(任意))
  3. 输出层 ( 12 输入特征(来自前一层的输出特征的数量), 3 输出特征(不同类的数量))

差不多就是这样。除此之外,我们将使用 ReLU 作为我们的激活函数。让我们看看如何用代码实现这一点:

class ANN(nn.Module):
   def __init__(self):
       super().__init__()
       self.fc1 = nn.Linear(in_features=4, out_features=16)
       self.fc2 = nn.Linear(in_features=16, out_features=12)
       self.output = nn.Linear(in_features=12, out_features=3)

 def forward(self, x):
     x = F.relu(self.fc1(x))
     x = F.relu(self.fc2(x))
     x = self.output(x)
     return x

PyTorch 使用这种面向对象的方式来声明模型,并且非常直观。在构造函数中,您将定义所有的层及其架构,在forward()方法中,您将定义一个向前传递。

就这么简单。

现在,让我们创建一个模型实例,并验证其架构是否与我们上面指定的架构相匹配:

model = ANN()
model

太好了。在我们训练模型之前,我们还需要声明几件事情:

  • 标准:基本上我们如何衡量损失,我们将使用CrossEntropyLoss
  • 优化器:优化算法,我们将使用学习率为0.01Adam

下面是如何用代码实现它:

criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)

现在是我们期待已久的部分——模特培训!

模特培训

这部分也会极其简单。我们将训练模型 100 个纪元,记录时间和损失。每隔 10 个时期,我们将向控制台输出当前状态——指示我们所处的时期以及当前的损失。

代码如下:

%%timeepochs = 100
loss_arr = []for i in range(epochs):
   y_hat = model.forward(X_train)
   loss = criterion(y_hat, y_train)
   loss_arr.append(loss)

   if i % 10 == 0:
       print(f'Epoch: {i} Loss: {loss}')

   optimizer.zero_grad()
   loss.backward()
   optimizer.step()

如果你想知道最后 3 行在做什么,答案很简单— 反向传播 —因此更新权重和偏差,这样模型就可以真正“学习”。

下面是上面代码的结果:

太快了——请不要习惯这种感觉。

如果简单的数字对你来说毫无意义,这里有一个我们损失的可视化(x 轴上的纪元编号和 y 轴上的损失):

我们已经训练了模型,但是现在呢?我们需要以某种方式在以前看不见的数据上评估。在这里多呆一分钟,你就会知道怎么做了。

模型评估

在评估过程中,我们希望以某种方式跟踪模型做出的预测。我们需要迭代X_test并做出预测,然后将它与实际值进行比较。

这里我们将使用torch.no_grad(),因为我们只是在评估——没有必要更新权重和偏差。

总之,代码如下:

preds = []with torch.no_grad():
   for val in X_test:
       y_hat = model.forward(val)
       preds.append(y_hat.argmax().item())

预测现在存储在preds数组中。我们现在可以用以下 3 个属性制作一个熊猫数据帧:

  • Y:实际值
  • YHat:预测值
  • Correct:标志,1 表示YYHat匹配,否则为 0

代码如下:

df = pd.DataFrame({'Y': y_test, 'YHat': preds})df['Correct'] = [1 if corr == pred else 0 for corr, pred in zip(df['Y'], df['YHat'])]

df的前 5 行将如下所示:

这很好,但是实际上如何计算精确度呢?

这很简单——我们只需要对Correct列求和,然后除以df的长度:

df['Correct'].sum() / len(df)**>>> 1.0**

我们的模型对以前未见过的数据的准确率是 100%。请记住,这只是因为虹膜数据集非常容易分类,这绝不是说神经网络是该数据集的最佳算法。我会说 NN 对于这种类型的问题来说太过了,但是这是另一个时间的讨论。

结论

这就是你所要写的最简单的神经网络,有一个完美干净的数据集,没有丢失的值,最少的层和神经元,承认吧,这很容易。

下一次就不会了——因为更多的先进概念将会被引入。

感谢阅读。再见。

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

[## 通过我的推荐链接加入 Medium-Dario rade ci

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

medium.com](https://medium.com/@radecicdario/membership)

你迈向 AI 的第一步——标签数据!

原文:https://towardsdatascience.com/your-first-step-towards-ai-labeled-data-826d114c9bba?source=collection_archive---------58-----------------------

照片由卡拉·伍兹Unsplash 上拍摄

成功的机器学习项目需要良好的数据——但在许多项目中,这可能已经是第一个主要障碍。例如,来自照相机的图像数据可能已经可用,但是到目前为止还没有记录计算机可读的数据,这些数据在将来应该会被自动识别。特别是如果你想从 AI 开始,前面的数据准备工作可能会令人不知所措。当然,在您只想从一个已定义领域的概念证明开始第一次尝试的情况下,这尤其令人沮丧。

因此,您需要一个解决方案来快速、轻松地标记您自己的原始数据。我们看了看工具丛林,收集了市场所能提供的和需要注意的东西。让我们来看看在开始贴标签之前,你应该问自己哪些重要的问题,以及你可以使用的工具。

谁应该给数据贴标签?

标注是一项非常繁琐的任务——尤其是如果你想为深度学习算法提供足够多的数据。如果你不相信这一点,你应该想象一下,以像素级的精度在数百张图像上画出组件的缺陷是什么样的。不幸的是,一定数量的标记数据是绝对必要的。那么你从哪里得到这些数据呢?基本上,有以下几种情况:

  1. 领域专家对数据的标注:当涉及到你自己的数据时,作为一名专家你自然最清楚应该如何标注。在开始时,您应该决定什么是存储标签的好格式,并使用合适的工具建立一个工作流,以便可以对数据集尽可能快地完成这项工作。
  2. 由人工智能服务提供商标记:在适当的指导和解释之后,您的人工智能伙伴当然也能够执行标记。这样做的好处是可以直接传达对基本数据及其类的良好理解。同时,这种方法在大多数情况下成本太高,因为贴标签本身并不复杂。
  3. 第三方贴标:也可以将工作完全外包。谷歌等云服务提供商也为此提供自己的服务(【https://cloud.google.com/ai-platform/data-labeling/docs】T2)。但是,仅支持某些格式(图像、视频和文本),并且必须制定非常具体的指令才能获得正确的结果。文档建议进行几次测试,直到它工作为止。数据本身当然也必须转移到云中。

在下文中,我们将更多地关注前两种情况,因为根据我们的经验,它们发生得最为频繁。

什么样的数据可以被标注?

虽然当考虑带标签的数据和图像中的人工智能对象识别是首先想到的事情,但来自不同应用程序的各种各样的数据类型都可以用标签来丰富。标签本身也可以应用在不同的层次上。例如,您可以标记整个图像,在其中绘制框并标记它们(边界框分割),甚至分配具有像素精度的类(语义分割)。

不同种类的标记级别(从左至右):标记、边界框、语义分割、安德里亚·苏克罗改编自的图片 https://www . pexels . com/photo/grey-and-white-long-coated-cat-in-middle-of-book-son-shelf-156321/

除了图像,当然还有其他非常适合处理的数据格式,其中最相关的有:

  • 时间序列:例如,这包括机器控制系统的记录或生产过程中保存的传感器值。
  • 音频:来自音频区的数据可用于识别语音或分析麦克风在任何过程中拾取的录音。
  • Text :对自然语言处理领域的所有用例都感兴趣,比如聊天机器人或智能文档管理系统。
  • 图像:通常来自照相机或光学传感器的数据,其应该支持例如生产过程结束时的质量控制。
  • 视频:视频记录可来自监控摄像头,例如可用于提高机器操作的安全性。
  • 3D 数据:也可以想象,例如制造模型的部件需要提供标签。

正如我们将在后面看到的,工具在不同程度上支持不同的数据区域。但是,除了功能性要求之外,还有其他一些一般条件需要考虑。

谷仓图片Unsplash 上拍摄

一个好的标签工具还有哪些进一步的要求?

如果你正在与一家人工智能服务提供商合作,并且拥有敏感的公司数据,那么还有更进一步的考虑。

  • 许可合规:当使用外部工具时,如果客户想要自己贴标,必须允许在有限的时间内将其传递给客户。另一方面,如果人工智能服务提供商支持贴标签过程,这种情况也可能发生在客户身上。
  • 数据安全性:如果可能的话,我们希望避免基于云的解决方案,因为我们经常处理敏感数据,不希望这些数据不必要地出现在标签供应商的服务器上。
  • 舒适性:该工具还应能被缺乏技术经验的员工直观地操作。这方面也包括时间投入。使用选择的工具总是比“手动”更快。该工具还必须在技术上易于设置,并且可以在尽可能多的环境中使用。
  • 用例覆盖:最理想的是,一个工具而不是五个工具。这应该是一个程序,支持图像分割,但也可以处理时间序列分类。
  • 成本:使用的工具不应超出财务和时间框架。在大多数情况下,这种考虑可以反映在免费工具和付费解决方案节省的时间的比较中。

鉴于这些标准,我们准备看看提供的解决方案!

有哪些工具?

我们环顾四周,试图了解市场上现有的解决方案。我们研究了商业软件和免费软件,试图理解它们涵盖了哪些用例。商业解决方案大多基于云支持,除了标签之外,还提供额外的功能,如人工智能算法的同步培训或外部劳动力的支持。大多数免费的替代方案通常需要命令行安装,并且不能作为现成的解决方案使用(如果您想自己托管它们)。

我们对不同标签工具的比较概述,图片作者 Andrea Suckro (slashwhy)

该表迄今为止还不完整,而是旨在给出当前解决方案的概述。我们注意到,对于 3D 数据的标记,没有真正规范的解决方案(除了 KNOSSOS,它是一种用于组织数据的专用工具)。因此,对于您的技术 3D 数据,您必须使用自己选择的工具(例如,AutoCAD、Blender 等)进行标注,并将其导出到相应的文件中。

最后的想法

所有的开始都是困难的——就像为一个最初的人工智能项目准备带有标签的原始数据一样。然而,我们可以依靠不断增加的支持和工具。对于这个领域的第一步,Label-Studio 最让我们信服,因为它安装迅速,易于使用。如果需要,它还对不同的数据类型和高级工作流提供了非常广泛的支持。我们希望这篇文章可以让你对标签世界有一点了解,并使你能够在你的个人人工智能之旅中迈出下一步。所以不要害羞,让我们开始吧——从收集数据到贴标签!

以下是我们介绍的工具的链接集合:

  1. 仓促https://hasty.ai/solution.html
  2. https://www.datagym.ai/数据体育馆
  3. https://labelbox.com/标签盒
  4. 谷歌云 AI 标签https://cloud.google.com/ai-platform/data-labeling/docs
  5. 云工厂https://www.cloudfactory.com/data-labeling
  6. 最终标记https://github.com/alexandre01/UltimateLabeling
  7. 拉贝尔梅https://github.com/wkentaro/labelme
  8. https://github.com/tzutalin/labelImg
  9. 标签工作室https://github.com/heartexlabs/label-studio
  10. 曲线https://github.com/baidu/Curve
  11. https://archive.mpi.nl/tla/elan 的锐气

线性回归模型指南

原文:https://towardsdatascience.com/your-guide-to-linear-regression-models-df1d847185db?source=collection_archive---------14-----------------------

用 Python 解释和编程线性回归模型

照片由德鲁·比默Unsplash 上拍摄

可解释性是机器学习中最大的挑战之一。如果一个模型的决策更容易被人理解,那么这个模型就比另一个模型更具有可解释性。有些模型非常复杂,内部结构如此复杂,以至于几乎不可能理解它们是如何得出最终结果的。这些黑盒似乎打破了原始数据和最终输出之间的关联,因为在这之间发生了几个过程。

但是在机器学习算法的宇宙中,有些模型比其他模型更透明。决策树肯定是其中之一,线性回归模型又是另外一个。它们的简单和直接的方法使它们成为解决不同问题的理想工具。让我们看看怎么做。

您可以使用线性回归模型来分析给定地方的工资如何依赖于经验、教育水平、角色、工作城市等特征。同样,您可以分析房地产价格是否取决于诸如面积、卧室数量或到市中心的距离等因素。

在这篇文章中,我将重点关注线性回归模型,这些模型检查一个因变量和一个(简单线性回归)或多个(多元线性回归)自变量之间的线性关系。

简单线性回归

当输出变量(目标)只有一个输入变量(预测值)时,使用的是最简单的线性回归形式:

  • 输入预测变量是帮助预测输出变量值的变量。俗称 X
  • 输出目标变量是我们想要预测的变量。就是俗称的 y

β0 的值,也叫截距,表示估计回归线与 y 轴相交的点,而 β1 的值决定了估计回归线的斜率随机误差描述的是因变量和自变量之间线性关系的随机成分(模型的扰动, yX 无法解释的部分)。真正的回归模型通常是未知的(因为我们无法捕捉影响因变量的所有效应),因此对应于观察数据点的随机误差项的值仍然未知。然而,回归模型可以通过计算观察数据集的模型参数来估计。

回归背后的想法是从样本中估计参数 β0β1 。如果我们能够确定这两个参数的最佳值,那么我们将有最佳拟合的线,我们可以用它来预测的值,给定 X 的值。换句话说,我们试图拟合一条线来观察输入和输出变量之间的关系,然后进一步用它来预测看不见的输入的输出。

我们如何估算 β0β1 ?我们可以使用一种叫做普通最小二乘法(OLS) 的方法。其背后的目标是将黑点到红线的距离尽可能地减小到接近零,这是通过最小化实际结果和预测结果之间的平方差来实现的。

实际值和预测值之间的差异称为残差(e) ,可以是负数,也可以是正数,这取决于模型是否高估或低估了结果。因此,为了计算净误差,将所有残差直接相加会导致项的消除和净效应的减小。为了避免这种情况,我们取这些误差项的平方和,称为 残差平方和(RSS)。

普通最小二乘法(OLS)将残差平方和最小化,其目的是拟合一条回归线,使观测值与预测值(回归线)之间的距离(以二次值测量)最小化。

多元线性回归

有两个或两个以上预测值或输入变量时,线性回归的形式。与之前描述的 SLR 模型相似,它包括额外的预测因子:

请注意,该方程只是简单线性回归方程的扩展,其中每个输入/预测值都有其对应的斜率系数 ) 。第一个 β

随着要素数量的增长,我们的模型的复杂性也在增加,并且变得更加难以可视化,甚至难以理解我们的数据。因为与单反相机相比,这些模型中的参数更多,所以在使用它们时需要更加小心。添加更多的术语将从本质上提高数据的拟合度,但新术语可能没有任何实际意义。这是危险的,因为它可能会导致一个模型符合这些数据,但实际上并不意味着任何有用的东西。

一个例子

广告数据集包括一种产品在 200 个不同市场的销售额,以及三种不同媒体的广告预算:电视、广播和报纸。我们将根据电视、广播和报纸广告预算(自变量),使用数据集来预测销售额(因变量)。

数学上,我们将尝试求解的公式是:

找到这些常数的值 (β) 就是回归模型通过最小化误差函数和拟合最佳直线或超平面(取决于输入变量的数量)所做的事情。我们编码吧。

加载数据并描述数据集

你可以在这个链接下下载数据集。在加载数据之前,我们将导入必要的库:

*import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn import metrics
from sklearn.metrics import r2_score
import statsmodels.api as sm*

现在我们加载数据集:

*df = pd.read_csv(“Advertising.csv”)*

让我们了解数据集并对其进行描述:

*df.head()*

我们将删除第一列(“未命名”),因为我们不需要它:

*df = df.drop([‘Unnamed: 0’], axis=1)
df.info()*

我们的数据集现在包含 4 列(包括目标变量“sales”)、200 个寄存器,没有缺失值。让我们想象一下自变量和目标变量之间的关系。

*sns.pairplot(df)*

电视和销售之间的关系似乎相当紧密,虽然广播和销售之间似乎有某种趋势,但报纸和销售之间的关系似乎并不存在。我们也可以通过相关图进行数字验证:

*mask = np.tril(df.corr())
sns.heatmap(df.corr(), fmt=’.1g’, annot=True, cmap= ‘cool’, mask=mask)*

正如我们所料,最强的正相关发生在销售和电视之间,而销售和报纸之间的关系接近于 0。

选择特征和目标变量

接下来,我们将变量分成两组:因变量(或目标变量“y”)和自变量(或特征变量“X”)

*X = df.drop([‘sales’], axis=1)
y = df[‘sales’]*

分割数据集

要了解模型性能,将数据集分为定型集和测试集是一个好策略。通过将数据集分成两个独立的集合,我们可以使用一个集合进行训练,并使用另一个集合中的未知数据来测试模型性能。

*X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)*

我们将数据集分成 70%训练和 30%测试。random_state 参数用于初始化内部随机数生成器,它将决定在您的情况下将数据分为训练和测试索引。我设置 random state = 0,这样您就可以使用相同的参数比较多次运行代码的输出。

*print(X_train.shape,y_train.shape,X_test.shape,y_test.shape)*

通过打印分割集合的形状,我们看到我们创建了:

  • 2 个各有 140 个寄存器的数据集(占总寄存器的 70%),一个有 3 个自变量,一个只有目标变量,将用于训练和生成线性回归模型。
  • 2 个数据集,每个包含 60 个寄存器(占总寄存器的 30%),一个包含 3 个自变量,一个仅包含目标变量,将用于测试线性回归模型的性能。

建立模型

构建模型非常简单:

*mlr = LinearRegression()*

火车模型

将模型拟合到训练数据代表了建模过程的训练部分。在模型定型后,可以使用预测方法调用来进行预测:

*mlr.fit(X_train, y_train)*

我们来看看模型训练后的输出,看看 β0 (截距)的值:

*mlr.intercept_*

我们还可以打印系数的值 (β) :

*coeff_df = pd.DataFrame(mlr.coef_, X.columns, columns =[‘Coefficient’])
coeff_df*

通过这种方式,我们现在可以根据电视、广播和报纸的不同预算值来估算“销售”值:

例如,如果我们确定电视预算值为 50,广播预算值为 30,报纸预算值为 10,则“销售额”的估计值为:

*example = [50, 30, 10]
output = mlr.intercept_ + sum(example*mlr.coef_)
output*

试验模型

测试数据集是独立于训练数据集的数据集。该测试数据集是您的模型的未知数据集,它将帮助您更好地了解其归纳能力:

*y_pred = mlr.predict(X_test)*

评估绩效

模型的质量与其预测与测试数据集的实际值的匹配程度有关:

*print(‘Mean Absolute Error:’, metrics.mean_absolute_error(y_test, y_pred))
print(‘Mean Squared Error:’, metrics.mean_squared_error(y_test, y_pred))
print(‘Root Mean Squared Error:’, np.sqrt(metrics.mean_squared_error(y_test, y_pred)))
print(‘R Squared Score is:’, r2_score(y_test, y_pred))*

在根据测试集验证了我们的模型之后,我们得到了 0.86 的 R,这似乎是一个相当不错的性能分数。但是,尽管较高的 R 表明模型更适合,但高度量并不总是一件好事。我们将在下面看到一些解释和改进回归模型的方法。

如何解读和改进你的模型?

好了,我们创建了模型,现在做什么?让我们看看训练数据的模型统计数据,以获得一些答案:

*X2 = sm.add_constant(X_train)
model_stats = sm.OLS(y_train.values.reshape(-1,1), X2).fit()
model_stats.summary()*

下面我们来看看这些数字是什么意思。

假设检验

运行 MLR 模型时,您应该回答的一个基本问题是,是否至少有一个预测因子对预测输出有用。如果自变量和目标之间的关系只是偶然的,并且没有任何预测因素对销售产生实际影响,那该怎么办?

我们需要进行假设检验来回答这个问题,并检查我们的假设。这一切都是从形成一个零假设(H0) 开始的,该假设声明所有系数都等于零,并且预测值和目标值之间没有关系(这意味着没有独立变量的模型既适合数据,也适合您的模型):

多元线性回归。来源:走向数据科学

另一方面,我们需要定义一个替代假设(Ha) ,该假设声明至少有一个系数不为零,并且预测值和目标值之间存在关系(意味着您的模型比仅截距模型更好地拟合数据):

多元线性回归。来源:走向数据科学

如果我们想要拒绝零假设并对我们的回归模型有信心,我们需要找到强有力的统计证据。为此,我们进行假设检验,为此我们使用了 F 统计量

如果 F-statistic 的值等于或非常接近 1,则结果有利于零假设,我们无法拒绝它。

正如我们在上表中看到的(用黄色标记),F-统计量是 439.9,从而提供了反对零假设(所有系数都是零)的有力证据。接下来,我们还需要在假设零假设为真的情况下,检查 F 统计量(也用黄色标记)出现的概率,即 8.76e-70,一个极小的低于 1%的数字。这意味着在有效的零假设假设下,F 统计值 439.9 偶然出现的概率远低于 1%。

话虽如此,我们可以拒绝零假设,并确信至少有一个预测因子在预测输出时是有用的。

生成模型

运行包含许多变量(包括不相关的变量)的线性回归模型会导致不必要的复杂模型。哪些预测因素是重要的?它们对我们的模型都有意义吗?为了找出答案,我们需要执行一个叫做特征选择的过程。特征选择的两种主要方法是:

  1. 正向选择:从与因变量相关性最高的预测值开始,一次添加一个预测值。然后,更大的理论重要性的变量被顺序地结合到模型中,直到达到停止规则。
  2. 逆向淘汰:从模型中的所有变量开始,去掉统计意义最小(p 值较大)的变量,直到达到停止规则。

虽然这两种方法都可以使用,除非预测值的数量大于样本大小(或事件数量),否则通常最好使用向后排除法。

你可以在链接中找到这些方法的完整示例和实现。

对比车型

每当你在一个模型中加入一个独立变量,R 就会增加,即使这个独立变量微不足道。在我们的模型中,所有预测因素都有助于销售增长吗?如果是的话,他们做的程度一样吗?

与 R 相反,调整后的 R 是一个仅在自变量显著并影响因变量时增加的度量。因此,如果随着您向模型中添加变量,您的 R 值增加了,但调整后的 R 值减少了,那么您就知道有些特性是没有用的,您应该删除它们。

上表中一个有趣的发现是,报纸的 p 值超高(0.789,红色标注)。找到每个系数的 p 值将会知道该变量对于预测目标是否具有统计显著性。

根据一般经验,如果给定变量的 p 值小于 0.05,则该变量和目标之间有很强的关系。

这种方式,包括变量报纸似乎不适合达到一个稳健的模型,删除它可能会提高模型的性能和泛化能力。

除了调整后的 R 分数,您还可以使用其他标准来比较不同的回归模型:

  • 赤池信息准则(AIC): 是一种用于估计模型的似然性以预测/估计未来值的技术。它奖励达到高拟合度分数的模型,如果它们变得过于复杂,则惩罚它们。一个好的模型是所有其他模型中 AIC 最小的模型。
  • 贝叶斯信息标准(BIC): 是模型选择的另一个标准,衡量模型拟合度和复杂性之间的权衡,对过于复杂的模型的惩罚甚至超过 AIC。

假设

因为线性回归模型是任何事件的长期序列的近似值,所以它们需要对它们所代表的数据做出一些假设,以便保持适当。大多数统计测试依赖于对分析中使用的变量的某些假设,当这些假设不满足时,结果可能不可信(例如,导致 I 型或 II 型错误)。

从输出是输入变量的线性组合的意义上来说,线性回归模型是线性的,并且只适合于对可线性分离的数据进行建模。线性回归模型在各种假设下工作,这些假设必须存在,以便产生正确的估计,而不仅仅依赖于准确性分数:

  • 线性:特征和目标之间的关系必须是线性的。检查线性关系的一种方法是目视检查散点图的线性。如果散点图中显示的关系不是线性的,那么我们需要运行非线性回归或转换数据。
  • 同方差:对于 x 的任何值,残差的方差必须相同。多元线性回归假设残差中的误差量在线性模型的每个点都是相似的。这种情况称为同质性。散点图是检查数据是否同质的好方法,也有几种测试可以从数字上验证假设(如 Goldfeld-Quandt、Breusch-Pagan、White)

线性回归算法的假设。来源:走向数据科学

  • 无多重共线性:数据不应显示多重共线性,当独立变量(解释变量)彼此高度相关时会出现多重共线性。如果发生这种情况,在计算出造成因变量/目标变量差异的具体变量时就会出现问题。这种假设可以用方差膨胀因子(VIF)法或通过相关矩阵来检验。解决这个问题的替代方法可能是将数据居中(扣除平均分数),或者进行因子分析并旋转因子以确保线性回归分析中因子的独立性。
  • 无自相关:残差的值应该彼此独立。残差中相关性的存在大大降低了模型的准确性。如果误差项相关,估计的标准误差往往会低估真实的标准误差。为了检验这个假设,你可以使用 Durbin-Watson 统计。
  • 残差的正态性:残差必须是正态分布的。正态性可以用拟合优度检验(如科尔莫戈罗夫-斯米尔诺夫或夏皮罗-维尔克检验)来检查,如果数据不是正态分布,非线性变换(如对数变换)可能会解决这个问题。

线性回归算法的假设。来源:走向数据科学

假设是至关重要的,因为如果假设无效,那么分析过程就会被认为是不可靠的、不可预测的和失控的。无法满足假设可能导致得出无效或没有数据科学支持的结论。

你可以在链接中找到对假设的全面测试。

最后的想法

虽然 MLR 模型扩展了 SLR 模型的范围,但它们仍然是线性模型,这意味着模型中包含的术语不能显示彼此之间的任何非线性关系,也不能代表任何种类的非线性趋势。预测要素观测范围之外的点时也应小心,因为当您移出观测范围时,变量之间的关系可能会发生变化(由于没有数据,您无法知道这一事实)。

观察到的关系可能是局部线性的,但在数据范围之外可能存在未观察到的非线性关系。

线性模型还可以通过包含非线性变量(如多项式)和转换指数函数来模拟曲率。线性回归方程在 参数 中为线性,意思是你可以将自变量提升一个指数来拟合一条曲线,仍然保持在“线性世界”中。线性回归模型可以包含对数项和反项,以遵循不同类型的曲线,但仍然保持参数的线性。**

当自变量被平方时,模型在参数上仍然是线性的

多项式回归 这样的回归可以模拟非线性关系,虽然线性方程有一种基本形式,但非线性方程可以采取许多不同的形式。您可能考虑使用 非线性回归模型 的原因是,虽然线性回归可以模拟曲线,但它可能无法模拟数据中存在的特定曲线。

您还应该知道,OLS 并不是拟合您的线性回归模型的唯一方法,其他优化方法,如 梯度下降 更适合大型数据集。将 OLS 应用于复杂的非线性算法可能不可扩展,梯度下降法在计算上可以更便宜(更快)地找到解决方案。梯度下降是一种最小化函数的算法,给定一个由一组参数定义的函数,该算法从一组初始参数值开始,迭代地向一组最小化该函数的参数值移动。这个迭代最小化是使用导数实现的,在函数梯度的负方向上采取步骤。

使用梯度下降的线性回归。来源:走向数据科学

另一个需要考虑的关键问题是异常值会对回归线和相关系数产生巨大影响。为了识别它们,有必要执行探索性数据分析(EDA) ,检查数据以检测异常观察,因为它们会以激烈的方式影响我们的分析和统计建模的结果。如果您发现任何异常值,可以对其进行估算(例如,使用平均值/中值/众数)、封顶(替换某些限制之外的值)或替换缺失值并进行预测。

最后,线性回归模型的一些限制是:

  • 省略变量。需要有一个好的理论模型来建议解释因变量的变量。在简单的双变量回归的情况下,人们必须考虑其他因素来解释因变量,因为可能有其他“未观察到的”变量来解释输出。
  • 反向因果关系。许多理论模型预测双向因果关系——也就是说,因变量可以引起一个或多个解释变量的变化。例如,更高的收入可以让人们在自己的教育上投入更多,这反过来会提高他们的收入。这使得回归估计的方式变得复杂,需要特殊的技术。
  • 测量错误。因子可能测量不正确。例如,天资很难衡量,智商测试也存在众所周知的问题。因此,使用智商的回归可能无法正确控制资质,导致教育和收入等变量之间的不准确或有偏差的相关性。
  • 太局限了一个焦点。回归系数仅提供一个变量的小变化(而非大变化)与另一个变量的变化之间的关系。它将显示教育中的一个小变化是如何影响收入的,但它不会让研究者概括大变化的影响。如果每个人同时接受大学教育,一个刚毕业的大学生不太可能挣得更多,因为大学毕业生的总供给会急剧增加。

对这些话题感兴趣?在 Linkedin或 Twitter 上关注我

你的网刮 Quora 问答指南

原文:https://towardsdatascience.com/your-guide-to-web-scrape-quora-q-as-92b802f6dd9?source=collection_archive---------43-----------------------

数据科学

只需几行代码,你就能抓取 Quora 的数据

来源:由 Flickr 中的托马斯·霍克(CC By-NC 2.0)

在本教程中,我将向您展示如何使用 Anaconda Jupyter 笔记本和 BeautifulSoup 库来执行 web 抓取。

我们将从 Quora 搜集问题和答案,然后我们将它们导出到Pandaslibrary data frame,然后导出到一个. CSV 文件。

让我们直接进入正题,然而,如果你正在寻找一个指南来理解网络抓取,我建议你阅读来自 Dataquest 的这篇文章。

1-使用一个 URL

让我们导入我们的库

import urllib
import requests
from bs4 import BeautifulSoup
import pandas as pd

插入你的 Quora 网址,一个例子显示。

url = ‘[https://www.quora.com/Should-I-move-to-London'](https://www.quora.com/Should-I-move-to-London')

然后让我们向 web 服务器发出一个GET请求,它将为我们下载给定网页的 HTML 内容。

page = requests.get(url)

现在,我们可以使用 BeautifulSoup 库来解析这个页面,并从中提取文本。我们首先必须创建一个BeautifulSoup类的实例来解析我们的文档:

soup = BeautifulSoup(page.content, ‘html.parser’)

然后,我们将创建熊猫数据框架来包含我们想要的问答。

df = pd.DataFrame({‘question’: [],’answers’:[]})

现在是从网页中选择问答类的时候了,类在抓取时被用来指定我们想要抓取的特定元素。

question = soup.find(‘span’, {‘class’: ‘ui_qtext_rendered_qtext’})
answers = soup.find_all(‘div’, attrs={‘class’: ‘ui_qtext_expanded’})

然后,我们可以通过将结果添加到之前创建的数据框架中来得出结论。

for answer in answers:
     df = df.append({‘question’: question.text,
         ‘answers’: answer.text
          }, ignore_index=True)
df

将结果导出到 CSV 文件的时间。

df.to_csv(‘One_URLs.csv’)

2-使用多个 URL

这一次我们将一起努力在同一时间内刮出不止一页。这一过程几乎与相对变化相同。

从导入库开始

import urllib
import requests
from bs4 import BeautifulSoup
import pandas as pd

添加所有你需要的网址,我们现在有 2 个

url = [‘[https://www.quora.com/What-are-best-places-to-relocate-and-settle-in-UK'](https://www.quora.com/What-are-best-places-to-relocate-and-settle-in-UK'), ‘[https://www.quora.com/Should-I-relocate-to-the-UK'](https://www.quora.com/Should-I-relocate-to-the-UK')]

创建我们的数据框架

df = pd.DataFrame({‘question’: [],’answers’:[]})

现在,我们将执行一个 for 循环,该循环将迭代两个 URL 来执行相同的过程,然后它可以将结果保存到 DataFrame 中。

for i in url:
   page = requests.get(i)
   soup = BeautifulSoup(page.content, “html.parser”)
   question = soup.find(‘span’, 
            {‘class’:      ‘ui_qtext_rendered_qtext’})
   answers = soup.find_all(‘div’, 
                attrs={‘class’:    ‘ui_qtext_expanded’})
   for answer in answers:
        df = df.append({‘question’: question.text,
          ‘answers’: answer.text
            }, ignore_index=True)
df

现在,让我们将数据帧导出到 CSV 文件。

df.to_csv(‘Two_URLs.csv’)

您现在应该对如何从 Quora 中抓取和提取数据有了很好的理解。一个很好的下一步,如果你对网络抓取有点熟悉,你可以选择一个网站,自己尝试一些网络抓取。

快乐编码:)

你想象中作为数据分析师的第一天

原文:https://towardsdatascience.com/your-imaginary-first-day-as-a-data-analyst-593f45a1e9fa?source=collection_archive---------39-----------------------

在你先前在线课程知识的帮助下完成你的第一个项目

你有没有问过自己,作为一名数据分析师,成功的第一天是怎样的?为了获得我的数据科学纳米学位,我将向您展示一个简单的场景。

你会学到:

  1. 什么是交叉销售?
  2. 如何分析你的客户?
  3. 如何使用机器学习进行交叉销售预测?

塞纳里奥

我从 Kaggle 获得了一个名为“健康保险”交叉销售预测的数据集🏠 🏥。请想象一下,你是一家大型保险公司的数据分析师。作为你的第一份工作,你的老板让你分析一个特定的客户数据集。他给了您一个 customer-info.csv 文件和以下三个问题:

  1. 我们公司的典型客户是什么?
  2. 什么因素决定了客户是否愿意接受我们的保险?
  3. 哪些客户会对我们的营销活动做出回应?

不幸的是,作为一名初露头角的数据科学家,你不知道什么是交叉销售,所以你马上去谷歌一下:

“交叉销售是向现有客户销售额外产品或服务的行为或实践”——维基百科 2020

现在你知道了。你在一家提供全面健康保障的大型保险公司工作。这家保险公司现在希望扩大其产品组合。因此,你的工作是找出哪些客户可能对汽车保险感兴趣。

我们公司的典型客户是什么?

现在您想使用您的 Python 知识来分析数据。为了可视化和分析数据,您使用了 Seaborn 和 Pandas 库。完成后,您定义了两个客户角色。

24 岁,住在,拥有【28】的优秀称号。她有驾照,她的车是两年前的并且已经损坏。到目前为止,她对汽车保险没有兴趣。

凯文今年 28 岁,也住在,有着优秀的头衔【28】。他也有驾驶执照。因为他真的很喜欢汽车,他的车是几个月前的,它的一点损坏都没有。到目前为止,他对汽车保险没有兴趣。

当你向你的同事展示人物角色时,他们会印象深刻。但是,他们建议您再添加一些图表。否则,老板会怀疑这一切是不是你编造的。你想,这一点问题都没有。毕竟,人物角色不是你想出来的。恰恰相反,数据分析是你假设的人物角色的基础。首先,您创建了一个性别分布图。

性别分布只相差几个百分点。所以,你决定要一男一女。下一步是观察年龄分布。你还确保每个年龄组的男性人数大致相同。因此,你用两种颜色描绘了年龄分布。您可以从图表中看到,大多数客户都在 25 岁到 30 岁出头之间。

所以,你决定选择 24 岁和 28 岁的两个人。所以你选择了 24 岁和 28 岁的两个人。即使你对此没有任何更精确的信息,你也要相信你的直觉。在关于该地区的图表中,您可以看到大多数人来自第 28 州,并且每个人都有驾驶执照。

最后,您决定仔细看看客户的汽车。您已经注意到,大多数客户的车龄在 1 到 2 年之间,甚至不到 1 年。你认为这是重要的信息,当然,你想把它包含在你的人物角色中。

客户是否会对我们的交叉销售方法做出反应,这取决于什么?

你的老板对你的分析印象深刻。但是他也有需要批评的地方。你的两个角色都对我们的产品不感兴趣。他想知道是什么因素影响了安和凯文,使他们更有可能从他的公司购买汽车保险。

所以,你回去工作,你决定在反应特征和其他特征之间找到一些关联。

您将从热图中获得的新信息添加到角色中:

如果凯文的车受到更严重的损坏,他会改变主意的。这是基于响应标准和车辆损坏标准之间的小相关性(0.35)。你认为向你的老板建议我们可以损坏凯文的车很有趣,但你决定反对。讽刺很可能第一天就没好结果。

如果 Ann 年纪大了,她可能会改变主意(相关系数仅为 0.11)。老年人对保险更感兴趣,这意味着我们的营销活动可以专注于长期客户,但我们还没有要求他们购买车辆保险。

哪些客户会对我们的营销活动做出回应?

当把你的最终结果展示给你的老板时,他留下了深刻的印象,他现在要求你使用一些奇特的机器学习来完成你的任务。因为您已经准备好了数据,所以这没什么大不了的,因为您知道预处理已经完成了 80%的工作。

然而,在快速研究了 ScitKit-Learn 文档之后,您现在也知道该怎么做了。你的问题是一个二元分类(会或不会响应我们的交叉销售方法)你可以使用一些分类器。你决定采用一些最先进的方法,如 LBM 或 XGBoost。

同时,您希望使用一个旧的但众所周知的模型,这样您就可以展示新的高级分类器的优势。对于评估指标,你又谷歌了一遍。研究表明,一个平衡的分类器(精确度和召回率之间的平衡)会非常好。所以你确保了这一点。

从结果中可以看出,与其他分类器相比,LBM 分类器工作得相当好,并且也是平衡的。您将使用它来预测哪些客户最有可能对我们的营销活动做出回应。

在你把最终结果发给你的老板后,你会感到无比的快乐。你在网上课程中投入的所有工作和努力确保了你能在你的第一个任务和新职位上取得成功!用你最喜欢的机器学习和统计蔻驰的话说。

三次爆炸。三次爆炸。作为一名潜在的数据分析师,我们在第一天就站稳了脚跟。明天我们将获得一份真正的工作,这样我们就可以在准确的数据上测试跨行业的数据挖掘标准流程。我们很好奇。

你可以在我的 GitHub 库找到这篇文章的代码💻。感谢阅读!如果你喜欢它,请一定要鼓掌,看看我的网站🌎不要犹豫,给我发电子邮件询问反馈📩。

您的实时新冠肺炎跟踪与气流和 GitHub 网页

原文:https://towardsdatascience.com/your-live-covid-19-tracker-with-airflow-and-github-pages-658c3e048304?source=collection_archive---------32-----------------------

加载数据,使用散景制作出色的可视化效果,将它们托管在 GitHub Pages 网站上,并随着新数据的到来,让气流自动完成这一过程!

Unsplash 上由 Fabrizio Verrecchia 拍摄的照片

随着新冠肺炎病的爆发,我们——数据科学爱好者——可以使用一系列令人惊叹的数据集来制作我们自己的可视化工具,获得有用的见解,并为有用和智能信息的传播做出贡献。

这些数据通常每天更新,因为新闻中报道了新的病例。因此,想象一下,您加载数据并花大量时间清理它,进行探索性的数据分析,并创建令人印象深刻的可视化;然后你决定保存你的图表并分享它们。到目前为止还不错,但是第二天呢?数据更新后,您是否每天都手动运行脚本?还有,你的朋友怎么能不用问你就能查看图表呢?

幸运的是,有一些工具可以让这项任务变得非常简单。首先, GitHub Pages 允许你创建自己的网站,在那里你可以托管你令人惊叹的新情节(并与世界分享它们)。)其次, Apache Airflow 允许您调度和自动化流程并执行任务。它是基于 Python 的,但是它处理不同种类的任务(比如运行 C++或 Bash 脚本。)

我们开始吧!

加载、清理和转换数据

让我们以约翰·霍普金斯大学系统科学与工程中心提供的广泛使用的CSSE·新冠肺炎数据集为例,来进行我们的可视化。我们旅程的第一步是加载数据集并(像往常一样)对它们进行一些清理:我们只需更改 StateCountry 列名,按国家对州进行分组并对值求和。

这很容易,主要归功于组织良好的原始数据集。

现在我们必须选择我们想要显示的内容。为了这篇文章,我决定在金融时报上复制这张漂亮的图表。该图根据每个国家首次通过 x 平均死亡人数的天数显示了每个国家的新冠肺炎死亡人数趋势。为此,我们需要计算相关时间序列的滚动平均值。下面的代码完成了这个任务:

原始数据集提供每天的病例总数,因此我们需要首先通过调用.diff()来计算每天的病例数(还要注意,我们将只显示前 10 个国家;)然后,我们计算每列的滚动平均值。通过重置索引并连接滚动的列,我们能够将索引称为从我们第一次计算n_since值开始的 x 天的数量。当调用rolling(n_since=3)[1].head()(死亡)时,您应该会看到这样的内容:

散景可视化

熊猫.plot()将很快显示图表,但这种类型的情节值得更多的风格。在这些选项中,散景是最简单和最有特色的选择之一。我不打算进一步解释这个库的功能,因为有许多资源,而只是简单地为您提供一个我创建的定制功能(它遵循上面的代码,因此它以滚动数据帧作为输入):

这就是了!

托管到 GitHub

现在是时候让世界看到它了。创建一个 Github 网站非常简单,按照这里的说明就可以完成。基本上,您需要创建一个名为 structureusername . github . io .的新公共存储库

然后你提交新的散景图,命名为index.html并推它。最后在http://. github . io就能看到了。你可以在这里找到我的:https://hectoramirez . github . io/covid/Daily _ deaths _ Europe . html

那么,明天 CSSE 数据集更新时会发生什么呢?一种选择是手动运行您的脚本,并将您的情节提交/推送到 GitHub。每天。试着在早上早点做——你的朋友可能想在早餐时检查一下。或者…

借助气流实现 it 自动化

如前所述,Apache Airflow 允许您调度和自动化流程——比如在特定时间运行脚本。更准确地说,

气流用于创建代码管道,我们可以在其中调度和监控我们的工作流。工作流可以是要像流程图一样执行的任务的集合。

设置

有很多学习使用 Airflow 的资源,包括 Airflow 自己的文档,所以我会引导你走向我们的具体目标。让我们从安装 Airflow 开始,这可以通过 pip 工具轻松完成:

$ pip install apache-airflow

如果一切都是正确的,通过运行$ airflow version,您应该会看到类似这样的内容:

____________       _________________    |__( )_________  __/__  /________      ______  /| |_  /__  ___/_  /_ __  /_  __ \_ | /| / /___  ___ |  / _  /   _  __/ _  / / /_/ /_ |/ |/ /_/_/  |_/_/  /_/    /_/    /_/  \____/____/|__/  v1.10.9

Airflow 应该已经创建了一个 AIRFLOW_HOME 文件夹,并在其中创建了一个dags文件夹(如果没有,自己创建。)在主文件夹中,我们调用

$ airflow initdb

以便初始化与工作流相关的数据库。完成后,你会发现包含初始设置的airflow.db数据库文件和airflow.cfg文件。最后,我们呼吁

$ airflow webserver

启动气流图形用户界面。转到 https://localhost:8080 ,您应该会看到类似这样的内容:

你现在看到的是一组默认的气流例子(要隐藏它们,去airflow.cfg文件并设置load_examples=False)。)注意这些被称为 DAG s:

在 Airflow 中,一个DAG——或者一个有向无环图——是你想要运行的所有任务的集合,以一种反映它们的关系和依赖的方式组织。

DAG 是在 Python 脚本中定义的,它将 DAG 结构(任务及其依赖项)表示为代码。

也就是说,我们需要编写 Python 脚本,其中包含一系列按照指定顺序执行的任务。它们按照时间表运行,使用 Cron 的语法。

新冠肺炎的例子

回到我们的新冠肺炎追踪器。(这也提供了 DAG 的简单示例;对于更复杂的任务,请参考文档。)

我们需要创建一个 DAG,包含我们想要执行的任务,以保持我们的跟踪器更新:在一个 Python 文件dags/covid_dag.py中,我们导入基本模块并定义default_args,如下所示:

from airflow import DAG
from airflow.operators.bash_operator import BashOperator
from airflow.operators.python_operator import PythonOperator
import datetime as dtdefault_args = {
    'owner': 'airflow',
    'start_date': dt.datetime(2020, 4, 1, 1, 00, 00),
    'retries': 1
}

气流操作员允许执行特定类型的任务。例如,我们可以在 DAG 文件中复制/粘贴bokeh_plot函数,并让PythonOperator调用它。类似地,您可以在外部脚本中拥有该函数,导入它并用相同的操作符调用它。另一个选择是拥有一个包含所有函数的外部 python 脚本,并让一个BashOperator为您运行它。这就是我们将要做的。

start_date设置工作流程执行的时间。可以是过去的某个日期。retries参数告诉 DAG 应该运行多少次,以防执行不成功。

接下来,我们定义 DAG 参数:

dag = DAG('covid',
          default_args=default_args,
          schedule_interval='0 1 * * *',
          catchup=False
          )

第一个参数是 DAG 的名称。schedule_interval告知执行频率—对于我们的案例,每天在凌晨 1 点执行。为了避免常见的陷阱,需要注意以下几点:

  • 正如您在 GUI 的右上角看到的,Airflow 使用 UTC 时间。
  • 设置计划时,将开始日期与计划对齐。如果计划在世界协调时凌晨 2 点运行,开始日期也应该在世界协调时凌晨 2 点。

请花些时间阅读这些条目,为你未来的努力节省能量:

根据schedule_interval,从开始日期到当前日期,可能有多次执行。catchup告知当我们打开 DAG 时是否应该执行这些执行。

现在,我们将完整的 load-clean-bokehplot 代码打包到一个covid_func.py脚本中——当运行时,它应该在脚本所在的同一文件夹中输出散景图;但是,由于我们希望将它托管在您的 GitHub 网站中,您可以通过将输出目录设置为

save(p, ‘YourGithubPageDirectoryPath/index.html’.format(cat))

如上所述,我们只想运行脚本,所以我们可以调用BashOperator来执行任务。它应该是这样的:

# replace PathToYourFile for the directory pathcommand_t1 = 'python PathToYourFile/covid_func.py 't1 = BashOperator(
          task_id = 'covidPlots',
          bash_command = command_t1
          dag = dag
)

接下来,我们需要提交和推送文件。从终端提交和推送文件需要几个步骤,实际上,多亏了[GitPython](https://gitpython.readthedocs.io/en/stable/),它们也可以用 Python 来完成。因此,我决定写一个提交和推送的小脚本,然后用另一个BashOperator调用它:

from git import Repo
import os

os.chdir(YourGithubPageDirectoryPath)

PATH_OF_GIT_REPO = YourGithubPageDirectoryPath/.git'COMMIT_MESSAGE = 'Daily update'

def git_push():

    repo = Repo(PATH_OF_GIT_REPO)
    repo.git.add('--all')
    repo.index.commit(COMMIT_MESSAGE)
    origin = repo.remote(name='origin')
    origin.push()

git_push()

这要求git被正确配置,并且你被允许连接到 GitHub 而不需要在每次访问时提供你的用户名或密码。这是通过 SSH 完成的,详情请查看此链接

侧注:气流提供了一堆不同的 运算符 。其中之一就是 [*GitOperator*](https://airflow-plugins.readthedocs.io/en/latest/plugins/operators/git.html) 。如果你愿意,你可以自己尝试。

我们现在准备给你的covid_dag.py添加下一个任务:

command_t2 = 'python PathToYourFile/git_push.py 't2 = BashOperator(
                  task_id = 'gitPush',
                  bash_command = command_t2,
                  dag = dag
)

t3 = BashOperator(
                 task_id = 'gitPush_repit',
                 bash_command = command_t2,
                 dag = dag)

t1 >> t2 >> t3

正如你所看到的,我决定重复这个任务,只是为了确保推的发生——没有危险。

最后,我们用>>操作符指定任务的顺序。

你的狗现在准备好了!让我们再次调用$ airflow initdb来设置它并打开气流 GUI——您的新 covid DAG 应该在那里。如果您单击它并转到树形视图,您应该能够看到工作流程:

回到主页,打开它!

这个旅程的最后一步是返回命令行并调用

$ airflow scheduler

你的死刑应该在明天凌晨 1 点执行。

最后一点,您可以随时点击链接栏中的 Trigger Dag,手动执行它并检查它是否工作正常。如果出现任何问题,您应该能够在日志中跟踪错误。

摘要

在这篇文章中,我们采用了广泛使用的 used 新冠肺炎数据集,并为前 10 个国家(死亡人数较多的国家)的每日死亡人数创建了一个高度互动的散景图。然后我们将它提交到 GitHub 页面。

由于数据每天都在更新,所以绘图也应该如此。为此,我们设置了 Apache Airflow,创建了一个新的 DAG,其中包含每天更新数据所需的任务集,并启动了 Airflow 调度程序。

我又创建了几个图表,都放在我的 GitHub 网站上。你可以在这里查看:

欢迎在评论中留下任何想法或问题!

更新(2021): 网页不再维护。完整的代码可以在这个中找到。

参考

** [## 我喜欢用 Python 进行数据探索的 6 个理由

散景已经存在很多年了,但我只是最近才真正发现它,没多久它就成了我的最爱…

towardsdatascience.com](/6-reasons-i-love-bokeh-for-data-exploration-with-python-a778a2086a95) [## Apache Airflow 入门

在这篇文章中,我将讨论由 Airbnb 开发的工作流管理系统 Apache Airflow。

towardsdatascience.com](/getting-started-with-apache-airflow-df1aa77d7b1b) [## 气流初学者指南

Airflow 用于创建简单和复杂的代码管道,我们可以在其中调度和监控我们的工作流。一个…

medium.com](https://medium.com/zenofai/a-beginners-guide-to-airflow-3572ddd14731) [## 冠状病毒追踪:疫情传播的最新数据|免费阅读

冠状病毒爆发的人类成本持续上升,全球确诊病例超过 207 万例,而…

www.ft.com](https://www.ft.com/coronavirus-latest?fbclid=IwAR2Pi_sryd7x2ZvOt_y0J0_00N5mDQeYLvBc4DfMr6bpninqV75dcxRtEsA)**

你的机器学习工程师不需要博士或硕士学位

原文:https://towardsdatascience.com/your-machine-learning-engineers-dont-need-phds-or-masters-degrees-a06b17babc95?source=collection_archive---------39-----------------------

要求机器学习/人工智能雇员拥有花哨的学位已经过时了。原因如下。

你的机器学习雇员应该有博士学位吗?在 ML 工作需要博士学位吗?

我总是看到博士和硕士学位被列为 ML 职位描述的要求。我为“机器学习工程师”打开的第一个谷歌工作结果要求:

数据科学、机器学习、统计学、运筹学或相关领域的博士

相关领域理学硕士,拥有 5 年以上将数据科学技术应用于实际商业问题的经验。

对于软件工程师来说,拥有博士甚至硕士学位是一个不寻常的要求。我们不指望从事网络、安全、系统架构或应用开发的开发人员会这样。那么是什么让机器学习如此特别呢?

有些人可能会说 ML 非常复杂和数学化,是科学家的领域,而不是软件开发人员的领域(哎哟!).

我不相信。ML 可能很棘手,但密码学、分布式系统、图形学以及计算机科学中的许多其他主题也是如此。然而,我们并不要求开发人员拥有博士学位来从事这些工作。我认为是别的原因:

我们经常忘记机器学习对我们大多数技术人员来说是很新的东西。就在五年前,我的同事们还在谈论深度学习是一个可疑的赌注。工具很难使用。为 ML 设计的结实的硬件很难得到。模型质量与今天相差甚远。

结果我们大部分人在学校都没学过 ML。五年前,我的母校普林斯顿大学只提供大约 3 毫升/人工智能课程。机器学习绝对不是你典型的计算机科学课程的“标准”部分,你可能不用学习太多就能轻松毕业。网上资源匮乏。然后,当人工智能突然成为新的热点时,许多人冲回硕士课程,以填补他们教育中新的相关空白。

在 ML 人才短缺的情况下,难怪如果你想雇佣一个在这个领域有经验的人,这个人很可能是一个学者。

与此同时,工程师们开始在工作中学习 ML。即使在世界上最大的人工智能博士研究人员雇主之一的谷歌,大量从事人工智能产品的工程师也只有有限的技术经验。他们通过在线资源、内部课程(如谷歌的机器学习速成课程)或通过承担小块项目并边做边学来学习。

五年对于技术来说是漫长的一年,数据科学领域已经发生了变化。如今,在课堂之外学习机器学习比过去容易得多,我们的工具集也变得更加用户友好(参见 PyTorch、TensorFlow 2.0、Keras)。再加上庞大且不断增长的在线资源生态系统,这位有决心的开发人员无需花费一毛钱,就能给自己提供一个丰厚的 ML 教育。

合格的数据科学家/机器学习工程师招聘库也发生了变化。2019 年,数据科学竞赛网站 Kaggle 调查了~4000 名数据科学家。他们发现,虽然 52%的受访者拥有硕士学位,但只有 19%拥有博士学位。与此同时,大多数受访者只有 3-5 年的工作经验,而且年龄偏年轻(25-29 岁)。一大批雄心勃勃、自学成才的数据科学家刚刚进入就业市场。

我们理所当然地认为,自学成才的软件工程师可能非常有才华(谷歌的一名招聘人员最近告诉我,她采访了一名高中生)。科技招聘人员很久以前就知道,如果他们只雇佣麻省理工的毕业生,他们根本不会雇佣任何人。因此,现在我们需要在雇佣数据科学家的方式上进行类似的视角转变。

这也意味着我们需要开始像评估软件工程师一样评估 ML 工作申请人。我们需要花更多的时间来建立有效的面试,让候选人展示他们的技能,而不是专注于证书,无论他们是如何或在哪里学到的。建立雇佣 ML 工程师的新标准不是一件容易的事情,但是对于雇主来说,回报是值得的。

我们来连线一下 Twitter 或者insta gram*!*

原载于 2020 年 8 月 26 日 https://daleonai.comT21

如果你的 ML 算法表现不好

原文:https://towardsdatascience.com/your-ml-algorithm-is-not-performing-well-613dd2b07fc?source=collection_archive---------29-----------------------

罗布·施莱克希斯在 Unsplash 上拍摄的照片

如何发现问题

我们花了这么多时间开发机器学习算法。但是在部署之后,如果该算法表现不佳,就会变得令人沮丧。问题是,如果算法没有达到预期效果,下一步该怎么办。哪里出了问题?训练数据的数量足够吗?我们使用了正确的功能吗?我们应该继续收集更多的数据吗?我们可以,但是那非常耗时而且昂贵。我们应该增加更多的功能吗?那也会很贵。

往哪个方向走?

如果你的机器学习算法没有达到预期效果,下一步该怎么办?有几个选项:

  1. 获取更多的训练数据非常耗时。甚至可能需要几个月才能获得更多的研究数据。
  2. 获得更多培训功能。这也可能需要很多时间。但是,如果添加一些多项式功能的作品,这是很酷的。
  3. 选择一组较小的训练特征。
  4. 增加正则项
  5. 减少正则项。

那么,接下来你应该尝试哪一个呢?开始尝试任何事情都不是一个好主意。因为你可能会在一些没有帮助的事情上花费太多时间。你需要首先发现问题,然后采取相应的行动。学习曲线有助于轻松发现问题,从而节省大量时间。

学习曲线对于确定如何提高算法的性能非常有用。确定算法是否存在偏差或欠拟合、方差或过拟合,或者两者兼而有之是很有用的。

学习曲线如何工作

学习曲线是成本函数的曲线。同一图中训练数据的成本函数和交叉验证数据的成本函数给出了关于算法的重要见解。提醒一下,下面是成本函数的公式:

换句话说,它是预测输出的平方减去原始输出除以两倍的训练数据。为了制作学习曲线,我们需要将这些成本函数绘制成训练数据数量(m)的函数。我们将只使用训练数据的一个较小子集来训练数据,而不是使用所有的训练数据。

请看下图:

这里是概念

如果我们用太少的数据来训练数据,算法将完全适合训练数据,并且成本函数将返回 0。

上图清楚地显示,当我们只使用一个、两个或三个数据训练数据时,算法可以很好地学习这几个数据,训练成本为零或接近于零。但是这种类型的算法不能在其他数据上很好地执行。

当您尝试用此算法拟合交叉验证数据时,它很可能在交叉验证数据上表现不佳。因此,交叉验证数据的成本函数将返回一个非常高的值。

另一方面,当我们采用越来越多的数据来训练算法时,它将不再完全适合训练数据。所以,培训成本会变得更高。

同时,由于该算法是在大量数据上训练的,它将在交叉验证数据上执行得更好,并且交叉验证数据的成本函数将返回更低的值。以下是如何建立一条学习曲线。

开发一个学习算法

我将一步步演示如何绘制学习曲线。为了绘制学习曲线,我们首先需要一个机器学习算法。为了简单起见,我将使用线性回归算法。我们先开发一个线性回归算法。

首先,导入包和数据集。我在这里使用的数据集取自吴恩达在 Coursera 上的机器学习课程。在该数据集中,X 值和 y 值被组织在 Excel 文件中的不同工作表中。

提醒一下,X 是我们将用来开发和训练机器学习算法的功能。y 是我们需要预测的输出特征。

交叉验证数据的 x 和 y 值也组织在同一个 Excel 文件的另外两个工作表中。我在本文末尾提供了数据集的链接。请随意下载数据集并自己练习。

%matplotlib inline
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
file = pd.ExcelFile('dataset.xlsx')
df = pd.read_excel(file, 'Xval', header=None)
df.head()

同样,导入定型集的 y 值:

y = pd.read_excel(file, 'yval', header=None)
y.head()

让我们快速开发线性回归算法。

定义假设

线性回归使用非常基本的线性方程进行预测,我们在学校都学过。公式如下:

Y = C + BX

对于机器学习,我们使用不同的术语。

这里,“h”是假设或预测值,θ0 和θ1 是系数,X 是输入特征。

这里,我们已经有了 x。我们必须计算' h '并且它应该与 y 的值匹配。因为我们的目标是能够预测 y 的值。

θ0 和θ1 在开始时被随机初始化。我们将通过迭代不断改进θ0 和θ1 的值。

在每次迭代中,我们将使用成本函数和梯度公式来计算成本,以更新θ值

成本函数和梯度下降

成本函数为我们提供了关于预测值与原始输出要素的差异的想法。这里,我们的输出特征是 y,预测输出将是‘h’。因此,成本函数会告诉我们“h”偏离“y”多少。我们希望成本函数值尽可能低。

下面是成本函数的公式:

我们将继续运行算法,直到成本函数最小。在每次迭代中,我们使用梯度下降来更新θ值。

为了更新θ值,我们将从先前的θ值中减去梯度下降。当我们把它编码的时候,它会变得更加清晰。

这里,m 是训练数据的数量,α是学习率。

开发线性回归算法

使用上述公式开发假设和成本函数。

m = len(df)def hypothesis(theta, X):
    return theta[0] + theta[1]*Xdef cost_calc(theta, X, y):
    return (1/2*m) * np.sum((hypothesis(theta, X) - y)**2)

现在,我们将定义梯度下降来优化参数θ0 和θ1。在每次迭代中,我们将更新θ值,并跟踪成本函数和θ值。

最后,它将返回每次迭代中的成本列表 theta 值。代码很简单。请检查这里。

def gradient_descent(theta, X, y, epoch, alpha):
    cost = []
    theta_hist = []
    i = 0
    while i < epoch:
        hx = hypothesis(theta, X)
        theta[0] -= alpha*(sum(hx-y)/m)
        theta[1] -= (alpha * np.sum((hx - y) * X))/m
        cost.append(cost_calc(theta, X, y))
        i += 1
    return theta, cost

完成了线性回归算法。我们需要一种方法来预测产量。在预测方法中,我们将使用来自梯度下降函数和假设函数的最终θ来进行预测。

def predict(theta, X, y, epoch, alpha):
    theta, cost = gradient_descent(theta, X, y, epoch, alpha)
    return hypothesis(theta, X), cost, theta

现在,将参数初始化为零,并使用预测函数来预测输出变量。

theta = [0,0]
y_predict, cost, theta = predict(theta, df[0], y[0], 1400, 0.001)

更新后的θ值为:[10.724868115832654,0.3294833798797125]

现在,将预测输出(h)和原始输出(y)与 df 或 X 绘制在同一个图中。

plt.figure()
plt.scatter(df, y)
plt.scatter(df, y_predict)

看起来算法运行良好。预测的输出线从中间位置开始。

是时候开发学习曲线了!!!

画一条学习曲线

现在,我们可以画一条学习曲线。首先,让我们为交叉验证数据集导入 X 和 y 值。正如我前面提到的,我们将它们组织在单独的 Excel 表格中。

file = pd.ExcelFile('dataset.xlsx')
cross_val = pd.read_excel(file, 'X', header=None)
cross_val.head()

cross_y = pd.read_excel(file, 'y', header=None)
cross_y.head()

为此,我想稍微修改一下 gradient_descent 函数。

在之前的 gradient_descent 函数中,我们计算了每次迭代的成本。我这样做是因为在传统的机器学习算法开发中,这是一个很好的实践。

但是对于学习曲线,我们不需要每次迭代的成本。因此,为了节省运行时间,我将排除在每个时期计算成本函数。我们将只返回更新的参数。

def grad_descent(theta, X, y, epoch, alpha):
    i = 0
    while i < epoch:
        hx = hypothesis(theta, X)
        theta[0] -= alpha*(sum(hx-y)/m)
        theta[1] -= (alpha * np.sum((hx - y) * X))/m
        i += 1
    return theta

正如我前面所讨论的,为了开发学习曲线,我们需要用不同的训练数据子集来训练学习算法。

在我们的训练数据集中,我们有 21 个数据。我将只使用一个数据来训练算法,然后使用两个数据,然后使用三个数据,直到 21 个数据。

因此,我们将在训练数据的 21 个子集上训练算法 21 次。我们还将跟踪每个训练数据子集的成本函数。请仔细看看代码,会更清楚。

j_tr = []
theta_list = []
for i in range(0, len(df)):
    theta = [0,0]
    theta_list.append(grad_descent(theta, df[0][:i], y[0][:i], 1400, 0.001))
    j_tr.append(cost_calc(theta, df[0][:i], y[0][:i]))
theta_list

以下是每个训练数据子集的训练参数:

以下是每个培训子集的成本:

查看每个子集的成本。当训练数据只有 1 个或 2 个时,成本为零或几乎为零。随着我们不断增加训练数据,成本也在增加,这是意料之中的。

现在,对所有训练数据子集使用上述参数来计算交叉验证数据的成本:

j_val = []
for i in theta_list:  
    j_val.append(cost_calc(i, cross_val[0], cross_y[0]))
j_val

一开始,成本确实很高,因为训练参数来自太少的训练数据。但是随着更多训练数据参数的改善,交叉验证误差持续下降。

让我们在同一个图中绘制训练误差和交叉验证误差:

%matplotlib inline
import matplotlib.pyplot as plt
plt.figure()
plt.scatter(range(0, 21), j_tr)
plt.scatter(range(0, 21), j_val)

这是我们的学习曲线。

从学习曲线中得出决策

上面的学习曲线看起来不错。它正按照我们预期的方式流动。刚开始的时候,训练误差太小,验证误差太高。

慢慢地,他们彼此完全重叠。所以那是完美的!但在现实生活中,这种情况并不经常发生。

大多数机器学习算法第一次并不完美。几乎每时每刻都有一些我们需要解决的问题。在这里我将讨论一些问题。

我们可能会发现我们的学习曲线是这样的:

如果训练误差和验证误差之间存在显著的差距,则表明存在高方差问题。这也可以被称为过度拟合问题。

获取更多的训练数据或选择更小的特征集,或者两者兼有,可能会解决此问题。

如果一个学习曲线看起来像这样,这意味着在开始的训练误差太小,验证误差太高。慢慢地,训练误差变高,验证误差变低。但是在某一点上它们变得平行。从图中可以看到,在一个点之后,即使有更多的训练数据交叉验证误差也不会再下降了。

在这种情况下,获得更多的训练数据并不会改善机器学习算法。

这表明学习算法正遭受高偏差问题。在这种情况下,获得更多的培训功能可能会有所帮助。

修复学习算法

假设,我们正在实现线性回归。但是算法并没有像预期的那样工作。

做什么?

首先,像我在这里演示的那样画一条学习曲线。

  1. 如果您检测到一个高方差问题,根据特性的重要性选择一个较小的特性集。如果那有帮助,那将节省一些时间。如果没有,尝试获取更多的训练数据。
  2. 如果您从学习曲线中发现高偏差问题,您已经知道获得额外功能是一个可能的解决方案。您甚至可以尝试添加一些多项式特征。大量的时间有助于节省大量的时间。
  3. 如果你正在实现一个带有正则项λ的算法,如果该算法正遭受高偏差,尝试减少λ,如果该算法正遭受高方差问题,尝试增加λ。这里有一篇文章详细解释了正则项与偏差和方差的关系:

[## 如何改进机器学习算法:正则化

本文解释了机器学习算法性能差的原因以及如何改进它。

towardsdatascience.com](/how-to-improve-a-machine-learning-algorithm-regularization-144a6697c2be)

在神经网络的情况下,我们也可能会遇到这种偏差或方差问题。

对于高偏差或欠拟合问题,我们需要增加神经元的数量或隐藏层的数量。为了解决高方差或过拟合问题,我们应该减少神经元的数量或隐藏层的数量。我们甚至可以使用不同数量的神经元来绘制学习曲线。

非常感谢您阅读这篇文章。我希望这有所帮助。

更多阅读:

在这个页面中,你会找到几个非常流行的机器学习算法的教程链接:

[## Python 中从头开始的 k 均值聚类算法:分步指南

并学习使用它来降低图像的维数

towardsdatascience.com](/k-mean-clustering-algorithm-from-scratch-in-python-and-dimensional-reduction-step-by-step-guide-9ebabe5ca433) [## Python Matplotlib 的日常备忘单

完整的可视化课程

towardsdatascience.com](/your-everyday-cheatsheet-for-pythons-matplotlib-c03345ca390d) [## 使用 Python 从零开始的多类分类算法:分步指南

本文介绍两种方法:梯度下降法和优化函数法

towardsdatascience.com](/multiclass-classification-algorithm-from-scratch-with-a-project-in-python-step-by-step-guide-485a83c79992) [## 完全理解精确度、召回率和 F 分数的概念

机器学习中如何处理倾斜数据集

towardsdatascience.com](/a-complete-understanding-of-precision-recall-and-f-score-concepts-23dc44defef6) [## 数据科学家假设检验完全指南,Python 示例

用样本研究问题、解决步骤和完整代码清楚地解释

towardsdatascience.com](/a-complete-guide-to-hypothesis-testing-in-python-6c34c855af5c) [## 用几行代码在 Python 中搜索相似的文本:一个 NLP 项目

使用 Python 中的计数矢量器和最近邻法查找类似的维基百科简介,这是一个简单而有用的…

medium.com](https://medium.com/towards-artificial-intelligence/similar-texts-search-in-python-with-a-few-lines-of-code-an-nlp-project-9ace2861d261)

你的 ML 代码结构良好…或者是吗?

原文:https://towardsdatascience.com/your-ml-code-is-well-structured-or-is-it-c1ef49aa5ba1?source=collection_archive---------36-----------------------

如何为你的机器学习项目构建代码

Unsplash 上由 Seika I 拍摄的照片

我是从 Web 开发来到机器学习领域的。当我意识到没有任何明确定义的项目结构原则时,我真的很沮丧。也许更好的说法是几乎 不可能为这个特定领域(机器学习/数据科学)找到项目结构和整个应用模块询问的最佳实践。关于 MVC 的信息更容易找到。现在我已经从事 ML 项目有一段时间了,在这篇文章中,我将尝试总结我在这个主题上的经验和知识。

让我们从基础开始。在大多数情况下,ML 项目由核心模型和一些包装器(GUI、HTTP API、CLI 接口)组成,最终用户将通过它们来使用它。让我们专注于核心的模型部分,把包装留给已经知道该做什么的人: )我们都知道,在大多数情况下,ML 世界中的软件开发过程是由 CRISP-DM (数据挖掘的跨行业标准过程)或其来自 IBM ASUM 的兄弟(数据挖掘/预测分析的分析解决方案统一方法)决定的。****

CRISP-DM ( 来源)

从这两种方法中,我们可以突出 3 个主要的软件开发阶段:数据准备、建模和评估,它们在整个应用程序存在期间循环。不管你是刚开始项目还是添加新功能,你都必须通过这三个阶段。好,现在让我们定义一下什么是核心模型,或者我说的核心模型是什么意思?

****核心模型是一种算法,它以明确定义的数据结构对输入执行有限且明确定义的后续数据转换,并作为结果返回具有明确定义的数据结构的输出。我认为这个定义实际上适合所有的 ML 项目。现在让我们来定义这个算法在所有 3 个阶段是如何受到影响的。

****数据准备:这里我们必须验证和清理从客户(或其他地方)获得的数据。实际上,我们正在做的是决定算法的输入应该是什么样子。

****建模:这里我们必须定义数据转换步骤,这些步骤将在输入数据上执行,在输出上将返回所需结构的数据。重要提示:这里我们不仅创建了我们习惯称之为 ML 的模型(kNN,逻辑回归等。),还包括数据预处理、特征工程和其他可能的数据转换步骤。事实上,我们习惯称之为“ML 模型”的任何东西都只不过是数据转换器。

****评估:这里我们必须使用一些度量来评估算法输出的相关性。

Uff,现在我们已经定义好了。那么代码呢?这三个阶段如何影响代码库?

当你在做数据准备的时候,你应该总是期望数据会及时变化,你当前正在解决的问题可能会被延长。例子:你要写一个模型,在显微镜图像上检测两种类型的粒子。您已经准备好了数据,并告诉客户以某种格式将输入发送给模型。在做出最终决定之前,您必须考虑的事情是:如果客户想要添加一种新型颗粒进行检测,这是否可行?

当你在做建模的时候,你应该总是期望评估的结果或者生产中的结果可能是不好的,你必须在模型中做出剧烈的改变,而且你必须尽可能快地去做。改变模型结构需要多长时间?

当您创建评估代码时,您应该始终预期评估指标、执行评估的数据甚至模型结构可能会改变。更改这些内容并再次运行评估需要多长时间?

所以现在我们看到在开发过程中可能会发生很多问题,我们的主要目标是尽可能快地解决它。那么,我们应该如何编写代码才能轻松做到这一点呢?我们都知道软件开发中主要的代码质量度量是可靠性可维护性可测试性可移植性可重用性。但是这些时髦的词语可能意味着任何事情,而不一定是特定领域的。

我们已经定义了核心模型,我认为这种模型的最佳技术实现是管道流水线是一组串联的数据处理步骤,其中一个步骤的输出是下一个步骤的输入。管道可以由几个管道构成。

文本预处理管道示例

现在,我想说出并描述我为自己定义的主要原则,我认为每个机器学习/数据科学项目都必须遵循这些原则:

  1. 管道由明确定义和有序的数据处理步骤组成。**数据有清晰的处理路径,有严格定义的顺序。这部分保证了应用输出的稳定性(可靠性)
  2. 高层管道结构透明**。任何不熟悉该项目的开发人员都必须能够理解(或者更好地写下一个有序列表)在应用程序管道中执行的所有步骤。这增加了整个应用程序的可维护性,并极大地简化了项目新人的加入。(可维护性
  3. 数据处理步骤原子性**。每一步都有一个明确定义的输入和输出数据结构,其内部状态与其他步骤相隔离。这简化了流水线步骤单元测试。此外,它保证了管道步骤在管道的不同位置或在另一个管道中可重用的可能性。(可维护性、可测试性、可重用性)
  4. 流水线步骤参数的可访问性**。每个数据处理步骤的任何参数都必须易于访问并可以修改。这对于手动和自动模型参数调整和评估都非常重要。它简化了单元测试的数据处理步骤。并且还提供了其他设置的可重用性,在这些设置中它可能是有用的。(可维护性
  5. 增加和删除流水线步骤的可能性**。如果前一步的输出和下一步的输入具有相同的结构,则可以删除管道的每一步。如果新步骤的输入和输出与它们的输入和输出兼容,则可以在两个步骤之间添加新的数据处理步骤。这加速了对整个数据处理流程建模的过程,并且在将来加速了根据反馈对现有模型的修正。(维修性)

我认为遵循这 5 条规则将有助于你为你的 ML 项目写出干净、可测试和可维护的代码

万一是sklearn,可以用它的Pipeline实现,真的很牛逼。如果你想有一些变压器,这是不在sklearn,只是谷歌如何编写自定义变压器,并将其集成到您的管道,这真的很容易。

如果你使用除了sklearn之外的东西,你有两个选择:把你的解决方案转换成sklearn或者写你自己的管道接口,所有它必须满足的规则都摆在桌面上。不管你是和textualnumericimage还是mixed data一起工作,这些规则都是通用的。

为了让语言与行动相匹配,我将展示这些原则是如何在实践中发挥作用的。假设我们有一个帖子数据集。每个岗位都有一个imagetextcategorytagsrating from criticsauthors ratingprice。让我们想象一下imagetext字段包含我们必须从中检索数据的文件名。我们的目标是估计帖子的数量。我想让你明白这个例子和现实没有任何联系。我用这个例子向您展示,您可以组合任意数量的具有不同接口和用途的工具,并将它们连接到管道中,这满足了上述所有规则。让我们假设,为了简单起见,我们选择了 stack: pandassklearnspacy 用于文本属性的 NLP, OpenCV 用于图像处理, YOLO 用于图像上的对象检测。

现在我将向你展示核心模型的一段代码,如果你不理解它的高层结构,那么我之前写的所有东西都不起作用,你可以立即离开这一页;)

模型核心代码

所以,如果你还在读这篇文章,我想你已经理解了代码。是不是看起来很棒,真的很好维护?首先我要强调的是,当然并不是所有的变形金刚都存在于 sklearn。但是就像我之前说的,你可以自己做一个。你可以看看我以前的帖子,最后你会发现使用 spacy API 的自定义 sklearn 转换器:****

** [## 文本预处理步骤和通用流水线

所有文本预处理步骤的描述和可重用文本预处理管道的创建

towardsdatascience.com](/text-preprocessing-steps-and-universal-pipeline-94233cb6725a)

管道方案

现在让我们命名所有的步骤。高级别代表:

  1. 预处理
  2. 特征选择
  3. 回归模型

预处理:根据数据表示类型对不同组的列独立应用不同的预处理步骤,然后将所有转换后的特征合并到一个数据帧中。

图像数据:

  1. 使用 OpenCV 从文件中读取图像
  2. 将色彩图从OpenCVBGR 转换为 RGB
  3. 使用 YOLO 检测猫、狗和人,并为每张图像返回检测到的对象数组
  4. 将输出数组转换为指示器矩阵,其中 1 表示对象在图像上,0 表示对象不在图像上

文本数据:

  1. 从文件中读取文本
  2. 对所有单词进行词汇化
  3. 使用 TF-IDF 算法进行矢量化,按单词进行标记化,并使用最大大小为 10000 的单词包

数字数据:

  1. 使用中位数策略估算缺失值
  2. 执行标准化

分类数据:

  1. 用单词“missing”估算缺失值
  2. 执行一键编码

分类多标签数据:将数组转换为指示矩阵,其中 1 表示对象在列表中,0 表示对象不在列表中。

现在你可以看到你的模型看起来有多棒了。这段代码满足了上述所有规则。

我希望你喜欢这篇文章,我期待你的反馈!我真的很想开始讨论这个话题,所以不要犹豫写评论或直接给我发电子邮件。

如果您在将您的模型转换为 pipeline 时遇到问题,请写评论或直接给我发电子邮件,我会尽力帮助您。

我的邮箱:maksym.balatsko@blindspot.ai**

你的下一个雇员应该是应用数据科学家

原文:https://towardsdatascience.com/your-next-hire-should-be-an-applied-data-scientist-977bd5835913?source=collection_archive---------42-----------------------

这种时候,更明显的是,你的下一个雇员应该是一个全面的超级明星。

拥有单一技能的数据科学家很容易找到,但找到一个全面的数据科学家却很难。但是这 10 倍的资源将决定项目的成败。

NeONBRANDUnsplash 上拍摄

一个企业超级明星,这就是他们…

企业环境中的数据科学家除了标准的技术要求之外,还需要具备很多技能。任何数据科学职位最难的部分是沟通,在一般人群中,良好的统计技能不一定与社交能力并存。

数据科学最难的部分是沟通。

当雇佣一名新的数据科学家时,问自己你在寻找什么是很重要的?你想象这个人如何经营你的企业?你想找一个有纯数学和统计技能的人吗?还是对底层编码有亲和力的人?或者,更有可能的是,某个可以成为桥梁建设者的人。能够向企业销售解决方案并获得项目(和未来费用)支持的人。

大多数公司都需要应用数据科学。数据科学专门应用于解决业务挑战。不是为了数据科学本身,而是为了一个目标。为了更好地理解应用数据科学能为你的公司做什么,我们必须理解“应用”部分实际需要什么,而不是所有的嗡嗡声。这也将帮助你确定你的公司真正需要的是什么,也许根本不是数据科学。

团 Nguyễn 明Unsplash 上拍摄的照片

应用科学家

应用数据科学家是一个有趣的角色。应用型的 T21 应该和研究型的数据科学家相提并论。研究数据科学家整天都在改进项目;摆弄最细微的细节。研究新的模型并寻找应用它们的领域。

应用数据科学家是值得信赖的业务顾问。他们与企业沟通,挖掘他们的需求,并利用适用于该工作的工具来满足这些需求。简单的数据分析,数据提取,或者,当工作需要时,更高级的建模。

不要误解我的意思:这些研究数据科学家有一席之地,但这可能需要他们周围有一个强大的支持团队,以便填补他们不愿意或无法填补的空白。这些人无法在复杂的商业环境中独自经营。

应用数据科学家将多种技能和工具结合起来,以便在商业环境中保持高效。

那么,你应该从候选人身上寻找什么呢?

应用数据科学家清单

  • 科学家。数据科学家需要对数学、统计学和科学探究方法有扎实的理解。他们需要能够用各种语言编写程序,以便提取、转换和操作数据。这也包括分析复杂问题并将它们分解成更小的、可解决的部分的能力。这是他们的分析思维。
  • 领域专家。科学家对深度垂直或领域知识的需求经常被忽视。领域专业知识对于正确构建手边的信息和创建对所述数据的缺点的认识是重要的。它还帮助数据科学家创造对业务直接有用的产品。真正的应用数据科学家利用他们的业务联系来获取每个项目的有用信息。
  • 译者。他们作为翻译的角色不被重视,但却非常重要。业务环境中的数据科学通常受到业务经理想象力的限制,他们的问题应该通过分析来解决。然而,由于他们从自己的角度看待问题,他们将不可避免地只能用这种世界观来看待问题。数据科学家从技术角度处理这个问题,可以提出大量不同的(有时是独特的)新方法。由于通常是业务买单,因此数据科学家可以充当技术方面和业务元素之间的翻译非常重要。可以说是在出售未来。

在某种程度上,这些角色可以分开,但是,每个应用数据科学家都需要具备这些关键技能。这些人将极大地提高数据科学团队的整体交付能力,他们可以提升整个团队。

所以,下次你雇佣数据科学家时,不要只评估他们的技术能力,还要寻找其他特质,比如领域知识和沟通技能。祝你好运!

你的电话号码让世界知道你是谁:开源情报收集快速指南

原文:https://towardsdatascience.com/your-phone-number-lets-the-world-know-who-you-are-a-quick-guide-on-open-source-intelligence-3009510ee3b4?source=collection_archive---------21-----------------------

你的手机泄露了你的什么信息——照片由 Unsplash 上的艾里克·索尔海姆拍摄

O 你的数据很重要!这是我们的隐私,公司不应该滥用它。不幸的是,这已经不是我们生活的世界了。这篇文章不会是危言耸听“让我们回到我们的诺基亚 5110”并关闭我们的账户,但它将是对我们数据的一种洞察,以及像电话号码这样平凡的事情如何能揭示这么多。在网络安全和数据科学中,有一个术语叫做开源情报收集(OSINT),它被描述为,

从公开来源收集的数据,用于情报环境。

在我们所处的疫情,我们的数据再次受到威胁,因为公司试图适应新的工作模式、新的连续性计划以及新的工具,因为他们希望完全采用远程观点。最近,越来越多的销售主管打电话来询问我是否对远程解决方案感兴趣。由于封锁,大多数人都不在办公室,少数人一直在使用手机号码,他们经常这样做是为了避免谷歌人工智能实际上可以根据谷歌搜索结果告诉你哪个公司在打电话(如果你有安卓系统,苹果的 IOS 也使用类似的功能)。使用手机号码至少可以让他们回避这个问题,和你搭讪。然而,一个日益增长的趋势是,由于持续的需求和供应链的中断,一些公司措手不及,现在要求员工使用个人手机并报销费用。对于销售主管来说,这实际上存在安全风险。你的手机号码可以透露很多关于你的信息,恶意攻击者可以利用它来获取更多关于你的信息,进行网络钓鱼攻击()我写了一个关于如何设置网络钓鱼服务器的指南)

那么这在现实生活中是什么样子的呢?

在过去的几年里,我们都会收到一封电子邮件,告诉我们由于不安全的数据库等原因,我们的数据被泄露了,公司很抱歉,他们非常关心我们的数据。通常,这些电子邮件遵循相同的主题,即你的信用卡信息是安全的,但他们可能已经得到了你的电子邮件和电话号码。公司经常淡化这一重要部分,因为你的信用卡信息被认为比电子邮件或电话号码更有价值,对吗?

那么我泄露的信息会怎么样呢?📧📱

你可能经常会看到垃圾邮件的增加,但如果你使用 Gmail 或 Hotmail,你实际上永远不会看到这一点,因为他们的垃圾邮件过滤器会发现它。有了你的电话号码,它可能会被卖掉,你会通过短信或电话收到奇怪的网络钓鱼企图,内容是有一次你撞坏了一辆你从未拥有过的汽车。姓名和个人标识符通常不与这些数据保存在一起,或者受到保护(哈希)。然而,它们中的大部分最终会出现在粘贴箱中,这些是来自互联网漏洞的大量“复制和粘贴”数据。像这样的服务已经通过这些数据让你知道你的电子邮件是否出现在这些数据泄露中。

我的信息被泄露过吗?😱

无时无刻😡!令人沮丧的是,这不是我的错。因此,我查看了一封我用来注册时事通讯的旧电子邮件,随着时间的推移,它已经被泄露了 6 次,从 2012 年开始,直到最近的 2019 年 2 月。

影响我的一个电子邮件地址的漏洞截图。资料来源:HaveIbeenPwned

并非所有违规行为都被披露或易于跟踪

这就是粘贴箱的用武之地,有时黑客不会透露信息的来源,或者这可能是一个大的操作,有人已经把泄露的信息放在一起,然后决定分享它。他们会将信息上传到 Pastebin,通常没有任何指示,其他用户会下载并使用这些信息进行钓鱼攻击、暴力攻击,甚至训练机器学习模型。

值得庆幸的是,你可以在火狐或谷歌上设置提醒,当你的电子邮件被泄露时提醒你

从一个电话号码,别人怎么找到你的名字?

正如我们在上面看到的,在 CafePress 数据泄露事件中,除了电子邮件地址,密码,用户名和电话号码也被泄露。你能用电话号码做什么?

首先,我们无法像控制电子邮件或其他信息一样控制它。如果有人加了我的电话号码,我永远也不会知道,如果我的电话号码被泄露,O2,Virgin 或 EE 从来没有联系过我说,“嘿,你的号码被攻破了,注意安全。”

因此,如果恶意方找到我的号码并将其添加为联系人,我的号码会告诉他们什么?首先,这足以暴露我所有的社交媒体账户。Instagram 会显示你的哪些联系人在平台上,现在大多数社交平台也是如此。同意手机号码是一个单向系统,现在大多数应用程序都要求导入你的联系人列表,因此从这里开始,用户可以添加一个号码,并查看一些热门应用程序,看看该号码是否与某人对应。如果你使用像 WhatsApp 这样的流行信息平台呢?总是检查只有你的联系人可以看到你的个人资料照片,将设置为每个人意味着即使是偶然发现你号码的陌生人现在也可以看到你的个人资料照片。通常,如果我接到一个未知号码的未接来电,我首先会保存它,然后在 WhatsApp 上查看,以了解是谁打来的。对于目前在疫情期间使用私人电话的销售人员来说,这将很难控制,而且这是对你隐私的不必要的侵犯。

但是如果是你的银行告诉别人你的情况呢?🏦

在疫情期间,当企业努力应对远程支持的新需求时,一些企业已经走在了前面。让我们看看 Monzo ,一家只支持移动设备的银行,它已经有了支持和远程扩展的基础设施。作为 Monzo 的客户,我喜欢这家银行。但是我有一个问题。

为了让朋友更容易支付和即时支付,Monzo 有一个功能,它列出了所有与 Monzo 联系的人。从那里你可以选择一个联系人并给他们汇款。从 UX 的角度来看,它使生活变得容易,在这个时代,谁有时间写下分类代码和帐号,事实上,这似乎是万无一失的,因为你输入错误信息的可能性很小。但通常,像这样的功能虽然有用,但也可能对恶意攻击者有用。作为一名恶意攻击者,我可以从粘贴箱中找到一个电话号码,将其添加为联系人,检查他们是否有社交媒体,然后打开 Monzo,找出他们的完整政府名称。Monzo 应用程序将用户注册并通过政府 ID 确认的姓名显示给任何拥有该人手机号码的人。此功能可以关闭,但关闭后,您将无法在没有账号和分类代码的情况下汇款。很遗憾,用户经常面临一个决定,是安全还是 UX 便利?

好吧,你知道我的名字和号码,你能做什么?

这就是 OSINT 真正发挥作用的地方,一个伟大的查找信息的开源平台是 Google(或任何搜索引擎),如果攻击者知道你的全名,就不难进行显式搜索来查找关于你的更多信息。作为一个现代互联网用户,你应该知道谷歌上出现了哪些关于你的信息。

一个朋友最近让我自己谷歌一下,看看是否会弹出某个结果。令我惊讶的是,在第二页,它就在那里。正如她所描述的那样,这是一个已经废弃了我所有 LinkedIn 内容和信息的页面,现在正出售给声称拥有我的电话号码和电子邮件信息的公司。为了删除我的信息,我需要通过给他们更多的信息来证明我就是我所说的那个人。

我没有允许他们拥有我的数据,但我们在这里!—阿波罗 AIs 网站截图。

不幸的是,这不是唯一一个提供这类信息的网站。从快速的谷歌搜索中,你可以找到不同的网站提供你的数据,要么是从社交媒体平台购买的,要么是从数据库泄露的,要么是我们从未读过的一些条款和条件。LinkedIn 等公司需要采取更多措施来防范网络垃圾邮件。网络抓取是使用机器人从网站中提取内容和数据的过程。与只复制屏幕上显示的像素的屏幕抓取不同,网络抓取提取潜在的 HTML 代码,以及存储在数据库中的数据。然后,抓取工具可以将整个网站内容复制到其他地方,或者打包出售给寻找线索和数据的公司。

网页抓取的工作原理—来源— Imperva

更糟糕的是,在 2018 年,尽管我从未和他们有过账户,也不知道他们是谁。阿波罗人工智能不知何故丢失了一个我不用的电子邮件地址。这只是我用于测试系统的一个虚拟收件箱。

阿波罗——如果你正在读这篇文章,请删除我。—来源已更新

我的地址呢?

从你的政府名称来看,如果你在公布的选民名单上,你的名字和地址很容易被找到。由于在英国的信用评分过程,它经常被用来作为一个很好的指标对你的信用评分有你的名字在这个选民名册上。然而,获得这些数据的公司通常会出售这些信息。因此,通过谷歌搜索,人们实际上能够找到你是谁,谁住在你的房子里的信息(是的,有一个网站列出了居住在某个地址的有资格投票的每个人,以及与该房产相关的以前的名字)。如果你是一家公司的董事,那么,公司之家允许某人搜索你的名字,并获得关于你的更多信息。但是攻击者要寻找的关键信息是你的出生日期。虽然它没有列出具体的日期,但对于攻击者来说,它缩小了你出生的月份和年份。使用任何公共社交媒体资料,如果你曾经发布过“这是我的生日”帖子,他们所要做的就是查看你在那个月的帖子。

那么是回 Nokias 吗?

是的,我们可以,但我们也可以在保护数据时采取主动。虽然我们无法控制谁在篡改我们的数据,但我们可以做些事情来保护自己。这可以通过使用安全方法来实现,例如不包含容易获取的信息的强密码。如果你的出生年份可以在公司主页上找到,为什么会出现在你的密码里?如果谷歌搜索可以显示你 5 年前住的地址,为什么你的秘密问题是关于你找到工作后住的第一条路?一个人的垃圾是另一个人的黄金。数据也是如此,对您来说可能不那么重要的东西可能是网络钓鱼企图中缺失的部分。对于公司来说,他们还应该注意,通常在鱼叉式网络钓鱼攻击中,攻击者正在寻找一种方法,而任何系统最脆弱的部分就是使用它的人。

如果你从这篇文章中有所收获,请在网上搜索自己,看看会有什么收获。了解你的数据,给公司发邮件要求他们把它拿下来,在这段无聊的时间里,检查你下载的应用程序的权限。一个数字能说这么多,我们一定要保护他们。

作者斯蒂芬·查彭达玛

你的处理器在你开始使用人工智能之前很久就试图预测未来

原文:https://towardsdatascience.com/your-processor-is-trying-to-predict-the-future-long-before-you-start-with-ai-892beeaf6a48?source=collection_archive---------51-----------------------

以一种更原始但没有太大不同的方式

Unsplash 上由 Vladimir Malyutin 拍照

如果你学过计算机体系结构,你可能知道硬件执行某个程序的基本步骤。如果没有,下面简单解释一下这个过程【1】:

第一步是将高级代码翻译成汇编语言。编译器负责做到这一点。之后,汇编程序将把汇编语言翻译成二进制指令。因此,如果您的代码在某个高级语言中包含以下语句:

A + B

编译器将变成:

add A,B

汇编程序会翻译成这样:

000001010011

从这一点开始,处理器执行以下步骤:

  • 获取:从 RAM 中读取指令。
  • 解码:理解指令的目的(例如 add)并设置允许执行指令的所有标志和寄存器。
  • 执行:处理指令。指令可以使用也可以不使用算术逻辑单元(ALU)。算术逻辑指令使用 ALU,
    内存指令也可以使用它进行地址计算。
  • 回写:将获得的结果写入寄存器组。

当处理器运行时,该序列一直重复,并且每个步骤花费一个时钟周期。执行依赖于解码,解码依赖于获取。然而,获取不依赖于解码,解码不依赖于执行,所以一旦某条指令的获取完成,下一条指令就已经可以被获取了。其他的也一样,那是处理器流水线(如下图所示)。

科林 M.L 伯内特在维基共享资源上的图片

预测从何而来?

要说预测,首先要说条件跳转(或者说条件分支)。条件分支指令是跳转到一个新地址,根据特定条件【2】可能发生也可能不发生。翻译成高级语言,它基本上是一个 if-then-else 子句:

if **some condition:**
   do this;
else:
   do this instead;

如果满足条件,代码将继续正常执行。如果不满足条件,代码将跳转到 If 块中的所有行,执行 else 块中的所有行。这是条件分支的一个例子。 For 的while 的也是条件分支,因为条件定义了代码是重复还是直接。关于条件分支的要点是:执行时需要计算条件结果

这意味着当条件分支指令在流水线中出现时,处理器将只知道在计算条件结果之后,即在执行阶段之后,是否需要采取分支。因此,处理器不知道下一条指令是否会被执行,或者是否会跳转到另一条指令。这种依赖隐含着一个管道气泡

图由二胡郝ResearchGate

一个流水线气泡,如上图所示,是处理器流水线上的一种延迟,目的是为了解决某种依赖(或者危害,在计算机架构语言中)【1】灰色块代表空闲时间。考虑到上图中的第一条指令是条件分支,下一条指令只有在条件分支指令完成其执行步骤后才会被提取,以确保下一条要执行的指令是正确的。所以如果你仔细想想,这在性能上是不可持续的。这就是预测出现的地方。

分支预测

如果处理器没有等到条件分支的计算,它有什么选择?嗯,猜测或预测条件结果可能是一个不错的选择…事实也的确如此。预测条件结果而不是阻塞处理器的过程已经使用了几十年,它被称为“分支预测”。

它们已经使用了很长时间的事实并不意味着它们是完美的,总是有改进的空间。使用真实处理器的实验表明,减少 50%的预测失误会使处理器的性能提高 13%【4】。然而,设计分支预测器(BP)不仅要考虑精度,还要考虑许多其他因素,例如处理器芯片的面积、能耗等。

分支预测是如何工作的?

Harshal Parekh 写了一个很好的故事,不仅解释了它是如何工作的,还展示了它在真实情况下的影响。我非常推荐阅读:

** [## 分支预测—您需要知道的一切。

在计算机科学中,谓词是一种体系结构特征,它为条件转移提供了另一种选择

medium.com](https://medium.com/swlh/branch-prediction-everything-you-need-to-know-da13ce05787e)

像大多数预测模型一样,分支预测通常基于条件分支的过去行为。最简单的分支预测算法可以使用一个标志来定义,该标志指示最后一个分支是否被采用,并且该算法将总是猜测上一次发生的事情也将在下一次发生。因此,标志需要采用初始值( 1 表示是, 0 表示否)。如果猜测正确,标志将保持其值。如果没有,标志会改变它的值。下面的情况可以举个例子。

运行某个例程后,给定分支 b 得到以下行为:

0 0 0 1 1 0 0 0 0 1

在前三次迭代中,没有执行分支,在接下来的两次迭代中,执行了分支。接下来的四个也没拍,最后一个拍了。考虑到我们的分支预测器以标记为 0、开始,准确度将为 70%。下图用一个红色箭头表示每次迭代,后面是当前标志值和一个表示分支行为预测是否正确的符号。

作者图片

第一次预测失误将发生在第四次迭代时,因为最后一次是 0 (第四次是 1) 。这样,标志现在将其值更改为 1 。由于将在下一次迭代中进行分支,所以预测将是正确的,然而,在第六次迭代中,分支不再进行,因此发生另一次未命中预测。现在,标志再次变为 0 ,并正确预测接下来的三次迭代,然后错过最后一次迭代。最终,我们得到了 7 个正确的预测和 3 个错误的预测。

显然,这不是现在处理器进行分支预测的方式。有一堆其他的技术可以给出更好的结果。你可以在 Sparsh Mittal 写的这篇文章中找到一些答案。

AI 可以用于分支预测吗?

很容易想知道这种问题是否可以由人工智能算法来解决,答案是是的,它们可以。事实上,从很久以前开始。使用这种方法的分支预测器的一个例子是感知器预测器,在 Sparsh Mittal 调查中也有涉及。由于人工智能领域的最新进展,这两个领域的结合可能是英特尔和 AMD 等主要科技公司建筑内的一个热门趋势,我们可以期待更多的到来。

因此,如果你喜欢计算机架构和人工智能,这是你可以利用你所有的知识来改进我们今天拥有的处理器的研究领域。

参考

[1]帕特森,大卫 a .,和约翰 l .轩尼诗。计算机组织与设计:硬件/软件接口 (2013)。平装本,摩根·考夫曼出版社。

[2]亨利、格伦和泰瑞·帕克斯。条件分支指令的静态分支预测机制 (2003)。美国专利 6571331 号。

[3]张宝勇。分类导向的分支预测器设计 (1997)。密歇根大学博士论文。

[4]米塔尔,斯巴什。动态分支预测技术综述 (2019)。并行性和计算:实践和经验。**

您的简化数据科学工作流已经到来!

原文:https://towardsdatascience.com/your-simplified-data-science-workflows-have-arrived-208ce20bad88?source=collection_archive---------15-----------------------

数据科学家及其团队领导会喜欢的 Google Cloud 新功能

图片:来源

嘿, 数据科学家 使用 谷歌云 :你怎么还没使用 机器图片 ?因为他们才出生两周,这就是为什么…

摘要

技术的

Google Cloud 上的机器映像 让您轻松创建、备份、恢复和共享您定制的虚拟机。如果将磁盘映像、快照和实例模板结合起来,就可以得到它们。(呃,好吧,生孩子不是这样的。)

虚拟机镜像 轻松创建、备份、恢复和共享虚拟机。

哦,如果你预算紧张,你会以一种你永远不会喜欢虚拟机副本的方式喜欢它们。

非技术性的

您是否曾经丢失过智能手机,然后使用一键解决方案来恢复您最喜爱的应用程序、联系人等。换一部手机吗?机器镜像就是那样,不过是针对 Google Cloud 上的虚拟机。

痛苦的非技术性

想象一下,你从谷歌云租用的虚拟电脑是一个视频游戏中的角色。在机器映像出现之前,这款视频游戏没有保存选项——每次你做了让你后悔的事情,你都必须从头开始玩游戏。现在,保存和加载你辛辛苦苦获得的所有物品和经验值变得超级容易。

咔嚓,咔嚓,搞定!

演示 GIF

要使用机器映像创建虚拟机:单击机器映像旁边的选项,单击 Create VM(命名您的小 best 是可选的),然后创建!哒哒,你漂亮的虚拟机的一个简单副本。(右下角是一个方便眼睛的放大图。)

为什么你应该关心你是不是一个…

数据科学家/研究员

如果你像大多数数据科学家一样,你无法在内心深处热爱虚拟机(VM)设置和其他计算琐事。这些事情会占用你处理数据的时间,而这正是你真正感兴趣的部分。当然,你有足够的洞察力想要你自己的特别定制设置——就像你喜欢的那样——所以你能够抑制你第一次抱怨。

几周过去了。你偶尔会安装闪亮的新包,调整设置,运行脚本,然后有一天…嘣!你打破了它。

理想情况下,你应该把时钟倒回到你完美的机器上,就像上周一样,但是…你不记得你点击了什么到达那里。即使你做了,从头开始也要花几个小时(如果你幸运的话)。

悲伤。

之前:恢复上周的设置意味着从头开始。

之后:咔嚓,咔嚓,搞定。更少的家务时间,更多的数据时间。

机器图像来拯救!机器映像是包含所有信息(机器类型、网络标记、标签等)的单一资源。—需要备份、拷贝、恢复和共享一个实例(虚拟机)。

这意味着您可以保存您喜欢的配置的副本,以便您可以轻松恢复实例的旧版本。听起来很简单。咔嚓,咔嚓,搞定。

等等,为什么不直接保存虚拟机本身的副本呢?因为您可能想在保存备份的同时省钱。

使用机器映像的成本远低于保存虚拟机的多个副本。

如果您制作了虚拟机的副本,您将获得双倍的计费磁盘空间。如果你创建一个机器映像,你只需要为磁盘内容的差异付费,所以即使你选择了一个华丽的虚拟机,每一个额外的机器映像也只需要你几分钱。

团队领导/经理

想象你是一名领导,有新的团队成员要加入。

您已经有了满足团队需求的完美设置,但是它存在于一个讨厌的文档中,该文档详细说明了每个新员工必须运行哪些脚本以及他们需要单击哪些按钮。

让新队友站起来并投入运行需要很长时间。

以前:让新队友起床跑步需要很长时间。

之后:更快的入职和一支能够跟上前沿的团队。

重复工作对你的业务没有好处,但幸运的是机器映像让我们跳过它。他们允许您定制一次,为您的团队创建一个黄金映像,并与整个团队共享。这让每个人的起跑线都向前移动,加快了你的入职速度。

“机器映像不仅仅是保存备份。这是加速你整个团队的一种方式。” —阿里·利伯曼,谷歌计算引擎产品经理

作为奖励,你会想不断更新黄金图像,以保持每个人的配置在最前沿。不用再跟踪你的小组的掉队者忘记做哪些更新了。

讲师/助教

给你给学生的编码作业打分——也许是在 TensorFlow 中的图像识别?—如果您不得不处理学生可能搞乱机器设置的所有不同方式的调试,这很快就会变成一场噩梦。(例如,你敢相信他们会想出如何获得 GPU 吗?)

当然,你可以告诉他们在市场解决方案上获得现成的解决方案——这个主意不错!—但是,如果您渴望定制该解决方案,该怎么办呢?你打算浪费一周的课堂时间来指导你的 100 名学生,让他们在试着按正确的顺序转动正确的旋钮时感到牙疼吗?你会放弃一个定制的起点吗?

有更好的方法。

以前:你浪费了宝贵的教学时间来指导学生按正确的顺序按正确的设置按钮。

之后:在您完成自己的定制后,您的学生可以立即开始(并停留在)同一页面上。

从您喜欢的任何地方开始(从零开始,从市场,从以前教授的机器映像开始)并定制到您满意的内容,然后与您的学生分享最终的机器映像。跳过课堂上的讨论,放心,如果他们的代码不工作,那不是因为他们在第一周忘记检查防火墙设置框。

另外,如果你在期中考试前对学生的设置感到后悔,很容易就可以替换。

如何

创建机器映像

选项 1 是从计算引擎中的 VM 实例创建一个机器映像,如第一个 GIF 所示。

是的,我给它们取名为“野兽”和“小野兽”不,当你与其他成年人合作进行专业数据科学工作时,这不是你命名事物的方式。似乎演示引出了我最糟糕的习惯!但在我看来,一个 VM 可以从很小的东西开始,如果需要,你总是可以选择将其扩展到相当大的规模。

选项 2 是直接进入机器映像部分,创建一个新的,在表单中指明 VM 实例源,如下一个 GIF 所示。

这将让你看到我们在上面的 GIF 中看到的相同的表格,以相同的方式进行…

使用机器映像

您已经看到了从您的机器映像创建 VM 的一种方法(本文中的第一个 GIF ),但是还有另一种方法:

几乎太容易了,对吧?差不多了。就我们这些数据科学家而言,不管有多容易,任何不涉及玩弄数据的事情应该总是更容易。但是在心灵感应界面出现之前,我很高兴拥有这个界面。

在谷歌云博客 了解更多机器图像

感谢阅读!人工智能课程怎么样?

如果你在这里玩得开心,并且你正在寻找一个为初学者和专家设计的有趣的应用人工智能课程,这里有一个我为你制作的娱乐课程:

在这里欣赏整个课程播放列表:bit.ly/machinefriend

与凯西·科兹尔科夫联系

让我们做朋友吧!你可以在 TwitterYouTubeLinkedIn 上找到我。有兴趣让我在你的活动上发言吗?使用表格取得联系。

您的终极数据操作和清理备忘单

原文:https://towardsdatascience.com/your-ultimate-data-manipulation-cleaning-cheat-sheet-731f3b14a0be?source=collection_archive---------24-----------------------

资料来源:Unsplash。

解析日期、输入、异常检测等等

数据科学项目的大部分由数据清理和操作组成。这些数据清理任务中的大多数可以分为六个方面:

  • 输入缺失值。标准统计常数估算,KNN 估算。
  • 异常值/异常检测。隔离森林,一类 SVM,局部离群因子离群检测算法。
  • X 变量清洗方法。应用自定义函数,删除重复项,替换值。
  • Y 变量清洗方法。标签编码,字典映射,一键编码。
  • 连接数据帧。连接、合并和连接。
  • 解析日期。自动格式检测字符串到日期时间的转换,日期时间对象到数字。

除非另有明确说明,否则图片由作者创作。

输入缺失值

缺失值经常困扰着数据,如果它们不太多,它们可以被估算(填充)。

简单的输入方法是统计常数测量,如用每列的统计测量值填充NaN(缺失值)的平均值或中值。参数strategy可以替换为‘均值’,‘中值’,‘最频繁’(模式),或‘常数’(带参数fill_value的手动值)。

from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy='mean')
data = imputer.fit_transform(data)

KNN 输入是输入缺失值的最流行和最复杂的方法,其中 KNN 算法在多维空间中寻找与缺失值相似的其他数据点。

from sklearn.impute import KNNImputer
imputer = KNNImputer()
data = imputer.fit_transform(data)

在使用 KNN 和其他基于距离的算法之前,需要对数据进行缩放或归一化以消除缩放差异(例如,一列代表孩子数量,另一列代表年薪——这些值不能从表面上看)。使用 KNN 估算遵循以下过程:

  1. 缩放/标准化数据。
  2. KNN-用于填充缺失值的估算。
  3. 反向缩放/归一化数据。

异常值/异常检测

隔离森林是返回样本异常分值的算法。该算法通过随机选择一个要素、随机选择一个分割值来创建路径,从而隔离观察值,路径长度表示其正态性。较短的路径代表异常-当随机树的森林共同为特定样本产生较短的路径长度时,它们极有可能是异常。

from sklearn.ensemble import IsolationForest
identifier = IsolationForest().fit(X)
identifier.predict(X)

异常检测器的预测输出是从-1 到 1 的分数数组,正分数表示异常的可能性较高。

一类 SVM 是另一种用于检测异常值的无监督方法,适用于像隔离森林这样的异常检测方法会产生太多差异的高维分布。

from sklearn.svm import OneClassSVM
identifier = OneClassSVM().fit(X)
identifier.predict(X)

局部异常值因子是三种常用异常值标识符中的第三种。每个样本的异常值(局部异常值因子)衡量给定样本相对于其相邻样本的局部密度偏差。基于 K-最近邻,密度显著低于其邻的样本被认为是异常值。

因为这种算法是基于距离的,所以在使用之前需要对数据进行缩放或归一化。该算法可被视为隔离森林的非线性高方差替代方案。

from sklearn.neighbors import LocalOutlierFactor
model = LocalOutlierFactor().fit(X)
model.predict(X)

对于所有三种异常算法,消除所有异常是数据科学家的选择。确保异常不仅仅是数据集群本身——确保异常的数量不会过多。PCA 可视化可以证实这一点。

x 变量清洁方法

对列应用函数经常需要对其进行清理。在内置函数无法完成清理的情况下,您可能需要编写自己的函数或传入外部内置函数。例如,假设 2 下面的列b的所有值都是无效的。然后,要应用的函数可以充当过滤器,为没有通过过滤器的列元素返回NaN值:

def filter_b(value):
     if value < 2:
          return np.nan
     else:
          return value

然后,通过使用熊猫的.apply()函数应用过滤器,可以创建一个新的已清理列‘cleaned _ b’:

data['cleaned_b'] = data['b'].apply(filter_b)

另一个常见的用例是转换数据类型。例如,将字符串列转换成数字列可以通过使用 Python 内置函数floatdata[‘target’].apply(float)来完成。

删除重复是数据清理中的常见任务。这可以用data.drop_duplicates()来完成,它删除具有完全相同值的行。使用时要小心-当要素数量较少时,重复行可能不是数据收集中的错误。但是,对于大型数据集和大多数连续变量,重复项不是错误的可能性很小。

数据点采样在数据集过大(或出于其他目的)且数据点需要随机采样时很常见。这可以用data.sample(number_of_samples)来完成。

重命名列是通过.rename完成的,这里传递的参数是一个字典,其中键是原始列名,值是重命名的值。例如,data.rename({‘a’:1, ‘b’:3})会将列‘a’重命名为 1,将列‘b’重命名为 3。

替换数据中的值可以通过data.replace()来完成,它接受两个参数to_replacevalue,这两个参数代表数据帧中将被其他值替换的值。这对于下一节输入缺失值很有帮助,可以用np.nan替换某些变量,这样输入算法就可以识别它们。

更方便的专门用于数据操作的熊猫函数可以在这里找到:

[## 7 熊猫功能减轻您的数据操作压力

熊猫没有白毛是有原因的

towardsdatascience.com](/7-pandas-functions-to-reduce-your-data-manipulation-stress-25981e44cc7d)

y 变量清洗方法

分类 y 变量需要标签编码。例如,如果数据有两个类别“猫”和“狗”,它们需要映射到 0 和 1,因为机器学习算法纯粹基于数学运算。

一种简单的方法是使用.map()函数,它采用一个字典,其中键是原始类名,值是它们要被替换的元素。

data['target'] = data['target'].map({'cat':0, 'dog':1})

然而,如果有太多的类不能用字典手动映射,sklearn有一个自动化的方法:

from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder().fit(data['target'])
data['target'] = encoder.transform(data['target'])

使用这种标签编码方法的好处是可以使用encoder.inverse_transform(array)对数据进行逆转换——也就是从数值到原始类的转换。

当标签编码对数据进行量化测量时,在具有多个类别的特定场景中,一键编码优于标签编码。类别“狗”、“猫”和“鱼”之间的标签编码为 0、1 和 2,假设不知何故“鱼”比“狗”大或者“狗”比“猫”小。

在 one-hot 编码中,每个y-值是一个向量,其长度为不同类的数量,其中“1”表示向量中的唯一索引,其余值标有“0”。例如,可以将向量[1, 0, 0]、【猫】分配给[0, 1, 0]、【鱼】分配给[0, 0, 1]

pandas有一个内置函数get_dummies,它自动接受一个序列或另一个数组形式,并输出一位热码编码数据帧。比如下面这个命令pd.get_dummies(data[‘target’]

连接数据框架

串联是数据帧的自顶向下连接。例如,pd.concat([df1, df2])将产生一个主数据帧,其中df2堆叠在df1下方。

合并是一个从左到右的过程,横向合并两个数据帧,而不是用concat()纵向合并。例如,pd.merge(left_df, right_df, on='ID')将基于‘ID’列合并左数据帧和右数据帧。

加入允许更专业的合并。默认情况下,合并是一个内部连接,它只适合关键字在两个数据框中的行。其他类型的连接包括左外部连接,其中包括左数据帧中的所有关键字,只有当其关键字存在于左数据帧中时,才包括右数据帧中的行。

可在merge内的参数how=”outer”“right”中概述选择的连接类型:

pd.merge(left = left_df, right = right_df, how = 'outer', on = 'id')

解析日期

日期可能是最难处理的数据对象,但对数据来说也是必不可少的。时间是现实生活中最重要的变量,重要的是不要让处理时间的困难影响到你的数据。

将字符串转换成日期是很常见的——数据集几乎从不带有可以方便访问的datetime对象。把字符串转换成日期最好的库是dateutil,可以自动推断日、月、年的位置,需要用其他库指定。

from dateutil import parser

dateutil可以适应多种日期,其中每个命令都产生相同的结果(datetime.datetime(2040, 7, 3, 0, 0)):

  • parser.parse(‘7/3/40’)
  • parser.parse(‘7–3–2040’)
  • parser.parse(‘7.3.40’)
  • parser.parse(‘July 3rd, 2040’)
  • parser.parse(‘July 3 2040’)
  • parser.parse(‘2040 July 3’)
  • parser.parse(‘3 July 2040’)

对一个列使用.apply(parser.parse)可以将几乎任何形式的字符串转换成一个datetime对象,在这里可以提取它的属性。

将日期转换成数字很重要,因为虽然时间对于模型来说是必不可少的,但它不能处理日期时间对象。相反,时间可以表示为整数,其中每个日期表示自数据中最早的日期以来经过的天数。在下面的示例中,2016 年 3 月 8 日是数据集中最早的日期(这需要找到并替换)。

import datetime
def convert_date_to_num(date):
     return (date - datetime.datetime(5,8,16)).daysdata['number date'] = data['date'].apply(convert_date_to_num)

使用.apply()将该函数应用于日期列(假设日期列的元素是datetime对象)。

感谢阅读!

如果你觉得有帮助的话,一定要把这个页面加入书签,以便于参考。如果您喜欢,您可能还会喜欢其他数据科学备忘单:

[## 你的终极数据科学统计和数学小抄

机器学习指标、统计指标等

medium.com](https://medium.com/@andre_ye/your-ultimate-data-science-statistics-mathematics-cheat-sheet-d688a48ad3db) [## 您的终极数据挖掘和机器学习备忘单

特性重要性、分解、转换等

medium.com](https://medium.com/analytics-vidhya/your-ultimate-data-mining-machine-learning-cheat-sheet-9fce3fa16) [## 您的最终 Python 可视化备忘单

这个备忘单包含了你最常需要的一个情节的要素,以一种清晰和有组织的方式,用…

medium.com](https://medium.com/analytics-vidhya/your-ultimate-python-visualization-cheat-sheet-663318470db)

您的终极数据挖掘和机器学习备忘单

原文:https://towardsdatascience.com/your-ultimate-data-mining-machine-learning-cheat-sheet-9fce3fa16?source=collection_archive---------4-----------------------

来源: Pixabay

特性重要性、分解、转换等

本备忘单将涵盖数据挖掘和机器学习的几个领域:

  • 预测建模。用于监督学习(预测)的回归和分类算法,用于评估模型性能的度量。
  • 聚类。将无标签数据分组为聚类的方法:K-Means,选择基于客观度量的聚类数。
  • 降维。降低数据和属性维数的方法:PCA 和 LDA。
  • 特征重要性。寻找数据集中最重要特征的方法:排列重要性、SHAP 值、部分相关图。
  • 数据转换。转换数据以获得更大预测能力、更容易分析或揭示隐藏关系和模式的方法:标准化、规范化、box-cox 转换。

预测建模

训练-测试-分割是测试一个模型表现如何的重要部分,通过在指定的训练数据上训练它,并在指定的测试数据上测试它。通过这种方式,可以衡量模型归纳新数据的能力。在sklearn中,两个列表、熊猫数据帧或 NumPy 数组都在Xy参数中被接受。

from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3)

训练一个标准的监督学习模型采取导入、创建实例和拟合模型的形式。

**sklearn** 分类器型号如下所示,分支用蓝色突出显示,型号名称用橙色显示。

**sklearn** 回归器模型如下所示,分支用蓝色突出显示,模型名称用橙色显示。

评估模型性能通过以下形式的列车测试数据完成:

**sklearn** 下面列出了分类和回归的指标,最常用的指标用绿色标出。在某些情况下,许多灰色指标比绿色指标更合适。每一种都有自己的优点和缺点,平衡优先级比较、可解释性和其他因素。

使聚集

在聚类之前,需要对数据进行标准化(这方面的信息可以在数据转换一节中找到)。聚类是基于点距离创建聚类的过程。

来源。图片免费分享。

训练和创建 K-Means 聚类模型创建一个可以聚类和检索关于聚类数据的信息的模型。

from sklearn.cluster import KMeans
model = KMeans(n_clusters = number_of_clusters)
model.fit(X)

访问数据中每个数据点的标签可以通过:

model.labels_

类似地,每个数据点的标签可以存储在一列数据中,其中:

data['Label'] = model.labels_

访问新数据的簇标签可通过以下命令完成。new_data可以是数组、列表或数据帧的形式。

data.predict(new_data)

访问每个聚类的聚类中心以二维数组的形式返回:

data.cluster_centers_

为了找到聚类的最佳数量,使用剪影得分,这是一个衡量特定数量的聚类与数据拟合程度的指标。对于预定义范围内的每个聚类数,训练 K-Means 聚类算法,并将其轮廓分数保存到列表中(scores)。data是模型被训练的x

from sklearn.metrics import silhouette_scorescores = []
for cluster_num in range(lower_bound, upper_bound):
     model = KMeans(n_clusters=cluster_num)
     model.fit(data)
     score = silhouette_score(data, model.predict(data))

分数保存到列表scores后,可以用图表显示或通过计算搜索找到最高的分数。

降维

降维是用减少的维数表达高维数据的过程,使得每个维数包含最多的信息。降维可用于高维数据的可视化,或通过移除低信息或相关特征来加速机器学习模型。

主成分分析或 PCA 是一种流行的方法,通过在特征空间中绘制几个正交(垂直)向量来表示减少的维数,从而减少数据的维数。变量number表示缩减后的数据将具有的维数。例如,在可视化的情况下,它将是二维的。

PCA 工作原理的可视化演示。来源

拟合 PCA 模型:函数.fit_transform自动将模型与数据拟合,并将其转换为减少的维数。

from sklearn.decomposition import PCAmodel = PCA(n_components=number)
data = model.fit_transform(data)

解释差异率:调用model.explained_variance_ratio_会产生一个列表,列表中的每一项都对应该维度的“解释差异率”,本质上就是该维度所代表的原始数据中的信息百分比。解释的方差比之和是保留在降维数据中的信息的总百分比。

PCA 特征权重:在 PCA 中,每个新创建的特征都是以前数据特征的线性组合。这些线性权重可以通过model.components_访问,并且是特征重要性的良好指示器(较高的线性权重表示该特征中表示的信息更多)。

线性判别分析 (LDA,不要和潜在的狄利克雷分配混淆)是另一种降维方法。LDA 和 PCA 的主要区别在于 LDA 是一种监督算法,这意味着它同时考虑了 xy 。主成分分析只考虑 x ,因此是一种无监督算法。

PCA 试图完全基于点与点之间的距离来保持数据的结构(方差),而 LDA 优先考虑类的清晰分离。

from sklearn.decomposition import LatentDirichletAllocation
lda = LatentDirichletAllocation(n_components = number)
transformed = lda.fit_transform(X, y)

特征重要性

特征重要性是找到对目标最重要的特征的过程。通过主成分分析,可以找到包含最多信息的特征,但是特征重要性涉及特征对目标的影响。“重要”特征的变化会对 y 变量产生很大影响,而“不重要”特征的变化对 y 变量几乎没有影响。

排列重要性是评价一个特征有多重要的方法。训练了几个模型,每个模型都缺少一列。由于缺少数据而导致的模型准确性的相应降低表明了该列对模型预测能力的重要性。eli5库用于排列重要性。

import eli5
from eli5.sklearn import PermutationImportance
model = PermutationImportance(model)
model.fit(X,y)
eli5.show_weights(model, feature_names = X.columns.tolist())

在这个排列重要性模型被训练的数据中,列lat对目标变量(在这个例子中是房价)具有最大的影响。为了获得最佳预测性能,在决定移除模型中的哪些要素(实际上混淆模型的相关或冗余要素,由负的置换重要性值标记)时,置换重要性是最佳的使用要素。

SHAP 是另一种评估功能重要性的方法,借用 21 点中的博弈论原理来估算玩家能贡献多少价值。与排列重要性不同,SHapleyAd active ExPlanation 使用更公式化和基于计算的方法来评估特性重要性。SHAP 需要一个基于树的模型(决策树,随机森林),并适应回归和分类。

import shap
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X)
shap.summary_plot(shap_values, X, plot_type="bar")

PD(P)图或部分相关图是数据挖掘和分析中的主要内容,显示一个特征的某些值如何影响目标变量的变化。所需的导入包括依赖图的pdpbox和显示图的matplotlib

from pdpbox import pdp, info_plots
import matplotlib.pyplot as plt

隔离的 PDP:下面的代码显示了部分依赖图,其中feat_nameX内将被隔离并与目标变量进行比较的特征。第二行代码保存数据,而第三行构建画布来显示绘图。

feat_name = 'sqft_living'
pdp_dist = pdp.pdp_isolate(model=model, 
                           dataset=X, 
                           model_features=X.columns,
                           feature=feat_name)
pdp.pdp_plot(pdp_dist, feat_name)
plt.show()

部分相关图显示了某些价值和居住空间平方英尺数的变化对房价的影响。阴影区域代表置信区间。

等高线 PDP:部分相关图也可以采用等高线图的形式,比较的不是一个孤立变量,而是两个孤立变量之间的关系。要比较的两个特征存储在变量compared_features中。

compared_features = ['sqft_living', 'grade']inter = pdp.pdp_interact(model=model, 
                          dataset=X, 
                          model_features=X.columns, 
                          features=compared_features)
pdp.pdp_interact_plot(pdp_interact_out=inter,
                      feature_names=compared_features),
                      plot_type='contour')
plt.show()

两个特性之间的关系显示了只考虑这两个特性时对应的价格。部分相关图充满了数据分析和发现,但是要注意大的置信区间。

数据转换

标准化或缩放是“重塑”数据的过程,使其包含相同的信息,但平均值为 0,方差为 1。通过缩放数据,算法的数学本质通常可以更好地处理数据。

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(data)
transformed_data = scaler.transform(data)

transformed_data是标准化的,可用于许多基于距离的算法,如支持向量机和 K-最近邻算法。使用标准化数据的算法的结果需要被“去标准化”,以便它们可以被正确地解释。.inverse_transform()可用于执行与标准变换相反的操作。

data = scaler.inverse_transform(output_data)

标准化数据将数据放在 0 到 1 的范围内,类似于标准化数据,使数据在数学上更容易用于模型。

from sklearn.preprocessing import Normalizer
normalize = Normalizer()
transformed_data = normalize.fit_transform(data)

虽然规范化不会像标准化那样改变数据的形状,但它限制了数据的边界。是否规范化或标准化数据取决于算法和上下文。

Box-cox 变换涉及对数据进行各种幂次变换。Box-cox 变换可以规范化数据,使其更加线性,或者降低复杂性。这些转换不仅涉及到数据的幂,还涉及到分数幂(平方根)和对数。

例如,考虑沿着函数 g ( x )的数据点。通过应用对数 box-cox 变换,可以容易地用线性回归对数据建模。

和德斯莫斯一起创造的。

sklearn自动确定应用于数据的最佳 box-cox 变换系列,使其更接近正态分布。

from sklearn.preprocessing import PowerTransformer
transformer = PowerTransformer(method='box-cox')
transformed_data = transformer.fit_transform(data)

由于 box-cox 变换平方根的性质,box-cox 变换的数据必须是严格正的(在 hand 可以处理这一点之前对数据进行归一化)。对于具有负数据点和正数据点的数据,通过类似的方法设置method = ‘yeo-johnson’,使数据更接近钟形曲线。

感谢阅读!

如果你觉得有帮助的话,一定要把这一页加入书签以便参考。通常,数据挖掘和分析需要可视化——请随意查看另一个可视化备忘单。当您创建可视化和执行机器学习操作时,您可能想看看数据操作和清理备忘单。

[## 你的终极数据科学统计和数学小抄

机器学习指标、统计指标等

medium.com](https://medium.com/@andre_ye/your-ultimate-data-science-statistics-mathematics-cheat-sheet-d688a48ad3db) [## 您的最终 Python 可视化备忘单

这个备忘单包含了你最常需要的一个情节的要素,以一种清晰和有组织的方式,用…

medium.com](https://medium.com/analytics-vidhya/your-ultimate-python-visualization-cheat-sheet-663318470db) [## 您的终极数据操作和清理备忘单

解析日期、输入、异常检测等等

medium.com](https://medium.com/@andre_ye/your-ultimate-data-manipulation-cleaning-cheat-sheet-731f3b14a0be)

你的终极数据科学统计和数学小抄

原文:https://towardsdatascience.com/your-ultimate-data-science-statistics-mathematics-cheat-sheet-d688a48ad3db?source=collection_archive---------19-----------------------

皮沙贝

机器学习指标、统计指标等

除非另有说明,所有图片均由作者创作。

在数据科学中,对数据的统计学和数学有一个坚实的理解对于正确有效地应用和解释机器学习方法是至关重要的。

  • 分类器指标。混淆矩阵,灵敏度,召回率,特异性,精确度,F1 得分。它们是什么,何时使用,如何实现。
  • 回归量指标。MAE,MSE,RMSE,MSLE,R .他们是什么,何时使用,如何实现。
  • 统计指标。相关系数,协方差,方差,标准差。如何使用和解释它们。
  • 分布类型。最常见的三种分布,如何识别。

分类器度量

分类器指标是用于评估机器学习分类器性能的指标,这些分类器是将每个训练样本归入几个离散类别之一的模型。

混淆矩阵是用于表示分类器对标签的预测的矩阵。它包含四个单元格,每个单元格对应于一个预测真或假和一个实际真或假的组合。许多分类器指标都是基于混淆矩阵的,所以在头脑中保存一个混淆矩阵的图像是有帮助的。

灵敏度/召回率是被准确预测的阳性数量。这被计算为TP/(TP+FN)(注意,假阴性就是阳性)。在正确预测阳性很重要的情况下,如医疗诊断,灵敏度是一个很好的指标。在某些情况下,假阳性可能是危险的,但人们普遍认为假阴性(例如,对患有癌症的人诊断为“没有癌症”)更致命。通过让模型最大限度地提高灵敏度,可以确定正确分类的优先级。

特异性是准确预测的阴性数,计算为TN/(TN+FP)(注意假阳性其实是阴性)。与敏感性一样,特异性在准确分类阴性比分类阳性更重要的情况下也是一个有用的指标。

精度可以被认为是敏感度或回忆的反义词,因为敏感度衡量的是预测为真的实际真实观察值的比例,而精度衡量的是预测真实观察值实际为真的比例。这被测量为TP/(TP+FP)。精度和召回一起提供了模型性能的全面视图。

F1 得分通过调和平均值结合了精确度和召回率。它的确切公式是(2 × precision × recall) / (precision + recall) 使用调和平均值是因为它惩罚更多的极值,与平均值相反,平均值是天真的,因为它对所有误差的加权都是一样的。

检测/准确率是正确分类的项目数量,计算方法为真阳性和真阴性的总和除以所有四个混淆矩阵象限的总和。这种准确率对积极因素和消极因素的权重是相等的,而不是优先考虑一个因素。

使用 F1 得分与准确性:当不犯错更重要时(假阳性和假阴性受到更重的惩罚),应该使用 F1 得分,而当模型的目标是优化性能时,应该使用准确性。这两个指标都是基于上下文使用的,并且根据数据表现不同。然而,一般来说,对于不平衡的类别(例如,癌症诊断,当阴性远远多于阳性时),F1 分数更好,而对于更平衡的类别,准确性更好。

实施指标遵循以下格式。

sklearn中讨论的指标名称有:

  • 混乱矩阵:confusion_matrix
  • 灵敏度/召回:recall_score
  • 精度:precision_score
  • F1 得分:f1_score
  • 准确度:accuracy_score
  • 平衡精度(对于非均匀分布的类):balanced_accuracy_score

回归指标

回归度量用于度量模型在连续规模上放置训练示例的效果,例如确定房屋的价格。

平均绝对误差(MAE) 也许是最常见和最易解释的回归指标。MAE 计算每个数据点的预测 y 值和实际 y 值之间的差值,然后对每个差值进行平均(差值计算为一个值减去另一个值的绝对值)。

中值绝对误差是评估平均误差的另一个指标。虽然它的好处是通过关注中间误差值来降低误差分布,但它也往往会忽略计入平均绝对误差的极高或极低误差。

均方差(MSE) 是另一种常用的回归指标,它更多地“惩罚”较高的误差。例如,误差(差值)2 将被加权为 4,而误差 5 将被加权为 25,这意味着 MSE 发现两个误差之间的差值为 21,而 MAE 将差值加权为其表面值-3。MSE 计算每个数据点的预测 y 值和实际 y 值的平方,然后平均这些平方。

均方根误差(RMSE) 用于给出均方差缺乏的可解释性水平。通过对 MSE 求平方根,我们获得了与 MAE 相似的度量,因为它处于相似的尺度,同时仍然在更高的水平上加权更高的误差。

均方对数误差(MSLE) 是平均绝对误差的另一种常见变化。由于误差的对数性质,MSLE 只关心百分比差异。这意味着 MSLE 将把小数值(例如,4 和 3)之间的小差异视为大范围内的大差异(例如,1200 和 900)。

R 是一个常用的指标(其中 r 被称为相关系数),用于衡量回归模型在多大程度上代表了因变量方差的比例,该方差可以由自变量来解释。简而言之,这是一个很好的数据拟合回归模型的指标。

实施指标遵循以下格式。

sklearn中讨论的指标名称有:

  • 平均绝对误差:mean_absolute_error
  • 中位数绝对误差:median_absolute_error
  • 均方差:mean_squared_error
  • 均方根误差:root_mean_squared_error
  • 均方对数误差:mean_squared_log_error
  • R : r2_score

统计指标

4 .主要数据科学统计方法。

相关性是衡量两个变量共同波动程度的统计指标。正相关意味着两个变量一起波动(一个变量的正变化是另一个变量的正变化),而负相关意味着两个变量的变化相反(一个变量的正变化是另一个变量的负变化)。相关系数,从+1 到-1,也称为 R

相关系数可通过 Pandas 数据帧使用.corr()功能访问。考虑以下两个序列:

seq1 = [0,0.5,0.74,1.5,2.9]
seq2 = [4,4.9,8.2,8.3,12.9]

使用构造函数table = pd.DataFrame({‘a’:seq1,’b’:seq2}),创建一个包含两个序列的数据帧。调用table.corr()会产生一个相关表。

例如,在相关表中,序列 AB 具有 0.95 的相关性。当序列与其自身比较时,相关表是对称的并且等于 1。

协方差类似于相关性,是当变量被线性变换时函数保持其形式的性质的量度。然而,与相关性不同的是,协方差可以是任何数字,而相关性则局限在一个范围内。因此,相关性对于确定两个变量之间关系的强度更有用。因为协方差有单位(与相关性不同),并且受中心或比例变化的影响,所以它不太广泛地用作独立的统计数据。然而,协方差用于许多统计公式中,是一个需要了解的有用数字。

这可以用 Python 中的numpy.cov(a,b)[0][1]来完成,其中ab是要比较的序列。

方差是随机变量与其均值的方差的期望值的度量。它非正式地测量一组数字偏离均值的程度。可以用statistics.variance(list)在统计库(import statistics)中测量方差。

标准偏差是方差的平方根,是一个关于分布如何展开的更大规模的统计。可以用statistics.stdev(list)在统计库中测量标准偏差。

分布类型

在处理数据分析和理解使用哪种统计和机器学习方法时,了解您的分布非常重要。

虽然有几种类型的数学专用分布,但其中大多数都适合这三种分布。

均匀分布是最简单的分布——它是完全平坦的,或者说是真正随机的。例如,对于 6000 次投掷中的每一次,记录的骰子落在多少个点上(从 1 到 6)将产生平坦分布,每个点数大约有 1000 次投掷。均匀分布具有有用的属性-例如,阅读盟军如何使用均匀分布的统计属性在第二次世界大战中挽救了无数生命。

[## 数据科学如何让盟军在二战中获得优势

用计算机模拟德国坦克问题

medium.com](https://medium.com/better-programming/how-data-science-gave-the-allied-forces-an-edge-in-world-war-ii-7fe92a74add5)

正态分布是一种非常常见的类似曲线的分布(该分布的一个名称是“钟形曲线”)。除了在数据科学中的常见用途,它也是宇宙中大多数事物可以用智商或工资来描述的地方。它具有以下特点:

  • 68%的数据在平均值的一个标准偏差内。
  • 95%的数据在平均值的两个标准偏差之内。
  • 99.7%的数据在平均值的三个标准偏差之内。

许多机器学习算法要求数据呈正态分布。例如,逻辑回归要求残差服从正态分布。这可以通过residplot()进行可视化和识别。关于该模型和其他统计模型用法的信息和示例可以在这里找到。

泊松分布可以认为是正态分布的推广;一种离散概率分布,表示在固定的时间或空间间隔内发生的给定数量的事件的概率,如果这些事件以已知的恒定平均速率发生,并且与上次事件后的时间无关。随着λ值的变化,泊松分布将均值向左或向右移动,从而能够创建左偏或右偏的数据。

感谢阅读!

如果你觉得这个备忘单很有帮助,请随意投票并为该页面添加书签以便参考。如果您喜欢这个备忘单,您可能会对在其他备忘单中应用您的统计知识感兴趣。如果你想在这个备忘单中看到更多的讨论话题,请在回复中告诉我!

[## 您的最终 Python 可视化备忘单

这个备忘单包含了你最常需要的一个情节的要素,以一种清晰和有组织的方式,用…

medium.com](https://medium.com/analytics-vidhya/your-ultimate-python-visualization-cheat-sheet-663318470db) [## 您的终极数据操作和清理备忘单

解析日期、输入、异常检测等等

medium.com](https://medium.com/analytics-vidhya/your-ultimate-data-manipulation-cleaning-cheat-sheet-731f3b14a0be) [## 您的终极数据挖掘和机器学习备忘单

特性重要性、分解、转换等

medium.com](https://medium.com/analytics-vidhya/your-ultimate-data-mining-machine-learning-cheat-sheet-9fce3fa16)

您的最终 Python 可视化备忘单

原文:https://towardsdatascience.com/your-ultimate-python-visualization-cheat-sheet-663318470db?source=collection_archive---------9-----------------------

来源:Pixabay 免费分享

轻松创建美丽的、可定制的情节

这个备忘单包含了你最常需要的一个情节的元素,以一种清晰和有组织的方式,带有代码和例子。在你创建任何情节之前,建议你浏览一下这个备忘单,以便清楚地知道你将如何构建可视化——毕竟,你的情节只有在你的脑海中,观众才会清楚。

除非另有明确说明,所有图片均由作者创作。

创建可视化的步骤

  1. 根据你的图有多少维来准备数据(分布图有一维,箱线图有二维,等等。).
  2. 启动图形世界(情节依赖的“世界”)美学,如风格或调色板。
  3. 创造情节。
  4. 使用标题、标签和附加功能自定义绘图。

进口

Python 绘图的两个最流行的库——matplotlib 和 seaborn——应该以它们的公共别名pltsns加载,以便快速访问它们的函数和属性,而不需要键入它们的完整冗长的名称。

import matplotlib.pyplot as plt
import seaborn as sns

开创图形世界

创建图形是指定图形尺寸所必需的。

plt.figure(figsize=(horizontal_length,vertical_length))

Seaborn styles 可以给图形空间添加网格和样式。seaborn 有四种风格,可以用.set_style加载。

sns.set_style(name_of_style)

Seaborn contexts 是内置的预先创建的包,它会影响标签的大小、线条和其他元素,但不会影响整体风格。

sns.set_context(name_of_context)

所有图都有白色网格样式。这是单独设置的。

Seaborn 调色板为图表提供了一组颜色,这可以给你的情节提供你希望你的观众感受到的感觉或背景。

Seaborn 有几十个策划调色板。它们装载着

sns.set_palette(name_of_palette)

kde 绘图中有四个调色板。

您可以通过故意设置不正确的调色板来访问 seaborn 的许多调色板的所有名称:

sns.set_palette('a string deliberately entered to get an error')

然后可以用 seaborn 的palpot(调色板绘图)查看每个调色板。传递给 seaborn 的color_palette构建器的第一项是调色板的名称,第二项是应该显示的颜色数量。在真实剧情中,seaborn 自动确定这个数字,但是你可以在palpot中控制它。

sns.palplot(sns.color_palette('GnBu', 15))

Seaborn 调色板也可以通过传入十六进制代码来手动设置。

sns.set_palette(['#ffffff', ...])

创造情节

seaborn 中的所有绘图都是用sns.name_of_plot(x, y)创建的,这取决于绘图的维数。像箱线图这样的一维图只需要一个x,而散点图则需要一个x和一个y

分布图

分布图通常是单变量数据——只有一个维度的数据,并显示数据点沿数字线的集中位置。Seaborn 对二维分布图进行了调整,可以同时显示两个分布图。

  • distplot用直方图绘制一维kdeplot
  • rugplot用记号代替数据点来显示聚类。
  • 仅输入一维数据时的kdeplot绘制分布曲线。当给定二维数据时,它将绘制出等值线图。
  • jointplot绘制一个散点图,每边都有直方图,以显示其各自的维度。
  • 通常用于探索性数据分析(EDA)的pairplot绘制数据的各个维度,当变量相对于自身绘制时,显示变量的直方图。该图接收一个pandas数据帧。

定量和定性变量关系

这些图结合了两种类型的变量——定量变量(如 13、16.54、94.004、连续变量)和定性变量(如红色、蓝色、雄性、离散变量)。

  • stripplot水平绘制垂直数据点,以便可以看到相同值的多个数据点。这需要一个定性的x和一个定量的y
  • swarmplotstripplot相似,水平绘制垂直数据点,但更有条理。这以结构化的方式消除了重叠的数据点。
  • violinplot绘制了数量轴两侧的分布,被视为箱线图的有利替代方案。
  • boxplot绘制了数据的五个数字摘要——最小值、第一个四分位数(第 25 个百分位数)、中间值、第三个四分位数(第 75 个百分位数)和最大值。不幸的是,它确实有隐藏不规则分布的趋势。
  • 通过在箱线图顶部展开,boxenplot可以显示尾部和更准确的分布描述。
  • 标准barplot显示高度与数值相对应的条。countplot表示相同的可视化,但只接受一个变量,并显示每个不同值中的项目数。
  • pointplot试图找到一个点(用适当的误差线)来恰当地表示那个数组。该图非常适合于比较数字定性变量。

数量关系

这些图显示了两个定量变量之间的关系。

  • scatterplot描绘了两个相互对立的定量变量。
  • lineplot沿着时间变量绘制一个数量变量,时间变量可以是数量变量或日期变量。

统计模型

统计模型可视化利用统计模型来可视化数据的性质。在许多统计模型可视化中,有调整可视化性质的参数。

  • residplot显示线性回归的残差(每个数据点偏离欧几里德距离的线性回归拟合有多远)。
  • lmplot在散点图上显示带有置信区间的线性回归拟合。该图有几个参数(可在长度中查看,此处为)可用于调整图的性质。例如,设置logistic=True将假设 y 变量是二进制的,并将创建一个逻辑(sigmoid)回归模型。

自定义情节

创建地块后对其进行自定义涉及到在地块顶部添加特征以增加可读性或信息。

**x** **y** 标签可以用plt.xlabel(‘X Label’)plt.ylabel(‘Y Label’)两个命令添加。

标题标签可以通过plt.title(‘Title’)命令添加。

刻度旋转可以加上plt.xticks(rotation=90)(以及 y 轴刻度标签的 yticks),其中 90°可以替换为任何合适的旋转角度。

轴值范围可以用plt.xlim(lower_limit, upper_limit)plt.ylim(lower_limit, upper_limit)指定。该尺寸显示的所有值都将在指定的限制范围内。这些也可用于为图形设置合适的 y 轴基线。

添加图例,如果默认没有,可以添加plt.legend()。可以添加一个参数loc来指示图例应该在哪里。默认情况下,matplotlib会找到最佳位置,这样它就不会与数据点重叠。

显示图plt.show()一样简单。虽然不是完全必要,但它去掉了 matplotlib 和 seaborn 打印出来的一些文本,并最终确定了情节。

请务必将此页面加入书签,以便于参考!如果你喜欢,你可能还会喜欢终极数据挖掘和机器学习备忘单,在这个领域你可以很好地利用你的可视化技能,以及终极数据操作和清理备忘单-将数据转换为可视化形式所需的技能。

[## 你的终极数据科学统计和数学小抄

机器学习指标、统计指标等

medium.com](https://medium.com/@andre_ye/your-ultimate-data-science-statistics-mathematics-cheat-sheet-d688a48ad3db) [## 您的终极数据挖掘和机器学习备忘单

特性重要性、分解、转换等

medium.com](https://medium.com/@andre_ye/your-ultimate-data-mining-machine-learning-cheat-sheet-9fce3fa16) [## 您的终极数据操作和清理备忘单

解析日期、输入、异常检测等等

medium.com](https://medium.com/@andre_ye/your-ultimate-data-manipulation-cleaning-cheat-sheet-731f3b14a0be)

你在 WhatsApp 上的聊天记录可以透露很多关于你的信息

原文:https://towardsdatascience.com/your-whatsapp-chats-can-tell-a-lot-about-you-3a7db37789b3?source=collection_archive---------17-----------------------

使用 Python 可视化 WhatsApp 聊天

威廉·艾文在 Unsplash 上的照片

最近,我在寻找一些小而令人兴奋的可视化项目来探索数据可视化领域。然后我在 WhatsApp 上发现了一个功能,可以将你的聊天记录导出到一个文本文件中,这个功能非常方便易用。Whatsapp 声称,2020 年,WhatsApp 每天发送近 650 亿条消息,即每分钟 2900 万条。

2016 年考上大学后开始频繁使用 WhatsApp,于是想到了收集并可视化自己最近四年的聊天记录。我从 WhatsApp 上获得了大约 50 个文本文件,包括与朋友和家人的个人对话,以及一些群聊。

对于对代码不感兴趣的人,您可以欣赏这些图片。对于其他人,我也上传了我的 GitHub 资源库中的全部代码。

我在这个项目中使用了 Google Colaboratory ,以防你使用这个或其他平台,然后相应地改变文件的路径。

更新—我在 Github 中添加了 WhatsApp 聊天的情感分析代码和话题建模代码。

加载消息

文本文件中的消息格式为—{日期}、{时间}—{作者}:{消息}

2017 年 9 月 12 日,晚上 10 点 20 分——表格:孙娜兄弟……

纯文本文件必须以有意义的方式进行转换,才能存储在 Pandas 数据框中。我使用这个函数来获取数据帧。

def read(file):
    f = open('/content/drive/Drive/Whatsapp/{}'.format (file) , 'r')
    m=re.findall('(\d+/\d+/\d+,\d+:\d+\d+[\w]+)-(.*?):(.*)',
f.read())
    f.close()
    h = pd.DataFrame(m,columns=['date','am-pm','name','msg'])
    h['date']= pd.to_datetime(h['date'],format="%d/%m/%y, %I:%M%p")
    h['msg_len'] = h['msg'].str.len()
    h['date1'] = h['date'].apply(lambda x: x.date())
    return h

我把我所有的对话都保存在一个数据文件夹中,这样我就可以列出、加载它们,并把它们合并到一个数据框架中。

files = os.listdir('/content/drive/My Drive/Whatsapp')
lst = []
for file in files:
    history = read(file)
    lst.append(history)
history = pd.concat(lst).reset_index()

现在我们的数据帧已经准备好了,看起来像这样。

数据帧的屏幕截图

一些统计数据

在过去的四年里,我发了多少条信息?在过去的四年里,我和多少不同的人交谈过?

history_clean[history_clean['name']=='sachin']['msg'].count()
history_clean['name'].nunique()

就我而言,我发送了超过 58k 条信息,和超过 350 个不同的人交谈。我也检查了我的 AM-PM 信息频率 PM-43820,AM-14185。

数据探索

照片由安德鲁·尼尔Unsplash 上拍摄

这是本文最激动人心的部分—数据探索。让我们挖掘出这些数据试图告诉我们的所有迷人的故事。

# Create a subset of the dataframe with only messages i've sent
msg_sachin = (history_clean[history_clean['name']=='sachin'])
plt.figure(figsize=(25,8))
msg_sachin.groupby(['date1']).count()['msg'].plot()

这段代码将告诉我们这些年来发送的信息数量。

多年来发送的消息(由代码生成)

这个图非常令人印象深刻,因为它可以非常快速地识别出我是在家里度假还是在大学里。冠状病毒对我发短信模式的影响可以很快确定(我猜每个人都在经历同样的情况)。除此之外,几个月(5 月至 7 月和 12 月)的一些峰值可以通过我大学的暑假和寒假来证明。

我也觉得看到这些年来我的信息长度很有趣。

plt.figure(figsize=(25,8))
history.groupby(['date'])['msg_len'].mean().plot()

历年消息长度(由代码生成)

所以我试着找出那个异常值,我得到了这个-

数组([\ ' Google drive movies https://drive.google.com/drive/u/ 0/mobile/folders/0 b 6 fjkm qkynziltlwzhl 4 ajuwcfu Google drive 上的编程语言收藏— https://drive.google.com/drive/folders/0ByWO0aO1eI_ Mn 1 bed 3 vnruzenku 书籍阅读—https://drive。google.com/drive/folders/0b 09 qtt 10 aqv 1 sgx rvxbwymnis2m 书籍(小说)—https://drive.google.com/drive/folders/0B1v9Iy1jH3FXdlND[Udemy]数字营销课程全集 https://drive.google.com/drive/ folders/0b x2 vez 2n 3 qd 7s GxkejRhQmdKQlk 书籍阅读用……]

在此之后,我绘制了几个月来我的信息频率。

每月消息频率(由代码生成)

看到这种分布,我很惊讶。我想这也暗示了我在夏天经常聊天😂。

每小时消息频率(由代码生成)

下一个情节很有趣,讲述了你睡觉的时间。这是一天中几个小时的消息频率图(0 表示午夜)。这表明我不是一个夜猫子,更喜欢在 11 点或午夜后睡觉。

此外,从早上到中午,消息的数量会增加。这与一个人应该在这些时间多工作或多学习的事实相反😜。

每日消息频率(由代码生成)

接下来,我还绘制了一周中每一天的消息频率。嗯,看起来不管是周日还是周一,我每天聊天的量都差不多。

现在来看这篇文章最有趣的情节。

让我们画出表情符号

表情符号的完整代码在我的 GitHub 里。我用 Python 的表情库来画这个。您可以使用以下代码行安装该库

pip 安装表情符号—升级

我在过去 4 年中使用的表情符号(由代码生成)

好吧,先说说我第二常用的表情符号💣。我通常在引用电影“Wasseypur 的帮派”中的一些对话时使用它,或者有时没有任何理由。但是我从来没有意识到我对这个表情符号如此着迷💣

此外,我很高兴地看到,显然,我的生活充满了笑声,惊喜和炸弹!

作为本文的延伸,我在我的 Github 中添加了 WhatsApp 聊天的情感分析和话题建模。对 NLP 感兴趣的可以查一次。

结论

看起来,这种分析在回答一些问题的同时,也提出了许多可以进一步解决的新问题。

你觉得这些见解有用吗?或者你对我错过的一些有价值的见解有什么建议?请随意在下面添加您的评论。

您也可以在 Linkedln 上添加我

创建高效的数据管道

原文:https://towardsdatascience.com/youre-importing-data-wrong-c171f52eea00?source=collection_archive---------14-----------------------

为什么您的数据管道可以快速发展

使用 TensorFlow 数据集和tf.data轻松将原始数据放入模型

来自 Pexels 的【energepic.com】T2 的照片

让我们弄清楚,现有的数据集是不够的

虽然大多数机器学习程序员从 MNIST 或 CIFAR-10 等常见的开源数据集开始,这一切都很好,但要扩展你的视野,解决问题,你需要超越这些,获得自己的数据。虽然收集数据可能太难,也可能不太难,但大多数人发现很难将这些数据用于训练。这主要是因为有大量的中间步骤,如格式转换(通常用于计算机视觉)、标记化(用于 NLP)以及数据扩充、混洗等一般步骤。

为了使这一过程更容易,让我们首先了解准备数据集的过程。

数据管道中涉及的步骤

图片来自 Pixabay

  • 选择要使用的数据集或原始数据后,从压缩格式中提取数据集。提取的数据的格式在下一步中起着重要的作用。
  • 将您的数据转换为适合深度学习模型的格式,即转换为数字形式,并应用所需的预处理步骤,如数据扩充、洗牌和批处理。
  • 只需您的数据库加载到工作区,并在您的机器学习模型中用于训练和测试。

这种 ETL 方法对于所有数据管道都是通用的,ML 管道也不例外。

使用单独的框架完成这些步骤可能会很乏味,这正是 TensorFlow 数据集或 TFDS**tf.data**模块适合的地方。让我们看看如何!

先决条件

知识前提

  • 熟悉 TensorFlow 或 Keras 框架,
  • Python 和安装库的知识。

所需的库

对于代码,你将需要下面的库~

  • tensorflow
  • tensorflow-datasets

如果你使用自定义数据集,你可能还需要pandasnumpy

完整的数据管道

收集数据

所有数据管道的前一步是收集数据,这可能很难,取决于资源的可用性。幸运的是,TFDS 确实可以帮助我们轻松快速地完成这一步。只需从 TFDS 广泛的数据集集合中选择符合您要求的数据集。注意数据集的名称、版本和分割,因为稍后我们将在提取步骤中使用它们。如果您已经找到合适的数据集,请跳到提取步骤!

[## 张量流数据集

适用于音频、图像、对象检测、NLP 等广泛应用的大型数据集集合。

www.tensorflow.org](https://www.tensorflow.org/datasets/catalog/overview)

然而,如果你想使用自定义数据集(由于没有找到一个合适的在线或其他方式),不要担心!使用tf.data导入数据集非常简单!

从 NumPy 数组

将您的数据放入两个数组,我将它们分别命名为featureslabels,并使用tf.data.Dataset.from_tensor_slices方法将它们转换成片。您也可以为两者制作单独的tf.data.Dataset对象,并在model.fit功能中分别输入。

从 CSV 文件

对于从 CSV 文件导入,只需提供文件路径和基本事实标签值所在列的名称。

从文本文件

使用tf.data.TextLineDataset可以将任何文本文件转换成数据集,这为文本数据集提供了许多选项。

如果你有任何其他格式,检查下面的链接使用它们作为数据集。

[## tf.data:构建 TensorFlow 输入管道| TensorFlow 核心

通过此链接查找从输入数据创建数据集的多种方法。

www.tensorflow.org](https://www.tensorflow.org/guide/data?hl=en#reading_input_data)

ETC 时间!

合作笔记本

这里有一个 IPython 笔记本,在快速训练的合作实验室上,所有这些代码都在这里。这是一种我称之为“动态笔记本”的笔记本,因为它在执行大量数据集和用例方面具有多功能性。一定要去看看!

[## TDSTFData.ipynb

适用于任何计算机视觉数据集的动态笔记本,现在就来看看吧!

colab.research.google.com](https://colab.research.google.com/drive/14dJXqs3nWXdeUMIwN5xVxfqYKERObWgV?usp=sharing)

提取

对于那些已经从 TFDS 找到合适数据集的人来说,这一步相当简单,只需要几行代码。例如,我将使用加州理工学院 2010 年鸟类数据集对 200 个类别进行图像分类[2]。选择这个数据集是因为这个数据集中的图像大小不一致,而且我想进加州理工大学读本科😁

很简单,不是吗?

运行上述代码后,您将看到类似于上图的输出进度线…

现在,如果您转到输出中显示的目录,在我的例子/root/tensorflow_datasets/caltech_birds2010/0.1.1中,您将能够看到 TFRecord 文件,这是一种适用于大型数据集的高效二进制文件格式。此外,如果数据集需要,您可能会看到多个碎片。

dataset_info.json文件是一个有趣的文件,因为它包含了大量关于数据集的信息,如引用、描述、分割、URL 等。这对于写研究论文和阅读材料来说很方便。

features.json是用张量流术语描述数据集模式的文件。这允许 tfds 对 TFRecord 文件进行编码。

改变

这一步通常需要大量的时间和代码。当使用我们已经导入数据集的tf.data.Dataset类时就不是这样了!第一步是用Dataset.map方法快速地将图像调整到合适的大小,之后是常规的转换,最后是将标签转换成类别。

助手功能

  • def resize(image, label)将不一致的图像尺寸改变为共同的(224,224,3)

  • def one_hot(image, label)将标签转换成分类形式。

转换

代码中完成的预处理步骤是~

  • 使用resize辅助函数调整数据集的大小,
  • 通过除以 255 来归一化图像值,
  • 打乱数据集,
  • 批处理数据集,
  • 最后,将标签转换成分类编码或一键编码。

创建模型

我创建了一个普通的深度 CNN,这里没有什么太花哨的…注意这里的input_shape。我在编译亚当优化器和分类损失。

加载模型

我们可以简单地在数据集上运行model.fit。注意我们没有为model.fit方法的y参数输入任何东西,因为y已经在数据集中了。我已经在图表上绘制了纪元和精确度,并最终以 h5 格式保存了模型。

我们完成了,谢谢你!

您刚刚使用 TensorFlow 数据集和tf.data训练了您自己的高效数据管道🎉

随着最先进的模型简化为几行代码,在使这些数据管道更好、更快和更通用方面还有改进的余地。随着我们的模型在速度和能力上的提高,我们需要我们的管道在这两方面都跟上。

尽管本文主要讨论了计算机视觉分类问题,但张量流数据集和 TFDS 的用途远远不止于此。

同样,您可以在 IPython 笔记本中轻松检查所有代码,我强烈建议您这样做。

非常感谢你阅读这篇文章!

参考

[1]金玛,迪耶德里克&巴,吉米。(2014).亚当:一种随机优化的方法。学习表征国际会议。

[2]韦林德 p,布兰森 s,塔米 t,华 c,施罗夫 f,贝隆吉 s,佩罗娜 p .加州理工 -UCSD Birds 200" 。加州理工学院。CNS-TR-2010–001。

你在策划错误的事情

原文:https://towardsdatascience.com/youre-plotting-the-wrong-things-3914402a3653?source=collection_archive---------14-----------------------

更聪明的 EDA 的技巧

快,告诉我,X1 能很好地预测 Y 吗?

正确答案是“不知道。看情况。”如果你很肯定地回答了是/否,那么我很抱歉地说,你对统计学有一个致命的误解。X1 和 Y 之间的相关性没有告诉我们任何关于预测能力的信息。

除了检测数据质量问题之外,绘制变量之间的关系图没有什么价值。如果有什么不同的话,它会导致人们得出不必要的错误结论。然而,这是探索性数据分析中的一个常见步骤(为什么???).

本文将解释为什么应该跳过这一步,以及您可以做些什么。

因果机制

" X1 是预测 Y 的好方法吗?"含蓄地问“如果我们加上 X1,模型会试图适应随机噪声吗?”答案是否会随着其他变量的变化而变化还不太明显。Pairs plots 天真地看待两个变量,好像其他变量都不存在。

事实证明,答案取决于(通常未知的)数据生成过程,可以使用因果图来表示。下面是一个有三列的数据集的一些可能的因果图,其中 X → Y 表示“X 引起 Y”:

u 是未观察到的变量。还有许多其他可能的图表,但我们将用这四个作为例子。如果你想更多地了解这些图表是如何工作的,请跳到我上一篇关于因果关系的文章的后三分之一。

X1 作为的预测器只有在 X2 不在的时候 才有用

上面的两个因果图表明,当我们有 X2 时,X1 作为预测因子是没有用的。从 X1 到 Y 的唯一路径只有通过 X2;一旦我们知道了 X2,X1 就变成了纯噪声。然而,如果我们没有 X2,那么 X1 是一个很好的预测!

X1 作为预测值总是有用的

上面这两个因果图表明,不管 X2 如何,X1 总是一个有用的预测因子,因为从 X1 到 Y 的信息流不经过 X2。

在所有这些图的中,X1 与 Y 相关!这种相关性没有告诉我们 X1 作为预测因子的有用性。

多重共线性检查从因果角度看也很愚蠢;最后一张图使 X1 和 X2 相关,但两者都是有用的预测指标!

没有 X2,X1 是一个很好的预测因子,尽管没有因果关系

此外,请记住预测和因果推断是不同的任务。看这张图表。如果我们的目标是预测,那么在没有 X2 的情况下,X1 应该用来预测 Y。如果我们的目标是因果推理,那么 X1 应该而不是在没有 X2 的情况下使用。本文主要关注预测模型。

我使用上面的图表生成了数据。看看如果我回归 Y~X1 会发生什么:

这表明 X1 是一个很好的预测因子。但是请记住,数据生成过程表明,当我们有 X2 时,X1 是无用的。在控制 X2 之后,查看 X1 中包含多少信息:

我们通过回归 Y~X2 并绘制相对于 X1 的残差来得到这个图,通常称为“增加变量图”或“部分回归图”。几乎没有留下任何信息。X1 变成纯噪声。

然而,这并不而不是意味着 X1 对 y 没有影响。X1 确实有因果关系,但它完全由 X2 介导。

回归输出取决于很多因素。有可能 X1 最终成为重要的一个,或者两者都是。在这种情况下,如果我们观察 X2 的部分回归图(在控制 X1 之后):

我们应该看到信息的痕迹,表明 X2 属于这个模型。

除了最简单的问题,我们很少知道“真正的”因果图。与其猜测哪些变量应该或不应该出现在回归模型中,不如保留所有的预测值,并把它们扔进套索的嘴里?我们有通过正则化自动选择变量的算法。在本例中,LASSO 将系数 0 指定给 X1:

介绍性回归课程讲授使用 AIC/BIC/F/Adj. R 的前向/后向选择,以及基于 VIF 移除预测因子。好吧,当你走出考场的时候,把这些都忘掉吧,因为它们在实践中毫无用处。您无法在这些系数上计算有效的 p 值,并且系数的幅度会太大(过拟合)。相反,或者咨询领域专家来构建一个因果 DAG 或者使用交叉验证正则化。

掩饰

新数据集!现在告诉我,X1 能很好地预测 Y 吗?

如果你回答“我不知道”,很好!X1 和 Y 是不相关的,但是一旦我们控制了 X2,X1 就成为 Y 的一个很好的预测因子:

这一次,因果结构就是所谓的倒叉:

如果我们不知道 X2,X1 和 Y 确实是独立的:

但是一旦我们知道了 X2,X1 给了我们关于 Y 的信息:

再次请参考我之前的文章更详细的解释。这篇文章的目的只是为了表明,将变量彼此对立起来是荒谬的。

需要明确的是,X1 对 Y 没有任何因果关系。但是,它是 Y 的一个很好的预测因子,如果目标是纯预测能力,则应该包括在模型中。

虽然第一个例子相对来说是良性的,但是当分析师因为没有相关性而从不尝试将 X1 放入模型时,这个例子可能是灾难性的。或者,同样糟糕的是,他们做了相关性测试,得出 X1 和 Y 完全不相关的结论:

永远不要永远不要 使用相关性或曲线手动选择回归变量。要么咨询领域专家来绘制因果 DAG,要么让它正规化——LASSO 可以比你我做得更好。

转换

从这两个例子中,应该很清楚残差是信息的使者

新数据集!X1 是 Y 的好预测吗?

正确的答案是,“我不知道。”

正如我们到目前为止所了解的,这种类型的视觉化几乎是没有意义的。那么我们应该用什么呢?当然是残差 vs 变量!这里我们回归 Y~X1+X2,并检查每个预测值的残差:

我们看到我们需要将 X1 特征工程到我们的回归模型中。这在变量与变量图中几乎看不到,但一旦我们检查残差,就会一目了然。

要获得关于 Y 的信息,您需要根据残差回归拟合值。在这种情况下,只能看到来自省略的 X1 的弱信号:

你从 pairs 图中看到的任何必要的变换也可以通过残差图看到,但是反过来就不正确了。你可以通过将所有变量放入一个回归中,并检查单个变量的残差来进行 EDA。

最后

希望你已经知道传统的对图/关联热图对于分析数据几乎没有意义。相反,依靠残差和拟合系数来查看因变量和自变量之间的关系。

有些人可能会反对“但是我们需要检查变量的分布!”实际上,,除了检查数据质量问题,我们真的不关心,例如,丢失的数据是否编码为 9999?数据被正确审查了吗?是否存在数据泄露?(尽管最后一项出现在好得令人难以置信的评估指标中。)

回归对任何变量的分布绝对没有假设或限制。假设是在残差上,甚至常态部分往往都无关紧要。

我最讨厌的一件事是,人们抱怨他们的预测值不是正态分布的,log/Box-Cox 变换不能使预测值成为高斯分布。然后他们开始抱怨统计因为不切实际的假设而不切实际,而他们抱怨的假设根本不存在。绝对触发。

反正 EDA 对变量不好,EDA 对残差好

用 P 值认识这些问题

原文:https://towardsdatascience.com/youre-probably-misusing-the-p-value-fef44d665955?source=collection_archive---------31-----------------------

以及为什么 P 值小于 0.05 并不重要

塞巴斯蒂安·赫尔曼在 Unsplash 上的照片

简介

p 值是频数统计中的一个重要概念,通常在统计学导论课程中讲授。

不幸的是,这些课程要么在解释 p 值可以(和不可以)做什么方面做得不好,要么公然宣传与 p 值在因果推理中的作用有关的虚假宣传。

这导致了很多本科生,甚至是应该更了解的学者,在研究中做出不正确的主张,都是因为发现 p 值小于 0.05。

本文的目标是澄清围绕 p 值的神话,并希望鼓励数据科学家在他们自己的项目中超越 p 值。

P 值是多少?

对 p 值的任何准确解释都必须首先讨论零假设显著性检验(NHST)。

NHST 是一个统计程序,研究者通过它陈述两个假设:一个零假设和一个替代假设。

零假设表明给定的处理对目标变量没有影响。另一个假设陈述了相反的情况;也就是说,给定的处理不会影响目标变量。

例如,假设我们想确定最低工资法是否会导致更高的失业率。

无效假设和替代假设可能如下:

零假设:最低工资法不影响失业率。

替代假设:最低工资法增加了失业率。

通常,研究人员想要拒绝零假设。(拒绝零假设会增加替代假设的可信度)。

然而,我们应该如何拒绝零假设呢?

这就是 p 值的来源。

p 值是一个介于 0 和 1 之间的数字,它告诉研究人员在假设零假设为真的情况下观察到某个值的概率。

假设我们想检验我们的最低工资假说。我们收集了美国城市的随机样本——有些城市有最低工资法,有些没有——发现有最低工资法的城市的失业率平均比没有最低工资法的城市高半个百分点。

这是自由市场资本主义的胜利吗?我们应该废除全世界的最低工资法吗?

不完全是。

在标准的学术研究中,大于 0.05 的 p 值通常不被认为是统计显著的——一个用来掩盖任意分界点的花哨短语。

假设我们得到 p 值为 0.78。也就是说,如果我们假设零假设是真的,那么有 78%的可能性,我们会看到有最低工资法的美国城市和没有最低工资法的美国城市之间有半个百分点的差异。

如果我们试图将这些结果提交给学术期刊,那么期刊的编辑可能会嘲笑我们回到 Medium(当然是开玩笑,因为阅读 Medium 的人比阅读美国政治科学杂志— 的人多,但我离题了)。

在标准的学术研究中,大于 0.05 的 p 值通常被认为不具有统计显著性一个用来掩盖任意分界点的花哨短语。

所以,p 值是 0.78。太糟糕了。我们如此努力的研究被证明是毫无意义的。

马科斯·保罗·普拉多在 Unsplash 上拍摄的照片

但是,等等!

也许任意截止点的一个优点是它防止虚假研究进入著名的学术期刊。

是吗?我们会回来的。

P 值的(许多)问题

1) P 黑客

我们刚刚被我们最喜欢的学术期刊拒绝,因为我们的 p 值太高了。

然而,我们对我们的结果有把握。我们是在弗里德曼、格林斯潘和伯南克的教导下长大的。我们知道最低工资法会对劳动力市场造成巨大破坏。

所以,我们回到我们的研究,看看我们是否可以降低我们的 p 值。首先,我们将更多的城市纳入研究:来自加拿大、中国、巴西、欧洲和俄罗斯的城市。因为 p 值与样本量成负相关,所以增加样本量会降低我们的 p 值。

其次,我们决定改变我们的模式。我们控制了可能对城市失业率产生影响的特征——人口规模、地理位置、税率等。还有一些与失业率有着更难以解释的关系的特征,比如城市中星巴克的数量。一般来说,增加模型的复杂性可以降低 p 值,因为我们的模型可以解释样本中更多的随机性。

现在我们的 p 值是 0.1。好一点,但还是没出息。

最后,我们改变我们的测试统计。也许我们使用了学生的 t 检验,但现在我们决定使用卡方检验和…

p 值= 0.049。

完美的。我们的结果现在具有统计学意义。学术期刊决定发表我们的研究。

上述程序被统计学家亲切地称为“p hacking ”,是一种操纵数据分析过程的形式,其程度之深,掩盖了比它提供的更多的信息。

作为一名研究人员,您不能:

  1. 报告称,只有当您将非美国城市包括在内时,您的测试才变得“具有统计学意义”
  2. 探索您使用的其他模型(这些模型在统计上不显著)
  3. 报告你的结果只有卡方检验有统计学意义;学生的 t 检验产生了无统计学意义的结果

不幸的是,p hacking 在学术研究中普遍存在,它通常会导致难以重现的结论。(如果一篇研究文章报告 p 值为 0.049,你可以合理地确定该研究人员进行了一些 p 黑客攻击)。

2) P 值不能说明事实

反正你的 p 值现在是 0.049。

万岁!

如果零假设是真的,那么我们有 4.9%的机会观察到有最低工资法的城市和没有最低工资法的城市之间的失业率差异 0.5 个百分点。

据应用研究人员称,这意味着我们现在可以安全地 拒绝 的无效假设。也就是说,我们已经证明最低工资法对失业率没有影响。

这是许多应用研究人员出错的地方。

低 p 值本身并不能说明零假设(或替代假设)的真假。

不相信我?

以下是美国统计协会(ASA)对这个话题的看法:

p 值不衡量所研究的假设为真的概率,也不衡量数据仅由随机机会产生的概率。

如果零假设为真,观察结果将出现的 4.9%的概率不转化为零假设真的 4.9%的概率。

根据 p 值的定义,这个结论应该是显而易见的:

p 值是一个介于 0 和 1 之间的数字,它告诉研究人员在假设零假设为真的情况下观察到某个值的概率。

我们测量的是观察某个值的概率,而不是假设为真的概率。

我们已经看到操纵 p 值是多么容易:

  1. 增加样本量
  2. 使我们的模型复杂化
  3. 使用不同的测试统计

然而,p 值作出了许多其他假设,这些假设可能不适用于当前的研究。

例如,p 值假设我们正在比较相似的组。也就是说,美国城市和中国城市相似。这是一个不太可能的假设,即使我们的模型过于复杂。首先,中国城市的政治体系与美国城市截然不同。我们的模型无法量化这种差异。

同样,p 值假设待遇(最低工资)是随机应用的。

当然,这不是真的。一个美国城市有最低工资而另一个没有,这一事实与随机性关系不大,更多的是与政治和经济差异有关。

3)低 p 值并不意味着强烈的影响

假设我们再次篡改了我们的模型。现在,我们得到 p 值为 0.004。如果我们假设零假设是真的,那么现在只有 0.4%的可能性,我们会观察到有最低工资法的城市和没有最低工资法的城市之间有 0.5 个百分点的差异。

暂时,让我们忽略 p 值的所有其他问题,让我们假设我们的结果代表地面真理。

谁在乎呢。

我们是否应该阻止数百万人获得生活工资,因为这可能会使失业率上升半个百分点?

通常,低 p 值掩盖了预测的因果影响微不足道的事实。美国广告标准局写道:

科学结论和商业或政策决策不应仅仅基于 p 值是否超过特定阈值

不幸的是,许多应用研究人员忽略了因果影响,并使用小 p 值来提出政策建议。

回到我们的最低工资的例子,仅仅考虑 p 值来决定一项政策是不正确的。我们必须采取更全面的方法。

所以,p 值很烂。我们做什么呢

我们已经展示了 p 值是如何误导人的。如果不是因为它几乎被普遍接受为因果关系的充分指标,这不会是一个大问题。毕竟,许多统计数据本身可能会产生误导。

因此,这就引出了一个问题:我们应该停止报告 p 值吗?

2015 年,基础和应用社会心理学【BASP】期刊禁止论文报道 p 值——在我看来,这是一个激烈的举措。

我认为解决办法是教育人们使用(和误用)p 值。

p 值从来没有打算成为统计研究的存在理由。相反,当罗纳德·费雪——频率主义统计学的教父——在 20 世纪 20 年代开发 p 值时,他打算把它作为因果分析中的一个步骤。

尽管许多人对它有误解,p 值仍然提供了一些有趣的信息。它必须与其他统计数据、领域知识和(一点)常识结合使用。

笔记

  1. 最低工资法例子的另一个假设也可以写成“最低工资法影响失业率”;然而,正如我在文章中所写的,劳动经济学家通常对另一种假设感兴趣。

文献学

[1]努佐·里贾纳(2014)《统计误差》 Nature Vol. 506。

[2] Head ML,Holman L,Lanfear R,Kahn AT,Jennions MD (2015)《科学中 P-Hacking 的程度和后果》。PLoS Biol 13(3): e1002106。【https://doi.org/10.1371/journal.pbio.1002106

[3] Cumming,Geof(2015)《p 黑客入门》。方法空间https://www.methodspace.com/primer-p-hacking/

[4]罗纳德·l·瓦瑟斯坦和妮可·a·耶戈(2016)“美国统计学会关于 p 值的声明:背景、过程和目的”,《美国统计学家》,70:2,129–133,DOI:10.1080/00003035486

[5]卡尔彭,塞缪尔·C(2017)“P 值问题”,美国药学教育杂志,* 81:9,93*

你说的是实话,但你的想象不是

原文:https://towardsdatascience.com/youre-telling-the-truth-but-your-visualization-isn-t-eef69298f1af?source=collection_archive---------35-----------------------

关于视觉完整性的一课

马库斯·温克勒在 Unsplash 上的照片

为什么要创造一个歪曲事实的形象呢?问得好。

虚假陈述可能有多种原因,但最主要的一个原因是:为了迫使观众做出某个特定的行为,在观众内部制造一种情绪反应。换句话说,可视化创建者对发布他们的议程比对精确描述数据更感兴趣。

现在,不要误解我,有很多时候事实数据支持一个人的潜在意图,但当它不支持时,一个人不应该在视觉上夸大它,使它确实如此。

综上所述,我们知道数字不会说谎,但是数字的呈现方式会极大地影响得出的结论。

在讲述一个当今的例子之前,我想先给你们介绍一下耶鲁大学的教授爱德华·塔夫特。早在 1983 年,他写了一本名为的书,定量信息的可视化显示,这本书对当今的统计界产生了深远的影响。《美国统计组织杂志》甚至称之为“迄今为止对图形研究的最重要贡献”

在这本书里,塔夫特介绍了一个寿命因子的概念。简而言之,这个因素的目的是计算可视化在表示其底层数据时的诚实程度。理想情况下,lie 因子应该是 1.0,因此任何其他值(除了较小的方差之外)都意味着可视化在表现底层数据方面存在一些不匹配。

寿命因数定义为:

接下来,数据中效应的大小定义为:

这还有点模糊吗?我的猜测是肯定的,因此当前的示例应该有助于您轻松理解这一重要指标。

在《华尔街日报》最近发表的一篇文章中,展示了一张图表,旨在说明 2020 年和之前年份之间各种原因导致的死亡的增加。在详细讨论图表之前,您认为其创建者的潜在意图是什么?

资料来源:国家卫生统计中心

我认为他们想让你认为 2020 年 4 月死亡人数会大幅增加。不仅仅是增加,而是显著的增加。此外,这张图出现在一篇关于新冠肺炎的文章中,这也可能是他们想让你认为这种病毒本身非常致命,尽管它实际上的死亡率在 0.2%到 0.4%之间

现在,让我们通过计算它的谎言因子来研究这个图表,看看它在视觉上如何准确地表示基础数据。

为了计算图形中效果的大小,我们首先测量从 X 轴到蓝色和褐色线的像素距离。蓝色线条的高度为 352 像素,而棕色线条的高度为 92 像素。

图形中显示的效果大小

接下来,我们计算数据中影响的大小。在这里,我们观察到,在 4 月 11 日这一周,2020 年记录了 71,784 例全因死亡,而同一周 2017-2019 年的平均值为 55,647 例死亡。

数据中显示的效果大小

最后,我们计算谎言因子为:

呀!看来我们关于图表歪曲数据的预感是正确的。可悲的是,这种事情发生得太频繁了。在这种情况下,用来误导观众的技巧是从 50,000 而不是 0 开始绘制图形。

将来,当你看到各种各样的视觉化图像时,请记住谎言这个因素。此外,问自己这些问题:

  • 轴线从哪里开始?它们是从 0 还是其他数字开始?
  • 这个图表是三维的吗?(我们的大脑很难理解这些)
  • 有不同大小的物体被比较吗?

这些问题,以及达雷尔·赫夫写的本书中概述的中的许多问题,在消化和创作图形时问自己是很重要的。

请记住,数字不会说谎——人会说谎,而且人们有各种各样的理由这样做。做一个能够正确描述你的数据的可视化的人,同时也要意识到其他人可能会试图用他们的数据误导你。

异常检测的 z 分数

原文:https://towardsdatascience.com/z-score-for-anomaly-detection-d98b0006f510?source=collection_archive---------5-----------------------

内森·希维利在 Unsplash 上拍摄的照片

小块数据科学

大多数时候,我会写一些关于数据科学主题的较长的文章,但最近我一直在考虑围绕特定的概念、算法和应用程序写一些小文章。这是我在这个方向上的第一次尝试,希望人们会喜欢这些作品。

在今天的“小话题”中,我写的是在异常检测背景下的 Z 分数。

异常检测是一个识别需要检查的意外数据、事件或行为的过程。这是数据科学中一个成熟的领域,有大量算法可以根据数据类型和业务环境来检测数据集中的异常。Z-score 可能是最简单的算法,可以快速筛选候选人进行进一步检查,以确定他们是否可疑。

什么是 Z 分数

简单地说,Z 得分是一种统计度量,它告诉你一个数据点离数据集的其余部分有多远。用一个更专业的术语来说,Z-score 表示一个给定的观察值距离平均值有多少标准偏差。

例如,Z 值为 2.5 意味着数据点距离平均值有 2.5 个标准偏差。由于它远离中心,因此被标记为异常值/异常值。

它是如何工作的?

z 得分是一种参数测量方法,它采用两个参数—平均值和标准差。

一旦计算出这两个参数,就很容易找到数据点的 Z 值。

注意,平均值和标准偏差是针对整个数据集计算的,而 x 代表每一个数据点。这意味着,每个数据点都有自己的 z 值,而均值/标准差在任何地方都保持不变。

示例

下面是 Z-score 的 python 实现,带有几个样本数据点。我会在每一行代码中添加注释来解释发生了什么。

# import numpy
import numpy as np# random data points to calculate z-score
data = [5, 5, 5, -99, 5, 5, 5, 5, 5, 5, 88, 5, 5, 5]# calculate mean
mean = np.mean(data) # calculate standard deviation
sd = np.std(data)# determine a threhold
threshold = 2# create empty list to store outliers
outliers = []# detect outlier
for i in data: 
    z = (i-mean)/sd # calculate z-score
    if abs(z) > threshold:  # identify outliers
        outliers.append(i) # add to the empty list# print outliers    
print("The detected outliers are: ", outliers)

注意事项和结论

如果你研究这些数据,你会注意到一些事情:

  • 有 14 个数据点,Z-score 正确检测到 2 个异常值[-99 和 88]。然而,如果您从列表中删除五个数据点,它只检测到一个异常值[-99]。这意味着您需要有一定数量的数据大小,Z-score 才能工作。
  • 在大型生产数据集中,如果数据呈正态分布(也称为。高斯分布)。
  • 我使用了一个任意的阈值 2,超过这个阈值,所有的数据点都被标记为异常值。经验法则是使用 2、2.5、3 或 3.5 作为阈值。
  • 最后,Z-score 对极值很敏感,因为均值本身对极值很敏感。

希望这有用,请随时通过 Twitter 联系。

斑马探测器——您的第三个端到端 CNN

原文:https://towardsdatascience.com/zebra-detector-your-third-end-to-end-cnn-in-5-minutes-3ffea91d5566?source=collection_archive---------60-----------------------

罗恩·多芬在 Unsplash 上的照片

第三 CNN?

这是我在自己动手 CNN 模型系列的第三篇文章。像往常一样,格式将保持不变。我给你一个 Colab 文件(非常好用),你必须在没有任何条件的情况下运行它,然后才能继续。原因是,一旦你自己运行它,你会变得更加重视这个问题,你会得到更深刻的见解。

你可以在这里查看我以前的文章:

所以,事不宜迟,让我把 Colab 文件交给你🚀。这不是我的作品,而是从各地抄袭来的。我在这里做的唯一一件事是确保它在 Colab 设置中运行良好(令人惊讶的是,这很难做到)。但是,尽管如此,它现在工作得很好,唷!

请随意上传您的图像并检测它们!现在,这个文件看起来可能有点吓人,但实际上并不是这样。像往常一样,我们先从理论开始,稍后将讨论实现细节。此外,根据我以前的文章,我会尽量保持简短和甜蜜。

分类 Vs 定位 Vs 检测

首先,我们所说的检测实际上指的是什么?

  • 分类——在图像中找到主要项目并标记它。
  • 定位——找到图像中的主要项目,标记它,并找到它的位置。
  • 检测—检测图像中的所有项目,找到它们的位置,并标记它们。

来源

目标检测

对象检测看起来很复杂,但实际上并不复杂。它只是建立在我们已经了解的 CNN 的基础上。因此,我们早期的细胞神经网络有一些缺点,由于它不适合对象检测。让我们试着找出这些问题,你自己会建议一些调整来克服它们。在这个过程中,我们将理解令人生畏的物体探测器背后的直觉。

请记住一件事——我们的目标不仅仅是对图像进行分类,还要找到它的位置。事实上,图像中的所有项目都应该被检测、标记和定位。

缺点 1 —输出层

一些快速的问题!

  • 我们在 手写数字分类器 中有多少个输出节点?
  • 我们应该如何在输出中输出被检测项目的位置?

想想吧!这不是火箭科学!!🤔
好了,回答时间!!

之前我们有 10 个输出节点。原因是,只有 10 个标签是可能的(0–9)。现在,如果我们除了标签还想要位置,我们应该怎么做?

想象一个假想的多边形(中心:(x,y),宽度:w,高度:h )可以包围那个数字。现在,我们只需要输出矩形和万岁的坐标,我们也将有本地化信息。仅此而已!因此,如果你会看到,我们刚刚在输出层添加了一些信息,以获得位置信息。

作者图片

上一次输出:【0,0,0,1,0,0,0,0,0】 新输出:【0,0,0,0,1,0,0, x,y,h,w

因此,这里前面的输出表示我们的输出数组的一位热编码,因此只有 3 是 1,其他的输出是 0。物体探测器会再增加 4 个坐标来让我们知道它的位置。瞧啊。所有其他反向传播将一如既往地工作(因为只多了 4 个输出)。

缺点 2-多重检测的输出层

现在,当一幅图像只有一次检测时,我们之前所做的工作是有效的。当一个图像可以有多个检测时,我们该怎么办?!

想想吧!?我们只需要一种方法来解决如何在输出中发送所有检测的多个坐标。

  • 上一次输出:【0,0,0,1,0,0,0,0,0,0】**
  • 你在上面看到了什么?一个有 10 个元素的数组?还是大小为 10 的[11]矩阵?你想想,个位数不过是个[11]矩阵,对吧?
  • 我们能不能用这种新的可视化方式来添加我们的位置信息?

是的,你认为它是正确的,如果我们有一个[10 * 5]矩阵,我们可以很容易地使用它来容纳所有类别的位置信息。

有趣的事实!实际上是[510]矩阵还是[11510]矩阵?坚持这个想法。

作者图片

缺点# 3-多个相同检测的输出层

上面的方法可以,但是如果一个图像中有两个 3 呢?我们的输出层将再次失败。有人可能会说,我们把上面的矩阵更新为[910]吧,多容纳一个 3。但是,它没有尽头。一个图像可以有 100 个相同的标签。我们需要想点别的!*

如果找不到答案,那就改问题!

好吧,这个问题什么时候来?当你有一个巨大的图像,里面有很多物体,对吗?让我们把图像分成更小的块来彻底解决这个问题。

因此,对于每个图像块,将有一个[510]矩阵。比方说,我们创建了一幅图像的 N 个块,因此我们在输出中将有[ N 510]个矩阵。*

作者图片

有趣的事实——你刚刚学会了 YOLO(你只看一次)!!🚀

缺点 4——CNN 将如何处理这些信息?

仔细想想,这里没什么新鲜的。输入图像是一样的,检测数字的内核也是一样的。因此,一切都将以完全相同的方式工作。

这里唯一不同的是输入图像的大小。比原来的层能处理的大一点。因此,由于尺寸较大,它将有大量的输出。

所以,早些时候 CNN 产生了 10 个输出。这一个将产生更多,因为我们有一个更大的图像,但卷积层的数量保持不变。这就是我们有意要做的。因为现在输出信息增加了(也包括仓位)。

来源

缺点 5——一个项目分成多个块

新的解决方案会带来一系列新的问题。当我们将一幅图像分成多个更小的块时,一幅图像可能存在于多个块中。在这种情况下,一个项目可能会被检测两次。如何解决这个问题?

当有 100 个学生想成为班上的第一名时,你通常如何解决这个问题?你要求他们证明他们的可信度。哪个分数最高,谁就是冠军。一模一样。检测到最高概率和最佳定位位置的任何一个组块都应该得到该项目。简单!

是的,在检测之后,将会有一层来宣布该物品在战斗块中的获胜者。在 YOLO,有一个概念叫做并上交集,用于检测战斗块的可信度。如果你愿意,你可以在网上了解更多。

顺便说一句,你刚刚学习了非最大抑制🚀

缺点 6——一个块中有多个项目

如果一个 chunk 需要检测多个类怎么办?我们来了解一下什么时候能发生这种情况?理想情况下,由于块的尺寸较小,这种情况不应该发生。但是,如果我们在一个图像中有重叠的项目呢?这种情况很有可能发生,对吗?

但是,多田!我们已经在我们的缺点#3* 中解决了。我们的每个块已经能够检测所有的类。很酷很强大,对吧?!*

履行

Colab 文件应该运行得很好。这可能有点令人望而生畏,但是当您阅读代码时,您会意识到这只是:

  • 创建一个巨大的多层 CNN
  • 从预先训练好的模型中加载砝码
  • 在样本图像上测试它(在我的例子中是斑马)
  • 然后剩下的代码只是创建一个框来帮助你可视化本地化输出

我强烈建议上传不同的图片,然后玩玩。还有,所有的实现逻辑都是受这个这个的启发。

这就是物体探测器的全部内容。我只是有意提到了 YOLO。其他技术将覆盖某一层。

零起点学习字母字符

原文:https://towardsdatascience.com/zero-shot-learning-the-alphabetic-characters-an-experiment-with-code-d1a0f23f4b4c?source=collection_archive---------48-----------------------

能否识别训练中未提供的字母字符?

在这篇文章中,我想解释并实际演示一个被称为零射击学习的机器学习领域,我发现这真的很有趣。让我们先简单描述一下它到底是什么:

零射击学习是一种识别类别的方法,这种方法在训练中没有观察到。

与传统的监督学习方法相比,传统的监督学习方法依赖于每个类别的大量示例,零射击学习的主要思想是基于从观察到的类别到新看到的类别的语义转移

想象一下,你这辈子都没见过字母“H”。如果我告诉你它是由两条垂直线和中间的一条水平线连接而成的呢?你能认出它吗?

15 个手动设计功能中的 10 个。图片作者。

这种语义转换的关键是将类别编码为语义空间中的向量。这对于培训和测试类别都是需要的,并且可以以监督或非监督的方式来完成。

监督方式将通过提出一些特征来手动注释类别,例如,狗=有尾巴、有皮毛、有四条腿等。并将它们编码成类别向量。这些特征也可以取自给定领域中已经存在的分类法。

一种不受监督的方式是对类别名称使用单词嵌入。这是因为单词嵌入已经根据类别名称出现在文本中的上下文(例如,在维基百科语料库中)捕获了类别的语义。

实验

我决定使用监督的方式,自己创建类别向量,这样我就可以更深入地了解最终的模型。因此,我开始寻找一个具有合理数量类别的任务,对于它来说,提出有意义的特性是可行的。正如你已经知道的,我用字母字符结束,使用 A-Z 手写字母数据集。

下一步是为所有 26 个类别(字母表中的字符)设计功能。这些特征必须足够通用,因此它们总是涵盖一个以上的类别,然而,每个类别都必须由一组独特的特征来描述,以便以后能够区分。总之,我想出了满足这些限制的 15 个特征(第一幅图中显示了其中的 10 个)。

之后,我必须划分数据集,决定哪些字符将被用作零拍类别。为此,我选择了五个特征相对不同的字符(“J”、“D”、“H”、“R”、“Z”),并将它们的所有数据放在一边。具有剩余 21 个类别的的数据集的剩余部分在训练集和测试集之间分割,用于拟合和测试模型。

有几种方法可以创建零起点学习的模型。我想尝试最简单的方法,它简单地预测任何给定输入的特性。该模型的输入是角色的图像,目标是其编码的类别向量(每个特征为 0 或 1)。这个任务可以被视为一个多标签分类,为此我在 Keras 中使用了以下两个卷积层的设置。

为了评估和实际使用经过训练的模型,我必须以某种方式将预测的类别向量映射回它们对应的类别。这是使用具有欧几里德距离的最近邻匹配完成的。首先,我使用测试集在观察到的类别上评估模型,达到了 96.53% 的准确率。

当我知道该模型能够正确概括时,我可以开始在看不见的零射击类别上评估它。基于这篇论文,我发现实际上有两种方法可以评估零炮模型。

第一个是某种限制性的设置,在预测的时候,我们知道这个实例是来自可见的还是不可见的类别。零触发学习为此受到了批评,因为在现实世界的应用中,我们通常没有这些可用的信息。我们的模型在被搁置的数据上这样评估,达到了 68.36% 的准确率。

第二种设置考虑了预测时所有可能的类别。处理这个问题的领域叫做广义零射击学习。以这种方式评估的结果通常低得多,因为观察到的类在搜索空间中充当干扰物。我们的情况也是如此,基于相同数据评估的模型仅达到了 10.83% 的准确度。对字符“R”的预测几乎总是更接近“P”,对“J”的预测更接近“U”,等等。解决这个问题的一种方法可以在本文中找到。

结论

这个实验让我第一次很好地了解了零起点学习的领域,以及从中可以期待什么。我希望它对你也一样。我必须承认,我期待一个更好的表现,主要是在广义的设置。然而,我使用的模型非常简单,当然可以使用更复杂的模型。一种看起来很有前途的方法,也是我想在未来尝试的方法,是使用双线性模型。该模型使用图像和类别向量作为输入,并预测该向量是否属于图像的实际类别。

感谢您的阅读。所有的代码都可以在这个 kaggle 笔记本中找到,所以你可以随意试验和训练你自己的模型。我将留给你一个卷积层的可视化,因为我很好奇它是否看起来有点类似于我设计的功能。

第一卷积层的特征图。图片作者。

[## 通过观察偏差和方差来系统地调整你的模型

有没有想过是否有比盲目猜测超参数或…更系统的方法来调整您的模型

towardsdatascience.com](/systematically-tuning-your-model-by-looking-at-bias-and-variance-4986662315b2) [## 主动学习能节省多少时间?

在 NLP 数据集上的动手实验。

towardsdatascience.com](/how-much-time-can-you-save-with-active-learning-b4886f5da462)

零镜头文本分类和评估

原文:https://towardsdatascience.com/zero-shot-text-classification-evaluation-c7ba0f56688e?source=collection_archive---------16-----------------------

最近,零镜头文本分类由于其简单性引起了人们极大的兴趣。在这篇文章中,我们将看到如何使用零镜头文本分类和任何标签,并解释背景模型。然后,我们将在情感分析、新闻分类和情感分类中使用人工标注数据集来评估它的性能。

零镜头文本分类

在零镜头文本分类中,该模型可以在没有任何先验数据的情况下对给定标签之间的任何文本进行分类。

白板(图片由维基百科提供)

使用零触发文本分类,可以执行:

  • 情感分析
  • 新闻分类
  • 情感分析

背景

实际上,零镜头文本分类的最新实现源于一个非常简单但非常棒的想法。自然语言处理中有一个领域叫做自然语言推理(NLI)。这个领域研究一个假设对于一个给定的前提是真的(蕴涵),假的(矛盾),还是不确定的(中性)。

监督 NLI 系统

现在,让我们假设我们的文本是“我爱这部电影。”我们想要预测候选标签之间的文本的情感。我们将这两个假设-前提对给已经训练好的 NLI 模型,并检验结果。

前提:我爱这部电影。
假设-1: 本例为

前提:我爱这部电影。
假设——2:这个例子是否定

基本上,它为每个类别创建“此示例是…”的假设模板,以预测前提的类别。如果推论是蕴涵,就意味着前提属于那个类。在这种情况下,它是积极的。

代码

得益于 HuggingFace,可以通过管道模块轻松使用。

#!pip install transformers datasets
from transformers import pipelineclassifier = pipeline("zero-shot-classification", device=0) #GPUcandidate_labels = ["positive", "negative"]
text = "I don't know why I like this movie so well, but I never get tired of watching it."
classifier(text, candidate_labels)> {'labels': ['positive', 'negative'],
> 'scores': [0.8987422585487366, 0.10125774145126343],
> 'sequence': "I don't know why I like this movie so well, but I
never get tired of watching it."}

在第一个示例中,我们从 transformers 管道中初始化分类器,然后从 IMDB 数据集中给出一个示例。您可以看到分类器为每个标签生成了分数。在第一个例子中,它正确地预测文本的情感是积极的。

candidate_labels = ["world", "sports", "business", "sci/tech"]
text = "Quality Gets Swept Away Quality Distribution is hammered after reporting a large loss for the second quarter."
classifier(text, candidate_labels)> {'labels': ['business', 'world', 'sci/tech', 'sports'],
> 'scores': [0.8066419363021851,   0.16538377106189728,   0.018306914716959,   0.009667363949120045],
> 'sequence': 'Quality Gets Swept Away Quality Distribution is hammered after reporting a large loss for the second quarter.'}

我们的第二个例子是来自 AG 新闻数据集的新闻分类。它能正确预测商业类新闻。

candidate_labels = ["anger", "fear", "joy", "love", "sadness", "surprise"]
text = "i didnt feel humiliated"
classifier(text, candidate_labels)> {'labels': ['surprise', 'joy', 'love', 'sadness', 'fear', 'anger'],
> 'scores': [0.66361004114151,   0.1976112276315689,   0.04634414240717888,   0.03801531344652176,   0.03516925126314163,   0.01925000175833702],
> 'sequence': 'i didnt feel humiliated'}

在我们的上一个例子中,我们研究了来自情感数据集的一个例子。零镜头分类模型预测句子“我不觉得丢脸”的情感为惊喜,然而金标是悲伤

评估

在这些例子中,零射击分类看起来很有希望。然而,它的性能应该通过使用已经标记的例子用正确的测量来评估。

摘樱桃???Andriyko Podilnyk 在 Unsplash 上拍摄的照片

通过使用 HuggingFace 最新的数据集库,我们可以很容易地在几个数据集上评估它的性能。

让我们将我们的零镜头文本分类模型与最先进的模型和微平均 F1 中的随机选取进行比较。

不同数据集中的微观平均 F1

有关初始化零射击分类管道和评估代码的更多详细信息,请查看这篇精心准备的 Colab 笔记本:

[## 零镜头文本分类—谷歌联合实验室

详细的讲解和评价!

colab.research.google.com](https://colab.research.google.com/drive/14NuJFnW3hsKNYvy0t37S0x3YYRhrxJ47?usp=sharing)

结论

我们可以看到零镜头文本分类在情感分析和新闻分类中取得了显著的效果。在具有 6 类的情感分类中的表现相当差。我相信这可能是由于类之间的相似性。在没有任何先验数据的情况下,很难区分快乐、爱和惊喜类。

如预期的那样,对于每个任务,零镜头分类的性能低于监督模型。即便如此,如果你没有任何具体分类问题的数据,还是值得尝试的

最初发表于【https://akoksal.com】

在 Twitter 上关注我:https://twitter.com/alkksl

拥抱人脸的零镜头文本分类

原文:https://towardsdatascience.com/zero-shot-text-classification-with-hugging-face-7f533ba83cd6?source=collection_archive---------5-----------------------

这篇文章是关于以无监督的方式检测文本情感,使用拥抱脸零镜头文本分类模型。

geraltPixabay 上拍摄的照片

几周前,我在实现 POC,其中一个要求是能够以无监督的方式检测文本情感(不需要事先有训练数据和建立模型)。更具体地说,这是关于数据提取。基于一些预定义的主题,我的任务是从文本数据中自动提取信息。在研究和寻找解决这个问题的最佳方法时,我发现拥抱脸 NLP 支持零镜头文本分类。

什么是零拍文本分类?查看这个帖子— 现代 NLP 中的零投学习。拥抱脸团队有一个现场演示和一个样品笔记本。简而言之,零射击模型允许我们对数据进行分类,而这些数据不是用来建立模型的。我在这里的意思是,这个模型是由别人建立的,我们用它来运行我们的数据。

我认为这将是一个有用的例子,我获取 Twitter 消息并运行分类来将消息分组到主题中。这可以作为更复杂用例的起点。

我使用 GetOldTweets3 库来删除 Twitter 消息。用变形金刚进行零镜头分类很简单,我是按照拥抱脸提供的 Colab 例子来做的。

进口清单:

import GetOldTweets3 as got
import pandas as pd
from tqdm import tqdm
import matplotlib.pyplot as plt
import seaborn as sns

from transformers import pipeline

从变压器管道获取分类器:

classifier = pipeline(**"zero-shot-classification"**)

我从 Twitter 上搜集了 500 条最新消息,基于一个预定义的查询——“气候斗争”。我们将把与气候变化斗争相关的信息提取到熊猫数据框架中,然后尝试使用零镜头分类将它们分成不同的主题:

txt = **'climate fight'** max_recs = 500
tweets_df = text_query_to_df(txt, max_recs)

在零触发分类中,您可以定义自己的标签,然后运行分类器为每个标签分配一个概率。有一个选项来做多类分类,在这种情况下,分数将是独立的,每个将落在 0 和 1 之间。我将使用默认选项,当管道假设只有一个候选标签为真时,返回每个标签的分数列表,加起来为 1。

主题的候选标签——这将让我们了解人们实际上在谈论什么气候变化斗争。有些信息是简单的广告,我们想忽略它们。零镜头分类能够很好地检测广告,这有助于清理数据:

candidate_labels = [**"renewable"**, **"politics"**, **"emission"**, **"temperature"**, **"emergency"**, **"advertisment"**]

我将进入循环并对每条消息进行分类:

res = classifier(sent, candidate_labels)

然后我在检查分类结果。检查第一个标签就足够了,因为当 pipeline 假设只有一个候选标签为真时,我使用默认选项。如果分类分数大于 0.5,我会记录下来,以便进一步处理:

if res[**'labels'**][0] == **'renewable'** and res[**'scores'**][0] > 0.5:
    candidate_results[0] = candidate_results[0] + 1

从结果中,我们可以看到,政治话题主导了气候变化的讨论,也许正如所料。与排放和紧急情况相关的话题通过流行度彼此接近。大约有 20 个案例的广告来自废弃的 500 条信息:

作者:安德烈·巴拉诺夫斯基

让我们看看每个主题的一些例子。

  • 可更新
Eco-friendly Hydrogen: The clean fuel of the future Germany is promoting the use of #eco-friendly hydrogen in the fight against climate change. Hydrogen can replace fossil fuels in virtually every situation, in an engine or fuel cell!
  • 政治
This is so crazy and wrong. It’s as if the ACA isn’t better than what we had before, that the fight for voting rights doesn’t matter, or equal pay for women, or marriage equality, or the Paris climate agreement. Just because Biden isn’t what we want doesn’t mean Dems = GOP
  • 发射
A simpler, more useful way to tax carbon to fight climate change - Vox
  • 温度
I've noticed any time someone tries to tell me global warming is not a big deal and how climate change has happened before, my body goes into fight or flight.
  • 紧急情况
(+ the next few years are CRUCIAL in the fight against climate change. if we don't address it, we'll pass the point of IRREVERSIBLE damage. biden supports the green new deal. trump... well, ya know.)
  • 广告
What is your favorite party game? Have a look on @ClumsyRush https://www.nintendo.com/games/detail/clumsy-rush-switch/ #party #game #NintendoSwitch

分类结果非常好,我认为抱脸零拍模型做得非常好。上面的例句没有直接提到主题标签,但是它们被正确地分类了。

结论

使用零镜头模型的无监督文本分类允许我们在没有训练数据来训练模型时解决文本情感检测任务。相反,你依赖于一个来自变形金刚的大型训练模型。对于特定的用例,当文本基于特定的单词或术语时,最好使用基于训练集的监督分类模型。但是对于一般的主题,零射击模型非常有效。

源代码

  • GitHub 回购
  • 在笔记本上自己运行

TensorFlow 2 计算机视觉从零到英雄—第一部分

原文:https://towardsdatascience.com/zero-to-hero-in-computer-vision-with-tensorflow-2-part-i-973775b9b898?source=collection_archive---------26-----------------------

使用 TensorFlow 开始使用神经网络的基本实现指南。

免责声明!

本系列不解释算法的底层数学,而只关注逻辑实现和使用带有特定参数集的特定算法的推理。学习神经网络和底层数学基础的资源包含在我的博客中,我是如何通过 TensorFlow 开发人员证书考试的

计算机视觉导论

最近,计算机终于能够执行看似琐碎的任务,检测图像中的物体/有机体,甚至识别口语。

更重要的问题是,为什么这些任务对人类来说如此微不足道?
简而言之,我们的意识缺乏理解这种感知的能力,这种感知利用了大脑中专门的视觉、听觉和其他感官模块。它是如此之快,以至于当感官信息到达我们的意识时,图像、视频或音频的高级特征已经被放大了。

卷积神经网络(CNN)已经从我们大脑视觉皮层的研究中出现,它们是一种深度学习模型,普遍用于计算机视觉应用。

但是在我们深入开发 CNN 之前,让我们先研究一下深度神经网络的构建模块。

这篇博客文章通过两个例子的帮助涵盖了开发深度学习模型:

  1. 用单神经元神经网络预测房价。
  2. 使用密集神经网络从图像中对时尚服装进行分类。

让我们从第一个非常简单的神经网络的实现开始。

构建最简单的神经网络

为了对神经网络如何工作有一个基本的了解,我选择了这个非常简单的房价预测的例子。我们将根据房子里卧室的数量来预测房价。

数据遵循简单的线性函数*y = mx + c*

这些数据仅仅是经过组织的:对于每间卧室,我们增加了 50K 美元的成本,等式中的 y 轴截距(当 x = 0 时)是 50K

我们不需要深度学习来解决这样的琐碎问题,这只是为了了解神经网络——它们是如何定义、编译、训练的,以及它们是如何进行预测的。

导入库

因此,第一步是导入所需的库,这里是 TensorFlow 和 NumPy:

##importing the main deep learningimport tensorflow as tf
from tensorflow import keras
import numpy as npprint("Tensorflow Version: ", tf.__version__)
print("Keras Version: ", keras.__version__)##output: 
Tensorflow Version:  2.3.0 
Keras Version:  2.4.0

确保你用的是 TensorFlow 2.x,我们已经单独导入了 Keras,可以直接使用。

数据

接下来,我们按照上面解释的公式定义数据:

bedrooms = np.array([2,3,4,5,6,7])
house_prices = np.array([150, 200, 250, 300, 350, 400])

模型定义

这将是你建立的最简单的神经网络模型。我们只需要一层,并且那层中只有一个神经元。输入形状也是[1],因为我们有一维数据。

我们将使用 Keras' Sequential API 来创建一系列相连的层:

model = tf.keras.Sequential([
    tf.keras.layers.Dense(units = 1, input_shape=[1])
])

units —层中神经元的数量。

Dense —构建密集的神经网络。虽然这个只有一层。

input_shape-告诉模型输入数据的维度。

模型汇编和培训

如果你一直想知道数学在机器学习中的作用,这是你应该更多探索的部分。虽然,我们有令人惊讶的定义函数,很好地封装了数学。

# model compilation
model.compile(optimizer='sgd', loss='mean_squared_error')#model training
model.fit(bedrooms, house_prices, epochs=100)

我们知道我们的数据遵循一个简单的数学函数,卧室(x)和房价(y)之间的关系是

y=50x+50。

当机器试图学习那个函数时,它会进行猜测…可能是 y=5x+10。然后,loss函数根据实际答案评估这个猜测的答案,以测量模型预测的误差。

optimizer函数试图通过另一种猜测来改善这种损失。随着每一次预测,它会尽量减少损失。经过多次迭代(历元),可能会达到一个接近 y=45x+45 的函数,这个函数仍然不正确,但更接近实际函数。

我们使用mean_squared_error作为优化器的损失函数和随机梯度下降(sgd)。

如何为特定场景找出合适的损失和优化函数是一项需要时间和实践来培养的技能。

模型预测法

print(model.predict([10]))

上图显示了一个 10 间卧室的房子的训练结果和图像末尾的预测值,该值应为 550,但模型预测值为 579.13。也许多训练几个时期的模型可以改进预测。你为什么不试试呢?

构建密集神经网络,从图像中对时尚服装进行分类

既然我们对 TensorFlow 制作的序列模型的各个组件有了相当好的理解,那么我们解决复杂的问题就会容易得多,例如图像分类,其中包括基于手头数据的一些预处理,在模型中添加密集层,以及更改输入和输出神经元。

资料组

我们使用的是时尚 MNIST 数据集,它是著名的 MNIST 数据集的替代品。它有 70,000 张 28x28 像素的灰度图像,但这些图像代表了时尚单品。因此,每一个阶层都更加多样化,问题也比 MNIST 更具挑战性。

让我们使用 Keras 实用函数加载数据集,以获取和加载常见的数据集,包括 MNIST 和时尚 MNIST,以及其他许多数据集。

##loading fashion MNIST dataset from tensorflow data API
fashion_mnist = keras.datasets.fashion_mnist
(X_train, y_train), (X_test, y_test) = fashion_mnist.load_data()

load_data方法将我们的图像分成训练和测试集。

让我们检查一下训练集的形状:

X_train.shape##output: 
(60000, 28, 28)

我们的数据集中有 60,000 张图片,每张都是 28x28 像素。

类似地,我们在测试集中有 10,000 张图像。

让我们看看打印出来的图像是什么样的:

X_train[0]#output:

我们在一个 2D 阵列中有 28×28 个强度。所有这些强度都在 0-255 之间。

从训练集创建验证集

由于我们在这里没有验证数据,我们将进一步分割我们的训练数据以创建验证集,如下所示:

  • 为验证集保留前 5000 行图像。
  • 因为我们将使用梯度下降来训练神经网络,所以我们必须缩放输入特征,也就是说,我们将通过将强度除以 255.0 来将强度缩小到 0–1 范围
X_valid, X_train = X_train[:5000] / 255.0, X_train[5000:] / 255.0
y_valid, y_train = y_train[:5000], y_train[5000:]
X_test = X_test / 255.0

此外,根据数据集描述,我们在数据集中有 10 种时尚服装,它们的编码都是从 0 到 9,我们将创建这些商品的列表:

class_names = ["T-shirt/top", "Trouser", "Pullover", "Dress", "Coat","Sandal", "Shirt", "Sneaker", "Bag", "Ankle boot"]class_names[y_train[1]]#output: 
'T-shirt/Top'

可视化数据集

import matplotlib.pyplot as plt
%matplotlib inlineplt.imshow(X_train[0], cmap='binary')
plt.axis('off')
plt.show()

看看前 40 件衣服,

n_rows = 4
n_cols = 10
plt.figure(figsize=(n_cols * 1.2, n_rows * 1.2))
for row in range(n_rows):
    for col in range(n_cols):
        index = n_cols * row + col
        plt.subplot(n_rows, n_cols, index + 1)
        plt.imshow(X_train[index], cmap="binary", interpolation="nearest")
        plt.axis('off')
        plt.title(class_names[y_train[index]], fontsize=12)
plt.subplots_adjust(wspace=0.2, hspace=0.5)
plt.show()

模型定义

下一步是定义模型:

model = keras.models.Sequential([
    keras.layers.Flatten(input_shape=[28, 28]), # input flatten layer
    keras.layers.Dense(300, activation='relu'),
    keras.layers.Dense(100, activation='relu'),
    keras.layers.Dense(10, activation='softmax') # output layer
])

让我们来分解一下这个模型:

  • 我们已经为密集神经网络创建了一个Sequential Keras 模型,该神经网络由顺序连接的单个层堆栈组成。
  • 接下来,我们构建第一层,这是一个Flatten层,它将每个输入图像转换成一个 1D 数组:如果它接收到输入数据X,它将计算X.reshape(-1, 28*28)。它是密集层之前的一个简单的预处理层。由于它是模型中的第一层,我们指定了input_shape,它只包括实例的形状。
  • 随后,我们添加一个有 300 个神经元的Dense隐藏层。它还使用 ReLU 激活功能。
  • 接下来,我们添加第二个有 100 个神经元的Dense隐藏层,同样使用 ReLU 激活函数。
  • 最后,我们添加一个有 10 个神经元的Dense输出层(每个类一个),使用 softmax 激活函数(因为类是排他的)。

每个Dense层管理自己的权重矩阵,包含神经元及其输入之间的所有连接权重。它还管理一个偏差项向量(每个神经元一个)。

我们可以访问这些层、它们的初始化权重和偏差:

模型摘要:

权重和偏差:

编译和训练模型

model.compile(loss="sparse_categorical_crossentropy",
              optimizer="sgd",
              metrics=["accuracy"])
  1. 损失:我们使用“稀疏 _ 分类 _ 交叉熵”损失,因为我们有稀疏标签(即,对于每个实例,只有一个目标类索引,在这种情况下从 0 到 9),并且类是唯一的。
  2. 优化器:“SGD”表示我们将使用简单的随机梯度下降来训练模型。基本上,Keras 将执行所讨论的反向传播算法。
  3. Metrics :由于这是一个分类问题,测量模型的准确性会很有用。

训练:

history = model.fit(X_train, y_train, epochs=30, 
                     validation_data=(X_valid, y_valid))

在历史对象中捕获模型训练历史,我们将使用它来绘制模型的损失和准确性。

模型评估

我们可以通过传递测试实例和实际标签来评估模型的性能。

model.evaluate(X_test, y_test)# output:
313/313 [==============================] - 0s 533us/step - loss: 0.3326 - accuracy: 0.8823
[0.3326309025287628, 0.8823000192642212]

该模型在这一点上具有 88%的准确性。您可以使用不同的参数来调整模型,以查看效果。

绘制模型历史

history = pd.DataFrame(history.history)
history.plot(figsize = (12,8))plt.grid(True)

您可以看到,历史记录有助于我们将模型训练准确性和损失与验证准确性和验证损失进行比较,即模型对未知数据的性能。

与其在训练数据上的性能相比,模型的性能总是略低。如果模型在训练和测试数据上的准确度较低,那么我们会遇到欠拟合的情况,但是如果模型在训练和数据上表现准确,而在验证数据上表现不太准确,那么我们会遇到过拟合的情况。

对样本测试图像进行随机预测

在测试数据集样本上运行它:

# extracting first 5 sample images
X_sample = X_test[:5]
y_proba = model.predict(X_sample)
y_proba.round(2)y_pred = model.predict_classes(X_sample)
y_pred#output:
array([9, 2, 1, 1, 6])

我们可以使用上面创建的列表获得这些服装的名称:

np.array(class_names)[y_pred]

实际标签:

您可以使用 Google Colab 笔记本试用这些模型并测试其他功能和参数:

[## 谷歌联合实验室

编辑描述

colab.research.google.com](https://colab.research.google.com/github/dswh/tf-end-to-end-image-classification/blob/master/Introduction.ipynb)

注意:这将是一系列博客(可能有 3 个),我们将在其中讨论基本的计算机视觉问题,用卷积对真实世界的图像进行分类&汇集并使用预先训练的模型来解决复杂的问题。

以下是这篇博客的视频版本:

数据科学与 Harshit

通过这个渠道,我计划推出几个覆盖整个数据科学领域的系列。以下是你应该订阅频道的原因:

ZetaBrot,无限分形生成器——超越 Mandelbrot 和 Zeta 函数的变体

原文:https://towardsdatascience.com/zetabrot-variations-an-exploration-on-fractal-generation-8c93290bd91b?source=collection_archive---------36-----------------------

轰炸—z →( tanh(arcsinh((e(sinh((log(arccosh((z))))c 上的无限迭代))))))*c

除了我对数据科学的热情,数学,尤其是混沌理论,一直是我探索的主题。更准确地说,我贪婪地阅读了关于混沌系统、奇怪的吸引子和分形的数学好奇心。我觉得它们在某种意义上是令人欣慰的,看似混乱的环境中的秩序,在某种意义上是鼓舞人心的希望。Mandelbrot 集合是最著名的分形结构之一,在互联网上有数百万的参考文献。 Github 统计了超过 9 种编程语言的 6000 个知识库。它已经成为开发者的游乐场,但也是网络上一些最具 T4 催眠效果的视频的来源。Mandelbrot 的美丽还来自于生成它的函数的简单性:z → z +c 的迭代。仅仅通过这个简单的公式,就可以生成一个无限的世界,其中有环路、螺旋、山谷和丰富的惊人结构。分形几何的发现对自然环境产生了巨大的影响,在自然环境中,这些图案在生物和物理世界中随处可见而且还应用于手机天线的小型化和信号处理中的图案识别,从而彻底改变了通信。

在数学的另一个分支——数论上,黎曼泽塔函数被誉为数学家的圣杯。证明黎曼假设的天才将获得100 万美元的奖励,由于其简单公式中隐藏的秘密,它也是激烈调查的主题。ζ函数可以简单地写成所有 1/(n^s 值的无穷和,其中 s 是一个复数。但是莱昂哈德·欧拉在 200 多年前证明了这个无穷级数等于 1/(1-p^(-s 的无穷乘积,其中 p 代表后来的素数。所以基本上,齐塔函数知道一些关于质数的事情,这是一件大事。因为质数是现代密码学的基石,也是全世界数百名数学家爱好者和研究论文的热情主题。

在我复制这两个数学对象的可视化的卑微尝试中,我尝试了一些小的变化。其中一个经典的方法是进一步提升 Mandelbrot 集合的能力,但是这个方法又重复了很多次。然后,我试着加入一些更标准的功能,但并不总是考虑合理性,只是为了创造出视觉上的美感。因此,我的第一个变化是将齐塔函数封装在 sin 中。由此产生的视觉效果是惊人的,见下文。

z → z + sin(1/(n+0.5)^c 迭代的第一个变量)(x:-10/+10,y:-10/+10)

但随后开始了一个乏味的试错过程,在原始配方和新模式的基础上结合了几种功能。见下面第一个 Zeta 和 Mandelbrot 函数与 sin 分量的组合。

与 z → sin 的迭代的组合((z +c)/n^c) (x:-5/+5,y:-5/+5)

这是一项艰巨的工作,因为许多小的变化导致不收敛的系列。虽然经过一些调整和复制来自同行爱好者的变体(这里那里),如燃烧的船分形垂直曼德尔布罗,我特别受到 Jeffrey Ventrella 的倡议的启发,使用遗传算法进化曼德尔布罗集合。这促使我通过创建一种算法来试验不同函数组合的自动化,该算法通过循环和随机迭代过程混合 Numpy 库中所有可用的函数,通过精心制作的适应度标准仅保留具有收敛结果的变化。目标不是找到最好的(我该如何定义它?)而是简单地生成可以聚合并导致有趣的可视化的变化。本文简介中的图片是这套的一部分。以下是一些最有希望的结果,它们的名字是由它们的形状启发而来的。有些公式也是由算法自动生成的,但是很难掌握…

藻类:z → z + 1/(n^zc) (x:-5/+5,y:-5/+5)

花园:z → e^(z + sin(1/n^c)) (x:-5/+5,y:-5/+5)

分形蝙蝠:z→ArcTan((ArcTan((Abs(1/(conj(ArcSinH(z)))))+c)(x:-5/+5,y:-5/+5)

蒙德里安:z→tan((angle(sin(sqrt(cosh(c^(cosh(abs(tan((angle(tan(z))))))))))))))(x:-5/+5,y:-5/+5)

冲击波:z→arctanh(sqrt(((c(sqrt(arcsinh(tan(log(((arcsin(c(tan(((conj((z)+c))+c )n))))(arcsin(c^(tan(((conj((z)+c))+c )n)))))n))))))^c)+c))(x:-5/+5,y:-5/+5)

你说对了,公式变得更加复杂,设计也变得更加复杂。但是,算法如何知道哪些组合是有效的,哪些是无效的呢?

zeta brot——无限分形生成器

该算法本身分 4 步工作:
1-定义复杂性的“深度”,例如 z →z +c 的复杂性深度为 2:首先是 z 的平方,然后加上 c。对于 Zeta 函数,它将是 3:首先将 n 提高到 c 的幂,然后对其求逆,最后将其加到 z 上。
我将深度限制为 20,但这是任意的。

2-对于每个复杂程度,从 34 个可用函数中选择一个(从 sin 到 square,下至 atan,甚至 re 或 Im 代表复数)。并按照步骤 1 中随机选择的复杂性级别的底部进行操作。

3.对于复杂计划的每个点,迭代结果(类似于 Mandelbrot) n 次,n 也是任意设置的,但会影响可视化(特别是对于负的 n 次方值)

4.评估结果值的平均值和标准偏差。任何射向无穷大或具有无穷小标准偏差的都被丢弃。一个简单的条件检查和阈值有助于关注最有意义的结果

它的妙处在于一个非常复杂的公式,比如:

z→im(tan(c^(arccos(arcsinh((cosh(conj(arccos(cosh( arccos(z))))))^n)))))

可以通过算法中的主要公式组件进行总结:

【23,26,23,6,26,9,28,23,13,2,20,2】分别对应 ArcCos,CosH,conj…在我的手工参照中。

按照这种逻辑,Mandelbrot 可以表示为[7,15],Riemann Zeta 函数可以表示为[34,10,5,17]。

由于一些伟大的数学思想家受到现有问题的新颖可视化的启发,也许一些宝石隐藏在这些模式中,可能对尚未发现的新定理感兴趣,并帮助我们在混沌中找到新的模式。

我的下一个努力将是尝试几种规模,但也增加了新的公式的变化。保持联系。

下面是我最喜欢的一个例子来总结这次探索之旅:

混乱与秩序的世界:z→((arcsinh(tan(sinh(e((arcsinh(c(arctanh(arccosh(arcsinh(e^(((z)+c)+c )))))))^c)))))+c

鸣谢:感谢 Python 可视化库 Matplotlib 对 Mandelbrot set 的惊人视觉效果的渲染的详细代码分解。我仍然需要探索更多由图卢兹数学大学发布的精细着色功能

纪尧姆·休特

ZFNet:用代码解释论文

原文:https://towardsdatascience.com/zfnet-an-explanation-of-paper-with-code-f1bd6752121d?source=collection_archive---------17-----------------------

揭开神经网络如何看待我们的世界的秘密!

丹尼尔·库切列夫在 Unsplash 上拍摄的照片

在 2013 年的 ImageNet 大规模视觉识别挑战赛(ILSVRC)中,ZFNet 受到了关注,与 AlexNet 相比有了显著的改进。本文是黄金宝典,为您提供了许多概念的起点,如深度特征可视化特征不变性特征进化、特征重要性

体系结构

https://arxiv.org/pdf/1311.2901.pdf

  • 我们的输入是 224x224x3 的图像。
  • 接下来,以 2步距执行 7x7 的 96 个卷积,随后是 ReLU 激活、以 2 步距的 3×3 最大汇集和局部对比度归一化
  • 接下来是 256 个 3×3 的滤波器,每个滤波器然后再次被局部对比度归一化汇集
  • 第三层和第四层与 384 个内核相同,每个3 个。
  • 第五层具有 3x3 的 256 个过滤器,接着是具有步幅 2 的 3x3 最大池局部对比度归一化
  • 第六层和第七层分别容纳 4096 个密集的单元。
  • 最后,我们输入 1000 个神经元的密集层,即 ImageNet 中的类的数量。

如果您不熟悉术语“局部对比度标准化”:

局部对比度归一化是一种执行局部减法和除法归一化的归一化,在特征图中的相邻特征之间以及不同特征图中相同空间位置的特征之间实施一种局部竞争。

来源:https://cedar . buffalo . edu/~ Sri Hari/CSE 676/12.2% 20 computer % 20 vision . pdf

特征的可视化

https://arxiv.org/pdf/1311.2901.pdf

对于特征的可视化,作者使用了去进化网络 (deconvnet)。可以把 deconvnet 看作是自动编码器的解码器部分。它与普通的卷积网络相反,它使用非 pooling 和过滤器从特征中恢复像素。

这个网络中唯一令人困惑的部分是它是如何撤销池的,因为当任何池完成时,给定使用 NxN 过滤器,N 个值中只有一个值剩余。整个数据不能被恢复,但是最大值仍然在那里,但是如果我们不知道它在卷积层的输出中的位置,它是没有用的。这就是为什么当进行汇集时存储最大值的位置以便以后使用。这些位置在文中被称为开关

https://ieeexplore.ieee.org/document/6126474

使用开关,最大值被放置在图层上正确的空间位置,从而允许将要素正确映射到像素。

此外,还有一点需要注意,卷积滤波器是在应用非线性之后应用的,这与卷积然后激活的正常流程相反。

https://arxiv.org/pdf/1311.2901.pdf

然后作者提取了特征图中前 9 个激活的特征并展示出来。

第一层去掉了最简单的特征,图像中的各种频率。把它当成学习图像中的线条。

第二层是建模各种角落和边缘/颜色组合。把它想象成学习图像中的曲线。曲线是由小线条构成的。

第三层学习网格等更复杂的图案。把它想象成学习那些曲线的组合,即网格。曲线聚集在一起创建网格(想想篮子)。

第四层学习特定类别的特征,例如狗脸。把它想象成把篮子做成不同的形状并涂上不同的颜色。网格可以被转换成类似于面和各种复杂的对象。

第五层学习具有一些姿势变化(侧面、正面和其他)的整个对象。把它想象成把所有这些篮子排列成相似的不同物体。可以将类似较大物体的较小人工制品的网格排列在一起,以形成整个形状。

从特征的可视化中,作者还获得了在 AlexNet 的第一层中减少过滤器大小和步幅的想法。

https://arxiv.org/pdf/1311.2901.pdf

在(b)中,我们有 AlexNet 的第 1 层功能,在(c)中,我们有 ZFNet 的第 1 层功能。在(b)的情况下,我们可以看到一些灰色方块,这些是没有激活值的死亡神经元。这是一件坏事。另一个问题是在(a)中可以看到颜色/强度的低值和高值,但是不能看到颜色/强度的中间范围。

第三个问题是图像特征中的锯齿状视觉特征或混叠。当采样率不够高时,就会发生混叠(想象一下图像中有正方形)。在这种情况下,采样率是将要发生的卷积数。如果滤波器尺寸较大,则采样率较低。如果滤波器尺寸较小,则采样率将会较高。大步流星也会发生同样的事情。

这就是为什么这些问题的解决方案是减小滤波器尺寸和步幅,这两者都导致采样速率增加,并且由于现在步幅很小,颜色/强度的中间范围出现。

特征不变性

卷积神经网络具有平移、缩放和旋转(给定对象具有旋转对称性)不变性。这是直观的证据:

https://arxiv.org/pdf/1311.2901.pdf

第一行是为了显示翻译不会影响训练有素的 CNN 的表现。在第一行的第二列中,您可以看到图像属于其真实类别的概率。除了在极端情况下,曲线在大多数情况下都是稳定的,主要是因为在图像中不能看到有问题的物体。

第二行是为了显示缩放不影响经过训练的 CNN 的性能。在第二行的第二列中,您可以看到图像属于其真实类别的概率。除了娱乐中心之外,大多数对象的曲线都是稳定的,娱乐中心实际上一直类似于电视,因此是这样的行为。但是,总的来说,CNN 看起来对缩放相当稳健。

第三行是为了显示旋转确实会搞乱 CNN。一个例外是,如果物体具有某种旋转对称性,那么 CNN 仍然保留其对该物体图像的预测能力。从第三行的第二列,你可以看到所有的曲线都乱了套,只有可爱的狮子狗和危险的非洲鳄鱼是稳定的,它们的图像看起来都是旋转对称的。CNN 对于具有旋转对称性的物体的旋转是鲁棒的,因此,你应该记住这一点。

因此,今天你就有了视觉证据,证明为什么 CNN 在图像任务上如此出色。

特征的演变

照片由 Alexas_Fotos 拍摄

这篇论文给了我们关于神经网络在引擎盖下做什么的视觉直觉。没有人知道如何处理和如何调整这个引擎的黑盒神经网络已经不再是谜了。下图显示了网络中图层的影像要素。

https://arxiv.org/pdf/1311.2901.pdf

这就是图像特征如何在层上演变,但用简单的自然语言来说,这就是它是如何发生的。

来源:作者

对这一观点的更多支持是,在第一层,你有线,我们可以把它联系起来,因为这两个方程看起来像:

来源:作者

正常神经元的方程式看起来像一条线。所以,第一层模拟图像中的线条。随着层数的增加,上面的 x 会越积越多。并且网络对越来越多的扭曲线及其组合进行建模。耶,我们得到了最好的算法来创建我们的模型。对于以上解释的更复杂的形式,请查阅通用逼近定理(UAT)和柯尔莫哥洛夫定理。

特征重要性

https://arxiv.org/pdf/1311.2901.pdf

精彩的部分还不止于此。本文还包含有关各图层特征预测能力的有用信息。正如我们所见,最后一层功能是最强大的。因此,在堆叠或迁移学习时,这些都可以使用。

密码

这里是上面广泛讨论的 awesome 网络的代码。

结论

ZFNet 第一次让世人看到了神经网络的内心世界。由于人类是视觉学习者,这为计算机视觉领域打开了新的大门和途径。它向我们展示了神经网络的中心思想以及它们是如何形成的。

通过 Lambda 函数在 EMR 中压缩和提交 PySpark 作业

原文:https://towardsdatascience.com/zipping-and-submitting-pyspark-jobs-in-emr-through-lambda-functions-46a58a496d9e?source=collection_archive---------28-----------------------

端到端的项目结构和部署

Denys Nevozhai 在 Unsplash 上拍摄的照片

语境

我假设你已经熟悉 AWS 云平台,尤其是 Lambda 和 EMR 服务。我假设您已经运行了一个 EMR 集群,并且知道如何设置 lambda 函数。本文涵盖了创建 PySpark 项目并提交给 EMR 的端到端主题。最后,本文产生了一个名为 pyspark-seed 的 PySpark 项目,它已经准备好被克隆并在它的基础上进一步开发。

重要的事情先来

我的 Python 项目的 go to IDE 是 PyCharm 。Jupyter 笔记本总是在那里快速检查。为了构建 Python 虚拟环境,我将使用 venv 。Venv 很简单,并且预装了 Python 解释器。对于 Python,我会选择 3.7 版本;对于 PySpark,我会选择 2.4.5 版本。提供了一个持续集成配置文件,可以通过 GitLab Runner 执行。由于社区更大,我也在 GitHub 中托管这个 pyspark-seed 项目的源代码。

部署模式

在创建项目之前,让我们讨论一下部署!是的,部署发生在最后,但是它的重要性应该在项目开始时讨论。为什么?因为大多数时候,你部署项目的方式会影响项目结构和代码组织。

在 PySpark 项目中,您可以部署独立脚本或者部署打包/压缩的项目。如果你有几个简单的工作,但彼此之间不共享功能,就部署独立脚本。当您有多个彼此共享功能的作业时,部署一个打包/压缩的项目。

当打包用 Java 或 Scala 编写的 spark 作业时,您会创建一个单独的 jar 文件。如果打包正确,在 EMR 中提交这个 jar 文件将会成功地运行作业。要在 EMR 中提交 PySpark 项目,您需要具备以下两点:

  • 您的项目的一个 zip 文件
  • 这个 zip 文件之外的一个 main.py 文件,它将这个 zip 文件作为一个模块导入。您不必指定。导入模块时压缩

构建项目

我创建了一个名为 pyspark-seed 的 Python 项目。该项目的结构如下:

pyspark-seed 项目结构

  • 模块 _ 种子:包含作业服务实用程序测试的模块。这可以被认为是一个独立的模块,内部有一个 run.py 文件。该文件被导入到 main.py.
  • 作业:我存储所有作业的包。
  • 服务:自定义编写的函数,在作业内部调用,处理数据。这些函数抽象了作业中使用的共享功能。例子可能是:模式服务、日期服务等。
  • utils : 一个包,我在里面存放了像 s3_utils、spark_utils、log_utils 等助手。(是的 utils 的意思和 helpers 一样)。
  • 测试:存储单元和集成测试的包。
  • 。gitignore :通常由 gitignore.io 生成。
  • main.py: 这是主函数,在部署时,它将被保存在 zip 文件之外。该文件从模块种子包中导入 run.py 并运行它。
  • setup.py: 安装这个项目。

虚拟环境

我使用 venv 来创建隔离的 Python 环境。这个环境中的 Python 二进制文件与您用来创建这个环境的 Python 中的二进制文件是相同的。安装在这个虚拟环境中的模块独立于安装在本地/系统 Python 中的模块。要创建 Python 环境,请在项目根目录(即/pyspark-seed)。

python3 -m venv venv. ./venv/bin/activate pip install -e .

第一个命令创建一个 Python 环境。这将在你的项目结构中创建一个名为 venv 的目录。第二个命令将激活创建的 Python 环境。最后一个命令将运行 setup.py 并安装/设置项目。

安装文件

该文件的职责是正确设置您的 Python 项目。您可以指定项目的名称、版本提供项目的描述作者名称、等等。一个简单的 setup.py 如下:

version 变量中指定项目版本,允许您在 CI 期间访问它,并使用它来生成一个路径,在那里您将在 s3 中存储工件(即 seed_modulemain.py )。访问这个变量非常简单:

python setup.py --version

CI-管道

PySpark 项目的 CI 管道通常有三个基本阶段:构建测试、部署。

pyspark-seed 项目的线性 CI 渠道

Python 3.7-stretch 用作基础图像。如果您想在测试阶段安装 PySpark 并运行 PySpark 测试,那么这个版本是必需的。这条管道是线性的。每个阶段在前一个阶段成功完成后运行。阶段构建测试自动运行,而部署应该手动触发以进行部署。AWS 凭证作为环境变量存储在 GitLab 中。当在 s3 中存储工件时,我们总是用最新的变更覆盖最新的路径内容。

s3 中部署的工件

乔布斯

每个作业都应该写在单独的 Python 文件中。为了简单起见,每个作业都应该有一个名为 process 的函数,它至少接收 spark_sessioninput_pathoutput_path 作为参数。这些参数,即我们想要运行的作业名和其他参数,在下一节讨论的 lambda 函数中指定。下面显示了一个简单的作业模板。

通过 Lambda 向 EMR 提交作业

AWS Lambda 是一种无服务器服务。您可以通过 AWS CloudWatch 安排 lambda 代码运行,触发代码运行作为对事件的响应,甚至通过 API 调用按需触发 lambda 函数。下面展示了一个向 EMR 提交作业的 lambda 函数。这个 lambda 函数在 Python 3.7 中运行。

我已经定义了 main_pathmodules_path ,它们默认指向产品的最新版本。特定于您的 main 函数的参数在 main_path 之后的 spark-submit 中传递。我更喜欢在字典中设置所有参数,将字典转换为字符串,并将整个字符串作为单个参数传递给 main。当收到这个字符串字典时,我使用 ast 模块,从中提取字典。

然后,该参数字典被传递给 run.py 函数,该函数使用提供的配置建立 spark 会话,并运行参数中规定的作业。

场景工作流

考虑一个用例,其中每 20 分钟将一个数据文件(大小约 3GB)转储到 s3 原始数据桶中。考虑一个事件侦听器被设置到这个桶属性。该事件监听器监听所有 对象创建事件。如果在这个桶中上传了一个对象,侦听器就会捕获它并触发目标 lambda 函数。这个 lambda 函数从事件消息中获取对象路径,提供作业参数,并在 EMR 中提交作业。下图显示了此工作流程的开始和结束。

通过 lambda 函数在 EMR 中提交 PySpark 作业的简单场景

最后的话

在本文中,我描述了启动 PySpark 项目、创建 CI 配置文件、在 S3 部署工件以及通过 Lambda 函数在 EMR 中提交作业的过程。提供的大部分建议都直接来自我在生产和研究中使用 PySpark 的个人经验。我在 Github 中托管了这个 pyspark-seed 项目的源代码。通过亲自探索这个知识库,可以了解许多其他细节。随意克隆它,让它变得更好。

当然,这个项目许多方面可以用不同的方式来完成。我打算提供这个种子项目作为一个起点,可以进一步发展。欢迎所有问题、反馈和批评。我相信在这个世界上,批评推动变化。

[## dardanxhymshiti/pyspark-seed

在 GitHub 上创建一个帐户,为 dardanxhymshiti/pyspark-seed 的发展做出贡献。

github.com](https://github.com/dardanxhymshiti/pyspark-seed)

用 Python 实现 4 步分区统计算法

原文:https://towardsdatascience.com/zonal-statistics-algorithm-with-python-in-4-steps-382a3b66648a?source=collection_archive---------19-----------------------

如何汇总面区域的栅格数据

照片由粘土银行Unsplash 上拍摄

通常需要汇总不规则形状区域内网格化数据集的信息。虽然乍一看这似乎很简单,但调和栅格(格网)和矢量(面)数据类型之间的差异可能会很快变得复杂。本文展示了如何通过 4 个步骤用 Python 实现区域统计算法。

  1. 加载栅格数据和矢量多边形
  2. 栅格化面要素
  3. 将输入数据掩膜到面范围
  4. 计算面范围的分区统计数据

1.加载栅格数据和矢量多边形

首先导入必要的 Python 模块。

现在设置光栅和矢量数据的文件路径,并使用gdalogr分别加载光栅和矢量数据。从已加载的矢量数据源访问包含面数据的图层。然后获取地理变换信息(定位网格化栅格数据并指定像元大小),而不获取栅格数据的数据值。

我们还要用gdalogr做一些设置,为确定栅格和矢量多边形之间的重叠做准备。让gdalogr驱动程序在内存中创建临时光栅和矢量图层,并为临时 shapefile 设置名称。

2.栅格化面要素

加载栅格和矢量数据后,就该确定它们重叠的地方了。这将是算法中最复杂和最密集的部分。首先,从矢量图层读取第一个面要素。然后开始一个while循环,只要矢量层中还有另一个特征,循环就会继续。下面是设置循环的基本方法。随着我们的继续,这个循环将被修改。

我们需要创建一些函数来帮助我们创建一个新的栅格来存储栅格化的面要素。当我们用实际数据调用这些函数时,它们会更有意义。现在,在脚本的顶部添加函数定义。首先,我们需要将包含面要素的边界框的坐标转换为与输入栅格相对应的像元坐标或偏移量(行号和列号)。面的边界框是包含整个面要素的矩形,它由最小和最大 X 和 Y 坐标组成。

接下来编写一个函数,用上面函数中计算的像元偏移量创建一个新的 GeoTransform。这两个函数将允许我们创建一个新的更小的栅格,该栅格仅覆盖由面要素重叠的区域。

现在是算法中最复杂的部分:在内存中创建新的空栅格,并将面要素转换为栅格。按照下面代码片段中的注释来理解每一行代码的作用。你可能还会发现查看 GDAL 和 OGR 文档很有用。

3.将输入数据掩膜到面区域

此时我们有两个并发的(重叠的)numpy数组:tr_arrayr_arraytr_array值为 1,表示多边形已栅格化的位置。r_array包含我们要用来计算每个面的分区统计数据的值。

首先,确保输入栅格存在。接下来创建一个遮罩数组。我们希望从r_array获取数据,其中不包含无数据值,并且tr_array中的相应值等于 1(或True)。

现在我们将使用maskarray来计算每个面要素的区域统计数据。

4.计算每个面范围的分区统计数据

再编写一个函数,它接受一些值作为输入,并创建一个值的字典。将此函数与其他函数一起放在区域统计脚本的顶部。

现在,计算来自maskarray的值,并将它们传递给setFeatureStats函数。仅当阵列存在时才这样做(is not None)。否则,传递 no data 值来设置统计信息。

结论

恭喜你!您已经创建了可应用于许多不同应用程序的 Python 区域统计脚本。以下是完整的脚本。使用自定义的区域统计算法可以让您在使用结果时更加灵活。从这一点来看,很容易将字典列表转换为 pandas 数据帧进行分析,导出到 csv,或者在原始 shapefile 中创建新字段并将统计数据直接添加到原始数据中。这可以加快、简化和定制您的工作流程。

原载于 2020 年 11 月 10 日 https://opensourceoptions.com

总统竞选中服用维柯丁:用马尔可夫链制造假头条

原文:https://towardsdatascience.com/zonked-on-vicodin-in-the-presidential-race-generating-fake-headlines-with-markov-chains-87f06cccd866?source=collection_archive---------56-----------------------

在讽刺和现实之间游走

来源:查尔斯·泰勒,via Adobe Stock

在这篇文章中,我们编写 Python 代码来生成假新闻标题,使用马尔可夫链模型,该模型是在过去一年中来自《纽约时报》的真实标题语料库上训练的。

一些假标题:

我曾经牵过手?

我们在下降,下降,下降

我们都在这张照片里吗?| 2019 年 9 月 18 日

在总统竞选中嗑了维柯丁

迈克·彭斯明确表示有一部新宪法

谁知道如何清除你孩子的 DNA 信息?

人工智能了解到自由主义者也会吃掉他们自己的律师

纽约人多么想要便宜的葡萄酒和许多真人大小的洋娃娃。

卡罗尔·巴斯金的丈夫唐·路易斯身上发生的一件事?

在帮助下,她找到了卡森·麦卡勒斯的情书。他们教她如何统治直到 2036 年

尽管这些标题很明显是假的,而且从未被《纽约时报》发表过,但在当前事件的背景下,它们却有着不可思议的真实性。

假设您有一个想要模拟的文本语料库,您可以扩展本文中的代码来生成任何想要的文本。

内容:

  1. 马尔可夫链是如何工作的
  2. 野外的马尔可夫链文本生成器
  3. 创建我们自己的马尔可夫链文本生成器
  4. 制造假标题
  5. 改进我们模型的方法
  6. 更多头条!

1.马尔可夫链是如何工作的

你可能没有意识到,但是你每天都在使用马尔可夫链。这些数学系统决定了哪些页面会出现在谷歌搜索的顶部。它们帮助你的手机预测你下一步要输入什么。它们还为各种 Twitter 和 Reddit 机器人以及其他模仿发生器提供动力。

从根本上说,所有这些应用程序中的马尔可夫链都是以同样的方式工作的。马尔可夫链描述了一系列可能的状态,其中每个状态的概率取决于紧接在其之前的状态。

马尔可夫链上有很多好的资源,比如这个可视化的,所以这篇文章只描述它们如何在 Python 包markovify中工作,这是一个方便的小包,可以让我们自己委托编写模型的工作。

当给定像我们的标题这样的语料库时, markovify 使用重叠滑动窗口将每个句子(或者在我们的情况下,标题)分解成用户指定大小的 n 元语法状态。例如,如果我们告诉它,我们希望我们的语料库用二元模型状态的马尔可夫链来建模,这个标题来自 2020 年 4 月 30 日

谁应该在飞机上戴口罩?更多的航空公司说每个人

被分解成这个二元模型状态列表:

('___BEGIN__', '___BEGIN__')
('___BEGIN__', 'Who')
('Who', 'Should')
('Should', 'Wear')
('Wear', 'Masks')
('Masks', 'on')
('on', 'Planes?')
('Planes?', 'More')
('More', 'Airlines')
('Airlines', 'Say')
('Say', 'Everyone')

当它把这个标题分解成 n 个字母时, markovify 也在字典中记录了遵循特定二元模型的所有单词的频率。这本字典构成了马尔可夫链。

到目前为止,我们的马尔可夫链是这样的:

{('___BEGIN__', '___BEGIN__'): {'Who': 1},
('___BEGIN__', 'Who'): {'Should': 1},
('Who', 'Should'): {'Wear': 1},
('Should', 'Wear'): {'Masks': 1},
('Wear', 'Masks'): {'on': 1},
('Masks', 'on'): {'Planes?': 1},
('on', 'Planes?'): {'More': 1},
('Planes?', 'More'): {'Airlines': 1},
('More', 'Airlines'): {'Say': 1},
('Airlines', 'Say'): {'Everyone': 1},
('Say', 'Everyone'): {'___END__': 1}}

再来看另一个标题。

应该先救谁?专家提供伦理指导

markovify 分解这个标题并更新链之后,我们的链看起来是这样的(更新以粗体显示):

{('___BEGIN__', '___BEGIN__'): **{'Who': 2}**,
('___BEGIN__', 'Who'): **{'Should': 2}**,
('Who', 'Should'): {'Wear': 1, **'Be': 1**},
('Should', 'Wear'): {'Masks': 1},
('Wear', 'Masks'): {'on': 1},
('Masks', 'on'): {'Planes?': 1},
('on', 'Planes?'): {'More': 1},
('Planes?', 'More'): {'Airlines': 1},
('More', 'Airlines'): {'Say': 1},
('Airlines', 'Say'): {'Everyone': 1},
('Say', 'Everyone'): {'___END__': 1},
**('Should', 'Be'): {'Saved': 1}**
**('Be', 'Saved'): {'First?': 1},
('Saved', 'First?'): {'Experts': 1},
('First?', 'Experts'): {'Offer': 1},
('Experts', 'Offer'): {'Ethical': 1},
('Offer', 'Ethical'): {'Guidance': 1},
('Ethical', 'Guidance'): {'___END__': 1}**}

我们可以看到模型知道单词“Who”在标题中作为第一个单词出现了两次。该模型还知道“谁应该”后面可能会有两个不同的词,以及标题可以在“说每个人”或“道德指导”后面结束。

最终[和大]链的一瞥:

这是我们马尔可夫链的一部分,它从我们的纽约时报标题语料库中捕获了 233,477 个二元模型。

当生成一个句子时, markovify 以开始状态('___BEGIN__', '___BEGIN__')或用户提供的开始状态开始,可能是('More', 'Airlines')或其他 233,476 个二元模型中的任何一个。

Markovify 然后从这个开始状态开始链接,随机添加一个单词,假设它跟随前面的二元模型。当链遇到结束状态时,它停止。现在我们有了假标题。

使用马尔可夫链生成文本时会出现一些常见的问题,但是 markovify 在幕后处理了这些问题。这些问题与生成句子片段而不是完整的句子有关。如果我们从一个随机的单词开始,去掉标点符号,或者试图在一定数量的单词后任意结束句子,就会发生这种情况。 Markovify 通过记录所有可能的首字、保留所有标点符号、记录所有结束状态来处理这些问题。Markovify 还确保我们不会生成语料库中已经存在的句子。

2.野外的马尔可夫链文本生成器

虽然马尔可夫链文本生成器可以进行微调或与其他模型结合,以创建强大的应用程序,如谷歌搜索或手机上的预测文本,但它们也只是一种使用非常简单的快捷方式模仿智能的有趣方式。

马尔可夫链文本生成器的一些例子:

  • 链发明精神错乱,一个反人类的卡片答题卡生成器。
  • /u/user_simulator ,一个基于用户评论历史生成评论的 Reddit 机器人。
  • Insta-Trump!,特朗普演讲生成器。
  • Tay ,这是一款微软聊天机器人,它被设计成基于与 Twitter 上的人的互动来做出回复。然而,它在不到 24 小时内变成了一个热爱希特勒的性爱机器人,这要感谢巨魔给它提供了煽动性和攻击性的推文,并立即被拿下。
  • shartificialintelligence.com,“世界上第一家完全由机器人文案组成的创意广告公司。”

3。创建我们自己的马尔可夫链文本生成器

为了创建我们自己的马尔可夫链文本生成器来生成模仿纽约时报的假标题,我们首先需要获得真实标题的语料库,然后我们使用马尔可夫链在这些标题上训练我们的模型。

从《纽约时报》下载真正的头条新闻

我们将使用去年《纽约时报》和《T21》的所有标题。我在这里描述如何得到它们。

[## 从《纽约时报》收集任何时期的数据

Python 中的简单指南

towardsdatascience.com](/collecting-data-from-the-new-york-times-over-any-period-of-time-3e365504004)

或者,您也可以对任何其他文本语料库执行此操作。文本越多越好。你只需要遵循由 markovify 包指定的格式规则就可以把它变成一个可用的语料库。

在我们开始之前,加载依赖项。

import pandas as pd
import markovify
import random

加载独特的标题。

headlines = pd.read_csv('NYT.csv', parse_dates=['date']).drop_duplicates(subset='headline').reset_index(drop=True)['headline']

《纽约时报》过去一年的独特标题。

我们有 46,135 个标题输入到我们的模型中。

使用 markovify 训练我们的模型

为了训练我们的模型,我们给 markovify 我们的标题语料库和我们想要的 n 元语法的大小。

model = markovify.NewlineText(headlines, state_size=2)

我测试了一元模型、二元模型、三元模型,发现二元模型在这种情况下给出了最好的概率一致性,所以这就是我们选择state_size=2的原因。

4.制造假标题

告诉模型生成一个假标题也很简单。

model.make_sentence()

我们还可以生成谈论特定话题的标题,比如当前的疫情。由于没有内置的方法来做到这一点,我不断地一个接一个地生成标题,如果它们包含至少一个与主题相关的预先指定的单词列表中的单词,就保留它们,直到我达到我想要的标题数量。

关于疫情的假标题:

冠状病毒已经赢了

总统赦免冠状病毒本身

你的访客应该知道冠状病毒

谋杀率惊人。病毒是冲着你来的?

冠状病毒成了圣人。但是首先,他的身体必须被释放

在充满枪支的漫画世界中半心半意的千禧年冠状病毒准备

当冠状病毒衰退时,堕胎是“合适的”

波兰和匈牙利利用冠状病毒在美国人中间挑拨离间?

冠状病毒导致 N.C.A.A .停止销售假冒的抗冠状病毒牙膏

爱泼斯坦原告敦促安德鲁·阿尔伯特·克里斯琴对性玩偶“全盘招供”,玛丽·雪莱创造了“弗兰肯斯坦”,然后是病毒

为了好玩,让我们尝试一个不同的话题——猫!

topic = ['cat', 'cats', 'kitty', 'kitten', 'kittens']

在变焦会议上为一只猫大吵大闹

掌握放牧数码猫的艺术

我们在衰退?永远养你的猫

他 22 磅重的猫太大了,无法保持安全

有小狗和小猫的房地产年

这些地方可能会没有爆炸的小猫

两只猫是美国第一批测试其安全团队的宠物

在奥地利,这是一个关于鬼魂、黑魔法和谋杀猫的俗气故事

一只黑猫为地球上令人不安的警告承担了一些责任

他在变焦会议上扔了一只猫后,他们的浪漫开始了

猫凯伦正要去和《纽约时报》的经理谈一谈。

我们可以将任何单词作为主题的一部分,因为纽约时报至少在一个标题中使用过它。这个词出现得越频繁,我们的模型就越有创意。

感谢,jsvine ,让这个过程变得如此简单!

5.改进我们模型的方法

这篇文章中的所有标题都是人工策划的。虽然我们的马尔可夫链文本生成器对于这样一个简单的算法表现得非常好,但它只是做了它被告知的事情。我们没有告诉它如何变得有趣。我们没有告诉它英语是如何工作的。我们的模型无法知道它是否有趣,甚至语法是否正确。我们得帮点忙。

正常输出:

这些标题有些有道理,但有些没有。

这是机器人社区内部的一场辩论——对于生成自然语言的机器人,我们应该允许多少人为干预?

听说过 @horse_ebooks 吗?这是一个非常受欢迎的 Twitter 机器人,因为人们在他们认为是概率的东西中看到了的高雅艺术。但是当发现只是有人假装概率时,推特被激怒了。

这是个难题。一篇关于名为@ headlinetron的 Twitter 机器人的文章很好地描述了这一点:

“如果纯粹是机器人,那就不好笑了。但如果太人性化,就没意思了。没有人希望看到一个纯粹的马尔可夫链生成器生成的随机混杂的单词沙拉,但也没有人希望看到某个家伙假装成机器人,”埃尔南德斯说。

通常答案是生成大量的句子,然后在最少的人工干预下挑选出最好的句子。除了手工策划,我们还可以做其他事情来改进我们的模型(直到它变得太好而不好笑):

  • 增加语料库的大小。
  • 与其他模型结合以创建集合模型。
  • 使用其他算法,例如神经网络(尽管我进行了初步测试,将 markovifytextgrnn 进行对比,结果 markovify 胜出)。

6。更多头条!

寻找一个棘手的情况

中国审查人员的工作日记

医生来拯救 2020 年夏天

我们从纽约时报学到了什么

内衣广告失去了如履薄冰的艺术

脸书是如何试图将“玉米卷星期二”注册为商标的

发微博抱怨我偏执的女房东的难以形容的代价

对于一些恐怖小说作家来说,没有什么比学生贷款更可怕的了

百老汇关闭了,但它的“施虐者”钢琴家仍然接受请求

每周健康问答:我们都在了解你妻子的垃圾

zoomers vs . Boomers——使用 Transformers 对 Twitter 用户进行世代分类,并进行世代分析

原文:https://towardsdatascience.com/zoomers-vs-boomers-5851a0df885d?source=collection_archive---------47-----------------------

作者:胡安·帕埃斯人、布伦特·鲍斯格、大卫·戴、萨米·坎德克、悉达多·谢特卡尔和伊迪·周

这个项目的目标是创建一个模型,根据给定 Twitter 用户的个人资料和推文的内容对他们进行分类。年龄分类的应用可以包括有针对性的数字体验,以及年龄验证和分析各年龄组的流行趋势。发表在《PLOS 一号》上的研究也启发了这个项目(【https://doi.org/10.1371/journal.pone.0183537】T2)。PLOS 小组使用元数据和推文将推特用户分为三个年龄组。在此基础上,来自 Twitter 的用户信息和他们的推文被收集起来,并按年龄分为四代——Z 世代(18-25 岁)、千禧一代(26-40 岁)、X 世代(41-55 岁)和婴儿潮一代(56-76 岁)。我们试图利用基于从个人资料中收集的元数据和他们过去十条推文的内容的模型对他们进行分类。

我们能够从大约 2300 个分布在四代人之间的 Twitter 个人资料中收集信息。由一个说英语的人运营的 18 岁以上的 Twitter 个人资料被搜集用于 tweets 和元数据来创建我们的数据集。使用这个数据集,基于元数据及其推文的统计细微差别设计了新功能。接下来,我们应用了一种基于迁移学习的方法,对 Google 开发的变压器双向编码器表示(BERT)模型进行了微调。该模型为 tweet 生成嵌入,以捕获上下文信息,并生成逻辑,显示模型的原始预测,即一组给定的 tweet 属于一个类别。

生成的逻辑和嵌入与元数据要素一起用于创建集合模型。测试了各种模型,但 CatBoost 梯度增强是表现最好的,总体精度约为 60%。该模型在 Z 代上存在相对超额表现的问题,因为它以大约 80%的准确度对该组进行了分类。此外,该模型是在来自老一代的较少样本上训练的。我们的模型可以用更多的数据进行改进,包括每个配置文件的 tweets 数和获得的配置文件数,但由于时间限制、GPU 限制和 API 访问,这是不可能的。尽管有这些问题,我们的年龄预测模型比基线随机预测模型提供了巨大的提升。

数据采集和预处理

我们曾试图获得官方 Twitter API 密钥,但 Twitter 没有及时回应。因此,一个名为 GetOldTweets3 的非官方 Twitter API 被用来收集数据。这个库允许我们查询符合一般搜索标准的推文,如文本内容、推文位置和推文时间戳。

搜索标准是为不超过一周的推文设置的,包含短语“生日快乐”,括号中有数字年龄及其正确的后缀(例如,“18 日”、“19 日”、“20 日”、“21 日”等)。)从 18 岁到 90 岁。这个短语很重要,因为包含它的推文通常包括生日的个人的 twitter 句柄。例如,“21 岁生日快乐@人”暗示@人年满 21 岁。因此,使用以下代码为每个年龄组收集了 2000 条符合搜索标准的推文:

数据抓取

然后,符合所需格式的 2000 条推文中的每一条(每个年龄的 2000 条推文中不到 25%符合这种格式)都被抓取到紧接在生日短语之前或之后的 twitter 句柄,以识别庆祝他们生日的用户。从每个用户那里收集了 10 条推文作为样本,每个样本包括生日祝福者的用户名、推文 ID、永久链接、文本内容、发布日期、转发次数和收藏次数、提及次数、标签、推文回复者用户名(如果适用)以及推文的地理位置(如果适用)。然后,对每条抓取的推文进行人工审查,删除使用外语的用户、年龄明显不正确的用户(例如,布兰妮·斯皮尔斯被错误地识别为 70 岁)或其账户属于公司或组织而非个人的用户(例如,Old Spice、BBC 等)发出的推文。)

在查看推文数据集后,来自单个用户的 10 条推文被合并成一个样本,该样本包括用户的所有连接推文的字符串,以及调整后的元数据,如最小、最大和平均转发数和收藏夹数。这样做是为了将每个样本与单个用户相关联,从而将数据集从大约 23,000 个样本减少到大约 2,300 个。此外,个人年龄被重新划分为四个不同的类别。18-25 岁的用户归类为 0 类(“Z 世代”),26-40 岁的用户归类为 1 类(“千禧一代”),41-55 岁的用户归类为 2 类(“X 世代”),56-76 岁的用户归类为 3 类(“婴儿潮一代”)。年龄超过 77 岁的用户被丢弃,尽管此操作并没有显著减小数据集的大小。在为每个用户收集了推文和推文元数据之后,网络搜集库 BeautifulSoup 用于搜集每个用户的关注者和追随者数量,因为这些数量无法通过 GetOldTweets3 获得。

一旦我们的整个数据集被管理,它被分成 80/20 的训练集和测试集。这种在所有团队成员之间共享的静态划分的目的是确保每个团队成员单独测试的模型的分数之间更大的一致性和更准确的可比性。在特征工程之前,生成的数据集包含约 2,300 个样本,每个样本包含 17 个特征。

特征工程

收集数据后,基于元数据和自然语言处理(NLP)对推文内容的洞察,生成了附加特征。使用了几个 python 库来生成这些特性:BeautifulSoup 用于抓取元数据,nltk 用于情感分析,better_profanity 用于脏话检测,enchant 用于有效英语检测。下表列出了一些附加功能及其用途说明。

  • 追随者/追随比率:知名人士拥有更高的追随者/追随比率。对于那些有更多时间获得声望的老年人来说,这可能是一个指标。
  • 收藏夹的平均/最小/最大数量:有很多收藏夹的推文表明用户有一群忠实的追随者。高参与度的用户通常是年轻人和名人。
  • 平均/最小/最大转发次数:就像喜欢的次数一样,一条推文的转发次数可以表明用户关注度的高低。这种特征在年轻人和名人中很常见。
  • 每条推文的平均标签数:标签被用来关注当前最受年轻用户欢迎的 twitter 趋势。因此,每条推文的大量标签表明用户更年轻。
  • 每条推文的平均提及次数:在推文中频繁提及其他用户可能是与其他简档高度互动的指标,这可能表明用户的年龄组。
  • 推特频率:我们预计年轻人会比老年人更频繁地发推特。
  • 平均字数:我们预计年轻人可能会自发或冲动地发微博,与老年人相比,他们的微博会更短,而老年人可能会发更长、更深思熟虑的微博。
  • 情感得分(积极、消极、中立):情感可能表明 twitter 用户的态度,这可能与年龄组相关。
  • 标点符号用法:代表标点符号用法的特征可以表明用户在发微博时有多细致或小心,这可以表明年龄组。
  • 大写/小写百分比:与标点符号用法类似,不成比例地使用大写或小写可能代表粗心或情绪,这可能表明年龄组。
  • 包含脏话、俚语计数、有效单词百分比:这些功能旨在揭示脏话、网络俚语(如 omg、lol、tbh)和正确拼写单词的代际用法差异。我们使用外部库来确定单词是否拼写正确或包含亵渎。

探索性数据分析

下图显示了细化数据集中按年龄组划分的推文分布:

按年龄组分列的概况样本分布

由此得出的按年龄组划分的抓取推文分布显示,年轻用户比年长用户有更强的代表性。这在意料之中,因为 Twitter 是最受年轻人欢迎的社交媒体平台。当人工审查个人资料时,许多针对老一辈的“生日快乐”推文实际上是针对公司或组织的,这减少了老年群体的样本量。受此影响最大的是“婴儿潮”一代。

使用以下包含所有特征和目标变量“年龄组”的相关性热图,对不同年龄组的特征分布进行了探究:

特征关联热图

相关矩阵显示,目标变量“年龄组”有几个预测因素,如中性推文情绪、平均字数、每条推文的标签数、每条推文的平均提及数和关注者与关注者的比率。此外,收藏的平均数量和转发的平均数量之间有很强的相关性。平均字数和周期数之间也有轻微的相关性。这些高相关系数意味着这些对中的一个特征可能在训练期间被丢弃,因为两个特征对目标变量具有相似的影响。

接下来,绘制箱线图,以了解特征如何分布在几个年龄组中,从而进一步研究与“年龄组”高度相关的核心特征例如,下面包含的箱线图用于检查四个不同年龄组的 10 个 tweet 样本的平均字数分布。

字数统计框图

这个箱线图清楚地显示了最小 IQR、最大 IQR 和平均字数在老年人群中是如何增加的。这一信息进一步证实了平均字数可以作为可靠的年龄预测指标。

另一个有趣的特征是关注者数量按年龄组的分布。scraper 捕获了所有年龄组的名人账户和非名人账户,但名人在年龄组中的分布可能有所不同。下图显示了按年龄组划分的关注者数量分布情况:

按年龄组分列的追随者分布

这个箱线图表明,被归类为“千禧一代”和“婴儿潮”的名人比被归类为“Z 世代”和“X 世代”的名人更扭曲这些分布。此外,“Z 世代”的追随者数量分布更加紧密,这表明相比之下,名人在其他年龄组中的比例可能过高。或者,这可能是因为与老一代名人相比,来自“Z 世代”的名人相对默默无闻,因此追随者较少。

最后,单词云被生成来可视化不同年龄组在他们的推文中如何使用单词:

年龄组的词云

虽然像“谢谢”和“爱”这样的词在所有年龄组中都很常见,但也有一些词是某些群体所独有的。例如,从 Instagram 上照片和账户的链接中砍掉了“igshid”令牌。这让我们考虑在我们的模型中加入 n-gram 分析。

模型

我们希望设计一个模型,利用文本推文风格和元数据趋势(如推文频率或字数)的代际差异。此外,最近在自然语言处理方面的突破性发展使用了深度学习模型,称为变形金刚(https://arxiv.org/abs/1706.03762)被用来将序列表示为嵌入,或包含关于它们所代表的单词和句子的上下文信息的向量。出于这些原因,我们的分类器针对我们的分类任务微调了谷歌著名的双向编码器表示(BERT)模型的预训练版本,并将其结果与我们的元数据和生成的特征进行了集成。我们的模型可以分为如下两个阶段:

  1. 在第一阶段,来自 Python huggingface transformer 库的预训练 BERT 模型加载有用于分类的附加线性图层。该模型被调整以优化分类准确性,并且产生的类逻辑和序列嵌入被用作下一阶段的特征。
  2. 在第二阶段,元数据特征与由调整的 BERT 模型产生的嵌入和逻辑一起使用,以训练经典的机器学习模型,如随机森林和梯度增强分类器。

模型

阶段 1:从 BERT 生成逻辑和嵌入

Python 中的 huggingface 库提供了对预训练的 BERT 模型的访问,这些模型针对特定任务的应用程序进行了优化,这些应用程序是在数十亿个文档上训练的。特别是,BertForSequenceClassification提供了一个 PyTorch 模块,该模块由 BERT 编码器组成,并在分类任务的合并输出上添加了一个全连接线性层。因此,我们只需加载模型,训练它以最大限度地提高 Twitter 文本数据的分类准确性,并最终提取其预测逻辑(分类器最后一层的向量代表非规范化预测)和嵌入(来自逻辑之前一层的向量代表每个令牌的上下文信息)。四个提取的 logits 代表了模型对十个 tweet 样本属于四个类别中的每一个的置信度,嵌入是向量,粗略地代表了简档的 tweet 作为一个整体。在嵌入空间中彼此更接近的向量代表上下文相似性。

我们为训练集生成了逻辑和嵌入,方法是将它分成八个块,并一次在七个块上微调一个新模型。八个模型中的每一个都用于为维持块生成嵌入和逻辑。这样做是为了避免信息泄漏,因为模型已经看到了它被训练的数据的标签,并且如果它们也被用于训练,则可能产生过度自信的逻辑或过度具体的嵌入。在对七个训练块进行调优之后,针对维持块对每个模型进行评估。最后一个输出图层的结果包含维持配置文件的 logits,上一个图层的结果包含每个令牌的唯一嵌入。一个新序列的开始由第一个[CLS]分类标记来标记,并且它产生一个代表整个序列的嵌入(【https://arxiv.org/pdf/1810.04805.pdf】)。这是被提取出来用作我们的集合模型的特征的嵌入。

首先,定义以下函数来调整 BERT PyTorch 模块,并从模块的输出中提取嵌入和逻辑:

使用 PyTorch 训练和评估配置文件的函数

接下来,在导入必要的库并将我们的训练集分割成 8 个组块之后,BERT 一次调整 7 个训练组块,将简档的链接 tweets 截断或填充到 512 个令牌(BERT 允许的最大值),从而为 8 个组块中的每一个生成如下特征:

为训练集提取逻辑和嵌入

一旦为训练集的所有八个组块生成了逻辑和嵌入,就在整个训练集上训练一个最终调整的 BERT 分类器,并用于为整个测试集生成逻辑和嵌入。测试集的特征是通过对整个训练集进行训练而生成的,并对分类器进行如下评估:

为测试集提取逻辑和嵌入

这个深度学习分类器本身在测试集上实现了 50%的准确率,但通过在模型的第二阶段将提取的特征与我们的元数据和其他工程特征进行集成,这个分数得到了提高。

我们使用 t-SNE 维数约简可视化了我们的 tweet 嵌入的可分性。如下所示,减少到二维的微调 BERT 嵌入已经开始显示出一种模式。特别是,Z 世代嵌入和婴儿潮嵌入之间有很多可分性,而来自 X 世代和千禧一代用户的推文产生了类似的嵌入。

微调 BERT 嵌入上的 t-SNE

这一信息得到了测试集上 BERT 分类器的混淆矩阵的支持,如下所示。Z 世代的分类准确率最高,千禧一代和 x 一代之间的困惑最多

阶段 2:分类器集成

在这一点上,每个 Twitter 个人资料样本都标有元数据特征以及来自 BERT 分类器的 4 个 logits 和 768 个嵌入元素。这种组合的数据被用作经典机器学习分类算法的输入,我们试图用它来实现比纯文本模型更好的准确性。经过一些超参数调整后,几种不同的模型达到了 50 年代中期的精度,包括逻辑回归、随机森林和梯度增强。

然后,我们使用梯度增强和随机森林模型的特征重要性来消除无用的嵌入特征。在所有的嵌入特征中,只有一小部分被认为是最重要的特征被保留下来。这样做的好处是双重的——它大大减少了我们的模型训练时间,同时也提高了性能。

我们的最终模型是一个基于 CatBoost 库的相当简单的梯度提升分类器,对于这个特定的数据集,它的性能优于 XGBoost 和 LightGBM。交叉验证用于深度调整,迭代次数增加,而学习率降低,以优化我们的准确性。这是结果集合模型,其产生 59.76%的准确度:

简单集合分类器

考虑了其他涉及使用 n 元语法的基于 NLP 的方法,这些方法使用 tweet 样本中出现的前 1000 个最常见的一到四个字符标记来创建特征。这种方法不是很成功,因为 BERT 的逻辑和嵌入比每个 n-gram 特征都要好。这可能是由于稀疏的 n-gram 集,可以通过从不同用户收集更多的 tweet 样本来改善;然而,这也凸显了变形金刚作为 NLP 工具的强大,因为 BERT 能够在同一组 tweets 上产生可分离的特征。

分析

最终模型混淆矩阵

总的来说,我们的最佳模型具有 59.76%的总体准确度,这明显优于产生 25%准确度的随机预测器。然而,对混淆矩阵的进一步检查表明,该模型在区分 Z 世代人和其他代人方面明显更好,准确率为 80%。尽管其他几代人 50%的准确率还不错,但这些结果表明,Z 世代人在 twitter 上表现出了与其他几代人明显不同的特征。即使在仅基于文本的模型中,Z 世代的分类准确率也比其他任何一代都高。

回顾我们的最佳模型的特征重要性揭示了一些有趣的结论。根据特征重要性,我们微调的 BERT 模型的输出逻辑和所选嵌入排名靠前,这表明不同代人在网上表达自己的方式存在明显差异。然而,脏话计数和俚语计数功能的排名出奇地低。这表明每一代用户使用脏话和俚语的方式相似,这与互联网上年轻人随意使用脏话和俚语的刻板印象相矛盾。然而,俚语和粗话随着时间的推移会发生快速变化,可以采取措施根据某些单词和短语在几代人之间的流行程度对粗话和俚语进行分类。

此外,以收藏和转发形式出现的用户参与似乎不是非常可靠的年龄预测指标。这表明,不同代人制作的内容质量没有差别。然而,这可能只是群体思维的一个迹象,因为个人倾向于追随与他们观点相同的其他人,这可能会导致一些推文在这些回音室中得到更积极的接收,而不是整个推特群体都接触到它们。

相反,跟随者、跟随者以及跟随者与跟随者的比率是决定世代的非常重要的特征,这回避了模型是名人分类器还是世代分类器的问题。

按年龄组划分的用户关注者热图

按年龄组列出的用户关注率热图

关注者数量和关注者/关注比率的相关热图显示,87%的 Z 世代人的关注者少于 10,000 人,88%的人的关注者/关注比率少于 10,这是用于确定个人推特用户名人地位的软基准。这些数字可能是 Twitter 上非名人和名人之间的百分比。然而,其他三代用户的分布则大不相同,有更多的用户拥有超过 10,000 名追随者,追随者与追随者的比率高于 10。这可以解释 Z 世代和其他几代人之间出现在原始混淆矩阵中的准确性差异的部分原因,这表明 Z 世代类可能被解释为伪非名人类,而其他几代人是伪名人类。

无论如何,Z 世代的优异表现并不能解释所有的差异,因为我们的模型仍然能够区分千禧一代、X 世代和婴儿潮世代,每一代的准确率接近 50%。此外,在通过完全删除关于关注者、转发和收藏的信息来“隐藏”可能创建伪名人类别的信息后,梯度增强分类器仍然能够达到 55%左右的准确率。这是对纯文本模型的一个重大改进,即使在隐藏信息以避免利用我们数据的名人分布之后。

结论

我们的模型展示了任何人都可以使用最先进的 NLP 工具来利用来自网络社交媒体的公共信息来创建新的有意义的信息。除了时间限制,最大的困难最终证明是我们缺乏干净、平衡的数据。虽然每个类别的用户数量相似,但大多数老一辈的生日愿望都是针对名人和机构的,这扭曲了我们基于元数据的模型的预测。此外,很难对接近年龄组临界值的个体进行分类,我们的标签程序虽然经过人工审查,但并不完善。也就是说,嵌入在推文和趋势中的信息仍然被有效地利用来创建一个良好的分类器,提供有趣的代际洞察。

例如,千禧一代被证明与婴儿潮一代和 X 一代有着非常相似的特征,尽管他们被老一代人排斥。事实上,仅仅根据推特内容来区分他们和老一代人是非常困难的。另一方面,Z 世代是最容易被推文内容和元数据分开的。这说明了 Z 世代在数字世界中成长的影响,他们在 Twitter 上的可分离性表明,他们对采用新技术的适应使他们能够在如何进行数字互动和交流中发展自己的集体身份。网络俚语和脏话的代际使用差异很小,这表明所有代人都能够适应快速变化的文化规范,从而对流行观点提出了挑战。

展望未来,这些方法不仅限于提取关于社交媒体使用的有趣事实,实际上可以用来对世界产生真正的影响。这项技术可能被证明在年龄分类起着重要作用的应用中是有用的,例如个性化数字体验或广告。此外,我们将基于迁移学习的模型与经典机器学习模型相结合的方法可以应用于利用最先进的 NLP 工具来完成其他重要的分类任务,如自杀预防和捕食者检测。自然,这些应用程序在数据可用性方面都会面临类似的挑战。但随着社会继续拥抱技术,从每天每秒共享的大量新数据中产生知识的新方法将继续出现。

posted @ 2024-10-16 09:02  绝不原创的飞龙  阅读(359)  评论(0)    收藏  举报