TowardsDataScience-博客中文翻译-2022-五十一-

TowardsDataScience 博客中文翻译 2022(五十一)

原文:TowardsDataScience

协议:CC BY-NC-SA 4.0

在 Heroku Cloud 上部署深度学习 Webapp 的技巧和诀窍

原文:https://towardsdatascience.com/tips-tricks-of-deploying-deep-learning-webapp-on-heroku-cloud-80ea9063211a

通过在 Heroku 服务器上部署基于 Tensorflow 的图像分类器 Streamlit 应用程序,我学到了一些东西

作者图片

Heroku 是 web 开发人员和机器学习爱好者中的一个著名平台。该平台提供了一种部署和维护 web 应用程序的简单方法,但如果您不熟悉部署深度学习应用程序,您可能会遇到存储和依赖问题。

本指南将使您的部署过程更加紧凑,这样您就可以专注于创建令人惊叹的 web 应用程序。我们将学习 DVC 集成、基于 Git 和 CLI 的部署、错误代码 H10、使用 python 包以及优化存储。

基于 Git 和 CLI 的部署

Streamlit 应用程序可以通过基于 Git 的 GitHub 集成或使用 Docker 来部署。基于 Git 是在 Heroku 服务器上部署任何数据应用程序的更快更简单的方法。

简单的基于 Git 的

可以使用以下方式部署 streamlit 应用程序:

git remote add heroku https://heroku:$HEROKU_API_KEY@git.heroku.com/<name of your heroku app>.git

git push -f heroku HEAD:master

为此,您需要:

  • Heroku API 密钥
  • Heroku App:通过 CLI 或使用网站。
  • 基于 Git 的项目
  • Procfile
  • Requirements.txt

基于 CLI

基于 CLI 的部署是简单易学的。

作者图片

  1. 在这里创建一个免费 Heroku 账号
  2. 使用此链接安装 Heroku CLI。
  3. 克隆远程存储库或使用git init
  4. 类型heroku loginheroku create dagshub-pc-app。这将使您登录到服务器并在 web 服务器上创建一个应用程序。
  5. 现在创建 Procfile ,其中包含运行应用程序的命令:web: streamlit run --server.port $PORT streamlit_app.py
  6. 最后,将代码提交并推送到 heroku 服务器git push heroku master

港口

如果您使用streamlit run app.py运行应用程序,它将产生一个错误代码 H10 ,这意味着服务器分配的 $PORT 未被 streamlit 应用程序使用。

你需要:

  • 使用 Heroku CLI 设置端口
heroku config:set PORT=8080
  • 在您的 Procfile 中进行更改,并在参数中添加服务器端口。
web: streamlit run --server.port $PORT app.py

调整 Python 包

这部分花了我两天时间调试,因为 Heroku cloud 有 500MB 的限制,而新的 TensorFlow 包是 489.6MB 。为了避免依赖性和存储问题,我们需要对 requirements.txt 文件进行更改:

  1. 添加 tensorflow-cpu 代替 tensorflow,这将使段塞大小从 765MB 减少到 400MB。
  2. 添加 opencv-python-headless 代替 opencv-python,避免安装外部依赖。这将解决所有 cv2 错误。
  3. 移除除数字、枕头流线型之外的所有不必要的包装。

DVC 一体化

作者图片

从 DVC 服务器成功提取数据需要几个步骤。

  1. 首先,我们将安装一个构建包,它将允许使用 Heroku API heroku buildpacks:**add** --**index** 1 heroku-community/apt安装 apt 文件
  2. 创建一个文件名 Aptfile 并添加最新的 DVC 版本https://github . com/iterative/DVC/releases/download/2 . 8 . 3/DVC _ 2 . 8 . 3 _ amd64 . deb
  3. 在您的 app.py 文件中添加额外的代码行,以从远程 DVC 服务器获取数据:
**import** os

**if** "DYNO" **in** os.environ **and** os.path.isdir(".dvc"):
    os.system("dvc config core.no_scm true")
    **if** os.system(f"dvc pull") != 0:
        exit("dvc pull failed")
    os.system("rm -r .dvc .apt/usr/lib/dvc")

之后,提交并推送你的代码到 Heroku 服务器。成功部署后,该应用程序将自动从 DVC 服务器拉数据。

优化存储

优化存储有多种方法,最常用的是使用 Docker。通过使用 docker,你可以绕过 500MB 的限制,你也可以自由地安装任何第三方集成或软件包。要了解更多关于如何使用 docker 的信息,请查看本指南。

用于优化存储:

  • 仅在 requiremnets.txt 中添加模型推理 python 库
  • 我们可以通过使用dvc pull {model} {sample_data1} {sample_data2}..从 DVC 提取选择性数据
  • 我们只需要模型推理文件,所以将其余文件添加到.slugignore中,它的工作方式类似于.gitignore,以了解更多信息,请查看 Slug 编译器
  • 从服务器成功拉取数据后,删除.dvc.apt/usr/lib/dvc 目录。

结果

最初的块大小是 850MB,但随着存储和封装的优化,最终的块大小减少到 400MB。我们用一个简单的命令解决了错误代码 H10,并添加了 opencv-python-headless 包来解决依赖性问题。本指南旨在解决 Heroku 服务器初学者面临的一些常见问题。

基于 Docker 的部署可以解决很多存储问题,但它带来了复杂性和缓慢的部署过程。您可以使用heroku container:push web,但在此之前,您需要构建 docker,测试它,并在本地解决所有问题,然后才能推送它。这种方法是高级 Heroku 用户的首选。

下一个挑战是用 webhook 部署您的 web 应用程序。这将允许您从任何平台自动化整个机器学习生态系统。自动化过程将包括创建一个运行 shell 命令的简单 Flask web 服务器。

额外资源

原载于 2021 年 12 月 24 日KDnuggets

这是探索我们最佳深海潜水的季节

原文:https://towardsdatascience.com/tis-the-season-to-explore-our-best-deep-dives-d5388478c103

伟大的数据科学博客文章有各种形状、格式和阅读时间;制作一个简短有效的教程或一个快速、范围广泛的解释器需要很多技巧!不过,TDS 团队确实对我们的作者擅长撰写的那些篇幅较长、发人深省的文章情有独钟——最近几周,我们已经发表了一批令人印象深刻的文章。

如果你错过了它们(或者当它们第一次出现在你的订阅中时没有时间阅读),本周我们收集了一些过去一个月中的突出深度潜水。它们涵盖了广泛的主题和方法,并以耐心、热情和对细节的关注来完成。享受你的阅读——别忘了把你想留到下一趟航班、穿越市区的公交车或安静的下午阅读的任何文章加入书签。

  • 了解一个简单却强大的心智框架 。“启发法”听起来可能像一个花哨的词,但正如 Holly 徽解释的那样,它实际上是一种清晰、简化的解决问题的方法。不服气?Holly 的帖子提供了清晰的定义和实用的数据科学用例供您考虑。
  • 全面看最新的物体探测 。有深潜,然后有克里斯·休斯伯纳特·普伊格坎普约洛夫 7 车型概述。不要让它长达 50 分钟的阅读时间吓到你——它引人入胜,易于理解,并且提供了理论和实践的完美结合。
  • 需要一个无障碍的 RL 介绍? 像很多新兴领域一样,强化学习偶尔会觉得有点力不从心:这么多流行语!Kay Jan Wong 在她的最新帖子中带来了令人耳目一新的清晰度,带我们了解了基本概念以及六种常用的算法。

妮娜·梅尔卡多在 Unsplash 上拍摄的照片

  • 普通最小二乘法(OLS)的一个有用替代,解释 。Sachin Date 在将复杂的理论主题转化为可接近且可操作的想法方面有着特殊的诀窍。他对广义最小二乘(GLS)估计的深入研究也不例外:它提供了一种处理呈现异方差(即非常数方差)的数据集的强大方法。
  • 如何培养更快、更高效的开发流程 。如果您在数据科学或 ML 中从事大量代码的工作,您可能会遇到相当多的笨拙、混乱或不灵活的代码库。Betty LD 的《重构入门》是避免这些陷阱的关键原则、规则和最佳实践的有益综合。
  • 追随帕斯卡和费马 的脚步。对于概率论的扎实阅读,不要错过纳曼·阿格拉瓦尔的首次 TDS 帖子。这是一篇关于赌徒破产问题的全面的、公式丰富的文章,这个问题已经让统计学家忙碌了几个世纪。

还有心情多读书吗?首先,脱帽致敬;其次,这里有几个很棒的——而且明显更短的——推荐帖子:

感谢您支持我们发表的作品。如果你想产生最大的影响,考虑成为中级会员

直到下一个变量,

TDS 编辑

要提高你的数据技能,找一个有激情的项目

原文:https://towardsdatascience.com/to-grow-your-data-skills-find-a-passion-project-a7e9c69b161

无论你称之为修修补补、动手学习,还是“我不确定我在做什么,但很有趣”,找到一个你感兴趣的话题,收集一些相关数据,然后看看接下来会发生什么,这都是非常有价值的。本周,我们将重点介绍四个奇妙的激情项目,它们将帮助你学习一些新技巧,同时也可能激发你的创造力。

照片由 Gary TouUnsplash 拍摄

  • 回办公室学习逻辑回归 。无论你是邓德-米夫林-永远的超级粉丝,还是从未看过一集《办公室》,威尔·克劳利的新教程展示了任何话题如何在正确的框架下变得有趣和引人入胜。在这里,Will 使用虚构的(但仍然是传奇的)造纸公司来解释领先分数和二元逻辑回归模型的来龙去脉。
  • 通过骰子游戏的机制了解强化学习 。正如 Thomas Dybdahl Ahle 在他在 TDS 上引人入胜的第一篇帖子中告诉我们的,骗子的骰子是一个看似简单的游戏。试图教一个人工智能玩它促使他探索像反事实后悔最小化这样的概念和像在浏览器中服务 PyTorch 模型这样的技术挑战。

我们每天都发布新的优秀实践教程,所以如果你有心情浏览,请查看我们的专栏收集一些最好的教程。

像往常一样,这里有太多的好书要与你分享,但我们不能不推荐一些我们最近的亮点:

  • 在 2021 年几何和图形 ML 令人兴奋的一年之后, Michael Bronstein 和 Petar Velič ković与领先的专家对话看看 2022 年该领域将会发生什么
  • 随着深度学习中使用的数据集规模不断增长,从业者面临新的挑战。 Suneeta Mall 分享了最近的进展的全面概述,这些进展使数据科学家和 ML 工程师能够扩大他们的运营规模。
  • 我们喜欢将数据、机器学习和环境影响结合在一起的深度探索。丹尼尔·加西亚的最新帖子讨论了垃圾分类技术和他建立分类器的工作,这将有助于当局改善他们的分类和回收工作。

如果你最近在做一个令人兴奋的项目——一些激励你推动你的工艺和尝试新方法的事情——我们很乐意听到它(我们的读者也一样)。

感谢您的时间和您的支持,直到下一个变量,

TDS 编辑

为了改善你与 DS 利益相关者的关系,给他们提供一份菜单

原文:https://towardsdatascience.com/to-improve-your-relationships-with-ds-stakeholders-offer-them-a-menu-dfc15f3006c6

通过分享你所能提供的和你所需要的投入,使统计、人工智能和 ML 更加透明

日出照片拍摄于 Unsplash

数据科学很难。我们投入大量的时间和精力来发展我们通过模型进行推理的能力,并在实践中应用来之不易的直觉。解释和总结足够多的逻辑回归模型,我们开始忘记理解什么是线性对数-优势关系的艰苦工作。

这是一个相对简单的方法。想象一下,当我们说这样的话时,我们可怜的利益相关者,“嗯,第一个模型没有对结构做任何假设——它将数据集视为完全平坦的。如果我们改变生成模型以假设一组集群中的混合成员,我们可能会提高性能,特别是在冷启动时。”

🥺

“哥们,什么?”我想当我在一次会议上听到这句话时。是我说的。

最终,我们数据科学家只有在理解我们自己组织中的实用机制的情况下,才能通过模型推动价值。这必然要求我们和我们的对手相互学习。你的模型会被如何使用?如果你能更好地预测转换率或流失率,解决这些问题的团队会如何使用你的工作呢?

在通往富有成效的合作和高度信任的关系的道路上,没有简单的答案。但是在这里,我们将开发一个快捷方式,一个选项菜单的概念,使我们的利益相关者沟通更加顺畅和透明。我们将专注于定义交付单元、我们的可重复项目表单,以及它们给组织带来的相关成本。这将帮助每个人做出明智的权衡决定。

如果您是一名数据科学贡献者或领导者,希望加快并顺利完成项目启动和执行,请继续阅读。

菜单包括提供的项目

菜单准确描述了顾客收到的东西。在我们的案例中,我们希望先发制人地为团队或个人勾勒出可能的数据科学交付成果的范围。这对许多建模者来说是双重挑战。第一,我们常常倾向于把每一个问题都当成一张白纸来处理。新鲜地处理问题是这份工作的一大乐趣,思考我们项目的形式会让他们觉得千篇一律。第二,忘记帮助我们在内部交流的行话,以及在外部产生共鸣的我们的学科和工艺描述,是一个严峻的挑战。然而,这些挑战可能是有趣的机会,你可以用他们能接触到的具体例子来问候你的同事。

考虑这些例子,在你为你的非 ML 从业者同行写的指南的想象环境中:

  • GLMs:这类模型允许我们对不同变量之间的关系进行建模,同时控制其他变量,并提供简单明了的解释。例如,假设您对单个客户的支出感兴趣,并发现我们的高收入客户在我们的产品上花费更多,我们的老年客户也是如此。但我们的许多高收入客户在职业生涯中已经领先,年龄也更大。在控制了其他因素后,哪一个因素会影响消费?这些模型可以回答这类问题。
  • 黑盒神经网络:这些通常很难解释,实际上几乎不可能。但是他们能够学习更复杂的关系,并且经常比简单的模型做出更好的预测。如果我们有办法利用准确的预测,这可能是一个明智的选择。

“但是,”我听到你担心,“我们知道怎么做的事情太多了!这将是全面的吗?这会让我们陷入困境吗?”

合理的担忧,首先,不:在实践中,你可能永远不会为你和你的团队能做的每件事列出一个全面的目录。菜单也不是一个厨师能做的所有菜的综合清单。这可能是一件非常好的事情,前提是你要让你的内部客户明白,这不是你所做的全部,而是一些你已经很熟悉的事情。如果您愿意,还可以推荐一些常见的使用案例。越来越熟悉你所做的事情通常会让你在其他部门的朋友更多地了解你可以做什么。“这是我们一直面临的一个问题,”许多愉快、富有成效的对话开始了,“我看了一下您团队的‘关于我’页面,没有看到任何类似的内容,但这是您可以帮助解决的事情吗?”

第二,我在实践中还没有看到这种分类。典型的 DS 项目包括对后续步骤或未来工作的号召。更典型的是,例如,您为合作伙伴交付的第一个逻辑回归模型将导致需要不同的、更复杂的方法的后续请求。如果你想变得有趣,你甚至可以对你的选项进行排序。

菜单包括相应的费用

如果对我们的工作进行透明、平易近人的描述还不够有挑战性,那么描述其成本会带来痛苦。我们在这里扩大了我们的比喻的范围:我们都熟悉的典型菜单提供简单明了的价格,数据科学工作的全部成本是数据科学和合作伙伴团队努力的精心混合。在这里,我们的目标是让同行清楚地了解我们的工作单元是什么。这一点至关重要,因为我们数据科学家和我们的合作伙伴都在权衡他们对我们的要求以及他们如何支配自己的时间。

让我们回到之前的两个例子:

  • 一旦我们(1)以我们决定要了解的因变量和自变量的形式开发了范围(2)建立了数据管道,GLM 就需要我们团队的一名成员花费大约 1-2 周的时间集中精力来改变我们的第一遍模型。此交付件包括一份报告(幻灯片),其中显示了变量的显著影响,以及哪些是实质性的影响。
  • 根据问题的复杂程度,基准神经网络可以简单,也可以复杂。在简单的分类案例中,假设一个开发的范围和一个现有的数据管道,一个数据科学家可以在 2 到 4 周内完成一个基准神经网络。该交付件包括对尝试方法的描述和模型性能的报告。

请注意对关注工作的的重复引用。这是一个需要强调的重要区别:你的信息必须是清楚的,这些估计没有假设竞争的优先权。这可以引发关于你的团队应该做什么的对话。保持这些对话公开透明,这是一件非常积极的事情。还要注意的是,可交付成果并不也不承诺特定的绩效水平。

“但是,等等,”你可能会想,“难道你没有回避确定项目范围和建立管道需要多长时间吗?”这是一种说法,但我鼓励你把这种透明度的增加理解为导致周转时间不确定的原因。尽最大可能列出导致变异的未知因素。对于我们的商业朋友来说,询问范围界定需要多长时间是很自然也很公平的。这个问题很难回答,因为它需要协作。即使他们有非常明确的非常适合您的 DS 团队的问题,沟通和记录意图也需要时间。同样,当存在一个现有的、干净的数据集(比如一个用于月度 KPI 报告的数据集)时,构建模型通常要容易得多,也快得多。(当一个建模用例不能与任何为报告目的而做的假设共存时,就会出现例外。)同样,这往往会促进更多的相互依赖的交流,这本身是一件非常好的事情。

同样,这里的目标不是对周转时间进行精确的估计。而是分享你的挑战和机遇,这样你和你的利益相关者可以互相帮助,消除挑战,创造更新、更大的机遇。如果有帮助的话,使用范围或 t 恤尺寸来宣传不确定性,给自己争取一些回旋的空间。

菜单已发布

最后,一个简单的问题:你的菜单需要易于访问。使用您组织选择的任何知识管理工具发布它。Github pages,一个 google 站点,或者你的 Slack 频道中的一个链接,任何可以完成它的东西。这里没有必要把事情搞得太复杂,它只需要是可访问的,最好是协作的。(在线提问比写邮件容易得多。)

入门指南

正如我上面所说的,这种方法有一些挑战,开发你的菜单可能会引起一些担忧。从某种意义上说,你是在承诺周转时间。如果您或您的团队陷入了将此与“我们在两周内扭转任何模型”这种形式的 SLA 混淆的陷阱,您会很快发现自己承诺过多,压力过大。保持任何隐含承诺的可行性和清晰性是至关重要的。

这里有几个步骤可以让你写出初稿:

  1. 从头脑风暴列出你最近完成的项目开始。
  2. 对于每个项目,仔细考虑并记下识别数据、清理数据、转换数据,以及最终训练模型和测量性能的典型步骤需要多长时间。
  3. 对于每个项目,严格限制或描述团队控制下的工作部分。然后,透明地描述所需的输入。保持最小范围是很重要的。我们大多数建模者会很高兴地修补一个有趣的建模问题,直到宇宙热寂。用一种非常有用的方法给你的第一次分娩加上一个上限,以防止完美成为好的敌人。
  4. 仔细考虑每一步的进展情况,以及出现的任何障碍是否会重复出现。你的周转时间被大大推迟了吗?一个快乐的意外因为一切都很完美?
  5. 对于每个项目,使用您在上一步中收集的信息,选择您认为完成另一个相同形式的项目所需的最短时间,并将其作为范围的下限。如果你是为一个团队这么做的,小心考虑不同成员熟悉程度的差异。让自己偏向更长的时间。

以一个最小的工作示例结束

最后,我们将把下面的整个示例菜单放在一起。想象这是一个网站的形式,在你的组织的私有网络内部,面向你的内部潜在客户。

我希望你和我一样发现这个方法很有帮助。在数据科学项目的合作中,你还发现了哪些有帮助的方法和沟通技巧?

【RaDSkills 团队期待与您合作!我们是一个拥有各种技术学科技能的 DS 团队,这里我们收集了我们已经完成的项目的样本,以及他们的输入要求和大致周转时间的草图。这些不是我们能做的唯一的事情,我们鼓励人们带着问题去寻求帮助。我们希望这份菜单能激发我们一起工作的想法!

GLMs:这类模型允许我们在控制其他变量的同时,对不同变量之间的关系进行建模,并提供直观的解释。例如,假设您对单个客户的支出感兴趣,并发现我们的高收入客户支出更多,我们的老年客户也是如此。但我们的许多高收入客户在职业生涯中已经领先,年龄也更大。在控制了其他因素后,哪一个因素会影响消费?这些模型可以回答这类问题。

一旦我们(1)确定了我们想要了解的因变量和自变量的形式的范围,( 2)建立了数据管道,GLM 需要我们团队的一名成员花费大约 1-2 周的时间专注于改变我们的第一遍模型。此交付件包括一份报告(幻灯片),其中显示了变量的显著影响,以及哪些是实质性的影响。

黑盒神经网络:这些通常很难解释,实际上几乎不可能。但是他们能够学习更复杂的关系,并且经常比简单的模型做出更好的预测。如果我们有办法利用准确的预测,这可能是一个明智的选择。

根据问题的复杂程度,基准神经网络可以简单,也可以复杂。在简单的分类案例中,假设一个开发的范围和一个现有的数据管道,一个数据科学家可以在 2 到 4 周内完成一个基准神经网络。该交付件包括对尝试方法的描述和模型性能的报告。

这不是我们能做的一切,如果您有这里没有提到的想法,请联系我们!

原载于 2022 年 1 月 5 日https://Easter . ai

要在任何行业产生影响,领域知识至关重要

原文:https://towardsdatascience.com/to-make-an-impact-in-any-industry-domain-knowledge-is-critical-bdd93a304a1d

作者聚焦

Abiodun Olaoye 讨论了他在可再生能源方面的工作

在 Author Spotlight 系列中,TDS 编辑与我们社区的成员谈论他们在数据科学领域的职业道路、他们的写作以及他们的灵感来源。今天,我们很高兴与 阿比奥顿·欧劳耶 分享我们的对话。

阿比奥顿·奥劳耶的摄影师

Abiodun Olaoye 是一名经验丰富的数据科学家,在德克萨斯州奥斯丁的 RWE 可再生能源公司担任高级性能工程师(数据分析)。他于 2019 年获得了麻省理工学院(MIT)机械工程和计算博士学位。他获得了多项学术奖学金,包括尼日利亚总统创新与发展特别奖学金(PRESSID),并三次获得拉各斯大学捐赠奖学金。

您的数据科学学习之旅是怎样的?

我对数据科学的兴趣最初是在麻省理工学院读研究生时出现的,当时我正在对 2014 年左右在拖曳水池实验室的船只上进行的实验中的传感器数据进行预处理。尽管那时我还没有像今天这样正式接触数据科学,但我当时所做的分析基本上都是时间序列分析。

也许是因为重点更多地放在科学研究海洋结构和船只在海洋波浪中的性能上,我没有意识到我已经掌握了多少数据科学的基础知识。当我开始参加 Udemy 和 Cousera 的课程时,这确实帮助我顺利地完成了数据科学技能的正规化。比如我用 MATLAB 写了几个数据处理和分析的程序,用了 5 年左右,这让我学习 Python 相对容易。

此外,我在线性代数和数值模拟方面的所有计算科学和工程研究生课程为我作为数据科学家的技能提供了一个坚实的起点。因此,老实说,我的学习曲线并不太陡。

随着你职业生涯的发展,你的数据科学和机器学习方法有没有随着时间的推移而发展?

绝对的。当我刚开始学习数据科学时,我喜欢使用超参数来提高 ML 模型的性能。然而,随着我的经验增加,我在一个给定的项目中花费了更多的时间来扩展我的领域知识,以提高我的特征工程技能,而模型调整成为了锦上添花。因此,我的方法逐渐从以模型为中心转向以数据为中心的建模。

在解决问题方面,我从用玩具数据集解决一般问题发展到解决更实际的问题,重点是将最先进的数据科学技术应用于现实世界的问题,特别是在可再生能源行业。展望未来,我看到自己将数据科学的应用扩展到解决工程研究问题和/或通过数据驱动的方法实现基于物理的解决方案。

你在科学、工程和数据方面的背景如何影响你目前在可再生能源方面的工作?

拥有涵盖机械工程和计算科学与工程领域的博士学位,我已经为我的职业生涯打下了广泛的基础。

一方面,我在研究生学习期间为机械部件所学的流体流动物理、动量和能量原理知识构成了我在可再生能源行业领域知识的基础。

另一方面,我研究生学习的计算方面涵盖了高级线性代数以及非线性和偏微分方程的数值解,这些都与数据科学中的优化和建模相关。有了这些知识,我就能够应用先进的数据分析技术,从传感器数据中获得可行的见解,从而提升我们可再生能源资产的性能。

你有什么建议可以和那些想找可持续发展相关工作,但不知道如何着手的人分享吗?

当然——我对在可持续发展领域工作的坦率建议是,首先确定行业的哪些方面你最感兴趣,当前的挑战,以及在这些领域部署的最先进的解决方案。

这将有助于增加你的领域知识,这对在任何行业产生影响都是至关重要的。此外,我建议建立一个当前专业人士的网络(通过 Medium、LinkedIn 等。)通过分享文章和帖子来增加你对行业的了解和获得第一份工作的机会。

你已经写了几年关于数据和可再生能源的交集。是什么促使你与更广泛的受众分享你的知识?

可再生能源行业的数据从业者有研究和运营的机会,我们的资产在全球范围内每秒产生数千兆字节的数据,我们需要更好地了解这些数据,以提高这些资产的性能、可用性和可靠性。我相信我的文章可以帮助人们发现新的职业前景或研究兴趣,因为有大量的机会,而拥有数据技能和核心工程知识的专业人士相对较少。

此外,我开始更多地写作,因为我意识到我能够以初学者友好的方式分解困难的概念,这可以帮助点燃初级专业人员的兴趣,同时扩展专家的知识。

就个人而言,自从我第一次发现有机会通过应用最先进的数据科学技术来帮助加速世界能源转型,我就开始进行独立研究,开发开源 python 包,并撰写文章。

作为一个在最近引起很多关注的领域工作的人,你希望它在未来一两年内如何发展?

在未来几年,可再生能源行业将越来越依赖现代数据技术来存储、提取、集成、转换和模拟传感器数据,总体目标是通过提高涡轮机性能和可用性来增加收入,同时降低能源成本。

此外,AutoML 等技术的低代码云平台将有助于降低该行业新专业人士的准入门槛。最后,我希望看到更多的开源项目、跨组织计划和社区驱动的知识共享,这些行业(如信息技术)多年来从中受益匪浅。

要了解更多关于阿比奥顿的工作,并了解他的最新文章,请在媒体推特上关注他。为了体验 Abiodun 的 TDS 文章,下面是我们的档案中的一些突出的:

想和广大观众分享一些你自己的作品吗?我们希望听到您的意见

这个问题&是为了长度和清晰度而稍加编辑的。

要真正“把事情搞砸”,你需要一台计算机——量子计算机

原文:https://towardsdatascience.com/to-really-foul-things-up-you-need-a-computer-a-quantum-computer-9620746f1e87

量子误差的原因和影响

量子机器学习要不要入门?看看 动手量子机器学习用 Python

犯错是人之常情,但要真正把事情搞砸,你需要一台电脑。

保罗·埃尔利希

我是一个软件人。因此,很难承认保罗·埃尔利希肯定不是指硬件而是软件。经典计算机是容错设备。他们不会犯错。

这些计算机需要区分零和一——高电压和低电压的区别。只要有高电压,就是一,有低电压,就是零。这种离散化意味着误差必须相对较大才能被注意到。因此,经典计算机不会把 0 当作 1,反之亦然。

所以,无论何时计算出错,都是因为软件的原因。作为一个写软件的人,这是一个严酷的教训。不,这不是电脑的错。它是我的。

但是,在量子计算领域,情况完全不同。量子计算机保持连续的量子态——量子叠加态。它意味着一个量子位(或量子位)不是零或一,而是处于零和一的复杂(如在复数中)线性组合中。只有一个警告。一个量子位只有在叠加态,除非我们测量它。一旦我们测量它,它立即跳到零或一。

测量一个量子位会瓦解它的叠加态。

但是什么是精确的测量呢?我们都习惯于测量事物,比如距离、温度和时间。这涉及到某种评估。那么,我们需要评估一个量子比特吗?如果是,评估意味着什么?

我们可以更深入地玩这个游戏。事实上,在量子计算的早期,对于测量一个量子力学系统是否涉及人类思维,存在着一种批判性的话语。

今天,大多数科学家认为我们可以更广泛地理解测量。量子力学系统与其环境之间的任何信息交换都可以称为测量。在亚原子世界中,信息交换频繁。如果两个原子发生化学反应,那就是信息交换。如果一个电子从一个原子移动到另一个原子——我们称之为电——那就是信息交换。即使两个电子、光子或任何两个粒子发生碰撞,那也是信息交换。

我们生活在一个充满运动粒子的世界(地球)。所以,你不会发现任何一个自然的量子力学系统不与它的环境持续交换信息。所以,我们尽可能地冷却量子计算机,这样就不会再有移动的粒子了。此外,我们用电磁场限制和悬浮一个粒子,使它处于自由空间,与周围环境没有相互作用。

然而,我们需要允许一些相互作用来使用这个粒子作为量子位。我们需要控制它。很容易想象这是一个微妙的过程——最小的不精确都可能让粒子接触到它的环境。好了,你知道了——信息交换。

我们今天拥有的最好的量子计算机遭受着与外界不必要的相互作用。它们以噪音的形式出现,破坏我们的计算。

所以,现在我们对量子误差的来源有了基本的了解。让我们从编程的角度来看看它们是如何影响我们的量子位的。

量子位是一个二维量子系统。我们可以用一个叫做“psi”的向量来表示它——|𝜓⟩.

下图描绘了 psi 最重要的特征——𝛼和𝛽.这些是到基本向量|0⟩和|1⟩.的距离这很重要,因为它们的绝对平方表示测量量子位的概率为 0 (=|𝛼|)或 1 (=|𝛽|)。

作者图片

所以,我们假设量子位处于一种状态,我们以 0.25 的概率把它测量为 0。相应地,我们以 0.75 的概率将其度量为 1。

如果你在这种状态下看一百个量子比特,你会数出 25 个 0 和 75 个 1。

进一步说,我们可以用量子位工作,比如改变概率。假设我们把它们作为一个整体测量的概率加上 0.25。因此,如果我们在改变量子位的概率之前不去看它,我们最终会得到一个我们一直认为是一个的量子位。所以,我们会数到 100。

但如果在我们改变它之前,量子位与它的环境发生了相互作用,它会以 0.25 的概率跳到零。接下来的变化会把它从零带到一个测量到 1 的概率为 0.25 的状态。

比方说,在我们改变它们的概率之前,十个量子位与它们的环境相互作用。然后,我们会测量七或八个量子位元为零。所以我们只能数出 92 或 93 个。

越来越糟了!

我上面不是提到过量子位叠加是零和一的复杂(如在复数中)线性组合吗?我不想听起来很聪明。

几何上,复数把一维数线的概念扩展到二维复平面。

作者图片

i 表示满足等式I = 1的虚数单位。因为没有实数满足这个等式,所以部分 abi 是相互独立的。因此,我们在迄今为止的二维量子态向量空间中增加了第三维度。

结果看起来像一个球体,因为该空间中的所有向量都被归一化为长度 1 (|𝛼| + |𝛽| = 1)。这是布洛赫球。

作者图片

这个代表相位的额外维度,不会直接影响量子位元状态向量到基本向量|0⟩和|1⟩.的距离因此,它不会直接影响测量概率。

然而,当你处理一个量子位时——我们所做的——它的相位很重要。例如,哈达玛门把一个正相位的量子位(|+⟩)变成|0⟩,把一个负相位的量子位(|-⟩)变成|1⟩.

不幸的是,意外测量不仅会导致比特翻转(混合 0 和 1),还会导致相位翻转(混合正负)。

结论

我是一个软件人。导致量子计算错误的是硬件而不是软件,我对此并不满意。最终,要靠我们这些软件工程师想出算法来纠正这些错误,或者更好的是,想出对错误免疫的算法。

例如,IBM 最近宣布了一项总额为 10 万美元的奖金,用于在 IBM Quantum 的 7 量子位 Jakarta 系统上使用 Trotterization 模拟三粒子系统的海森堡模型哈密顿量。完成这项挑战的主要问题是应对噪音。

量子机器学习要不要入门?看看 动手量子机器学习用 Python

在这里免费获得前三章。

跳过,还是不跳过?这是一个问题

原文:https://towardsdatascience.com/to-skip-or-not-to-skip-that-is-the-question-a0c76925737e

分析和预测用户在 Spotify 上的行为:过去的互动似乎会推动未来的互动

照片由 EffyUnsplash 上拍摄

介绍

作为我在 BrainStation 数据科学训练营的顶点项目的一部分,我深入研究了音乐流媒体平台 Spotify 上的跳过行为。我的目标是观察用户如何在平台上互动,并了解哪些因素可能会驱动他们的行为。

总的来说,我希望探索如何改善用户体验,因为它与曲目跳过有关。我设想了一个响应式播放列表,它会对一首接一首的用户交互敏感。例如,如果一个用户跳过了连续的歌曲,并完全停留在他们播放的一首歌曲上,我可以提取用户的动机并根据需要重新构建播放列表吗?

这个项目是我探索用户动态听觉体验可能性的第一步。第一个目标是预测用户是否会跳过给定的曲目。这篇文章总结了我解决这个问题的方法和结果。

关于数据

作者图片

我在这个项目中使用的数据集是在数据科学竞赛平台 AIcrowd 上找到的。

原始数据集包含 Spotify 服务上大约 1.3 亿次与用户互动相关的收听会话,占用户互动的近 400 万首曲目。我在这个项目中使用了这个数据集的缩略版本,它包含了 10,000 个听力会话,代表了不到 168,000 个单独的音轨交互。

作者图片

选择目标变量

这个项目的目标变量是用户是否跳过了一个曲目。数据集中的各种跳过行为表明一首歌曲在被跳过之前播放了多长时间。我选择‘skip _ 2’作为我的目标变量。它拥有最好的阶层平衡,积极阶层和消极阶层的比例为 52:48。

‘skip _ 2’表示歌曲在被跳过之前被短暂播放过。

探索性数据分析的发现:用户在 Spotify 上的行为如何?

我首先想了解用户如何与平台交互的总体情况。我发现的一些关键见解是:

  • 52%的歌曲被跳过
  • 根据用户与前一首曲目的交互方式,平均跳过率会有所不同
  • 跳跃率似乎根据一天中的时间而变化

上图强调了跳跃行为的差异,基于它们如何到达当前轨道。平均而言,如果用户在播放前一首歌曲时按下前进按钮(红色),跳过率会比完整播放(蓝色)时高。

特征工程:历史很重要

推动项目向前发展的因素之一是能够转换数据以做出准确的预测。我想知道在我试图预测的赛道附近发生了什么。用户最近是否心情不好?或者他们对歌曲的选择非常满意,并且演奏了大部分歌曲?

受这个想法的启发,我对数据进行了转换,以反映每次听力会话期间的指数加权移动平均值。在给定听力会话期间的每个时间点,计算偏向当前音轨的移动平均值。随着时间的推移,在预测当前曲目是否将被跳过时,开始播放的曲目变得不那么重要。

上图以跳过行为为例,说明了如何捕捉总体用户行为。请注意,指数加权移动平均线(蓝色)在计算中落后一个轨迹。这种策略可以防止模型预见未来,从而降低数据泄露的风险。与实际跳跃结果(红色)相比,EWMA 捕捉平均跳跃行为,并对当前轨道进行加权。

基线建模:之前的用户交互很重要

在使用逻辑回归进行基线建模的过程中,我遇到的一些关键发现是:

  • 前一首曲目中前进按钮的使用是跳过当前曲目的有力预测
  • 相比之下,播放到最后的前一首歌曲是不被跳过的强有力的预测

我的探索性数据分析反映了这些发现,强调了将过去的用户交互与未来联系起来的重要性。换句话说,如果用户先前跳过曲目,则他们更有可能跳过当前曲目,反之亦然。

最终模型:结果和讨论

除了基线逻辑回归模型之外,我还使用了一个随机森林分类器,通过计算整个听力过程中的指数加权移动平均值,对一组特征进行了训练。这个模型表现最好,预测跳跃结果的准确率为 78%,远远超过一个简单的模型。这个天真的模型会猜测一个曲目总是被跳过,并且 52%的时间是正确的。

模型的假设和限制

这一模式在某些假设下运作,有其局限性。它假设有关于它试图预测的歌曲之前和期间发生的事情的基线知识。给定一个歌曲序列,该模型将需要理解用户的行为,并跟踪后续歌曲的特征。

这意味着它可以预测收听会话中的一首歌曲,但不能处理连续歌曲的预测。由于该模型是一个分类器,它可以提供关于一首曲目是否可能被跳过的见解。如果部署在平台上,它可以根据歌曲被跳过的可能性来决定保留或丢弃播放列表中的歌曲。但它不能提供更多创造性的解决方案,比如在播放列表中添加新歌。

结论

这个模型在没有用户交互历史的情况下表现最好,比一个简单的模型稍好。这突出了在预测跳过结果时理解用户在听力会话中的行为的重要性。

随着用户跳过大约 50%的歌曲,可能有机会通过一个响应更快的平台来改善用户体验。就目前的情况而言,用户跳过多首歌曲可能比通过使用搜索栏或多次按键来尝试找到特定歌曲并导航到该歌曲更容易。我的愿景是通过用户与平台的互动来理解他们的意图,并尝试在那一刻给他们带来他们想听的歌曲。

后续步骤

在我对 Spotify 用户行为的分析和预测中,我对这个问题有了更深刻的理解。正如我之前提到的,这个项目是一个更大想法的起点。一个围绕着反应式播放列表监管,对用户的收听情绪敏感。

当我回到 Spotify 兔子洞时,我将采用更复杂的方法来解决这个问题,并回顾与这个主题相关的文献或类似的文献来寻找灵感。当用户决定跳过或播放一首歌曲时,寻求对用户动机的更深入理解——利用这些见解来进一步推动这个项目。

参考:

[1] B. Brost,R. Mehrotra 和 T. Jehan,《音乐流会话数据集》(2019),2019 年网络会议论文集

要解决复杂的问题,找到正确的点来连接

原文:https://towardsdatascience.com/to-solve-complex-problems-find-the-right-dots-to-connect-f6cf650725dc

成为一名数据科学家的过程有时可能会感觉像是在浏览一个永无止境的购物清单:获得更多的证书、更多的算法、更多的 Python 技巧……我们在 TDS 上发表的文章中经常看到的是,与将看似不相关的点连接成可行的方法或解决方案的关键技能相比,我们所知道的可能没有那么重要。

本周,我们展示了最近的三篇文章,它们强调了利用——有时是即兴发挥——你所拥有的经验的好处。他们处理完全不同的项目和主题——从水文学到 Wordle——但是他们都有相似的创造性。让我们开始吧!

  • 变形金刚能成功分类复杂文本吗? Jaren R HaberThomas LuNancy Xu 耐心地向我们展示了他们引人入胜的项目——从预处理到模型训练等等——他们使用深度学习来帮助人类阅读和分析学术资源,他们称之为“计算文献综述”的管道
  • 解决字谜的最好方法是什么? 你现在很可能还没有听说过 Wordle 但是你解决日常挑战的方法有多强呢?可能没有 Sejal Dua 的强大。Sejal 最近分享了对赢得游戏的最佳策略的深入研究,甚至创造了一个人工智能工具来帮助你更快地找到正确的单词。
  • AutoML 如何帮助预测洪水(并赢得黑客马拉松) 。创造力和独立思考是在数据科学和 ML 竞赛中取得好成绩的基本要素; Mikhail Sarafanov 和他的团队使用了他们技能组合中的每一种可能的工具,在俄国建立了一个成功的洪水预测模型。米哈伊尔的文章是一个引人入胜的,一步一步的有效解决问题的案例研究。

照片由 Lydia TallentUnsplash 上拍摄

最近几周,我们发表了几十篇其他优秀的解释者、分析和教程——以下是一些我们推荐阅读的快速样本,每一篇都以自己独特的方式将点连接起来:

  • Angela Shi 分享了一个极其全面(也极其有用)的监督学习算法概述
  • 如果你准备好进入数据库魔法之旅的下一步, Matt Sosna 最近出版了一本关于中级 SQL 的可访问指南。
  • 对于数据公民概念的现状和主要挑战的发人深省的观点,不要错过本·斯坦西尔和马克·格罗弗的新文章。
  • 为了帮助提高你的数据可视化技能,我们已经收集了一些关于主题的最好和最新的资源,涵盖了绘图、地图、Python 库以及优秀设计背后的一般原则。(还有:猫。)

感谢您花时间阅读我们作者的作品——我们希望您能通过探索学到一些新的有用的东西。

直到下一个变量,

TDS 编辑

今天我退出了数据科学;以下是 7 个原因

原文:https://towardsdatascience.com/today-i-quit-data-sciences-here-are-7-reasons-why-15c29e51d032

数据科学

在这篇文章中,我分享了我作为一名数据科学家的经历,以及我是如何发现它不适合我的。

照片由 Unsplash 上的尼克·费因斯拍摄

我一直以为我想成为一名数据科学家。我读到过这个职业带来的魅力。人们有能力借助数据和数据导向的决策来改变业务成果。除此之外,一个人还能得到一笔可观的收入,而且当家人告诉他们自己的工作时,往往会让他们大吃一惊,因为你的朋友和家人可能不知道你在做什么。

这一切看起来很有希望。因此,为了在这个方向上更进一步,我在德里大学最有影响力的学院之一攻读了统计学(H)学士学位。为了进一步补充我的知识和获得商业理解,我获得了一个围绕商业和企业家精神的研究生学位。我觉得自己比以往任何时候都更愿意从事数据科学方面的职业。

在做了大约 4 年半的数据科学家,并与顶级研究和学术机构合作了各种项目之后,我今天辞职了。在这篇文章中,我解释了七个原因。

样样精通,一无所知!

你们可能都听说过“万事通,无所不能”。对我来说,总是反过来。包括我在内的许多数据科学家都被期望成为机器学习、深度学习、网页抓取、数据库工程、部署生产级 ML 模型、软件工程、数据策略和治理方面的专家。

谈到工具,我以前的一些雇主希望我了解 Python、R、Java、Javascript、Hadoop、Spark、Tableau、Power BI、Excel、Scala、吉拉和 SAS。我辜负了他们对我无所不知的期望。很多时候,数据科学家需要回答他们遇到的各种随机数据问题,因为如果他们被称为“数据科学家”,他们必须了解所有关于数据的知识。可悲的是,这不是真的。

这个问题的解决方案是在工作描述中清楚地阐明一个组织使用的技术堆栈,而不是写下宇宙中的所有东西或组织认为他们应该使用的所有东西。

没有数据基础设施或数据基础设施不足

数据科学家的工作是使用数据推动决策。前提是要有可以分析和行动的数据。我参与过一些组织和项目,那里没有数据,最糟糕的是,没有基础设施来捕获、存储和提取决策所需的数据。在这些地方获取数据的方式主要是在 Google Drive 或 Sharepoint 上,一段时间后,没有人知道什么数据在哪里,以及它是如何存储的。

我认同吴恩达的观点,他认为拥有好的数据比拥有好的模型更重要。看到的另一个方面是,很多时候,业务领导者没有针对其组织的数据愿景,而且大多数时候,这些行动是以临时方式反映的。

这个问题的解决方案是具备数据素养,开发能够在需要时捕获和提取数据的系统。这些是数据架构师或数据库工程师的工作职责。

成为数据科学家的期望与现实

许多数据科学家面临的最大挑战之一(对我也是!)就是对角色的期望和你实际做的事情有巨大的差异。很多时候,数据科学家希望他们将获得精心制作的数据,他们将使用这些数据来构建模型,而这些模型将被业务领导用来制定决策。不幸的是,现实生活中事情并不是这样。

如上所述,许多组织甚至没有数据报告基础设施。因此,数据科学家大约 80%的时间被要求获取数据、清理数据、转换数据,然后将数据发送给下一个团队。这在数据科学家的头脑中造成了幻灭。在最坏的情况下,数据科学家被要求执行琐碎的数据任务,如下载数据或在 Excel 中进行分析。

当这些幻想破灭的数据科学家试图找到另一份工作时,他们不会很容易找到另一份工作,因为未来的雇主无法清楚地看到他们之前角色的成就。大多数雇主寻找能够建立模型的人,然后让他们做数据清理和转换或临时业务报告。

解决这个问题的方法是与可能的候选人建立一个期望与现实的匹配。这不仅对候选人有帮助,对雇主也有帮助。

客服代理

我厌倦了总是被当作客户服务代表,因为我是负责“数据”的人,我会收到公司所有部门的请求。在许多组织中,尤其是那些不是由基于机器学习的产品驱动的组织,数据分析师和数据科学家被视为支持人员,他们需要支持组织所做的更“研究主导”的重要事情。

经常会收到这样的请求:“嘿,Aayush,你能帮我下载这个数据集,做一些快速的探索性分析,制作一些幻灯片,并在第二天早上 8 点之前与我分享,因为我们需要在下周与一些资助者分享它们吗?”或者“嘿,Aayush,我看到了这篇漂亮的使用机器学习的研究论文。你能读一下这张纸,告诉我里面有什么吗?”。

解决这个问题的方法是尊重每个人的任务和职责,不要把它们看作是组织中可以随意使用的产品。

孤立与单调

就我而言,我几乎是数据团队(有时是整个组织)中唯一的一个人,这导致我的工作处于孤立状态。远程工作环境更加剧了这种情况。正如上面所解释的,上面的大多数请求都是临时的,这意味着我独自工作,一次又一次地做着同样的事情。

我的个性与此不同步,因为我是一个喜欢与同事一起工作和完成各种任务的人。对我来说,机器学习的整个生产周期似乎并被证明是精神疲惫和单调的。尽管做了这么多苦差事,管理层还是没有做出决定,因为他们心里有其他优先考虑的事情。

这个问题的解决方案是构建由不同人群组成的团队。此外,消除候选人的疑虑并事先向他们解释隔离期也会有所帮助。

缺乏资深数据科学家和领域专家的指导

许多高层领导对手头问题的细微差别以及数据科学如何帮助解决这些问题的洞察力有限。他们有崇高的想法,然后要求并期望数据科学家在这些未定义的指导方针和模糊的目标内以最高效率工作。这有可能使数据科学家采取的不是最符合逻辑和结构化的方法来解决问题,而是一种寻找解决方案的试凑法。

这种方法既不利于组织的财务,也不利于运营效率。除此之外,这对在这种环境中工作的数据科学家也没有太大帮助。此外,没有多少资深数据科学家可以帮助初级数据科学家的专业和技术发展。

解决方案是对数据科学家进行领域知识培训,倾听他们基于数据的观点,并为他们在组织中的职业发展制定计划。许多千禧一代不是被高薪打动,而是被他们职业和个人生活的高速增长所打动。

政治

我在以前的职位中被要求为我的同事做一些小事情,以便他们知道并理解我现在是组织中的数据科学家。这种毫无目的的取悦他人的行为对我来说并不太鼓舞人心。此外,很多时候我甚至不能访问其他部门拥有的数据,因为这些部门的管理员不希望这些数据泄露出去。

有时,我甚至被要求以一种有助于同事提出他们的议程的方式展示部分持有的信息。作为一名数据科学家,我没有受过操纵这些的训练。这也是很多未来的数据科学家在工作中面临的一个问题。

解决这个问题的方法是要么接受组织的方式,然后在那个系统中向上爬(通常,这是最简单的方法!或者,如果你足够热情,大声说出你的观点,并提出切实可行的方法来改变企业中的这些情况。然而,它可能并不总是有效的。

结论

以上原因来自我的个人经验,并不是每个人在工作中都会遇到这种情况。当我开始下一次旅程时,我打算带着这些课程前进。作为一名数据科学家,我在工作中获得的见解和经验告诉我,我最适合的角色应该包括以协作的方式与团队合作,执行一系列不同的活动,以及为用户的成功代言。

我的教育和经历给了我相关的分析技能,这些技能在许多组织中都很有用。凭借正确的分析思维和解决问题的能力,我期待帮助组织做出正确的战略决策。随着我职业生涯的进一步发展,我将更多地成为一名应用决策科学家,而不是数据分析师。

对于任何问题或细节,你可以与我联系,我们可以谈谈你的经历。做出错误的决定从来都不是一件令人兴奋的事情,我希望凭借我的经验,你将能够更好地决定你是否愿意朝着数据科学的方向前进。

带 Rust 的令牌桶算法

原文:https://towardsdatascience.com/token-bucket-algorithm-with-rust-4fa130c08ca8

周末建设和学习。这个周末让我们用铁锈做一个象征性的桶。

我开始写作之旅已经快三年了。

每个周末,除了孩子和家庭活动之外,只要我有时间,我就会进行代码演练或编写代码和学习的想法。

你们的支持是让我不断前进,写出更多精彩学习分享的最重要动力。

你可以看看我的其他系列和不同主题的文章。

https://jayhuang75.medium.com/

令牌桶是什么?

先说“限速”。每个软件工程师都明白“速率限制”是如何通过监控传入的请求并确保它们不违反阈值来管理 API。

我们正在定义每单位时间的请求率,并排队/拒绝发送超过我们的速率中描述的请求数的传入请求。

我们需要一种测量和跟踪的方法来实现这一点。具体来说,有两种主要算法可以实现这一点。

  1. 令牌桶算法。
  2. 漏桶算法。

让我们来关注一下令牌桶算法。我这里用的比喻是电影院。

克里斯特·卢哈尔斯在 Unsplash 上的照片

  1. 一个电影院(桶)有预定义的最大容量(代币)和在此期间进入电影院的平均人数(比率)。
  2. 每一批进电影院的人都会消耗来自电影院(桶)的容量(代币)。
  3. 如果容量允许(有足够的代币),人们可以从事以下活动,例如观看电影。
  4. 如果没有足够的可用容量(令牌),我们可以根据您的使用案例和策略,拒绝即将到来的一批人的访问或排队。

这些步骤是我们需要在代码中反映的业务逻辑。

让我们编码

免责声明,该代码主要侧重于逻辑演练,可能不包含一些实现细节或性能调优。

编码就像写一个故事。

在这个用例中,让我们从什么开始。

什么

Rust 中的结构是我们想要处理的对象。在这种情况下,我们查看令牌桶,其中包含容量(max_tokens)、平均人数(rate)、current_tokens、last_refill_timestamp 将是公式的变量。

令牌桶结构—按作者

怎么

构建新令牌桶的方式,我们可以考虑我们的第一个“如何”如何初始化新令牌桶。

令牌桶构造器—按作者

接下来的如何将是基本公式,私有核心引擎,来更新令牌桶的状态。

令牌桶更新—按作者

T 主要想法是检查最后更新的时间戳,并根据预定义的速率确定将有多少令牌添加到当前容量。

一旦它被更新,我们可以决定我们的下一步行动。

在下一个动作中,我们将把它塑造成一个 trait,它对令牌桶的动作函数进行分组。

令牌桶特征—按作者

最后如何将如何处理即将到来的人,一个公共功能控制与中央核心更新功能触发的时间间隔内。

令牌桶句柄—按作者

让我们测试一下

电影院我们最多能容纳 10 个人,平均两个人,输入速率,让我们用今天的 10 场电影来测试它,每部电影只有 2 秒。(仅供演示,我不相信有 2 秒钟的电影存在:)

令牌桶测试—按作者

令牌桶测试结果—按作者

最后的话

从逻辑代码演练的角度来看,我们主要了解了 Rust Token Bucket 算法。

请加入我的中码学习连载,获取最新更新。

https://jayhuang75.medium.com/membership

另外,你可以用下面的链接给我买一杯咖啡,让我有动力在周末进行更多的锻炼和学习。

https://www.buymeacoffee.com/jayhuang75

汤加火山:可视化冲击波传播

原文:https://towardsdatascience.com/tonga-volcano-visualizing-the-shockwave-propagation-75dcfbadef76

利用气压数据制作穿越美国的冲击波动画。

约什·金斯利Unsplash 拍摄的照片

介绍

2022 年 1 月 15 日,汤加北部的洪加-洪加哈派火山经历了一次猛烈喷发。爆炸释放的能量相当于几十兆吨 TNT 炸丨药,并引发了海啸,爆炸如此猛烈,以至于声波冲击波传遍了整个地球表面。

有趣的是,随着冲击波的传播,它压缩空气并在气象站的大气压力传感器中产生信号。在这项研究中,我们使用 GeoPandas 和 matplotlib 可视化了穿过美国的高能冲击波。

数据收集和探索

我们使用的公共数据集来自由爱荷华州立大学的爱荷华环境 Mesonet 维护的 ASOS 网络,并且可供公众使用,在该网络中,来自美国所有机场的历史气象数据以一分钟为间隔进行记录。我们感兴趣的测量是大气压力(以英寸汞柱测量)。 Iowa Environmental Mesonet 网站为我们提供了查询其数据的 python 脚本,简化脚本(带多线程加速下载)可以在这里找到。对于这项研究,我们下载了从 1 月 15 日午夜(UTC)到 1 月 25 日的 10 天数据。

首先,我们检查旧金山国际机场(SFO)的气压测量。蓝色曲线显示了相对于 t = 0 时测量值的压力测量值。黄色曲线显示使用np.gradient()计算到二阶精度的相对压力梯度(放大 30 倍以便可视化)。梯度的每一次突然下降都对应于冲击波的通过。

SFO 的压力数据(蓝色)和比例梯度(橙色)。品红色/青色:冲击波的向前和向后通道。

因为冲击波是一种围绕地球传播多次的圆形波,如这里的模拟所示,每个梯度下降应该对应于冲击波的“向前”或“向后” 通道,由洋红色和青色三角形标记表示。标记的时间戳计算如下(假设冲击波以音速传播):

forward: t(eruption) + t(Tonga to SFO) + N * t(go around Earth)
backward: t(eruption) - t(Tonga to SFO) + (N+1) * t(go around Earth)

因为压力梯度的突然下降在两次向前通过后不再明显,我们将只看到前两次激波通过。

可视化冲击波

首先,我们选择冲击波第一次“向前”通过(对应于第一个洋红色标记)周围的 12 小时时间窗口中的数据,即 1 月 15 日,上午 8 点到下午 8 点。空值大于 90%的机场被删除。然后,我们将冲击波的到达时间定义为对应于最小负梯度的时间。下图显示了 SFO 冲击波到达时间(红点)的计算结果。

SFO 的压力和梯度。红点:定义的到达时间。

然后我们用同样的方法计算所有机场的到达时间。还记录了每个机场到达时的梯度幅度。为了稍后创建更清晰的可视化,我们检查了所有机场的到达时间分布,并选择了中心峰值(在下图中两条紫色线之间),移除了到达时间异常的机场。

所有机场的到达时间分布。

一个有趣的观察是梯度的幅度作为到达时间的函数而减小。下图显示了对所有过滤机场的梯度振幅与时间数据进行的线性回归;观察到统计上显著的负相关。这是意料之中的,因为冲击波在传播过程中会损失能量

内层机场梯度幅度与到达时间的关系。

最后,我们可以使用计算出的到达时间信息来可视化冲击波在美国的传播!在下面的 GIF 中,在每一个时间步(帧),我们根据相应的冲击波到达时间和时间步之间的差异来改变站的颜色和大小。正如你所看到的,汤加火山爆发的能量如此之大,以至于一股压力波正在全国蔓延。

第一次向前通行。

地球是球形的

记住,冲击波是一种圆形的压力波,它会穿过整个地球。这意味着我们可以观察到压力波“向后”传播,因为它的一部分从地球的另一边向美国传播。

如果我们使用第一张图中第一个青色标记附近的数据对到达时间进行同样的计算,我们会得到下面的动画。

第一个反向通道。

当然,随着时间的推移,冲击波阵面的形状会发生扭曲,因为地球的形状是椭球形的。这大概解释了上面波前后面的搞笑“尾巴”;也可能是由于其他数据假象。

结论

我们利用机场的气压数据成功地显示了汤加火山冲击波穿过美国。正如我们提到的,冲击波围绕地球传播了多次,我们鼓励你在 Github 上用我的代码尝试可视化后面的传播!剧透警告:第二和第三波通道在视觉上是可识别的,但是数据变得更加嘈杂。

鸣谢:这项工作的动机来自加州大学伯克利分校 AY 250: Python 研讨会的一个家庭作业项目。

太简单了,无法解决

原文:https://towardsdatascience.com/too-simple-to-solve-1758d63d562f

柯拉茨猜想数据的可视化探索

初始值 ≤ 1,000,000 的 100,000 个排序序列的可视化。图片作者。

这是一个简单到连一年级学生都能理解的数学问题,但它却如此复杂,以至于世界上最伟大的数学家都警告其他人不要去做。

开始是这样的。选择一个数字。如果是偶数,就除以 2。如果是奇数,乘以 3 再加 1。用新号码重复。数到 1 就停下来。

你看到了吗?简单。无非就是简单的整数除法,乘法,加法。例如,从 20:

  • 20 是偶数,所以我们除以 2 得到 10;
  • 10 也是偶数,所以除以 2 得 5;
  • 5 是奇数,所以我们把它增加三倍,再加 1,得到 16。
  • 16 是偶数,所以我们把它除以 2 得到 8,再(4)再(2)再(1)。
  • 我们已经点击了 1,所以我们完成了。为什么?井 1 是奇数,所以可以将它增加三倍,加上 1 得到 4,然后 2,然后 1。我们陷入了一个4–2–1的循环中,因此当我们数到 1 时我们就完成了。

因此, n=20 的顺序是 20,10,5,16,8,4,2,1;其长度(或总停止时间为 8,其最大值(或高度)为 16。规则看似简单,但不同的数字会产生非常不同的、不可预测的序列。例如,n = 127 的序列有 111 个数长,在回落到 1 之前达到 9232 的高度;这是用粗体显示的奇数:

27 ,82, 41 ,124,62, 31 ,94, 47 ,142, 71 ,214, 107 ,322, 161 ,484,242, 121 ,364,182, 395 ,1186, 593 ,1780,890, 445 ,1336,668,334, 167 ,502, 251 ,754, 377 ,1132,566, 283 2734, 1367 ,4102, 2051 ,6154, 3077 ,9232,4616,2308,1154, 577 ,1732,866, 433 ,1300,650,

这些序列被称为科勒兹序列轨道,而科勒兹猜想——洛萨·科勒兹命名——声明无论我们从什么正整数开始,应用上述规则总会把我们带到4–2–1

到目前为止,这个猜想抵制了所有证明它的尝试,包括许多世界顶级数学家的努力。已经取得了进展,但解决方案仍然遥不可及,有些人认为目前的数学水平还不能解决如此简单的问题!事实上,数学家们的建议往往是,追求这一职业生涯终结的追求太危险了,一个老笑话是,这个问题是俄罗斯在冷战时期发明的,旨在减缓西方数学的进步。

“数学可能还没有准备好解决这样的问题”——保罗 ready

但这是一个如此简单的问题,很难抗拒。例如,下面几行代码将获取一个数字 n ,并生成到达4–2–1所需的数字序列。现在我们可以生成任意多的序列。

Python 代码为一个数字 n 生成一个排序序列/轨道。

因此,我对 Collatz 的主要兴趣是作为有趣数据的来源。这是另一个例子,数论领域作为丰富的数据来源迫切需要探索和可视化。我第一次发现这个猜想是在数字爱好者上,自从我偶然发现阿肯色大学数学家埃德蒙·哈里斯精彩的 Collatz 可视化后,它就一直在我的待办事项列表上。因此,在巧克力蛋和一些休息时间的包围下,这个复活节我决定尝试再现埃德蒙的一些精彩画面。

一种常见的可视化柯拉茨数轨道的方法是使用一个有向图。例如,下图显示了一组小整数的图表。这些序列都收敛到 1,正如 Collatz 猜想所预测的那样;不失一般性,仅示出了奇数。

显示小数目排序序列的有向图:由维基百科提供。

E 德蒙德·哈里斯走得更远——至少从美学的角度来看——提出了一种新的方法来渲染这些序列,产生更有机、更直观的数据表示。

基本想法很简单。给定的序列/轨道被渲染为一组相连的单位长度线段,但是每个线段的角度是根据它对应的是偶数还是奇数来选择的。偶数产生顺时针旋转,而奇数产生(通常较小)逆时针旋转。例如,下图显示了小数字的轨道示例,偶数角为 23 度(顺时针),奇数角为 42 度(逆时针)。与早期更传统的有向图相比,这种视觉化已经有了更有机的感觉。

柯拉兹轨道的样本。图片作者。

通过一些小的调整,事情变得有趣多了,比如去掉标签和添加一些颜色。下面的可视化网格显示了各种不同的偶数/奇数角度的修改结果,每个角度都是从高达 1,000,000 的初始值中随机选择的 10,000 个初始值。我们可以看到不同的角度组合如何改变最终视觉形式的形状。

不同偶(E)角和奇(O)角对的哈里斯式可视化网格。基于从初始值中随机选择的一组 10,000 个初始值,每个可视化对应于相同的一组 10,000 个轨道,直到 1,000,000 个。图片作者。

为了更清楚,下面的四个图显示了从初始值到 1,000,000 随机选择的 100,000 个序列的较大样本的较小偶数和奇数角度组的这些修改的结果。

从高达 1,000,000 的初始值中随机选择的一组 100,000 个初始值的 100,000 个轨道的类似 Harriss 的可视化。每次观想都使用不同的偶角和奇角组合。图片作者。

生成这些图像中使用的 Collatz 轨道的 Python 代码如下所示;为了方便起见,Matplotlib 用于绘制线段,但也可以使用各种其他库。为了生成给定的图像,需要迭代一组选定的初始数字。

Python 代码,用于生成单个 Collatz 轨道的埃德蒙·哈里斯式可视化。作者代码。

W 这里到下一个?我认为有几个调整将有助于增强这些视觉化的有机本质,并进一步提高它们的美学效果。

  • 首先,我们可以添加一个衰减参数来逐渐减少对应于一个轨道的各个线段的长度;这将特别减少较长轨道的长度,并潜在地为观想创造一些额外的空间。
  • 第二,我们可以减少线段的厚度,让每一条都逐渐变细,让最长的轨道在极端处变得更像线。
  • 最后,我们还可以调整线段的透明度,使线条逐渐变得不那么饱和,在极端情况下更加透明。

下面提供了实现这些更改的修改后的代码。请注意,这一次必须单独绘制线段,以便可以用特定的线宽/线宽和透明度/alpha 值来呈现每一条线段。和以前一样,代码使用 Matplotlib 作为绘图库,但是只需稍加修改就可以使用任意数量的替代库。

Python 代码,用于生成 Collatz 轨道的修改后的 Edmund Harriss 可视化,包括默认参数设置。作者代码。

再一次,为了使用这个代码生成一个完整的可视化,需要迭代一组期望的初始值。例如,下面的可视化是使用 200,000 个 Collatz 轨道创建的,这些轨道基于从所有这些轨道中采样的 200,000 个初始值,直到 1000,000 个。

200,000 个柯拉茨轨道的可视化(偶数转角= 11.45,奇数转角= 20.61)

这一次我选择了一对新的偶角和奇角来创造一种视觉效果,在过于统一和过于混乱之间取得了更好的平衡。新的锥形和透明效果确实有助于创建一个非常令人愉快的视觉效果,看起来非常自然。

在这篇文章中,我讨论了看似简单的柯拉茨猜想,几十年来,这个猜想已经被证明对许多人来说,既吸引人又令人沮丧。

我对这个问题的兴趣来自不同的地方。最近,我发现数论是数据科学和可视化实验中有趣数据的巨大来源。素数、重复分数以及现在的柯拉茨猜想都提供了无限的复杂数据和有趣的假设,这对于锻炼和发展我的数据科学和可视化技能以及探索一些有趣和新颖的计算艺术形式的创作来说是理想的。

在我看来,像这里产生的这些可视化确实有助于捕捉像柯拉兹规则这样简单的公式所产生的复杂性——秩序和混乱之间的微妙平衡——这无疑是为什么柯拉兹猜想被证明是如此难以破解的原因。

功劳归功劳:大部分艰难的工作都是由埃德蒙·哈里斯完成的,他的工作为我的起步提供了最初的动力和方向。但我希望我的改编也能增加一些价值,也许它们会鼓励其他人开始他们自己的旅程……但要小心,因为有些人警告说,柯拉茨猜想是对不知情的探险家的诱惑……

如果您有兴趣阅读数据科学和数论交叉领域的进一步探索,您可以在以下内容中找到更多信息:

学习编程的十大最佳社区

原文:https://towardsdatascience.com/top-10-best-communities-for-learning-to-code-c46e4e4ef1f0

从哪里寻找项目灵感、特定问题的答案或对您学习之旅的支持

通过像素拍照

每个程序员都有一个共同点,不管你是只执行过“Hello World”程序还是高级软件工程师,都需要不断学习。新技术、编程语言、框架、库和约定不断被引入到行业中。作为一个初学者,可能很难搞清楚你需要知道什么才能进入这个行业,一旦你是一个熟练的程序员,不断调查技术领域的趋势话题是很累的。

这就是为什么加入技术社区如此重要。随着混合、远程和自由职业工作的兴起,与您的团队和公司内其他团队的同事联系比以前更难了。这是假设你有其他编码同事。大量的辞职和较高的离职率也使人们很难与工作同事的旋转门联系起来。如果你发现自己缺少技术导师、同行或类似职业的朋友,你最好的办法是在网上接触许多现有的编码社区。

编码社区可以帮助您解决基本的编程问题,权衡一个包管理器相对于另一个包管理器的优缺点,选择雇主,选择下一步学习哪种编程语言,等等。编码社区非常适合支持你的硬技能和软技能。根据工作描述和你的掌握程度,在这个行业有更多经验的人可以建议你如何在面试中推销你的技能,以及在编码面试中最好使用哪种编程语言。

如果你刚刚开始,另一个要考虑的方面是程序员社区可以帮助你的支持和责任。作为该领域的初学者,很难发现计算机科学的许多不同的应用,更难的是克服“你不知道你不知道什么”的范式。

所有这些环境因素完美地结合在一起,展示了为什么在编码世界中找到一个社区是如此重要。你需要一个在技术、专业甚至情感方面支持你的社区。无论您是因为无法编译的代码、工作被拒还是不知道下一步该做什么而感到沮丧,您所在的社区应该能够帮助您清除所有这些障碍。

谢天谢地,计算机科学作为一个慷慨的行业享有很高的声誉。开源项目比比皆是,许多技术娴熟、知识渊博的程序员在论坛上支持其他人。我将带您浏览顶级社区,开始您的编码之旅。

1.不调和

Discord 是一款基于社区的聊天应用,最初是为游戏玩家开发的。有许多突出的、流行的不和谐“服务器”,它们是专注于一个主题的频道或社区。

有类似于 Boot.dev 的代码学习社区的服务器,学习编码的人可以在那里找到支持、建议和经验。还有针对 JavaScriptTensorFlowPython 等主题的服务器。

不和谐对于获得实时支持非常有用。有这么多不同的服务器专注于共享内容、推广项目、协作开源项目、特定工具和技术,甚至专业主题,很容易在一个地方找到许多不同领域的帮助。

不和谐的最大好处是它创造了一个更亲密的环境,这意味着更容易获得一对一的帮助或与更小的一群人联系。Discord 服务器可以给你提供一种强烈的团体感和支持感,这对于你编程生涯的开始阶段至关重要。

2.Reddit

Reddit 是一个受欢迎的在线论坛,你可以在互联网上找到几乎任何东西。在编程的保护伞下,存在许多不同主题的子主题,如 JavaJavaScriptGoRust 等。内容以问答的形式发布,类似于 Dream In Code,DEV,CodeNewbie。

您可以查看不同的主题集合,查看每个主题中投票最多的帖子,还可以向单个用户发送消息,这意味着确实存在与其他用户建立类似指导关系的可能性。然而,由于 Reddit 是如此开放、公开和庞大,很难真正与其他用户建立关系。

对我来说,Reddit 更像是文章、教程、会议、黑客马拉松等链接的随机集合。这是一个展示酷项目或从他人那里获得灵感的好地方,但如果你正在寻找一群志同道合的人来度过进入软件行业的旅程,Reddit 会让你感到孤立和不知所措。

3.哈希诺德

Hashnode 提供了一个发现和消化技术博客的好方法。这个平台允许你关注个人科技博客,并与他们联系。他们有很多编程挑战和基础知识的解释,所以这是一个很好的地方,可以让你脚踏实地,拓展技能的应用。

这个平台更侧重于给有技术知识的作家一个发布内容的地方。这意味着它是一个从那些拥有技术知识的人那里找到写得好的内容的好地方,但它不是一个超级社交环境。平台不利于获得某个问题的具体帮助或建立更深层次的联系。这更像是追随某人,而不是与他们互动。

4.黑客新闻

黑客新闻主要是由著名的 Y 组合家整理的新闻文章列表。他们有很多关于创业/自由职业建议的好内容。在 Hacker News 上,您可以找到许多有趣的文章,这些文章可以为您利用自己的编码技能做些什么提供很好的灵感,无论是在您自己还是在公司。

你可以与其他用户联系,但它并不完全是一个社区平台。《黑客新闻》最大的优势是提供关于开发者世界正在发生的事情的最新消息。如果你正在寻找关于有用的库和工具的提示,这是一个很好的地方。

《黑客新闻》的一个额外好处是,它有一个面向初创公司的招聘板,所以如果这是你想要进入的方向,它会为你提供一些好的联系方式。

黑客新闻没有为你提供的是具体的问题帮助,社区不会纵容你。如果你正在寻找开始编码的鼓励和支持,这里不是合适的地方。

5.密码笔

社区帮助你学习编码的另一个很好的选择是 CodePen 。CodePen 主要专注于前端内容,因此根据您希望的编程职业发展方向,这可能是一个优点,也可能是一个缺点。然而,知道在哪里寻找信息是很重要的,所以即使你目前对前端开发不感兴趣,也可能有一天这种情况会改变,或者你未来的团队会分配给你一个随机的 UX bug 来处理。

CodePen 提供了一个很好的环境来处理你的代码。我认为这是一个巨大的优势,尤其是当你刚刚开始从事编码工作的时候。让整个应用程序在本地启动和运行会导致很多令人头疼的问题,并且会妨碍您只是摆弄一些代码。CodePen 声称它是“构建、测试和发现前端代码的最佳场所”至少,CodePen 的开发工具可以作为一个很好的沙盒。

Codepen 还举办每周挑战,磨练你的前端开发技能。他们通过社交渠道展示获奖者,让你向最优秀的人学习,并与那些拥有你渴望拥有的技能的人联系。

他们有很多非常酷、非常有用的前端开发内容,这使得它成为寻找实现灵感的好地方。

CodePen 最大的缺点是你需要一个私人的付费账户来保存你在他们的前端环境中实现的所有酷的东西。如果你只是在不同的地方乱搞,那不是问题,但是如果你在做一些敏感的东西或者你不想让别人看到的东西,你就不能用 CodePen 做他们的沙箱。

6.CodeNewbie

从每周一次的 TwitterChat 开始,已经成为一个国际社区,人们学习编码,互相支持。CodeNewbie 希望为需要早期职业指导的开发人员提供支持。他们想用知识武装你,让你从训练营结束后的阶段开始职业生涯,成为高级软件工程师。

CodeNewbie 拥有大量不同格式的内容,包括播客、Twitter 聊天、CodeLand 会议、黑客马拉松等等。他们已经成功吸引了大量专家加入他们的平台。这是一个偶然发现面向所有级别程序员的高质量内容的好地方。

CodeNewbie 被称为一个平台,开发者可以“写下他们的知识和经验,以及彼此之间的联系”CodeNewbie 的一个突出的方面是,他们旨在帮助你了解如何使用像他们的提问指南这样的内容来解决问题。这些非代码提示对支持你的职业发展大有帮助。

7.偏差

如果你正在寻找一个能为你提供协作和网络学习空间的社区,那么 DEV 可能非常适合你。他们的平台上有超过 800,000 名开发人员,并深入涵盖了许多利基主题,如在 HTML 和 CSS 中发现跨浏览器兼容性问题,如何建立 AWS 安全中心,以及更多具有商业头脑的主题,如常见 B2B SaaS 集成模式指南以及何时使用它们。

DEV 社区有大量由他们庞大的社区贡献的文章。你可以对一个特定的主题进行更深入的研究,看看有什么最新的帖子来感受一下当前的计算机科学新闻,或者看看他们有史以来最热门的文章。

DEV 确实有一个社交媒体方面,所以你可以发布问题并通过评论和#help 标签获得答案。这种格式类似于脸书的时间线反馈,带有对答案的评论,文章更像是你在 Medium 上的技术主题中找到的。至于找到一群人来支持你的旅程,DEV 缺乏 1:1 的联系能力,并且已经发展得太大,无法在个人层面上帮助你,并为你提供量身定制的支持或建议。

8.用代码做梦

代码中的梦有很多按话题划分的论坛。他们有一个广泛的主题列表,在回答问题时有一个非常活跃的社区。他们也有很多教程、编程帮助和非正式的聊天论坛。

他们以教程、编程语言或应用程序的编程帮助以及基于社区的论坛的方式主持社区学习,主题包括 IT 专业人员、学习代码、软件架构、设计模式、文档、编程笑话等等。

Dream In Code 的最大弱点是,它的平台使得它很难与贡献者建立长期关系,因为没有简单的方法来发送消息或联系个人来建立关系。

9.CoderDojo

CoderDojo 有一个可爱的免费、开放的本地编程俱乐部,主要面向年轻一代。他们为初学者策划了一个编程项目样本,比如用 scratch 制作了一个聊天机器人,用 HTML 创建了一个热图生成器,用 Python 实现了一个 pong 游戏。

最大的问题是,它的重点是学龄学习者,它往往侧重于面对面的会面,所以你的参与受到你所在位置的限制。另一方面,如果你有一些经验,你可以志愿做导师。向他人解释计算机科学基础可以帮助巩固你对概念的理解。

即使你没有利用他们的面对面交流,我认为他们的迷你项目指南对于以不同的方式应用你的编码技能是非常酷的。他们的大多数指南也面向完全的初学者,这可以帮助你避免变得超级沮丧和不知所措。

10.数字海洋

数字海洋是开发者支持开发者的平台。他们有技术教程以及技术讨论的空间。他们的社区支持许多不同技术主题的内容,如数据库KubernetesDockerPythonJavaScript安全Linux 基础知识

此外,他们有一个类似 StackOverflow 格式的论坛和一个越来越多的令人敬畏的技术演讲的 T2 储备。

Digital Ocean 声称更专注于云中的开发。他们通过他们的“开放教程、资源和活动”支持云开发者

去哪里寻找你想要的东西

不同的社区有不同的优势。有些是通过与其他个人联系来提供实际支持的,比如像 Boot.dev 这样的 Discord 服务器。其他的比较好回答具体的技术问题( DEVCodeNewbieDream in Code )。

人际关系将帮助你建立一个技术导师的群体。一个紧密的关系网也非常适合模拟面试、求职推荐等。特别是当涉及到保持你的动机、灵感和情感能量时,一个紧密团结的编码学习者团体是在编程世界中成功开始的支柱。

如果你是编程新手,从其他初学者和职业生涯早期的人已经实现的所有很酷的应用程序中获得灵感对你的长期动机是很好的。当你使用这些网站从很酷的项目中找到灵感,并且有机会提高你的技能后,你马上就可以展示你的惊人的项目了。

我最常用的熊猫功能的 10 大类

原文:https://towardsdatascience.com/top-10-categories-of-pandas-functions-that-i-use-most-61fae58082f6

熟悉这些函数可以帮助您处理数据

照片由Firmbee.comUnsplash 上拍摄

人们喜欢使用 Python,因为它有一个用于各种工作的第三方库的通用存储库。对于数据科学,最受欢迎的数据处理库之一是 Pandas。多年来,由于它的开源特性,许多开发人员为这个项目做出了贡献,使得 pandas 对于几乎任何数据处理工作都非常强大。

我没数过,但我觉得熊猫有上百种功能可以使用。虽然我经常使用 20 或 30 个函数,但把它们都谈一谈是不现实的。因此,在这篇文章中,我将只关注 10 个最有用的函数类别。一旦你和他们相处得很好,他们可能会满足你超过 70%的数据处理需求。

1.读取数据

我们通常从外部来源读取数据。根据源数据的格式,我们可以使用相应的read_*函数。

  • read_csv:当源数据为 CSV 格式时使用。一些值得注意的参数包括header(是否以及哪一行是标题)、sep(分隔符)和usecols(要使用的列的子集)。
  • read_excel:当您的源数据为 Excel 格式时使用。一些值得注意的参数包括sheet_name(哪个工作表)和 header。
  • read_pickle:当你的源数据是一个酸洗的DataFrame时使用它。Pickling 是一种存储数据帧的好机制,通常比 CSV 和 Excel 要好。
  • read_sas:我经常使用这个功能,因为我以前用 SAS 处理数据。

2.写入数据

处理完数据后,您可能希望将数据帧保存到文件中,以便长期存储或与同事进行数据交换。

  • to_csv:写入 CSV 文件。它不保留某些数据类型,比如日期。尺寸往往比别人大。我通常将参数索引设置为False,因为我不需要额外的列来显示数据文件中的索引。
  • to_excel:写入 Excel 文件。
  • to_pickle:写入 pickle 文件。正如我刚才提到的,我使用 pickled 文件,这样当我读取它们时,数据类型可以被正确地保留。

3.数据总结/概述

将数据读入数据帧后,获取数据集的一些描述符是一个好主意。

  • head:检查前几行,看数据是否读取正确。
  • tail:检查最后几行。这同样重要。当您处理一个大文件时,读取可能是不完整的。通过检查尾部,你会发现阅读是否已经完成。
  • info:对数据集有一个整体的总结。一些有用的信息包括列的数据类型和内存使用情况。
  • describe:提供数据集的描述性摘要。
  • shape:行数和列数(是属性,不是函数)。

4.分类数据

我通常在完成大部分其他处理步骤后对数据进行分类。特别是,如果我要将数据帧写入外部文件,比如 Excel,我几乎总是在导出之前对数据进行排序。这是因为排序后的数据更容易让其他人利用眼球定位到需要的信息。

  • sort_values:通过指定列名对数据进行排序。因为我主要处理行是观察值的文件,所以排序是按列进行的。

5.处理重复

当我们处理现实生活中的数据集时,很可能会有重复的数据集。例如,有些数据意外地在数据源中输入了两次。重要的是删除重复的内容。

  • duplicated:识别数据帧中是否有重复。您可以指定使用哪些列来标识重复项。
  • drop_duplicates:从数据帧中删除重复项。我不盲目使用这个功能。为了谨慎起见,我总是首先使用duplicated函数来检查重复项。

6.处理缺失值

数据集中存在缺失值几乎是不可避免的。检查数据集的缺失并决定如何处理缺失值是一个很好的做法。

  • isnull:检查您的数据帧是否丢失。
  • dropna:删除缺失数据的观测值。值得注意的参数包括how(如何确定是否删除一个观察值)和thred(符合删除条件的缺失值的数量)。
  • fillna:按照指定的方式填充缺失值,如向前填充(ffill)。

7.提取新数据

列可以包含多条信息。例如,我们的数据集可能有像 proj-0001 这样的数据,其中前四个字母是项目的缩写,而最后四个数字是主题的唯一 ID。为了提取这些数据,我经常使用以下函数。

  • map:使用单个列中的信息创建一个列。换句话说,你在一个Series对象上调用这个函数,比如df[“sub_id”] = df[“temp_id”].map(lambda x: int(x[-4:]))
  • apply:使用多列数据创建一列或多列。在创建列时,您经常需要指定axis=1

8.转换数据

通常有两种数据。一种是“宽”格式,指的是每行代表一个单独的主题或观察,列包括对该主题的重复测量。另一种是“长”格式。在这种格式中,一个主题有多行,每一行可以代表某个时间点的度量。通常,您可能需要在这两种格式之间转换数据。

  • melt:将宽数据集转换为长数据集。值得注意的参数包括id_vars(用于标识符)和value_vars(其值构成值列的列列表)。
  • pivot:将长数据集转换为宽数据集。值得注意的参数包括index(唯一标识符)、columns(成为值列的列)和values(具有值的列)。

9.合并数据集

当您有单独的数据源时,您可能希望合并它们,这样您就有了一个组合的数据集。

  • merge:将当前的与另一个合并。您可以指定一列或多列作为合并的标识符(参数on,或left_on & right_on)。其他值得注意的参数包括how(如 inner 或 left,或 outer),以及suffixes(两个数据集使用什么后缀)。
  • concat:沿行或列连接 DataFrame 对象。当您有多个相同形状的 DataFrame 对象/存储相同的信息时,这很有用。

10.按组汇总

我们的数据集通常包括指示数据特征的分类变量,例如学生的学校、科目的项目以及门票的班级级别。

  • groupby:创建一个 GroupBy 对象,可以指定一列或多列。
  • mean:您可以在 GroupBy 对象上调用 mean 来找出平均值。你可以对其他属性做同样的事情,比如std
  • size:群体频率
  • agg:可定制的聚合功能。在这个函数中,您可以请求对指定的列进行统计。

结论

在这篇文章中,我回顾了我在日常数据处理工作中经常使用的 10 大类函数。虽然这些评论很简短,但它们为你组织学习熊猫提供了指导方针。

希望这篇文章对你有用。感谢阅读。

数据团队的 10 大指标

原文:https://towardsdatascience.com/top-10-metrics-for-a-data-team-782999eb614f

以及如何去测量它们

数据团队的十大指标—图片由 Castor 提供

衡量数据 ROI 是数据团队面临的最大挑战之一。有许多方法可以做到这一点,没有既定的最佳实践。在之前的一篇文章中,受与数据领导者讨论的启发,我们试图确定一个衡量数据团队绩效的框架框架。本文试图进一步完善这种方法,提出 10 个可识别的指标来衡量数据团队的绩效。简而言之,这篇文章代表了我们的数据 ROI 框架的骨架。我们最喜欢的数据团队指标如下:

精度

一致性

可靠性

完整性

可用性

请求数量减少

基础设施成本节约

数据可访问性

数据正常运行时间

分析周转时间

这些度量标准分为三大类:数据质量度量标准、可操作性度量标准和团队生产力度量标准。我们在这篇文章中简要解释了这些类别是如何产生的,但是不要犹豫去检查我们之前关于这个问题的文章来理解我们是如何形成这个框架的。这里的主要思想是,数据团队经历不同的开发阶段,并且每个阶段对应于特定的指标。这个想法很直观:根据您的数据团队是 1 人还是 20 人,您将会看到不同的指标。

根据团队规模的数据团队指标—图片由 Castor 提供

数据质量指标

数据团队的首要任务应该是向利益相关者提供干净、可靠和易于理解的数据。在你关注其他事情之前,你需要勾选数据质量框。我们的前五个指标应该可以帮助您实现这一目标。

1.准确(性)

这是什么?

💡数据准确性是指每个可用的数据字段是否代表现实。

为什么重要?

准确的数据是确保项目顺利进行的先决条件。准确的银行信息意味着您可以向客户收费,准确的电话号码意味着您可以随时联系到他们,等等。相反,不准确的数据往往会导致挫败感和高昂的运营成本。这个标准听起来很基本,但是每个组织都要处理准确性问题。获得正确的数据准确性只会让你站在数据分析比赛的起跑线上:它不会让你走得很远,但你不能在没有勾选的情况下开始比赛。

如何衡量?

测量精度相当直观。您需要计算准确数据和可用数据总量之间的比率。

数据准确性公式—图片由 Castor 提供

正如你所想象的,棘手的部分是分子。事实上,它需要区分准确和不准确的数据。理想情况下,这应该以自动方式执行,以防止任何人无休止地滚动数据集,拨打每个客户的电话号码,以确保其准确性。衡量数据准确性的关键是建立适当的规则,然后进行测试和评估来衡量数据集的质量。可以针对参考数据集或真实实体进行验证。

它看起来像什么?

应该为每个数据集计算数据准确性,并且数据集用户可以方便地访问数据准确性。它应该显示为一个百分比,并与公司达成协议,即在某个准确度阈值下,数据集不应用于分析。‍

2.一致性

这是什么?

💡一致性衡量应该匹配的实体实际上是否匹配。

为什么重要?

数据一致性确保分析能够正确捕捉和利用数据的价值。在大多数组织中,相同的信息可以存储在多个地方。如果这些信息在不同的地方都与相同的信息一致,我们就说数据是一致的。数据一致性确保具有相同名称的元素也具有相同的值。例如,如果你的人力资源信息系统显示一名员工已经不在那里工作了,但你的工资单显示他仍在收到一张支票,这就是不一致的。

如何衡量?

数据一致性通常显示为各种记录中匹配值的百分比。

数据一致性公式—图片由 Castor 提供

它看起来像什么?

一致性很难定义和计算。这个度量应该在不同的粒度级别进行计算:两个同名的表应该包含相同的信息,两个同名的列应该具有相同的结构。在最小的粒度级别上,从相同、一致的数据计算两个指标应该得到完全相同的数字。‍

3.可靠性

这是什么?

💡可靠数据是随着时间的推移保持准确和一致的数据

为什么重要?

可靠性指的是数据质量和准确性能否长期保持。如果您的数据集在 T 时刻保持一致和准确,这很好,但您希望它在 T+1、T+2、T+3 等时刻保持一致和准确。如果数据不可靠,随着时间的推移,你就无法信任它。

如何衡量?

要衡量数据的准确性,应该查看用于创建和刷新数据的过程。这些过程被称为数据管道。如果数据管道完成了它们的工作,数据将被及时更新、刷新和交付。为了测量数据的准确性,你应该观察你的数据管道的健康状况,以及它们断裂的频率。数据准确性可以通过没有数据事故的时间百分比来获取。查看数据血统还可以让您更好地了解数据的可靠性。

数据可靠性公式—图片由 Castor 提供

它看起来像什么?

在数据集级别表示数据可靠性是最合适的。这将有助于您了解决定是否使用数据集所需的洞察力。例如,在使用过去两个月内中断十次的数据集之前,您可能要小心谨慎。‍

4.完全

这是什么?

💡完整性是指你手头信息的全面性。

为什么重要?

你可能有很多数据,如果不完整,就没有用。假设您正在查看一个客户的数据集,您只有客户的姓名,而没有他们的电子邮件地址,这使得您无法联系到任何人。你的数据不完整也没用。

如何衡量?

数据完整性的衡量标准是缺失数据条目的百分比。例如,有 100 个缺失字段的 500 列的完整度为 80%。

完整性公式—图片由 Castor 提供

它看起来像什么?

完整性也是一个度量标准,它非常适合在数据集级别显示。查看数据集的完整程度将指导您决定是使用数据集还是继续寻找更相关的信息。比方说,你偶然发现一个完备性为 15%的数据集。你可能更喜欢走自己的路,找到另一个更完整的。‍

5.可用性

这是什么?

💡数据可用性是指数据是否能被流畅地使用和理解。

为什么重要?

当您的数据易于理解并以明确的方式正确解释时,它就是可用的。例如,当一个外观仪表板很难理解时,你就有一个可用性问题。总的来说,用元数据丰富你的数据(即记录你的数据)使它在移动中变得可用和容易解释。即使您的数据在所有其他数据质量指标方面表现良好,它也很可能无法使用。事实上,这可能仍然意味着用户不信任、不理解或找不到数据。

如何衡量?

可用性可以通过查看您的数据资产的文档的级别,或者数据用户的数量来衡量。总的来说,用元数据丰富你的数据(即记录你的数据)使它在移动中变得可用和容易解释。这里要查看的关键指标是记录的列的百分比。展示和传播您的数据文档的最佳方式是使用一个 数据目录

数据可用性公式——图片来自 Castor

它看起来像什么?

这是一个在每个数据集上显示的好数字。它还提高了数据团队的生产力,因为它鼓励利益相关者使用最流行的文档。

可操作性度量

‍Once:你的数据质量已经超过 80%,这意味着你可以从你的数据中得到明确的答案,现在是第二阶段的时候了:数据可操作化。对于一个简单的概念来说,操作化是一个复杂的词。这意味着将您的高质量数据交给领域专家,以便他们可以在自己的工作中更快地移动,而不必依赖数据团队来完成他们的请求。运营分析不是使用数据来影响长期战略,而是为业务的日常运营提供战略。‍

6.请求减少

这是什么?

💡此指标指特定业务类别中请求数量的减少。

为什么重要?

衡量数据可操作性的一个好方法是查看您允许其他团队独立解决的问题的数量,这要归功于所提供的基础设施。例如,当数据团队相对年轻时,它可能会收到来自其他团队的许多关于归因的请求。随着数据基础设施的改善,以及运营团队轻松访问数据,依赖数据团队解决归属问题的需求将会减少。营销团队在解决这类问题时变得更加独立,最终将归因相关请求的数量降至零。衡量数据可操作性的一个好方法是查看不同类别中请求数量的减少。你能从列表中剔除的问题越多,你的数据就越容易操作。

如何衡量?

评估这一指标的一个好方法是测量自支持查询的百分比。也就是说,企业完全可以自己完成的查询。它反映了这样一种思想,即数据团队应该专注于卸载查询,并为业务提供基础设施来自己运行查询。(杰西,2022 )

自支持查询公式的百分比—图片由 Castor 提供

它看起来像什么?

你应该记录几个月来每个类别的下降情况。这将使您清楚地了解团队独立处理的问题,以及哪些问题他们仍然需要依靠数据团队来解决。当您收到关于某个特定类别的零个请求时,您可以认为该特定类别中的数据完全可操作。‍

团队生产力指标

现在,您已经有了干净且可操作的数据。这使你成为数据世界中一个非常小的特权群体的一部分。您需要做的最后一件事是衡量数据团队成员的工作效率。尽管它将恢复数据质量和数据操作化特性,但这些都很重要。事实上,你想确保你的团队成员做好他们的工作。这并不简单,因为你团队中的人有不同的任务。数据工程师的使命是通过提供良好的数据基础设施让每个人的生活变得更轻松,而数据分析师则专注于帮助人们做出更好的数据驱动型决策。Mikkel Dengsoe 很好地解释了工程和分析之间的区别。关键是,他们有不同的任务,应该有不同的衡量标准。这是本部分的目的。

7.基础设施成本节约

这是什么?

💡由于良好的数据管理和巧妙的工具选择,节省了成本

为什么重要?

除了向其他团队提供干净可靠的数据,数据工程师还负责良好的数据管理。这包括清理表格、归档不必要的表格,以及充分利用云所提供的优势。事实证明,良好的数据管理可以在存储成本方面节省大量资金。同样,数据工程师通常会寻求流程自动化或提高效率。这节省了时间和金钱。

基础设施成本的节约自然应该遵循良好的数据管理实践,并作为执行数据工程团队的自然回报。

如何衡量?

同样,这是一个合理的基本措施。您可以简单地查看基础设施成本降低的百分比。当然,你应该对这个数字持保留态度,并理解成本下降并不总是一个好兆头。成本下降是因为您的团队变得更有效率(好迹象)还是仅仅因为他们处理的数据比以前少了很多(不好迹象)?不管答案是什么,这个数字除了非常容易测量之外,还会告诉你一些事情。

它看起来像什么?

看看这些数字在几个月/几年内的变化,并相应地调整你的策略。‍

8.数据可访问性

这是什么?

💡该指标衡量数据人员访问数据的难易程度。

为什么重要?

乍一看,这个指标似乎有点愚蠢,但是您会惊讶地看到由糟糕的数据可访问性导致的沮丧程度。由于糟糕的文档或与数据治理计划相关的摩擦,数据科学家有时可能需要两到三天才能访问感兴趣的数据集。问题是,这些数据对于无法访问它们的人来说没有任何意义。

如何衡量?

这一指标并不容易衡量。你基本上是在寻找一个数据人员访问一个给定数据集所花费的平均时间。为了衡量这一点,您可以查看从请求访问数据集到获得访问权限之间的平均时间。这已经让您对贵公司的可访问性水平有了一个很好的了解。理想情况下,您还应该确定数据人员在仓库中找到所需数据集所需的平均时间。最直接的方法是做一个调查。

它看起来像什么?

你可以从全球层面来看这个数字。以及它的演变。如果这个数字非常高或者越来越低,也许是时候投资一个数据目录或一个更高效的数据治理计划了,这样可以同时实现数据保护和数据发现。‍

9.数据正常运行时间

这是什么?

💡数据正常运行时间指的是数据集准时交付百分比时间

为什么重要?

数据正常运行时间是一个关键指标,允许团队对工程团队的“乘数效应”进行量化。事实上,工程师很少影响组织中的顶级 KPI。它的使命是创建一个可靠的数据基础架构,然后充当“倍增器”,让分析团队更快、更高效地移动。数据正常运行时间是衡量这一基础设施质量的一个好方法,也是工程在多大程度上促进了分析生命的一个有力指标。它基本上是衡量数据可用和更新的频率。

如何衡量?

数据正常运行时间是数据集按时交付的时间百分比。它总是相对于预期频率SLA 要求进行计算。

**预期频率指的是数据集的预期更新频率。这通常是每天、每小时或实时的。

**SLA(服务水平协议)要求是由数据生产者和消费者之间的 SLA 协议规定的频率条款,规定数据必须在何时更新。例如,SLA 可能会规定一个绝对时间,如早上 7:00,或者一个相对时间,如每 3 小时一次。

测量数据正常运行时间的最简单方法是测量数据停机时间(当数据没有按时交付时),然后从 100%中减去这个数字。Barr Moses 在这篇伟大的文章中推导出了数据停机时间的公式。

数据停机时间公式—图片由 Castor 提供

例如,如果您在上个月有 15 个数据事件,每个事件需要 5 个小时来检测,3 个小时来解决,那么您的数据宕机时间估计为 120 个小时。‍

10.分析周转时间

它看起来像什么?

应该经常测量整个数据集的数据正常运行时间。观察它在几个月中的演变将会告诉你你的工程团队是否在更好、更有效地工作。

这是什么?

💡周转时间指的是从提出数据驱动的问题到分析能够提供答案之间所经过的时间。

为什么重要?

周转时间是衡量分析团队效率的一个很好的方法。这一指标最初是由 Benn Stancil 提出的。与工程团队相反,分析团队直接影响决策和顶级 KPI。他们的最终使命是为关键问题提供快速答案,从而启发组织的决策。在衡量他们的表现时,应该考虑到这一点。正如 Benn Stancil 所建议的,最好的方法是测量从提出问题到根据分析师给出的答案做出决定之间的时间。

以这种方式衡量分析性能的好处在于,它鼓励分析师将工作重点放在现实生活的决策上,防止他们迷失在探索性的数据分析中。

如何衡量?

“当分析师被问到一个问题时,一个计时器就开始计时。当基于该问题做出决定时,计时器停止计时。分析师的唯一目标应该是最小化计时器上的小时数和天数。"( B.Stancil,2022 )。因此,衡量分析周转时间的最佳方法是减去从提出问题到根据问题做出决定之间的时间。

分析周转时间公式——图片由 Castor 提供

它看起来像什么?

应该为团队中的每个分析师计算这个数字,因为它最适合衡量个人绩效。你可以随意合计它来获得团队的总周转时间,但是单独测量它将允许你做出更多的战略决策。

结论

数据分析的声称用途是增强组织内的决策。这是一个崇高的目标。然而,只有当数据是干净的,被决策者使用,并且你的团队成员是高效的,数据才会推动决策。这正是上面给出的度量标准所测量的。跟踪这些可以让你回答这样的问题:“我有高质量的数据吗?”,“领域专家是否将数据作为日常决策的一部分,或者他们是否仍然过于依赖数据团队?”以及“我的团队成员是否高效工作,完成他们的使命”。我们认为这三个维度最适合衡量数据团队的绩效,本文展示了在实践中如何做到这一点。

关于我们

我们写了利用数据资产时所涉及的所有过程:从现代数据栈到数据团队组成,再到数据治理。

在 Castor,我们正在开发一个数据文档工具 Figma,Slack generation。

想去看看吗?联系我们,我们将向您展示一个演示。

最初发表于https://www.castordoc.com

我从交付数据项目中学到的 10 个最重要的经验

原文:https://towardsdatascience.com/top-10-most-powerful-lessons-i-learned-by-delivering-data-projects-4dcb647f5219

最终将帮助你踏上学习之旅的核心课程

哈里森·库格勒在 Unsplash 上的照片

在任何新项目/冒险开始时,你都应该反思过去和吸取的教训。在交付了多个复杂的数据仓库、数据湖和分析项目之后,我对该做什么和该避免什么了如指掌。

任何成功项目的关键是为项目做出贡献的人。但失败的主要原因也是人,以及不切实际的时间表、不断变化的目标和疲惫的利益相关者。

今天,我将总结我在交付复杂数据项目时学到的 10 大经验。我相信这些也将适用于其他领域。

让我们开始吧。

1.没有独角兽

数据本质上是复杂的;它有许多移动的部分、难以理解的挑战和难以消化的解决方案。我还没见过一个人能解决项目中的所有问题。那个人不存在。

基础架构、应用、数据工程和分析团队拥有您必须利用的技能,以取得成功。有些人足够灵活,可以身兼数职,但专业化是无可替代的。将它作为你的优势,并确保所有相关的技能都出现在项目中。

2.最终用户不知道他们想要什么

这绝不是轻率的评论——最终用户对他们想从项目中得到什么有一个模糊的想法。然而,一旦他们看到第一次迭代,他们很快意识到结果与他们的第一个愿景不一致。用一把盐来对待早期需求并不是一个坏主意。

敏捷交付在某种程度上解决了这个问题;然而,在深度技术交付中,快速的第一次迭代有时是不可能的。在这种情况下,线框通常是显示您期望的最终产品的关键,无论是报告、指标还是模型输出。

3.假设数据质量很差

因此,这并不奇怪,但大多数组织都在与低质量的数据作斗争。规划数据项目交付时,必须包括数据分析和补救时间。99%的情况下,数据的质量低于标准,需要一些人工或机器干预来解决。

4.在风险成为问题之前,没有人会关心风险

人类自然不会厌恶风险。如果他们看到了风险,即使是闪烁的红灯,他们也会认为这是未来可能不会发生的事情。例如,说数据质量可能很差,解决问题可能需要一些时间,通常会被翻译成“我们可能会没事的。”

对你认为的风险和问题要慷慨。不要担心听起来很消极,突出你早期发现潜在问题的领域,并在它们成为问题之前采取缓解措施。如果你坚持每天在风险周报上报道,人们会适应的;采取行动显示即将发生的问题的威胁。

5.某人的技术债务就是你的破产

几乎所有项目的交付都带有一些技术债务。你知道那张欠条,项目发起人签字同意让那该死的东西过线。与银行借条不同,没有人能让项目对这笔债务负责。

就像国家债务一样,它会传递给下一代。在我们的例子中,它被提供给下一个需要这些数据的项目。确保在项目规划的时候,你清楚地看到这些技术债务。你需要一个计划,在没有原始项目团队的情况下解决债务。

6.软技能与技术技能同等重要(如果不是更重要的话)

与富有挑战性的利益相关者打交道,清晰地管理关键信息,并以可控的方式传递坏消息;在这一行里有些事情是意料之中的。当然,技术技能会让你成为一个可靠的资源,但是拥有软技能会让你与众不同。

理解复杂的技术概念,将它们转化为商业用语,然后说服商业用户,同时保持你的诚信和声誉,这是成功项目交付的秘诀,事实上,也是成功职业生涯的秘诀。

如果你不能简单地解释它,你就理解得不够好——阿尔伯特·爱因斯坦

7.厨师多了烧坏汤

除非交付非常复杂,否则坚持使用 1 或 2 家供应商(顾问、系统集成商等)是有意义的。)和等量的厂商(软件公司)。每个人都有最终目标和议程;花太多时间让人们认同你的最终愿景并不容易。

尽量保持团队结构简单,报告路线透明,官僚作风最小化,升级路径沟通良好。确保问题得到快速管理,不一致得到纠正。数据项目已经有许多可移动的部分,不要让人员和团队成为另一个可能导致失败的部分。

8.20%的工作将带来 80%的收益

帕累托原则非常适用于数据项目;有限的工作量将获得最大的收益。关键是要快速识别这 20%,并确保该部分的风险得到及时缓解。例如,提高数据质量将减少人工返工、数据管道干预以及降低成本和风险。专注于第一点,这将导致快速的利益实现。

继续使用这种方法进行优先级排序;很快,您将结束一个交付积压,这将更快、更有效地使最终用户受益。

9.问责文化并不总是存在的

复杂的项目意味着你要和一个多样化的团队一起工作。我非常惊讶地发现,并不是每个人都像你一样考虑责任。当事情变得艰难,项目截止日期迫在眉睫时,你希望团队中有一种负责任的文化,在这种文化中,每个人都平等地尽自己的职责。

但是让小错误不受挑战,例如代码开发、测试输出、用户参与等的延迟。没有充分的理由,就会滋生一种散漫的文化。从项目的第一天起,就把责任作为一个关键原则,确保每个人都遵守它,并生活和呼吸它。

10.定期的反馈会造就一个快乐的团队

如果我问任何人他们最喜欢哪个项目?答案不会是最容易/最有挑战性的,而是拥有最好团队的。在这个项目中,你知道你的团队成员支持你,并为一个共同的目标共同努力,这种感觉令人振奋。

但是一个好的团队只有当你分享关于什么有效,什么可以改进的定期反馈时才有可能。我们天生避免对抗的情况,但这种对话往往会带来最大的改善。

结论

这是我的十大经验,我确信还有更多我可以记录下来,也许我会把它留到续集里。如果你遇到了更多,请在下面留言分享。

如果您想了解数据架构的趋势,请查看这篇文章:

如果您没有订阅 Medium,请考虑使用我的推荐链接订阅。它比网飞便宜,而且客观上能更好地利用你的时间。如果你使用我的链接,我会获得一小笔佣金,而你可以在 Medium 上获得无限的故事。

我也定期在推特上写东西;跟着我这里

提高生产力的十大 VS 代码扩展

原文:https://towardsdatascience.com/top-10-vs-code-extensions-to-boost-productivity-526595b18325

您应该开始使用 VS 代码扩展来提高开发人员的生产力

VS Code 受欢迎的关键之一是其无与伦比的扩展生态系统,它提供了额外的功能并改善了整体编码体验。

10 个最佳 VS 代码扩展(图片由作者提供)

在这篇文章中,我将分享我的十大 VS 代码扩展的精选列表,这将大大提高你的生产力,使你成为一名更有效的开发人员。我们将深入研究这些扩展做什么,它们是如何工作的,以及为什么它们使编码更加容易。

GitLens

GitLens 是一个非常流行的扩展,但由于它对任何开发人员的工作流程都很方便,所以总是值得一提。通常,作为开发人员,我们想知道谁写了一行代码或文件的作者,GitLens 允许您在 VS 代码文件中直观地显示 git 上下文。我最喜欢的扩展用例是当我需要找到合适的人来标记 PR 时。使用 GitLens,我可以预览每个文件的所有作者,然后使用这些信息来标记同行。文件的作者特别适合公关评论,因为他们有必要的背景来提供有价值的反馈。

除了查看行和文件周围的 git 上下文等基本功能之外,GitLens 还让您能够在编辑器中执行各种 Git 操作,而不是使用终端。使用 GitLens,您可以恢复、合并、甚至重置提交。如果您有兴趣了解 GitLens 的所有特性,文档内容丰富,涵盖了每一个特性。

Gitlens ( 来源)

棋子

Pieces 是一个 AI 助手,可以让你保存自动分类的代码片段,将代码截图转换为文本,并根据编码模式自动保存常用代码。Pieces 的 VS 代码扩展允许您管理所有存储的代码片段,并将它们直接导入到编辑器中。然而,当你集成 Pieces 的其他应用程序时,比如它的 Chrome 扩展,Pieces 的真正力量就来了。只需 VS 代码和 Chrome 扩展,您就可以在任何网页上保存代码块,如 Stack Overflow,并将其直接导入 VS 代码文件或使用 Pieces 的自动完成功能导入。

要开始使用 Pieces,请下载 Pieces 引擎、Pieces OS 和 VS 代码扩展,Pieces OS 支持所有的集成,VS 代码扩展也可以在上面的网站链接中找到。

件(图片由作者提供)

更好评论

更好的注释使开发人员能够使用完全可定制的标记系统更好地记录他们的代码。使用这个扩展,您可以通过定制不同注释类型的样式来获得语义上下文。例如,有了更好的注释,你可以让所有的todo注释在你的配置中显示为蓝色,当你查看一个有 todo 的文件时,它会立即显示为蓝色。我用更好的注释来表示常见的注释,如bugtodoqueryquestion

更好的评论(图片由作者提供)

涡轮控制台日志

在编写 JavaScript 时,大多数人都喜欢说他们一直在使用调试器,但事实并非总是如此。有时,控制台日志记录只是开发过程中的一个必要部分,而 Turbo 控制台日志使它变得异常简单。使用 Turbo 控制台日志,您可以突出显示变量,使用键盘快捷键插入多个控制台日志,并使用一个命令删除所有日志。这对于加速 JavaScript 开发和调试确实至关重要。

涡轮控制台日志(来源)

LiveShare

随着时间的推移,远程和混合工作变得越来越普遍,但这并没有降低协作和结对编程的重要性。LiveShare 使我们能够通过 VS 代码会话亲自模拟结对编程。使用 LiveShare,您可以邀请多达 30 人参加您的结对编程会议。如果您有 LiveShare 扩展包,其他人也可以跟随您处理文件、编辑或编写代码(取决于您授予的权限),并通过音频与您交谈。

LiveShare(图片由作者提供)

代码飞行者

优化和重构代码是开发过程的一个重要部分,而 Code Runner 是这个过程中不可或缺的工具。每当您想要测试代码片段时,Code Runner 都为您提供了突出显示您的代码并执行它以检查它是否工作的能力。编写许多行代码却不知道代码是否有效的日子已经一去不复返了。

代码运行者(图片由作者提供)

https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode

Prettier 是一个非常固执己见的代码格式化程序,它在开发过程中强制执行 JavaScript 最佳实践。虽然 prettle 也是一个独立的 JavaScript 包,但是这个扩展的强大之处在于它可以被定制来在保存时根据 prettle 的配置重新格式化你的代码。Prettier 的唯一警告是它非常固执己见,会强行重新格式化和构建代码。如果这不是您想要的行为,它可能不是一个很好的选择,但是我坚信它有助于增强初学者的最佳实践。

更漂亮(作者图片)

码头工人

Docker 扩展有助于执行 Docker 操作,而不会留下 VS 代码。大多数开发现代应用程序的开发人员都使用 Docker 来封装他们的应用程序,通过这个扩展,任何开发人员都可以与他们的 Docker 容器、卷、网络等进行交互。除了执行所有涉及 Docker 的本地操作,开发人员还可以将图像推送到他们的容器注册中心。这个扩展真正支持从初学者到高级的任何级别的 Docker 开发。

Docker(图片由作者提供)

导入成本

在编写 web 应用程序时,总会有关于应用程序包大小和性能的讨论。尽管这些讨论是必要的,也是重要的,但是围绕这些问题采取一些基本措施的最佳时机是在您编写代码的时候。Import Cost 通过在 Import 语句旁边显示导入的大小,帮助我们轻松地做到这一点。在引擎盖下,import cost 使用 webpack,当您更改导入报表时,它会立即给出反馈。如果您是从事 web 应用程序开发的前端开发人员,这一点很简单,也是必须的,因为应用程序的性能会影响用户体验、SEO 排名和转化率。

导入成本(图片由作者提供)

ESLint

和 Prettier 一样,ESLint 也是一个独立的 JavaScript 包,附带一个 VS 代码扩展。ESLint 这个包既是 linter,也是代码格式化程序,经常被许多 JavaScript 项目引导。使用这个扩展将会根据您设置的配置规则,提供实时改进代码的建议。同样,这有助于在您进行项目时,强制执行使用最佳实践来编写编写良好的代码的实践,而不是在以后考虑这些事情。

EsLint(图片由作者提供)

如果除了这里描述的以外,你有任何有用的扩展,请在下面评论它们,如果你知道任何新的或有用的扩展,请给这篇文章一个分享或赞!

给初学者的关于 BigQuery 和 SQL 的 12 条建议

原文:https://towardsdatascience.com/top-12-advice-on-bigquery-and-sql-for-beginners-cc82924ca60b

以正确的方式使用 BigQuery 开始您的数据仓库项目

凯瑟琳·拉威利在 Unsplash 上拍摄的照片

介绍

BigQuery 是众多数据仓库解决方案中的一个,但却是最受欢迎的一个。在对不同公司使用的四种相互竞争且熟悉的解决方案进行快速研究比较后, BigQuery 似乎在领奖台上排名第二。

每个解决方案的采用量。来源:https://discovery.hgdata.com(图片由作者)

为了分析数据,Google BigQuery 以及许多其他数据仓库系统使用 SQL 作为编程语言。

所以,无论你是想学习 SQL,启动一个数据仓库项目,还是想在顶级数据仓库平台上实践,这里有一些建议我很乐意与你分享!

建议 1:免费使用 BigQuery

您可以在一定程度上免费使用 BigQuery。通常需要考虑两个问题:数据存储数据分析(查询)

您每月可以免费获得:

  • 10 GB 存储空间
  • 1 TB 的查询

其他操作,如批量加载数据(流接收将收费)、复制数据、删除数据或导出数据,通常是免费的。所以,如果你的数据量允许,就不要再等着开始了!

您可以在此找到所有 BigQuery 定价详情:

https://cloud.google.com/bigquery/pricing

关于所有谷歌云平台服务(BigQuery 和其他)的免费层和免费层的更多细节可以在这里找到:

https://cloud.google.com/free

建议 2:理解查询定价

BigQuery 的主要用例是对数据进行查询,以便提取有用的信息。有两大类成本:

  • 保管费用
  • 查询成本(分析)

从前面的建议中,我们看到有一个免费层,但在此之后,对于分析统一费率(这是最常见的一种)您将对每 TB 查询的数据收取 5 美元。

要估计一个查询需要解析多少数据,您可以查看您的 web 浏览器代码编辑器,其中有一个通知说:

该查询在运行时将处理“10 GB”。

其中“10”将根据您的查询进行调整,“GB”也是如此(这个 可以是 24 MB、102 KB、14TB 等等……)

运行该查询将处理的字节数(这里是 1.2GB)

为了了解成本,您可以将查询中处理的数据量转换为兆字节,然后乘以 5 美元。

在我们的示例中,我们有 1.2GB,相当于 0.0012 TB,然后乘以 5 等于 0.006 美元。

正如你所看到的,我们将为这个查询支付一个非常适中的金额,但我相信你会运行不止一个!

一般来说,控制查询成本是一个好的做法。你可以通过这个链接来学习。

https://cloud.google.com/bigquery/docs/best-practices-costs

建议 3:探索 BigQuery 免费数据集

如果您没有加载数据,并且想要练习您的技能,BigQuery 通过 Google Cloud 公共数据集计划向公众提供了许多可用的数据集。

稍后,如果您想要合并/丰富您自己的数据,这些数据集也会很有用。(例如,地理数据等)

你可以上数据集市场。这就是市场的样子,当点击一个可用的数据集时,您会看到详细信息(数据的描述和每个字段的描述)。

谷歌大查询数据集市场(图片由作者提供)

我个人使用以下数据集:

  • Google 分析示例
  • 秘密党员
  • 公用事业 _ 欧盟

费用警告:谷歌为这些数据集的存储付费,但你将为你执行的查询付费。(参见 建议# 1——免费使用 big query)。

您可以在 SQL FROM 语句中使用项目前缀bigquery-public-data来查询它们,如下所示:

查询 Google BigQuery 公共数据集

建议 4:在同一地区创建数据集

创建数据集时,您必须填写以下信息:

  • 数据集 Id :您想要给数据集起的名字
  • 数据位置:决定你的数据存储在哪里(欧洲、美国、亚洲等)
  • 默认表过期:如果您希望在指定的天数后自动删除该数据集中的表,或者从不删除
  • 加密:您希望数据如何加密(默认情况下是加密的)

重要的是在你的项目中选择三个可用位置中的一个:美国、欧洲或亚太地区

主要原因是,如果您在欧盟有一个数据集,并且您正尝试对美国的数据集进行联接/合并,BigQuery 将返回如下错误:

运行查询时出错

未找到:在位置 US 中未找到数据集 datastic:crypto

如果您试图连接来自不同位置的数据,这也适用于其他服务(云 SQL 等)。

还要记住,数据集一旦创建,其位置就不能更改。(但是您可以将数据集复制/移动到另一个位置,这需要额外的工作)

此外,不同的地区和位置有不同的定价和特性,您可以在 Google 文档中找到更多信息。

https://cloud.google.com/bigquery/docs/locations

建议 5:极限陈述不会降低成本

运行查询时,BigQuery 会评估需要处理多少字节(比较 建议#2 —了解查询价格)

使用或不使用 LIMIT 子句的每个查询处理的字节数(图片由作者提供)

在左边,我们观察到这个查询将使用 1.2 GB 的数据,而没有使用LIMIT子句。在右边,我们看到这个查询将使用子句处理完全相同的数据量。

那么这个条款有什么好处呢?

优点是它减少了用户界面中显示的数据量,使得显示速度更快。

此外,当您有一个聚集表时,LIMIT子句可以减少扫描的字节数,并且确实减少了查询的成本。

建议 6:只选择你需要的列

BigQuery 是一个面向列的数据库,简而言之,在大型数据库中扫描和聚合(求和或平均等)数据非常有效。

它是高效的,因为它不必从整个行中读取数据。想象一下需要处理的数据,如果您有 10 亿行 40 列,您需要读取每行所有 40 列中包含的数据,而您只需要两三列。

作为一个良好的实践,建议尽可能不要使用通配符 SELECT * FROM table ,而是实际上只选择您需要的列,例如:

SELECT col_1,col_2 FROM table;

这将极大地降低您的查询成本。

您可以在下面的 BigQuery 中找到关于数据如何存储和表示的更多细节。

https://cloud.google.com/bigquery/docs/storage_overview

建议 7:在末尾排序,在使用 a JOIN之前减少数据

编写查询的方式对成本和执行性能都有影响。这可以通过避免 SQL 反模式和使用正确的语法来避免。

以下是我可以分享的一些优化:

  • 当你之前不需要的时候,在最后订购一次结果
  • 在执行连接之前减少数据量
  • 在查询开始时使用 WHERE 和 DISTINCT 语句,以减少所需的数据量。
  • 使用近似聚合函数

除了本文中的其他建议(参见 建议# 5——仅选择您需要的列)之外,另一个优秀的实践是在早期减少必要的数据量,以减轻后续查询步骤的负担。

一般来说,避免 SQL 反模式是最佳实践。SQL 反模式只是开发 SQL 代码时的一个常见错误。

https://cloud.google.com/bigquery/docs/best-practices-performance-patterns https://github.com/boralp/sql-anti-patterns

您还可以更深入地了解 SQL 查询优化和性能。

https://cloud.google.com/bigquery/docs/best-practices-performance-overview

建议 8:格式化你的查询

格式化你的查询将会对你的读者或者在完成代码审查时产生影响,这是我鼓励从一开始就养成的习惯。

对于 mac 用户,可以在 BigQuery 浏览器编辑器中使用以下快捷键: cmd+shift+f

它将改变您的查询的外观:

非格式化查询

更易读、更清晰的格式,突出显示函数、名称、子句和语句,如下所示:

使用 BigQuery 自动格式化 cmd+shift+f 的 SQL 格式化查询

建议 9:跟上时代

谷歌开发人员不断地给他们的产品添加新功能,BigQuery 也是如此。这可以是新功能公告bug 修复或者简单的改动。了解这些变化是值得的。

这些说明包括对 BigQuery、BigQuery ML、BigQuery 数据传输服务和 BigQuery Omni 的更改。

https://cloud.google.com/bigquery/docs/release-notes

您可以在 BigQuery 中以编程方式访问发布说明,这也将使您能够灵活地通过日期和以及说明类型(修复、问题、特性、服务、重大变更等)对进行排序

查询 BigQuery 的 Google 发行说明

建议 10:在你的查询中添加评论

不管使用什么语言(SQL、Python、R、C++、Javascript 等),注释代码都是一个好习惯。

它解释了代码做什么,SQL 查询也不例外。

在 BigQuery 以及许多其他系统中,可以使用双破折号(连字符)进行注释,如下所示:

使用双破折号插入注释

对于 mac 用户,可以使用键盘快捷键 cmd+/ 来自动注释查询的每一行。

建议 11:学会调试你的查询

调试和改进您的查询可能需要一些练习。但是,如果您发现您的查询过于缓慢或过于昂贵,您可以阅读查询编辑器中的查询执行细节选项卡。

查询的执行细节(图片由作者提供)

一篇很好的帖子讨论了 BQvisualiser,这是一个可以用来评估你的查询哪里可以改进的工具。此工具直接连接到您的项目。

https://medium.com/google-cloud/visualising-bigquery-41bf6833b98

有关查询执行的更多信息,请访问:

https://cloud.google.com/bigquery/query-plan-explanation?_ga=2.124063242.-1866349659.1650452569

建议#12:社区 UDF

尽管 UDF(用户定义函数)已经是一个比较复杂的主题,但是有一些社区资源可以帮助您入门,或者至少在您自己的项目中重用它们!

https://github.com/GoogleCloudPlatform/bigquery-utils

UDF 是允许您将 Javascript 或 SQL 代码作为函数运行的函数。例如,假设您的表中有一个包含城市名称的字段,并且您希望对它们进行整理,那么您可以使用 Javascript 库编写一个函数,并将它一次性应用到整个表中。

让我们付诸行动吧。✨

我希望这十二条建议能够帮助您在 BigQuery 上有一个良好的开端,或者只是探索并熟悉这项技术。

许多数据仓库技术都有类似的品质,肯定会是您的应用程序的绝佳选择。我要说的是,根据您的特殊要求仔细检查规格和细节仍然很重要。

请让我知道你是否觉得这篇文章内容丰富,是否在评论中对你有所帮助!🤓

15 大著名数据科学名言

原文:https://towardsdatascience.com/top-15-famous-data-science-quotes-f2e010b8d214

著名数据科学家的顶级语录,有时很有启发性,通常很幽默,而且总是很有见地

安德鲁·乔治在 Unsplash 上的照片

背景

在过去的几年里,随着我阅读和研究数据科学领域,我养成了收集、记录和解释数据科学相关引文的习惯,无论我在哪里遇到它们。

我发现这些引语有时很有启发性,往往很幽默,而且总是很有见地,因此我在下面列出了我非常喜欢的一系列引语,以及我对它们含义的解释和我们可以从它们身上学到的东西。

在我们开始报价之前,请考虑…

通过我的推荐链接加入 Medium(如果你使用这个链接注册,我将收取一定比例的费用)。

每当我发表新故事时,订阅一封免费电子邮件。

快速浏览我之前的文章

下载我的免费战略数据驱动决策框架

访问我的数据科学网站- 数据博客

15 大著名数据科学语录

1。“只有当我们收集的数据能够通知和激励那些有能力做出改变的人时,事情才能完成。”

(麦克·施默克博士,作者)

这是我最喜欢的数据科学名言之一。它提到了数据科学的“最后一英里”,并推断我们可以接触到聪明的数据科学家和良好的数据,但如果我们无法影响关键决策者根据研究结果采取行动,那么一切都是徒劳的,我们心爱的模型注定会在数据科学的书架上积灰。

https://www.amazon.co.uk/Analytics-Lifecycle-Toolkit-Practical-Capability-ebook/dp/B07BB63MXH

2。“拷问数据,它什么都会坦白。”

(罗纳德·科斯,经济学,诺贝尔奖获得者)

这是我收集的第一个与数据科学相关的引语,它指的是让数据符合假设的诱惑,如果我们对数据集痴迷足够长的时间,也称为“确认”偏差。

关键的学习是培养一种意识,即何时接受对特定数据集的持续分析无法实现进一步的价值,甚至有时我们可能需要放弃。

3。“数据是新的石油。”

(克莱夫·亨比,数学家和市场专家)

2006 年,Clive Humby 通过宣称“数据是新的石油”创造了一个持久的数据科学名言。

这种比较已经被争论和质疑了很多次,但它仍然强调了数据对企业具有重要的、通常未被利用的货币价值,并且数据必须被挖掘、提取、提炼和交付以实现这种价值。

4。"所有的模型都是错误的,但有些是有用的."

(乔治·e·p·博克斯,英国统计学家)

数据科学模型是现实世界的简化抽象,因此在某种程度上它们都是错误的,因为现实世界是唯一真实的表示,所以为什么要费心呢?

我们建立了一个数据模型来开发描述性和预测性的洞察力,以推动决策制定的改进,任何足够准确的模型都可以产生这种洞察力和相关的竞争优势,即使它必然会与它所代表的现实世界有差距。

5。“如果我们有数据,让我们看看数据。如果我们只有意见,那就用我的吧。”

(吉姆·l·巴克斯代尔,美国执行官)

Jim Barksdale 鼓励他的团队带着可以在决策过程中分析的数据来找他,并带有内在的威胁,即如果没有数据可用,Jim 将会实施他自己的观点,所以你最好在下一次会议上带着数据!

6。"直觉是认为你知道,但不知道你为什么这样做."

(以色列裔美国心理学家、诺贝尔奖得主丹尼尔·卡内曼)

根据丹尼尔·卡内曼的著作,纯粹的直觉是一种谬误,根据推论,仅仅依靠直觉而没有数据和证据的决策者会做出错误的或者只是侥幸的决定。

https://www.amazon.co.uk/Thinking-Fast-Slow-Daniel-Kahneman/dp/0141033576

7。“大数据就像青少年性行为;每个人都在谈论它,没有人真正知道如何去做,每个人都认为其他人都在做,所以每个人都声称自己在做。”

(美国教授丹·艾瑞里)

这条轻率、幽默但颇有见地的引用来自丹·艾瑞里的一条著名的推特。

它指的是许多数据科学专业人员、经理和领导者在没有真正了解大数据是什么的情况下吹嘘他们的公司利用大数据的趋势,更不用说开发出成熟的大数据能力来提供这些重要而切实的影响和成果。

8。“我们相信上帝。其他的都带数据。”

(李丽蕊烘焙集团首席执行官巴里·贝拉查)

这是另一位成功高管的伟大数据科学相关语录。

我的解释是,巴里只会相信上帝在没有数据支持的情况下做出决定,如果其他人来到他的办公室,他们最好带一些数据来支持他们的观点和意见!

9。"使用不充分数据的错误比完全没有数据的错误要少得多."

(查尔斯·巴贝奇,英国数学家)

您是否曾经参加过这样的会议:数据团队努力工作以提供所需的信息,但却被其他与会者否决,他们认为这些数据不能作为决策依据?

好吧,我把这句名言放在我的后兜里,以防万一。

不言而喻,我们希望我们的数据尽可能准确、及时和一致,以实现和支持有效的决策,但即使有一些不足之处,使用数据仍然比求助于无知的直觉、轶事和个人意见好得多。

10。“先生们,你们需要把装甲板放在没有弹孔的地方,因为那是没有返回的飞机上的弹孔。”

(匈牙利数学家亚伯拉罕·瓦尔德)

众所周知,亚伯拉罕·瓦尔德减少了二战盟军飞机的损失,他建议高级军官在返回基地的飞机上没有弹孔的地方增加装甲板,而不是弹孔的地方。

他的想法是,返回的飞机不是增加装甲的好指标。没有回家的子弹被射到了其他地方,比如发动机和前锥。

在数据科学中,这是指“可用性偏差”,即倾向于只使用容易获得的数据来开发项目,而不是使用对分析至关重要但难以获得的数据。

11。"没有数据就进行理论化是一个严重的错误。"

(夏洛克·福尔摩斯,侦探)

我们可能会认为夏洛克·福尔摩斯主要是一名侦探,但在这句话中,这位伟大的侦探支持了我们最近的一些企业贡献者的观点,即数据是形成和评估我们假设的关键先驱。

12。"没有任何伟大的营销决策是基于定性数据做出的."

(约翰·斯卡利,美国商人)

我们已经确定,数据诋毁者经常质疑数据的准确性,但另一个经常谴责数据在决策中的重要性的群体是创意人员。

在这里,约翰·斯卡利用相反的观点对此提出了质疑,他说,即使我们把营销和定性数据联系起来,除非有定量数据,否则从来没有做出过伟大的营销决策。

在现代的机器学习世界中,我们甚至可以使用模型,利用情感分析和其他自然语言处理技术,将定性数据开发成定量信息,因此真的没有借口!

13。"你可以拥有没有信息的数据,但你不能拥有没有数据的信息."

(丹尼尔·凯斯·莫兰,美国小说作家)

随着企业获得更高的数据成熟度,数据可以被分析、综合并发展为信息,然后再转化为情报,最后转化为知识,然而这一过程是单向的。

丹尼尔·凯斯·莫兰的引用强调了两个关键的教训。首先,如果我们无法分析、清理和提炼原始数据,我们就永远无法获得结构化的、有意义的、有洞察力的信息,而且如果一开始就没有原始数据,我们就永远无法达到更高的数据成熟度水平。

14。“数据战胜了情绪。”

(Sean Rad,Tinder 联合创始人)

约会应用 tinder 完全是关于建立友谊和浪漫关系的情感业务,但在这里,Sean Rad 用三个词表明了数据作为在数字和现实世界中建立这种能力的基础组成部分的重要性。

15。“在未来的劳动力市场上,任何没有数据的决策都只是瞎猜”

(经济学家邓肯·布朗和董事总经理安迪·杜尔曼)

我将用这句话来结束我著名的引语,这句话暗指了历史上基于感觉招聘的趋势,让位于一个设想的未来,在这个未来,没有数据的招聘比猜测好不了多少。

当然,它与数据的道德和伦理用途有着重要的重叠。

我们不应该也不能根据公共空间(社交媒体等)的数据做出以人为本的决定。)除非这些数据已经过严格、有力的检查和保证,但数据在未来的招聘、人员配备和人事决策中肯定会发挥越来越大的作用。

结论

感谢您的阅读!我希望您喜欢我最喜欢的数据科学相关语录,希望您觉得它们有趣、有见地且幽默,希望您会考虑使用它们来塑造您的数据科学之旅,并通知和吸引您的同行、公司和网络。

如果你喜欢这篇文章,请考虑…

通过我的推荐链接加入 Medium(如果你使用此链接注册,我将收取一定比例的费用)。

每当我发表一个新故事时,订阅一封免费电子邮件

快速浏览我之前的文章

下载我的免费战略数据驱动决策框架

访问我的数据科学网站— 数据博客

15 个最常见的数据质量问题(以及如何解决它们)

原文:https://towardsdatascience.com/top-15-most-common-data-quality-issues-and-how-to-fix-them-c1ef0854dca6

处理常见数据质量问题的提示和技巧

Unsplash 上由 Miikka Airikkala 拍摄的照片

想象一下,你所有的分析、机器学习和决策都有干净、高质量的数据。是的——我也想象不出来!

数据的固有特性是其质量,即使有最强有力的控制,质量也会下降。100%的准确性和完整性是不存在的,这也不是重点。相反,重点是选择你的战斗,并将质量提高到一个可接受的阈值。

让我们看看 15 个常见的数据质量(DQ)问题,以及我们应该如何解决它们。

1.不完整数据

这是迄今为止与 DQ 打交道时最常见的问题。关键列缺少信息,ETL 作业失败或导致下游分析影响。解决这个问题的最好方法是建立一个调节框架控制。该控件将检查通过分析图层的记录数量,并在记录丢失时发出警报。

2.默认值

有没有分析过你的数据,发现交易日期是 1891 年 1 月 1 日?除非您的客户群由 130 岁的人组成,否则这很可能是使用默认值的情况。如果缺少文档,这尤其是个问题。解决这个问题的最好方法是分析数据并理解为什么使用默认值的模式。通常,当现实生活中的替代日期不可用时,工程师会使用这些数据。

3.数据格式不一致

字符串列最容易遇到这个问题,因为数据可以以多种格式存储。例如,客户的名和姓以不同的大小写存储,或者电子邮件地址没有正确的格式。当多个系统存储信息时,如果没有一致的数据格式,就会出现这种情况。为了解决这个问题,数据需要在整个源系统中或者至少在数据管道中被均匀化(标准化),当被送入数据湖或数据仓库时。

4.重复数据

相当容易发现,很难修复。如果关键属性中包含脏数据副本,将会破坏所有关键的下游流程。这也可能导致其他 DQ 问题。为了解决这个问题,需要实现一个主数据管理控制,甚至像惟一性检查这样的基本控制。此控件将检查记录的精确副本并清除一条记录。它还可以将其他记录的通知发送给数据工程师或管理员进行调查。

5.跨系统不一致

在通过收购和合并发展起来的大型组织中非常普遍。多源遗留系统对世界的看法都略有不同。客户名称、地址或出生日期信息不一致或不正确。与 4 一样,必须实施主数据管理解决方案,以确保所有不同的信息都匹配到一条记录中。这种匹配不需要精确;基于匹配百分比的阈值,它可以是模糊的。

努力理解缩写,首先阅读这篇文章:

https://medium.com/geekculture/25-terms-to-help-you-in-your-career-in-data-science-14ca681b0699

6.剧烈的数据变化

假设您每天都收到一个装满客户地址的数据文件。您通常每天会收到 5000 条记录,但今天您只看到 30 条记录。该文件仍然通过其他检查,如唯一性、有效性和准确性;但是,它仍然缺少数据。1 中提出的协调框架。将有助于在您的分析图层中解决这一问题。如果此数据来自不同的来源,您将必须实施一个控制文件来确认发送的记录。然后,一个自动化过程会将该文件与数据传输后收到的记录进行核对。该控件将有助于捕捉和修复此问题。

7.孤立数据

这个 DQ 问题与数据不一致问题有关,即数据存在于一个系统中,而不存在于另一个系统中。客户存在于表 A 中,但他们的帐户不存在于表 b 中。该客户将被归类为孤立客户。另一方面,如果一个帐户存在于表 B 中,但是没有关联的客户,那么它将被归类为孤立帐户。每次在表 A 和 B 中接收数据时检查一致性的数据质量规则将有助于发现问题。要解决这个问题,源系统需要检查这种不一致的根本原因。

8.功能失调的历史维护

历史维护对于任何数据仓库实现都是至关重要的。现在,数据是按时间顺序接收的,历史是使用 SCD(渐变维度)类型 2 维护的。然而,不正确的行被打开和关闭,导致最新有效记录的错误表示。进而打破历史维护方法和下游流程。要解决此问题,请确保使用正确的日期列来确定历史维护。

不了解历史维护方法,请查看这篇文章:

https://medium.com/geekculture/6-different-types-of-slowly-changing-dimensions-and-how-to-apply-them-b152ef908d4e

9.无关数据

没有什么比获取所有可用信息更令人沮丧的了。除了数据最小化的监管限制之外,获取所有可用数据的成本更高,也更不可持续。要解决这个问题,需要就数据捕获原则达成一致;每个数据属性都应该有一个最终目标;否则,它不应该被捕获。

10.不明确的数据定义

与财务部的 Sam 和客户服务部的 Jess 交谈,他们对相同的数据点有不同的解释;听起来很熟悉?清晰是 DQ 的一个方面,它没有被过多讨论,因为在现代数据堆栈中,它是业务术语表或数据目录的一部分。从根本上说,这是一个 DQ 问题。解决这个问题需要在每次创建新的指标/数据点时调整数据定义。

11.冗余数据

跨组织的多个团队,重复捕获相同的数据。在一个具有在线和高街存在的组织中,多次捕获相同的信息将导致数据在不同的系统中可用,从而导致数据冗余。这不仅对公司的底线不利,而且也是糟糕的客户体验。为了解决这个问题,应该使用一个单一的基础系统,其中所有组织的代理都接收他们的数据,这也是一个主数据实现。

12.旧数据

存储数据超过一定期限不会增加数据堆栈的价值。它花费更多的钱,使工程师困惑,并且影响你进行分析的能力。这也使得数据变得无关紧要(见 9)。要解决这个问题,应用 GDPR 原理,把它保存到“不必要的时间”。

13.不一致的密钥

想象一下,用主键和代理键为核心数据模型构建一个新的数据仓库。一旦数据仓库成熟并每天接收新数据,包括季节性高峰,您就会意识到自然键不是唯一的。这一发现破坏了模型的设计,导致了引用完整性的破坏。要解决这个问题,必须对数据进行全面的分析,包括季节性数据,以确保代理键所依赖的键总是唯一的。

14.数据可访问性差

需要高质量数据的人应该能够访问这些数据,以便做出明智的决策。将数据锁在数据仓库中,不与数据分析师、管家或科学家进行集成和访问是没有用的。要解决这个问题,您应该实现一个操作模型,包括团队如何访问数据的权限。

15.数据接收太晚

数据需要足够及时,以便在此期间做出关键决策。如果您的营销活动每周进行一次,您必须在一周的指定日期前收到所需的数据才能触发它们。否则,太晚的数据可能会导致您的活动反响不佳。您必须与工程团队商定一个合适的时间窗口来解决这个问题。并反向工作以确保您的源系统能够遵守那些 SLA(服务级别协议)。

结论

哇——这是一个很长的列表。不幸的是,这还不足以处理所有可能的 DQ 问题。让 DQ 走上正轨是许多组织的首要任务,在这方面投资将会有回报。如果你在日常生活中遇到了更多的 DQ 问题,请在下面留下评论,与我们分享。

如果您想了解在您的数据之旅中哪里可以找到 DQ,请查看这篇文章:

如果您没有订阅 Medium,请考虑使用我的推荐链接订阅。它比网飞便宜,而且客观上能更好地利用你的时间。如果你使用我的链接,我会获得一小笔佣金,而你可以在 Medium 上获得无限的故事。

我也定期在推特上写东西;跟着我这里

25 个令人头疼的数据迁移陷阱,您希望自己能早点知道

原文:https://towardsdatascience.com/top-25-painful-data-migration-pitfalls-you-wish-you-had-learned-sooner-a949c3e3b80a

我希望在开始数据迁移之旅之前了解的经验教训

照片由西格蒙德Unsplash 拍摄

“生活就像一盒巧克力;你永远不知道你会得到什么”——要是汤姆·汉克斯知道数据迁移(DM)的危险就好了。在周五下午晚些时候,收到一个可怕的“和解又失败了”的紧急 ping 会让你的心跳比早上的有氧运动还要快。

如果你参与过 DM,你会知道这是数据团队承担的最复杂的项目之一。DM 本身很简单,即我将数据从一个地方移动到另一个地方。但是执行有许多活动的部分,从技术映射到数据质量和协调数字到目标架构。让所有的元素都到位是一项艰巨的工作。

您不是在迁移数据,而是在为多年的技术债务买单

本文旨在通过真实世界的例子,帮助你列出一个你应该积极避免的陷阱清单,根据我过去十年的经验,帮助你在你的 DM 之旅中取得成功。

它分为五个小节:

  • 数据迁移规划
  • 源和目标架构
  • 数据质量
  • 测试、测试和更多测试
  • 不要让这些成为事后的想法

让我们开始吧!

数据迁移规划

1.计划失败,计划失败

一个成功的 DM 有一个复杂的计划做后盾;有许多移动的部分和许多源和目标依赖关系。拥有一个突出风险、假设、问题和依赖性的计划是你在执行 DM 的成功结果时可以瞄准的最好的开始。

例如:在将数据从商店 A 迁移到 B 的计划中,我将包括这些核心部分;利益相关者参与图、源和目标数据架构、数据分析、测试数据覆盖、数据映射文档、测试策略和执行计划、迁移迭代/完整加载活动。

2.没有经验的团队

低估面前的艰巨任务肯定会让你的 DM 之旅失败。不要通过让初级/无经验的团队领导核心工作流来节省成本。投资一个有经验的团队,这个团队以前经历过 DM,知道这些陷阱。

例如:在采访项目团队成员时,我会问一些与数据挖掘相关的具体问题,比如“数据挖掘成功的核心风险是什么?”或者“迭代 vs 满负荷 DM 的利弊是什么?”或者“你如何确定好的测试数据覆盖率?”

3.低估成本

如果任何项目需要一个应急基金,那就是这个。许多参与者必须得到补偿:源系统、基础设施、数据测试、架构师、工程师、项目经理、scrum masters 等。用一个复杂的计划来确保你已经考虑了所有这些任务的成本。

例如:当制定成本和预算计划时,我会避免使用基于直觉的成本估算。对于每个参与者,我会要求根据计划中的已知活动进行粗略的影响评估,添加适当的延误风险,然后提交预算以供批准。

4.寻找独角兽

你不会找到一个能够回答所有项目问题的主题专家(SME)。然而,你会有许多拥有各种技能的中小企业。如果你能确保正确的 SME 相互沟通,帮助定义详细的任务和具有巨大影响的风险,那将是最好的。

举个例子:面试时,专注于这个人的核心技能,我会避免让同一个人在团队中身兼数职,因为你会希望他们精通各自的工作流程。

5.缺乏自主权

计划将 DM 作为一个大项目来运营,所有的道路都通向一个决策者,这将会导致挫败感,并使你慢下来。组织一个合适的团队结构,把自主权交给有经验的人。

例如:在管理资源时,我会在需要时为他们的工作提供指导和支持;然而,我会避免一直盯着他们。通常,我会让他们坚持自己的决定,让他们建立自信。

源和目标架构

6.没有人知道源系统问题

在大型迁移中,源系统是陈旧过时的。他们缺乏文件;他们没有明确的血统;他们没有明确的过程;没有字典。少数人知道系统的复杂性,有时他们坐在官僚程序的后面。在你的计划中考虑这种细微差别(见 11。)

例如:我见过客户个人信息不正确的客户核心系统。在迁移之前的许多年里,这些都是不正确的,但是从来没有注意到,因为没有执行基本的概要分析。电子邮件和姓氏等不正确的元素导致了许多客户投诉;然而,由于缺乏文档和明确的补救流程,这些问题持续存在。

7.基础设施不容易获得

我已经记不清为数据传输和测试建立一个源和目标环境需要几个月的时间了。作为计划的一部分,拥有一个开放的环境应该是一个关键的依赖和风险。您可能需要不止一个环境来进行不同类型的测试。可悲的是,即使在更新的云环境中,这种痛苦依然存在。

例如:在计划迁移活动时,我会向相关团队提交一个请求,以尽快建立一个环境。IT 团队有时可以使用沙盒环境;但是,请确保这符合您需要的规格。

8.没有意识到技术债务的程度

技术债是最好的一种债;你不用偿还,也没有任何后果!当然是讽刺。

几十年来,技术债务一直在源系统中积累;作为规划的一部分,有必要花一些时间来了解这种影响在您进行的 DM 活动中的作用。记住(3。)你可能不得不拿出一些预算来解决这些债务项目。

例如:大多数组织都有一个技术性债务登记册;我通常以此开始,然后将已知的问题与计划中的活动联系起来,并建立一个依赖/滑动技术债务成本的图片。

9.过于雄心勃勃的数据之旅

将数据从源迁移到目标会非常困难;一路上不能改正自己的错误,就会变得不可能。确保数据旅程的设置经过各种暂存环境,使您能够在不影响最终目的地的情况下协调数据并解决问题。

例如:采购基础设施时(在 7)。我还将提供一个高级逻辑架构图,展示在使用新数据填充目标系统之前所需的多个登台环境。

10.决定迭代和交付大爆炸

决定您打算如何迁移数据,并相应地设置基础架构。如果环境是迭代地迁移数据,确保你真正地迭代,而不是收集你的发布来制造一个大爆炸。

举个例子:我见过无数次这种情况,早期的版本由于各种问题而延迟,后期的版本“迭代”超载。环境(7)不是为 big bang DM 设置的;我们就是这样做的,伪装成一个大的迭代。

数据质量

11.期待高质量的数据

数据质量会一直很差。我从来没有开始过一个具有高质量数据的迁移项目,我可以提升和转移这些数据。这样的事件类似于猪飞。相反,在迁移数据之前,与源系统 SME 一起投入时间和精力来理解和提高数据质量。

例如:我会从已知的关键数据表开始,并进行简单的分析,以查看大量的空值、格式、重复等。,以帮助衡量整体质量。

12.没有对足够大的数据样本进行分析

数据有趋势;更多的数据有更多的趋势。使用大量数据样本来了解隐藏在明处的数据质量问题。您总会遇到一些边缘案例,这些案例无法在剖析练习中全部捕获;因此,在选择数据样本时要有意识。

例如:我以前接触过中小企业,了解到企业何时对源系统进行了重大变更;我将那个特定时期的数据纳入了剖析工作,这导致更多的 DQ 问题浮出水面。

13.不知道您的关键数据属性

您的目标结构可能只有有限数量的属性值得迁移。如果你明白什么是最重要的,这会有所帮助。100%的数据质量不是一个东西,所以你必须在什么是关键的和值得修复的,什么不是之间找到一个平衡。

例如:我确保关键属性以两种方式定义;首先,目标系统 SME 从技术上确认哪些属性是关键的,其次,业务最终用户确定哪些属性满足最终业务目标。

14.期望数据只有一个定义

当执行数据映射时,我们需要知道源数据属性的定义,包括它的质量度量。组织通常在数据治理方面投资不足;因此,这一信息不容易获得。

例如:通常,我会对定义进行最好的猜测,并确保业务用户验证它。

15.没有数据补救流程

发现数据质量问题是一场战斗;补救是另一个问题。特别是如果您有一个陈旧的源系统,其中的更改需要很长时间,那么系统故障转移的风险就很高。拥有合适的团队会带来回报(参见 2。)和流程,以找到一种在源中补救数据质量问题的快速方法。

例如:在项目开始时,我会为整个数据挖掘过程中出现的问题制定一个端到端的补救流程。这个过程将有助于解决 DQ 和其他技术问题,如批处理失败和数据损坏。

测试,测试和更多的测试

16.没有在验证测试上花费足够的时间

还记得被问到计划有没有懈怠吗?然后,奇迹般地,测试工作减少了,以使项目上线并承担可接受的风险水平。我不知道是否有人定义过什么是可以接受的。测试应该是数据挖掘之旅的核心,而验证是这个核心的中心。

例如:我项目中的测试团队将执行两种类型的验证,数据的技术验证,确保它符合数据标准,以及功能验证,确保它符合最终业务需求。

17.没有明确的验收标准

你可以继续测试直到母牛回家,但这可能是浪费时间。定义验收标准可以确保最终目标不会不断变化。此外,拥有验收标准有助于创建边界,这有助于规划核心任务。

例如:我使用一套标准,并随着项目的进展对其进行调整。这些标准包括“数据质量的可接受百分比”、“用户能否以相同的方式在源和目标中访问报告/数据”,或者“数据能否在源中加载的同时在目标中加载。”

18.缺乏早期性能考虑

性能测试通常是项目的最后活动之一,立即成为下一组技术债务。在一个漫长而艰巨的项目之后,很少有兴趣重新审视项目早期做出的设计和编码决策。更改它们既费钱又费时,将最重要的“上线”日期置于风险之中。通过确保从一开始就考虑性能来避免这种情况。

例如:性能测试团队将从项目开始就参与到数据迁移的短期性能测试中。这提供了有意义的结果和性能开始恶化的阈值。

19.跳过测试阶段

每个测试阶段都有一个目的;跳过或缩短它们会增加 DM 输送失败的风险。系统集成和回归测试因为项目期限紧张而大打折扣。确保就强大的测试团队达成一致,并且所有相关团队都了解其影响。

举个例子:每个测试阶段都会被定义并且有一个明确的目标。我避免为了增加测试阶段而增加测试阶段,因为这会导致在交付时间紧迫时跳过这些阶段。

20.缺乏明确的协调框架

游戏的目标是在目标中拥有与源中相同的数据集。最好的方法是建立一个协调框架,在整个数据之旅中检查数据是否丢失。

例如:我不会只在源端和目标端进行对账;中间的每个检查点都将进行协调检查,以尽早发现问题并进行补救。

不要让这些成为事后的想法

21.不了解数据迁移的含义

处理数据和创建新的服务或架构需要咨询组织的核心团队。与安全团队合作对于避免未知的网络风险至关重要。与数据隐私团队合作对于正确处理个人身份数据至关重要。有必要与数据治理团队合作,以确保遵循正确的策略。

例如:在迁移开始时,我会召开动员会,邀请所有受影响的/已知的各方讨论整个计划。此外,我会与相关团队澄清,以最好的方式让他们支持这一 DM 活动。

22.缺乏环境容量规划

环境能经受住时间的考验吗?甚至在此之前,环境能经受住 DM 事件的考验吗?值得花时间与相关基础架构团队一起创建容量规划,以管理数据大小随时间的波动。当然,有了云技术,大部分工作都可以自动化。

例如:创建一个简单的容量规划,添加所有当前正在迁移的数据和属性及其数据大小。然后,我会根据业务/数据战略增加%的数据,并确保在这些计算中包括删除冗余数据的容量增强措施。最后,您会得到一个合理的容量案例,可用于规划。

23.不投资自动化

与其手动执行每个迁移事件,不如投资于自动化整个迁移序列;这包括自动化数据捕获、摄取、测试、传输和转换。

例如:即使迁移是一次性事件,我也会确保开发一个自动化代码来帮助运行多个迁移事件,包括彩排。这也使得将来的执行变得简单。

24.单人依赖

执行迁移需要很长时间;在整个阶段,关键的超级明星开始发光。由于缺乏知识共享文化,这些人变成了一个人的依赖者。

例如,创建一个知识共享门户,每个团队成员都可以在其中添加和标记信息。创建一个包含这些信息的新的加入者培训包,以便他们可以快速上手。

25.不断变化的变量

DM 旅途中有足够多的动人片段;尽量减少不断变化的变量。

例如:减少源系统中的新变化,尤其是当目标系统应该是你的最终目标时。创建灵活的目标模型以适应源测试和数据质量变化:对有限范围的数据属性进行 DQ 和验证测试。尝试一次限制太多的更改,以避免产生新的依赖关系,并使整体目标处于风险之中。

结论

哇——这是一个很长的列表。数据挖掘是任何人都可以从事的最具挑战性但也是最有回报的项目之一。本文应该涵盖了 80%的已知数据挖掘场景;当然,这里不会捕获边缘案例,所以请在下面的评论中分享它们。

如果你喜欢这类内容,可以看看我的其他帖子:

如果您没有订阅 Medium,请考虑使用我的推荐链接订阅。它比网飞便宜,而且客观上能更好地利用你的时间。如果你使用我的链接,我会获得一小笔佣金,而你可以在 Medium 上获得无限的故事。

我也定期在推特上写东西;跟着我这里

三大 Matplotlib 技巧——如何像专业人士一样设计图表

原文:https://towardsdatascience.com/top-3-matplotlib-tips-how-to-style-your-charts-like-a-pro-f79bd53f45d7

Matplotlib 可视化不必碍眼——这些提示会有所帮助

康尼·施耐德Unsplash 上拍摄的照片

如果我必须用一句话来总结 Matplotlib,那将是下面这句话——易于使用,难以查看。默认情况下,Matplotlib 图表看起来不是最好的,这不是什么秘密,所以许多数据专业人员选择了不同的数据可视化库。你可以实施一些简单的调整,这些将会使白天和黑夜有所不同。

首先,我们需要一个数据集来可视化。虹膜数据集会做得很好,因为我们在这里不需要任何复杂性。它是在知识共享 0 (CC0)下授权的,这意味着你可以免费使用它。以下代码片段将其作为熊猫数据帧加载到 Python 中:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv("https://gist.githubusercontent.com/netj/8836201/raw/6f9306ad21398ea43cba4f7d537619d0e07d5ae3/iris.csv")
df.head()

它看起来是这样的:

图片 1 —虹膜数据集(图片由作者提供)

X 轴上的萼片长度和 Y 轴上的萼片宽度的简单散点图将作为基线。下面是如何绘制它:

plt.figure(figsize=(9, 5))

plt.plot(df["sepal.length"], df["sepal.width"], "rs")
plt.xlabel("Sepal length")
plt.ylabel("Sepal width")
plt.title("Iris dataset - Sepal length vs. Sepal width")
plt.show()

正如你所想象的,它看起来不是最好的:

图 2-默认的 Matplotlib 可视化(作者图片)

这张图表四四方方,模糊不清,还有许多不足之处。让我们开始逐一解决这些缺点。

提示 1 —将 Matplotlib 图形显示为 SVG

之前 Matplotlib 图形模糊的原因很简单——它是作为图像(像素)而不是可缩放矢量图形(SVG)呈现的。SVG 允许您任意缩放图形,并且质量保持不变。

这听起来像是魔术,但它如何与 Matplotlib 一起工作呢?您可以在笔记本环境中更改 Matplotlib 格式,如下所示:

from IPython import display
display.set_matplotlib_formats("svg")

这就是你要做的全部。如果使用 Python 脚本生成 Matplotlib 图表,请使用以下语法将其保存为 SVG 格式:

plt.savefig("<figure-name>.svg")

现在,您可以像以前一样运行完全相同的图表生成代码:

plt.figure(figsize=(9, 5))

plt.plot(df["sepal.length"], df["sepal.width"], "rs")
plt.xlabel("Sepal length")
plt.ylabel("Sepal width")
plt.title("Iris dataset - Sepal length vs. Sepal width")
plt.show()

图像质量的差异是白天和黑夜:

图 SVG 格式的 Matplotlib 图形(图片由作者提供)

即使放大到图表段,质量也保持不变,如下所示:

图 4 —放大的 SVG 图(图片由作者提供)

一言以蔽之,始终使用 SVG。这是迄今为止最好的方法,它需要 1-2 行代码,这取决于您是在脚本环境中还是在笔记本环境中。

技巧 2 —调整默认绘图参数

每次要制作图表时,指定图形大小、标题大小、轴刻度大小和许多其他参数可能会非常繁琐。这就是为什么 Matpltolib 打包了一个名为rcParams的配置字典。更好的是,你可以随意改变它的关键值。

看看下面的代码片段——它修改了默认的图形大小,删除了顶部和右边框,并调整了整体字体大小:

plt.rcParams["figure.figsize"] = 12, 6
plt.rcParams["axes.spines.top"] = False
plt.rcParams["axes.spines.right"] = False
plt.rcParams["font.size"] = 14
plt.rcParams["figure.titlesize"] = "xx-large"
plt.rcParams["xtick.labelsize"] = "medium"
plt.rcParams["ytick.labelsize"] = "medium"

您现在可以呈现任何 Matplotlib 图表,修改后的样式将适用:

plt.plot(df["sepal.length"], df["sepal.width"], "rs")
plt.xlabel("Sepal length")
plt.ylabel("Sepal width")
plt.title("Iris dataset - Sepal length vs. Sepal width")
plt.show()

图 5 —调整了 rcParams 的 Matplotlib 图形(图片由作者提供)

您可以将这些修改后的参数保存在计算机上的单独文档中,然后将它们粘贴到任何将使用 Matplotlib 的笔记本中。没有必要每次都从头开始写。

技巧 3——改变字体

这个技巧可能是将您公司的外观和感觉添加到数据可视化中的最简单的方法。添加自定义字体的方法有很多种,但我要展示的这种方法每次都能奏效。没有必要安装字体,只需下载即可。

比如,你可以从谷歌字体下载 Poppins,解压 ZIP 文件。完成后,使用 Matplotlib 的font_manger从目录中添加字体。以下是 Poppins 提供的所有内容:

import matplotlib.font_manager as font_manager

font_dir = ["/Users/dradecic/Desktop/Poppins"]
for font in font_manager.findSystemFonts(font_dir):
    print(font)
    font_manager.fontManager.addfont(font)

图 6 —目录中的 TTF 字体(作者图片)

字体口味倒是挺多的,但是在 Matplotlib 里怎么用呢?这很简单,只需指定另一个rcParam:

plt.rcParams["font.family"] = "Poppins"

plt.plot(df["sepal.length"], df["sepal.width"], "rs")
plt.xlabel("Sepal length")
plt.ylabel("Sepal width")
plt.title("Iris dataset - Sepal length vs. Sepal width")
plt.show()

图 7 —带有自定义字体的 Matplotlib 图形(图片由作者提供)

不用说,这种方法适用于你能找到的任何 TTF 字体。

3 个 Matplotlib 样式技巧总结

默认情况下,Matplotlib 看起来不是最好的——我承认这一点——但是它是高度可定制的。在呈现静态可视化方面,您可以做的事情没有限制。唯一的问题是你愿意在文档和代码样本上钻研多深。如果你需要交互式图表, Plotly 可能是一个不错的解决方案。

你有什么使用 Matplotlib 的顶级技巧?你在每个项目中都使用一些参数吗?请在下面的评论区告诉我。

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

https://medium.com/@radecicdario/membership

保持联系

原载于 2022 年 8 月 29 日 https://betterdatascience.com**

Python 3.11 的三大新特性:做好准备

原文:https://towardsdatascience.com/top-3-new-features-in-python-3-11-prepare-yourself-701cca4af9c3

Python 3.11 还没有发布,但是你可以尝试一下 RC 版本。剧透警告:太神奇了

照片由 Unsplash 上对比纤维

Python 3.11 预计 2022 年 10 月播出。那是五个月以后的事了,为什么要大肆宣传呢?像往常一样,我们可以测试 RC 版本,看看它与 Python 3.10 相比如何。

这正是我所做的。我设置了两个 Docker 容器,一个用于 Python 3.10 ,另一个用于 Python 3.11 ,并将它们附加到单独的 Visual Studio 代码窗口。我们将在两个版本中运行完全相同的代码,看看新版本带来了什么。

TL;有很多新功能,但我决定写三个。这些是更好的错误位置、异常注释和内置的 TOML 解析器。相对于旧的 Python 版本,这是一个很大的改进。参考官方变更日志获得新特性的完整列表。

您知道 Python 3.11 将比 Python 3.10 快 60%吗? 下面是详细的基准

不想看书?请观看我的视频:

Python 3.11 功能 1-增强的错误位置

当打印回溯时,Python 解释器现在将指向导致错误的确切表达式,而不仅仅是该行。例如,下面的代码片段会抛出一个错误,因为给定索引处的列表项不存在:

if __name__ == "__main__":
    l = [1, 2, 3]
    print(l[3])

在 Python 3.10 中,您将获得以下输出:

图片 1-增强的错误位置(1)(图片由作者提供)

另一方面,Python 3.11 将打印以下内容:

图 2-增强的错误位置(2)(图片由作者提供)

Python 3.11 在导致错误的代码部分加了下划线,非常简洁。比方说,Python 字典也是如此。下面的代码片段将引发一个错误,因为字典没有那个键:

if __name__ == "__main__":
    d = {"key1": "value1", "key2": "value2"}
    print(d["key3"])

以下是 Python 3.10 吐出的内容:

图 3-增强的错误位置(3)(图片由作者提供)

这是 Python 3.11 的输出:

图 4 —增强的错误位置(4)(图片由作者提供)

Python 3.11 再次强调了导致错误的确切代码部分。

Python 3.11 功能# 2-异常注释

Python 的Exception类在 Python 3.11 中会有一个__note__属性。默认情况下它是None,但是你可以用任何你想要的字符串覆盖它。当然,这不是最具突破性的特性,但是如果您有几十个自定义异常类,这里或那里的一个注释会派上用场。

下面是我们将在两个容器中运行的代码:

class CustomException(Exception):
    __note__ = "Note about my custom exception" if __name__ == "__main__":
    raise CustomException()

这是 Python 3.10 的输出:

图 5 —引发自定义异常(1)(作者图片)

正如您所料,Python 3.10 的Exception类不知道这个新属性。Python 3.11 的情况完全不同:

图 6 —引发自定义异常(2)(作者图片)

Python 3.11 再次强调了导致错误的那一行——在本例中是一个明显的错误——但是它也在最后打印了我们的注释。

Python 3.11 特性#3 —内置的 TOML 解析器

TOML ,或者说 Tom 显而易见的极简语言,是一种极简配置文件格式。在 Python 3.11 之前,没有内置的库来处理 TOML 配置文件。现在情况变了。

下面是我们将在两个容器中运行的代码片段:

import tomllib DOC = """
[main]
python_version = 3.11[api]
endpoint_users = "/api/v2/users"
endpoint_posts = "/api/v2/posts"
"""if __name__ == "__main__":
    doc_parsed = tomllib.loads(DOC)
    print(doc_parsed)

Python 3.10 没有tomllib库,所以立即引发了异常:

图 7 — TOML 配置文件(1)(图片由作者提供)

Python 3.11 支持它,因为解析 TOML 字符串没有问题:

图 8 — TOML 配置文件(2)(图片由作者提供)

当然,安装一个解析 TOML 文件的专用库需要几秒钟,但是很高兴看到它将成为新版本的内置功能。

Python 3.11 新特性概述

我们已经介绍了 Python 3.11 中的三个特性。当然,还有其他的,比如自我类型、异常组、异步理解等等,但是如果你感兴趣的话,你可以参考官方变更日志。

新 Python 版本带来的最大改进可能是速度的提高。平均而言,Python 3.11 将比 Python 3.10 快 15%,差距高达 64%。我在我的详细的基准测试文章中比较了这两者,所以请务必查看一下。

你最喜欢的 Python 3.11 特性是什么?请在下面的评论区告诉我。

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

https://medium.com/@radecicdario/membership

推荐阅读

保持联系

原载于 2022 年 5 月 9 日 https://betterdatascience.com**的

三大非机器学习技能将在 Kaggle 竞赛中崛起

原文:https://towardsdatascience.com/top-3-non-machine-learning-skills-to-rise-in-kaggle-competitions-d438fec7d551

数据、创造力和策略会让你爬上排行榜

Unsplash 上的 Element5 数码拍摄

这听起来可能有违直觉。但在像 Kaggle 这样的机器学习竞赛中,让你比其他人更有优势的关键技能可能不是机器学习。

你对机器学习算法的了解只是你在 Kaggle 中需要的基本技能。应用不同的算法、集成和超参数优化当然是必要的,但这只是自动化。任何人都可以从 Stack-overflow 或 Python Scikit-learn 复制/粘贴算法函数代码。它会帮助你获得一个不错的分数,但很少会让你进入前 10 名或前 20%。

我将用 Kaggle Space Titanic 问题来说明这篇文章,我在这个竞赛中取得了前 20%的成绩。(参考资料和数据集引用可在故事结尾获得)

进入排行榜的前 20%(图片由作者提供)

我使用的机器学习算法是 XGBoost。然而,帮助我达到前 20%的并不是算法。帮助我的是

  • 关注数据
  • 创造性特征工程
  • 选择正确的机器学习策略

获胜需要的不仅仅是机器学习算法技能(图片由作者提供)

1.关注数据、数据、数据

机器学习过程中 80%的时间花在数据准备上。和 Kaggle 空间泰坦尼克号的问题没有什么不同。准备数据的主要活动之一是消除偏差和处理缺失值

消除偏斜——这一步通常会被忽略,但却非常必要

歪斜可能是一个杀手。你可以把它看作是一个沉默的离群值,我们往往会忘记它。在太空泰坦尼克号问题中,有许多倾斜的数值。让我们来看看其中的一项,那就是客房服务。

高向左倾斜(图片由作者提供)

正如你将观察到的,分布是高度左倾的。原因是大多数乘客没有为客房服务付费。但是,有一些高客房服务值,在直方图中几乎看不到。如果不处理偏斜,机器学习算法就会偏向小值。

消除偏斜的一种方法是应用幂变换函数。移除倾斜后的结果如下所示。

非倾斜数据(图片由作者提供)

应用电源变压器后,高值变得更加突出。机器学习算法将能够获得这些高值。在太空泰坦尼克号问题中,非偏斜有助于提高准确性,因为服务是决定乘客命运的重要特征。

处理缺失的价值——最关键的一步需要像专家一样完成

数据中有许多缺失值。虽然有许多方法可以替换丢失的数据,但 KNN (K 近邻)方法在太空泰坦尼克号问题中非常有效。

关于如何进行 KNN 缺失值替换的完整指南,你可以在这里看到我的文章。

2.创造性特征工程是领导者和其他人之间的区别

创造力是领导者区别于其他人的地方。功能工程是跳出框框思考的地方,并获得那些在 Kaggle 排行榜上上升的关键点。虽然创造力不能被记录,让我尝试给它一个基于太空大问题的结构。

在数据中查找复合字段

复合字段是开始您的创造性特征工程的好方法。复合字段将多个信息打包到一个字段中。当字段中有“_”、“-”或“/”或“:”时,您就有可能识别它们。典型的例子是日期字段。当你看到类似于 31/12/2022 的东西时,它有三个东西组合成一个——日期、月份和年份。

在空间大问题中,有两个场是复合场。第一个是 Passengerid,它包含 0001_01、0003_01 等数据。“_”表示复合字段。所以我们可以从这个领域创造两个特征。

分解乘客 id 字段(图片由作者提供)

类似地,您可以分解具有 G/3/S 和 C/1/S 等值的 cabin 字段。正如您所猜测的,您可以将它们分成三个特性。

寻找多个数字字段,看它们是否可以相加

数值字段是创造性特征工程的最佳伙伴。将它们以不同的方式结合起来很容易,并且可以帮助你赢得一些额外的准确性分数。创建最简单但非常有效的要素之一是基于数值字段的总体要素。通常,如果没有明确指定为特征,机器学习算法将不能导出“全部”信息。

在太空泰坦尼克号数据集中,您有多个数字字段,如客房服务费用、水疗费用、购物中心费用(想象一下在太空购物!),等等。这是一个很好的机会来创建反映乘客总费用的总字段。

创建总体特征(按作者分类的图像)

在太空泰坦尼克号问题上,整个领域远远超过了所有的竞争对手!

用好奇的眼光寻找垂直的图案!

我们看数据的时候,一般倾向于横向分析。然而,当你垂直分析数据时,你可能会发现隐藏的金块。在太空泰坦尼克号问题中,隐藏的金块之一是乘客是独自旅行还是集体旅行的信息。

通过垂直分析数据创建新要素(图片由作者提供)

在垂直分析数据时,您会发现有些乘客具有相同的乘客 id(在 _)和相似的姓氏。这意味着他们是一家人,作为一个团体旅行。因此,我们可以创造性地创建一个新功能来指示乘客是否独自旅行。

无论你使用什么复杂的算法,都无法自动推断出这样的特征。这就是人脑的创造力发挥作用的地方。这将帮助你在 Kaggle 排行榜上遥遥领先。

3.战术——赢得竞争的最后一英里

战术是一系列行动,旨在实现某一目标。战术这个词起源于军事战争。人类已知的经典战术之一叫做斜序,曾用于希腊战例。

解决一个机器学习问题,其实就是一系列的算法。就像战争战术,如果你答对了,你就赢了。如果你做错了,即使你使用了正确的算法,你也输了!

在太空泰坦尼克号问题中,你有多种算法:KNN 缺失值替换、幂变换、创建附加特征、归一化、一键编码和 XGBoost。有没有特定的顺序有助于取得更好的成绩?答案是肯定的!这就是了。

制胜策略(图片由作者提供)

如果使用不同的序列,例如,如果反转幂变换和新特征创建,则精度会降低。

结论

要想在 Kaggle 排行榜上名列前茅,你需要的不仅仅是机器学习算法的知识。以下是最重要的三件事

  • 专注于理解和准备您的数据
  • 创造性特征工程将使你遥遥领先
  • 像战争战术家一样思考!行动的顺序非常重要

额外资源

我学习数据科学的无代码平台

您可以访问我的平台,以一种非常简单的方式学习数据科学,并在不编码的情况下应用本文中描述的一些技术。https://experiencedatascience.com

我的 Youtube 频道上的数据科学演示

这是我的 YouTube 频道的链接,我在那里展示了关于数据科学、机器学习和人工智能的各种演示。https://www.youtube.com/c/DataScienceDemonstrated
T3

订阅,以便在我发布新故事时随时获得通知。

https://pranay-dave9.medium.com/subscribe

您也可以通过我的推荐链接加入 Medium

https://pranay-dave9.medium.com/membership

太空泰坦尼克号参考和数据源引用

太空泰坦尼克号问题和数据在这里:https://www . ka ggle . com/competitions/space ship-titanic/overview

正如规则(【https://www.kaggle.com/competitions/spaceship-titanic/rules】)中所规定的,在第 7 A 节中,数据可以用于任何目的。

A.数据访问和使用。您可以出于任何商业或非商业目的访问和使用竞赛数据,包括参加竞赛和 Kaggle.com 论坛,以及学术研究和教育。

用于机器学习验证的前 3 个 Python 包

原文:https://towardsdatascience.com/top-3-python-packages-for-machine-learning-validation-2df17ee2e13d

用这些包验证你的机器学习模型

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

作为数据科学家,我们被期望开发机器学习模型来分析数据和解决业务问题。无论我们是开发一个简单的模型还是一个复杂的模型,模型验证对于衡量我们工作的质量都是必不可少的。

我们需要测量每一个移动的部分,以确保通过验证数据、方法和机器学习模型指标,模型是适当的。有很多技术可以做机器学习验证。尽管如此,在这篇文章中,我想介绍 python 包,它将使我们在验证机器学习模型时的生活变得更容易。

以下是我最喜欢的 3 个用于机器学习验证的 python 包。让我们开始吧。

1.明显地

显然是一个分析和监控机器学习模型的开源 python 包。该软件包是明确开发的,以建立一个易于监控的机器学习仪表板,并检测数据中的漂移。它是专门为生产而设计的,所以在有数据管道的情况下使用更好。然而,你仍然可以在开发阶段使用它。

让我们尝试使用显然来验证我们的机器学习模型开发。在现实环境中,我们会有参考数据集和生产数据集,但对于我们现在的情况,让我们使用来自 Kaggle 的分割训练和测试数据。

作为一个初学者,我们需要安装明显的软件包。

pip install evidently

安装软件包后,我们可以尝试检测数据集中发生的数据漂移。数据漂移一种现象,即参考数据或以前时间表中的数据在统计上不同于当前数据。

import pandas as pdtrain = pd.read_csv('churn-bigml-80.csv')
test = pd.read_csv('churn-bigml-20.csv')

数据集需要预处理,我现在只想使用数字数据。

train.drop(['State', 'International plan', 'Voice mail plan'], axis =1,inplace = True)
test.drop(['State', 'International plan', 'Voice mail plan'], axis =1, inplace = True)train['Churn'] = train['Churn'].apply(lambda x: 1 if x == True else 0)
test['Churn'] = test['Churn'].apply(lambda x: 1 if x == True else 0)

数据准备就绪后,我们将构建仪表板来检测任何偏差。显然需要我们独立地导入每个选项卡;对于数据漂移,我们将使用DataDriftTab

from evidently.dashboard import Dashboard
from evidently.tabs import  DataDriftTabdata_drift_report = Dashboard(tabs=[DataDriftTab()])
data_drift_report.calculate(train, test, column_mapping = None)
data_drift_report.save("reports/my_report.html")

我们将数据保存在 HTML 报告中,并在不同的选项卡中打开它。

数据漂移选项卡(作者 GIF)

正如你在上面的 GIF 中看到的,我们有一个监控仪表板。我们可以在这个仪表板中看到每个特性分布和数据漂移的统计测试。在我们的样本中,训练数据和测试数据之间没有显示任何漂移——这意味着所有的数据分布都是相似的。如果是在生产中,传入的数据和我们当前的数据在模式上没有差异。

显然也可以用来创建一个机器学习分类仪表板,以监控机器学习的健康状况。例如,让我们使用以前的数据训练一个分类模型。

from sklearn.neighbors importX_train = train.drop('Churn', axis =1)
X_test = test.drop('Churn', axis =1)
y_train = train['Churn']
y_test = test['Churn']model = KNeighborsClassifier(n_neighbors=5)
model.fit(X_train, y_train)

拟合模型后,我们需要实际和预测的结果。我们还需要完整的训练和测试数据集。

train_predictions = model.predict(X_train)
test_predictions = model.predict(X_test)X_train['target'] = y_train
X_train['prediction'] = train_predictionsX_test['target'] = y_test
X_test['prediction'] = test_predictions

监视器还需要我们映射我们使用的列;在这种情况下,我们显然会使用来自。

from evidently.pipeline.column_mapping import ColumnMappingchurn_column_mapping = ColumnMapping()churn_column_mapping.target = 'target'
churn_column_mapping.prediction = 'prediction'
churn_column_mapping.numerical_features =train.drop('Churn', axis =1).columns

所有准备工作完成后,让我们设置分类器监视器仪表板。

from evidently.tabs.base_tab import Verbose
from evidently.tabs import ClassificationPerformanceTabchurn_model_performance_dashboard = Dashboard(tabs=[ClassificationPerformanceTab(verbose_level=Verbose.FULL)])
churn_model_performance_dashboard.calculate(X_train, X_test, column_mapping = churn_column_mapping)
churn_model_performance_dashboard.save("reports/classification_churn.html")

分类器仪表板(作者 GIF)

如上面的 GIF 所示,我们可以从整体上监控我们的机器学习模型指标,并对每个特征进行预测。细节足够好,可以知道新数据传入时是否有差异。

如果你想清楚地知道所有可以使用的仪表板,请参考文档

2.深度检查

Deepchecks 是一个 python 包,用几行代码验证了我们的机器学习模型。许多 API 可用于检测数据漂移、标签漂移、训练测试比较、评估模型等等。深度检查非常适合在研究阶段和模型投入生产之前使用。你应该在下面的第中了解更多关于何时使用深度检查的信息。

让我们尝试使用 Deepchecks 包来生成完整的数据集和模型性能报告。我们将使用full_suite类来生成报告。

首先,让我们安装 Deepchecks 包。

pip install deepchecks

安装完成后,我们需要准备训练数据集和机器学习模型。对于我们的例子,我将使用来自深度检查的简单虹膜数据集。

import pandas as pd
from deepchecks.datasets.classification import iris
from sklearn.ensemble import RandomForestClassifier# Load Data
iris_df = iris.load_data(data_format='Dataframe', as_train_test=False)

加载完数据后,我们需要拆分训练测试数据,加载机器学习模型。你可以用你的模型来拟合数据,但我会用现成的模型。

df_train, df_test = iris.load_data(data_format='Dataframe', as_train_test=True)
label_col = "target"rf_clf = iris.load_fitted_model()

如果将 Pandas 数据框转换为 Deepchecks 数据集对象,Deepchecks 会工作得更好,因此我们会这样做。

from deepchecks import Datasetds_train = Dataset(df_train, label=label_col, cat_features=[])
ds_test =  Dataset(df_test,  label=label_col, cat_features=[])

一切准备就绪;我们只需要从我们的 Jupyter 笔记本上运行完整的套件报告。

from deepchecks.suites import full_suitesuite = full_suite()
suite.run(train_dataset=ds_train, test_dataset=ds_test, model=rf_clf)

运行 Deepchecks 完整套件(图片由作者提供)

全套报告(作者 GIF)

完整套件报告将包含许多信息,如混淆矩阵报告、简单模型比较、混合数据类型、数据漂移等。检查机器学习模型所需的所有信息都可以在一次代码运行中获得。

3.张量流-数据-验证

TensorFlow 数据验证或 TFDV 是由 TensorFlow 开发者开发的一个 python 包,用于管理数据质量问题。它用于自动描述数据统计,推断数据模式,并检测传入数据中的任何异常。

让我们尝试安装软件包。

pip install tensorflow-data-validation

首先,我们需要导入包并从 CSV 数据中生成统计对象。我会使用我们之前使用的培训流失数据集作为参考数据集。

import tensorflow_data_validation as tfdv
stats = tfdv.generate_statistics_from_csv(data_location='churn-bigml-80.csv')

我们可以将统计对象的统计信息可视化。

tfdv.visualize_statistics(stats)

TFDV 统计推断(作者提供的 GIF)

TFDV 包不仅可以生成统计可视化,还可以帮助检测输入数据的任何变化。为此,我们需要推断原始或参考数据模式。

schema = tfdv.infer_schema(stats)
tfdv.display_schema(schema)

作者图片

该模式将用于验证任何传入的数据;如果传入的数据在模式中没有推断出任何列或类别,那么 TFDV 将通知异常的存在。我们将使用下面的代码和测试数据来完成这项工作。

new_csv_stats = tfdv.generate_statistics_from_csv(data_location='churn-bigml-20.csv')

anomalies = tfdv.validate_statistics(statistics=new_csv_stats, schema=schema)tfdv.display_anomalies(anomalies)

作者图片

没有发现异常,因为所有的数据都是相似的。

结论

机器学习模型项目不是一蹴而就的事情;这是一个持续的项目。如果存在任何异常,生产中的模型将需要不断地被监视和控制。为了帮助我们验证机器学习模型,我们可以使用以下 python 包:

  1. 明显地
  2. 深度检查
  3. 张量流验证数据

希望有帮助!

在我的 LinkedInTwitter 上访问我。

如果您喜欢我的内容,并希望获得更多关于数据或数据科学家日常生活的深入知识,请考虑在此订阅我的 简讯。

如果您没有订阅为中等会员,请考虑通过 我的推荐 订阅。

用于异常值检测的前 3 个 Python 包

原文:https://towardsdatascience.com/top-3-python-packages-for-outlier-detection-2dc004be9014

这些软件包会让你在分析中占有优势

Bermix 工作室Unsplash 拍摄的照片

我们数据分析的主要活动之一是识别数据中的异常值。异常值可以定义为不符合模式的极端数据或数据点。离群值有很多种,离群值的分类取决于数据或上下文。如果你想阅读更多关于异常分类或异常分析的内容,你可以在我的另一篇文章中阅读。

有许多检测异常值的技术。然而,该技术的有效性取决于数据和异常值分类。有时我们甚至不知道如何选择合适的方法或解释异常值。这就是为什么许多 python 包是专门为离群点检测开发的。

在本文中,我想展示我最喜欢的三个用于检测异常值的 python 包。我假设读者对异常值及其对数据的影响有所了解,所以我不会进一步解释。让我们开始吧。

1.热电偶

PyOD 或 python 离群数据检测是一个用于检测离群数据的 Python 包工具包。PyOD 包拥有 30 个离群点检测算法,从经典到最新-证明 PyOD 包维护良好。异常值检测模型的示例包括:

  • 基于角度的异常检测
  • 基于聚类的局部异常因子
  • 主成分分析异常检测
  • 可变自动编码器

还有很多。如果你有兴趣看到所有可用的方法,你应该访问下面的页面

PyOD 通过使用更少的代码行来预测异常数据,使异常检测变得简单而直观。与模型训练一样,PyOD 使用分类器模型来训练数据,并根据模型预测异常值。让我们用代码示例来试试这个包。首先,我们需要安装软件包。

pip install pyod

安装完这个包之后,让我们试着加载一个样本数据集。我会使用 seaborn 包中的 tips 数据。

import seaborn as sns
import pandas as pddf = sns.load_dataset('tips')
df.head()

作者图片

假设我们想找出 total_bill 和 tip 之间的多元异常值。如果我们可视化这两个特征之间的散点图,我们可能会感觉到数据扩散。

sns.scatterplot(data = df, x = 'total_bill', y = 'tip')

作者图片

如果我们看到上面的图,我们会注意到一些数据位于右上角,表明有异常值。但是,如果我们要将数据分为内层和外层,有什么限制呢?在这种情况下,我们可以使用 PyOD 来帮助我们完成这项工作。

对于我们的例子,我只使用两种方法——基于角度的离群点检测(ABOD)和基于聚类的局部离群点因子(CBLOF)。

from pyod.models.abod import ABOD
from pyod.models.cblof import CBLOF

让我们从 ABOD 模型开始;我们需要设置污染参数或从数据中检测到的异常值的分数。如果我将污染设置为 0.05,我希望从我们的数据中检测出 5%的异常值。让我们用我们的代码试一试。

abod_clf = ABOD(contamination=outliers_fraction)
abod_clf.fit(df[['total_bill', 'tip']]))

我们拟合想要检测异常值的数据。类似于模型分类器,我们可以访问分数/标签并使用该分类器进行预测。

#Return the classified inlier/outlier
abod_clf.labels_

作者图片

您也可以访问决策得分或概率,但让我们继续使用另一个模型并比较结果。

cblof_clf = CBLOF(contamination=0.05,check_estimator=False, random_state=random_state)
cblof_clf.fit(df[['total_bill', 'tip']])df['ABOD_Clf'] = abod_clf.labels_
df['CBLOF_Clf'] = cblof_clf.labels_

我们将结果存储在数据帧中,以比较两种检测算法。

sns.scatterplot(data = df, x = 'total_bill', y = 'tip', hue = 'ABOD_Clf')

ABOD 离群值(图片由作者提供)

从 ABOD 异常值检测结果中,我们可以看到来自中心的数据的极端部分被认为是异常值。从 CBLOF 模型来看。

sns.scatterplot(data = df, x = 'total_bill', y = 'tip', hue = 'CBLOF_Clf')

CBLOF 离群值(图片由作者提供)

与 ABOD 不同,CBLOF 算法将外部分类为在一侧(右侧)。如果愿意,您可以尝试另一种算法来检测数据中的异常值。

2.不在场证明-检测

alibi-detect python 包是一个开源包,专注于异常、敌对和漂移检测。该软件包可用于表格和非结构化数据,如图像或文本。如果你对图像数据的异常检测感兴趣,你可以在这里访问示例。然而,在本文中,我将重点关注表格数据。

alibi-detect 软件包提供了 10 种异常检测方法,你可以在这里阅读所有的。让我们用一个数据集示例来尝试其中一种方法。我将使用与前一个包相同的数据。

对于这个例子,我将使用隔离林方法。

from alibi_detect.od import IForestod = IForest(
    threshold=0.,
    n_estimators=100
)

我们设定门槛;如果你想自动设置阈值,有一个阈值推断的方法。接下来,我们将模型训练到数据集。

od.fit(df[['total_bill', 'tip']])

在模型拟合之后,我们需要做一个预测。

preds = od.predict(
    df[['total_bill', 'tip']],
    return_instance_score=True
)

如果我们将它设置为 True,那么结果将是一个包含实例得分和异常值标签的字典。

preds['data'].keys()

作者图片

然后,我们将异常值检测输入到数据框中,并使用散点图来可视化这些发现。

df['IF_alibi'] = preds['data']['is_outlier']
sns.scatterplot(data = df, x = 'total_bill', y = 'tip', hue = 'IF_alibi')

从 alibi-detect 隔离森林(图片由作者提供)

图像显示了更保守的结果,因为稍微偏离中心将被视为异常值。

你可以从 alibi-detect 中尝试很多算法。此处显示了算法概述

3.侏儒

PyNomaly 是一个 python 包,基于循环检测异常值(局部异常值概率)。该循环基于本地异常值因子(LOF),但分数被标准化为范围[0–1]。如果你不确定 LOF 是什么,你可以在我的另一篇文章中读到它。

PyNomaly 的应用简单直观,类似于之前的包。让我们使用数据集示例来试验异常值检测。

from PyNomaly import loop
m = loop.LocalOutlierProbability(df[['total_bill', 'tip']], use_numba=True, progress_bar=True).fit()
scores = m.local_outlier_probabilities

如果有许多数据集要预测,我们可以在这里使用 Numba 否则,你可以关掉它。训练产生了我们可以自己推断的概率。

作者图片

每个数据都包含作为异常值的概率。我们可以尝试通过判断来推断哪个数据集是异常值,例如,概率高于 0.5 的数据点

df['loop_score'] = scores
df['loop_label'] = df['loop_score'].apply(lambda x: 1 if x >0.5 else 0)
sns.scatterplot(data = df, x = 'total_bill', y = 'tip', hue = 'loop_label')

循环法(图片由作者提供)

从上图中我们可以看到,如果概率高于 0.5,异常值位于数据的最极值点。

结论

离群点检测是数据科学家的主要活动。离群值可能在许多方面影响我们的分析和建模;这就是为什么我们希望在数据探索中发现异常值。

为了帮助离群点检测活动,我列出了我的前 3 个离群点检测 python 包;它们是:

  1. 热电偶
  2. 不在场证明-检测
  3. 侏儒

希望有帮助!

在我的 LinkedInTwitter 上访问我。

如果您喜欢我的内容,并希望获得更多关于数据或数据科学家日常生活的深入知识,请考虑在此订阅我的 简讯。

如果您没有订阅为中等会员,请考虑通过 我的推荐 订阅。

生成合成数据的前 3 个 Python 包

原文:https://towardsdatascience.com/top-3-python-packages-to-generate-synthetic-data-33a351a5de0c

为您的数据科学项目提供合成数据

照片由马克西姆·伯格Unsplash 拍摄

数据是每个数据项目的支柱;数据分析,机器学习模型训练,或者简单的仪表盘都需要数据。因此,获取满足您的项目的数据非常重要。

但是,您想要的数据不一定已经存在或公开。此外,有时您希望用符合您的标准的“数据”来测试您的数据项目。这就是为什么当您有特定需求时,生成数据变得很重要。

生成数据可能很重要,但是手动收集满足我们需求的数据需要时间。出于这个原因,我们可以尝试用编程语言来综合我们的数据。本文将概述我用来生成合成数据的 top 3 python 包。所有生成的数据都可以用于您想要的任何数据项目。让我们开始吧。

1.骗子

Faker 是为简化生成合成数据而开发的 Python 包。很多后续的数据合成生成器 python 包都是基于 Faker 包。人们喜欢这个包的简单和直观,所以让我们自己试试吧。首先,让我们安装这个包。

pip install Faker

为了使用 Faker 包生成合成数据,我们需要初始化Faker类。

from faker import Faker
fake = Faker()

随着课程的开始,我们可以生成各种合成数据。例如,我们将创建一个合成数据名称。

fake.name()

作者图片

当我们使用 Faker 类中的.name属性时,结果是一个人的名字。每次我们运行属性时,Faker 合成数据会随机产生。我们再来一次这个名字。

作者图片

结果是一个不同于我们之前迭代的名字。随机化过程在生成合成数据时很重要,因为我们希望数据集有所变化。

使用 Faker 包,我们可以生成更多的变量。它不仅限于名称变量,其他例子还有地址、银行、工作、信用评分等等。在 Faker 包中,这个生成器被称为提供者。如果您想查看整个标准提供者社区提供者本地化提供者,您可以在他们的文档中查看。

2.SDV

SDV 或合成数据库是一个 Python 包,根据提供的数据集生成合成数据。根据您在环境中提供的方案,生成的数据可以是单表、多表或时间序列。此外,生成的将具有与提供的数据集相同的格式属性和统计信息。

SDV 通过应用数学技术和机器学习模型(如深度学习模型)来生成合成数据。即使数据包含多种数据类型和缺失数据,SDV 也会处理它,所以我们只需要提供数据(以及需要时的元数据)。

让我们试着用 SDV 生成我们的合成数据。首先,我们需要安装软件包。

pip install sdv

对于我们的示例,我将使用 Kaggle 的马生存数据,因为它们包含各种数据类型和缺失数据。

import pandas as pd
data = pd.read_csv('horse.csv')
data.head()

作者图片

我们的数据集已经准备好了,我们希望基于数据集生成合成数据。让我们使用一个可用的单桌 SDV 模型GaussianCopula

from sdv.tabular import GaussianCopula
model = GaussianCopula()
model.fit(data)

训练过程很容易;我们只需要初始化类并拟合数据。让我们使用模型来产生合成数据。

sample = model.sample(200)
sample.head()

作者图片

利用来自模型的.sample属性,我们获得随机化的合成数据。您想要多少数据取决于您传递给.sample属性的数字。

您可能会意识到数据有时包含一个唯一的标识符。例如,我可以将上述数据集中的标识符指定为“hospital_number”上面的数据有多个“hospital _ nunber”的实例,如果它是唯一的数据,我们就不想要它。在这种情况下,我们可以将primary_key参数传递给模型。

model = GaussianCopula(primary_key='hospital_number')
model.fit(data)

样本结果将是从模型中生成的每个样本的唯一主键。

我们可能会问的另一个问题是,生成的合成数据有多好?在这种情况下,我们可以使用 SDV 的evaluate函数。该评估将真实数据集与样本数据集进行比较。有许多测试可用,但我们只关注 Kolmogorov-Smirnov(KS)和卡方(CS)测试。

from sdv.evaluation import evaluate
evaluate(sample, data, metrics=['CSTest', 'KSTest'], aggregate=False)

作者图片

KSTest 用于比较连续列,CSTest 用于比较离散列。两种测试的结果都是 0 到 1 之间的标准化分数,目标是使分数最大化。从上面的结果,我们可以评估离散样本列是好的(几乎与真实数据相似)。相比之下,连续列的分布可能会有偏差。如果您想了解 SDV 所有可用的评估方法,请参考文档页面

3.葛丽特

Gretel 或 Gretel Synthetics 是一个基于递归神经网络(RNN)的开源 Python 包,用于生成结构化和非结构化数据。python 包方法将数据集视为文本数据,并基于此文本数据训练模型。然后,该模型将产生带有文本数据的合成数据(我们需要将数据转换成我们想要的结果)。

Gretel 需要一点强大的计算能力,因为它是基于 RNN 的,所以如果你的电脑不够强大,我建议使用免费的谷歌 colab 笔记本或 Kaggle 笔记本。出于可访问性的目的,本文还将参考由 Gretel 提供的教程。

我们需要做的第一件事是使用下面的代码安装包。

pip install gretel-synthetics

然后,我们将使用以下代码生成一个配置代码,作为训练 RNN 模型的参数。以下参数基于 GPU 上的训练,使用的数据集是可从 Gretel 获得的踏板车旅程坐标数据集

from pathlib import Pathfrom gretel_synthetics.config import LocalConfig# Create a config for both training and generating dataconfig = LocalConfig(# the max line length for input training
max_line_len=2048, # tokenizer model vocabulary
datavocab_size=20000, # specify if the training text is structured, else ``None``
sizefield_delimiter=",", # overwrite previously trained model checkpoints
overwrite=True,# Checkpoint location
checkpoint_dir=(Path.cwd() / 'checkpoints').as_posix(),#The dataset used for RNN training
input_data_path="https://gretel-public-website.s3-us-west-2.amazonaws.com/datasets/uber_scooter_rides_1day.csv" # filepath or S3)

当配置就绪时,我们将使用下面的代码来训练我们的 RNN 模型。

from gretel_synthetics.train import train_rnntrain_rnn(config)

根据您的处理能力、配置和数据集,该过程可能需要一些时间。完成后,配置将自动保存您的最佳模型,并准备生成合成数据。让我们尝试使用generate_text来生成数据。

from gretel_synthetics.generate import generate_text#Simple validation function of the data is containing 6 data parts or not. You could always free to tweak it.
def validate_record(line): rec = line.split(", ")
   if len(rec) == 6:
      float(rec[5])
      float(rec[4])
      float(rec[3])
      float(rec[2])
      int(rec[0])
   else:
      raise Exception('record not 6 parts')#Generate 1000 synthetic data
data = generate_text(config, line_validator=validate_record, num_lines=1000)print(data)

作者图片

默认情况下,生成的数据是一个包含所有合成数据的生成器对象。我们可以尝试迭代对象值并打印结果来访问数据。

for line in data:
   print(line)

让我们仔细看看生成的合成数据。

line

作者图片

上图是格雷特 from 模型的合成数据示例。文本参数是我们的数据是以文本数据的形式出现的。如果我们想访问它,我们可以使用.text属性。

print(line.text)

作者图片

因此,我们只需要通过分隔符(',')分割数据,并将其处理成表格形式。但是,并非所有数据都是有效的(取决于您的评估),并且在使用之前需要彻底清理。

作者图片

上面的数据是无效的,因为它们产生了超过 6 个部分的数据,而我们只需要 6 个。这就是为什么我们需要小心 RNN 模型产生的数据。然而,实用性大于缺点,所以如果你使用 Gretel,做一点工作应该没问题。

准备好以 365 Data Science 上的折扣价向所有专家学习数据科学吧!

https://365datascience.pxf.io/c/3452806/1037878/11148

结论

数据是任何数据项目的支柱,但有时我们想要的数据不可用或难以满足我们的要求。这就是为什么我们可以使用 Python 包来生成合成数据。本文解释了用于生成数据的 3 个顶级 Python 包,它们是:

  1. 骗子
  2. SDV
  3. 葛丽特

希望有帮助!

在我的社交媒体上访问我。

如果您没有订阅为中等会员,请考虑通过 我的推荐 订阅。

创建 Python 列表的 3 大 Python 思维技巧

原文:https://towardsdatascience.com/top-3-pythonic-thinking-tips-for-python-list-creation-161fe893e81a

用于数据科学的 Python 列表派生

图片由谢恩·奥尔登多夫像素上拍摄

Effective Python 是 Brett Slatkin 写的一本书,涵盖了 59 种编写更好的 Python 的具体方法。这本书以随机访问的方式编写,每个主题都有独立的源代码。对于中级 python 程序员来说,无论是工程师还是数据科学家,它都是一个很好的资源,因为它涵盖了可以按任何顺序学习的广泛主题。

涵盖的许多主题非常适用于数据科学工作流。例如,它用 PEP8 介绍了 python 思维,pep 8 是一种风格指南,确保您的 python 代码是可读的。它涵盖了函数、类和元类的最佳实践,所有这些在数据科学工作流中都有重要的用例。它还涵盖了为列表、元组和字典编写可读理解的最佳方法。这可以应用于诸如特征工程、数据预处理和数据后处理的任务。

理解是以可读的方式从一个列表导出另一个列表的有用方法。有效的 python 涵盖了理解的最佳实践(也适用于元组和字典)。它不鼓励使用 map 和 filter,它们可以完成与理解相同的任务,但代码更嘈杂、更难阅读。它也建议不要在理解中使用多种表达方式。最后,它建议对需要理解大量数据的任务使用生成器。

在数据科学工作流中编写有效的 python 可以确保用于要素工程、数据预处理和数据后处理等任务的代码高效易读。效率和可读性使得数据科学和机器学习代码库更容易维护。代码越容易阅读,就越容易在不产生错误的情况下进行修改。此外,了解执行任务的更有效的方法,如列表派生,最终有助于开发人员编写更有效的代码。

在这里,我们将看到如何将三种有效的 python 实践整合到一个简单的数据科学工作流中。我们将看看如何使用列表理解,而不是映射和过滤,可以提高可读性。我们还将看到,将理解限制在最多两个表达式可以确保代码清晰。最后,我们将在处理大量数据时比较理解和生成器。

对于这项工作,我将在 Deepnote 中编写代码,这是一个协作数据科学笔记本,使运行可重复的实验变得非常容易。我们将使用医疗成本数据集。这些数据在数据库内容许可 (DbCL: Public Domain)下公开免费使用、修改和共享。

使用列表理解代替映射&过滤器

Map 和 filter 内置于 python 函数中,这些函数为可以通过列表理解实现的任务提供了方便快捷的方式。为了展示这些技术之间的区别,我们将考虑两个常见的数据任务。具体来说,我们将展示如何使用 map 来生成列的 log 转换,然后展示如何使用 list comprehension 来完成相同的任务。

首先,让我们导航到 Deepnote 并创建一个新项目(如果您还没有帐户,可以免费注册)。

让我们创建一个名为“effective_python”的项目,并在这个项目中创建一个名为“list_comp_generators”的笔记本。另外,让我们将 insurance.csv 文件拖放到页面左侧的“文件”面板中:

作者截图

接下来,让我们导入 pandas 库并将我们的数据读入 pandas 数据框架:

作者创建的嵌入

接下来,让我们显示前五行数据:

作者创建的嵌入

使用地图进行对数变换

我们首先要考虑的列转换是对数转换。这是一种常用的技术,用于将倾斜数据转换为近似正常的数据。我们可以使用 map()函数来转换数据中的数值列表。让我们使用地图进行身体质量指数值的对数变换。我们将导入 Numpy 库,并定义一个函数,该函数将一个列表作为输入,并返回一个经过对数转换的元素列表:

作者创建的嵌入

接下来,我们可以使用 map 将我们的函数应用到我们的身体质量指数列表。map 函数接受我们将要应用的函数的名称和一个 iterable(在我们的例子中是一个列表):

output_list = map(function, list)

我们首先定义一个名为 bmi_list 的变量,并将 bmi 值的列表存储在变量中。然后,我们可以将我们的函数和列表传递给内置的 map 函数,并将结果存储在一个新列表中,我们称之为 bmi_lt_map。然后,我们需要定义一个新列来存储转换后的列:

作者创建的嵌入

请注意,这需要 5 行代码来完成:

import numpy as np 
def log_transform(input_list):
    return np.log(input_list)
bmi_list = list(df['bmi'])
bmi_lt_map = map(log_transform, bmi_list)
df['bmi_lt_map'] = bmi_lt_map

使用列表理解进行日志转换

让我们看看如何使用列表理解来帮助我们用更容易理解的代码达到同样的目的:

作者创建的嵌入

我们发现只用两行代码就可以做同样的事情。它也更容易阅读。值得注意的是,将 log 转换直接应用到 dataframe 列也是紧凑且易于阅读的,尽管这对于更复杂的转换是不可能的。

作者创建的嵌入

在列表理解中避免两个以上的表达

假设我们有一个由分类机器学习模型生成的预测概率列表:

作者创建的嵌入

我们可以使用列表理解将这个列表转换成单个列表(我们可以“展平”列表):

作者创建的嵌入

这是一个包含两个 for 循环的列表理解。这是使用两个传统 for 循环的一个易于阅读的替代方法:

作者创建的嵌入

列表理解方法占用了两行代码,而传统的 for 循环占用了 5 行代码!尽管列表理解起来很方便,但可读性和紧凑性会随着两个以上的表达式而迅速减弱。假设我们想为概率大于 0.8 的列表生成一个标签为“是”的列表。、“可能”表示概率在 0.5 到 0.8 之间,而“否”表示概率小于 0.5。我们可以使用列表理解来做到这一点:

作者创建的嵌入

虽然这是紧凑的,但阅读和理解起来相当困难。如果我们使用传统的 for 循环,虽然它需要更多的代码行,但却更容易理解:

作者创建的嵌入

thump 的一个好的规则是避免使用两个或更多的列表理解表达式,包括 for 循环和条件。

大输入的发电机表达式

虽然列表理解非常有用、简洁且易于理解,但是对于大量输入,它们需要大量的内存。对于大量输入,列表理解的替代方法是生成器表达式。生成器表达式结合了理解和生成器。它们是大量输入的理想选择,因为它们从表达式中一次产生一个项目。要编写生成器表达式,我们只需使用括号()。假设我们有一个分类预测概率的大列表。我们将使用 Numpy 的 random.normal 方法生成 2 亿个预测概率的综合列表,其平均值为 0.5,标准偏差为 0.1:

作者创建的嵌入

现在假设我们想使用列表理解生成一个标签列表。我们将为大于 0.5 的概率指定“是”,为小于 0.5 的概率指定“否”。

如果我们尝试在与我们的列表理解相同的单元格中打印前十个元素,我们将耗尽内存:

作者创建的嵌入

所以我们需要在一个单独的单元格中这样做:

作者创建的嵌入

生成器表达式可以用来计算一个迭代器,它一次产生一项,而不是整个表达式。这有助于避免内存分配问题:

作者创建的嵌入

我们看到,我们能够创建生成器对象并打印前十个元素,而不会遇到内存问题。

这篇文章中的代码可以在 GitHub 上找到。

结论

在这篇文章中,我们讨论了一些通过 pythonic 思维来改进列表创建的有用方法。首先,我们讨论了列表理解应该如何用于 map 和 filter,因为它更容易理解,尤其是在与 python 初学者合作时。然后,我们讨论了如何避免在列表理解中使用两个以上的表达式,以最大限度地提高清晰度和可读性。最后,我们展示了如何使用生成器表达式来替代对大量输入的列表理解。我鼓励你将这些技术应用到你自己的软件工程和机器学习项目中。

促进您在分析和数据科学领域工作的三大工具

原文:https://towardsdatascience.com/top-3-tools-to-promote-your-work-in-analytics-data-science-7b87d80615fc

获得你应得的荣誉

照片由帕特里克·福尔Unsplash 拍摄

介绍

您是否厌倦了将分析和数据科学视为支持职能,而很少或根本不认可您的团队所推动的价值?

对于你和你的团队所做的工作,你是否经常感到被低估?

你想学习有助于宣传你的团队的贡献的工具吗?

在这篇博文中,我们将讨论让你和你的团队得到应有认可的 3 种最有效的方法。

宣传你的工作

“作品会自己说话”的日子已经一去不复返了。能够传达你正在推动的价值在任何工作中都很重要,但在分析领域这一点至关重要,因为在许多情况下,你正在让其他职能部门有效地完成他们的工作。例如,您与产品经理合作制定产品功能发布的初始策略。3 个月后,该功能推出,虽然你在构思阶段做出了巨大贡献,但随着发布时间的临近,互动越来越少,项目经理在发布时没有提到你。这只是一种情况,但还有几个这样的情况,累积起来会导致错过认可的机会。

能够宣传你的工作在分析中极其重要——没有这种技能,你所产生的影响很容易被忽视。

作为一个害羞、书呆子和自我意识强的孩子,我在 30 岁出头的时候一直不擅长自我推销。然而,随着我成为一名领导者,我不得不特别注意和学习这一技能——不仅是为了我自己,也是为了我所领导的团队。

以下是我学到的 3 个最有效的策略,用于提升分析和 DS 团队,展示所做工作的影响——

1.公告电子邮件

不久前,在一家科技初创公司工作时,我和我的团队认为我们在传播我们的工作方面做得很好。但是后来发生了一件事,彻底改变了我们的看法。我们非常努力地创建了一个新的客户保持仪表板——创建新的数据管道,定义有助于展现关键见解的指标,并进行迭代以最终实现出色的可视化。我发送了一封电子邮件,与一小群观众分享仪表板,我们得到了预期的不错的回应。

'这看起来棒极了!谢谢,”

“非常有帮助——感谢分享。”

然后,我们的营销副总裁介入进来,告诉我们用正确的包装可以实现什么。她发出了另一封信,向更广泛的受众“宣布”(而不仅仅是分享)仪表板。反响是惊人的!她在仪表盘上比我们在通讯上产生了更多的参与和兴奋。

这真是不可思议。谢谢🙌'

真是杰作。🔥这种水平的分析严谨性将有助于释放未来的增长!我想提出一个午餐学习仪表板演示的请求;)’

‘爱,爱,爱——了不起的作品!!'

最后,这是最受欢迎的仪表板之一,显然为作者和团队创造了大量的品牌资产。

这让我意识到更好地包装我们的公告或分发电子邮件的巨大机会。以下是我一路走来学到的一些技巧:

  • 使用吸引人的主题行 —例如,“保留仪表板在这里!”或“介绍保留仪表板”
  • 除了陈述仪表板包含的内容,还要将其与关键见解、建议和后续步骤联系起来
  • 使用图标&视觉效果——添加相关的图标和视觉效果使电子邮件更容易阅读,并能很好地摆脱所有沉重的文本。注意:不要过度使用!

John、Ramya 和 Kevin 一直在开发一个奇妙的一站式商店,用于将客户情绪趋势整合到一个集中的客户反馈仪表板中。这将是我们支持公司关注“了解您的客户”的主要资源,这将为我们打开许多增长杠杆。🚀

在该控制面板中,您会发现-

—按业务条线划分的客户情绪:💡在所有客户群中,XXX 的负面情绪最高,而 YYY 的负面情绪最低

—情绪随时间的变化:💡在过去的 6 个月里,客户情绪一直在恶化,在几周前的冬季暴风雪中急剧上升

建议&下一步-

—进行用户研究,深入挖掘改进客户服务的机会

我强烈建议大家收藏此资源,与您的团队分享,并利用团队的出色工作,利用以前未开发的数据源来挖掘客户见解。请留意如何使用这个仪表板的演示。在此之前,如有任何问题,请随时联系#Customer-Insights slack channel。

来源:作者

2.宣读

对于你们中可能没有听说过这个术语的人来说,“读出”是另一个术语,指的是以一种易于通读的方式包装的分析。通常,我会看到团队在进行一次性分析时给出的读数——无论是对某个主题的深入探究,例如是什么推动了客户保持率,还是根本原因分析,例如为什么漏斗顶端转化率下降,或者分析实验/发布/活动绩效。

除了一次性的读数,对你的利益相关者重要的主题进行重复性的读数会给你带来很多荣誉。根据业务需求,您可以选择每周或每月一次。

仪表板的重复读数

你多久听到一次“更多的洞察力和更少的仪表板”的需求?我见过许多分析团队对此感到慌乱——他们会反驳说,你需要仪表板来创造洞察力。虽然这可能是真的,但最终发生的是没有来自这些仪表板的持续洞察流,它们只是被视为另一个数据来源。积极地与利益相关者分享这些仪表板的总结结果将会改变这种看法。

我们需要更多的洞察力,更少的仪表板

月度或季度业务回顾

这是另一种保持信息向利益相关者循环流动的好方法。业务回顾是根据关键指标的趋势来回顾业务健康状况的演示。这为高层领导提供了一个机会,让他们从单调乏味的一天中抽身出来,看看每个月或每个季度的业务表现。

分析团队最适合呈现业务评论,原因有多种——
1)他们是真实数据和指标来源的专家
2)他们更有可能采取分析严谨和假设驱动的方法
3)他们不偏不倚

客户的观点

归根结底,从某种意义上来说,你的商业伙伴就是你的客户,所以让我们站在他们的角度想想他们的需求。想象一下,作为一名营销人员、产品经理或运营经理,你的日常工作就是挖掘和整合来自仪表盘的信息。这对他们来说是一个很大的时间陷阱,坦率地说,这不是他们最擅长的。如果你能把这些信息推给他们,而不是他们不断来找你,这不仅会减轻他们的痛点,他们也会开始把你视为值得信赖的合作伙伴。重新调整这种推拉动力也将帮助你更好地控制你的时间和工作重点。

我们需要改变这种动态,这样团队就可以向高管推动见解,而不是让他们提出要求

~分析和决策支持团队中一家科技创业公司的首席财务官

3.时事通讯

这是一个简单而有效的方法。就准备或设置而言,您不需要为此进行大量跨职能协调。您可以简单地开始向目标受众发布简讯,表达您的目标,并根据反馈进行迭代。这里的诀窍是突出正在进行的工作流的目标和那些已经完成的工作流的结果,总是与业务结果或利益相关者的需求相联系。下面是一个能让你赢得更多印象分的样本布局:

  • 总结 —关键胜利&接下来会发生什么
  • 按主题详细更新
  • 时事通讯常见问题—
    目标:这篇时事通讯的目标是什么。例如,提供可见性并协调优先级
    • 节奏:每周/两周/每月
    • 受众:公司高级领导
    • 团队成员-
      -POC:如果他们有问题,应该联系谁

总结:该团队主要关注(1)客户情绪分析框架,(2)修订北极星指标定义。除此之外,我们一直在研究一个新的实验平台 POC (A/B 测试),并研究客户流失建模。

下一步:最终确定北极星指标定义和管道、客户细分框架和目标设定会议(在接下来的 1 个月内)。

1。客户情绪仪表板:

目标: 创建一个整合的视图,以展示可操作的见解,促进高级领导的成长

—开发框架方法、路线图并在其上执行

—确定了一组初始指标,并进行了可行性研究和利益相关方访谈

—构建了新的数据管道,从表面到表格,并产生了见解和建议

来源:作者

奖励提示

发送完所有这些信息后,将这些信息视为对话的开始,而不是对话的结束。这个想法不应该是“我已经为他们提供了工具,他们将从那里得到它”,而应该是一个对话的开始。您应该在沟通中始终有足够的信息,让他们知道可以向谁寻求更多的问题和合作。

结论

想想你正在做的一个项目或者你领导的一个团队。你能想象自己利用这些工具来传播你的作品吗?

LinkedIn 上有超过 100 万个分析和数据科学职位的招聘信息。大多数非分析角色也强调数据驱动技能的重要性。然而,许多分析和数据科学团队努力证明他们正在推动的价值。有了有效沟通工作的额外技能,你不仅能做好自己的工作,还能因此得到认可。

如果您想继续看到我关于分析&数据科学职业发展的内容,您可以关注&订阅我的https://preeti-semwal.medium.com/subscribe

我提供的其他资源可以帮助您在分析和设计领域发展职业生涯—

完成产品 A/B 测试课程及面试指南 (使用此链接可享受折扣价)

异常检测模型赢得您信任的三大方法

原文:https://towardsdatascience.com/top-3-ways-your-anomaly-detection-models-can-earn-your-trust-f59072a6199c

将异常检测模型结果连接回原始信号

Unsplash 上由zdenk macha ek拍摄的照片

在上一篇文章中,我介绍了一些通过对原始结果进行后处理来从异常检测模型中提取更丰富信息的方法:

通读本文并付诸实践后,您可能会对这些见解的可信度有所反馈:

“我不知道我是否能相信这些见解。为什么这个模型会这么说?给我看看数据!”

在某些情况下,证据就在布丁中:您必须在实时数据上部署模型,并对标记的异常进行几周的调查。这将使您能够进行定期的现实检查,并将模型标记的事件与您的用户在该领域中的知识进行比较。这种合作将逐渐建立和加强对你的模型的信任。

不久前,我在 LinkedIn 上发布了一个简短的演示(如果你想了解这篇文章,请查看 这篇文章 ),其中我解释了当我试图将异常检测模型结果与输入时间序列联系起来时所遵循的过程。

我鼓励你跟随这篇博文,浏览 GitHub,获取 这一系列的 Jupyter 笔记本 。你可以使用你常用的 Jupyter 环境,或者用 Amazon SageMaker 创建一个。在您克隆了 repo 并运行前四个笔记本(从 数据生成部分模型评估部分 )后,您可以打开最后一个笔记本(synthetic_4_results_deep_dive.ipynb)并遵循本文。

数据集概述

在本文中,我仍然使用我用一些合成异常生成的人工数据集。如果您想了解更多关于这个数据集的信息,请前往我的 上一篇文章 的数据集概述部分。简而言之,这是一个 1 年长的数据集,有 20 个时间序列信号和 10 分钟的常规采样率。当可视化这些数据时,您会发现一些故障时间(下面的红点)和一些恢复期(下面的黄色部分):

综合数据时间序列概览(图片由作者提供)

在上一篇文章中,我们还使用Amazon Lookout for Equipment(运行在 AWS 云中的托管服务)训练和异常检测模型。如果您想更深入地了解这项服务(即使您不是开发人员),我在 AWS 书籍的时间系列中专门为这项服务写了 6 章:

https://www.amazon.com/Time-Analysis-AWS-forecasting-anomalies-ebook/dp/B09MMLLWDY

回到时间序列

我将假设你已经运行了前 4 个笔记本到最后,你有一个训练有素的模型和你的第一次可视化来理解它的结果。为了更好地理解正在发生的事情,你可能想回到最初的时间序列。即使在已经部署了这种模型的生产环境中,执行常规的错误分析也可能是您需要与您最喜欢的主题专家一起进行的活动。毕竟,这些人工智能模型不会取代你的专家和操作员:它们只是通过提供更快的洞察力来增强他们。

时间序列可视化

可视化你所有的时间序列(即使只有 20 个)可能已经很有挑战性了。这是我最近遇到的一个数据集示例,您可以看到近 100 个时间序列在一起:

多元数据集:时间序列概述(图片由作者提供)

真是大海捞针,不是吗?如果我们为 20 个传感器的更简单的合成数据集组合相同的图,则更容易看到发生了什么:

合成多元数据集概述(图片由作者提供)

然而,在现实生活中依靠这种简单性可能是不够的…您可以做的第一件事是突出显示您的模型检测到一些事件的时间范围:

突出显示检测到的异常范围(图片由作者提供)

这稍微好一点,特别是如果你有很少的时间序列,并且异常很容易发现。然而,如果你读了我以前的文章,你会记得我们的异常检测模型实际上挑出几个传感器。让我们绘制第一个,而不是在一个单一的窗格中显示所有这些:

现在这看起来更明显了(图片由作者提供)

signal_07输入是我们的异常检测模型挑选出来的时间序列之一,是这些检测到的事件的主要贡献者。在上面的图中,我用红色突出显示了异常的时间范围:现在更清楚为什么第一个事件被检测到了。第二个事件更有趣:实际的失败是清晰可见的,但是模型实际上在这种情况发生前 2 周就检测到了错误。

“如果不太明显,我也没发现我的信号有什么问题,会发生什么?”

这是你可能会关心的问题之一,尤其是当你看到前一个图中突出显示的失败之前的两周时间时。看起来信号在故障前略有增加,但没有这么明显。这就是使用直方图来可视化时间序列信号所取值的分布可能会派上用场的地方。让我们看看这个…

可视化时间序列值分布

让我们关注上面第一个检测到的事件。我在笔记本上添加了一些实用函数来绘制两个叠加的直方图:

第一个异常点周围信号 _07 的值分布(图片由作者提供)

蓝色直方图signal_07在训练范围内所取值的分布,而红色直方图突出显示了异常期间同一信号所取的值。行为的变化甚至更加明显,您甚至可以用您的领域专业知识来丰富这些直方图。例如,您可能知道在正常操作条件下,signal_07的范围在 1320 和 1450 之间。在这种情况下,您可能希望通过在直方图中添加以下信息来帮助您的用户:

突出显示正常操作条件(图片由作者提供)

让我们看看第二个异常的直方图:

第二异常周围信号 _07 的值分布(图片由作者提供)

这里可以看到失败发生的部分(0 左右的横条)。让我们放大第二部分,看看在失败之前发生了什么:

故障前信号 _07 的值分布(图片由作者提供)

在这里,尽管在时间序列上差别很小,但分布的变化却非常明显。

结论

在本文中,您了解了如何将异常检测模型结果与原始时间序列联系起来。这对于在您的机器学习系统中建立信任非常有价值,也是与领域专家合作并进一步改善您的异常管理流程的一个很好的工具。基本上,异常检测模型输出可以帮助您集中调查,而适当的可视化或原始数据可以帮助您查明原因!

在以后的文章中,我将深入研究如何计算直方图之间的距离,并使用它作为异常检测模型中衡量特征重要性的代理。

我希望你觉得这篇文章很有见地:如果你不想错过我即将发布的帖子,请随时在这里给我留下评论,并不要犹豫订阅我的 中型电子邮件订阅源 !想支持我和以后的工作?通过我的推荐链接加入 Medium :

https://michoara.medium.com/membership

2022 年初前 30 名 GitHub Python 项目

原文:https://towardsdatascience.com/top-30-github-python-projects-at-the-beginning-of-2022-86b1e3dad1a

图片来自皮克斯拜

2022 年初前 30 名 GitHub Python 项目

拥有最多明星的仓库

2022 新年快乐!作为新年的第一个帖子,我很好奇到目前为止最受欢迎的 Python 项目是什么。GitHub 绝对是最适合拥有这些统计数据的地方。虽然不是所有的开源项目都会在这里维护,但是不会有任何其他地方有这种能力。

这个排名很简单,因为我会分享我的代码。现在,让我们看看如何用几行代码从 GitHub API 中获取排名列表。之后,我将使用我的术语对这些项目进行分类,然后添加一些简短的介绍。

排名前 30 的 GitHub 项目分类如下:

  • 7 项提高生产率的回购
  • 作为编程框架的 3 个回购
  • 促进机器学习的 5 个回购
  • 4 个便利现实生活的回购
  • 6 个收集整理有用信息的回购
  • 5 个教授某些科目的回购

GitHub 搜索 API

图片来自阿雷克索查来自皮克斯拜

官方 API 文档可以在这个页面找到:https://docs . github . com/en/rest/reference/search # search-repositories

所以,本文不再重复参数等细节。如果您对我们还能做什么感兴趣,请参考该页面。

最美妙的是,我们不需要注册或申请一个 API 密钥来使用这个端点。当然,它有一个速率限制,每分钟最多 10 个请求,但这对我们测试代码和拉排名列表来说已经足够了。

首先,我们需要使用 Python 的requests模块。它是内置的,我相信你们大多数人应该很熟悉它。然后,我们需要熊猫对数据进行一些转换。

import requests
import pandas as pd

URL 是基于 API 文档的https://api.github.com/search/repositories。因为我们只对基于 Python 的项目感兴趣,所以我们需要在查询中放入参数language:python。然后,我们要将搜索结果按星数排序,按降序排序。

url = '[https://api.github.com/search/repositories?q=language:python&sort=stars&order=desc'](https://api.github.com/search/repositories?q=language:python&sort=stars&order=desc')

然后,我们可以使用requests模块来调用这个 API 端点。我们应该使用 GET 方法。然后,我们可以将结果转换成 Python 字典。

res = requests.get(url)
res_dict = res.json()

所有的搜索结果都将放在一个带有关键字“items”的数组中。所以,我们可以得到所有的回购信息如下。默认页面大小是 30,所以我们将有 30 个回购。他们正是排名前 30 的 Python Repos:)

repos = res_dict['items']
len(repos)

结果字典中还有一些其他信息。如果我们删除项目数组,我们可以看到它表明搜索结果有更多的页面,在我发出请求时,总共有 8,046,758 个 Python Repos。

现在,让我们将条目数组转换成熊猫数据帧。

repo_df = pd.DataFrame(repos)

然后,我想删除所有不感兴趣的列。我还将添加一个名为year_on_github的专栏来记录这个项目在 GitHub 上创建了多少年。

repo_df = repo_df[['name', 'full_name', 'html_url', 'created_at', 'stargazers_count', 'watchers', 'forks', 'open_issues']]
repo_df['created_at'] = pd.to_datetime(repo_df['created_at'])
repo_df['created_year'] = repo_df['created_at'].dt.year
repo_df['years_on_github'] = 2022 - repo_df['created_at'].dt.year

以下是 30 大回购的完整列表:

提高生产率的回购

图片来自 Pixabay玛利亚 _ 多姆妮娜

这些项目方便了我们的日常工作,提高了我们的工作效率,例如为操作系统增加了一些功能。

1.thefxxk(排名第六,65,988 颗星)

请注意,这个名字是经过编码的,因为我正在写一篇适合所有年龄段的文章:)

当我们在 Linux 或 GitBash 环境中使用控制台时,这个工具可以帮助我们纠正前面命令中的错误。

图片提供:https://raw . githubusercontent . com/nvbn/the fuck/master/example . gif

2.httpie(排名第九,53,255 颗星)

HTTPie 是一个命令行 HTTP 客户端。它的目标是使 CLI 与 web 服务的交互尽可能人性化。HTTPie 是为测试、调试和通常与 APIs & HTTP 服务器交互而设计的。http & https命令允许创建和发送任意 HTTP 请求。它们使用简单自然的语法,并提供格式化和彩色化的输出。

图片提供:https://raw . githubusercontent . com/httpie/httpie/master/docs/httpie-animation . gif

3.you-get(排名第 12,42,791 颗星)

这是一个很小的命令行工具,用于从网络上下载媒体内容(视频、音频、图像),以防没有其他方便的方法。

4.localstack(排名第 16,38,008 颗星)

这个 repo 是一个云服务模拟器,运行在您的笔记本电脑或 CI 环境中的单个容器中。使用 LocalStack,您可以完全在本地机器上运行 AWS 应用程序或 Lambdas,而无需连接到远程云提供商!无论您是在测试复杂的 CDK 应用程序或 Terraform 配置,还是刚刚开始了解 AWS 服务,LocalStack 都可以帮助您加快并简化测试和开发工作流程。

5.Shadow丨socks(排名第 20,33,099 颗星)

Shadow丨socks 是一个免费的开源加密协议项目,在中国被广泛用于规避互联网审查。在撰写本文时,由于违反规定,此回购已被删除。

6.富人(排名第 23,32,075 颗星)

这种回购可以轻松地为终端输出添加色彩和风格。它还可以呈现漂亮的表格、进度条、降价、语法高亮源代码、回溯等等——开箱即用。

有一篇我的文章详细介绍了这个库。

[## 使用 Python 在控制台中显示富文本

towardsdatascience.com](/get-rich-using-python-af66176ece8f)

7.certbot(排名第 30,28,587 颗星)

Certbot 是 EFF 加密整个互联网努力的一部分。web 上的安全通信依赖于 HTTPS,它要求使用数字证书,让浏览器验证 Web 服务器的身份(例如,这真的是 google.com 吗?).Web 服务器从被称为证书颁发机构(ca)的可信第三方获得证书。Certbot 是一个易于使用的客户端,它从 Let's Encrypt(一个由 EFF、Mozilla 和其他公司推出的开放认证机构)获取证书,并将其部署到 web 服务器上

作为编程框架的回购协议

来自 PixabayCapri23auto 图片

这些回购协议都是非常著名的框架,要么用于 web 开发,要么用于其他一些软件开发。

1.flask(排名第七,57584 颗星)

对于这个框架,我想不需要太多的介绍。如果您正在使用 Python 进行 Web 开发,您必须曾经使用过它,或者至少了解它。

2.scrapy(排名 14,42,471 颗星)

如果你想使用 Python 进行 Web 抓取,这是一个“必须学习”的框架。它简化并自动化了从网页中提取信息的工作。它用于抓取网站并从其页面中提取结构化数据。它可以用于广泛的目的,从数据挖掘到监控和自动化测试。

3.fastapi(排名 15,40,363 颗星)

与 flask 类似,这也是 Python 中用于 web 后端开发的流行框架。它的重点是使用最少的代码编写常规的 Web APIs。如果你的后端不太复杂,就使用它。

促进机器学习的回购协议

图片来自PixabayGerd Altmann

机器学习无疑是 Python 最火的用法。所以,在这个列表中有这么多与机器学习相关的项目并不奇怪。

1.模特(排名第五,72,417 颗星)

如果你听说过使用 Python 的机器学习,你一定听说过 TensorFlow。这个回购也叫“TensorFlow Modul Garden”。它组织机器学习模型,并使用 TensorFlow 通过示例实现它们。模型可能来自 TensorFlow 官方,也可能来自一些著名的研究项目或社区。当我们想要在 TensorFlow 中使用任何机器学习模型时,它们可以非常有助于节省我们的时间。

2.keras(排名第八,53,638 颗星)

Python 中非常流行的机器学习框架。它提供了许多高级 API,使数据科学家能够用最少的代码训练深度学习模型。

3.人脸识别(排名 13,42,762 颗星)

顾名思义,这个项目可以从 Python 或命令行识别和操作人脸。号称是世界上最简单的人脸识别库。只要输入一张人脸图像,它就会识别定位。然后,您甚至可以使用一些现成的功能对其进行修改。

4.实时语音克隆(排名第 21,32,607 颗星)

我宁愿把它放在 ML 类别中,因为这是一个了不起的项目,但我们需要小心,它不应该被滥用。基本上,它可以从 5 秒钟的语音记录中“学习”某人的声音,然后用同样的声音说任何话。下面是作者的演示视频。

5.DeepFaceLab(排名第 27,30,651 颗星)

如果你曾经看过“deepfake”视频,很可能就是这个项目创作的。它学习一张人脸,并将其“植入”到另一个视频中,用它学习的那张脸替换这张脸。可能会有很多伦理问题,但这个项目确实令人惊叹。

便利现实生活的回购

图片由钱比发自 Pixabay

这些回购都是用 Python 写的,但是在现实生活中使用。它们既可以节省我们的时间,也可以让我们做一些非常酷的事情。

1.核心(排名第 11,48,763 颗星)

这种回购是开源的家庭自动化,将本地控制和隐私放在第一位。由世界各地的修补匠和 DIY 爱好者组成的社区提供动力。非常适合在 Raspberry Pi 或本地服务器上运行。它被许多成功的家庭自动化产品使用,如亚马逊 Alexa 和谷歌 Cast。

2.openpilot(排名第 24,31,998 颗星)

这个 repo 是一个开源的驾驶辅助系统。它执行自适应巡航控制(ACC)、自动车道居中(ALC)、前方碰撞警告(FCW)和车道偏离警告(LDW)等功能,适用于越来越多的受支持的汽车品牌、车型和年款。然而,你需要购买他们的产品并安装在你的车上。不是完全 DIY 而是减少了努力。

3.XX-Net(排名第 26,31,002 颗星)

这是一个绕过中国“防火长城”的代理工具,使中国互联网用户能够浏览某些网站,如 YouTube 和脸书。

4.12306(排名第 28,30401 星)

12306 是中国预订火车票的热线号码,大约 15 年前,当他们开始网上预订时,它也被用作域名。这个回购是一个自动订票工具,因为在高峰期座位可能会短缺,很难预订。这就是开发者解决问题的方式:)

收集和组织有用信息的仓库

图片来自 Pixabay艾哈迈德·阿迪蒂

这些 repos 可能不会维护太多代码,但它们要么使用 Python 来收集这些信息,要么这些信息是关于 Python 的。这些信息被认为是非常有帮助的,所以他们的排名很高。

1.公共 API(排名第一,173,658 颗星)

这个 repo 组织了数百个可用于软件和网络开发的免费 API。它们中的许多都非常有趣,比如有趣的事实,每次我们调用它时,它都会随机产生一个有趣的事实。还有一些非常有用的 API,如 Colormind API,它可以用来生成华丽的颜色代码,这些代码可能会在我们的数据可视化中使用。此外,有许多政府开放的 API 可以用来提取一个国家的统计数据。

2.牛逼——python(排名第四,112,609 星)

这个 repo 组织了数百个其他 GitHub Python 项目,这些项目“棒极了”。它们对你的“反重力”非常有用:(这些项目被分类,以便更容易找到我们需要的。

3.令人敬畏的机器学习(排名第十,52,487 颗星)

和上一个类似,这个 repos 收集的是机器学习项目。

4.funNLP(排名第 17,35,922 颗星)

这是一个中文回购,虽然它也可以用于英语。但是,该文档不提供英文版本。它提供了 NLP 词典,如敏感词,NLP 工具集和一些学习材料。

5.面试 _ 内部 _ 参考(排名 19,33,135 星)

又一个中国回购。它经常组织来自华为等知名公司的面试问题。它还提供了作为数据开发人员必须了解的基本知识,如算法和数据库设计原则。

6.深度学习-论文-阅读-路线图(排名第 24,31,521 颗星)

如果你想从基础开始学习机器学习,这个回购可能是一个好的开始。它利用学术论文绘制了历史上机器学习发展的“路线图”。

教授某一学科的报告

图片来自 PixabayStefan Meller

这些回复不是用来编码的。它们可以被认为是一种开源的“书”。他们提供的信息可以用来学习一些东西。

1.系统设计入门(排名第二,157,775 颗星)

如果你想开始你的系统架构师职业生涯,这个回购是一个宝石。它介绍了许多有用的概念和必要的演示图表。您可以找到几乎所有您想知道的信息,例如何时使用 SQL 或 NoSQL、如何设计分布式关系数据库以及什么是反向代理。

2.Python-100 天(排名第三,113,812 颗星)

这个回购是中文的,它变得如此受欢迎是因为许多开发人员在中国学习 Python。它将 Python 编程知识组织成 100 个部分,这样,如果学习者坚持每天学习其中的一部分,他们可以在 100 天内完成。不幸的是,它没有被翻译成英语。

3.PayloadsAllTheThings(排名 18,33,407 颗星)

该报告显示了 Web 应用程序安全的有用负载和旁路列表。如果你想成为一个有经验的 web 开发人员,避免流行的安全漏洞和陷阱,这是一个必须学习的材料。几乎所有的概念都是用 Python 示例实现的。

4.AiLearning(排名第 22 位,32,517 颗星)

一个从 Python 基础到 PyTorch ML 框架教学的中文回购。

5.d2l-zh(排名第 29 位,29,618 颗星)

这是一本名为《潜入深度学习》的书。虽然这份回购是中文的,但英文版(原版)可以找到如下。

https://www.d2l.ai/

摘要

图片来自 PixabayKanenori

由于我定义“受欢迎”的方式仅仅是使用明星的数量,很明显一些教授一些学科和组织信息的 repos 会排名很高。那是因为人们会倾向于添加星星作为“书签”。代码是提供的,所以这取决于你添加一些更多的考虑到这个排名,并满足你的好奇心。

https://medium.com/@qiuyujx/membership

如果你觉得我的文章有帮助,请考虑加入 Medium 会员来支持我和成千上万的其他作者!(点击上面的链接)

遗留数据堆栈中应避免的 4 大数据质量错误

原文:https://towardsdatascience.com/top-4-data-quality-mistakes-to-avoid-on-your-legacy-data-stack-32d09f5a02c

在追求现代数据堆栈的过程中,不要忘记传统

Yassine Khalfalli 在 Unsplash 上拍摄的照片

我阅读并撰写了许多现代数据堆栈(MDS)的文章,我很高兴作为一个行业,我们正在正面迎接大数据及其更大问题的挑战。但是我们似乎忽略了一件事,那就是了解在迁移到 MDS 的同时,我们如何至少“保持遗留数据堆栈(LDS)”。

在迁移到 MDS 的过程中,您的大多数客户将继续使用您的传统数据堆栈。事实上,客户并不关心他们在哪个堆栈上;他们关心你提供给他们的服务。在当前的“最新趋势”讨论中,谈论传统的本地数据堆栈几乎是亵渎神明。你不应该把时间花在移居 MDS 上吗?

许多公司正在经历巨大的转型项目,尤其是大型企业组织;当这些巨大且往往命运多舛的转变继续时,我们是否忽视了 LDS?显然,花掉的每一分钱都将是“留给遗产”或“后悔花掉”。我们需要在这种方法中找到平衡。

让我们开始吧。

1.不在源位置分析数据

在考虑迁移到 MDS 之前,您应该花点时间了解现有 LDS 中的数据质量。在源位置对数据进行分析将提供对已知和未知数据质量(DQ)问题的清晰理解。

对数据进行分析还有助于估算修复 DQ 问题所需的时间,从而估算迁移到具有更高质量数据的 MDS 所需的时间。缺乏特征分析肯定会给客户带来负面影响,并导致 MDS 迁移的失败。

你能做什么?

检查常见的 DQ 问题,如唯一性、完整性和准确性。实现一个简单的仪表板,在一段时间内对质量进行趋势分析,以确定质量是在恶化还是在改善。制定一个计划来解决这些问题及其对 MDS 迁移时间表的影响。

2.未修复已知的 DQ 问题

众所周知,LDS 是不灵活的庞然大物,由官僚程序管理,甚至一点也不灵活。因此,解决已知的 DQ 问题需要很长时间和专业知识。取而代之的是,寻求将数据转储到 MDS 并在将来进行修复的方法。我们都知道,未来的修复不会发生。项目团队继续前进;产生了有限的文档,并且具有该知识的专业工程师退休了。而高管们则为“我们已经迁移到 MDS”而欢欣鼓舞。

你能做什么?

如果存在格式不一致或重复数据等 DQ 问题,直接在源位置解决问题将会带来巨大的好处。首先,这将减少对客户的不利影响;其次,迁移会变得更容易,因为你将有更好的数据带到 MDS;第三,你可以更快地在 MDS 开始你的洞察力之旅。

3.对 LDS 投资不足

一旦 MDS 的战略达成一致,LDS 就好像变成了一个没人想要的孩子。这听起来很刺耳,但这就是组织处理遗产的方式。当然,LDS 将在未来 2-4 年内逐步淘汰/退役,但是您认为您还会在这个平台上为您的客户服务两年吗?连续两年提供糟糕的客户服务,你会开心吗?过了这段时间,你可能就没有多少顾客了。

你能做什么?

持续投资 LDS 以确保数据的高质量和问题的及时解决对于避免负面的客户影响至关重要。如果由于系统不灵活而无法在 LDS 中解决 DQ 问题,那么计划将这些数据迁移到 MDS 并找到解决方法将是至关重要的。由于 DQ 问题产生技术债务(永远不会偿还)是一个灾难的处方。

4.期待 MDS 成为 DQ 问题的总括

MDS 不是你所期望的圣杯。如果您的组织以前遭受过低质量数据的困扰,实施 MDS 将使这些 DQ 的不良影响迅速显现出来。简单地将旧数据转储到新堆栈中会继续导致您的 ML / AI 模型和决策中的错误。

你能做什么?

理解问题本身就是解决方案的一半:认识到基础必须从一开始就到位。一个跨 LDS 和 MDS 运作的坚实的 DQ 框架具有正确的角色和职责,并具有发现、分类和补救问题的有效流程,将是赢家。

结论

我敢肯定,在下一个闪亮的物体中,我们犯了反对和忽视遗留数据堆栈的策略。你想要的关键是找到一些平衡。如果这引起了你的共鸣,请在下面留下评论来分享你的想法。

如果对您来说这是太多的传统话题,请随意查看一些最新的数据架构趋势:

如果您没有订阅 Medium,请考虑使用我的推荐链接订阅。它比网飞便宜,而且客观上能更好地利用你的时间。如果你使用我的链接,我会获得一小笔佣金,而你可以在 Medium 上获得无限的故事。

我也定期在推特上写东西;跟着我这里

前 5 名基准数据集

原文:https://towardsdatascience.com/top-5-benchmark-datasets-35d38bc9bfd7

使用 Scikit-learn 和 Keras 访问玩具数据

图片由像素上的 Ashutosh Sonwani 拍摄

玩具数据集可以用来教授机器学习中的重要概念,而不必应对数据工程的挑战。虽然数据工程是机器学习管道中非常重要的一部分,但使用玩具数据集可以避免缺失值处理、异常值处理、文件格式等问题。

玩具数据集对于数据科学教育来说是特别有用的资源。例如,如果有人第一次学习如何构建随机森林分类模型,他们不应该担心如何并行处理丢失的数据。由于这些原因,玩具数据集是教育工作者和教育平台的常用资源。例如,DataCamp 有关于使用糖尿病数据集的表格数据分类的学习模块。它还有一个使用手写数字(MNIST)数据集的影像分类课程。玩具数据集使教师能够以可控的方式教授基本概念。这对于真实数据来说要困难得多。

玩具数据集还可以让研究人员轻松构建模型基准,这些基准可用于比较最先进的方法和新颖的机器学习方法。例如,MNIST 数据集已被用于各种机器学习研究任务中的模型基准测试。具体来说,MNIST 已被用于测试卷积神经网络模型的改进、神经网络中的新型激活函数、利用生成对抗网络的异常检测等等。

鉴于其在教育和研究中的普遍用途,玩具数据集是机器学习和数据科学生态系统的重要组成部分。这有助于教师培养下一代数据科学家,研究人员在机器学习领域进行创新。话虽如此,对数据科学家来说,了解哪些玩具数据集是可用的,无论是用于学习、教学还是研究,都是至关重要的。Scikit-learn 和 Keras 是两个开源包,可以轻松访问开源玩具数据集,用于学习和研究基准标记。

Scikit-learn 是 python 中的一个开源机器学习库,它使数据科学家和研究人员能够执行各种分析任务,如分类、回归、聚类、数据预处理、降维、模型选择等。Scikit-learn 中的 datasets 模块有一系列用于分类和回归的玩具数据集。

Scikit-learn 数据集模块中三个最常用的分类数据集是手写数字数据集(MNIST)、虹膜数据集和糖尿病数据集。由于这些数据集是预加载的,我们不必担心与访问和准备数据相关的许多挑战。这对机器学习教育和研究有积极的意义。

Keras 是一个开源的深度学习 API,建立在 tensorflow 之上。鉴于许多机器学习研究涉及开发新的神经网络架构,轻松访问玩具数据集进行基准标记和测试非常有用。Keras 有各种各样的基准数据集。像 Scikit-learn 一样,Keras 提供了访问 MNIST 的途径。此外,Keras 提供了对时尚 MNIST 数据集的访问,这是 MNIST 的替代方案。时尚 MNIST 包含 10 个时尚类别的图像,包括衬衫、外套、连衣裙、运动鞋、包、凉鞋等。Keras 还提供对 CIFAR100 数据集的访问,该数据集包含各种图像,如飞机、汽车、鸟、鹿、猫、狗等。

在这里,我们将介绍如何访问五个最常用的基准数据集。对于这项工作,我将在 Deepnote 中编写代码,这是一个协作数据科学笔记本,使运行可重复的实验变得非常容易。

sci kit-学习数据集

首先,让我们导航到 Deepnote 并创建一个新项目(如果您还没有帐户,可以免费注册)。

让我们创建一个名为“sklearn_data”的项目,并在该项目中创建一个名为“access_data”的笔记本:

作者截图

接下来,让我们从 Scikit-learn 导入数据集模块:

作者创建的嵌入

分类数据集

手写数字(MNIST)

让我们从 Scikit-learn 中导入 datasets 类开始:

作者创建的嵌入

接下来,我们可以通过调用 datasets 类的 load_digits 方法来访问 MNIST 数据。让我们将数据存储在一个名为 digits 的变量中:

作者创建的嵌入

接下来,让我们将数据集中的第一幅图像可视化。我们可以使用 Matplotlib 来做到这一点:

作者创建的嵌入

我们还可以在一台显示器上显示多幅图像:

作者创建的嵌入

虹膜数据

用于学习和基准标记分类模型的流行数据集是 Iris flowers 数据集,该分类模型是基于表格数据训练的。为了访问 Iris 数据集,我们从 datasets 模块导入 load_iris 方法。与 MNIST 类似,我们可以调用 load_iris 方法,并将返回值存储在一个名为 iris_data 的变量中:

作者创建的嵌入

我们可以用 Matplotlib 中的散点图来显示目标:

作者创建的嵌入

回归数据集

糖尿病数据集

另一个流行的数据集是糖尿病数据集。该数据集最常用于回归任务。它包含诊断测量的特征,如胰岛素水平、葡萄糖水平和身体质量指数,可用于预测患者是否患有糖尿病。

与前面的数据集类似,我们从 datasets 模块导入 load_diabetes 方法,我们可以调用该方法并将数据存储在名为 diabetes_data 的变量中。我们还将为参数 as_frame 传入值“True ”,这使得 load_diabetes 在被调用时返回一个数据帧:

作者创建的嵌入

我们还可以从糖尿病数据中生成一些散点图:

作者创建的嵌入

Keras 数据集

接下来,我们将看看如何通过 Keras API 访问玩具图像分类数据集。让我们从导入 Keras 开始:

作者创建的嵌入

时尚 MNIST

Keras 为 MNIST 数据集提供了另一种选择,称为时尚 MNIST。它包含几个时尚类别的图像。与 Scikit-learn 类似,Keras 有一个数据集模块,允许您访问这些数据集。让我们从 dataset 模块访问 fashion_mnist 数据,并在 fashion_mnist 类上调用 load_data 方法:

作者创建的嵌入

我们还可以轻松地解开这些数据中的训练集和测试集:

作者创建的嵌入

生成可视化效果非常简单:

作者创建的嵌入

CIFAR100

最后,CIFAR100 数据集是另一个流行的图像分类数据集。与时尚 MNSIT 类似,我们可以从数据集模块访问 CIFAR100:

作者创建的嵌入

打开数据包装:

作者创建的嵌入

并生成可视化效果:

作者创建的嵌入

这篇文章中使用的代码可以在 GitHub 上获得。

结论

在这篇文章中,我们学习了如何使用 Scikit-learn 和 Keras 访问公开的玩具数据集。玩具数据集对于教育和研究是必不可少的。由于玩具数据通常是干净的、结构化的和易于访问的,因此它对于教授机器学习和数据科学的基本概念非常有用,而不必担心数据准备的问题。这包括围绕数据清理、异常值去除和结构化数据的复杂性。此外,出于同样的原因,在开发新的机器学习算法时,玩具数据集也可用于研究基准。无论您是第一次学习机器学习概念的学生,还是开发新算法的经验丰富的研究人员,了解可用于分类和回归任务的玩具数据集都是至关重要的。

新数据科学职位前 3 个月的 5 大建议

原文:https://towardsdatascience.com/top-5-bits-of-advice-for-the-first-3-months-in-your-new-data-science-role-a93d1fe91a7f

充分利用你的新数据科学家职位

布拉登·科拉姆在 Unsplash 拍摄的照片

S 开始一份数据科学家的新工作是你职业生涯中伟大的下一步。新的团队,新的经理,新的数据(希望有),新的挑战和机遇。在与同事和朋友讨论了前三个月最重要的建议后(感谢所有的投入!),就想出了这篇文章。

这样做的目的不仅是帮助你在新职位的前三个月里游刃有余,还能帮助你为快节奏的职业生涯打下基础。

所以,即使你不在一个新的岗位上,我相信这个建议无论如何都会帮助你,让你最大限度地利用你的现状。

#1 了解同事和利益相关者

第一天最常见的做法是了解你的团队成员。你可能会从一张桌子走到另一张桌子去打招呼,并在你的第一次团队会议上进行详细的介绍。除此之外,我建议与你的团队成员安排 30 分钟的一对一会议。这有助于你更好地理解他们面临的挑战,他们对你的角色的期望,以及对他们来说什么是重要的。这些会议的目的是倾听 T21 的意见并做笔记。你通常已经介绍过自己,所以这都是为了更好地了解你的同事。

你可以问的问题:

  • 你的背景是什么?
  • 你目前正在做的项目是什么?
  • 最大的挑战是什么,为什么?
  • 你感兴趣的数据(科学)/科技话题有哪些?
  • 正在使用哪些工具/软件/框架?
  • 我们和其他部门的关系如何?
  • 如果你是我,你会关注什么?
  • 你对我的角色有什么期望?
  • 在一起工作时,对你来说什么是重要的?

你通常也会和类似的团队在一个水平层次上一起工作。因此,安排与他们的会面也是有意义的。这些会议不仅能帮助你更好地了解情况,还能发出正确积极的政治信号。

第一次垂直 1:1 会议很可能是和你的经理。确保你和他/她经常见面是很重要的,尤其是在最初的三个月。这有助于你参与进来,保持在正确的轨道上,并明确期望。我们将在第四点中对此进行更深入的探讨。

除了你的老板,还有很多(非技术)利益相关者。与他们会面不仅有助于你更好地了解公司的战略和 T2 的政治形势,还能让他们了解你。

在这些会议中你可以问的问题有:

  • 你的背景是什么?
  • 组织面临的最大挑战是什么?
  • 你对我们的团队/单位有什么期望?

这些会议也有助于你找到未来的导师或看门人。一个重要的利益相关者群体还没有被提及:业务。作为一名数据科学家,你的工作是创造商业价值。您通常要么咨询业务,要么研究能为业务带来价值的数据产品。了解你的(内部)客户、他们的(真实)需求和期望至关重要。你应该利用第一次会面来了解对方,谈论期望和挑战。在接下来的几周里,你还应该关注敏锐的商业知识。我们将在第 3 点中讨论这一部分。

#2 尽快爬上学习曲线

在与你的经理和同事进行第一次一对一会谈后,尽快熟悉数据、用过的技术和当前的项目是很重要的。主动是关键。如果您在创建环境方面有任何问题或需要帮助,请联系同事或与他们安排会议。如果你不完全理解一个缩写或者一个项目的目的/方法,就问。在最初的几个月里,没有人会因为你不知道一些只有内部人员才能知道的事情而责备你。在德国,我们有“保护小狗”的说法。每个人都知道你是新来的,所以没有人会责怪你——至少在最初的几个月。后来,人们可能会说“已经六个月了——你应该知道的”。

在对所使用的技术和项目更加熟悉之后,你可能会意识到你还有一些差距。在前三个月内,集中精力填补这些空白。您通常会在网上找到许多围绕任何数据科学相关主题的资源和培训。

#3 敏锐的商业知识

如前所述,业务或领域知识是必不可少的。你的目标是为企业带来价值。要做到这一点,你首先要了解业务。安排与客户的会面,以便更好地了解他们的业务如何收集数据、他们的需求是什么。此外,询问他们如何衡量他们的成功(例如,使用什么 KPI)。

请记住,他们所说的和他们想要的可能有差异。根据您的团队和职位,您可能会有专门面对客户的人。无论如何,在最初的几个月里获得第一手信息是有益的。所以至少要参加客户和你的团队之间的会议。但是没有人会责怪你和你的客户建立 1:1 的关系。

#4 与老板和利益相关者的期望一致

你的经理是决定你在公司的奖金和未来的人。对于中长期的未来,其他因素和联系可能更重要,但让我们专注于前三个月。

为了与你的经理建立成功的关系,让他们能够信任你以及你专注并执行正确的事情对他们来说很重要。紧密合作、期望管理和积极主动是关键。

让我们简短而精确:

  • 与您的经理进行频繁的一对一会谈,每周一次到两次。
  • 关注 1:1 会谈中最重要的几点,以及你的老板可以如何提供帮助
  • 不要只谈论问题,也要谈论成就
  • 尽早并经常阐明期望
  • 协商诊断和行动计划的时间表
  • 不要让自己马上陷入救火中——先弄清楚状况

大部分要点也可以在与利益相关方合作时使用。始终确保您和您的利益相关者之间的每一项决策和协调都与您的经理保持一致。

#5 确保早期胜利——摘下唾手可得的果实

最后但同样重要的是,我最喜欢的建议。安全早胜。重要的是在最初的几个月里显示出你是最适合这个角色的,并且是一个启动者。争取在对你的经理和利益相关者(你的老板尊重他们的意见)重要的领域尽早取得成功。

然而,确保这些事情是可行的,现实的。你的外部依赖越多,不能及时完成任务的风险就越大。我打赌你知道下面的影响和复杂性图表(图 1。).

图一。价值-复杂性矩阵(图片由作者提供)。

明智的做法是拿起低垂的果实来确保这些早期的胜利。影响大且相对容易完成的任务。在你“收获”果实后,确保让你的经理和利益相关者知道你的成就。换句话说,做好事并谈论它。这有助于你获得可见性。说到可见性,确保能够访问所有相关的数据源。这有助于您稍后回答业务问题、启动新项目和监督数据环境。

这些是我对你作为数据科学家职业生涯前三个月的 5 条建议。由于数据科学家一词被理解为意味着许多事情,因此提到的一些要点可能并不完全适合您的情况。然而,我希望这些提示对你的新职位有所帮助。

每个数据分析师都应该拥有的 5 大书签

原文:https://towardsdatascience.com/top-5-bookmarks-every-data-analyst-should-have-547a2c9ad1fe

节省您时间和精力的在线工具

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

作为一名高级数据分析师,我的工作通常包括一两个大型底层数据研究项目,以及分散在不同团队中的“时间敏感型”小型项目。在一个典型的星期里,我可能会制作 5-7 个图表,编写一些查询,再调整一些,并帮助一个同事调试他们的。我可能会张贴 1 或 2 张 JIRA 内部门票,并执行一些 StackOverflow 搜索。

主要的潜在问题是,有了这些次要的干扰,我离脱离手头更大的任务只有一步之遥了。这就是为什么最好的分析师是敏捷和快速的。他们逆来顺受,很快就解决了琐碎的工作。

事实是,成为一名优秀的分析师就是要平衡质量和速度。这表现在寻找好的工具来帮助你更有效率。在那一周,我可能会使用半打不同的工具和软件。如果有一件事分析师们都同意,那就是没有一个单一的工具可以做所有伟大的事情。这就是为什么我给年轻分析师的最大建议之一是开始收集在线书签。养成导出这些书签的习惯,这样当你换工作或升级电脑时就可以随身携带。

以下是每个分析师都应该拥有的 5 大书签。有些在日常生活中很有用,而有些则是在特定情况下很少使用的。然而,你可能有一天会需要它们,当你需要的时候——它会帮你省去很多麻烦和时间。

#5 Ascii 表格格式化程序

表格格式化程序允许您将复制/粘贴的数据块转换为更高效、更美观的格式。这在许多不同的方面都会派上用场。有时候我会通过 Slack 或者 email 给同事发一个快表;其他时候,我会将数据粘贴到 JIRA 的机票上。此外,表格格式化程序对于在论坛中发布或回答问题非常有用,比如堆栈溢出,或者在博客中发布数据。诀窍是选择一个像 Courier New 这样的等宽字体来正确排列。

https://ozh.github.io/ascii-tables/

//================\\
|| Useful For...  ||
|]================[|
|| Slack          ||
|| Email          ||
|| JIRA tickets   ||
|| Stack Overflow ||
|| Code Comments  ||
|| Blogging       ||
\\================//

有很多选择,但我最喜欢的是 https://ozh.github.io/ascii-tables/。它快速、简单,并且对于输出格式有很多不同的选择。此外,Ascii 表格式化程序将自动转换文本,而不必单击任何东西;就是瞬间!

以下是几个不同的例子:

第四名 SQL 美化者

有两种类型的 SQL 作者——一种以自己的查询为傲,并将其格式化以便于阅读,另一种喜欢看着世界毁灭。无论你想格式化别人的混乱还是你自己的——SQL 美化器是必不可少的。

下一次,当您发现自己试图破译类似这样的查询时:

使用 SQL 美化器立即使它看起来像这样:

在可下载程序、插件和在线版本的形式中,有很多选择。我更喜欢网络版,这里:【https://codebeautify.org/sqlformatter】T2。

#3 JSON 查看器和转换器

我尽量避免使用 JSON 数据,但不幸的是,有时候,我别无选择。这就是为什么我在书签中保留了各种各样的 JSON 相关的查看器和转换器。

想快速浏览一个 JSON 结构,看看有哪些元素可用?需要调试解析脚本失败的原因吗?然后我推荐使用 https://www.convertcsv.com/json-to-csv.htmhttps://www.convertcsv.com/csv-to-json.htm来实现表格和 JSON 结构之间的转换,使用 http://jsonviewer.stack.hu/来解析和查看。

#2 图表构建者

构建可视化和仪表板是分析师工作的重要部分。不幸的是,我估计我制作的大约 80%的图表实际上不是为了仪表板,而是为了回答快速的、特别的问题。启动一个专门的应用程序,比如 Tableau,或者摆弄 Excel,对于很多这样的任务来说都是多余的。相反,我需要可以快速建立图表的东西。

有很多在线资源可以用来构建快速图表,但是 https://app.rawgraphs.io/是我最喜欢的。我喜欢它,因为它有各种不太为人所知的图表类型(如日历热图和圆圈包装),否则在 Excel 中要花很长时间才能弄清楚。

https://app.rawgraphs.io/

#1 SQL 生成器

大多数分析师实际上并没有记住天底下每一种转换的语法。更确切地说,大多数人会回忆起以前做过类似事情的查询,他们会在他们的文件夹Untitled1.sqlUntitled2.sqlCopy of RevenueQuery_final_final_final(3).sql中挖掘,直到找到为止。或者,谷歌也可以来帮忙,但这需要花费大量的时间在论坛或教程中找到正确的问题和正确的语法。

相反,给自己标上一个好的 SQL 生成器。SQL 生成器基本上是一个 SQL 查询的模板,它允许您定制列名和表结构,选择想要执行的操作,然后它为您构造各种不同“风格”的 SQL 语法。

再也不要强调DATEDIFF()DATE_DIFF()之间的细微差别了!我推荐这款:https://app.rasgoml.com/sql

结论

事实是,作为一名分析师,平衡质量和速度至关重要。拥有一个可以帮助你在不牺牲质量的情况下偷工减料的工具包是提高效率的一种方法。如果您目前还没有“工具”的书签文件夹,希望本文能给您一个好的起点!

其他人呢?你有我错过的书签吗?

社区建议

面向数据科学家的 5 大浏览器扩展

原文:https://towardsdatascience.com/top-5-browser-extensions-for-data-scientists-17a0195ca26f

这些扩展将极大地帮助您的工作

格伦·卡斯滕斯-彼得斯在 Unsplash 上拍摄的照片

大多数数据科学家的工作都是通过 Jupyter Notebook 或现代其他类似的基于浏览器的笔记本在我们的浏览器中完成的。有些部分的工作可以在浏览器之外完成,但是我们不断回到基于浏览器的笔记本。

因为我们大部分时间都在使用互联网浏览器,所以我想介绍一下我的顶级浏览器扩展,它们可以帮助数据科学家工作。扩展是什么?让我们开始吧!

1.Diigo

Diigo 是一个浏览器扩展,可以在不快速离开页面的情况下给网页添加书签和注释。Diigo 对于数据科学家来说非常有用,可以记录所有的学习材料和研究参考资料,以备将来使用。

对于 Diigo,有几个特性对于数据科学家来说非常重要:

  1. 书签 —收集网站页面

作者图片

2.标记 —标记收藏

作者图片

3.高亮显示 —高亮显示网页

作者图片

作者图片

4.便笺 —在网页上添加便笺

作者图片

  1. Outliners —根据我们的需要构建研究材料

作者图片

6.小组 —与同事分享材料

作者图片

您还可以使用高级功能,尤其是归档网页功能,但是所有主要的 Diigo 功能对于高效工作已经足够了。

2.催化 x

catalzex是一个浏览器扩展,用于自动查找 AI/ML 论文中实现的代码。这些扩展可以直接用于研究论文或谷歌搜索结果。

例如,如果我试图找到一篇“神经网络 GAN 论文”,扩展会自动找到代码实现(通常,它会将您带到 GitHub 页面)。

作者图片

如果我尝试按下 CODE 按钮,它会把我带到存储代码的 GitHub 页面。

作者图片

作者图片

与 Google 的结果相似,当我们阅读研究论文时,CatalyzeX 扩展也可以工作。

作者图片

甚至是谷歌学术的页面。

作者图片

最后,你可以访问 CatalyzeX 找到你需要的人工智能/人工智能研究论文。

总的来说,扩展允许我们数据科学家快速研究代码实现,这样我们就可以专注于我们的工作。

3.八叉树

Octotree 是一个浏览器扩展,专门用于简化 GitHub 上的代码探索。当你打开 GitHub 页面时,这个扩展会自动工作,并出现在页面上。

作者图片

扩展功能简单;它将采用当前的 GitHub 页面,并创建一个有见地的树状结构,供我们快速浏览。

作者图片

有了 Octotree,我们可以立即知道代码结构,并能够很容易地找到所需的代码。此外,Octotree 还提供了一些附加功能,包括:

  1. 轻松显示分支和标签

作者图片

2.拉请求查看器

作者图片

3.GitHub 页面书签

作者图片

总的来说,Octotree 对数据科学家来说是有价值的,因为它允许我们快速理解 GitHub 页面,尤其是代码实现。

4.在 Colab 中打开

Open in Colab 是一个简单的浏览器扩展,可以直接在谷歌协作笔记本上打开 GitHub 中托管的笔记本文件。

通常,如果我们想试用 GitHub 页面中的笔记本文件,需要下载它,但是使用 Colab 扩展中的 Open,我们不需要这样做。让我们通过使用这个笔记本文件来尝试一个简单的例子。

作者图片

只需点击一下扩展,笔记本就可以在在线谷歌实验室中使用了。

作者图片

有了这个简单的扩展,您将无需担心测试各种笔记本示例或研究实现。

5.BibItNow!

BibItNow 是一个浏览器扩展,可以方便地引用各种格式的研究论文。这个扩展是为那些每天需要引用大量论文的数据科学家设计的。

使用该扩展,当我们打开研究论文网页或 pdf 时,我们会自动获得引用。

作者图片

还有一种变体格式可供您选择。例如,我选择 Bibtex 格式。

作者图片

当你需要更高级的格式时,可以选择你需要的引文。

作者图片

总的来说,BibItNow 是一个简单的浏览器扩展,但对于阅读大量论文的数据科学家来说很有价值。

结论

现代数据科学家的工作现在与作为工作工具的浏览器密切相关。在这篇文章中,我展示了我的 5 大浏览器扩展来改进数据科学家的工作。它们是:

  1. Diigo
  2. 催化 x
  3. 八叉树
  4. 在 Colab 中打开
  5. BibItNow

希望有帮助!

访问我的 社交媒体进行更深入的交谈或有任何问题。

如果您不是作为中等会员订阅,请考虑通过 我的推荐 订阅。

五大数据架构趋势(以及它们对您的意义)

原文:https://towardsdatascience.com/top-5-data-architecture-trends-and-what-they-mean-for-you-ef7c07bfa755

这只是炒作,还是也有学问?

斯蒂芬·道森在 Unsplash 上拍摄的照片

我记得四年前为一个客户开发了一个新的数据管理策略,重点是他们现有的治理、层次结构和本地数据堆栈。尽管该战略已经像美酒一样陈年,但一些要素和假设已被证明是不正确的。

稳健策略的关键是避免追逐下一个闪亮的目标。一个好战略的复合效应只有在单调重复地实施之后才会显现。所以不要放弃。事情成形需要时间。

现在—如果您正在基于新的数据堆栈、新的假设和潜在的新领导创建新的战略,您应该注意什么样的趋势?

我们来详细看看这些。

1。数据质量&可观察性

自从有数据以来,数据质量问题就一直存在。DQ 经历了几个阶段的改善,IT 监管减少,企业所有权增加。然而,DQ 仍然是所有战略计划中的头号问题。

不能把 DQ 丢在一边或忘记它;糟糕的数据会困扰你。以前,DQ 分为两个核心类别:技术和商业。前者主要解决与较差的源数据、设计不佳的管道和未管理的协调相关的 DQ 问题。相比之下,后者将确保符合业务 DQ 规则,如信息的准确性、给定时间范围内的唯一性等。

数据可观察性是从软件工程的角度看待数据的一种新方式。它正试图整合技术性的 DQ 检查,并引入更独特的数据管理方式,以减轻 DQ 商业检查的负担。这是一个受欢迎的变化,因为依赖业务用户解决问题需要宝贵的时间和精力,更好地投资于决策。

这会对您的战略产生怎样的影响?

如果您正在进行战略性数据转换计划,请查看您的现任供应商/销售商/内部团队是否正在整合数据可观察性检查(可能使用不同的名称)。如果不是,考虑提议对数据完整性、唯一性和准确性进行基本检查。还提出了一些自动化的解决方案,如分类,自愈管道等。

https://medium.com/geekculture/how-data-quality-is-being-subsumed-by-data-observability-ea7e17b4e46a

2.数据产品&作为产品的数据

长期以来,我们一直将数据视为一种资产,而这种资产的实施一直充满挑战。你如何定义资产?谁管理它?他们如何管理它等等。数据产品现在就是建立在这种思想之上的。

数据产品不同于数据资产方法,因为后者主要是数据的逻辑分离。你不能根据代码、表格、ETL 等来量化数据资产。当人们问“那么,你到底指的是数据的哪一部分?”这样的问题时,他们很难理解。

数据产品是提供最终结果的实际有形的东西。它可以是 board metrics/KPI,数据仓库中销售数据的组合,以及产品目录。

另一方面,作为产品的数据支持围绕数据产品的流程和技术。迷惑?让我解释一下。拥有董事会指标是一种数据产品;你如何存储、编码、分发、购买、销售等。将该数据产品视为产品。实施数据产品市场是实现这一目标的一种方式。

这将如何影响你的战略?

要将数据视为一种产品,您需要满足特定的基本数据管理和基础架构要求。如果你对某样东西不够信任,你就不能生产它。实施可靠的数据质量框架以及数据接收和保留框架等,将有助于确保您能够在组织中真正将数据作为产品进行营销。

3.活动元数据

我已经记不清我坐过的许多开始谈论活动元数据的供应商演示文稿了。历史上,我们将元数据用于下游目的;然而,它没有一个足够吸引人的名字。现在—用于做出某些决策的元数据是实现成熟数据平台的一个重要趋势。

例如,个人身份信息(PII)等元数据,在用于分析目的时,这些元数据会自动用于屏蔽客户数据。另一种方法是使用 PII 标签来限制访问。另一种方法是帮助提醒最终用户潜在的 DQ 问题。

这将如何影响你的战略?

你可能已经在用不同的名字做类似的事情了。如果您不是,这是一个真正的游戏规则改变者,自动标记 DQ 问题,对问题解决方案进行分类,并根据隐私和数据分类标记采取行动,可以在您的数据管理空间中创建一个顺畅的工作流。在隐私等重点领域小规模实施,这将在自动化节约和法规遵从性方面带来回报。

4.数据组合性

可组合性是我们从我们的系统设计朋友那里借鉴来的一种趋势。虽然在 Web3 世界中相当夸张,但是可组合性可以应用到我们开发数据解决方案的方式中。我所知道的每个组织都使用多种数据工具来实现最终结果,包括数据存储层、数据传输工具、数据可视化工具、数据分发和保护工具等。

来自 cdixon 的 tweet on web 3 Composability

想象一下,您拥有数据解决方案的核心模块化包,包括您的代码、逻辑和实际数据。最终用户可以重用这个包来得出一些决策,而不必从头开始重新构建一切。无许可创新是 Web3 的关键,但组织也可以利用这一趋势,允许他们的最终用户创新,帮助趋势 5。

我认为可组合性高于可重用性,因为重用组件意味着您对特定信息的解释与该组件的作者相同。可组合性让你“像艺术家一样偷窃”并允许灵活地使用他人的前期工作来改进你的决策。

这将如何影响你的战略?

可组合性与数据产品方法密切相关;您希望避免让每个团队创建相同数据的不同版本来回答类似的问题。您还希望确保数据堆栈中新工具的引入是易于打包的,以便可以对它们进行组合。无法打包或合成的内容将需要额外的应用程序管理开销,因此可能不会列入候选名单。

5.数据民主化

所以,我知道我没有谈到数据网格。但是网格的核心概念已经被诸如数据产品/可观察性等个人趋势所覆盖。数据民主化是一种结果,而不是一种架构趋势。向最终用户提供数据以帮助他们做出决策是双赢的。

但是,没有适当的控制和治理的数据民主化也是一个灾难的处方。趋势 1–4 有助于确保趋势 5 的结果是成功的。拥有正确质量的数据确保了足够的数据可组合性,而实现活动元数据实践确保了对数据分发和管理的限制。发布和订阅数据产品将为数据民主化带来强大的运营模式。

这将如何影响你的战略?

不要只谈论数据民主化;写下你的章程(操作模型),以确保数据以受控的方式被访问。实施流程,推出关于如何实现数据民主化的沟通和培训计划。如果你的策略目前只关注技术团队,想想如何满足业务终端用户?

结论

数据领域目前有很多炒作/趋势;把杂草从谷壳中分离出来变得很困难。我用来判断趋势是否有用的一件事是它是否有助于移动指针。这种趋势是否有助于你更快地走向市场?帮助你变得更有效率?使您能够降低核心风险?如果是这样的话,那么这个趋势是值得推行的。

如果这引起了你的共鸣,请在下面留下评论来分享你的想法。想了解如何改善数据的健康状况吗?查看这篇文章:

如果您没有订阅 Medium,请考虑使用我的推荐链接订阅。它比网飞便宜,而且客观上能更好地利用你的时间。如果你使用我的链接,我会获得一小笔佣金,而你可以在 Medium 上获得无限的故事。

我也定期在推特上写东西;跟着我这里

撰写优秀数据科学简历的五大常见问题

原文:https://towardsdatascience.com/top-5-faqs-on-writing-a-great-data-science-resume-a439cbc75289

撰写 DS/ML 简历最常见问题的答案

图一。克里斯蒂娜@ wocintechchat.com 在 Unsplash 上的照片

以下是我在撰写数据科学简历时收到的一些最常见的问题。所提供的建议将帮助你调整你的简历,使之更好地符合一系列工作要求,并更经常地通过最初的简历筛选。

下面的建议帮助我整理了一份简明的简历,这份简历是为我申请的每个职位定制的,并且随着时间的推移增加了我收到的回电数量。

我的简历可以有多长?我应该如何组织我的简历?

平均来说,一个招聘人员在一份简历上花费 7 秒钟。这意味着你需要把你的简历精简到与招聘人员最相关的数据点。因此,最好把你的简历控制在一页以内。

在组织你的简历时,要让招聘人员容易理解。这意味着使用一种通用的、易于阅读的格式。常见的如下图。

图二。作者图片

需要注意的一些建议是

  • 避免多列格式。
  • 按时间顺序写。如果你目前是研究生,教育应该是第一部分。如果你目前正在工作,把工作经验放在第一位,教育放在第二位。
  • 突出显示您的联系方式。在这种格式中,它位于名称标题的正下方。
  • 突出你每一次工作经历的开始和结束时间。大多数角色都需要工作经验,计算你在这个领域的经验应该很容易。
  • 保留一个技能部分,这有助于记下你熟悉的 DS/ML 角色中使用的编程语言和框架。当简历被 ATS(申请跟踪系统)自动处理时,这些也可以作为关键词。ATS 识别的关键词越多,人们查看你简历的机会就越大。

我应该如何写我的项目?我应该在我的项目描述中提到技术栈吗?

当写项目的时候,坚持一个版本的星形格式。这意味着提及—你着手解决什么问题(情况),你建立了什么模型/解决方案(任务&行动),以及应该产生可量化影响的结果是什么(结果)。下面是一个例子。

图三。作者图片

一个常见的建议是每个要点以一个动作词开始,并确保一个要点不超过两行。

关于提到技术栈,如果细节可以编织到项目描述中,那么保留它们(如图 3 所示)。否则,我不建议利用简历中有限的空间列出每个项目的技术堆栈(你可以在技能部分列出你熟悉的所有语言和工具)。

我应该在简历中加入哪些项目来破解 DS 角色?我应该在简历中喊出哪些技术技能?

要编写的项目将取决于工作角色描述。

  • 如果职位描述是一般性的(例如,仅仅提到使用数据向企业推荐解决方案),那么你的简历也要保持一般性。试着在诸如 NLP、CV、推荐等领域提及项目。试着提及对框架的熟悉——包括开发 ML 解决方案(PyTorch、TensorFlow、Sklearn 等)。)并部署它们(AWS、ML Pigeon 等。).
  • 如果角色描述很具体,就根据它来定制你的项目和简历。例如,对于以 NLP 为中心的角色,确保您的 NLP 项目是前期的。是的,这意味着你不能只有一份简历!理想情况下,有一个列出多个项目的文档。然后,根据角色描述,你应该找出与角色最相关的项目,并制作一份简历。

技能也取决于角色描述。

因此,除非你有明确的研究倾向,否则最好在 DS 应用领域积累经验。这有助于你建立一个广泛的工作组合,你可以利用它来申请不同的角色,最大限度地增加你被选中的机会。

论文/专利是否应该在简历上提及?

这要看你瞄准的角色。某些数据科学角色以研究为中心。在这种情况下,提及论文/专利是相关的,应该突出/详细说明。

另一方面,某些角色更面向产品。在这些情况下,最好强调正在解决的最终客户问题。如果这个项目导致了一项专利/论文,只需在最后链接它,如图 3 所示。

我应该在简历中强调软技能/课外活动/奖项之类的东西吗?

让我们一个一个地考虑这些

  • 软技能——对于大多数面向行业的角色来说,领导能力、解决问题能力、谈判能力等技能都是有价值的。鼓励在简历中使用这些词语。
  • 课外活动通常不会给招聘决定增加多少价值。某些角色,如俱乐部领导、主持研讨会等。被正面看待。然而,这些应该是非常低的优先级。只有在提到你的项目后,你的简历上还有空间的时候,才提到它们。
  • 奖励——研究资助/奖励与以研究为导向的角色相关。否则,奖励/荣誉应该再次处于低优先级。只有在提到你的项目后,你的简历上还有空间的时候,才提到它们。

外卖食品

要记住的主要事情是

  • 使用易于阅读的简历格式
  • 根据你申请的职位,突出并重新安排你的内容
  • 确保你有足够的相关关键词来确保你的简历通过 ATS 的筛选。

面向数据科学家的五大 Python 编程书籍

原文:https://towardsdatascience.com/top-5-python-programming-books-for-data-scientists-af6caf4ff7b

让您的职业生涯更上一层楼的绝佳资源

照片由 refargotohpUnsplash 上拍摄

从基础统计学到高级计算机科学家使用的复杂数据集,数据科学已经在每个行业的图表中上升。前几年,所有人都认为数据只是一个晦涩的话题,需要科技行业的专业人士掌握。现在,数据无处不在。从购买超级碗球票到麦当劳的汉堡,再到员工工资单,我们每天都要向庞大的计算机智能数据库输入数据点。

在数据科学领域取得成功所需的基准之一是 Python 知识。编程语言因其出色的库、交互式社区、干净的数据集和高度的通用性而成为数据专业人员最青睐的语言。Python 已经成为数据行业的中流砥柱。

数据科学家可以在几乎任何领域使用 python,例如人工智能、机器学习、大数据、服务器端开发、自动化等等。

你可能会问,作为一个数据科学初学者真的有必要掌握 python 吗?

是的。

数据科学的早期阶段是获取尽可能多的有价值资源的最佳时机,这些资源将有助于您未来的分析。将 python 排除在框架之外并不是一个好主意。

Python 开始于 1991 年,作为基本 web 开发的脚本解决方案,但现在 python 是整个数据科学背后的驱动语言。

就我个人而言,在我开始接触数据的时候,书籍给了我很大的帮助。我选择了五本必不可少的书来帮助你开始使用 Python 在数据领域的职业生涯。其中一些是我个人的最爱,对新人和专业人士都适用。

1。Basant Agarwal 博士用 Python 实践数据结构和算法。

数据结构是分析数据时的关键组成部分。它们在解决许多问题方面是通用的,就像可重用的代码一样,并允许您成功地使用、存储和安排数据。数据结构有时很棘手——它们在数据分析中几乎扮演任何角色——大多数专业人员经常试图为大量数据集找到一个合适的数据结构。

这是本书的主要目的之一:帮助你探索并理解 python 数据结构的分析和设计。

在阅读完"用 Python 实践数据结构和算法"之后,你将能够开发复杂的数据结构、合并算法、排序插入、实践概念,如大 O 符号、哈希表、堆栈和队列、算法设计、建模等等。

从个人的角度来看,除了模型拟合,数据结构是那些一开始你并没有真正掌握概念的主题之一。不要着急。这本书有 400 页长,一点一点地读,确保在进入下一章之前,你能够理解并操作每一章。当你熟悉 Python 中的数据结构和算法时,它会彻底改变游戏规则。

2。Python 机器学习导论:数据科学家指南——Andreas c . müller 和 Sarah Guido。

当我开始我的数据科学生涯时,我浪费了很多时间来逃避编程。史上最糟糕的决定。几年前,当我最终决定将编程与数据结合起来时,我从 python 开始。《用 Python 进行机器学习入门》是我看的第一本书。从此就喜欢上了。

对于数据科学行业的专业人士来说,理解机器学习至关重要。构建数据集、开发和使用模型、利用框架以及管理数据库是使用数据的重要方面。这些方面大多是用机器学习的概念来设计和构建的。

这本书用 python 分解了机器学习的基础。因此,即使你以前没有 python 知识,你也会从书中解释的各种编程技术中受益匪浅。

3。数据科学的艺术——罗杰·d·彭和伊丽莎白·松井。

数据科学的艺术完全融入了数据科学的基础。它围绕数据分析的内部工作进行导航,如何找到数据,用数据讲述故事,并将其过滤成高效的结果。

大多数时候,数据并不需要一个优秀的数学家,它只需要一个善于讲故事的人。一个拥有正面沟通知识和良好 python 技能的数据科学家将能够探索任何数据池。

两位作者 Peng 和 Matsui 在管理数据项目以及培养业内最成功的数据专业人士方面都有着令人印象深刻的业绩。

在这本中,他们用自己的经验通过分析基本和复杂数据集的各种概念来指导初学者和高级学习者。

4.用 Python 自动化枯燥的东西:实用编程。

对于发现很难过渡到 python 的数据科学家和程序员来说,这是我最喜欢的选择。在它发布之前,许多专业人士表达了他们对一本书的强烈需求,这本书提供了与现实生活数据科学项目合作的纯粹实用的解决方案。

如果你是一个通过实时做事情来学习的人,这本就是为你准备的。

它将教你所有基本的实际操作,比如在网上丢弃数据、过滤数据集、添加到 XLS、解释数据库、模块选择和排序算法,所有这些都使用 python。

读完这本书后,强烈建议你继续学习作者在 Udemy 上创建的在线课程“用 Python 编程自动化枯燥的东西”。获得书中讨论的一些技巧的最新解决方案是一个好主意。

5。学习 Python,第五版——作者马克·卢茨。

从初学者到专业开发人员,马克·卢茨在他对 Python 的完整、基本的介绍中带着每个人。这是一本非常强大的,面向想要了解核心 Python 及其不同库的交互工作的数据科学家。

它涵盖了您需要了解的关于 Python 及其函数的重要内容。你将能够完成测验、练习和练习自我理解教程。它让您从 2.7 版本开始,然后过渡到 3.3。

适用的外卖

数据科学中的编程可能看起来是一项令人生畏的任务,但是使用像 Python 这样简单易学的语言,您就可以很好地掌握它。无论你是刚开始学习 python 的初学者,还是希望扩展知识的专业人士,这些书都会给你很大帮助。有些只有几页,有些则很长。没关系,只要确保你从每一章中获得最大价值。

2022 年你应该知道的五大 SQL 日期函数

原文:https://towardsdatascience.com/top-5-sql-date-functions-you-should-know-in-2022-2180328ab940

数据科学

掌握 SQL 日期时间函数,赢得数据科学面试

照片由本斯·巴拉-肖特纳Unsplash 拍摄

使用 SQL 节省时间!

在以数据为中心的世界中,使用时间戳将数据组织到毫秒级的细节。然而,这种详细程度并不总是有用的。相反,通常你只需要日期的一部分,比如年、月或日。

因此,了解从日期时间变量中提取所需数据的不同方法非常重要。

我在这里列出了 5 个最有用的 SQL 函数和例子,以帮助您理解日期-时间数据操作和分析。

我把这篇文章写得很短,这样你就可以很快地完成它,掌握那些必须知道的、赢得面试的 SQL 技巧。🏆

您可以使用此索引快速导航到您最喜欢的部分。

**·** [**DATE and TIME function**](#dad0) **·** [**EXTRACT()**](#2d4e) **·** [**DATEDIFF()**](#0f53) **·** [**TIMESTAMPDIFF()**](#e11d) **·** [**MONTHNAME() and DAYNAME()**](#7727)

📍注意:我使用的 MySQL Workbench &地震数据集来自ka gglepublicdataset&现在可以在我的 Github repo 上免费获得,并有 MIT 许可

我将使用的数据集如下所示..

地震数据集|作者图片

这是一个简单的 2000 x 7 数据集!

好了,我们开始吧…🚀

让我们从最简单的部分开始——从日期时间变量中提取日期和时间。

日期和时间功能

这个函数只从日期时间变量中提取日期。

如上图所示,日期列包含格式为**YYYY-MM-DD HH:MM:SS**的日期和时间,而您只想提取日期部分,即月、日和年。

对于这个问题,**DATE()**函数是最简单的解决方案。

SELECT Dates, **DATE(Dates)** as only_date
FROM sql_practice.earthquakes;

按作者从 SQL | Image 中的日期时间变量提取日期

同样,你也可以使用另一个有用的函数 **TIME()**只获取时间部分,即小时、分钟、秒

SELECT Dates, **TIME(Dates)** as only_time
FROM sql_practice.earthquakes;

按作者从 SQL | Image 中的日期时间列仅提取时间

嗯,正如它名字所暗示的,它非常简单和直接。

深入研究日期-时间数据,接下来让我们看看如何从日期中只提取日、月或任何其他部分。

提取()

它从给定的日期时间值中提取部分日期。

在大多数访谈中,您会被要求按月或按周汇总数据,或者计算特定月份或季度的特定指标。💯

EXTRACT()是为提取日期的不同部分提供最大灵活性的函数。它有最简单的语法,

**EXTRACT(part_of_date, date-time column)**

到目前为止,MySQL 支持使用该函数提取以下类型的日期部分。

SELECT Dates AS given_date, 
       EXTRACT(**SECOND** FROM Dates) as seconds_value,
       EXTRACT(**MINUTE** FROM Dates) as minute_value,
       EXTRACT(**HOUR** FROM Dates) as hour_value,
       EXTRACT(**DAY** FROM Dates) as day_value,
       EXTRACT(**MONTH** FROM Dates) as month_value,
       EXTRACT(**YEAR** FROM Dates) as year_value,
       EXTRACT(**WEEK** FROM Dates) as week_value,
       EXTRACT(**QUARTER** FROM Dates) as quarter_value
FROM sql_practice.earthquakes
LIMIT 5;

使用 MySQL 中的 MySQL | Image by Author 提取日期部分

这样,您可以提取日期的基本和常用部分。MySQL 还支持其他不常见的日期部分组合,例如

SELECT Dates AS given_date, 
       EXTRACT(**YEAR_MONTH** FROM Dates) as year_month_value,
       EXTRACT(**DAY_HOUR** FROM Dates) as day_hour_value,
       EXTRACT(**HOUR_MINUTE** FROM Dates) as hour_minute_value,
       EXTRACT(**MINUTE_SECOND** FROM Dates) as minute_second_value
FROM sql_practice.earthquakes
LIMIT 5;

MySQL 摘录中的日期部分组合|作者图片

下面举个例子来了解一下EXTRACT()函数在实际中是如何使用的。

🔸假设,你想知道每次地震发生在一天中的什么时间。日期列的时间戳高达秒级。

在这里,你可以得到如下的时间。

SELECT Dates, 
       **EXTRACT(HOUR FROM Dates)** as hour_of_day
FROM sql_practice.earthquakes;

提取一天中的某个小时|作者图片

当您想要汇总每周、每月或每季度的数据或了解数据的每月、每年趋势时,通常会使用此函数。

🔸例如,您想获得 1965 年前三个月的每周地震总数。

SELECT **EXTRACT(WEEK FROM Dates)** as week_of_year,
       COUNT(DISTINCT ID) as number_of_earthquakes
FROM sql_practice.earthquakes
WHERE Type LIKE 'Earthquake'
AND **EXTRACT(MONTH FROM Dates)** < 4
AND **EXTRACT(YEAR FROM Dates)** = 1965
**GROUP BY EXTRACT(WEEK FROM Dates)**;

每周汇总|作者图片

如你所见,列由一年中的周数组成,最大地震发生在第五周。

这是理解如何提取日期的不同部分以及如何在WHEREGROUP BY子句中使用它们的经典示例。

这种类型的聚合问题经常在数据科学访谈中被问到。✅

接下来,有时您需要根据两个事件计时之间的差异来过滤时间戳数据。

DATEDIFF()

它实际上是比较这两个日期,并返回它们之间的天数差。

它需要两个参数,

DATE_DIFF(1st date, 2nd date)

举个例子,

SELECT **DATEDIFF('1965-02-28', '1965-01-01')** as DATEDIFF_output-- Output
**58**

DATEDIFF()中,第一个日期应该总是大于第二个日期。如果相反,输出将是负数。

🔸在另一个例子中,假设您想要查看今天(【2022 年 7 月 3 日)之前每场地震发生了多少天。为此,您可以使用另一个 MySQL 函数NOW(),它基本上以时间戳格式返回今天的日期。

SELECT Dates,
       **DATEDIFF(NOW(), Dates)** as DATEDIFF_Output
FROM sql_practice.earthquakes

SQL | Image 中的 DATEDIFF(按作者)

嗯,这两个日期之间的差异以天数的形式返回,这对您来说可能太细了,因为DATEDIFF()没有提供日期部分的灵活性,比如以月或年的形式获得两个日期之间的差异。

这就是下一个功能出现的时候。

TIMESTAMPDIFF()

它提供了部分日期的灵活性,并让您在日、周、月、季度和年的两个日期之间有所不同。💯

它的语法略有不同,如下所示:

**TIMESTAMPDIFF(part of date, 1st date, 2nd date)**

其中,第一个日期应始终小于第二个日期,日期的一部分可以是日、月、年、周中的任何内容

因此,截止到DATEDIFF()的相同查询可以重写为:

SELECT Dates,
       **TIMESTAMPDIFF(YEAR ,Dates, NOW())** as TIMESTAMPDIFF_Output
FROM sql_practice.earthquakes

MySQL 中的 timestamp diff |作者图片

现在,今天和日期之间的差值以年数返回。

🔸让我们举一个实际的例子—您想要查看从 1965 年 1 月 2 日起 10 天内发生的所有震级超过 6 级的地震。

SELECT ID,
       Latitude,
       Longitude,
       Magnitude,
       Dates
FROM sql_practice.earthquakes
WHERE Type LIKE 'Earthquake'
AND Magnitude > 6
AND Dates >= '1965-01-02'
AND **TIMESTAMPDIFF(DAY, '1965-01-02', Dates) <= 10**;

过滤 X 天内发生的日期|按作者分类的图片

正如你在上面的图片中看到的,两次地震的日期都是 1 月 5 日和 10 日,距离 1 月 2 日不到 10 天。

根据包裹递送所用的时间选择记录,您需要找出运输日期和递送日期之间的差异

找出用户订阅特定服务的时间。

这些是一些现实生活中的使用案例和常见的数据科学面试问题,可以使用TIMESTAMPDIFF()DATEDIFF()解决。

🔸另一个关于DATEDIFFTIMESTAMPDIFF的有趣例子是—

温度上升 关于 Leetcode 的问题

您需要选择温度高于前一天的所有 id。问题的输入是一个简单的表格,如下所示,

**Input table name:** Weather
+----+------------+-------------+
| id | recordDate | temperature |
+----+------------+-------------+
| 1  | 2015-01-01 | 10          |
| 2  | 2015-01-02 | 25          |
| 3  | 2015-01-03 | 20          |
| 4  | 2015-01-04 | 30          |
+----+------------+-------------+

在我上一篇文章中提到,5 高级 SQL 查询 这个问题可以结合SELF JOINDATEDIFF()一起使用来解决。💯

-- **Query using DATEDIFF()**SELECT today.id FROM Weather AS today 
JOIN Weather AS yesterday
ON today.temperature > yesterday.temperature
AND **DATEDIFF(today.recordDate, yesterday.recordDate) = 1****-- Query using TIMESTAMPDIFF()**# Write your MySQL query statement below
SELECT today.id FROM Weather AS today 
JOIN Weather AS yesterday
ON today.temperature > yesterday.temperature
AND **TIMESTAMPDIFF(DAY, yesterday.recordDate, today.recordDate) = 1****Output:** 
+----+
| id |
+----+
| 2  |
| 4  |
+----+

注意TIMESTAMPDIFFDATEDIFF语法中提及日期值的顺序。

接下来,让我们看看如何获得日期和月份的名称,而不是它的编号。

月名()和日名()

顾名思义,MONTHNAME()返回月份名称,DAYNAME()返回给定日期的日期名称。

🔸例如,从 date 获取今天的日期和月份名称。

SELECT NOW() AS given_date,
       **MONTHNAME**(NOW()) AS month_name,
       **DAYNAME**(NOW()) AS day_name;

按作者获取 SQL | Image 中的日期和月份

当您需要按天或按月对列进行聚合,并且列中只有日期-时间值时,这很有用。

:函数**NOW()**YYYY-MM-DD HH:MM:SS格式返回当前日期和时间,可以在上图第一栏看到。

🔸例如,您想了解一周中哪一天发生的地震最多。

SELECT **DAYNAME(Dates) AS day_name**,
       COUNT(DISTINCT ID) AS number_of_earthquakes
FROM sql_practice.earthquakes
WHERE Type LIKE 'Earthquake'
**GROUP BY DAYNAME(Dates)**
ORDER BY number_of_earthquakes DESC;

按日期名称分组|按作者分组

这就是你如何找出周四发生地震的最大次数。你可以使用MONTHNAME()来获得类似的洞察力。

仅此而已!

我希望您能很快完成这篇文章,并发现它对在 SQL 中处理日期很有用。上面提到的函数涵盖了大量的操作,您将使用日期-时间值进行操作。

我在过去 3 年里一直在使用 SQL,我发现这些概念经常成为数据分析师和数据科学家职位的面试问题。这些功能在处理实际项目时也非常有用。

对阅读介质上的无限故事感兴趣??

💡考虑 成为媒体会员无限访问媒体上的故事和每日有趣的媒体文摘。我会得到你的费用的一小部分,没有额外的费用给你。

💡请务必 注册我的电子邮件列表 以免错过另一篇关于数据科学指南、技巧和提示、SQL 和 Python 的文章。

感谢您的阅读!

不确定接下来要读什么?我为你挑选了另一篇文章—

</5-advanced-sql-concepts-you-should-know-in-2022-b50efe6c99>

甚至更多的实用查询可以在这里查询,

</5-practical-sql-queries-you-should-know-in-2022-11b428560a30>

尽管如此,了解 SQL 的最佳实践还是很重要的!

</5-most-useful-sql-best-practices-you-should-follow-ef753a50ad26>

你的免费会员故事吗??

💡考虑 成为中等会员 继续阅读

值得关注的 6 大女性数据科学 YouTubers

原文:https://towardsdatascience.com/top-6-female-data-science-youtubers-to-watch-a3e921075bfa

这里有一些在数据科学领域工作的最优秀的 YouTubers 用户,可以了解更多关于科技行业和数据科学职业道路的信息

照片由耶稣爱奥斯丁Unsplash

虽然全国大约 55%的大学毕业生是女性,但只有 2/3 的人从事 STEM 相关领域的职业。根据 WEF、《全球性别差距报告》BCG Research 的各种调查,所有数据科学专业人士中只有 15%到 22%是女性。一个突出的原因是学习环境和社会信仰体系,尤其是从高中开始,会影响妇女的进步和职业选择。

作为一名计划追求数据科学的女性,意识到这些社会偏见,我有一个强烈的理由为什么喜欢记录和分享她们在 STEM 领域的经验的女性。它不仅展示了在这一领域取得成功的可能性,而且在追求 STEM 事业的整个过程中为女性提供了支持和动力。

这里列出了我最喜欢的 6 个数据科学 YouTubers,我发现自己作为一名学习数据科学的本科生经常回去看。他们都回答了关于数据科学领域的最常见问题,并提供了关于他们在工作中执行的任务和角色的信息。

1.差点成为天体物理学家

图片作者,主页几乎天体物理学家

Priya 毕业于 UChicago 大学,获得物理学学位,目前在一家被优步收购的科技初创公司工作。她在自己的频道上制作了许多教育视频,谈论大学指南、物理学、生活方式以及她目前作为数据科学家的经历。她有一个名为“数据生活✨”的播放列表💻“她讲述了自己的经历、技术角色/项目细节以及数据科学的面试流程。

2.阿纳斯塔西娅 K

图片由作者提供,安娜斯塔西娅 K 的主页

Anastasia 是 Spotify 的数据科学家,在瑞典工作,她制作的视频大多是关于生活方式、数据科学和技术的。你可以期待看到许多作为数据科学家的日常视频,统计数据,作为数据科学家利用你的工具,她成为数据科学家的故事,以及这个角色由什么组成。她的视频非常有助于了解数据科学家的日常生活,所以你肯定会更了解会发生什么。

3.蒂娜·黄

图片作者,主页蒂娜黄

Tina 是 FAANG 的一名数据科学家,她制作关于技术、职业、生产力和生活方式的视频。她讲述了她在 FAANG 担任数据科学家的经历,以及她是如何获得数据科学家职位的。她的生产力和自学视频通常与学习成为数据科学家密切相关,也适用于其他职业。虽然她最近辞去了在 FAANG 的工作,但她正在制作更多关于如何学习和成为数据科学家的视频,所以这些技术细节肯定会在你的旅程中帮助你,因为数据科学的一部分是自学和不断学习新事物。

4.巽他斯·哈立德

图片由作者提供, Sundas Khalid 主页

Sundas 是一名自学成才的数据科学家,在 FAANG 工作。她的所有视频都围绕着数据科学、技术和职业建议。她讲述了自己自学数据科学的过程,包括商业学位背景、技术面试以及你需要了解的关于数据科学的一切。Sundas 也有一个 Instagram 账户,她在那里定期分享职业、金融和数据科学方面的技巧,它是 STEM 中许多女性聚集和联系的一个伟大社区。

5.数据中的大坝

作者图片,数据中少女的主页

Data 中的 Damsel 以幽默、有趣的方式讲述了她的数据科学职业故事、数据科学采访以及您需要了解的关于数据科学的一切。她还制作视频,介绍有助于你成为数据科学家的资源以及数据科学行业本身。Data 中的 Damsel 也有一个 Instagram 账户,在那里她制作了许多与数据科学和在科技行业工作有关的有趣、精彩和信息丰富的卷轴。

6.卡西·科济尔科夫

作者图片,凯西·科济尔科夫主页

凯西是谷歌的首席决策科学家。她不是专门研究数据科学的 YouTuber 用户,但她制作了关于统计概念和机器学习的视频,这两者对数据科学都非常重要。她是一个彻底的讲师,让机器学习概念从根本上容易理解。看了她的视频后,我更加喜欢上了统计学,当我纠结于机器学习相关概念时,她是我的灵感和指导来源。

希望这些对你搜索数据科学家 YouTubers 有帮助!

如果你想了解更多关于我的信息,点击 这里 随时连接!

🫶🏽

将包含在您的下一个项目中的 7 大隐藏 API 宝石

原文:https://towardsdatascience.com/top-7-hidden-api-gems-to-include-in-your-next-project-548e66c34ff9

你可能从来没有听说过这些

JSON Server Kitty 来自维基共享| 知识共享 归因 2.0 通用

介绍

我们程序员有一种重新发明轮子的倾向。重新发明轮子能好玩吗?是的。它能教会你有价值的技能吗?是的。你应该总是写几千行代码来解决已经解决的问题吗?不要!

通过利用其他程序员编写的数十亿行代码来帮助你完成你的代码目标,来增强你自己的能力

想要生成随机图像吗?请,请不要创建另一个网络服务器来处理随机的图像请求。用一个代替几十个随机的镜像服务器。

查询随机的维基百科页面?不需要复杂的网页抓取,这个 API 已经覆盖了你。

这里有一些你应该在下一个项目中包含的最有趣、最有趣、最有用的 API。

1 —使用 arch🔎

这是 API 所能获得的最接近“谷歌搜索”的结果。usearch API 使用人工智能来检索查询的搜索结果。例如,你可以查询短语“泰勒·斯威夫特”,得到类似谷歌的关于泰勒·斯威夫特的链接页面。

usearch api 检索的屏幕截图。我再也不用谷歌网络抓取了!

你可以试试这里的。

2 —临时邮件📫

无论是处理垃圾邮件,免费试用,还是其他事情,我们都使用过临时电子邮件。这个 API 为您提供了一个接口来实现这一点,但是是以编程方式实现的。Tempmail 可以为您生成一个临时电子邮件地址列表。

在你的下一个项目中尝试 tempmail

3 —谷歌地图🏫

尽管谷歌的 API 被广泛使用,但 places API 似乎有点过时了。Places 返回关于“机构、地理位置和主要兴趣点”的信息例如,我将 Places Search API 用于一个 web 抓取项目,用户可以输入类似 Google 的搜索查询(例如“哈佛广场的餐馆”、“旧金山的技术公司”),我的程序会向每个匹配搜索查询的企业发送赞助请求电子邮件。

使用地点 API 探索世界

3 —坎耶休息 API ✨

“我讨厌在飞机上醒来时身边有一个水瓶,就好像哦,太好了,现在我得为这个水瓶负责”

  • Kanye Rest

返回一个随机的 Kanye 引用。

Kanye Rest API 构建你的感知 Kanye 人工智能

4-非官方的抖音 API💃🏻

作为一个自称为 TikToker 的人,我喜欢这个易于使用、基于 python 的 API。这个 API 可以用来获取视频元数据、作者信息、音乐、浏览量、标签等等。

这就是抖音 API 返回的信息类型!想象一下可能性。

用这个 API 实现你成为一名吉他手的梦想。

5 —科诺尔·🪙

Coinlore 是一个加密货币 API,它返回股票信息(例如价格、百分比变化、市值等。)数千种加密货币,包括比特币。我最喜欢的部分是,它还会返回硬币的社交状态,例如其 subreddit 上的活跃用户数或其 twitter 页面上的关注者数。关于 Coinlore 最好的部分——不需要 API 键。

硬币成为比特币百万富翁。

6 —中等 API📓

Medium API 可以提供关于任何用户配置文件的信息,并允许您以编程方式将帖子发布到您的配置文件。这有点令人失望,因为除此之外你做不了什么,但是这对于搜集中等用户的信息来说是很棒的!对于查询文章本身来说,定期的网络搜集是个不错的选择。

在这里找到更多关于媒体 API 的信息。

6—img lip😎

Imgflip 是终极记忆工具。使用 imgflip,您可以为一个流行的迷因提供一个模板 ID 和一个标题,然后 imgflip 将返回一个到生成的迷因的链接。你还可以在互联网上找到许多标题最多的(也就是最受欢迎的)迷因。

用 imgflip API 生成的 Meme。

img slip制作你的下一个迷因

7 — Spotify API🎵

有了 Spotify API,你可以获得你最喜欢的艺术家、专辑和曲目的所有信息。您还可以访问用户相关数据,如他们的音乐库和播放列表中的歌曲。除了有很好的文档记录之外,这个 API 真的很容易使用,而且显然是经过深思熟虑的。用这个 API 你可以创造出无限的可能性!

截图来自Skiley.net,一个使用 Spotify API 追踪你的 Spotify 统计数据的网站。

点击此处了解 Spotify API 的更多信息。

这只是我用过的一些最酷、最有趣、最有用、最全面的 API 的汇编。我希望你喜欢这篇文章。

感谢阅读!

进一步阅读

https://medium.com/geekculture/dont-just-learn-to-code-learn-to-build-cool-stuff-instead-7d0783d51655

我希望早点知道的 7 大机器学习资源

原文:https://towardsdatascience.com/top-7-machine-learning-resources-i-wish-i-knew-earlier-89f4b8d3364c

不是教材,只是有用的网站

马库斯·斯皮斯克在 Unsplash 上的照片

我学习数据科学和机器学习已经两年多了,在那段时间里我被动地收集了很多有用的资源。你知道它实际上是如何发生的——你正在阅读一本书或观看一门课程,作者引起了你的注意(或只是简单提及)一些你以前没有听说过的东西。这可以是一切:编程语言、技术、数据集、任务、度量、基准、可视化工具,真的是一切。你把它保存起来,以便以后弄明白,然后永远忘记它。

我试着不忘记,并探索这些资源,现在我向你展示我的前 7 个。它们根据用途分成几类,第一类是有趣的东西,最后一类是最有用的:

  • 趣味性
  • 去哪里找模特?
  • 如何开始阅读研究论文

这些不是学习资源(如书籍或课程)。这些材料可以让你的生活变得更简单,或者帮助你从稍微不同的角度看待机器学习世界。

趣味性

首先,让我们来看三个适合拥有任何数据科学和机器学习知识水平的人的资源。这些只是有趣的东西,熟悉它们可能会让你开心,同时也会给你带来一些好处。

虚假相关

你还认为相关性意味着依赖吗?这个网站是劝阻你不要这样做的最简单的方法——而且必须这样做:统计不是 ds 和 ML 中的最后一笔交易。它包含了 15 个高度相关的案例,但是,这些案例之间并不存在因果关系。

掉进泳池淹死的人数和尼古拉斯凯奇出演的电影数量?嗯,相关性只有 66%,看起来像是巧合。缅因州的离婚率和人造黄油的消费呢?99%?什么…

https://www.tylervigen.com/spurious-correlations

Netron

Netron 是探索神经网络架构最简单、最方便的方法之一。我在之前的一篇文章里讲过。不用多说,它会生成以下类型的可视化:

神经网络架构。由 Netron 可视化

神经网络越来越大,越来越难可视化。然而,在你的 ML 旅程的开始,从内部看架构或者理解 ResNet152 到底有多大是很有趣的。Netron 给你这个机会。

这些可视化效果令人愉快且具有交互性——您可以更详细地查看每个结构,甚至可以下载特定层的权重。在这里探究上面的例子。

Netron 支持 TensorFlow 和 Keras,并对 PyTorch 提供实验支持。要了解更多信息,请访问 GitHub 官方回购。

神经网络操场由 TensorFlow

本节的最后一个资源也不会让有机器学习经验的人感到惊讶。然而,对于那些刚刚开始发现深度学习的人来说,这个交互式游乐场将有助于更好地理解神经网络的功能原理。

了解单层神经网络的局限性(以及如何添加额外的层来克服这些局限性),尝试不同的学习速率、数据形状和激活函数,以便获得关于什么是神经网络以及它如何工作的直观想法。

http://playground.tensorflow.org/

去哪里找模特?

你已经认识到什么是机器学习,了解神经网络或 SVM 是如何训练的,并且知道 L1 正则化与 L2 正则化有何不同。

接下来的步骤(可能的步骤之一)是,看看模型能够做什么,以及它们现在正在解决什么任务。当然,你现在从新闻中学到了很多,但是从内部看到架构,亲手运行它,并且如果实现是开源的,弄脏你的手,看到它与所有其他模型具有相同的层和参数,这要有用得多。

以下三个资源将帮助您解决这个问题。

人工智能中心

来自谷歌的 AI Hub是你可以开始的第一个地方。在这里,您可以找到数据集、预训练模型等等。但是也许这种资源的主要优势是大量的 Google Colab 笔记本,它们展示了一些模型的功能或训练过程。

来自 AI Hub 的随机笔记本示例。 大众网页 截图

因为笔记本是交互式的、简单的,并且通常不包含很多代码,所以这是开始不害怕另一个人写的代码的好方法。

https://aihub.cloud.google.com/u/0/

TensorFlow Hub

TensorFlow Hub 适合你如果你在用 TensorFlow(令人惊讶)。如果你正在使用 Keras,也许这是一个深入神经网络,切换到 TF 并尝试实现定制模型或层的好机会。

该网站包含大量易于运行的预训练模型。

使用 TensorFlow Hub 运行预训练模型。 大众网页 截图

只有通过微调这些模型,你将能够在许多任务上获得非常好的结果。还要注意教程选项卡,这里通常会提供一个模型链接,提供更详细的描述和解释。

https://www.tensorflow.org/hub

拥抱脸

最后,抱抱脸。它是最强大的资源,包含了我认为最大数量的模型,同时,拥有最好的工具来熟悉这些模型。

拥抱脸主要是一组变形金刚或类似变形金刚的模型,它们主要是为解决各种 NLP 任务而设计的。然而,该网站为各个领域的其他任务提供了模型和数据集——从计算机视觉到强化学习。但正如我们所知,变形金刚的主要成功是在 NLP 中实现的,通常就在这里你可以找到一个最先进的(SOTA)模型,它以最高的质量解决了一个特定的任务。

但是让这个网站特别有价值的是社区和在浏览器中直接发布我们模型的演示的能力。现代神经网络可以做很多事情,如果不是所有事情的话。你想把不同的音乐派对分开吗?不客气。从图像中移除背景?不客气。用甘把你的照片变成你喜欢的动漫或漫画的英雄?不客气。没有什么需要下载,一切都是绝对免费的。

巴拉克·奥巴马和嗝嗝可怕的阿道克三世肖像风格转换的结果。照片由国会图书馆Unsplash 上拍摄,使用 DualStyleGAN 处理

这对任何人来说都是最好的资源之一,即使是非机器学习的人,我也很高兴与您分享。

**https://huggingface.co/

如何开始阅读研究论文

本文的最后一部分是最重要的。这是“如何开始阅读 ML 研究文章”这个问题的答案。。如果我有什么要说的,我肯定会写一篇单独的文章。但是

开始阅读研究论文的最好方法是开始阅读研究论文。

这听起来很傻,但是把这个短语再读几遍,一切就会井井有条了。其实很多问题都可以这样回答。学习编程最好的方法是编程,学习骑自行车最好的方法是骑车,阅读研究论文最好的方法是阅读研究论文。

当然,我不会只给你这个愚蠢的建议。这个网站会帮你解决这个问题,它叫做论文,代码为。出于某种原因,我很晚才发现这件事,好像每个人都在瞒着我,所以我才和你分享。

https://paperswithcode.com/

直观的界面,对数据集和任务的广泛搜索能力,以及看到最佳模型的机会——这个网站对任何 ML 人员来说都是一个真正的发现。

仅此而已。但是等等。我给你看了两类六种资源,但说到最重要的,我只有一种?是的,没错。那是因为够了(不用我你大概也知道 arXiv )。剩下的就看你的了。这个网站有很多值得一提的地方,但是你最好自己去发现它。

如果你认为研究论文只针对精英,那么这是不正确的。如果你第一次不明白某件事,感到困惑或者你只是感到无聊——这没关系,没有人一开始就明白。如果你以前从未读过这些文章,请关注这篇令人敬畏的 NVIDIA 博客文章,它可以帮助你很多:

https://developer.nvidia.com/blog/how-to-read-research-papers-a-pragmatic-approach-for-ml-practitioners/

摘要

就是这样!祝你探索这些资源好运,如果你知道更多,请在评论中分享。最后,让我以更简洁的方式再次列举所有内容:

  1. 趣味性
  • 虚假关联:获得为什么关联不是依赖的直观解释;
  • Netron :可视化神经网络架构;
  • 神经网络游乐场:直接在你的浏览器里玩密集的神经网络。

2.去哪里找模特?

3.如何开始阅读研究论文

感谢您的阅读!

  • 我希望这些材料对你有用。在 Medium 上关注我以获得更多类似的文章。
  • 如果您有任何问题或意见,我将很高兴得到任何反馈。在评论中问我,或者通过 LinkedInTwitter 联系。
  • 为了支持我作为一名作家,并获得数以千计的其他媒体文章,使用我的推荐链接获得媒体会员资格(不收取额外费用)。**

在 R 中制作漂亮表格的 7 大软件包

原文:https://towardsdatascience.com/top-7-packages-for-making-beautiful-tables-in-r-7683d054e541

了解如何用 R 包构建有吸引力的数据表

Unsplash 上由 Mahbod Akhzami 拍摄的照片

介绍

在数据科学中,开发有意义的可视化是一项重要而又具有挑战性的任务。在正确选择工具的同时,对目标受众和分析目标的总体理解也是任何数据分析所期望的。在相同的上下文中,表是组织和总结任何可用数据集的强大而有效的方式,尤其是包含分类变量的数据集。表格通常与支持数据可视化一起在报告中使用,以有效地传达数据分析的结果。通过一些相关的叙述性文本,表格可以精确地共享分析结果,以便在组织中进行决策。虽然 R 中的数据可视化本身是一个巨大的主题,因为有几个健壮且易于使用的绘图库,但 R 中的表格也是如此。 CRAN 网站为 R 用户提供了许多开源包。这些包不仅可以创建表格,还可以将基本表格转换成漂亮的表格,有效地传达分析结果。

在本文中,我们将讨论在 r 中构建彩色表格的七个有趣的包。

用 R 语言制作漂亮数据表的包

几个 R 包提供了创建结构良好的表的特性。这里有几个软件包,我们将使用它们来创建漂亮的表格。

  1. gt(许可证: 麻省理工 )

gt 包提供了一组不同的、易于使用的函数,帮助我们从表格数据中构建显示表。gt 理念指出,桌子零件的综合集合可用于创建各种功能桌子。它们是表体、表尾、扳手列标签、列标签和表头。以下是 gt 包架构的图示:

图像来源

gt 目前支持的输出格式有 HTML、LaTeX 和 RTF。你可以在这里找到更多关于 gt 的信息。要从 CRAN 安装 gt 包,请使用以下命令:

install.packages(“gt”)

要从 GitHub 安装 gt 的开发版本,请使用以下命令:

devtools::install_github(“rstudio/gt”)

接下来,我们将导入 gt 库包。

library(gt)

让我们从 r 的预装数据集中选取 mtcars 数据集。该数据集是从《美国汽车趋势》杂志(1974 年)中提取的,由 32 辆汽车(1973 年和 1974 年款)的燃油消耗信息以及汽车设计和性能的 10 个属性组成。我们可以使用以下命令打印“mtcars”数据集的前几行:

head(mtcars)

作者图片

接下来,我们使用来自数据集 mtcars 的前几个列和行创建一个新的数据帧 df。

我们将用新创建的数据帧“df”调用主函数“gt”如果您使用 RStudio 或其他 R GUI,该表将出现在您的默认浏览器或查看器面板上。

df %>%gt()

作者图片

我们创建的表是一个简单的表,因为使用的格式属性是默认属性。表格的默认外观可以通过使用tab_style()函数来改变,通过这个函数我们可以定位特定的单元格并对它们应用样式。

df %>%gt() %>%
tab_header(title = “mtcars dataset”) %>%
tab_style(
style = list(cell_fill(color = “#b2f7ef”),
cell_text(weight = “bold”)),
locations = cells_body(columns = mpg))%>%
tab_style(
style = list(cell_fill(color = “#ffefb5”),
cell_text(weight = “bold”)), 
locations = cells_body(columns = hp))

作者图片

2。formattable(许可证:MIT +文件 许可证 ):

可格式化数据框是将使用格式化程序函数在 HTML 表格中显示的数据框。这个包包括产生具有预定义格式规则的数据结构的技术,这样对象保持原始数据但被格式化。该软件包由几个标准的可格式化对象组成,包括百分比、逗号、货币、会计和科学。你可以在这里找到更多关于 formattable 的信息。

要从 CRAN 安装 formattable 软件包,请使用以下命令:

install.packages(“formattable”)

要从 GitHub 安装 formattable 的开发版本,请使用以下命令:

devtools::install_github(“renkun-ken/formattable”)

接下来,我们将导入 formattable 库包。

library(formattable)

为了演示这个库,我们将使用内置函数color_bar()来比较给定数据列中值的大小。

formattable(df, list(
hp = color_bar(“#e9c46a”),
cyl = color_bar(“#80ed99”),
wt = color_bar(“#48cae4”),
disp = color_bar(“#f28482”)))

作者图片

3。kableExtra(许可证:MIT +文件 许可证 )

kableExtra 包用于扩展knitr::kable tables()的基本功能。虽然knitr::kable()的设计很简单,但它缺少许多其他包中通常有的功能,kableExtra 很好地填补了knitr::kable().的空白。关于 kableExtra 最好的事情是它的大多数表格功能都适用于 HTML 和 PDF 格式。你可以在这里找到更多关于 kableExtra 的信息

要从 CRAN 安装 kableExtra 包,请使用以下命令:

install.packages(“kableExtra”)

要从 GitHub 安装 kableExtra 的开发版本,请使用以下命令:

remotes::install_github(“haozhu233/kableExtra”)

接下来,我们将导入 kableExtra 库包。

library(kableExtra)

我们将使用数据帧“df”调用 kbl 函数来查看该表的基本版本。

kable(df) %>% kable_styling(latex_options = “striped”)

作者图片

要样式化单独的行和列,我们可以使用函数 row_spec()column_spec()

df %>% kbl() %>%
kable_paper() %>% column_spec(2, color = “white”,
background = spec_color(mtcars$drat[1:2],end = 0.7)) %>%
column_spec(5, color = “white”,
background = spec_color(mtcars$drat[1:6], end = 0.7),
popover = paste(“am:”, mtcars$am[1:6]))

作者图片

4。dt(许可证:GPL-3)

dt 是“数据表”的缩写。R 中的数据对象可以使用 JavaScript 库“数据表”呈现为 HTML 表格(通常通过 R Markdown 或 Shiny)。你可以在这里找到更多关于 dt 的信息

要从 CRAN 安装 dt 包,请使用以下命令:

install.packages(‘DT’)

要从 GitHub 安装 dt 的开发版本,请使用以下命令:

remotes::install_github(‘rstudio/DT’)

接下来,我们将导入 dt 库包。

library(DT)

DT 包的主要特性是它能够为 HTML 表提供过滤、分页和排序。通过使用这个包,我们可以切片、滚动和排列表格,以便更好地理解表格内容。

datatable(
data = mtcars,
caption = “Table”,
filter = “top”
)

作者图片

5。flextable(许可证:GPL-3)

flextable 包帮助您轻松地从数据框架创建报表。您可以合并单元格、添加页眉、添加页脚、更改格式以及设置单元格中数据的显示方式。表格内容也可以包含混合类型的文本和图像内容。表格可以从 R Markdown 文档嵌入到 HTML、PDF、Word 和 PowerPoint 文档中,也可以使用 Package Officer for Microsoft Word 或 PowerPoint 文档嵌入。表格也可以导出为 R 图或图形文件,例如 png、pdf 和 jpeg。点击可以了解更多关于 flextable 的信息。

要从 CRAN 安装 flextable 包,请使用以下命令:

install.packages(“flextable”)

要从 GitHub 安装 flextable 的开发版本,请使用以下命令:

devtools::install_github(“davidgohel/flextable”)

接下来,我们将导入 flextable 库包。

library(flextable)

对于这个库,主要的函数是 flextable。我们将调用flextable函数来查看表格的基本版本,如下所示:

flextable(df)

作者图片

我们将使用set_flextable_defaults函数来改变表格的默认外观。

set_flextable_defaults(
font.family = “Arial”, font.size = 10,
border.color = “#e5383b”,
padding = 6,
background.color = “#EFEFEF”)
flextable(head(df)) %>%
bold(part = “header”)

作者图片

6。reactable(许可证:MIT +文件 许可证 )

reactable()从表格数据创建数据表,默认带有排序和分页。数据表是一个 HTML 小部件,可以在 R Markdown 文档和闪亮的应用程序中使用,或者从 R 控制台查看。它基于 React 表库,用 reactR 制作。有很多特点可以反应;其中一些列举如下:

  • 它创建一个带有排序、过滤和分页的数据表
  • 它有内置的列格式
  • 它支持通过 R 或 JavaScript 定制渲染
  • 它可以在 R Markdown 文档和闪亮的应用程序中无缝工作

从起重机安装可反应包时,使用以下命令:

install.packages(“reactable”)

要从 GitHub 安装 reactable 的开发版本,请使用以下命令:

# install.packages(“devtools”)
devtools::install_github(“glin/reactable”)

接下来,我们将导入 reactable 库包。

library(reactable)

我们将使用reactable()函数创建一个数据表。默认情况下,该表是可排序和分页的:

reactable(mtcars)

作者图片

为了改变表格的默认外观,我们将使用reactableTheme()函数。如果希望为所有表设置默认主题,也可以使用全局 reactable.theme 选项。

library(reactable)
reactable(mtcars)
options(reactable.theme = reactableTheme(
color = “black”,
backgroundColor = “#bde0fe”,
borderColor = “#a3b18a”,
stripedColor = “#a3b18a”,
highlightColor = “#2b2d42”
))

作者图片

7。reactablefmtr(许可证:MIT +文件 许可证 )

reactablefmtr 包改进了使用 reactable R 库创建的表格的外观和格式。reactablefmtr 包包括许多条件格式器,这些格式器高度可定制且易于使用。

从 CRAN 安装reactable fmtr包时,使用以下命令:****

**install.packages(“reactablefmtr”)**

要从 GitHub 安装 reactablefmtr 的开发版本,请使用以下命令:

**remotes::[install_github](https://remotes.r-lib.org/reference/install_github.html)(“kcuilla/reactablefmtr”)**

R 中的 reactable 包允许您创建交互式数据表。然而,在 reactable 内部格式化表需要大量的代码,这对许多 R 用户来说可能是一个挑战,需要更好的可伸缩性。reactablefmtr 库中的data_bars()函数使得创建条形图变得更加容易。

**library(reactablefmtr)
reactable(data,defaultColDef = colDef(
cell = data_bars(data,text_position = “outside-base”)
))**

作者图片

有几种方法可以改变data_bars()的外观,包括条对齐、文本标签位置以及向条添加图标和图像的能力。

**library(reactablefmtr)
reactable(data,defaultColDef = colDef(cell = data_bars(df, box_shadow = TRUE, round_edges = TRUE,
text_position = “outside-base”,
fill_color = c(“#e81cff”, “#40c9ff”),
background = “#e5e5e5”,fill_gradient = TRUE)
))**

作者图片

结论

在本文中,我们讨论了七个强大的 R 包来为给定的数据集创建漂亮的表。还有更多的 R 库,事实上将来还会开发一些新的 R 库。但是本教程可以帮助那些希望用 r 创建更漂亮、更有效的表的人开始使用这些包。

你可以关注我: GitHubKaggleTwitterLinkedIn

清理原始数据的 8 大 SQL 函数

原文:https://towardsdatascience.com/top-8-sql-functions-to-clean-raw-data-2b6141de06a

因为垃圾数据进来意味着垃圾数据出去。

安东Unsplash 上拍照

在一个完美的世界里,我们的数据从一开始就是干净的。不会有丢失的值。列将被转换为正确的类型。我们将能够执行聚合并在模型中使用数据,而无需做任何工作。

不幸的是,原始数据可能非常混乱。如果在模型中使用数据之前,您从未需要对数据进行大量转换,那么您应该感到幸运。每个分析工程师都知道,为我们的分析师提供干净的数据是我们工作的一个关键部分。

混乱的数据输入意味着混乱的数据输出。您的数据模型的有效性和简洁程度取决于您加载到其中的数据。

在本文中,我将简要介绍如何使用 Airbyte 轻松地从业务 API 中提取原始数据,并将它们接收到数据仓库中。然后,我将展示从 Google Sheets 提取原始数据到数据仓库时一些常见的数据质量问题。最后,我将向您介绍一些流行的 SQL 字符串函数来清理这些数据,并准备好供您的分析师使用。

将原始数据从 Google Sheets 加载到雪花

在转换原始数据之前,我们需要使用 Airbyte 提供的 100 个连接器中的一个来接收数据。确保你按照指示在本地设置 Airbyte】并创建你的第一个数据连接器。

您还需要设置目的地,或者您希望将数据加载到的仓库。Airbyte 在这里有关于如何做这个的详细说明。

当将数据加载到目的地时,您会注意到选择“基本规范化”的选项。通过选择此项,您将允许 Airbyte 创建适合您的数据及其目的地的模式和表。如果不选择规范化,您的数据将以 JSON blob 的形式作为一列上传。JSON blob 只需要在我们这边做进一步的转换。让我们接受帮助,让 Airbyte 让我们的工作变得更容易!

作者图片

值得注意的是,这个模式及其表将始终作为原始数据存在,由 Airbyte 直接接收。我们不会将我们的转换直接应用于这些表,而是将它们写在 SQL 文件中,用 dbt 运行。我们将在下一篇文章中详细介绍如何设置 dbt 源文件和基本模型。

现在,要知道你总是希望有一个数据库只是为了原始数据。这样,如果您需要更改您的转换,您可以这样做,而不必从 Airbyte 源连接器重新吸收数据。

正如 Airbyte 的文件中所写的,

“ELT 理念的一个核心原则是,数据在 E 和 L 阶段移动时应该保持不变,以便原始数据始终可以访问。”

在建立数据仓库时,请记住这一点。您应该有两个独立的数据库,一个用于原始数据,一个用于转换后的数据。

转换和清理原始数据

在本教程中,我从 Google Sheet 向 Snowflake 获取数据。你可以在 Google Sheets source 文档Snowflake destination 文档中找到更多关于设置 Airbyte 数据连接器的信息。

虽然 Google sheets 不是自动化和跟踪数据的最佳方式,但它们被经常使用。当你在一家小公司工作时,有时这是你必须跟踪不同信息的唯一解决方案,如营销预算、有影响力的联系人或产品成本。

也就是说,来自 Google sheets 的数据是最难处理的数据之一。与 Shopify 和脸书等其他应用程序不同,这里没有检查。Google sheets 容易出现大量人为错误。我曾多次遇到有人以错误的格式填写值,导致我们整个数据管道中断的情况。

这里有一个加载到雪花的 Google Sheets 数据集的例子,我将在本教程中使用:

作者图片

让我们看看我们在原始数据中看到的一些常见场景,以及我们如何将它们转换成可以在模型中使用的数据。内置的 SQL 字符串函数帮助您清理来自原始数据的字符串,以便在数据仓库中查询它们。

重命名列

清理任何数据时,您要做的第一件事是将列名更改为对您的分析最有意义的名称。在这里, date 是一个跨表使用的常见关键字,所以您会希望将其更改为更具描述性。

此外,我们希望将列名活动链接更改为没有空格或大写字母的名称。这将使我们的分析顺利。列名中的空格可能会导致将来的查询出现问题。我推荐使用大小写,或者单词间的下划线。您可以使用AS语句轻松地重命名表列。

select
  LCV AS lifetime_value,
  date AS activation_date,
  name,
  email,
  phone,
  "Campaign Link" AS campaign_link
from AIRBYTE_DATABASE.AIRBYTE_SCHEMA.GOOGLE_SHEETS_CUSTOMER_DETAILS;

太棒了,现在我们可以轻松地在转换中使用这些列了!

将一列拆分为多列

让我们从查看 customer_name 列开始。如您所见,它包含了名和姓。我们希望使用该列创建两个单独的列,名字姓氏

作者图片

这就是split_part()字符串函数派上用场的地方。我们指定要拆分的列、要拆分的字符,以及要将字符串放在该字符的右边还是左边。

1 将给出空间左边的字符串,而-1 将给出空间右边的字符串。

select
  split_part(name, ' ', 1) AS first_name,
  split_part(name, ' ', -1)    AS last_name
from AIRBYTE_DATABASE.AIRBYTE_SCHEMA.GOOGLE_SHEETS_CUSTOMER_DETAILS;

我们现在有两个单独的列,一个用于客户的名,一个用于客户的姓。

作者图片

改变案例

现在,注意仍然有一些大写问题。为了便于分析,所有字符串都小写是有意义的。这样,在过滤或比较值时,您就不必担心字符串会成为问题。

我们可以通过使用lower()字符串函数来做到这一点。

select
  lower(split_part(name, ' ', 1)) AS first_name,
  lower(split_part(name, ' ', -1)) AS last_name
from AIRBYTE_DATABASE.AIRBYTE_SCHEMA.GOOGLE_CUSTOMER_DETAILS;

该查询会产生以下结果:

作者图片

现在我们的名字姓氏列都是小写的。

从字符串中提取值

再来看看 campaign_link 栏目。本专栏遵循从 Google 或 Bing 广告生成的典型链接的结构。这在市场营销中屡见不鲜,提取起来可能有点痛苦。

像这样从 URL 中提取字符串的关键是识别模式。在某些情况下,同一列中会有一些不同的模式。幸运的是,在这里,它是统一的。

作者图片

我们可以看到 utm_source 总是在 a 之后?而在一个&之前。 utm_medium 跟在此&之后,在另一个&之前。最后, utm_campaign 跟在最后一个&后面。我们需要使用split_part()函数编写一些 SQL 代码,该函数使用这种模式提取每个值。

select
  split_part(split_part("Campaign Link", 'utm_source=', -1), '&', 1) AS utm_source,
  split_part(split_part("Campaign Link", 'utm_medium=', -1), '&', 1) AS utm_medium,
  split_part(split_part("Campaign Link", 'utm_campaign=', -1), '&', 1) AS utm_campaign
from AIRBYTE_DATABASE.AIRBYTE_SCHEMA.GOOGLE_CUSTOMER_DETAILS;

当我们使用前面提到的相同的split_part()字符串函数时,我们可以从包围它们的字符之间提取源、媒介和活动字符串。我们使用内部的split_part()函数提取每个=右边的值,然后使用另一个函数提取下一个字符左边的值。

这会产生三个新列:

作者图片

现在,原始活动链接的每个部分都有单独的列。

设置列条件

再来看 lifetime_value 一栏。我们知道该列必须包含数值,而不包含文本。然而,有一栏输入了随机的字母。为了进一步清理这个列,我们需要首先删除这个字符串值。

作者图片

Snowflake SQL dialect 有一个名为[TRY_TO_NUMBER()](https://docs.snowflake.com/en/sql-reference/functions/try_to_decimal.html)的方便的字符串函数,如果值是数字,它将值转换为数字,如果不是,则返回空值。

SELECT
 try_to_number(lifetime_value)
FROM AIRBYTE_DATABASE.AIRBYTE_SCHEMA.GOOGLE_SHEETS_CUSTOMER_DETAILS

作者图片

注意这个 SQL 函数是如何消除原始值中的小数位的。因此,我们只想在 case 语句中使用它来检查空值。

select
    case 
        when try_to_number(lifetime_value) is NULL then NULL else lifetime_value
    end as lifetime_value 
from AIRBYTE_DATABASE.AIRBYTE_SCHEMA.GOOGLE_SHEETS_CUSTOMER_DETAILS;

作者图片

我们还可以看到小数的格式不统一,有些是负数。为了清理数据,我们不希望该列中有任何负值。相反,我们希望用 0 代替负数。

我们可以使用iff()函数来测试一个列中的条件。首先,指定条件。然后,如果它是 false,它将返回指定的第一个值。如果为 true,将返回指定的第二个值。

select
    case 
        when try_to_number(LCV) is NULL then NULL else IFF(LCV<0, 0, ROUND(LCV,2))
    end as lifetime_value 
from
AIRBYTE_DATABASE.AIRBYTE_SCHEMA.GOOGLE_SHEETS_CUSTOMER_DETAILS;

在这里,我测试一下 lifetime_value 是否小于 0。如果是,函数将返回 0。如果不是,我就使用round()函数将数值四舍五入到两位小数。这个函数非常适合舍入货币值或任何小数。指定要舍入的列,然后指定小数位数。

作者图片

检查长度

再来看电话栏目。我们可以看到其中一些电话号码实际上根本不是电话号码。我们希望最大限度地减少不准确数据的数量,所以让我们看看是否可以向该列添加一个条件。

作者图片

我们知道电话号码最多只能是 11 位,如果不包括国家代码,可能是 10 位。为了限制表中虚假数据的数量,让我们删除所有没有 10 位或 11 位数字的电话号码。更好的办法是,在不满足这个条件的情况下,让列值为 NULL。

SELECT
  IFF(len(phone) IN (10, 11), phone, null) AS phone
from AIRBYTE_DATABASE.AIRBYTE_SCHEMA.GOOGLE_SHEETS_CUSTOMER_DETAILS;

这里我再次使用一个IFF()函数来检查列中的值是否满足某个条件。我使用len()函数来检查列值中的字符。如果电话号码不是 10 或 11 个字符,我们将用空值替换它。

作者图片

现在,我们只有一个电话号码,但至少我们知道它是准确的!干净数据比脏数据好,即使脏数据更少。质量重于数量。

检查字符

与电话号码一样,我们希望确保电子邮件列包含准确的电子邮件地址。我们可以进行一些检查来确保这些信息的准确性。其中之一是确保这些值包含@字符,这是所有电子邮件都有的字符。

我们可以通过使用 charindex()字符串函数来实现这一点。这个函数返回指定字符在字符串中的位置。如果字符串中不存在该字符,函数将返回 0。

这里,我们在电子邮件列中搜索@符号。我们使用 case 语句来检查这个函数的结果是否是 0 以外的数字。如果不是 0,它必须包含一个@。如果它是 0,它不是一个正确的电子邮件地址,我们用 null 替换这个值。

select
  case
     when charindex('@', email) != 0 then email
     else null
  end AS email
from AIRBYTE_DATABASE.AIRBYTE_SCHEMA.GOOGLE_SHEETS_CUSTOMER_DETAILS;

新电子邮件将如下所示:

作者图片

类似于电话列,电子邮件列现在具有空值,而以前的值不满足指定的条件。

检查子字符串

除了@符号之外,电子邮件地址必须以“.”结尾。com”。我们可以检查以确保该电子邮件列中的值都以该字符串结尾。如果不是,我们可以用一个空值来代替它。

这里,我们将使用LIKE语句来确保它包含这个子串。

select
  case
     when email LIKE '%.com' then email
     else null
  end AS email
from AIRBYTE_DATABASE.AIRBYTE_SCHEMA.GOOGLE_SHEETS_CUSTOMER_DETAILS;

%符号表示任何字符串都可以出现在“.”之前。com”。但是,既然我们没有一个%的结尾”。该值必须在它之后结束。像麦迪逊这样的价值观。comgmail 不准确,将被 NULL 代替。

作者图片

因为我们所有的电子邮件都符合这个条件,所以我们得到的表看起来是一样的。

铸造日期

将日期输入电子表格有许多不同的方式。我在使用 Google sheets 作为数据源时经常遇到这个问题。每当一个新的人将数据输入到表单中时,列的格式就会改变!如您所见,日期的输入方式不同,有些用斜线,有些用连字符。

作者图片

幸运的是,有一个 SQL 函数to_date()可以将字符串转换成日期。第一次接收数据时,带有日期的列的数据类型为 varchar。使用此函数对它们进行转换会将它们转换为数据类型为 date 的日期,从而使该列为分析做好准备。

select 
  to_date(activation_date) AS activation_date 
from AIRBYTE_DATABASE.AIRBYTE_SCHEMA.GOOGLE_SHEETS_CUSTOMER_DETAILS;

这将产生一个日期如下所示的列:

作者图片

结论

现在,我们的原始数据已经被清理成我们的数据分析师可以实际使用的数据!这些 SQL 清理函数对于创建可用的数据模型至关重要。你会一遍又一遍地使用它们,所以理解它们是如何工作的很重要。

下面是我们今天学习的 SQL 字符串函数的概述:

  • split_part() 按字符分割字符串
  • lower() 删除字符串中的所有大写
  • try_to_number() 将值转换为数字
  • iff() 为测试条件
  • round() 将一个数四舍五入到一定的小数位数
  • len() 检查字符串的长度
  • char_index() 查找字符串中某个字符的索引
  • to_date() 将字符串转换为日期

下一步是在 SQL 文件中编写代码,供 dbt 使用和自动化。该代码与 dbt 一起将创建一个自动化系统,在该系统中,当您的分析师需要数据时,您的数据总是干净的和可用的。这就是数据驱动型公司和数据驱动型公司的区别。但是我们将在另一篇文章中讨论这个问题。数据清理快乐!

通过订阅我的电子邮件列表,了解更多关于 SQL 和分析工程师使用的其他工具的

顶级数据清理 Python 包

原文:https://towardsdatascience.com/top-data-cleaning-python-packages-e6bde24b273b

使用这些 Python 包轻松清理您的数据

Towfiqu barbhuiyaUnsplash 上的照片

许多人会认为数据科学工作是开发机器学习模型和评估技术指标的专有工作。虽然没有错,但工作责任要大得多。数据科学家需要从事数据收集、清理、分析、数据理解等工作。

那么,数据科学家在哪个任务上花费的时间最多?根据 CrowdFlower 的一项调查,数据科学家 80%的时间都花在数据清理上。这并不奇怪,因为我们的数据科学项目取决于我们的数据有多干净。

但是,有一些方法可以通过使用数据清理包来缩短数据清理处理时间。这些包是什么,它是如何工作的?让我们一起学习。

1.py 看门人

py gateway是 gateway R 包的一个实现,用于在 Python 环境中用链接方法清理数据。该软件包易于使用,直观的 API 直接连接到 Pandas 软件包。

从历史上看,Pandas 已经提供了很多有用的数据清理功能,比如用dropna删除空值,用to_dummies进行分类编码。另一方面,py teacher 增强了 Panda 的清理 API 能力,而不是取代它。py guardian 是怎么工作的?让我们试着在我们的数据清理过程中实现 py teacher。

作为一个项目示例,我将使用来自 Kaggle 的数据集 Coffee meet Bagel review。

import pandas as pd
review = pd.read_csv('data_review.csv')
review.info()

我们的数据集中有 11 列包含对象和数字数据。乍一看,有些数据似乎丢失了,列名也不规范。让我们试着用熊猫和 py guardian 清理数据集。

在我们开始之前,我们需要安装 py guardian 包。

pip install pyjanitor

当你安装完这个包后,我们只需要导入这个包,API 函数就可以通过 Pandas API 立即使用了。让我们用我们的样本数据集来试试 py guardian 包。

import janitorjan_review = review.factorize_columns(column_names=["userName"]).expand_column(column_name = 'reviewCreatedVersion').clean_names()

在上面的代码示例中,py teacher API 执行了以下操作:

  1. 因式分解 userName 列以将分类数据转换为数字数据(factorize_columns),
  2. 展开 reviewCreatedVersion 列或一键编码过程(expand_column),
  3. 通过将列名转换为小写来清除列名,然后用下划线(clean_names)替换所有空格。

以上是我们可以用 py toolter 做的一个示例操作。你还可以用 py guardian 做更多的事情,我将在下面的图片中展示给你看。

作者图片

此外,链式方法还可以与 Panda 的原始 API 一起使用。您可以将两者结合起来实现您想要的干净数据。

2.Klib

Klib 是一个用于导入、清理和分析的开源 Python 包。这是一个一站式软件包,用于轻松理解您的数据和预处理。该软件包非常适合使用直观的可视化和易于使用的 API 来评估您的数据。

因为本文只讨论数据清理,所以让我们把重点放在数据清理 API 上。如果您想进一步探索 Klib,您可以查看下面的文章。

对于数据清理,Klib 依靠data_cleaning API 来自动清理数据帧。让我们用数据集例子来试试 API。首先,我们需要安装软件包。

pip install klib

安装完成后,我们会将数据集传递给data_cleaning API。

import klib
df_cleaned = klib.data_cleaning(review)

作者图片

上面的函数产生了对我们的数据集示例所做的数据清理信息。Klib data_cleaning程序遵循当前步骤:

  • 列名清理,
  • 删除空的和几乎空的列,
  • 删除单基数列,
  • 删除重复的行,
  • 记忆力减退。

3.数据准备

DataPrep 是为数据准备而创建的 Python 包,其主要任务包括:

  • 数据探索
  • 数据清理
  • 数据收集

出于本文的目的,我将重点关注 DataPrep 的数据清理 API。然而,如果您对 DataPrep 包感兴趣,您可以访问我在下面文章中的解释。

DataPrep cleaning 为数据清理和验证提供了 140 多个 API。我将在下面的 GIF 中展示所有可用的 API。

作者 GIF

从上面的 GIF 可以看到,有各种 API 可以使用,比如列标题、国家名称、日期和时间等等。清洁所需的所有 API 都在那里。

如果您不确定要清理什么,您总是可以依赖 DataPrep 的clean_df API 自动清理您的数据,并让包推断您需要什么。让我们试试这个 API 来了解更多信息。

首先,我们需要安装 DataPrep 包。

pip install dataprep

在包安装之后,我们可以在之前的数据集例子中应用clean_df API。

from dataprep.clean import clean_df
inferred_dtypes, cleaned_df = clean_df(review)

API 将有两个输出—推断的数据类型和清理的数据帧。此外,该过程还会生成数据框清理摘要。

作者图片

上面的报告向我们提供了关于处理了哪些数据类型、清理了哪些列标题以及减少了多少内存的信息。如果您认为清理已经足够,则可以在下一步中使用清理后的数据框。如果没有,那么您可以使用可用的清理 API。

4.scrubadub

Scrubadub 是一个开源的 Python 包,用于从文本数据中删除个人身份信息。Scrubadub 的工作方式是删除检测到的个人数据,并替换为文本标识符,如{{EMAIL}}或{{NAME}}。

目前,Scrubadub 仅支持删除以下个人数据:

作者图片

让我们尝试用 Scrubadub 清理我们的样本数据集。首先,我们需要安装软件包。

pip install scrubadub

正如我们在上面的图片中看到的,我们可以使用 Scrubadub 删除各种个人数据,比如姓名和电子邮件地址。让我们使用一个包含姓名和电子邮件个人信息的数据样本。

review['replyContent'].loc[24947]

作者图片

该数据包含我们想要删除的姓名和电子邮件数据。让我们使用 Scrubadub 来完成它。

sample = review['replyContent'].loc[24947]
scrubadub.clean(sample)

作者图片

干净数据删除了电子邮件数据,并替换为标识符{{EMAIL}}。但是,我们仍然有识别的名称数据。那么 Scrubadub 怎么能去掉这个名字呢?

为了增强 Scrubadub 名称标识符,我们需要添加来自其他包的名称检测改进。对于这个例子,让我们添加来自 TextBlob 的检测器。

scrubber = scrubadub.Scrubber()
scrubber.add_detector(scrubadub.detectors.TextBlobNameDetector)
scrubber.clean(sample)

作者图片

现在,我们已经删除了该名称,并替换为{{NAME}}标识符。您可以浏览软件包文档来更好地理解 Scrubadub。

结论

数据清理是数据科学家工作中花费时间最多的过程。为了帮助清理工作,开发了许多用于数据清理的 Python 包。

在本文中,我概述了我的顶级数据清理 Python 包;它们是:

  1. py 看门人
  2. Klib
  3. 数据准备
  4. Scrubadub

希望有帮助!

在我的 LinkedInTwitter 上访问我。

请不要错过我的内容,点击此处订阅我的 时事通讯,获取更多关于数据的深入知识,提升您的数据科学事业。

如果您没有订阅为中等会员,请考虑通过 我的推荐 订阅。

2022 年使用的顶级数据库:什么是适合您的用例的数据库?

原文:https://towardsdatascience.com/top-databases-to-use-in-2022-what-is-the-right-database-for-your-use-case-bb8d3f183b21

这里是你需要知道的关于数据库的一切

图片来自 Shutterstock,授权给 Frank Andrade

不管你是做什么工作的,你都可能听说过数据库这个词。

外面的公司使用不同类型的数据库来存储他们多年来收集的所有信息。尽管所有这些数据库可能看起来都一样,但它们有一些功能使它们更适合某些情况,因此值得对它们进行更多的了解。

让我们来看看哪种数据库最适合您的使用情形!为此,我们将了解什么是数据库,什么类型的数据库更适合你,2022 年的顶级数据库是什么,以及它们的优缺点。

**Table of Contents** 1\. [What is a Database?](#4272)
2\. [Types of Databases](#2895)
 - [Relational databases](#062a)
 - [Non-Relational databases](#5c9c)
3\. [The top databases in 2022](#ffcb)
 - [Oracle](#6415)
 - [MySQL](#9923)
 - [SQL Server](#a17b)
 - [PostgreSQL](#3ad4)
 - [MongoDB](#6f1e)

请务必 订阅此处 获取我在所有教程中使用的 SQL 备忘单(免费 PDF)

什么是数据库?

数据库是通常以电子方式存储在计算机系统中并由数据库管理系统(DBMS)控制的数据集合。数据、DBMS 以及与之相关的应用程序被称为数据库系统(或简称为“数据库”)。

数据库管理系统和数据库这两个词经常互换使用,但从技术上讲,它们并不相同。

为了区分它们,考虑一个社交媒体应用程序的情况,该应用程序存储关于其用户的不同信息,如消息、照片、评论等。数据库存储了大量的数据,但这就是它所做的。如果你想编辑、更新或删除数据,你需要一个数据库管理系统为你说话。一些最流行的数据库管理系统是 Oracle、MySQL、SQL Server 和 PostgreSQL。

作者在 Canva 上制作的图像

同样,人们经常把 DBMS 和 DB 简单地称为“数据库”,但是现在你知道这实际上是如何工作的了。

另一种看待数据库的方式是将数据库视为一个包含许多行和列的大电子表格。这是一个很好的比较,但数据库超越了这一点。数据库和电子表格都适合存储信息,但它们主要在以下方面有所不同:

  • 数据是如何存储和操作的:数据库允许复杂的数据操作,而电子表格不适合需要大量数据操作的用户。
  • 谁可以访问数据:数据库允许多个用户快速访问和查询数据,而电子表格只为单个用户或少数用户设计。
  • 可以存储的数据量:数据库被设计用来存储更大的数据集合,而电子表格有一个限制。

最后但同样重要的是,数据库不能只在表和行中存储数据。这就是关系数据库通常的工作方式,但是还有另一种类型的数据库叫做非关系数据库,这就引出了我们的下一点。

数据库的类型

数据库通常分为关系数据库和非关系数据库。在前 10 个数据库中,您会看到关系数据库和非关系数据库。一种类型的数据库并不比另一种更好,但是它们适合不同的需求。

关系数据库

关系数据库(也称为 SQL 数据库)将数据存储在表和行中,也称为记录。这种类型的数据库通过键链接不同表中的信息。

键是表中的唯一值,也称为“主键”。当这个键被添加到位于另一个表中的记录时,它在第二个表中被称为“外键”。主键和外键之间的这种连接在两个表中的记录之间创建了一种关系。

一些流行的关系数据库管理系统(RDBMS)是 Oracle、MySQL、SQL Server 和 PostgreSQL。

下面是一个基本模式,展示了关系数据库是如何工作的。

来源: Pixabay

为了在 RDBMS 中查询数据,我们使用结构化查询语言(SQL)。使用 SQL,我们可以创建新的记录,更新它们,等等。这使得 RDBMS 适用于需要事务功能、数据挖掘和复杂报告的应用程序。

非关系数据库

非关系数据库(也称为 NoSQL 数据库)存储数据时没有表、行或键。换句话说,非关系数据库以非表格形式存储数据。这增加了灵活性,有助于满足所存储数据类型的特定要求。

您可以将非关系数据库视为文档的集合。一个文档可以包含许多关于客户的详细信息。每个客户可以有不同类型的信息,但是它们可以存储在同一个文档中。

作者图片

处理和组织不同类型信息的能力使得非关系数据库比关系数据库更加灵活。

有四种流行的非关系类型:文档数据存储、面向列的数据库、键值存储和图形数据库。最流行的 NoSQL 数据库之一是 MongoDB。

2022 年有哪些顶级数据库?

很难根据数据库的功能对其进行排序,因为它们适合不同的需求,并且在某些情况下可能比在其他情况下更方便。也就是说,可以根据数据库管理系统的受欢迎程度对它们进行排序。

事实上, DB-Engine 根据 DBMS 当前的流行程度对其进行排名。为此,他们按照不同的参数计算分数。

以下是 2022 年最受欢迎的 10 大数据库。

现在让我们更多地了解它们,比较它们,看看它们的优缺点。

1.神谕

Oracle 数据库是跨行业广泛使用的 RDBMS。事实上,它在 RDBMS 市场中占有最大的市场份额,约为 30.2%。

Oracle 数据库支持 SQL 语言与数据库交互。它被认为是最好的数据库之一,因为它支持涉及关系、图形、结构化和非结构化信息的所有数据类型。除此之外,Oracle 数据库因其灵活的标准、可伸缩性、高可用性和强大的安全性而成为首选。

赞成的意见

  • 它与不同的应用程序和平台高度兼容
  • 有助于提高可扩展性
  • 它提供了良好的隐私和安全性

骗局

  • 许可证很贵
  • 用户可能需要丰富的 SQL 知识才能使用 Oracle 数据库

流行

在过去 5 年中,Google Trends 对 Oracle 的兴趣超过了对 MySQL 的兴趣。该图还显示了两个数据库的相同起伏。

来源:谷歌趋势

2.关系型数据库

MySQL 是 2022 年最受欢迎的数据库之一。它是开源的,因此任何人或公司都可以免费使用 MySQL,但如果代码需要集成到商业应用程序中,则需要购买许可证。也就是说,对于任何想尝试一个友好而强大的数据库的人来说,这个数据库仍然是值得的。

MySQL 是由 Oracle 开发的,它是一个关系数据库管理系统。如前所述,关系模型包括用行和列来组织表中的数据,而元素之间的关系遵循逻辑结构。脸书、Twitter、维基百科和 YouTube 等公司都使用 MySQL 后端。

赞成的意见

  • 它是开源的:不像其他选择,你不需要付费就可以使用 MySQL 的大部分特性
  • 它是跨平台的:在 Linus、Solaris 和 Windows 上运行,并支持使用 C、C++、Java、Python 等编程语言的平台。
  • 可靠的数据安全性:MySQL 是一个安全的数据库管理系统。这也是为什么这么多知名公司在应用中使用它的原因。
  • 它很容易使用:任何人都可以在几分钟内下载、安装并开始使用 MySQL。

骗局

  • 它不适合大数据
  • 它不支持 SQL 检查约束
  • 与付费数据库相比,它没有一个好的调试工具
  • 它处理交易的效率不高

流行

Google Trends 显示,在过去 5 年中,对 MySQL 的兴趣略有下降,但与 SQL Server 等其他数据库相比,在 2022 年突然上升。

来源:谷歌趋势

3.SQL Server

SQL Server 是由微软开发的,它被认为是适用于内部和云环境的出色的 RDBMS。它有一个数据库引擎组件,允许存储、处理和保护数据。数据库引擎分为两个部分—关系引擎和存储引擎。第一个用于处理命令和查询,而第二个用于管理表、页面、文件、索引和事务等特性。

除了 SQL 语言,SQL Server 还包括 Transact-SQL (T-SQL),这是微软对用于与关系数据库交互的 SQL 的扩展。对于希望根据需求无缝扩展性能、可用性和安全性的企业来说,SQL Server 是一个不错的选择。

赞成的意见

  • 它有各种受支持的版本(企业版、标准版、速成版和开发者版)。express SQL server 版是免费的。
  • 它有一个在线文档
  • 内部和云数据库支持
  • 它提供不同的工具和应用程序

骗局

  • 昂贵的企业版
  • 它适用于 Windows、Linux 和 macOS,但在 Mac 上安装它的步骤不像在 Windows 机器上那么简单。

流行

随着时间的推移,Google Trends 对 SQL Server 比对 PostgreSQL 更感兴趣。事实上,在过去的 5 年里,人们对 PostgreSQL 的兴趣并没有改变多少。

来源:谷歌趋势

4.一种数据库系统

PostgreSQL 被称为世界上最先进的开源对象关系数据库管理系统(ORDBMS)。这种声誉部分归功于它的架构、可靠性、健壮性和可扩展性。

PostgreSQL 提供了许多功能,有助于构建应用程序、保护数据完整性并帮助管理数据,无论数据大小。它在许多领域也是高度可扩展的。仅举几个例子:

  • 存储函数和过程
  • PL/PGSQL、Perl、Python
  • SQL/JSON 路径表达式
  • 附加功能,如 PostGIS(PostgreSQL 的空间数据库扩展器)

这些扩展帮助我们直接处理来自 PostgreSQL 的数据,因此我们不需要寻找变通方法来实现它们。

赞成的意见

  • 它是高度可编程的:由于它基于目录的操作和动态加载,您可以扩展 PostgreSQL
  • 它是高度可扩展的
  • 它有一套非常丰富的索引选项

骗局

  • 性能:PostgreSQL 有时不如 MySQL 等其他 RDBMS 高效(至少对于简单的精读操作是这样)
  • 可能很难排除 PostgreSQL 故障

流行

随着时间的推移,Google Trends 对 PostgreSQL 和 MongoDB 表现出了类似的兴趣。也就是说,我们应该考虑 PostgreSQL 最初是在 1996 年发布的,而 MongoDB 是在 2009 年发布的。

来源:谷歌趋势

5.MongoDB

MongoDB 是一个开源文档数据库,它使用灵活的模式来存储数据。与将数据存储在行列表中的 SQL 数据库不同,像 MongoDB 这样的 NoSQL 数据库程序使用类似 JSON 的文档和可选的模式。

MongoDB 非常适合那些构建互联网和商业应用程序并需要快速发展和扩展的人。MongoDB 对开发人员的一些优势是面向文档的数据库的强大功能(可以直接以 JSON 格式检索文档,开发人员会发现这很容易使用)、用户体验、可伸缩性和事务性,以及它蓬勃发展的社区。

总的来说,如果您正在寻找一个具有以下特征的数据库,MongoDB 是不错的选择:

  • 支持快速迭代开发
  • 支持扩展到高水平的读写流量
  • 创建应用程序时存储、管理和搜索数据

赞成的意见

  • 它提供了在 RDBMS 中不可能得到的灵活模式
  • 可伸缩性:MongoDB 使用分片,这允许数据库使用水平可伸缩性。
  • 它是免费的,支持 Windows、macOS 和 Linux

骗局

  • 高内存使用率:MongoDB 中的数据大小高于其他数据库
  • 查询灵活性较差:它不支持作为关系数据库的连接

学习 SQL —数据专业人员最需要的技能。 加入我的 20k+人电子邮件列表,获取我的免费 SQL 备忘单。

如果你喜欢阅读这样的故事,并想支持我成为一名作家,可以考虑报名成为一名媒体成员。每月 5 美元,让您可以无限制地访问数以千计的 Python 指南和数据科学文章。如果你使用我的链接注册,我会赚一小笔佣金,不需要你额外付费。

https://frank-andrade.medium.com/membership

数据科学家的顶级编码器

原文:https://towardsdatascience.com/top-encoders-for-data-scientists-fbc8dce42531

意见

2022 年,为您的机器学习算法提供更好的分类编码方法(而不是一次性编码)

桑迪·米勒在Unsplash【1】上拍摄的照片。

目录

  1. 介绍
  2. 目标编码器
  3. CatBoost 编码器
  4. CatBoost 库自动编码器
  5. 摘要
  6. 参考

介绍

曾经的编码统治者,一键编码,已经不复存在。更新、更好、更简单的编码方法已经出现,并开始取代传统的编码类型。在一个算法实现更快、特性可解释性更好的世界里,等等。,数据科学过程中仍有一部分相当陈旧和缺乏——编码——它花费的时间太长、太乏味、太混乱。并非所有的模型,但在一些模型中,是不能被模型吸收的分类特征。您会看到错误,并想,为什么我不能使用一个看起来如此明显的特性,为什么我必须将我的数据框架扩展到数百列?这些新的编码方法使您能够将更多的精力放在您想要使用的功能上,有些功能非常明显,而不是您愿意花费时间来消化它们。话虽如此,让我们更深入地探讨一下,如何通过对分类特征进行更好的编码来获得更好的结果。

目标编码器

布雷迪·贝里尼Unsplash【2】上的照片。

以下编码器就是基于这种目标编码方法构建的。根据sci kit-learn【3】,“特征被替换为目标的后验概率,以及目标在你的训练数据上的先验概率”。更简单地说,当您有一个分类特性时,您可以将列值从一个文本值/字符串替换为该分类值的数字表示。

以下是您将用于此编码的通用代码:

pip install category_encoders**import** **category_encoders** **as** **ce**target_encoder = ce.TargetEncoder(cols=['cat_col_1', 'cat_col_2'])target_encoder.fit(X, y)X_transformed = target_encoder.transform(X_pre_encoded)

所以,假设你有:

  • cat_col_1 =动物
  • cat_col_2 =天气类型

您可以用一个实际的 float 代替 one-hot-encoding,one-hot-encoding 会将可能的值转置到新的列中,如果实际上是该类别值,则表示为 0/1。

此外,不是dogfishcat,你会有→ 0.33、. 20、. 10 等。根据你的数据,和天气类型类似的东西,比如rainingsunnysnowing → 0.05、. 60、. 05 等。

这种目标编码方法也是接下来两种方法的基础方法。

CatBoost 编码器

詹姆斯·萨顿在Unsplash【4】上的照片。

与上面的编码器类似,字符串/文本、对象或类别值类型将被替换为浮点型。代码也是一样的,除了用CatBoostEncoder替换TargetEncoder

使用这种目标编码方法将编码器应用于分类要素的另一个好处是,您不仅可以减少数据帧的维数,还可以通过另一个库(如 SHAP)更容易地了解分类要素的要素重要性。

CatBoost 编码 [5]更好使用,因为它通过过去数据的有序目标编码以及更多随机排列来防止目标泄漏。

从 CatBoost 文档中,我们可以看到该方法是下面的方法【6】,主要有以下好处,对此我表示赞同:

  • 改变输入的随机顺序和数据类型的转换
  • 通过利用不仅仅是数字特征来改进培训,因此您在预处理数据上花费的时间更少

CatBoost 库自动编码器

图片由 Geran de KlerkUnsplash【7】上拍摄。

有了一种全新的名为 CatBoost 的算法,可以自动对数据的类别数据类型进行编码,而不必手动对数据应用编码器。该算法结合了目标编码的优点,特别是 CatBoost 编码的优点,此外,还在本机代码中实现了功能解释。

虽然它与上面的编码器没有什么不同,但它甚至更容易使用,对我来说,这是对分类特征进行编码的最简单的方法,特别是当您还处理有时会混淆的数字特征时(两种数据类型)。

这种编码器不仅更容易使用,算法库和编码器经常击败大多数其他算法,包括 Random Forest 和 XGBoost,这在 CatBoosts 的主页上有文档记录。

以下是用 Python 实现 CatBoost 代码的简单方法:

# import your library
from catboost import CatBoostRegressorCAT_FEATURES = [] #list of your categorical features# set up the model
catboost_model = CatBoostRegressor(n_estimators=100,
                                   loss_function = 'RMSE',
                                   eval_metric = 'RMSE',
                                   cat_features = CAT_FEATURES)
# fit model
catboost_model.fit(X_train, y_trian, 
                   eval_set = (X_test, y_test),
                   use_best_model = True,
                   plot = True)# easily print out your SHAP feature importances, including your CAT_FEATURESshap_values = catboost_model.get_feature_importance(Pool(
                       X_train,
                       label = y_train,
                       cat_features = CAT_FEATURES
),type = "ShapValues")shap_values = shap_values[:,:-1]shap.summary_plot(shap_values, X_train, max_display=50)

摘要

正如你所看到的,数据科学总是在不断发展,编码方法也不例外。在本文中,我们看到了一些与分类变量的 one-hot-enoding 相反的替代方法。好处包括能够在总体上利用分类特征,以及通过更简单的解释轻松地接受它们,最终允许更快、更便宜(有时)和更准确的建模。

总而言之,以下是较好的编码类型:

* Target Encoder* CatBoost Encoder* CatBoost Library Automatic Encoder

我希望你觉得我的文章既有趣又有用。如果您同意或不同意这些编码器,请随时在下面发表评论。为什么或为什么不?关于数据科学预处理,您认为还有哪些编码器值得指出?这些当然可以进一步澄清,但我希望我能够为您的数据和数据科学模型提供一些更有益的编码器。

我不隶属于这些公司。

请随时查看我的个人资料、 Matt Przybyla和其他文章,并通过以下链接订阅接收我的博客的电子邮件通知,或通过点击屏幕顶部的订阅图标 点击订阅图标 ,如果您有任何问题或意见,请在 LinkedIn 上联系我。

订阅链接:【https://datascience2.medium.com/subscribe】

引荐链接:https://datascience2.medium.com/membership

(如果你在 Medium 上注册会员,我会收到一笔佣金)

参考

[1]桑迪·米勒在 Unsplash 上拍摄的照片,(2021)

[2]照片由布雷迪·贝里尼Unsplash(2021)拍摄

[3] Will McGinnis,sci kit-学习目标编码器,(2016)

[4]詹姆斯·萨顿(James Sutton)在 Unsplash 上拍摄的照片,(2018)

[5] Will McGinnis, scikit-learn CatBoost 编码器,(2016)

[6] Yandex, CatBoost —分类—数字,(2022)

[7]图片由 Geran de KlerkUnsplas(2017)上拍摄

用于分类的 6 大机器学习算法

原文:https://towardsdatascience.com/top-machine-learning-algorithms-for-classification-2197870ff501

如何用 Python 构建机器学习模型管道

用于分类的机器学习算法(原图来自我的网站

监督与非监督与强化学习

区分有监督学习和无监督学习最简单的方法就是看数据是否被标注。

监督学习学习一个函数,根据输入数据对定义的标签进行预测。它可以是将数据分类(分类问题)或预测结果(回归算法)。

无监督学习揭示数据集中没有明确呈现的潜在模式,它可以发现数据点的相似性(聚类算法)或揭示变量的隐藏关系(关联规则算法)…

强化学习是另一种类型的机器学习,其中代理学习根据其与环境的交互采取行动,目的是最大化回报。它非常类似于人类的学习过程,遵循试错法。

分类与回归

监督学习可以进一步分为分类和回归算法。分类模型识别对象属于哪个类别,而 回归模型 预测连续输出。

有关回归算法的指南,请参见:

有时在分类算法和回归算法之间有一条模糊的线。许多算法既可以用于分类,也可以用于回归,而分类只是应用了阈值的回归模型。当数量高于阈值时,它被分类为真,而低于阈值时,它被分类为假。

在本文中,我们将讨论分类问题的 6 大机器学习算法,包括:l 逻辑回归、决策树、随机森林、支持向量机、k 近邻和朴素贝叶斯。我总结了每种方法背后的理论,以及如何使用 python 实现每种方法。在我的网站上查看模型管道的代码。

1.逻辑回归

逻辑回归(图片由作者提供)

逻辑回归使用上面的 sigmoid 函数来返回标签的概率。当分类问题是二元的——真或假,赢或输,正或负时,它被广泛使用...

sigmoid 函数生成概率输出。通过将该概率与预定义的阈值进行比较,对象被相应地分配给标签。查看我在逻辑回归上的帖子,获得详细的演示。

下面是默认逻辑回归和常用超参数的代码片段,看看哪些组合能带来最好的结果。

from sklearn.linear_model import LogisticRegression
reg = LogisticRegression()
reg.fit(X_train, y_train)
y_pred = reg.predict(X_test)

logistic 回归常用超参数 : penalty,max_iter,C,solver

2.决策图表

决策树(图片由作者提供)

决策树以分层的方式构建树分支,每个分支可以被视为一个 if-else 语句。分支是通过基于最重要的特征将数据集划分为子集来发展的。最终的分类发生在决策树的叶子上。

from sklearn.tree import DecisionTreeClassifier
dtc = DecisionTreeClassifier()
dtc.fit(X_train, y_train)
y_pred = dtc.predict(X_test)

决策树常用超参数 : criterion,max_depth,min_samples_split,min _ samples _ leaf 最大 _ 功能

3.随机森林

随机森林(图片由作者提供)

顾名思义,随机森林是决策树的集合。这是一种常见的集合方法,它集合了来自多个预报器的结果。随机森林还利用 bagging 技术,允许每棵树在原始数据集的随机采样上训练,并从树中获得多数票。与决策树相比,它具有更好的泛化能力,但可解释性较差,因为模型中增加了更多的层。

from sklearn.ensemble import RandomForestClassifier
rfc = RandomForestClassifier()
rfc.fit(X_train, y_train)
y_pred = rfc.predict(X_test)

随机森林常用超参数 : n_estimators,max_features,max_depth,min_samples_split,min_samples_leaf,boostrap

4.支持向量机(SVM)

支持向量机(图片作者提供)

支持向量机根据与正类和负类之间的边界相关的位置找到对数据进行分类的最佳方式。这个边界被称为超平面,它最大化来自不同类的数据点之间的距离。类似于决策树和随机森林,支持向量机可以用于分类和回归,SVC(支持向量分类器)用于分类问题。

from sklearn.svm import SVC
svc = SVC()
svc.fit(X_train, y_train)
y_pred = svc.predict(X_test)

支持向量机常用超参数: c,内核,伽马

5.k-最近邻(KNN)

knn(图片由作者提供)

您可以将 k 最近邻算法视为表示由 n 个特征定义的 n 维空间中的每个数据点。它计算一个点到另一个点的距离,然后根据最近的观察数据点的标签分配未观察数据的标签。KNN 也可以用来构建推荐系统,如果你对这个话题感兴趣,可以看看我的文章“协同过滤推荐电影”。

from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier()
knn.fit(X_train, y_train)
y_pred = knn.predict(X_test)

KNN 常用超参数:n _ neighbors,weights,leaf_size,p

6.朴素贝叶斯

朴素贝叶斯(作者图片)

朴素贝叶斯基于贝叶斯定理——一种基于先验知识计算条件概率的方法,以及每个特征相互独立的朴素假设。朴素贝叶斯的最大优点是,虽然大多数机器学习算法依赖于大量的训练数据,但即使训练数据量很小,它也能表现得相对较好。高斯朴素贝叶斯是一种遵循正态分布的朴素贝叶斯分类器。

from sklearn.naive_bayes import GaussianNB
gnb = GaussianNB()
gnb.fit(X_train, y_train)
y_pred = gnb.predict(X_test)

高斯朴素贝叶斯常用超参数 :先验,var_smoothing

如果你想知道更多其他机器学习算法,请查看我的列表:

Destin Gong

德斯坦贡

机器学习实用指南

View list10 storiesPrincipal Component Analysis for MLTime Series Analysisdeep learning cheatsheet for beginner

构建分类模型管道

1.加载数据集和数据概述

我选择了 Kaggle 上流行的数据集心脏病 UCI 来预测基于几个健康相关因素的心脏病的存在。

使用df.info()获得数据集的汇总视图,包括数据类型、缺失数据和记录数。

2.探索性数据分析

直方图、分组条形图和箱线图是适合分类机器学习算法的 EDA 技术。如果你想要更全面的 EDA 指南,请参见我的帖子“Python 中的半自动探索性数据分析过程

https://www.visual-design.net/post/semi-automated-exploratory-data-analysis-process-in-python

单因素分析

单变量分析(图片由作者提供)

直方图用于所有要素,因为所有要素都已编码为数据集中的数值。这为我们节省了通常发生在特征工程阶段的分类编码时间。

分类特征与目标—分组条形图

分组条形图(作者图片)

为了显示分类值在确定目标值时的权重,分组条形图是一种直观的表示方法。例如,性别= 1 和性别= 0 具有明显的目标值分布,这表明它可能对目标的预测贡献更大。相反,如果不管分类特征如何,目标分布是相同的,那么它们很可能是不相关的。

数值特征与目标值的对比——箱线图

箱线图(图片由作者提供)

箱线图显示了不同目标群体的数值特征如何变化。例如,我们可以看出,当目标值为 0 与目标值为 1 时,“旧峰”具有明显的差异,这表明它是一个重要的预测因子。然而,“trestbps”和“chol”似乎不太突出,因为目标群体之间的箱线图分布相似。

3.将数据集分成训练集和测试集

分类算法属于监督学习的范畴,因此数据集需要分成一个子集用于训练,一个子集用于测试(有时也是一个验证集)。该模型在训练集上进行训练,然后使用测试集进行检查。

from sklearn.model_selection import train_test_split
from sklearn import preprocessingX = df.drop(['target'], axis=1)
y = df["target"]X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)

4.机器学习模型流水线

为了创建一个管道,我将上面提到的所有分类算法的默认状态附加到模型列表中,然后迭代通过它们来训练、测试、预测和评估。

模型管道(图片由作者提供)

5.模型评估

模型评估(图片由作者提供)

下面是分类模型常用评价方法的抽象解释——准确率、ROC & AUC 和混淆矩阵。以下每个指标都值得深入研究,请随意访问我关于逻辑回归的文章,获取更详细的说明。

1。精确度

精确度是模型性能最直接的指标。它衡量准确预测的百分比:准确性=(真阳性+真阴性)/(真阳性+假阳性+假阴性+假阳性)

2。ROC & AUC

ROC 和 AUC(图片由作者提供)

ROC 是在不同分类阈值下真阳性率对假阳性率的图。AUC 是 ROC 曲线下的面积,AUC 越高表明模型性能越好。

3。混乱矩阵

混淆矩阵显示实际值与预测值,并以矩阵形式汇总真阴性、假阳性、假阴性和真阳性值

然后,我们可以使用 seaborn 在热图中可视化混淆矩阵。

混乱矩阵图(图片由作者提供)

准确性和 AUC 结果(图片由作者提供)

基于上述三种评估方法,随机森林和朴素贝叶斯的性能最好,而 KNN 的表现不佳。然而,这并不意味着随机森林和朴素贝叶斯是优越的算法。我们只能说,它们更适合这种规模相对较小、数据不在同一尺度的数据集。

每种算法都有自己的偏好,需要不同的数据处理和特征工程技术,例如 KNN 对不同尺度的特征很敏感,多重共线性会影响逻辑回归的结果。了解每种模型的特征使我们能够权衡利弊,并根据数据集选择合适的模型。

感谢您到目前为止,如果您想阅读更多来自 Medium 的文章并支持我的工作,我真的很感谢您使用这个附属链接注册 Medium 会员。

带回家的信息

本文介绍了以下 6 种机器学习算法,并指导您构建模型管道来解决分类问题:

  1. 逻辑回归
  2. 决策图表
  3. 随机森林
  4. 支持向量机
  5. KNN
  6. 朴素贝叶斯

更多这样的资源

Destin Gong

德斯坦贡

机器学习实用指南

View list10 storiesPrincipal Component Analysis for MLTime Series Analysisdeep learning cheatsheet for beginner Destin Gong

德斯坦贡

开始学习数据科学

View list8 storiesStatistical Tests in Python

原载于 2022 年 2 月 22 日 https://www.visual-design.net**的

机器学习中的四大线性回归变量

原文:https://towardsdatascience.com/top-machine-learning-algorithms-for-regression-c67258a2c0ac

初学者友好的实现和比较指南

回归的机器学习算法(原图来自我的网站

在我之前的文章“用于分类的顶级机器学习算法”中,我们介绍了常见的分类算法。现在让我们深入到监督学习的另一个类别——回归,其中输出变量是连续的数字。主要是,如何实现和比较四种常见类型的回归模型:

  • 线性回归
  • 套索回归
  • 里脊回归
  • 多项式回归

如果你喜欢视频演练,请查看我在本文末尾的 YouTube 视频。

线性回归

线性回归找到自变量和因变量之间的最佳线性关系,从而做出相应的预测。最简单的形式是 y = b0 + b1x。当只有一个输入特征时,线性回归模型拟合 2 维空间中的直线,以最小化预测值和实际值之间的残差。测量残差大小的常用成本函数是残差平方和(RSS)。

线性回归(作者图片)

随着更多功能的引入,简单线性回归演变为多元线性回归 y = b0 + b1x1 + b2x2 + … + bnxn。如果你想要简单线性回归模型的具体指南,请随意查看我的文章。

套索回归

拉索回归(图片由作者提供)

Lasso 回归是 L1 正则化的线性回归的变体。听起来令人畏惧?简单地说,它给回归模型试图最小化的残差(RSS)增加了一个额外的元素。它被称为 L1 正则化,因为这个增加的正则化项与系数的绝对值成比例。上面的项是基于最简单的线性回归形式 y = b0 + b1x。

与岭回归相比,它更好地将某些特征的系数变为 0,因此是一种合适的特征消除技术。您将在后面的“特性重要性”一节中看到。

里脊回归

岭回归(图片作者提供)

岭回归是 L2 正则化的另一种回归变体。因此不难推断,正则项是基于系数的平方值——2 次。与 Lasso 回归相比,岭回归具有收敛速度快、计算量小的优点。

正则化强度(图片由作者提供)

拉索和脊线的正则化强度由λ值决定。λ值越大,系数越小,模型越平坦,方差越小。因此,正则化技术通常用于防止模型过拟合。

多项式回归

多项式回归(作者图片)

多项式回归是线性回归通过多项式特征变换的一种变体。它增加了独立变量之间的相互作用。PolynomialFeatures(degree = 2)用于将输入特征转换到最大程度 2。例如,如果原始输入要素是 x1、x2、x3,这会将要素扩展为 x1、x2、x3、x1、x1x2、x1x3、x2、x2x3、x3。结果,该关系不再是线性的,而是能够提供对数据的非线性拟合。

实践中的回归模型

在所有的理论之后,时间来实现和比较这些回归模型,并探索不同的 lambda 值如何影响模型性能。

如果你有兴趣获得这个项目的完整代码,请查看代码片段

1.目标和数据集概述

该项目旨在使用回归模型,根据其他因素“人均国内生产总值”、“社会支持”、“健康预期寿命”、“做出生活选择的自由”、“慷慨程度”和“对腐败的看法”来预测国家幸福指数。

我用的是 Kaggle 上的《世界幸福报告》数据集,包含 156 个条目,9 个特征。df.describe()用于提供数据集的概述。

数据集概述(按作者分类的图片)

2.数据探索和特征工程

1)删除冗余特征

特性“总体排名”被删除,因为它是目标“得分”的直接反映。此外,“国家或地区”被删除,因为它不会给预测带来任何值。

2)单变量分析

应用直方图了解每个特征的分布。如下图所示,“社会支持”似乎严重左倾,而“慷慨”“对腐败的看法”则是右倾——这为转换的特征工程技术提供了信息。

# univariate analysis
fig = plt.figure(figsize=(16, 8))  
i = 0
for column in df:
    sub = fig.add_subplot(2,4 , i + 1)
    sub.set_xlabel(column)
    df[column].plot(kind = 'hist')
    i = i + 1

单变量分析(图片由作者提供)

我们还可以将直方图与下面的偏斜度结合起来,以量化特征是否严重向左或向右偏斜。

skew_limit = 0.7
for col in df.columns:
    skewness = df[col].skew()
    if skewness + skew_limit < 0:
        print(col, ": left skewed", str(skewness))
    elif skewness > skew_limit:
        print(col, ": right skewed", str(skewness))
    else: 
        print(col, ": not skewed", str(skewness))

偏斜度

3)平方根变换

*np.sqrt* 是应用于变换右斜特征“慷慨”和“对腐败的看法”。因此,这两个特征变得更加正态分布。

平方根变换(图片由作者提供)

4)日志转换

*np.log(2 — df['Social Support'])*用于变换左歪斜特征。偏斜度从 1.13 显著降低到 0.39。

日志转换(图片由作者提供)

5)双变量分析

*sns.pairplot(df)*可以用来可视化变换后特征之间的相关性。散点图表明“人均 GDP”、“社会支持”、“健康预期寿命”与目标特征“得分”相关,因此可能具有较高的系数值。让我们在后面的部分看看是否是这样。

6)特征缩放

由于正则化技术正在操纵系数值,这使得模型性能对特征的比例敏感。所以特征应该被转换成相同的比例。我在三种定标器上做了实验——标准定标器、最小最大定标器和鲁棒定标器。

查看我的文章“3 种常见的数据转换技术”以获得更全面的数据转换技术指南。

请注意,缩放器仅适合使用训练集,然后将变换应用于训练集和测试集。所以,应该先拆分数据集。

from sklearn.model_selection import train_test_splitX = df.drop(['Score'], axis=1)
y = df['Score']X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)print(X_train.shape, X_test.shape)

然后,迭代这 3 个缩放器,比较它们的结果。

特征缩放代码(图片由作者提供)

如您所见,缩放器不会影响数据的分布和形状,但会改变数据的范围。

特征比例比较(图片由作者提供)

要获得更全面的 EDA 和特征工程指南,请查看我的精选列表。

Destin Gong

德斯坦贡

EDA 和特征工程技术

View list9 stories

3.回归模型比较

现在我们来比较下面三种线性回归模型——线性回归、岭回归和套索回归。

lr = LinearRegression().fit(X_train, y_train)
l2 = Ridge(alpha = 0.1).fit(X_train, y_train)
l1 = Lasso(alpha = 0.001).fit(X_train, y_train)

1)预测比较

首先,在一个散点图中可视化三个模型的预测值与实际值,这表明在当前的参数设置下,它们的预测大部分相互重叠。

回归预测比较(图片由作者提供)

2)特征重要性

第二步是实验不同的 lambda 值(scikit-learn 中的 alpha)如何影响模型。具体来说,当 alpha 值从 0.0001 增加到 1 时,特征重要性和系数值如何变化。

特征重要性代码(图片由作者提供)

套索与山脊的特征重要性(图片由作者提供)

基于 Lasso 和 Ridge 模型生成的系数值,“人均 GDP”、“社会支持”、“健康预期寿命”似乎是前 3 个最重要的特征。这与之前散点图的发现一致,表明它们是“乡村快乐得分”的主要驱动力。并排比较还表明,alpha 值的增加在不同程度上影响 Lasso 和 Ridge,Lasso 中的特征被更强烈地抑制。这就是为什么套索经常被选择用于特征选择的目的。

3)应用多项式效果

此外,还引入了多项式要素来增强基线线性回归,从而将要素数量从 6 个增加到 27 个。

from sklearn.preprocessing import PolynomialFeatures
pf = PolynomialFeatures(degree = 2, include_bias = False)
X_train_poly = pf.fit_transform(X_train)
X_test_poly = pf.fit_transform(X_test)

看看它们在多项式变换后的分布。

多项式特征单变量分析(图片由作者提供)

4.模型评估

最后一步,评估多项式效应前后 Lasso 回归与岭回归模型的性能。在下面的代码中,我实现了四个模型:

  • l2:没有多项式特征的岭回归
  • l2_poly:具有多项式特征的岭回归
  • l1:无多项式特征的套索回归
  • l1_poly:具有多项式要素的套索回归

回归模型评估(图片由作者提供)

常见的回归模型评估指标有 MAE、MSE、RMSE 和 R 平方——查看我的文章“线性回归实用指南”了解详细解释。在这里,我使用 MSE(均方误差)来评估模型性能。

1)通过在一个图表中比较山脊与套索,表明当α值较低时,它们具有相似的精度,但是当α值接近 1 时,套索显著恶化。在多项式变换之前和之后观察到相同的模式。

一张图中的山脊与套索(图片由作者提供)

2)通过在一个图表中比较之前与之后的多项式效应,我们可以知道,多项式总体上降低了 MSE,从而增强了模型性能。当α增加到 1 时,这种效应在岭回归中更显著,当α接近 0.0001 时,这种效应在套索回归中更显著。

一个图表中多项式效果的前后对比(图片由作者提供)

但是,即使多项式变换提高了回归模型的性能,它也会使模型的可解释性变得更加困难-很难从多项式回归中分辨出主要的模型驱动因素。

更少的错误并不总是保证更好的模型,它将在基于项目目标的可预测性和可解释性之间找到正确的平衡。

感谢到达终点。如果你想阅读更多我关于媒介的文章,我将非常感谢你的支持,注册成为 媒介会员

带回家的信息

希望本文提供了不同类型回归模型的一般思路,包括:

  • 线性回归
  • 里脊回归
  • 套索回归
  • 多项式回归

我们还将演练:

  • 回归模型的基本 EDA 和特征工程技术。
  • 不同 alpha 值下的特征重要性
  • 套索和脊的模型比较
  • 多项式特征前后的模型比较

更多这样的文章

Destin Gong

德斯坦贡

机器学习实用指南

View list10 storiesPrincipal Component Analysis for MLTime Series Analysisdeep learning cheatsheet for beginnerDestin Gong

德斯坦贡

开始学习数据科学

View list8 storiesStatistical Tests in Python

原载于 2022 年 3 月 20 日 https://www.visual-design.nethttps://www.visual-design.net/post/top-machine-learning-algorithms-for-regression

2022 年数据科学求职中要避免的最大错误

原文:https://towardsdatascience.com/top-mistakes-to-avoid-in-your-2022-data-science-job-search-89788701c6d9

数据科学

3 个最常见的数据科学求职错误和避免它们的技巧

你是否发现自己在寻找数据科学工作的过程中不断失败?事实是,在求职过程中,你几乎可以做对每一件事,然而一个错误就可能毁掉你获得工作的机会。

那么,导致人们在数据科学求职和面试中失败的最常见的错误到底是什么?

数据科学求职过程中最常犯的三个错误包括:

  • 同时申请不同类型的职位
  • 没有准备面试
  • 患有分析麻痹

当然,在数据科学求职中取得成功需要的不仅仅是知道潜在的错误。你还需要知道如何最好地避开他们。我们将在下面详细讨论每个错误,特别向您展示它们是如何发生的以及如何避免它们。

在我们开始之前,我想让你知道,如果你认识到自己犯了这些错误,你不应该感到难过!我正在回顾这些特殊的错误,因为很多人都犯了这些错误,包括我自己!希望通过了解这些错误,你可以在将来不再重复这些错误,从而节省大量的时间和精力。

如果你想以不同的形式获得这些信息,我的 YouTube 频道上还有关于这个主题的视频。

目录

错误 1:同时申请多个职位类型

我们要看的第一个错误是同时申请不同的职位类型。对于不同的职位类型,我指的是数据科学领域的职位,如数据科学家分析师、数据科学家算法,或相关职位,如机器学习工程师。

刚进入科技行业的时候,我并没有意识到数据科学工程和数据科学统计这样的岗位可以有多么不同。你可能会认为同时申请多种职位类型是一个扭转不利局面的好方法。然而,在现实中,这是一个坏主意。但是为什么呢?

帕特里克·帕金斯在 Unsplash 上的照片

效率低下。如果你刚进入这个行业,不要像我一样。我申请了我能申请的每一个职位:数据科学家、数据分析师、软件工程师、数据算法等等——这简直是浪费时间。

虽然你可能觉得自己取得了很多成就,但你没有给自己找到真正适合自己的职位的最好机会。为了获得最佳结果,你应该专注于申请一种类型的职位,并成为这方面的专家。

你的技能不会那么犀利。这听起来可能很简单,但如果你从来没有专注于一个单一的角色,你将很难获得所需的技能来获得一份数据科学家的工作。通过专注于一种类型的数据科学角色,你将能够更深入地学习并快速获得雇主正在寻找的技能。

你浪费时间申请。一开始你可能没有意识到,但是每份申请都需要为这份工作量身定做你的简历和求职信,而且做这些改动所花费的时间会很快增加。

在一个像数据科学这样专业化的行业中,从一个应用程序到下一个应用程序可能会遗留一些东西。这就是为什么浪费精力去追逐数据分析师、软件工程师或机器学习工程师等不同职位的面试是没有意义的。适用技能的重叠是如此之小,以至于你会在申请上浪费很多时间。

所有这些最终导致低面试录用率。数据科学面试非常严格,而且高度依赖于他们的职位类型。根据你申请的内容,你会被问到不同的问题。不同的职位也将侧重于不同的技术技能和知识。

有这么多东西要学,如果你申请多个不同类型的职位,你会很快发现面试过程变得令人不知所措。你会有压力,你无法充分准备,很可能面试失败。

如果以上理由不能让你相信申请多种类型的职位是个坏主意,不要相信我的话。最近,一位追随者发来了一封短信,我认为它完美地诠释了我想表达的意思:

我不知道我应该寻找机器学习的机会还是一般的数据科学工作,我什么都申请了。看完你的博客和视频后,我改变了我的简历,专注于指标,并开始申请产品数据科学家的角色。到三月底,我接到了几个电话,所有这些电话都变成了现场面试和多份工作邀请。上周,我接受了脸书产品分析数据科学家的职位。这是我在产品数据科学领域的梦想工作,如果没有你的帮助,我不会达到这个里程碑。

这里的要点是,用激光精度专注于一个职位类型可以帮助你的数据科学求职。在一个合适的领域磨练你的技能比尝试所有你能做到的事情要好得多。如果你想得到更多的帮助来找到正确的位置,看看我做的这个关于这个主题的视频

错误 2:毫无准备地参加面试

许多求职者犯的下一个错误是没有做好充分准备就去参加面试。有些人甚至不知道会被问到什么样的问题就直接去面试了。

这个错误比你想象的要普遍得多,原因是人们错误地认为求职是一个简单的数字游戏。他们认为,如果一个人申请了足够多的工作,最终他们必须找到一份工作。

照片由Firmbee.comUnsplash 上拍摄

回顾我自己找工作时的心态,我可以看到这可能是有意义的。我以前也是这样想的,但是我从来没有这样想过。最终,我不得不弄清楚我的面试问题是什么,并学会解决它们的方法。你不能仅仅依靠面试次数来找到工作。

为了理解这个错误以及如何更好地避免它,让我们看看我过去找工作时没有准备的几个有用的例子:

没有准备好技术面试

谈到技术面试,面试前的练习是必不可少的。你可能觉得你真的理解了一门学科,但如果你不花时间准备和练习,你会发现自己在面试中表现很差。这是怎么发生的?下面以我的编码面试经历为例来看看。

我遇到的编码面试通常由四个问题组成:两个简单,一个中等,一个困难。因为我在过去有过一些编码密集型数据科学项目的经验——从零开始实现算法,通过比较不同的算法优化运行时,以及类似的工作——我通常认为自己是一个自信的程序员。

然而,有一次,我完全没有时间了,只能解决两个简单的问题。我后来意识到自己在房间里写代码和有人在你身后监视是非常不同的——在你编码的时候仔细检查每一个按键。此外,在面试中,你还应该解释你编码时的思维过程,同时不引入任何错误。当练习编码面试时,一定要用语言描述你的思维过程,这样你才能对实际面试的时机有所感觉。

不了解你的面试官

你永远不应该盲目地去参加面试。事先做一点调查会大有帮助。在一次演讲面试中,我得到了这个教训。

演示面试准备起来可能有些棘手。有一次,一家公司让我展示我最有影响力的项目。我假设我的观众将是数据科学家,所以我引入了许多技术术语,如统计学和机器学习术语,希望给我的观众留下这个项目有多么具有挑战性的印象。

但事实证明这是一个大错误。观众是利益相关者的混合体,在这里是数据科学经理和产品经理。产品经理对项目的商业影响比对技术细节更感兴趣。我没有准备讨论那些方面,所以自然,我在那次面试中表现不好。

这就是为什么研究你的面试官总是有好处的。一封简单的面试前邮件通常有助于揭示面试官在公司中的位置。

正如你从我上面的例子中看到的,即使是我也经历过没有充分准备的面试。直到我分享了我的故事,人们开始联系我,我才意识到我不是唯一一个没有为面试做好充分准备的人。

有的没想到编码题,就不准备了。其他人告诉我,他们没有为关于项目或简历的深度问题做好充分准备。不管怎样,关键是在你走进面试之前,你需要做一些工作。

不熟悉产品

最后,有些人面试失败是因为他们根本不熟悉公司的产品。

一些例子可以是问一些问题,表明你显然不熟悉这家公司或其产品。如果你不知道脸书的新闻源是什么,或者 ETA 对优步这样的公司意味着什么,你会显得毫无准备,很可能不会给人留下好印象。

我真的希望每个人都认真对待面试,尽最大努力准备,因为当人们为面试做好充分准备,甚至准备过度时,他们会更快找到工作。

这不仅是基于我经历过几次求职的经历,也是基于许多向我寻求分享他们故事的人的经历。最重要的是,为面试做准备将会使工作提前,并获得将所学知识应用到数据科学家日常工作中的好处。

错误 3:分析麻痹

我们要讲的最后一个错误是被分析麻痹。这可能会触怒一些人,但作为一名数据科学家,你不能总是分析一切——没有指标会告诉你应该进入该领域的哪个部分。

我完全理解人们关心效率和 ROI,但我想指出的错误是在采取行动学习之前担心学习某样东西是否会有帮助。

照片由布鲁斯·马尔斯Unsplash 拍摄

人们有时会问我这样的问题:

  • 你在 YouTube 视频里推荐的书真的有帮助吗?
  • 你的博文中的资源真的有益吗?
  • 如果我要选出最有用的,我该选哪个?

我理解你问这些问题背后的动机,但是,事实上,你只有在学会之后才知道某样东西是否有帮助。别人的经验可能不适用于你。请记住:

  • 不要花太多时间担心你不知道的,而是花时间获得新技能。例如,不要花几个小时研究哪本书可能最有帮助,只要挑一本开始学习。
  • 稳步提高将为你作为数据科学家的能力打下坚实的基础,并让你在面试中获得更多成功。

所以,如果你意识到你有一个知识缺口,并且你知道有一种方法可以帮助你获得知识并填补缺口,那么就简单地采取行动,而不是浪费时间过度分析。记住,你永远不会后悔对自己的任何投资。

结束语

好了,各位,这就是我看到的人们在数据科学求职中最常犯的三个错误。我已经从过去的这些错误中吸取了教训,我希望你能记住这些教训,这样你就不会再犯同样的错误了。

感谢阅读!

如果你喜欢这个帖子,想支持我…

[## 第一份数据科学家工作的面试:期待什么以及如何准备

towardsdatascience.com](/interviewing-for-your-first-data-scientist-job-what-to-expect-and-how-to-prepare-1f3f9a977e14)

熊猫中用于有效探索性数据分析的顶级一行程序

原文:https://towardsdatascience.com/top-one-liners-in-pandas-for-effective-exploratory-data-analysis-a739b1c9de5

使用 Pandas,通过这 6 行代码轻松浏览您的数据

杰伊·温宁顿在 Unsplash 上的照片

探索性数据分析(EDA)是一种探索数据以发现有用模式的艺术,这些模式可用于创建最强大的模型。数据科学初学者的一个常见错误是直接或相当快速地进入建模,而没有花费适当的时间进行适当的 EDA。

当我问自己为什么总是犯这个错误时,我发现这是因为通常需要很多行代码来进行适当的 EDA,绘制从分布到各种属性的所有特性。拥有一个很长的笔记本只是为了探索数据,甚至没有开始建模,有时会非常令人沮丧,因此我写这篇文章来总结 6 个最有用和最常见的 pandas 函数,可以帮助你快速完成 EDA,尽快开始建模。

在本文中,我将使用 Kaggle 的泰坦尼克号数据集作为例子来演示这些熊猫函数。

1.DF 描述

当然,我不会提到著名的“df.head()”或“df.tail()”,因为几乎每个人都知道它们(它们用于显示数据帧的前 5 /后 5 行)。

df.describe()

来源:作者

如上所示,数据框描述显示了数据框中每一列的有用数量。例如,了解每列的范围(从最小和最大)是很有用的。查看要素的标准偏差是高还是低也很有用。当然,我们应该知道我们拥有的功能的数量(使用计数)

2.测向信息

df.info()

来源:作者

同样,非常简单而且非常有效。了解内存使用通常非常重要,因为机器学习中的内存不足错误是不可避免的!

3.DF 数据类型

df.dtypes

来源:作者

该属性列出了数据帧中每一列的数据类型。知道您正在处理的是数字特征还是分类特征是非常方便的,因为这将影响您将要使用的编码类型。例如,一些特征可能是字符串,而一些特征可能是数字。如果打算同时使用这两组特性,您可能需要将字符串转换为数值。

我还从经验中了解到,当您的硬件资源有限时,当您处理大型数据集时就会如此。简单的数据类型转换可能非常方便。我举个实实在在的例子。我们在这里使用的数据帧大约有 350 万行,这是相当大的。在大多数计算机上,将该数据帧加载到内存中、对其进行操作、转换和拟合模型可能会导致内存不足的错误。

在这种情况下,一个简单的技巧是检查是否可以减少在这种情况下使用的数据类型的大小。例如,dataframe 可能使用 64 位整数来表示只能用 32 位整数表示的值,对于 floats 也是如此。然后,您可以简单地对数据帧中的值进行循环,并将它们的类型转换为较小的类型。这个技巧可以使数据帧的大小减少 50%!

4.DF 应用

df.apply(lambda x: x.nunique())

来源:作者

应用采用 lambda 函数,并应用于数据框中的所有值。有大量有用的 lambda 函数可以应用。上面列出的方法可用于查找每列中不同值的数量。

5.DF 为空

df.isnull()

来源:作者

永远不要忘记检查是否有空值。我曾经忘记这样做了很长一段时间,总是以多个错误结束,包括 NaN 梯度等等。在存在空值的情况下,您需要找到最有效的方法来处理它们。一种非常常见的方法是用“平均值”替换这些值,完全删除它们,或者简单地用 0 替换它们。

6.DF 列历史记录

df['Age'].hist(figsize = (15,5))

来源:作者

这是我的最爱之一。您可以简单地指定 dataframe 中的任何列(将其名称放在方括号中),然后添加一个“.”。然后你会得到一个列值分布图!找出特征的分布是至关重要的。通常,正态分布是优选的。在偏态分布的情况下,您可能希望使用标准定标器对数据集进行归一化。如果数据集包含大量异常值,您还需要找出处理异常值的最有效方法。

结论

我确信还有更有效的俏皮话!欢迎在下面留下你的评论。我认为让 EDA 变得更容易对数据科学社区非常有帮助。我相信有更多的现代图书馆致力于实现这一目标。

如果您想定期收到关于人工智能和机器学习的最新论文的论文评论、高质量的 ML 教程等,请添加您的电子邮件此处 &订阅!

学习数据科学的顶级开源项目

原文:https://towardsdatascience.com/top-open-source-project-to-learn-data-science-dc962210d855

利用这些项目启动您的数据科学教育

马文·迈耶在 Unsplash 上的照片

学习数据科学对初学者和专业人士来说都不容易。之所以辛苦,是因为每天总有新的东西要学,但学习的内容却分散在各处。如果没有正确的指导,许多人会迷失在学习的旅途中。这就是为什么许多人认为数据科学有很高的门槛。

幸运的是,许多优秀的人已经启动了开源项目来学习数据科学。这些项目写得简洁而有见地,人们可以彻底学习。

本文将概述学习数据科学的各种开源项目。让我们开始吧。

1.维尔吉利奥

Virgilio 被称为数据科学电子学习的新导师,旨在让每个人都有机会学习数据科学。Virgilio 还试图为学习者创建一条结构化学习的路径,以避免在数据科学学习过程中不知所措的混乱。

开源项目由三层构成,以满足每个人的需求。该层被称为高级向导的 Paradiso、入门级的 Purgatorio 和高级向导的 Inferno。

作者图片

学习从天堂级别开始,这里的内容都是关于理论以及为什么你应该学习数据科学(完全没有编码),例如:

  • 机器学习和人工智能的区别是什么
  • 需要机器学习吗?
  • 使用案例
  • 教学策略

还有很多。对于开始数据科学之旅并更好地了解该领域的人来说,Paradiso 是一个完美的开始。

从天堂级别,我们移动到 Purgatorio 级别。这一级别涵盖了数据科学家的基础知识,从基础知识到动手实践,例如:

  • 数学与统计基础
  • 编程 Python 基础
  • 问题定义
  • 数据探索
  • 机器学习培训

还有很多。在数据科学领域,你可以学到你需要的一切。不用担心结构,因为 Purgatorio 也是从基础到更基础的用法开始的。

最后,高级等级是地狱等级,这部分是为高级用户准备的。本节将教您数据科学的一个具体应用:

  • 时间序列
  • 计算机视觉
  • 自然语言处理

此外,Inferno 级别为特定的数据科学工具和库提供学习材料。这个列表会随着时间的推移而增长,所以请继续关注这个项目。

Virgilio 的项目是由各个核心团队和该领域的专家开发的。如果你有兴趣,试着和这里的团队聊天,特别是为他们的事业做贡献。

2.ml 课程

MLCourse 是一个开源项目,由来自 OpenDataScienceYury Kashnitsky 领导,旨在了解更多关于机器学习的知识,学习者可以在理论和实践技能之间取得完美平衡。顾名思义,MLCourse 是一个课程项目的汇编,我们可以按照自定进度学习。

然而,这些课程稍微面向那些拥有 Python 和数学等基本数据科学技能的人。但是,这并不意味着初学者不能尝试这些课程——毕竟,他们的指南是非常有见地的。

MLCourse 包含十个主题供人们学习,这是一个结构中要遵循的主题;它们是:

  1. EDA 和熊猫
  2. 视觉数据分析
  3. 分类、决策树和 K-NN
  4. 普通最小二乘法和线性模型
  5. 制袋材料
  6. 特征工程和特征选择
  7. 无监督分析
  8. 最佳化
  9. 时间序列
  10. 梯度推进

每个主题都包含一个简单易懂的指南、范例笔记本、作业和视频课程。

MLCourse 的缺点是,针对英语的开发在 2019 年停止(俄语在 2022 年复活)。然而,这些材料仍然与我们当前的数据科学领域相关,尤其是对初学者而言。

3.ProjectLearn

ProjectLearn 是一个开源项目,它提供了一个指导项目的精选列表。ProjectLearn 的创建者的目标是更多的实践应用学习,而不是理论学习,所以你可以期望学习一个特定的技能集,而不是一个通用的。

ProjectLearn 不是专门针对数据科学的,因为你也可以学习 web、移动和游戏开发。但是,有一个专门针对机器学习和 AI 的板块,这就是我们想要的。

ML & AI 部分(图片由作者提供)

该项目的大部分是另一篇文章或视频的外部链接,但这些项目已经策划好了,非常适合那些想探索机器学习可以做什么的人。

4.迪普卡帕哈

Deepkapha 是一个开源项目,策划了许多人工智能和深度学习教程供人们学习。当我看 Deepkapha 的时候,我感觉这个项目是为有数据科学和编程基础知识的人设计的,所以当你准备好了的时候,最好去探索 Deepkapha。

很多 Deepkapha 专注于深度学习和各种框架教程,如果你想学习深度学习的概念和框架之间的差异,这是非常完美的。然而,你仍然可以探索许多学习材料,尽管它们不是那么具体。

我认为另一个特别的部分是深度学习博客集,它由各种作家和深度学习博客组成。这个收藏如此完整,以至于浏览所有的博客可能要花上几天时间。

5.最佳 ML Python

Best-of ML Python 是 Best-of 开源项目的一部分,该项目每天管理各种开源包和工具。最佳 ML Python 是专门针对 Python 编程语言的精选开源机器学习包的。

最佳系列没有具体给出如何学习基本概念的教程。然而,相反,他们将所有令人敬畏的 Python 包进行了分类,供我们试用。

最佳 ML Python 项目列表(GIF 由作者提供)

从上面的 GIF 可以看出,这个列表很丰富,并且根据你的需要进行了细分。通过 Python 包学习某个特定主题所需的几乎所有东西都存在,所以尽可能多地尝试探索。

结论

学习数据科学并不容易,当我们不知道从哪里开始时,可能会感到困惑。这就是为什么在本文中,我想展示我学习数据科学的顶级开源项目。这些项目是:

  1. 维尔吉利奥
  2. ml 课程
  3. ProjectLearn
  4. 迪普卡帕哈
  5. 最佳 ML Python

希望有帮助!

在我的LinkedInTwitter 上访问我。

如果您喜欢我的内容,并希望获得更多关于数据或数据科学家日常生活的深入知识,请考虑在此订阅我的 简讯。

如果您没有订阅为中等会员,请考虑通过 我的推荐 订阅。

在数据准备过程中必须使用的热门 Python 关键字

原文:https://towardsdatascience.com/top-python-keywords-that-you-must-use-in-your-data-preparation-process-290536a46576

为初学者提供易于理解的示例

Theo Crazzolara 在 Unsplash 上的照片

你有数据。

你需要洞察力。

不幸的是,在您从数据中获得任何洞察力之前,您需要处理数据准备过程。

此时,有常用的 Python 关键字帮助您完成基本的数据准备任务。

在本文中,我将通过简单的例子来解释那些顶级 Python 关键字以及它们在数据准备过程中的用途。

什么是关键字

Python 关键字是保留字,不能用作变量名、函数名或任何其他标识符,因为它们在 Python 语言中有特定的用途和含义。

Python 3.835 个关键字,列举如下:

False      await      else       import     pass
None       break      except     in         raise
True       class      finally    is         return
and        continue   for        lambda     try
as         def        from       nonlocal   while
assert     del        global     not        with
async      elif       if         or         yield

你不必导入 关键词,因为它们总是可用的,但它们需要完全按照上面的写法拼写。

Python 关键字可分类如下:

  • 导入关键词:importfromas
  • 结构关键词:defclasswithpasslambda
  • 价值关键词:TrueFalseNone
  • 操作员关键词:andornotinis
  • 控制流关键字:ifelifelse
  • 迭代关键词:forwhilebreakcontinue
  • 返回关键词:returnyield
  • 异常处理关键字:tryexceptraisefinallyassert
  • 异步编程关键词:asyncawait
  • 变量处理关键字:delglobalnonlocal

什么是数据准备

数据准备过程包含一组预建模任务。这些任务可以分类如下:

  • 数据清理:纠正或删除数据集中不正确、损坏、缺失、重复或不完整的数据
  • 特征选择:定义与任务最相关的输入变量。
  • 数据转换:改变数据的规模或分布。
  • 特征工程:从可用数据中推导出新变量。
  • 降维:减少数据集中输入变量的数量,同时保持尽可能多的变化。

使用哪种特定的数据准备任务取决于将用于建模的数据和算法。

数据准备任务中使用的热门 Python 关键字

‘导入’和‘as’

在数据科学项目中执行特定任务时,不要重新发明轮子,您需要使用其他人的模块和库。要使用这些库,您需要使用导入关键字将它们导入到您的代码中,例如‘import’as’,以及from’

**import** pandas **as** pd
**import** numpy **as** np

在上面的代码中, pandas 和 numpy,库被导入。我们将在后面的代码中使用这些模块。‘as’关键字在这里帮助我们重命名模块。当使用长名称的模块时,或者当需要分隔名称空间时,这尤其有用。

‘def’

‘def’用于定义一个 python 函数。函数在数据科学项目中大量使用。它们帮助我们将大的代码块转换成逻辑的和可管理的部分。

让我们创建一个函数来打印数据框列中缺失项目的计数。

**def** missing_item_count(**df**):

for 和 in

一种常见的做法是循环遍历数据帧、或复杂的数据对象中的项目,如字典列表中的中的对这样的任务来说是绝配。下面你可以看到,我们可以用关键字的得到‘Airbnb’data frame 的列。

我们的循环从关键字的开始,然后我们添加变量‘col’来分配数据容器的每个元素,后面是关键字中的’。在'关键字中的之后,最后是【df . columns】,它是数据容器本身。

**airbnb_url** = 'https://raw.githubusercontent.com/ManarOmar/New-York-Airbnb-2019/master/AB_NYC_2019.csv'
**airbnb** = pd.read_csv(**airbnb_url**)**def** missing_item_count(**df**):
  **for** col **in** df.columns:
    **missing_item_count** = df[**col**].isna().sum()
    print(f'Column {**col**} has {**missing_item_count**} missing items')missing_item_count(**airbnb**)**Output:** Column **id** has 0 missing items 
Column **name** has 16 missing items 
Column **host_id** has 0 missing items 
Column **host_name** has 21 missing items

现在,在 for 循环中,我们可以迭代 df.column 对象中的项,并在 'col' 变量中获取它们。

“如果”和“否则”

‘如果’‘否则’控制流关键字用于决策。代码块的执行取决于测试表达式的值。

**def** missing_item_count(**df**):
  **for** col **in** df.columns:
    **missing_item_count** = df[**col**].isna().sum()

    **if** **pct**:
      print(f'Column {**col**} has {**missing_item_count**} missing items')
    **else:**
      print(f'Column {**col**} has ZERO missing item')missing_item_count(**airbnb**)**Output:**
Column **id** has ZERO missing item 
Column **name** has 16 missing items 
Column **host_id** has ZERO missing item 
Column **host_name** has 21 missing items

在上面的代码中,如果 missing_item_count 变量是 True (如果在我们的例子中它不是一个零整数,它打印列名和 missing_item_count 值。

如果 missing_item_count 变量为 False,(如果是零整数则为)则执行 else 关键字内的代码块。

这就是你如何用‘if’和‘else’关键字控制你的代码流。

关键要点和结论

  • Python 关键字是保留字,有特定的含义和用途。您不必 关键字导入到您的代码中,因为它们总是可用的
  • ‘def’用于定义一个 python 函数。函数在数据科学项目中大量使用。它们帮助我们将大的代码块转换成逻辑的和可管理的部分。
  • 【if】****【else】控制流关键字用于决策。代码块的执行取决于测试表达式的值。
  • 一种常见的做法是循环遍历数据帧、或复杂的数据对象中的项目,如字典列表中的中的对这样的任务来说是绝配。

我希望你已经发现这篇文章很有用,并且你将开始在你自己的代码中使用上述关键词。

可视化顶级 Python 库:入门指南

原文:https://towardsdatascience.com/top-python-libraries-for-visualization-a-starting-guide-73402178811b

Python 中散点图、热图、脊线图和线图绘制指南

丹尼尔·奥拉在 Unsplash 上的图片。

鉴于 Python 中有大量的库和数据可视化的可能性,对于该领域的新手来说,浏览这些库很快就会变得困难,甚至有些力不从心。有大量的选项可供选择,但是知道哪一个适合你(以及为什么)是有效展示数据的重要一步。在本文中,我们将重点关注几个用于有效数据可视化的关键库,并提供了在任何数据集中实现的清晰工作示例。

什么是数据可视化?

通俗地说,数据可视化是利用图形显示来显示原始数据的“艺术”。更具体地说,它对于探索数据结构、检测异常值、趋势和聚类以降低数据复杂性非常有用。因此,有效的数据可视化将有助于在人脑易于理解的视觉环境中向目标受众传达数据。

数据可视化的前景将会持续下去,并随着技术的进步而继续发展,在科学出版物、媒体和网站展示中留下越来越显著的足迹。更精确的复制、更好的颜色(包括阿尔法混合)和更快的绘图是过去十年中迅速改进的一些变量。

此外,在开发图形理论方面也取得了进展,如威尔金森的 Grammar of Graphics (2005)和哈德利·威克姆在 R 包 ggplot2 中对其的实现(威克姆,2016)。在这样做的过程中,过去很少使用且难以绘制的图形,如平行坐标图(如 Theus,2015)和镶嵌图(如 Unwin,2015),现在都得到了完善和发展。

为什么要用 Python 进行数据可视化?

有许多用于数据可视化的非代码工具,比如 Tableau、Power BI、ChartBlocks、Prism 等等。然而,即使编程是必需的,Python 也是数据科学家的首选语言之一,因为它具有可视化功能。这还伴随着用于数据操作和转换的数据收集和探索库(例如 Pandas、NumPy、SciPy)。Python 已经有了许多可用于可视化的库和特性,由于其庞大的用户群和开源特性,这些库和特性还将继续增长。随着技术领域的不断发展,Python 在未来几年内将继续保持其作为数据科学家首选语言的地位。

库安装和数据集准备

用 Python 绘制统计图形的方法有很多,但是我更喜欢用下面列出的库来创建。在本文中,我们将使用以下工具重点绘制热图、散点图、折线图和脊线图:

  • 快乐
  • 海生的
  • plotly.express

出于一般兴趣,我总结了关键的库信息,并提供了源文档的链接:

  • Plotly Express 是一个高级 Python 可视化库,作为 Plotly.py 的包装器,为复杂的图表提供简单的语法。它可以用于在一个函数调用中制作丰富的交互式绘图,包括分面、地图、动画和趋势线。Plotly Express 也完全兼容 Plotly 生态系统的其余部分。
  • Seaborn 构建在 matplotlib 之上,通过捕获整个数据帧或包含数据的数组来工作,并执行必要的内部函数进行语义映射和统计聚合,以生成信息丰富的图。
  • Joypy 是一个基于 matplotlib 和 pandas 的单功能 Python 包,目的只有一个:绘制 joyplots(即脊线图)。这个库对于以清晰的方式可视化数据分布非常有用。

库安装

如果还没有,请运行以下命令行通过终端安装这些库:

pip install seaborn
pip install joypy
pip install plotly

完成后,我们将导入以下结节,然后继续:

import numpy as np
import pandas as pd
import seaborn as sns
from joypy import joyplot
import plotly.express as px
from scipy import stats
import matplotlib.pyplot as plt

加载数据集

没有数据,我们无法想象任何东西。因此,在我们逐步完成一系列绘图示例之前,我们将使用seaborn库加载以下关于航班的内置(常用)python 数据集:

# Load a dataframe
flights_data = sns.load_dataset("flights")# Display dataset
flights_data.head()

航班数据数据框示例。图片由作者提供。

散点图

可以使用plotly.express制作基本散点图,灵活地改变其宽度和高度,以获得更佳的图像输出。模板也可以从simple_white更改为包含网格和更深的颜色:

px.scatter(flights_data, x=”year”, y=”passengers”, width=700, height=600,template=”simple_white”)

作者使用 plotly.express. Image 的基本散点图示例。

值得注意的是,plotly.express非常适合颜色排序,这就是为什么我更喜欢用它来可视化分组数据。您还可以选择将颜色从离散颜色序列(如下所示)更改为连续颜色方案,这对于连续数据测量非常有效。总的来说,不同的颜色可以赋予不同的数据组,以提高视觉清晰度。

#group data 
flights_data.loc[flights_data.year <= 1954 , 'group'] = '<= 1954'
flights_data.loc[flights_data.year > 1954 , 'group'] = '> 1954'

#re-plot data with discrete color scheme
px.scatter(flights_data, x="year", y="passengers", width=700, height=600, template="simple_white", color="group", color_discrete_sequence=['red','blue'])

Plotly.express 带组显示的散点图。红色和蓝色分别对应≤ 1954 和> 1954 飞行年。图片由作者提供。

如果您和我一样,不喜欢散点图的默认美学,这里有一些有用的示例,可以用来更改刻度长度、字体大小、轴标题、标记颜色等等:

#size dimension change
fig1 = px.scatter(flights_data, x="year", y="passengers", width=700, height=450,template="simple_white", color="group",color_discrete_sequence=['red','blue'])#tick font and size change
fig1.update_layout(
yaxis = dict(
tickfont = dict(size=20)),
xaxis = dict(
tickfont = dict(size=20)),
font_family="Arial")#x-axis title and size + tick length changes
fig1.update_xaxes(
title_text = "Year of flight",
title_font = {"size": 20},
title_standoff = 15, ticklen=10)#y-axis title and size + tick length and value changes
fig1.update_yaxes(
title_text = "Passengers",
title_font = {"size": 20},
title_standoff = 15, ticklen=10, tickvals=list(range(0,700,100)))#marker size, outline and color change 
fig1.update_traces(marker=dict(size = 9,
line=dict(width=0.8, color='white')),
selector=dict(mode='markers'))#legend off 
fig1.update_layout(showlegend=False)

fig1.show()

作者使用 plotly.express. Image 调整了标记和字体大小,以及刻度长度和字体样式。

值得注意的是,您可以从px.colors.qualitative模块中选择以下任何内置的定性颜色序列,或者定义您自己的颜色序列:

ploty.express 调色板示例。图片由绘声绘色

线形图

尽管plotly.express可以选择添加趋势线,这里我们展示了如何使用seaborn库对现有数据实现填充的趋势线。这对于可视化变量之间的关系特别有帮助。在年份和乘客变量的情况下,可以看到线性关系,因此趋势线将有助于加强这一点。

#use lmplot to plot scatter points
sns.set(font_scale = 1.6)
sns.set_style("white")
fig2 = sns.lmplot(data = flights_data, x="year", y="passengers", height=5, aspect=1.64, legend=False, line_kws={'color': 'black'}, scatter_kws={"color": "black"})#change axis titles
fig2.set(xlabel='Year of flight', ylabel='Passengers')

带有填充趋势线的 seaborn 散点图示例。图片由作者提供。

为了保持先前数据组的配色方案,我们可以为特定的数据点指定颜色。填充了趋势线也可以应用于整个数据集,如下所示:

#get coeffs of linear fit
slope, intercept, r_value, p_value, std_err = stats.linregress(flights_data['year'],flights_data['passengers'])#use lmplot to plot scatter points
sns.set(font_scale = 1.6)
sns.set_style("white")
sns.lmplot(data = flights_data, x="year", y="passengers", height=5, aspect=1.64, hue="group", fit_reg= False, legend=False, palette=["red","blue"])#use regplot to plot the regression line and use line_kws to set line label for legend
fig3 = sns.regplot(data = flights_data, x="year", y="passengers", scatter_kws={"zorder":-1}, line_kws={'label':"y={0:.1f}x+{1:.1f}".format(slope,intercept)}, color="black")#change axis titles
fig3.set(xlabel='Year of flight', ylabel='Passengers')

第 1 组和第 2 组的 Seaborn 散点图,带有填充的趋势线和不同的配色方案。图片由作者提供。

或者,可以使用以下代码将单独的填充趋势线应用于每个组:

#use lmplot to plot scatter points
sns.set(font_scale = 1.6)
sns.set_style("white")
fig4 = sns.lmplot(data = flights_data, x="year", y="passengers", height=5, aspect=1.64, hue="group", palette=["red","blue"], legend = False)#change axis titles
fig4.set(xlabel='Year of flight', ylabel='Passengers')

使用色调填充趋势线的 Seaborn 散点图。图片由作者提供。

在所有情况下,为了简化数据,每个相应 x 值的所有 y 值的平均值(或中值)可以显示如下:

#set fontsize
sns.set(font_scale = 1.6)
sns.set_style("white")fig5 = sns.regplot(data = flights_data, x="year", y="passengers", x_estimator=np.mean, color = "black")#set fig size
fig5.figure.set_size_inches(8.2, 4.5)#change axis titles
fig5.set(xlabel='Year of flight', ylabel='Passengers') #despine
sns.despine()

Seaborn 散点图,填充趋势线,x_estimator = np.mean。图片由作者提供。

脊线图

观察折线图和散点图很容易看出,各组内的数据分布有很大差异。Python 中的 Joyplots 或 ridgeline plots 是可视化所述分布的绝佳方法,同时提供对分布类型(如正态、伽玛、贝塔)的洞察。作为复习,可以在 这里 找到这些的精彩总结。

我特别喜欢用 Python 可视化 joyplots 或 ridgeline plots 的一个库是— joypy.它归结为一个函数调用,使其易于使用和修改。

# x variables to plot with corresponding text
xvar = ['year', 'passengers']
xlabel = ['Year of flight', 'Passengers']for x,xlabel in zip(xvar,xlabel):
    joyplot(data = flights_data[[x, "group"]], 
            by="group", figsize=(10, 4), 
            labels = ["Group 1","Group 2"],
            linecolor = 'black',
            color = ['red','blue'], 
            alpha = 0.85, 
            linewidth=3, overlap = 0.9)
    plt.rc("font", size=24)
    plt.xlabel(xlabel, fontsize = 24)
    plt.show()

组 1 和组 2 的脊线图示例。图片由作者提供。

当然,这是两个任意组的一个简化的脊线图,你能用这个库做的事情取决于用户。更多文档可在 此处 找到,并提供更多示例以获取灵感。

热图

热图可以通过彩色编码叠加提供数据集的简化摘要。为了实现这一点,seaborn库为热图绘制提供了多种选项。

对于这个例子,我已经通过“year”对数据集进行了分组,并将均值和中值输出生成到一个连接的数据帧中。这使我能够在生成热图之前简化数据集:

#grouped flights_data and calculated mean
grouped_df = flights_data.groupby("year")
mean_df = grouped_df.mean()
mean_df.rename({'passengers': 'Mean'}, axis=1, inplace=True)
mean_df = mean_df.reset_index()#grouped flights_data and calculated median
median_df = grouped_df.median()
median_df.rename({'passengers': 'Median'}, axis=1, inplace=True)
median_df = median_df.reset_index()#concat dataframes
data_concat = pd.concat([median_df['Median'], mean_df['Mean']], axis=1, ignore_index=False)#display 
data_concat.head()

data_concat 数据帧。图片由作者提供。

完成后,您可以绘制每年的热图:

#finding y-axis titles
y_axis_labels = flights_data.year.unique()# plot heatmap
fig, ax = plt.subplots(figsize=(6,10)) 
fig7 = sns.heatmap(data_concat, cmap="vlag", linewidth=0.1, annot=data_concat, fmt=".2f", cbar_kws={'label': 'Passengers', "shrink": .4}, annot_kws={"size": 16}, yticklabels=y_axis_labels)# set yticks and axis label
plt.yticks(rotation=0) 
fig7.set(ylabel='Year of flight')

使用 seaborn 库的热图示例。不同的列对应于每个分组飞行年的中间值和平均值。图片由作者提供。

结论

当然,数据科学领域有大量可用于数据可视化的工具,这些工具在不断改进和变化。然而,对于任何刚接触 Python 语言的人来说,保持更新和导航可能是一项有些难以完成的任务。

总结一下——seaborn``joypyplotly.express等关键库为初次接触 Python 数据可视化的人提供了一个有效的起点。在本文中,我们利用这些数据生成散点图、热图、折线图和带有简单数据集的喜悦图。

我希望你喜欢读这篇文章,就像我喜欢写它一样。

在接下来的文章中,我将深入研究机器学习和深度学习理论,以及进一步的数据可视化技术。

用于要素工程的顶级 Python 包

原文:https://towardsdatascience.com/top-python-packages-for-feature-engineering-c0a75dba0081

了解这些软件包以改进您的数据工作流程

马库斯·斯皮斯克在 Unsplash 上的照片

特征工程是从现有数据创建新特征的过程。无论我们是简单地增加两列还是组合一千多个特性,这个过程都已经被认为是特性工程了。

特征工程过程本质上不同于数据清理。虽然特征工程会创建附加特征,但数据清理可能会更改或减少现有特征。

特征工程是数据工作流程的重要组成部分,因为这项活动可以极大地提高我们的项目绩效。例如,希顿 (2020)的实证分析表明,特征工程提高了各种机器学习模型的性能。

为了帮助特征工程过程,本文将介绍我的用于特征工程的顶级 Python 包。让我们开始吧!

1.功能工具

Featuretools 是一个开源的 Python 包,用于自动化由 Alteryx 开发的特性工程过程。这是一个为从我们拥有的任何特征,尤其是从时态和关系特征中进行深度特征创建而设计的包。

深度特征合成(DFS)是 Featuretools 活动的核心,因为它允许我们快速从数据中获取新特征。如何执行?让我们使用 Featuretools 中的示例数据集来做这件事。首先,我们需要安装软件包。

pip install featuretools

接下来,我将加载已经来自包的玩具数据集来执行深度特征合成。

import featuretools as ft#Loading the mock data
data = ft.demo.load_mock_customer()cust_df = data["customers"]
session_df = data["sessions"]
transaction_df = data["transactions"]

所有来自 Featuretools 模拟数据的数据集(图片由作者提供)

在上面的数据集中,我们有三个不同的连接数据集:

  • 客户表(唯一客户)
  • 会话表(客户的唯一会话)
  • 事务表(会话事务活动)

在某种程度上,所有的数据集都与它们各自的键相关联。要使用 Featuretools DFS,我们需要用 dictionary 对象指定表名和主键(如果有 DateTime 特性,我们也将其添加为键)。

dataframes = {
    "customers": (cust_df, "customer_id"),
    "sessions": (session_df, "session_id", "session_start"),
    "transactions": (transaction_df, "transaction_id", "transaction_time"),
}

然后我们需要指定表之间的关系。这很重要,因为 DFS 将依赖这种关系来创建特性。

relationships = [
    ("sessions", "session_id", "transactions", "session_id"),
    ("customers", "customer_id", "sessions", "customer_id"),
]

最后,我们可以启动 DFS 流程。为此,我们可以运行下面的代码。重要的是需要为您想要的结果级别指定target_dataframe_name参数。例如,该代码将导致客户级别的特性工程。

feature_matrix_customers, features_defs = ft.dfs(
    dataframes=dataframes,
    relationships=relationships,
    target_dataframe_name="customers",
)
feature_matrix_customers

作者图片

从上图中我们可以看到,客户数据有了新的特性,会话和事务表有了各种新的特性;例如,某些特征的计数和平均值。用很少的台词,我们制作了很多特写。

当然,并不是所有的特征都有助于机器学习建模,但这是特征选择的工作。在我们的例子中,特征工程只关心创建特征。

如果您需要对每个特性的解释,我们可以使用下面的函数。

feature = features_defs[10]
ft.describe_feature(feature)

作者图片

2.特征引擎

特征引擎是一个开源的 Python 包,用于特征工程和选择过程。这个包就像一个转换器,类似于 scikit-learn 函数,比如fittransform

特征引擎有多大价值?当您已经有了一个机器学习管道时,这是有益的,主要是如果您使用基于 scikit-learn 的 API。功能引擎转换器旨在与 scikit-learn 管道一起工作,并与 scikit-learn 包进行类似的交互。

在特性引擎包中有许多 API 可以尝试,但是就本文的目的而言,我们将只关注可用的特性工程功能。对于功能工程,我们可以尝试三种 API:

让我们尝试所有的变形金刚来测试特征工程过程。对于初学者,我将使用 seaborn 的示例 mpg 数据集。

import seaborn as snsdf= sns.load_dataset('mpg')

作者图片

首先,我想尝试一下特征工程数学函数的MathFeatures函数。为了做到这一点,我将使用我们想要做的列和转换来设置转换器。

from feature_engine.creation import MathFeaturestransformer = MathFeatures(variables=["mpg", "cylinders"],
func = ["sum", "min", "max", "std"])

设置完成后,我们可以使用转换器来转换原始数据。

df_t = transformer.fit_transform(df)
df_t

作者图片

正如我们在上面看到的,我们的特征工程过程中有新的栏目。列名已经被很容易地陈述,以便理解在这个过程中发生了什么。注意,我们总是可以将我们的函数传递给 transformer 函数来进行计算。

我们还可以尝试使用RelativeFeatures函数来创建一个使用引用变量来开发特性的转换器。

from feature_engine.creation import RelativeFeaturestransformer = RelativeFeatures(
variables=["mpg", "weight"],
reference=["mpg"],
func = ["sub", "div", "mod"])df_r = transformer.fit_transform(df)
df_r

作者图片

从上面的结果中我们可以看到,新创建的列都是基于引用特征(' mpg ');例如,重量减去 mpg。这样,我们可以根据我们想要的功能快速开发功能。

3.Tsfresh

Tsfresh 是一个开源的 Python 包,用于时序和序列数据特征工程。这个包允许我们用几行代码创建数千个新功能。此外,该包与 Scikit-Learn 方法兼容,这使我们能够将该包合并到管道中。

来自 Tsfresh 的特征工程是不同的,因为提取的特征不能直接用于机器学习模型训练。这些功能用于描述时间序列数据集,需要额外的步骤才能将数据包含到训练模型中。

让我们用一个示例数据集来试试这个包。对于这个示例,我将使用来自 Kaggle 的 DJIA 30 股票数据(许可证: CC0:公共域)。具体来说,我将只使用 2017 年的所有股票数据。我们来读一下数据集。

import pandas as pd
df = pd.read_csv('all_stocks.csv')#cleaning the data by dropping nan values
df = df.dropna().reset_index(drop = True)df

作者图片

股票数据包含作为时间索引的日期列和作为股票引用的名称列。其他列是我们想用 Tsfresh 描述的值。

让我们使用下面的代码来测试这个包。

from tsfresh import extract_features
extracted_features = extract_features(df, column_id="Name", column_sort="Date")extracted_features

作者图片

extracted_features.columns

作者图片

从上面的结果可以看出,提取的特征包含大约 3945 个新特征。这些特性都是对可用特性的描述,随时可以使用。如果你想知道每个特性的描述,你可以在这里阅读全部

我们还可以使用特征选择功能来只选择相关的特征。您可以在下面的上阅读功能选择。

结论

要素工程是从现有数据集创建新要素的活动。该行动被证明有助于改善数据科学项目。但是,创建我们的功能可能需要很长时间。

本文展示了我为本文中的特性工程过程编写的顶级 Python 包。它们是:

  1. 功能工具
  2. 特征引擎
  3. Tsfresh

希望有帮助!

访问我的 社交媒体进行更深入的交谈或有任何问题。

如果您不是作为中等会员订阅,请考虑通过 我的推荐 订阅。

获取数据集的热门 Python 包

原文:https://towardsdatascience.com/top-python-packages-to-acquire-dataset-3c1b4a31a287

利用这些数据集改善您的数据科学产品组合

托拜厄斯·菲舍尔在 Unsplash 上的照片

学习数据科学并不容易,产生学习成果的过程也不容易。您的数据科学项目组合是被评估为输出的东西。无论你是否理解数据科学过程,它都会反映在投资组合中。

然而,有时我们不能实现我们的意图,有预期的项目,因为数据不可用。在我的教学时间里,我知道许多学生会问,“在哪里可以轻松地为我们的数据科学项目获取数据集?”。这个问题引起了我的共鸣,所以我在写这篇文章。

我想在本文中分享我的顶级 python 包来获取数据集。让我们开始吧。

1.seaborn/Scikit-Learn/stats models

从我们常见的数据科学 Python 包开始:Seaborn、Scikit-Learn 和 Statsmodels。这三个包本质上有不同的可用性,但是它们有共同点——一个内置的数据集。让我们看看这些包中的每个数据集。

海生的

Seaborn 是一个可视化软件包,有我们可以用来做实验的基本数据集。让我们尝试获取数据集列表以及如何获取它。

import seaborn as snssns.get_dataset_names()

作者图片

从 seaborn 包中,我们有 19 个不同的数据集可以探索。如果您想要为您的环境获取数据集,让我们使用下面的代码行。

titanic = sns.load_dataset('titanic')titanic.head()

作者图片

sci kit-学习

Scikit-Learn 包含各种用于玩具和真实世界数据集的 API,我们可以利用它们进行实验。

作者图片

对于每个数据集,都有一个 API 来加载该特定数据集。例如,您可以使用以下代码行加载 Iris 数据集。

from sklearn.datasets import load_iris
data = load_iris()
data.target[[10, 25, 50]]data.keys()

作者图片

所有数据集都包含在字典中,您可以将它们加载到另一个变量中进行研究。

统计模型

Statsmodels 是一个用于统计建模的 Python 包,但该包也提供了各种数据集供用户探索。下图显示了可用的数据集。

作者图片

要从 statsmodels 获取数据集,我们可以使用下面的代码行。例如,我们可以用朗利数据集。

data = sm.datasets.longley.load_pandas()
data.data

作者图片

您可以访问参考页面以获得每个数据集的详细信息。

2.Pydataset

Pydataset 是一个 Python 包,提供各种开源数据集。这些包中的许多数据集可能是您之前在介绍性数据科学学习中发现的,如 Titanic 和 Iris。

但是,这并不意味着 pydataset 不是一个好的数据集包。我发现很多数据集对你的初始项目很有帮助。

让我们试着探索我们能得到什么样的数据集。首先,我们需要安装 pydataset 包。

pip install pydataset

成功安装软件包后,我们需要导入下面一行来获取所有数据集列表。

from pydataset import datadata()

作者图片

我们最终得到了 757 个数据集。有很多数据集需要探索。

如果我们想检查每个数据集的细节,该怎么办?然后我们可以用下面的代码行。

#Pass the dataset_id to the first parameter and show_doc = True
data('BJsales', show_doc=True)

作者图片

所有的数据集信息都在你的可及范围内,并且是有用的。现在,我们只需要用下面的代码获取数据集。

bjsales = data('BJsales')bjsales.head()

作者图片

Pydataset 非常易于使用和直观。然而,除了基本数据集之外,您可能还需要其他东西。所以,让我们来看看其他的包。

3.NLTK

NLTK 是一个专门用于自然语言处理工作的 Python 包。它提供了各种与文本相关的任务 API。对于我们的使用,NLTK 还提供了一个文本数据集,我们可以将其用于我们的项目。

大约有 111 个来自 NLTK 的文本数据集可供我们使用。完整列表请参见本页。让我们尝试从 NLTK 获取一个数据集。

import nltk# Download the abc corpus 
nltk.download('abc')

作者图片

数据集现在已经下载完毕,可供我们使用。出于探索的目的,我们可以使用下面的代码行来访问数据。

abc.words()

作者图片

单词列表现在是可用的。其他数据集包含的数据不仅仅是单词,所以请根据您的需求进行探索。

4.数据集

Datasets 是 HuggingFace 专门为访问和共享数据集而创建的 Python 包。数据集包旨在快速获取自然语言处理(NLP)、计算机视觉和音频任务数据,尤其是用于深度学习建模。

数据集包的伟大之处在于,无论数据集有多大,您都可以通过零拷贝读取来处理数据集,而没有任何内存限制,因为数据集在后台使用 Apache Arrow。您可以查看数据集 HuggingFace hub 以获得完整的 2600+数据集列表。

让我们试着用 Datasets 包加载样本数据集。首先,我们需要安装软件包。

pip install datasets

首先,我们需要决定要将哪些数据集加载到我们的环境中。在您知道您想要什么数据集之后,让我们使用下面的行来读取数据集元数据信息。

from datasets import load_dataset_builder#I want the IMDB dataset
dataset_builder = load_dataset_builder('imdb')

作者图片

使用load_dataset_builder函数,我们可以推断数据集特性和可用的特定数据集子集。

print(dataset_builder.info.features)

作者图片

print(dataset_builder.info.splits)

作者图片

我们可以获得数据集特征(“文本”、“标签”)和可用子集(“训练”、“测试”、“无监督”)。此外,每个输出包含更详细的信息。

让我们尝试加载数据集。我们将使用下面几行来加载 IMDB 数据。

from datasets import load_dataset#We load the train dataset subset from IMDB dataset
dataset = load_dataset('imdb', split='train')

上面的代码行将让我们从 IMDB 获取列车数据。让我们看看完整的数据集信息。

print(dataset.info)

作者图片

我们也可以使用下面几行来访问列名。

dataset.column_names

作者图片

如果我们想更详细地查看数据集,我们总是可以访问类似于 Pandas API 的数据集。例如,如果我想访问 IMDB 数据集中的第一个数据,我将使用零索引子集。

dataset[0]

作者图片

或者,如果我们想要访问列方式,我们只需要选择具有特性名称的数据集。当我们按特征选择时,数据集本身将是一个列表对象,以便我们可以使用零索引进一步选择它。

dataset['text'][0]

作者图片

您可以使用以下页面了解有关数据集包可用性的更多信息。

5.打开数据集

Opendatasets 是一个 Python 包,用于从在线资源下载数据集,尤其是 Kaggle 和 Google Drive。此外,opendatasets 提供了我们可以从包中内置使用的各种数据集。

要开始从 Kaggle 数据集下载数据集,我们需要登录 Kaggle 网站并获取 API。从 Kaggle 部分的 API 中,您将获得包含您的用户名和密钥的 kaggle.json 文件。

**{"username":"YOUR_KAGGLE_USERNAME","key":"YOUR_KAGGLE_KEY"}**

让我们从安装包开始。我们将使用下面一行来安装 Opendatasets。

pip install opendatasets

要开始从 Kaggle 下载数据集,我们需要找到您想要获取的链接数据集。在这个例子中,我将尝试从 Kaggle 下载美国选举数据集。

import opendatasets as odod.download('https://www.kaggle.com/tunguz/us-elections-dataset'

作者图片

在开始下载之前,您需要提供您的 Kaggle 用户名和密钥。数据集文件夹将位于您的 Jupyter 笔记本目录路径中。

此外,还有可从 Opendatasets 包中下载的内置数据集。下图是您可以获取的数据集。

作者图片

od.download('stackoverflow-developer-survey-2020')

作者图片

您下载的数据集也将出现在您的目录中。

结论

每个数据科学项目都需要一个合适的数据集来处理。没有数据集,我们就无法开展数据项目。在本文中,我想概述一下我用来获取数据集的顶级 Python 包。这些软件包是:

  1. seaborn/Scikit-Learn/stats models
  2. Pydataset
  3. NLTK
  4. 数据集
  5. 打开数据集

希望有帮助!

在我的 LinkedInTwitter 上访问我。

请不要错过我的内容,点击此处订阅我的 时事通讯,获取更多关于数据的深入知识,提升您的数据科学事业。

如果您没有订阅为中等会员,请考虑通过 我的推荐 订阅。

招聘经理对数据科学家候选人的最高要求

原文:https://towardsdatascience.com/top-qualities-hiring-managers-look-for-in-data-scientist-candidates-2e2cd52444c2

蒂姆·莫斯霍尔德在 Unsplash 上的照片

招聘经理对数据科学家候选人的最高要求

其中一些可以说比编写高效的代码更重要

随着 2021 年接近尾声,我反思了过去一年我的数据科学之旅,并意识到我最自豪的成就之一是帮助团队聘请了两位我曾与之合作过的最优秀的数据科学家。他们出色的工作无疑帮助我晋升为数据科学经理。

在新的一年里,我将成为我的团队的正式招聘经理,就像我最喜欢的一位经理告诉我的那样,“正确的招聘将极大地有助于你成为一名成功的经理”;这促使我反思自己过去作为面试官在招聘过程中的成功,并整理了从中得到的一些经验。希望这可以作为我和其他数据科学经理的备忘录,告诉他们在招聘过程中我们应该注意哪些品质,也可以作为有抱负的数据科学家的指南,告诉他们经理重视哪些品质/技能,会让你成为更好的数据科学家。

  • 学习能力/意愿

这可以说是我在候选人身上寻找的最重要的技能/属性;因为让我们面对它,数据科学是一个快速发展的领域,在这个领域中,跟上的唯一方法是不断学习。

不断有新的工具、算法和方法被引入;因此,让团队中的人拒绝适应新事物是极其令人沮丧的,因为他们“习惯”或“熟悉”其他东西。我经常看到这种对需要学习新事物的恐惧影响了人们的判断——例如,对需要学习 Looker 的恐惧可能会导致人们强烈推动使用 Tableau。不要误解我,我不是说 Looker 比 Tableau 好,也不是说团队不能推迟关于技术堆栈、工具和其他事情的决策;但是我不能接受推后的基础是没有能力和/或不愿意学习新事物。

如何在面试中检验这一点:

你可以测试候选人的学习意愿和适应能力,方法是询问他们某个时候他们缺乏某个职位所必需的技能,以及他们是如何处理这种情况的。同样,通过询问他们最近一次主动学习与其领域相关的新技能是在工作中还是在业余时间,来测试他们的动力。

如何培养这项技能:

学习的能力就像肌肉——你必须不断训练它,使它保持活跃。做到这一点的最好方法是让自己跟上该领域的发展趋势,要么随意阅读该主题的相关文章(medium 是一个很好的平台),要么定期通过参加在线课程(例如通过 Udemy 或 Coursera)有意识地提升自己的技能。

  • 既讲代码又讲业务

编码能力对于优秀的数据科学家至关重要,这就是为什么几乎每个数据科学职位都有一个技术回合。但同样重要但有时被忽视的是理解业务的能力。如果没有商业头脑,数据科学家将永远是任务的被动实施者,而不是他们应该成为的主动思考伙伴。此外,只有当你真正理解这些问题以及它们如何适应更大的业务时,你才能以创造性的方式解决问题,而不需要指望别人开出解决方案。

如何在面试中检验这一点:

在技术挑战之上,构建一个候选人必须完成的商业案例。商业案例应该与工作描述紧密结合。如果该角色将进行大量的指标分析,那么该案例可能是一个指标分解类型的问题;如果这个角色主要是建立模型,那么这个案例可以是一个真实的商业场景,候选人可以通过头脑风暴找到建模的解决方案。

如何培养这项技能:

培养这种技能的最好方法是跳出你的直接范围,尽可能多地了解公司里其他人的工作。在我看来,与不同角色的人交谈,了解他们的工作,思考他们的角色如何融入公司,是培养商业头脑的最佳方式。

此外,让自己熟悉公司的战略,练习问问自己,你的每一项工作是如何与公司的优先事项相匹配的。最后,关注最新的行业新闻和发展,这样你就能了解公司当前路线图之外的业务背景。

  • 利益相关者管理

如今,公司正试图通过让数据科学家嵌入各种不同的团队或与其密切合作,在整个业务中实现数据驱动的决策。因此,管理利益相关者已经成为数据科学家日常工作的重要组成部分。利益相关者管理的哪个方面是重要的,可能因角色而异,但是根据我的经验,有几个方面我认为是普遍重要的。

对于大多数数据科学/分析问题,数据科学家与利益相关方合作并将业务需求转化为分析需求非常重要;因此,倾听利益相关者需求的能力剖析业务问题的能力是一名优秀数据科学家的基础。

利益相关者管理不是对所有事情都说“是”;相反,知道什么时候说“不”****如何沟通“为什么不”很重要。管理利益相关者的期望并解释分析方法的限制和警告的能力是成为一名优秀数据科学家的关键。

如何在面试中检验这一点:

检验这一点的最佳方式是让跨职能的利益相关者参加面试小组,评估候选人与他们互动的能力,让关键利益相关者了解候选人是否合适,以及他们是否愿意与之共事。

传统的行为面试问题可以提供额外的信号(例如,询问候选人他们拒绝利益相关方要求的时间,并继续了解他们为什么以及如何这样做)。

如何培养这项技能:

培养这种技能的最佳方式是寻找跨职能的机会,与尽可能多的人一起工作,并试图完全“拥有”这种关系,而不让你的经理充当中间人。在与不同的人一起工作的过程中,真正倾听他们的需求,与他们一起头脑风暴解决问题的最佳分析方法,并在事后反思每个项目。这最后一步至关重要;确保你从你的利益相关者那里得到诚实的反馈,这样你就能学会变得“很好共事”。

这不是你能在一周内从一本书上读到的东西,它需要练习和时间;所以要有耐心建立这种能力。

  • 识别低效并提出解决方案的能力

这些年来,我遇到过很多喜欢被“唯唯诺诺的人”包围的经理/领导;我们都知道做了那件事的皇帝发生了什么——最终在公共场合赤身裸体。这是儿童友好的版本,其中只提到了最轻的后果。我想让自己周围都是不怕质疑现状、不怕提出改变并付诸实施的人。

臭名昭著的“冒名顶替综合症”在任期较短的数据科学家中很常见;但重要的是要认识到,不管你有多年轻,你都可以有所贡献。所以,当你看到一些低效的事情时,不要害怕说出来,如果你能想出一个解决方案,那将会更受欢迎。

如何在面试中检验这一点:

这一点很难在一个小时的谈话中“测试”,因此了解这一点的最佳方式是直接询问候选人他们上次发现效率低下并提出改变是什么时候。但是一定要在回答中深入挖掘,了解确切的情况,以避免肤浅的回答。

如何培养这项技能:

永远不要把任何事情当成既定事实。质疑那些在你看来效率低下的事情,不管你的任期有多长。为了能够提出解决方案,利用前面提到的一些建议是有帮助的——让自己了解该领域的最新趋势,并与利益相关者交谈,以了解他们的痛点和适合该情况的最佳解决方案。

关键要点:

非技术性技能会向招聘经理表明你是一名优秀的数据科学家

  • 学习新技能和适应变化的能力
  • 有商业头脑
  • 能够管理利益相关者
  • 识别低效流程并提出解决方案的能力

想了解更多关于数据科学和商业的信息吗?我可能有一些建议给你:

</5-mistakes-i-wish-i-had-avoided-in-my-data-science-career-6c22a44304a1> https://medium.com/illumination/why-i-wont-participate-in-the-great-resignation-for-my-side-hustle-e6ef6f9c85ab

面向数据科学家的顶级 R 库

原文:https://towardsdatascience.com/top-r-libraries-for-data-scientists-16f064151c04

r 是一种开源语言,有大量的库可供探索。在这篇文章中,你会发现一些最著名的,你可以在那里了解更多。

照片由阿尔方斯·莫拉莱斯@ unsplash.com 拍摄

L 在过去的十年里,开源语言已经成为数据科学领域事实上的标准。开源工具是免费的、可扩展的,并且在合作社区中拥有成千上万个人的广泛支持。

r 是最著名的开源语言之一,受到了全世界数百万数据科学家的青睐。其主要优势之一是大型社区支持大量不断更新和改进的图书馆,能够捕捉世界各地机器学习和数据科学研究的最新发展。

使用 R 时,可以使用的库实际上有数百个——对于初学者来说,这可能会令人困惑,尤其是在您注意到许多库有相同的目的并做类似的事情之后。

这篇文章将帮助你了解世界各地的数据科学家经常使用哪些库。这个摘要应该为您提供数据科学领域最著名的库的详细列表。

从数据争论到训练机器学习模型,以下库是当今生产中大多数数据科学脚本的一部分。如果你是 R 的新手,围绕下一个库制定一个学习计划会给你一个很好的方法来提高你的 R 技能,并且能够处理我们那里的大量数据科学项目。

我们开始吧!

提示:为了能够运行本文中的示例,不要忘记下载并安装本文中提到的库。

数据争论— Dplyr

我们的第一个库来自于包的宇宙。 Dplyr 是一个数据角力库,以解锁 R ( %>%)内部管道运算符的权力而闻名。

在处理复杂的数据管道时,r 语法并不是特别简洁。添加几个过滤器或合并不同的数据框可能会使您的代码混乱不堪。 Dplyr 增强您的数据争论游戏,使您能够快速编写复杂的数据管道。

此外,使用 dplyr 你可以很容易地将一个函数封装在另一个函数中,而不是使用典型的复合格式 f(g(x)) ,这种格式会扩展到混乱的 R 代码,几乎不可能维护或调试,并且会产生大量的技术债务。

让我们来看看下面这个关于 iris 数据集的例子——想象一下,在过滤了 virginica 物种的行之后,我想要对 sepal_width 求平均值。如果我们使用 R 基代码,我们可能会做以下事情:

mean(iris[iris$Species==’virginica’, ‘Sepal.Width’])

那好像也不太复杂!但是,现在假设我们想要添加另一个条件,取出 virginicas 一个小于 2:

mean(iris[(iris$Species==’virginica’) & (iris$Petal.Width < 2), ‘Sepal.Width’])

这段代码有点令人困惑。有了 Dplyr ,我们可以简单地:

iris %>% 
 filter(Species == ‘virginica’, Petal.Width < 2) %>%
 summarise(mean(Sepal.Width))

多酷啊。%>%通过作用于前一个函数返回的元素来工作。功能summarise仅在filter返回时应用。在filter中,我们直接使用逗号分隔的两个条件,这比使用多个&条件更加实用和简洁。

如果你想改进你的代码,让它对其他人来说更可读,Dplyr 真的很酷,也是最重要的学习内容之一。您可以使用一些资源来了解更多信息:

数据访问— RODBC

当你想直接从数据库中检索数据时,RODBC 是你的好朋友。该库使您能够使用 ODBC(开放式数据库连接)通道直接连接到数据库管理系统中的表,并直接从数据库系统中检索一些示例,而无需使用任何 csvxlsxjson 接口。使用 RODBC,你使用查询语言将数据库管理系统中的数据直接转换成数据帧。

要使用 RODBC ,您需要:

  • 在您的系统中配置一个 ODBC 连接到您想要的 DBMS
  • 设置访问数据库服务器的凭据。当然,这意味着您需要有效的权限来访问数据。

就是这样!超级简单。

例如,在下面的例子中,我使用 root 用户名创建了一个到本地 MYSQL 服务器的连接:

connection <- odbcConnect(“mysqlconn”, uid=”root”)

创建之后,我可以立即使用一些 SQL 代码直接从 MYSQL 服务器检索数据:

result1 <- sqlQuery(channel, paste(“SELECT * from sakila.city”))

我使用带有查询SELECT * from sakila.city的 SQL 代码从 sakila 数据库中检索整个城市表。这样做的时候,这个表将以 dataframe 格式存储在我的result1对象中!之后,我可以将我所知道的所有 R 代码应用到这个对象中,因为我正在使用一个数据框架

RODBC 可以访问大多数数据库系统,如微软 SQL ServerPostgreSQLMYSQLSQLite 等。

sqldf 相结合,这两个库能够解释 R 内部的 SQL 代码,并且能够为您的数据科学和分析项目带来巨大的生产力收益。

您可以了解更多关于 RODBC 的信息:

  • RODBC 的官方文档。
  • R 博主 RODBC 举例。
  • 从我的编程课程中读取外部数据部分。

数据可视化— GGPlot2

R base 包含绘图功能,一旦安装 R 就可以使用——例如分别绘制线图和条形图的plotbarplot。这些功能很酷,但它们有两个主要限制:

  • 每个函数都有自己的参数来提供数据和设置绘图画布。
  • 添加元素(标题、标签等。)的情节相当繁琐和混乱。

幸运的是,在 tidyverse 之外还有另一个图书馆,可以说是有史以来最著名的 R 图书馆。 GGplot2, 俗称 GGplot

掌握 GGplot 本身就是一种技能。它的一个主要特点是使用户能够在代码变化最小的情况下在图之间切换。例如,假设我们想要使用折线图绘制每分钟互联网使用时间序列——我们使用的是 R 的 WWWusage 沙盒数据集:

internet <- data.frame(
  internetusage = WWWusage
)

为了绘制线图,我可以使用 GGplot 的本地函数:

ggplot(
  data = internet,
  aes(x=row.names(internet), y=internetusage)
) + geom_line(group = 1) +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank())

GGplot 是模块化的,分解了我们上面看到的元素:

  • 我们从包含我们绘图“基础”的ggplot函数开始。这是我们陈述数据的地方,也是我们将如何映射 x 和 y 维度的地方。
  • 然后,我们加一个geom_line。我们刚刚添加了一个新的“模块”到我们的图中,声明我们想要一个线图。
  • 最后,我们使用theme为我们的情节添加了一些小的美学变化。在我们的例子中,我们隐藏了 x 轴的所有标签和信息。

我们可以使用一个+符号继续向我们的 GGplot 添加模块。

但是..我已经告诉过你,在不同类型的图之间转换非常简单——我们如何将它转换成另一种类型的图呢?

超级简单!例如,要将该图变为散点图,我们只需用geom_point替换geom_line:

ggplot(
  data = internet,
  aes(x=row.names(internet), y=internetusage)
) + geom_point() +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank())

plottly并列(另一个很酷的绘图库!), GGplot 大概是大部分 R 用户画剧情的首选。与 R base 相比,它更容易在不同的情节之间切换,并且格式在灵活性和代码流畅度方面无法与 GGPlot 竞争。

一些学习资源 GGplot :

模型培训— rpart 和 randomForest/ranger

如果我们在谈论数据科学家的库,我们必须包括训练模型的库,对吗?让我们从训练基于树的模型的三个最著名的库开始。

Rpart 是训练决策树的首选库。使用 rpart 你可以用一行代码训练一个简单决策树:

rpart(
 formula = Species ~ .,
 data = iris
)

使用默认参数, rpart 训练以下决策树:

使用默认 Rpart 参数在 Iris 数据集上训练的树模型-按作者分类的图像

我们还可以使用control参数覆盖 rpart,上的其他树参数:

rpart(
 formula = Species ~ .,
 data = iris,
 control = list(minsplit=1, minbucket=1, cp=.001)
)

这里,我们覆盖了决策树上的三个超参数minsplitminbucketcp。这产生了一个更深的树:

在 Iris 数据集上训练的带有调整参数的树模型-图片由作者提供

Rpart 是用 r 训练你的第一个模型的好方法,也是让你了解超参数的巨大影响的好方法,尤其是在基于树的模型中。

在偶然发现了决策树的概念之后,你自然会学习随机森林——前者的一个更稳定的版本。

随机森林是决策树的“民主”版本。它们更稳定,更不容易过拟合新数据。在 R 中,我们也有用一行代码训练这些模型的库,即 randomForestranger 库。

randomForest 库是 Leo Breiman 的原始 pape r 的第一个 R 实现。因此,它也比 ranger 慢。您可以通过执行以下操作,使用 randomForest 库训练随机森林算法:

randomForest(
 formula = Species ~ .,
 data = iris,
 ntree=10
)

就这么简单!这里,我们用 10 个不同的决策树来训练一个随机森林。我们还可以通过向函数添加新参数来调整超参数:

randomForest(
 formula = Species ~ .,
 data = iris,
 ntree=10,
 mtry = 2
)

在本例中,我们在构建的每棵树中使用 2 个随机列作为样本。您可以使用查看完整的参数列表。R 控制台上的 randomForest

或者, ranger 是随机森林的一个更快的实现——如果您有高维数据(大量行或列), ranger 是更好的选择:

ranger(
 formula = Species ~ .,
 data = iris,
 num.trees=10
)

我们还可以使用函数的新参数为 ranger 提供新的超参数:

ranger(
 formula = Species ~ .,
 data = iris,
 num.trees = 10, 
 mtry = 2
)

rpart、randomForestranger 是理解我们如何使用 r 训练具有不同超参数的模型的很好的起点。如果我们有一些抽象层,就像 GGplot 为 plots 所做的那样,一个可以让我们更快地在模型之间切换的库,岂不是很酷?

幸运的是,我们有!叫脱字符号

在谈论插入符号之前,先了解一些关于这些库的资源:

模型培训—Caret

caret 库是 r 内部与机器学习相关的最酷的库之一,正如我们之前看到的,有某些库可以训练特定的模型,如 rpart (用于决策树)和 randomForest/ranger (用于随机森林)。为了在这些模型之间切换,我们需要改变函数,并且可能调整我们提供给它们的一些参数。

Caret 将模型抽象成一个通用的train函数,可以用于不同的模型,提供了一个method。与其他库的主要区别在于,这个模型现在被抽象为caret内部的一个参数,而不是一个独立的函数。

有了 caret ,比较模型的性能和结果也非常简单——这是机器学习项目中的一项标准任务。

举例来说,让我们看看如何使用来自 caret — 的这个train 函数来训练一个随机森林模型。为简单起见,我们使用 iris 数据集:

caret_model <- train(
  Species ~ .,
  data = iris, 
  method = "ranger",
  num.trees = 4
 )

不错!我们只是用method来定义模型!在这种情况下,我们使用ranger来训练一个基于 ranger 库实现的随机森林。在同一个数据集上训练决策树有多容易?

我们只要换上method

decision_tree <- train(
  Species ~ .,
  data = iris, 
  method = "rpart"
 )

使用脱字符号时可以随便选择上百种型号

这种灵活性使 caret 成为您可以在 r 中使用的最令人印象深刻的库之一。

  • 交叉验证方法的良好实现;
  • 对超参数执行网格搜索的平滑方法;

您可以通过以下链接了解更多关于 caret 的信息:

模型训练— h2o

Caret 适合大多数机器学习模型。然而,当你想变得更高级一点的时候, h2o 是你的朋友。

h2o 包含非常酷的前馈神经网络和其他高级模型的实现。如果你想对你的模型进行实验和高级调整, h2o 应该是一个不错的起点。

在这里介绍的所有库中, h2o 绝对是最先进的一个。通过学习它,你会偶然发现很多新概念,比如分布式和可扩展环境。这些特性使得 h2o 适合机器学习部署,这是 caret 或其他 ML 库可能会遇到的问题。

让我们在 iris 数据集上使用 h2o 构建一个简单神经网络的快速示例:

h2o.init()iris.frame <- as.h2o(iris)model <- h2o.deeplearning(
 x = c(‘Sepal.Length’,’Sepal.Width’,’Petal.Length’,’Petal.Width’),
 y = ‘Species’,
 training_frame = iris.frame,
 hidden = c(2,2),
 epochs = 10
 )

由于它的分布式本质,使用 h2o 不像使用其他机器学习库那样简单。在上面的代码中,我们执行了以下操作:

  • h2o.init() —启动 h2o 本地集群。
  • as.h2o(iris) —将光圈数据帧转换成 h2o 帧。
  • h2o.deeplearning() —使用 iris h2o 框架训练神经网络。

虽然 caret 支持神经网络,但是 h2o 在调整图层、激活函数和其他参数时具有更大的灵活性。上面,我们使用了 2 个隐藏层和 2 个节点——使用hidden参数,我们可以通过修改这个参数中给出的向量将它扩展到更深的网络。

使用以下资源更深入地了解水资源:

我们完事了。感谢你花时间阅读这篇文章。你在工作中经常使用这里没有提到的其他库吗?把它们写在下面的评论里吧!

我在 Udemy 上建立了一个R入门和一个 学习数据科学的 boot camp。这两个课程都是为初学者量身定做的,我希望你能在我身边!

https://ivopbernardo.medium.com/membership

像经验丰富的数据科学家一样使用谷歌搜索的顶级技巧

原文:https://towardsdatascience.com/top-tips-to-google-search-like-a-data-science-pro-897599f4d9ae

了解高级 Google 搜索功能,提高您查找数据科学解决方案的效率

凯文泽尔Unsplash 上拍照

在一个经验丰富的数据从业者应该具备的许多技能中,准确高效地用谷歌搜索答案的能力名列前茅。

在本文中,探索 Google 搜索技巧,帮助您更快更好地搜索数据科学解决方案和想法。

内容

(1) 确切的(2)排除(3)站点

(1)精确

虽然简单的搜索词通常工作良好,但带有多个关键字的较长搜索词可能会返回与我们想要的不匹配的混合结果。

一个很好的例子是寻找我们在编写数据科学项目时遇到的错误消息的解决方案。以下错误是我最近用stats model包运行线性回归模型时得到的一个。**

找到准确答案的技巧是使用引号( " " )来括住我们冗长的搜索词。

作者图片

这样,我们会看到我们的搜索结果已经大大缩小到那些直接回答我们的问题。

(2)排除

有时候,我们不希望特定的术语作为搜索的一部分被返回,尤其是当结果往往由特定的主题所主导时。

例如,我们可能想知道如何在除 Python 之外的其他编程语言中实现XGBoost算法。这种排除可以通过在要排除的术语后加上连字符( - )来实现。****

作者图片

结果将是 R 和 KNIME 等其他流行软件中关于 XGBoost 的信息。

(3)场地

如果我们只想要特定网站的结果,我们可以在搜索词中包含 SITE:

例如,我们想要搜索可信赖的 StackOverflow 来找出如何使我们的 matplotlib 图显示为全屏图像。

作者图片

搜索结果将显示与我们的特定查询相关的 StackOverflow 网站的链接。

(4)文件类型

在我们的数据科学工作过程中,我们可能希望找到特定文件类型的项目(例如,图像、文档)。

例如,我们可能正在寻找斯坦福大学最新人工智能报告的 PDF 版本。为此,我们可以在搜索中包含文件类型:

作者图片

然后我们会看到一个 pdf 文件结果的列表,最上面的结果将是我们斯坦福大学的'人工智能指数报告 2021 '。

(5)日期范围

数据科学是一个快速发展的领域,每年都有许多进步。如果我们想要特定年份之前或之后的信息,我们可以在搜索中包括之前的:或之后的:

例如,我们想了解更多关于计算机视觉中 YOLO 算法的最早和最新版本的出版物。

作者图片

此外,如果我们希望在某个时间段内找到结果,我们可以使用双点** ( ..)来指定日期范围。**

例如,假设我们想了解更多关于 YOLO 算法在 2016 年和 2020 年之间的多次迭代。

作者图片

(6)通配符

如果我们对想要搜索的内容只有一个模糊的概念,我们可以在搜索词中使用通配符星号作为占位符。谷歌搜索引擎会自动填充 ***** 作为搜索的一部分。

例如,我们可能想要发现各种平台,以构建和托管一个 SQL 数据库

作者图片

搜索结果将显示流行的云平台(如 GCP、AWS 等。)提供关系数据库服务。

(7)逻辑运算符

如果搜索需要多个标准,我们可以使用 Google search 中可用的逻辑运算符来检索更准确的结果。

例如,假设我们想要找到用 Python 或 R. 构建数据可视化仪表板的资源,在这种情况下,我们可以使用|(‘or’操作符)并将它们放在括号 () 中,将其与下面的搜索词链接起来。****

作者图片

搜索结果将显示与 Python 和 r。

在你走之前

欢迎您来到加入我的数据科学学习之旅!关注我的 Medium 页面,查看我的 GitHub ,了解更多精彩的教育数据科学内容。同时,祝你谷歌搜索愉快!

** **

如何使用 Python 执行语音转文本和主题检测

原文:https://towardsdatascience.com/topic-detection-python-assemblyai-315ea417f885

使用 Python 和 AssemblyAI 对音频文件执行文本转录和主题检测

沃洛季米尔·赫里先科在 Unsplash 上的照片

介绍

在我最近的一篇文章中,我讨论了关于语音识别以及如何在 Python 中实现它。在今天的文章中,我们将进一步探讨如何对音频和视频文件进行主题检测。

作为一个例子,让我们考虑一下随着时间的推移变得越来越流行的播客。想象一下每天有多少播客被创建;不同平台(如 Spotify、YouTube 或 Apple Podcasts)上的推荐引擎根据讨论的内容对所有这些播客进行分类难道没有用吗?

使用 Python 执行语音转文本和主题检测

在本教程中,我们将使用 AssemblyAI API 来标记音频和视频文件中的主题。因此,如果您想继续,您首先需要获得一个 AssemblyAI 访问令牌(这是绝对免费的),我们将在调用 API 时使用它。

现在我们有了一个访问令牌,让我们开始准备在向 AssemblyAI 的各个端点发送请求时将使用的头。

为我们将发送到 API 端点的请求准备头部——来源:作者

接下来,我们需要将音频(或视频)文件上传到 AssemblyAI 的托管服务。然后,端点将返回上传文件的 URL,我们将在后续请求中使用它。

上传音频/视频文件到 AssemblyAI 主机服务-来源:作者

现在,下一步是最有趣的部分,我们将对上传的音频文件执行语音到文本的转换。在POST请求中,我们需要传递的只是从上一步接收到的audio_url以及需要设置为Trueiab_categories参数。后者将触发文本转录上的主题检测。来自TRANSCRIPT_ENDPOINT的示例响应也显示在以下要点的末尾。

使用话题检测执行语音转文本—来源:作者

现在,为了获得转录结果(以及主题检测结果),我们需要再发出一个请求。这是因为转录是异步的 —当提交文件进行转录时,我们需要一段时间才能访问结果(通常大约是整个音频文件持续时间的 15–30%)。

因此,我们需要发出一些GET请求,直到得到成功(或失败)的响应,如下图所示。

获取转录和主题检测结果—来源:作者

最后,让我们将接收到的结果写入一个文本文件,以便我们更容易检查输出并解释从转录端点接收到的响应:

将转录输出写入文件—来源:作者

解读回应

转录终点的响应示例如下所示:

启用话题检测的转录结果示例—来源:作者

外部的text键包含输入音频文件的文本转录结果。但是让我们更关注包含与主题检测结果相关的信息的categories_iab_result的内容。

  • status:包含话题检测的状态。正常情况下,这将是success。如果由于任何原因,主题检测模型已经失败,则该值将是unavailable
  • results:该键将包括在输入音频文件中检测到的主题列表,包括影响预测并触发预测模型做出该决定的精确文本。此外,它还包括一些关于相关性和时间戳的元数据。我们将在下面讨论这两个问题。
  • results.text:该键包括已用特定主题标签分类的音频部分的精确转录文本。
  • results.timestamp:该键表示输入音频文件中说出results.text的开始和结束时间(以毫秒为单位)。
  • results.labels:这是包含由主题检测模型为results.text中的文本部分预测的所有标签的列表。相关性关键字对应于可以取01.0之间的任何值的分数,并且指示每个预测标签相对于results.text的相关程度。
  • summary:对于由主题检测模型在results阵列中检测到的每个唯一标签,summary键将包括该标签在输入音频文件的整个长度上的相关性。例如,如果在 60 分钟长的音频文件中仅检测到一次Science>Environment标签,则摘要关键字将包括该标签的相对较低的相关性分数,因为没有发现整个转录与该主题标签一致相关。

为了查看主题检测模型能够预测的主题标签的完整列表,请确保查看官方文档中的相关章节。

完整代码

下面的 GitHub Gist 分享了作为本教程一部分的完整代码:

作为本教程一部分的完整代码——来源:作者

最后的想法

在今天的文章中,我们探讨了如何使用 Python 和 AssemblyAI API 对生成的文本转录执行语音转文本和主题检测。我们通过一个分步指南详细解释了如何使用各种 API 端点来对音频和视频文件执行主题检测。

成为会员 阅读介质上的每一个故事。你的会员费直接支持我和你看的其他作家。你也可以在媒体上看到所有的故事。

https://gmyrianthous.medium.com/membership

你可能也会喜欢

主题建模——介绍和实现

原文:https://towardsdatascience.com/topic-modeling-intro-and-implementation-927d6463b892

使用 NLTK 进行主题建模的简短教程

成堆的书。E 2

企业与他们的客户互动,以更好地了解他们,也改善他们的产品和服务。这种互动可以采取电子邮件、文本社交媒体帖子(如 Twitter)、客户评论(如 Amazon)等形式。让人类代表浏览所有这些形式的文本通信,然后将这些通信路由到相关团队以对客户进行审查、采取行动和/或做出响应,这将是低效且成本高昂的。将这样的交互分组并分配给相关团队的一种廉价方法是使用主题建模。

自然语言处理(NLP)环境中的主题建模是一种无监督(即,数据未被标记)的机器学习任务,其中算法的任务是基于文档的内容将主题分配给文档集合。给定的文档通常包含不同比例的多个主题,例如,如果文档是关于汽车的,我们将期望汽车的名称比某些其他主题(例如,动物的名称)更显著地出现,而我们期望诸如“the”和“are”之类的某些词以几乎相等的比例出现。主题模型实现了数学方法来量化给定文档集合中这种主题的概率。

在本帖中,我们将扩展我们的 NLP 知识深度,作为数据科学家角色要求的一部分。我们将首先围绕标记化、词性和命名实体识别的概念建立一些基础知识。然后,我们将实现一个情感分析练习,最后使用潜在的狄利克雷分配进行主题建模。

和我的其他帖子类似,学习会通过练习问答来实现。我将根据需要在问题中包含提示和解释,以使旅程更容易。最后,我用来创建这个练习的笔记本链接在文章的底部,你可以下载,运行和跟随。

我们开始吧!

(所有图片,除非特别注明,均为作者所有。)

https://medium.com/@fmnobar/membership

数据集

为了实现这篇文章中涵盖的概念,我们将使用来自 UCI 机器学习知识库的数据集,该数据集基于论文“使用深度特征从组到个体标签”(Kotzias et al .al,2015 )并且可以从这个链接下载(CC BY 4.0)。

让我们从导入我们今天将使用的一些库开始,然后读取数据集并查看数据帧的前 10 行。每个命令前都有注释来进一步解释这些步骤。

# Import libraries
import pandas as pd
import numpy as np
import nltk

# Making the full width of the columns viewable
pd.set_option('display.max_colwidth', None)

# Making all rows viewable
pd.set_option('display.max_rows', None)

# Read the data set and drop the df['label'] column
df = pd.read_csv('imdb_labelled.csv').drop('label', axis = 1)

# Taking out a list of strings to clean up the data
df = df.replace(['\n', '\t1', '\t0'],'', regex=True)

# Return top 10 rows of the dataframe
df.head(10)

结果:

教程+问答

标记化

标记化是指将文本字符串分解成更小的子字符串。这些子字符串可以位于不同的级别。例如,一个句子级的标记化策略将一个给定的字符串分解成句子,而其他标记化器可以将一个句子分解成更小的标记,如单词、二元模型等。在这个练习中,我们只需要将字符串分解成句子和单词,所以我不会深入研究其他标记化策略,但是如果你有兴趣了解更多,我有另一个帖子链接到这里,在这里我将更详细地介绍标记、二元模型和 N-gram。

问题 1:

定义一个名为“make_sentences”的函数,它接受一个系列作为它的参数,默认为我们的数据帧的“text”列的前 15 行,将每个条目分解成句子并返回这样的句子的列表。然后将该函数应用于数据帧的前 10 行。

提示: 使用 *nltk.sent_tokenize* ,将一个给定的字符串分成一个句子级别的子字符串列表。

答案:

# Import packages
from nltk import sent_tokenize

# Define the function
def make_sentences(text = df['text'].head(15)):

    # Define a lambda function to apply the sent_tokenize to the df['text']
    return text.apply(lambda x: sent_tokenize(x)).tolist()

# Return the results for the top 10 rows of the dataframe
make_sentences(df['text'].head(10))

结果:

词性

到目前为止,我们可以把给定的字符串分成句子,句子由单词的集合组成。单词可以分解成词汇类别(类似于分类机器学习任务中的类),包括名词、动词、形容词、副词等。这些词汇组在自然语言处理中被称为词类。将词性自动分配给单词的过程称为词性标注,这是 NLP 管道的常见步骤。标记在各种 NLP 任务中非常有用,例如,在机器翻译中,任务是提供输入文本(原始语言)的翻译(目标语言)。如果原始文本输入包括一个人的名字,我们不希望机器翻译模型翻译这个名字。确保这一点的一种方法是将那个人的名字标记为实体,然后当有标记的实体时,该模型将被绕过。换句话说,除了那个标记的实体之外,句子中的其他所有内容都将被翻译。然后,在最后,作为后处理步骤的一部分,标记的实体将被映射到最终翻译结果中的正确位置。

有各种方法来创建标记策略,例如基于正则表达式的或甚至训练过的机器学习模型。在今天的练习中,我们将依靠 NLTK 提供的现有的词性标注。让我们看一个例子来更好地理解这个概念。

让我们从创建一个样本字符串开始,然后通过 NLTK 的 POS 标记器运行它并检查结果。

# Create a sample sentence
sample = 'I am impressed by Amazon delivering so quickly in Japan!'

# Import required libraries
from nltk import word_tokenize, pos_tag

# Break down the sample into word tokens
tokens = word_tokenize(sample)

# Create POS tagging
pos = pos_tag(tokens)

# Return the POS tag results
pos

结果:

现在我们看看标记结果是什么样的。例如,“快速”被标记为“RB”,这意味着一个副词,或者“亚马逊”被标记为“NNP”,这意味着一个名词。NLTK 为标签提供了文档。例如,如果我们想知道“RB”指的是什么,我们可以运行以下命令:

nltk.help.upenn_tagset('RB')

结果:

如果您想查看所有的标签,您可以不带参数运行相同的命令。

命名实体识别

现在我们对句子中的每个单词都进行了词性标注,但并不是所有的名词都是相同的。例如,“亚马逊”和“日本”都被标记为“NNP”,但一个是公司名称,另一个是国家名称。命名实体识别或 NER(又名命名实体分块)涉及通过将给定的文本输入分类成预定义的类别,如个人、组织、位置等,来从给定的文本输入中提取信息。让我们看一个例子来看看这是如何工作的。

问题二:

首先将示例句子分解成标记,然后应用词性标注,接着进行命名实体识别并返回结果。

回答:

# Import required packages
from nltk import word_tokenize, pos_tag, ne_chunk

# Break down the sample into tokens
tokens = word_tokenize(sample)

# Create POS tagging
part_of_speach = pos_tag(tokens)

# Create named-entity chunks
named_entity_chunks = ne_chunk(part_of_speach)

# Return named_entity_chunks
named_entity_chunks

结果:

让我们看看结果,特别是“亚马逊”和“日本”,因为我们知道这两个是实体。亚马逊被归类为“人”,这是我们算法的改进机会。我更喜欢“公司”或类似的类别。然后“日本”被归类为 GPE,代表一个地缘政治实体。听起来没错!因此,我们观察了 NER 是如何帮助我们将名词进一步细分为实体类的。

现在我们已经学习了如何执行词性标注和 NER,让我们创建一个可以自动实现这些任务的函数。

问题三:

定义一个名为“make_chunks”的函数,它接受一个句子列表作为参数,默认为问题 1 中定义的“make_sentences”函数,并返回一个字典(将被称为外部字典),其中外部字典的键是一个整数,表示条目的行号。外部字典的值是字典本身(将被称为内部字典),其中内部字典的关键字是句子编号,内部字典的值是命名实体识别的结果(类似于问题 2)。例如,回顾问题 1 的结果,结果的第六行是以下句子列表:

['The rest of the movie lacks art, charm, meaning...',  
"If it's about emptiness, it works I guess because it's empty."],

因此,使用默认参数运行问题 3 中定义的函数,预计会为第六行返回以下内容:

5: {
     0: [('The', 'DT'),
         ('rest', 'NN'),
         ('of', 'IN'),
         ('the', 'DT'),
         ('movie', 'NN'),
         ('lacks', 'VBZ'),
         ('art', 'RB'),
         (',', ','),
         ('charm', 'NN'),
         (',', ','),
         ('meaning', 'NN'),
         ('...', ':')
     ],
     1: [('If', 'IN'),
         ('it', 'PRP'),
         ("'s", 'VBZ'),
         ('about', 'IN'),
         ('emptiness', 'NN'),
         (',', ','),
         ('it', 'PRP'),
         ('works', 'VBZ'),
         ('I', 'PRP'),
         ('guess', 'NN'),
         ('because', 'IN'),
         ('it', 'PRP'),
         ("'s", 'VBZ'),
         ('empty', 'JJ'),
         ('.', '.')
     ]
 },

回答:

为了定义这个函数,我们将遍历两个字典,其中内部字典将包括标记化、词性标注和 ner,类似于这个问题之前的例子。

# Define the function
def make_chunks(make_sentences = make_sentences):

    # Create the outer dictionary with row number as key
    row_dict = dict()

    # Form the first iteration
    for i, row in enumerate(make_sentences()):

        # Create the inner dictionary with sentence number as key
        sent_dict = dict()

        # Form the second iteration
        for j, sent in enumerate(row):

            # Tokenize
            w = word_tokenize(sent)

            # POS tagging
            pos = pos_tag(w)

            # Add named-entity chunks as the values to the inner dictionary
            sent_dict[j] = list(ne_chunk(pos))

        # Add the inner dictionary as values to the outer dictionary
        row_dict[i] = sent_dict

    # Return the outer dictionary
    return row_dict

# Test on the sixth row of the dataframe
make_chunks()[5]

结果:

{0: [('The', 'DT'),
  ('rest', 'NN'),
  ('of', 'IN'),
  ('the', 'DT'),
  ('movie', 'NN'),
  ('lacks', 'VBZ'),
  ('art', 'RB'),
  (',', ','),
  ('charm', 'NN'),
  (',', ','),
  ('meaning', 'NN'),
  ('...', ':')],
 1: [('If', 'IN'),
  ('it', 'PRP'),
  ("'s", 'VBZ'),
  ('about', 'IN'),
  ('emptiness', 'NN'),
  (',', ','),
  ('it', 'PRP'),
  ('works', 'VBZ'),
  ('I', 'PRP'),
  ('guess', 'NN'),
  ('because', 'IN'),
  ('it', 'PRP'),
  ("'s", 'VBZ'),
  ('empty', 'JJ'),
  ('.', '.')]}

正如所料,结果与问题中提供的示例相匹配。

情感分析

在自然语言处理领域,情感分析是从文本数据中识别、量化、提取和研究主观信息的工具。在这个练习中,我们将使用极性得分,这是一个在[-1.0,1.0]范围内的浮动值,旨在区分文本是积极还是消极的情绪。这种熟悉程度足以满足这篇文章的目的,但如果你有兴趣了解更多,请参考我关于情绪分析的文章,链接于此。我们一起来看一个例子。

问题 4:

创建一个接受句子列表作为参数的函数,默认为问题 1 中定义的“make_sentences”函数,然后返回一个包含“句子”和“情感”两列的 dataframe。请使用 NLTK 的“SentimentIntensityAnalyzer”进行情感分析。最后,使用默认参数运行函数并返回结果。

回答:

# Import the package
from nltk.sentiment.vader import SentimentIntensityAnalyzer

# Define the function
def sentiment_analyzer(make_sentences = make_sentences):

    # Create an instance of SentimentIntensityAnalyzer
    sia = SentimentIntensityAnalyzer()

    # Create the dataframe with two columns as described
    df = {
        'sentence' : []
        , 'sentiment' : []
    }

    # Create two loops to add the column vlaues
    for i, row in enumerate(make_sentences()):
        for sent in row:

            # Add the sentence to the dataframe
            df['sentence'].append(sent)

            # Add the polarity score of the sentiment analysis to the sentiment column of the dataframe
            df['sentiment'].append(sia.polarity_scores(sent)['compound'])

    # Return the dataframe
    return pd.DataFrame(df)

# Run the function
sentiment_analyzer()

结果:

主题建模——潜在的狄利克雷分配

潜在狄利克雷分配(LDA)是用于主题建模的常用模型之一。虽然探索 LDA 的数学细节超出了本文的范围,但我们可以将它视为一个将单词与主题和文档联系起来的模型。例如,当一组文档被提供给 LDA 模型时,它将查看单词,并根据每个文档中包含的单词,为每个文档分配具有各自概率的主题。

幸运的是,LDA 可以在 scikit-learn 中轻松实现。NLTK 的 LDA 类接受文档术语矩阵(DTM)作为参数,因此,让我们回顾一下什么是 DTM,然后我们将看一个使用 scikit-learn 的 LDA 模型进行主题建模的例子。

文档术语矩阵

DTM 是一个矩阵,表示在文档集合中出现的术语的频率。让我们看两个句子来理解 DTM 是什么。

假设我们有以下两个句子(在本例中,每个句子都被视为一个“文档”):

sentence_1 = 'He is walking down the street.'

sentence_2 = 'She walked up then walked down the street yesterday.'

DTM 的上述两句话将会是:

DTM 可以使用 scikit-learn 的计数矢量器来实现。这将满足我们当前练习的目的,但如果你有兴趣了解更多关于 DTM 的知识,请访问我在情感分析上的帖子,链接于此

让我们把目前所学的东西付诸实践。我们将实施以下步骤:

  1. 导入 DTM 和 LDA 所需的包并实例化它们
  2. 为我们的数据框架的“文本”列创建一个 DTM
  3. 使用 LDA 为提供的 DTM 创建主题
# Step 1 - Import packages
from sklearn.decomposition import LatentDirichletAllocation
from sklearn.feature_extraction.text import CountVectorizer

# Create an instance of the imported packages
lda = LatentDirichletAllocation()
cvect = CountVectorizer(stop_words='english')

# Step 2 - Create a DTM of 50 randomly-selected rows of the dataframe
dtm = cvect.fit_transform(df['text'])

# Step 3 - Create list of topics using LDA
topics = lda.fit_transform(dtm)

既然我们已经做好了模型,让我们来看看每个话题都包括哪些单词。可以使用lda.components_查看模型的结果。让我们看一个例子。

问题 5:

定义一个名为“top_n_words”的函数,它接受两个参数:
1。“特征名称”,这是从 DTM
2 产生的特征名称。“n”,这是将要返回的行数和字数。

该函数接受上面的两个参数,并返回 n 个主题以及该主题中的前 n 个单词。例如,第一个主题的结果可能如下:

Topic 0: film ve really end movies just dialogue choked drama worthless

最后,运行函数,返回每个主题的前 10 个单词。

回答:

# Define the function
def top_n_words(feature_names, n): 

    for topic_index, topic in enumerate(lda.components_):

        # Create the "Topic {index}:" portion of the output
        output = "Topic %d: " % topic_index 

        # Add the top n words of that topic
        output += " ".join([feature_names[i] for i in topic.argsort()[:-n - 1:-1]])

        # Print the output
        print(output)

    # Print the output
    print()

# Create function names from the DTM
feature_names = cvect.get_feature_names_out()

# Run the function for top 10 words of each topic
top_n_words(feature_names, n=10)

结果:

问题 6:

定义一个函数,它接受两个参数“search_word”和“n ”,并返回与“search_word”中提供的主题相关的前“n”个最可能的单词。结果应该是数据帧的形式,包含两列。第一列是每个单词的“概率”,第二列是“特征”或与提供的主题相关的单词(即“search_word”)。最后,使用“action”作为“search_word”运行该函数,并返回与该主题相关的前 10 个单词。

回答:

# Define the function
def word_feature(search_word, n=10):
    search_word_cvect = cvect.transform(np.array([search_word])) 
    probabilities = lda.transform(search_word_cvect)
    topics = lda.components_[np.argmax(probabilities)]
    features = cvect.get_feature_names_out()
    return pd.DataFrame({'probability': topics, 'feature': features}).nlargest(n, 'probability')

# Run the function for the given search_word and return top 10 results
word_feature('action', n=10)

结果:

带练习题的笔记本

下面是带问题和答案的笔记本,您可以下载并练习。

结论

在这篇文章中,我们讨论了如何使用机器学习,特别是主题建模来将一组文档分组在一起,这可以促进企业的下游任务,处理大量以电子邮件、社交媒体帖子、客户评论等形式传入的文本数据。我们从建立所需的直觉和基础开始,涵盖了标记化、词性和命名实体识别,然后是情感分析和主题建模的实现,使用潜在的狄利克雷分配。

感谢阅读!

如果你觉得这篇文章有帮助,请在媒体上关注我,订阅接收我的最新文章!

PyCaret — Redux 上的主题建模

原文:https://towardsdatascience.com/topic-modeling-on-pycaret-redux-46cd8e4869f4

数据科学/ PYTHON NLP 片段

PyCaret 自然语言处理模块初学者指南

照片由 Unsplash 上的尼克·费因斯拍摄

我以前说过,现在我再说一遍,“我们从数据到见解的速度越快,我们的境况就越好。”

PyCaret 可以帮助我们做到这一点。通过几行 Python 代码,它帮助我们比以往任何时候都更快地获得洞察力。

那么,PyCaret 是什么?

PyCaret 是 Python 中的一个开源、低代码机器学习库,允许您在几秒钟内从准备数据到在您选择的笔记本环境中部署模型。

换句话说,PyCaret 让数据科学变得更加简单。

像往常一样,我不会告诉你所有的事情,而是给你看。

家政

首先,让我们安装 PyCaret。在终端中键入以下内容:

pip install pycaret

但是等等,一个问题!

"安装构建依赖项的 pip 子进程没有成功运行"

作者截图

没起作用?您可能正在使用不兼容的 pip 最新版本。让我们稍微降级一下:

python.exe -m pip install pip==21.3.1

其次,我们将下载一些语言包。对于英语语言模型,在终端中一次键入以下一行:

python -m spacy download en_core_web_smpython -m textblob.download_corpora

第三,让我们安装我们最好的朋友,熊猫:

pip install pandas

现在,我们准备好摇滚了。

摇滚

让我们开始一个 Jupyter 笔记本,让我们做一些编码!

上面,我们只是简单地导入 PyCaret 的 NLP 模块,当然还有 pandas。其他代码块完全是可选的,但是很有帮助。第一个代码块让我们不必一直键入 print()语句,而第二个代码块让我们看到了数据帧的所有优点——也就是说,没有截断列和行。

接下来,我们将获取数据并将其加载到 dataframe 中。

对于这个实验的其余部分,我们将只处理一千条 tweets 的样本,以使我们的代码运行得更快。

让我们来看看我们的数据:

作者截图

现在让我们进入这个小项目的核心部分。不要忘记更改目标,因为它适用于您的数据。在本例中,我要分析的 dataframe 列在“tweet”列中,所以这就是我放在 setup()的目标参数中的内容。

在短短的三行代码中,我们预处理了文本数据,定制了停用词,创建了模型,并将模型分配回我们的数据框架。

现在是时候进行一些可视化了!

唉,没那么快。如果您遇到了下面的错误,不要惊慌。

打嗝

ModuleNotFoundError:没有名为“pyLDAvis.gensim”的模块

作者截图

让我们阅读错误消息,寻找如何纠正问题的线索。

在这种情况下,脚本没有找到 pyLDAvis.gensim 模块,因为它更改了名称。以前的“gensim”现在是“gensim_models ”,修复这个问题只需要修改 pycaret 包中的两行代码。

是的,我们将改变库本身的代码,因为它已经过时了。

作者截图

上面的错误告诉我们查看“nlp.py”文件的第 2512 行。让我们简单地转到目录,找到文件进行一些编辑。

在“nlp.py”文件的第 2512 行和第 2519 行,我们发现两个 pyLDAvis.gensim 需要更改为“pyLDAvis.gensim_models”。让我们更改它们并保存文件。

作者截图

在改变生效之前。我们需要重启笔记本电脑的内核。

简单地运行所有的单元格,我们不应该得到任何更多的错误。

以下是一些输出:

作者截图

作者截图

作者截图

结论

使用 PyCaret 的 NLP 模块,我们已经看到了如何通过几行代码快速地从获取数据到洞察。

感谢您的阅读!PyCaret 的 NLP 模块有更多的特性,我鼓励您阅读他们的文档来进一步熟悉这个模块,甚至整个库!

请登录查看

https://pycaret.org/

敬请期待!

你可以通过推特LinkedIn 联系我。

[1] PyCaret。(2020 年 6 月 4 日)。为什么是 PyCarethttps://pycaret.org/

基于潜在狄利克雷分配的主题建模

原文:https://towardsdatascience.com/topic-modeling-with-latent-dirichlet-allocation-ea3ebb2be9f4

自然语言处理中一种流行建模技术的综述与实现

布雷特·乔丹在 Unsplash 上的照片

介绍

随着大量数据以文档的形式出现,例如文章、电子邮件和简历,对组织、总结、访问和解释这些数据的方法有了新的需求。

这就是主题建模发挥作用的地方。

主题建模是一种无监督的学习技术,在给定的文档集合中挖掘潜在的“主题”。它能够根据主题对文档进行分组或划分,这使它成为企业非常宝贵的资产。主题建模存在于许多应用中,例如推荐系统和搜索引擎。

主题建模最流行的方法之一是潜在狄利克雷分配(LDA)。

在这里,我们提供了一个关于 LDA 的快速概要,并演示了如何使用 Python 来执行它。

皱胃向左移

执行 LDA 需要用概率模型捕获给定文档集合中的信息。

这项技术基于以下两个假设:

  1. 每个文档都包含多个主题
  2. 每一个主题都由单词组合而成

LDA 用主题概率表示文档,用词概率表示主题。

由于 LDA 背后的算法,使用这种主题建模方法需要大量的计算。

幸运的是,有了 Python 的 NLP 模块(我们将很快介绍),所有繁重的工作都为您完成了。任何给定文档集合的实际 LDA 模型都可以用最少的代码构建!

在这种情况下,我们可以坐视引用栈溢出,让我们的程序为我们做所有的工作,对吗?

不完全是。

挑战

虽然由于 Python 强大的模块,LDA 中的计算并不难执行,但在进行 LDA 时,用户需要做出一些关键决定。

首先,一个给定的数据集应该有多少个主题?这是用户定义的参数。如果分配的主题数量不适合给定的文档集,任何从文档中获取主题的努力都将失败。

此外,在建立 LDA 模型之后,你将会得到每个主题的单词概率。请记住,LDA 是一种无监督的学习技术,因此用户的工作是根据每个主题所关联的单词来决定每个主题代表什么。即使 LDA 模型是健壮的,如果它的结果是不可理解的,它也没有用。

个案研究

为了巩固对这种主题建模方法的理解,使用真实数据来应用它是有益的。

LDA 可用于汇总大量数据。人们可以利用这种主题建模方法来识别文档中陈述的要点,而不是解析每个文档中的每个细节。

让我们使用 LDA 从评论集中挖掘话题。

在这个演示中,我们使用了亚马逊食品评论(无版权)的数据集,可以在这里访问。这是一个很大的数据集,所以我们将研究范围限制在前 100,000 条记录。

这是数据集的预览。

代码输出(由作者创建)

  1. 预处理

当然,在执行 LDA 之前,需要对评论进行预处理,以便成功地进行分析。

首先,我们使用 Gensim 模块对评论进行标记。此外,我们小写所有字符,并删除任何标点符号。

接下来,我们将二元模型添加到标记化文档中。

最后,我们删除所有出现的停用词或短词,并使用 NLTK 模块对剩余的标记执行词汇化。

为了查看预处理后数据是如何被修改的,我们可以将其添加到数据框中。

代码输出(由作者创建)

2。创建文档术语矩阵和字典

像大多数 NLP 模型一样,LDA 模型需要一个文档术语矩阵作为输入。它还需要语料库中所有单词的字典。

3。确定主题数量

在构建 LDA 模型之前,我们需要决定食品评论集合中的主题数量。

这可能很难确定,因为在任何给定的文档集合中没有多少主题的经验法则。因此,有不同的方法可以用来确定这个数字。

第一种方法是用不同数量的主题创建多个 LDA 模型,看看哪一个最容易解释。另一种方法是利用领域知识来确定这个值。

在这种情况下,我们将使用 coherence score 度量作为食品评论集合中有多少主题的指标。连贯性分数本质上是对分配给每个主题的单词在语义值方面有多相似的度量。分数越高越好。

让我们计算具有 2 到 10 个主题的 LDA 模型的一致性分数,并查看哪个数量的主题导致最高的一致性分数。

代码输出(由作者创建)

根据一致性得分指标,亚马逊食品评论中应该有 9 个潜在主题。

4。构建 LDA 模型

既然我们已经确定了主题的最佳数量,我们就可以构建 LDA 模型了。

5。解读结果

一旦建立了模型,我们就可以根据概率得分来查看哪些单词与每个主题的亲和力最强。

代码输出(由作者创建)

我们可以使用与每个主题相关的单词来解释主题,并找出它们所代表的内容:

主题 0:茶相关产品的评论

话题 1:美味小吃评论

主题 2:对产品质量的总体正面评价

话题 3:对含糖饮料的评论

议题 4:对咖啡相关产品的评论

主题 5:对产品口味的总体评价

主题 6:宠物食品评论

主题 7:关于产品包装的评论

主题 8:巧克力相关产品的评论

就这样,我们能够以 9 个主题的形式总结 10 万条食品评论中的数据。这些主题提供了客户谈论内容的大致概念。

我们还可以使用该模型来确定每个文档中的主题混合。

代码输出(由作者创建)

我们以第一篇美食评论为例。

评论:“我已经购买了几个活力罐装狗粮产品,发现它们的质量都很好。这种产品看起来更像炖肉,而不是加工过的肉,而且闻起来更香。我的拉布拉多很挑剔,她比大多数人都更喜欢这个产品。”

根据 LDA 模型,本综述包含主题 2 和主题 6。与主题 2 和主题 6 相关的单词证实了这次复习的主题任务。

6。可视化结果(可选)

虽然我们可以用已经提供给我们的信息来解释文档中的每个主题,但是可视化 LDA 的结果将增强后续的分析。

pyLDAvis 模块允许我们通过交互式可视化更好地解释 LDA 模型的结果。

代码输出(由作者创建)

交互式可视化以图表(左)和水平条形图(右)的形式出现。

图中的每个气泡代表一个主题。气泡的大小代表包含该主题的评论的比例,气泡越大,比例越高。气泡之间的距离代表主题之间的相似度;距离越短,话题越相似。

条形图中的条代表每个单词的词频。蓝色条显示了文档集合中的总术语频率,而红色条显示了所选主题的术语频率。

当然,在执行 LDA 时,创建这样一个工具并不是一个强制性的步骤,但是任何漂亮而实用的视觉辅助工具总是一个受欢迎的补充,因为它可以更容易地从研究中获得发现并向他人展示。

毕竟,谁不喜欢好的视觉效果呢?

结论

照片由 Unsplash 上的 Prateek Katyal 拍摄

到目前为止,您已经对 LDA 的功能以及如何使用 Python 强大的模块来执行它有了大致的了解。

也就是说,这只是 LDA 作为主题建模方法的一个概述。如果你有兴趣了解更多关于 LDA 的内部运作,我强烈建议你从查看这篇论文开始。

我祝你在数据科学的努力中好运!

参考

  1. J.麦考利和 j .莱斯科维奇。从业余爱好者到行家:通过在线评论模拟用户专业知识的演变。WWW,2013。
  2. 布莱,大卫和吴,安德鲁和乔丹,迈克尔。(2001).潜在狄利克雷分配。机器学习研究杂志。3.601–608.

基于潜在语义分析的主题建模

原文:https://towardsdatascience.com/topic-modeling-with-latent-semantic-analysis-58aeab6ab2f2

探索一种从文本中提取主题的流行方法

布雷特·乔丹在 Unsplash 上的照片

想想目前流通的大量文本。新闻文章、博客文章、在线评论、电子邮件和简历都是大量存在的文本数据的例子。

由于大量非结构化数据以这些文档的形式涌入,我们需要一种自动化的方法来分析这些大量的文本。

这就是主题建模发挥作用的地方。主题建模是一种无监督的学习方法,允许我们从文档中提取主题。

它在诸如文档聚类和信息检索等许多应用中起着至关重要的作用。

在这里,我们提供了一个最流行的主题建模方法的概述:潜在语义分析。

重要的一点

在讨论潜在语义分析之前,理解“主题”在 NLP 中的含义是很重要的。

一个主题由一组强相关的单词定义。例如,单词“土豆”、“汤”和“吃”可以代表主题“食物”。

由于文档不受有限的一组单词的限制,它们通常包含多个主题。我们可以通过找到与文档最相关的主题,将文档分配给主题。

潜在语义分析

潜在语义分析(LSA)是一种允许我们通过将文本转换成单词-主题和文档-主题矩阵来从文档中提取主题的方法。

LSA 的程序相对简单:

  1. 将文本语料库转换成文档术语矩阵
  2. 实现截断奇异值分解
  3. 用提取的主题对单词/文档进行编码

简单吧?

好吧,我可能忽略了一些细节。让我们一次检查一个步骤。

1。将原始文本转换成文档术语矩阵

在从文档中导出主题之前,必须将文本转换成文档术语矩阵。这通常通过单词袋或 TF-IDF 算法来完成。

2。实现截断奇异值分解

截断奇异值分解(SVD)是 LSA 的核心。该操作是从给定的文档集合中获取主题的关键。

数学上,可以用下面的公式来解释:

这个公式乍一看令人生畏,但它相当简单。

通俗地说,该操作将高维文档术语矩阵分解成 3 个更小的矩阵(U、S 和 V)。

变量 A 表示文档术语矩阵,在每个文档和单词对之间分配一个基于计数的值。该矩阵具有 n×m 个维度,其中 n 表示文档的数量,m 表示单词的数量。

变量 U 代表文档-主题矩阵。本质上,它的值显示了每个文档与其派生主题之间的关联强度。矩阵有 n×r 个维度,n 代表文档的数量,r 代表主题的数量。

变量 S 表示评估文档集合中每个主题的“强度”的对角矩阵。矩阵有 r×r 维,r 代表主题的数量。

变量 V 代表词-主题矩阵。它的值显示了每个单词和派生主题之间的关联强度。矩阵有 m×r 维,m 代表字数,r 代表题目数。

注意,虽然语料库中的文档和单词的数量总是恒定的,但是主题的数量不是固定的变量,因为它是由运行操作的人决定的。因此,SVD 的输出取决于您希望提取的主题数量。例如,与提取 4 个主题的 SVD 相比,提取 3 个主题的 SVD 将产生不同的矩阵。

3。用衍生主题编码单词/文档

通过 SVD 操作,我们能够将文档术语矩阵转换成文档主题矩阵(U)和单词主题矩阵(V)。这些矩阵允许我们找到与每个主题关联最强的单词。

我们可以使用这些信息来决定每个派生主题代表什么。

我们还可以确定哪些文档属于哪个主题。

限制

LSA 使我们能够快速有效地发现文档中的潜在主题。话虽如此,但它确实有自己的缺点。

首先,在进行 LSA 时,一些信息的丢失是不可避免的。

当文档被转换成文档-术语矩阵时,词序被完全忽略。由于词序在单词的语义值中起着很大的作用,省略它会导致主题建模过程中的信息丢失。

此外,LSA 无法解释同形异义或一词多义。因为该技术基于单词出现的上下文来评估单词,所以它不能识别具有多重含义的单词,也不能通过单词在文本中的使用来区分这些单词。

对于给定的一组文档,也很难确定主题的最佳数量。虽然在寻找表示文档集合的理想主题数量方面有几种思想流派,但是没有一种确定的方法可以实现这一点。

最后,LSA 缺乏可解释性。即使在成功地提取了具有强关联性的词语集的主题之后,从这些词语集中获得洞察力也是具有挑战性的,因为很难确定每组词语代表什么主题。

案例研究

现在我们已经给出了 LSA 的概要,让我们看看如何用 Python 实现它。

这个案例研究将主要利用 Gensim 库,这是一个专注于主题建模的开源库。

我们将使用一个包含乐器评论的数据集,看看我们如何从中挖掘出主要话题。数据集(无版权)可以在这里获得

以下是数据预览:

代码输出(由作者创建)

第一步是将这些评论转换成文档术语矩阵。

为此,我们必须对文本进行一些预处理。这需要将所有文本小写,删除标点符号、停用词、短词(即少于 3 个字符的词),并用词干将每个词还原为其基本形式。

所有这些都可以通过 preprocess_string 函数来实现,该函数将给定的文本转换成一系列经过处理的标记。

这是预处理后文本的快速预览。

代码输出(由作者创建)

现在,我们可以使用单词袋模型将这些经过处理的评论转换成文档术语矩阵。

接下来,我们必须对这个矩阵进行截断奇异值分解。在 Gensim 库中,我们可以使用 LSImodel 来构建一个在给定矩阵上执行 SVD 的模型。

然而,在我们创建低维矩阵之前,我们需要确定应该从这些综述中提取的主题数量。

寻找最佳主题数量的一种方法是使用一致性分数度量。一致性分数实质上显示了来自每个主题的单词在语义值方面有多相似,较高的分数对应于较高的相似性。

同样,我们可以用 Gensim 模块获得一致性分数。让我们来看看 2 到 10 个主题的连贯性得分如何。

代码输出(由作者创建)

2 个主题的一致性得分最高,所以这是我们在执行 SVD 时将提取的主题数。

我们能够从文档术语矩阵中获得 2 个主题。这样一来,我们就可以看到哪些词与每个话题的关联最强,并推断出这些话题代表了什么。

让我们来看看与每个话题关联最强的 5 个单词。

代码输出(由作者创建)

根据给定的词,主题 0 可以表示针对使用产品时产生的声音或噪音的评论,而主题 1 可以表示针对设备本身的评论。

此外,我们可以看到模型为每个文档和主题配对分配了什么值。

如前所述,文档通常有多个主题。但是,有些主题与文档的关联比其他主题更强。因此,我们可以通过找到记录最高值的主题来确定文档属于哪个主题。

让我们看一个样本评论作为例子。

代码输出(由作者创建)

样本评论的主题 0 和主题 1 的得分分别为 0.88 和 0.22。虽然这两个主题都出现在评论中,但是主题 0 比主题 1 具有更高的价值,因此我们可以将该评论分配给主题 0。

让我们看看属于每个主题的评论。

代码输出(由作者创建)

主题 0 中的示例文本讨论了购买电子管尖叫器后乐器的声音,而主题 1 中的示例文本则更关注购买的踏板本身的质量。这符合两个衍生话题的解读。

结论

照片由 Unsplash 上的 Prateek Katyal 拍摄

现在,您已经对如何使用 LSA 在一组文档中找到潜在主题有了一些了解。

虽然这种技术相对快速有效,但由于其局限性,应该谨慎使用。

我祝你在 NLP 的努力中好运!

参考

  1. 麦考利法官(未注明)。亚马逊产品数据。亚马逊评论数据。于 2022 年 3 月 1 日从 http://jmcauley.ucsd.edu/data/amazon/取回

主题建模与 LSA、pLSA、LDA、NMF、BERTopic、Top2Vec 的比较

原文:https://towardsdatascience.com/topic-modeling-with-lsa-plsa-lda-nmf-bertopic-top2vec-a-comparison-5e6ce4b1e4a5

不同主题建模策略的比较,包括实际的 Python 例子

图片作者。

目录

  1. 简介
  2. 话题建模策略
    2.1 简介
    2.2 潜在语义分析(LSA)
    2.3 概率潜在语义分析(pLSA)
    2.4 潜在狄利克雷分配(LDA)
    2.5 非负矩阵分解(NMF
    2.6BERTopic 和 Top2Vec
  3. 对比
  4. 附加备注
    4.1 一个题目不一定是我们所想的
    4.2 题目不容易评价
  5. 结论
  6. 参考文献

1.介绍

在自然语言处理(NLP)中,术语主题建模包含一系列统计和深度学习技术,以在文档集中找到隐藏的语义结构。

主题建模是一个无监督的机器学习问题。无监督意味着算法在没有标签或标记的情况下学习模式。

我们人类产生和交换的大多数信息都具有文本的性质。文档、对话、电话、消息、电子邮件、笔记、社交媒体帖子。在缺乏先验知识的情况下,从这些来源中自动提取价值的能力是数据科学中一个永恒且普遍存在的问题。

在这篇文章中,我们讨论了主题建模的流行方法,从传统算法到基于深度学习的最新技术。我们旨在分享一个对这些模型的友好介绍,以及比较它们在实际应用中的优缺点

我们还为最主要的方法提供了端到端的 Python 示例。

最后,我们分享了关于无监督文本数据分析的两个最具挑战性的方面的一些考虑:人类对“主题”的定义与其统计对应物之间的差异,以及与主题模型性能的定量评估相关的困难。

2.主题建模策略

2.1 简介

潜在语义分析(LSA) (Deerwester 等,1990)概率潜在语义分析(pLSA) (Hofmann,1999)潜在狄利克雷分配(LDA) (Blei 等,2003)非负矩阵分解 (Lee 等,1999)是传统的和众所周知的主题建模方法。

他们将文档表示为一个单词包,并假设每个文档都是潜在主题的混合物。

它们都是从将文本语料库转换成文档术语矩阵(DTM) 开始的,这是一个表格,其中每行是一个文档,每列是一个不同的单词:

来自一组样本文档的文档术语矩阵。图片作者。

:实施/研究论文也可能使用/参考术语文档矩阵(TDM),即 DTM 的转置。

每个单元格<i, j>包含一个计数,即单词j在文档i中出现的次数。字数统计的一个常见替代方法是 TF-IDF 评分。它考虑了词频(TF)逆文档频率(IDF) 来惩罚在语料库中出现非常频繁的词的权重,并增加更罕见的词的权重:

TF-IDF。图片作者。

潜在主题搜索的基本原理是将 DTM 分解为文档-主题和主题-术语矩阵。以下方法在定义和实现这一目标的方式上有所不同。

2.2 潜在语义分析(LSA)

为了分解 DTM 和提取主题,潜在语义分析(LSA) 应用称为单值分解(SVD) 的矩阵分解技术。

SVD 将 DTM 分解为三个不同矩阵的乘积:DTM = U ∙ Σ ∙ Vᵗ,其中

  • UV的大小分别为m x mn x n,分别是文档的数量m和语料库中单词的数量n
  • Σm x n,并且只有它的主对角线被填充:它包含 DTM 的奇异值。

LSA 选择 DTM 的前t <= min(m, n)个最大奇异值,从而分别丢弃UV的最后m - tn - t列。这个过程被称为截断奇异值分解。得到的 DTM 近似值的等级为t,如下图所示。

就 L₂范数而言,DTM 的秩t近似是最接近 DTM 的秩t矩阵,从这个意义上说,DTM 的秩t近似是最佳的。剩下的列UV可以解释为文档-主题和单词-主题矩阵,t表示主题的数量。

在文档术语矩阵(DTM)上截断 SVD 以提取潜在变量(主题)。图片作者。

优点:

  • 直觉。
  • 它既适用于短文档,也适用于长文档。
  • 主题通过V矩阵向人类解释开放。

缺点:

  • DTM 不考虑语料库中单词的语义表示。相似的概念被视为不同的矩阵元素。预处理技术可能会有所帮助,但只是在一定程度上。例如,词干可能有助于将"意大利语"和"意大利语"视为相似的术语(它们应该是相似的),但是具有不同词干的相近单词,如" money "和" cash "仍然会被视为不同的。此外,词干化也可能导致更难解释的主题。
  • LSA 需要大量的预处理阶段来从文本输入数据中获得有意义的表示。
  • 截断 SVD 中要维护的奇异值t(题目)个数必须是已知的 先验的
  • UV可能包含负值。这就造成了可解释性的问题(详见第 2.5 段)。

2.3 概率潜在语义分析(pLSA)

Hofmann (1999)提出了一种 LSA 的变体,其中使用概率模型而不是 SVD 来估计主题。因此得名,概率潜在语义分析(pLSA)

特别地,pLSA 将看到单词w和文档d的联合概率P(d, w)建模为条件独立多项式分布的混合:

摘自霍夫曼(1999)。

其中:

  • w表示一个词。
  • d表示文档。
  • z表示一个话题。
  • P(z|d)是主题z出现在文档d中的概率。
  • P(w|z)是单词w出现在主题z中的概率。
  • 我们假设P(w|z, d) = P(w|z)

前面的表达式可以重写为:

摘自霍夫曼(1999)。

我们可以在这个表达式和以前的 DTM 分解公式之间进行类比,其中:

  • P(d, w)对应于 DTM。
  • P(z)类似于Σ的主对角线。
  • P(d|z)P(w|z)分别对应UV

该模型可以使用期望最大化算法(EM) 进行拟合。简而言之,EM 在潜在变量(在本例中是主题)存在的情况下执行最大似然估计。

值得注意的是,DTM 的分解依赖于不同的目标函数。对于 LSA,它是 L₂范数,而对于 pLSA,它是似然函数。后者旨在明确最大化模型的预测能力。

pLSA 与 LSA 模型具有相同的优点和缺点,但也有一些特殊的差异:

优点:

  • 与 LSA 相比,pLSA 表现出更好的性能(Hofmann,1999)。

缺点:

pLSA 没有提供文档级别的概率模型。这意味着:

  • 参数的数量随着文档的数量线性增长,导致可伸缩性和过度拟合的问题。
  • 它不能给新文档分配概率。

2.4 潜在狄利克雷分配(LDA)

潜在狄利克雷分配(LDA) (Blei 等人,2003)通过使用狄利克雷先验以贝叶斯方法估计文档-主题和术语-主题分布来改进 pLSA。

狄利克雷分布Dir(α)是一族由正实数向量α参数化的连续多元概率分布。

让我们想象一份报纸有三个部分:政治、体育和艺术,每个部分也代表一个主题。报纸版面中主题混合的假设分布是狄利克雷分布的一个例子:

第一节(政治):

  • 混合主题:政治 0.99,体育 0.005,艺术 0.005。

第二节(体育):

  • 主题混合:政治 0.005,体育 0.99,艺术 0.005。

第 3 节(艺术):

  • 混合主题:政治 0.005,体育 0.005,艺术 0.99。

让我们观察 LDA 的平板符号(在图形模型中表示变量的传统方法)来解释 Dirichlet 先验的使用:

LDA 的平面符号。来自 Barbieri⁵ (2013)。灰色圆圈表示观察变量(语料库中的单词),而白色圆圈表示潜在变量。

m 表示文档的数量,N 表示文档中的字数。从顶部开始,我们观察到α,它是每个文档主题分布的 Dirichlet 先验的参数。从狄利克雷分布Dir(α)中,我们抽取一个随机样本来代表文档的主题分布θ。就好像,在我们的报纸例子中,我们用一个混合物( 0.99 政治,0.05 体育,0.05 艺术)来描述一篇文章的主题分布。

从选择的混合物θ中,我们根据分布绘制一个主题z(在我们的例子中,政治)。从底部,我们观察到β,狄利克雷先验关于每主题单词分布的参数。从狄利克雷分布Dir(𝛽)中,我们选择一个代表给定主题z的词分布φ的样本。并且,从φ我们画出一个字w

最后,我们感兴趣的是在给定文档d和参数α𝛽的情况下,估计主题z的概率,即P(z|d, α, 𝛽)。该问题被公式化为给定文档的隐藏变量的后验分布的计算:

图片作者。

由于这种分布难以计算,Blei 等人(2013 年)建议使用近似推理算法(变分近似)。通过最小化近似分布和真实后验分布之间的 Kullback-Leibler 散度找到优化值P(θ, z|d, α, 𝛽)。一旦我们获得了数据的最佳参数,我们可以再次计算P(z|d, α, 𝛽),在某种意义上,它对应于文档-主题矩阵U𝛽₁, 𝛽₂, ..., 𝛽ₜ的每一个条目都是p(w|z),与术语-主题矩阵V相对应。主要区别在于,很像 pLSA,矩阵系数有一个统计解释。

优点:

  • 它提供了比 LSA 和 pLSA 更好的性能。
  • 与 pLSA 不同,由于文档主题狄利克雷分布,LDA 可以为新文档分配概率。
  • 它既适用于短文档,也适用于长文档。
  • 主题可以由人来解释。
  • 作为一个概率模块,LDA 可以嵌入到更复杂的模型中,也可以扩展。Blei 等人(2013)的原始工作之后的研究扩展了 LDA,并解决了一些原始限制。

缺点:

  • 题目的数量必须事先知道。
  • 与 LSA 和 pLSA 类似,词袋方法不考虑语料库中词的语义表示。
  • 贝叶斯参数αβ的估计基于文档可交换性的假设。
  • 它需要大量的预处理阶段来从文本输入数据中获得有意义的表示。
  • 研究报告 LDA 可能会产生过于笼统的 (Rizvi⁶等人,2019 年)或不相关的 (Alnusyan⁷等人,2020 年)主题。不同的执行结果也可能不一致(Egger⁸等人,2021)。

LDA 的实际例子

流行的 LDA 实现在 Gensimsklearn 包(Python)和 Mallet (Java)中。

在下面的例子中,我们使用 Gensim 库和 pyLDAvis 进行可视化主题探索。

由前面的代码片段生成的 pyLDAvis 主题探索的交互式图表。图片作者。

2.5 非负矩阵分解(NMF)

lee⁴等人(1999)提出的非负矩阵分解(NMF) 是 LSA 的一种变体。

LSA 利用奇异值分解分解文档术语矩阵,提取潜在信息(主题)。SVD 的一个特性是基向量彼此正交,迫使基中的一些元素为负。

简而言之,矩阵系数为负的因式分解(如 SVD)带来了可解释性的问题。减法组合不允许理解一个成分如何对整体作出贡献。NMF 将文档-术语矩阵分解成主题-文档矩阵U和主题-术语矩阵Vᵗ,很像奇异值分解,但是有一个额外的约束,即UVᵗ 只能包含非负元素

此外,虽然我们利用了形式U ∙ Σ ∙ Vᵗ的分解,但在非负矩阵分解的情况下,这变成了:U ∙ Vᵗ

DTM 的分解可以被视为一个优化问题,其目标是最小化 DTM 与其近似值之间的差异。经常采用的距离度量是 Frobenius 范数和 Kullback-Leibler 散度。

NMF 与其他经典模型具有相同的主要优点和缺点(单词袋方法、需要预处理等),但也有一些独特的特征:

优点:

  • 文献论证了 NMF 比 SVD(因此 LSA)在产生更多可解释的和连贯的主题方面的优势(Lee⁴等 1999,Xu⁹等 2003;卡萨利诺·⁰等人,2016 年)。

缺点:

  • 非负约束使得分解更加困难,并可能导致不准确的主题。
  • NMF 问题是非凸问题。不同的UVᵗ可能近似 DTM,导致不同运行的结果可能不一致。

NMF 的实际例子

2.6 BERTopic 和 Top2Vec

Grootendorst (2022)和安杰洛夫(2020)提出了主题建模的新方法,分别是 BERTopicTop2Vec 。这些模型解决了迄今为止讨论的传统策略的局限性。我们将在下面的段落中一起探讨它们。

2.6.1 文件嵌入

BERTopic 和 Top2Vec 从输入文档中制造语义嵌入。

在最初的论文中,BERTopic 利用 BERT 句子转换器(SBERT)来制造高质量的上下文单词和句子向量表示。相反,Top2Vec 使用 Doc2Vec 创建联合嵌入的单词、文档和主题向量。

在撰写本文时,这两种算法都支持各种嵌入策略,尽管 BERTopic 对嵌入模型的覆盖范围更广:

BERTopic 和 Top2Vec 目前支持的嵌入模型。表中的参考资料提供了更详细的信息。

2 . 6 . 2 UMAP 降维

可以将聚类算法直接应用于嵌入,但是这将增加计算开销并导致较差的聚类性能(由于“维数灾难”)。

因此,在聚类之前应用降维技术。 UMAP(均匀流形近似和投影)(麦金尼斯等人,2018)提供了几个好处:

  • 它在较低的投影维度中保留了更多的高维数据的局部全局特征(麦金尼斯等人,2018)。
  • UMAP 对嵌入维数没有计算限制(麦金尼斯等人,2018)。因此,它可以有效地用于不同的文档嵌入策略。
  • 使用 UMAP 降低嵌入维数提高了 K-Means 和 HDBSCAN 在准确性和时间方面的聚类性能(阿拉维⁴等人,2020)。
  • UMAP 可以轻松扩展到大型数据集(安杰洛夫,2020)。

2.6.3 聚类

BERTopic 和 Top2Vec 最初都利用 HDBSCAN(麦金尼斯·⁵等人,2017 年)作为聚类算法。

优点:

  • HDBSCAN 继承了 DBSCAN 的优点,并对其进行了改进(麦金尼斯·⁵等人,2017)。
  • HDBSCAN(作为 DBSCAN)不会将观察结果强制到集群中。它将不相关的观察值建模为异常值。这提高了主题的代表性和连贯性。

缺点:

  • 将不相关的文档建模为离群值可能会导致信息丢失。离群值可能成为噪声数据集中原始语料库的相关部分。

BERTopic 目前还支持 K 均值凝聚聚类算法,提供了选择的灵活性。K-Means 允许选择所需数量的簇,并强制每个文档成为一个簇。这避免了离群值的产生,但也可能导致较差的主题表示和连贯性。

2.6.4。主题表示

BERTopic 和 Top2Vec 在如何制造主题的表示方面互不相同。

BERTopic 将同一个集群(主题)内的所有文档连接起来,并应用修改后的 TF-IDF。简而言之,它用原始 TF-IDF 公式中的集群替换文档。然后,它使用每个聚类的第一个最重要的词作为主题表示。

这个分数被称为基于类别的 TF-IDF (c TF-IDF) ,因为它估计的是词在聚类中的重要性,而不是文档。

Top2Vec 相反,使用最接近集群的质心的单词来生成表示。特别地,对于通过 HDBSCAN 获得的每个密集区域,计算原始维度中文档向量的质心,然后选择最接近的单词向量。

BERTopic 和 Top2Vec 的优劣:

  • 题目数量不一定事先给定。BERTopic 和 Top2Vec 都支持分层主题缩减,以优化主题数量。
  • 与单词袋方法不同,高质量的嵌入考虑了语料库中单词之间的语义关系。这就引出了更好、更丰富的话题。
  • 由于嵌入的语义本质,在大多数情况下不需要文本预处理(词干化、词元化、停用词移除等)。
  • BERTopic 支持动态主题建模。
  • 模块化。每个步骤(文档嵌入、降维、聚类)实际上都是自洽的,并且可以根据该领域的进步、特定项目的特性或技术限制而改变或发展。例如,可以使用具有 Doc2Vec 嵌入的 BERTopic 来代替 SBERT,或者应用 K-Means 聚类来代替 HDBSCAN。
  • 与传统方法相比,它们在更大的语料库中具有更好的扩展性(安杰洛夫,2020)。
  • BERTopic 和 Top2Vec 都提供了高级的内置搜索和可视化功能。它们使调查主题质量和推动进一步优化变得更加简单,并为演示制作高质量的图表。

BERTopic 和 Top2Vec 的对比:

  • 他们更擅长处理较短的文本,如社交媒体帖子或新闻标题。大多数基于 transformers 的嵌入在构建语义表示时,对可以考虑的标记数量有限制。T2 有可能对较长的文档使用这些算法。例如,可以在嵌入步骤之前将文档分成句子或段落。然而,这不一定有利于为较长的文档生成有意义和有代表性的主题。
  • 每个文档只分配给一个主题。相反,像 LDA 这样的传统方法是建立在每个文档都包含混合主题的假设之上的。
  • 与传统模型相比,它们的速度较慢(Grootendorst,2022)。此外,更快的训练和推理可能需要更昂贵的硬件加速器(GPU)。
  • 尽管 BERTopic 利用基于 transformers 的大型语言模型来制造文档嵌入,但主题表示仍然使用单词包方法(c TF-IDF)。
  • 对于小数据集,它们可能不太有效(<1000 docs) (Egger¹⁶ et al., 2022).

BERTopic的实际例子)

由前面的代码片段生成的主题间距离图。该可视化类似于 pyLDAvis 获得的可视化。图片作者。

记录由前面的代码片段生成的投影(细节)。图片作者。

由前面的代码片段生成的主题层次结构(树状图)。图片作者。

top 2 vec 的实际例子

由前面的代码片段生成的与输入查询“faith”最接近的五个主题的词云。图片作者。

3.比较

下表总结了考虑到实际应用场景的不同主题建模策略的显著特征:

不同主题建模技术的比较。 : LSA 和 pLSA 未包括在内,因为 LDA 克服了它们的局限性,被认为是三种方法中的最佳方法。按作者分类的表格。

该汇总表为给定用例提供了高级选择标准

下面分享一些例子。

想象一下,只需很少的预处理工作,就能在推文中找到热门话题。在这种情况下,可以选择使用 Top2Vec 和 BERTopic。它们在较短的文本资源上表现出色,并且不需要太多的预处理。

相反,设想一个场景,其中客户有兴趣发现一个给定的文档如何包含多个主题的混合。在这种情况下,像 LDA 和 NMF 这样的方法会更好。BERTopic 和 Top2Vec 只为一个主题分配一个文档。虽然 HDBSCAN 的概率分布可以作为主题分布的代理,但 BERTopic 和 Top2Vec 并不是混合成员模型的设计

4.附加备注

在讨论主题建模时,有两个主要的注意点值得在我们的旅程结束时提及。

4.1 一个话题(不一定)是我们想象的那样

当我们在候诊室看到一本杂志时,我们一眼就知道它属于哪种类型。当我们进入一段对话时,几句话就足以让我们猜出讨论的对象。这是一个从人类角度出发的话题

不幸的是,术语“主题”在到目前为止讨论的模型中具有完全不同的含义。

让我们记住文档术语矩阵。在高层次上,我们希望将其分解为文档-主题和主题-术语矩阵的产物,并提取该过程中的潜在维度-主题。这些策略(如 LSA)的目标是最小化分解误差。

概率生成模型(如 LDA)添加了一个额外的统计形式层,采用了一种健壮而优雅的贝叶斯方法,但它们真正试图做的是以最小的误差重建原始的文档词分布。

这些模型都不能确保人类的角度来看,所获得的主题是有信息的或有用的。

用 Blei 等人(2013)的漂亮话来说:

“我们将 LDA 模型中的潜在多项式变量称为主题,以便利用面向文本的直觉,但是 除了这些潜在变量在表示单词集 上的概率分布的效用之外,我们不对这些潜在变量做出认识论上的声明。”

另一方面,BERTopic 和 Top2Vec 利用了语义嵌入。因此,从“人”的角度来看,用来表示文档的向量代表了它们的“意义”(这是目前为止我们所知道的最接近的)。这些令人惊叹的模型假设,将这些嵌入的投影聚集起来可能会导致更有意义和更具体的主题。

研究(举几个例子:Grootendorst 2022,Angelov 2020,Egger ⁶等人 2022)表明,利用语义嵌入获得的主题在几个领域中更具信息性和连贯性。

但即使在这种情况下,人类和这类模型的主题定义之间仍然存在潜在的不匹配。这些算法产生的是“语义相似的文档的可解释的、良好表示的和连贯的组”

毫无疑问:这是一个杰出和独特的结果,在该领域开辟了一个全新的前沿,取得了前所未有的成绩。

但是我们仍然会争论这如何接近人类对主题的定义,以及在什么情况下。

而如果你认为这是一个微不足道的微妙之处,你有没有尝试过向商业利益相关者解释类似“ mail_post_email_posting ”这样的话题?是的,它是连贯的,可解释的,但它是他们想象一个“题目”时想到的吗?

这就引出了我们要注意的第二点。

4.2 题目不好评价

主题建模是一种无监督的技术。评估期间没有标签可依赖。

连贯性测量已被提议用于评估主题在可解释性方面的质量。例如,归一化逐点互信息(NPMI) (布马·⁷,2009)估计两个单词xy同现的可能性比我们随机预期的要大:

图片作者。

NPMI 可以从-1(无共现)到+1(完全共现)不等。xy发生之间的独立性导致 NPMI=0。

刘⁸等人(2014)认为,这一指标在合理的程度上模仿了人类的判断。

还存在其他一致性措施。例如,Cv(罗德⁹等人,2015 年)和 UMass(明诺⁰等人,2011 年)。

这些一致性度量存在一系列缺点:

  • 对于定性绩效应使用何种指标,目前尚无统一的约定(左等人,2016 年;布莱尔等人,2020 年;杜根等人,2021 年)。
  • Blair 等人(2020)报告了不同一致性测量之间的不一致结果。
  • Doogan 等人(2021 年)指出了一致性测量在评估特定领域(Twitter 数据)的主题模型时的不可靠性。
  • 霍伊尔·⁴等人 2021 年提出,NPMI 等指标可能无法评估神经主题模型的可解释性。
  • 由于报道的不一致,Cv 的作者不鼓励⁵使用 cv。

正如 Grootendorst (2022 年)所写:

主题一致性和主题多样性等验证措施是本质上主观评估的代理。一个用户对主题的连贯性和多样性的判断可能与另一个用户不同。因此, 虽然这些衡量标准可以用来得到一个模特表现的指标,但它们仅仅是一个指标

总之,验证方法无法清晰地评估主题模型的性能。它们不像分类问题的准确度F1 分数那样提供明确的解释。因此,对所获得主题的“品质度量的量化仍然需要领域知识和人工评估。商业价值的评估(“这些主题会使项目受益吗?”)不是一件小事,可能需要综合指标和整体方法。

5.结论

在这篇文章中,我们分享了流行主题建模算法的友好概述,从生成统计模型到基于变压器的方法。

我们还提供了一个表格,突出了每种技术的优点和缺点。这可用于比较,并有助于不同场景下的初步模型选择。

最后,我们分享了无监督文本数据分析的两个最具挑战性的方面。

首先,人类对“主题”的定义和它的统计对应物之间的差异经常被忽视,这是“主题建模”算法的结果。理解这种差异对于满足项目目标和指导 NLP 工作中业务涉众的期望是至关重要的。

然后,我们讨论了定量评估主题模型性能的困难,介绍了流行的度量标准及其缺点。

6.参考

[1] Deerwester 等人,潜在语义分析索引,《美国信息科学学会杂志》第 41 卷第 6 期第 391–407 页,1990 年(链接)。

[2] Hofmann,概率潜在语义分析,第十五届人工智能不确定性会议论文集(UAI1999),1999 ( 链接)。

[3] Blei 等人,潜在狄利克雷分配,《机器学习研究杂志》第 3 卷第 993–1022 页,2003 ( 链接)。

[4] Lee 等,用非负矩阵分解学习物体的部件,《自然》,第 401 卷,第 788–791 页,1999 ( 链接)。

[5]巴比耶里等,序列数据的概率主题模型,《机器学习》第 93 卷第 5–29 页,2013 ( 链接)。

[6] Rizvi 等人,分析社交媒体数据以了解消费者对膳食补充剂的信息需求,Stud。健康技术。告知。,第 264 卷,第 323–327 页,2019 年(链接)。

[7] Alnusyan 等,一种用于用户评论主题建模和分类的半监督方法,国际计算与信息技术会议,2020 年 1–5 期(链接)。

[8] Egger 和 Yu,识别 Instagram 数据中隐藏的语义结构:一个主题建模比较,Tour。版本 2021:244,2021 ( 链接)。

[9]徐等,基于非负矩阵分解的文档聚类,第 26 届国际 ACM 信息检索研究与发展会议论文集,2003 年第 267–273 页(链接)。

[10] Casalino 等人,智能数据分析的非负矩阵分解,非负矩阵分解技术。Springer,第 49–74 页,2016 ( 链接)。

[11] Grootendorst, BERTopic:基于类的 TF-IDF 过程的神经主题建模,2022 ( 链接)。

[12]安杰洛夫, Top2Vec:主题的分布式表示,2020 ( 链接)。

[13]麦金尼斯等, UMAP:降维的一致流形逼近与投影,2018 ( 链接)。

[14] Allaoui 等人,使用 umap 降维技术显著改进聚类算法:比较研究,图像和信号处理国际会议,斯普林格,第 317–325 页,2020 ( 链接)。

[15]麦金尼斯等, hdbscan:基于层次密度的聚类,开源软件杂志,2(11):205,2017 ( 链接)。

[16] Egger 等人,LDA、NMF、Top2Vec 和 BERTopic 之间的一个主题建模比较,以揭开 Twitter 帖子的神秘面纱,Frontiers in Sociology,Volume 7,Article 886498,2022 ( 链接)。

[17] Bouma,词语搭配抽取中的归一化(逐点)互信息,GSCL 学报,2009 年 30:31–40(链接)。

[18] Lau 等,机器阅读茶叶:自动评估话题连贯性和话题模型质量,计算语言学协会欧洲分会第 14 届会议论文集,第 530–539 页,2014 ( 链接)。

[19]roder 等人,探索主题一致性测量的空间,第八届 ACM 网络搜索和数据挖掘国际会议论文集,第 399-408 页。ACM,2015 ( 链接)。

[20] Mimno 等人,优化主题模型中的语义一致性,Proc .Conf 的。论自然语言处理中的经验方法,第 262–272 页,2011 ( 链接)。

[21] Y .左等,词网主题模型:一种简单但通用的解决短小不平衡文本的方法,《知识与信息系统》,48(2),第 379–398 页(链接)

[22] Blair 等人,增加社交媒体话题连贯性的聚合话题模型,Applied Intelligence,50(1),第 138–156 页,2020 ( 链接)。

[23]杜根等人,话题模型还是话题废话?重新评估语义可解释性测量,计算语言学协会北美分会 2021 年会议记录:人类语言技术,第 3824–3848 页,2021 年(链接)。

[24] Hoyle 等,自动化话题模型评估是否被打破?相干性的非相干性,神经信息处理系统进展,34,2021 ( 链接)。

https://github.com/dice-group/Palmetto/issues/13

数据集许可:本文中的 Python 示例使用了 20 个新闻组数据集,这些新闻组数据集是由 scikit-learn 包在 BSD 3 条款许可下提供的。

政治文本的话题建模

原文:https://towardsdatascience.com/topic-modeling-with-political-texts-4a9b20b5e91

自然语言处理和文本分析系列的第二部分——利用 LDA

欢迎来到我们的自然语言处理和文本分析系列的第二部分!如果你还没有机会,请阅读本系列的第一部分这里。为了总结我们迄今为止的进展,我们从政治著作的文集开始,如马基雅维利的《君主论》、汉密尔顿/麦迪逊/杰伊的《联邦党人文集》和马克思/恩格斯的《***宣言》。从这些作品中,我们导出了文本表格,并使用余弦相似性度量来确定各个作品的聚类,如下所示。

作者图片

在下一部分中,我们将在先前结果的基础上,尝试为这些集群找到最相关的主题。我们确定的三个集群将被称为“Old_West ”,代表较老的西方政治哲学(红色部分),“US”代表美国政治哲学(绿色部分),而“Communist”代表共产主义政治哲学(橙色部分)。我们还将构建在本系列第 1 部分中创建的令牌表,下面显示了一个示例。

作者图片

主题建模 首先我们应该定义什么是主题建模,以及我们希望通过进行这种分析达到的目标。根据维基百科的定义,主题建模是“一种用于发现出现在文档集合中的抽象‘主题’的统计模型”。考虑到我们使用的是政治作品,很明显,每部作品的主题都与政治理想相关,但是通过使用主题建模,我们将寻找在每个聚类的顶级主题中找到的特定单词,并寻找我们不同聚类之间的潜在关系。

我们的第一步将是把我们的令牌表做成进行建模所需的格式。为此,我们首先为标记表中的每个标记添加聚类和作者名称作为主要的分层术语,然后我们将各个标记和句子聚合成一个字符串,形成完整的段落字符串。如果我们聚集了太多,比如整个章节的字符串,我们的许多主题将会完全相同,如果我们使用的样本太少,比如一个句子或单个术语,我们的模型将无法识别正确的主题。我们的新层级应反映以下内容:

*# Create Topic Model OHCO*
OHCO_TM **=** ['clusters', 'authors', 'book_id', 'chap_num', 'para_num']

作者图片

现在我们已经准备好了表,我们可以开始应用我们的主题建模算法了。

tfv **=** CountVectorizer(max_features**=**4000, stop_words**=**'english')
tf **=** tfv**.**fit_transform(PARAS**.**para_str)
TERMS **=** tfv**.**get_feature_names()
**def** model(PARAS **=** PARAS, tf **=** tf, TERMS **=** TERMS):
    lda **=** LDA(n_components**=**25, max_iter**=**10, learning_offset**=**50)
    THETA **=** pd**.**DataFrame(lda**.**fit_transform(tf), index**=**PARAS**.**index)
    THETA**.**columns**.**name **=** 'topic_id'

    *#PHI*
    PHI **=** pd**.**DataFrame(lda**.**components_, columns**=**TERMS)
    PHI**.**index**.**name **=** 'topic_id'
    PHI**.**columns**.**name  **=** 'term_str'

    **return** THETA, PHI

在这个代码块中,我们从使用 sklearn 模块中的 CountVectorizer 函数开始,它遍历我们新创建的表“PARAS”,为前 4000 个术语的计数创建一个稀疏矩阵。可以在传递给 CountVectorizer 函数的参数“max_feature”中调整项数。我们最终将使用潜在的狄利克雷分配(LDA)模型来创建我们的主题。LDA 模型通常用于主题建模,并且在我们的上下文中通过基于所使用的术语识别文档语料库中的主题,然后将这些文档分配给最合适的主题来工作。

上面的 LDA 函数可以在 sklearn 库中找到。我们传递的第一个参数“n_components”设置我们选择创建的主题数量,在本例中是 25 个。第二项“max_iter”指的是在训练数据上的迭代次数,而“learning_offset”用于避免由训练数据中的早期学习引起的错误。

作为 LDA 函数的结果,我们得到了θ和φ的输出。Theta 矩阵将用于确定给定文档中主题的分布,而 Phi 将用于表示特定主题中单词的分布。使用下面的代码块,我们可以做到这一点,这意味着我们可以识别组成每个主题的单词,以及每个集群中最流行的主题。

*# Create topics*
TOPICS **=** PHI**.**stack()**.**to_frame()**.**rename(columns**=**{0:'weight'})\
    **.**groupby('topic_id')\
    **.**apply(**lambda** x: 
           x**.**weight**.**sort_values(ascending**=False**)\
               **.**head(10)\
               **.**reset_index()\
               **.**drop('topic_id',1)\
               **.**term_str)*# Add label column to TOPICS table*
TOPICS['label'] **=** TOPICS**.**apply(**lambda** x: str(x**.**name) **+** ' ' **+** ' '**.**join(x), 1)

*# Set topics by Doc weight*
TOPICS['doc_weight_sum'] **=** THETA**.**sum()*# Topics by book cluster given top 25 topics*
topic_cols **=** [t **for** t **in** range(25)]
CLUSTERS **=** THETA**.**groupby('clusters')[topic_cols]**.**mean()**.**T                                            
CLUSTERS**.**index**.**name **=** 'topic_id'
CLUSTERS**.**TCLUSTERS['topterms'] **=** TOPICS[[i **for** i **in** range(10)]]**.**apply(**lambda** x: ' '**.**join(x), 1)

现在,我们可以对三个集群中的每一个进行排序,以确定哪些主题是最受欢迎的,以及组成这些主题的单词。如下面可以看到的,每个聚类用不同的主题和相关术语集合来最大程度地标识。如前所述,大多数话题都属于政治思想的范畴,这在我们的领域中并不奇怪,但在这些话题中,我们可以看到一些不同的词汇选择。例如,在共产主义集群的主题 17 中,我们可以看到,这个主题通常是关于劳动者和/或劳动条件的,根据我们对这些作品的了解,这也是有意义的,而美国集群中最普遍的主题似乎反映了我们的共和制度的基础词汇。

作者图片

作者图片

作者图片

结论:
如上图所示,我们可以使用主题建模来发现哪些主题在我们的文本聚类中最普遍。主题建模可以是一个强大的工具,用于区分不同的文本数据集,同时识别与数据相关的主要主题和单词。然而,主题建模也有一些缺点,例如潜在的需要专家给每个主题 ID 一个整体的身份,以及主题中单词的重复性质,尤其是那些彼此密切相关的主题。这里获得的结果是基于我们为 LDA 模型选择的特定参数。我鼓励您试验这些参数,看看调优如何改变您的结果。这篇文章是 LDA 和主题建模的基本演示,应该如此对待,而不是模型准确性/成功的决定性证明。一如既往地感谢你花时间阅读这篇文章,如果你想阅读更多,请关注我的频道!

这个项目的完整代码可以在我的 GitHub 页面上找到:https://GitHub . com/nbehe/NLP _ texts/blob/main/Beheshti _ project _ code . ipynb

这个项目是我的文本分析课程的一个大项目的一小部分。来自这个项目的代码是我自己写的,由讲师提供的,以及通过课程材料提供的作品的混合物。

拓扑数据分析(TDA)

原文:https://towardsdatascience.com/topological-data-analysis-tda-b7f9b770c951

不太数学化的介绍

这是关于拓扑数据分析(TDA)的三篇系列文章中的第一篇。TDA 是一种正在兴起的数据科学工具,它可以让观察数据形态。它由各种方法组成,其基本主题是从非结构化数据(即点云)中提取结构(即形状)。在这第一篇文章中,我将对 TDA 做一个浅显易懂的介绍,较少关注数学术语,而更多关注宏观观点。以后的帖子会在 TDA 的保护伞下讨论两个具体的技术: Mapper 算法持久同调

要点

  1. TDA 研究数据的形状
  2. TDA 非常适合高噪声和高维数据集

数据的崛起

跨域的数据量似乎在加速增长。这已经成为许多现代技术的燃料,例如 NLP、图像识别、自动驾驶汽车等。尽管数据是创新的关键,但细节中有魔鬼。

数据量的加速增长。图像来源

生产任务数据,生产任务问题。任何从业者都会告诉你,来自真实世界的数据往往是嘈杂的。我们需要投入大量的精力和精力来将我们测量的东西转化为我们可以分析的东西。

这就是拓扑数据分析(TDA) 可以帮忙的地方。TDA 的目标不是直接处理原始数据,而是提取数据的潜在形态。从这种形状,我们可以评估拓扑特征,它(通常)比原始数据本身更好地适应噪声。

数据→形状。TDA 的基本思想是从数据中提取形状。图片作者。

拓扑学

TDA 是建立在拓扑学数学领域的思想之上的。拓扑学的故事可以追溯到一个著名的数学问题,叫做柯尼斯堡的七座桥。

柯尼斯堡是一座由 7 座桥连接的 4 块陆地组成的城市(如下图)。这个著名的问题是:一个人如何在一条路径上穿过所有 7 座桥,但每座桥只穿过一次?

柯尼斯堡的七座桥(1736 年)。图片来源

如果你试图找到这样一条没有运气的路,不要难过;不存在这样的路径。然而,这一证明使著名数学家莱昂哈德·欧拉为现代图论和拓扑学奠定了基础。

那么,他是怎么做到的呢?欧拉画了一幅柯尼斯堡的图,但不像上面的地图,而是更基本的东西。他画了我们现在称之为的图,它只是一组由线连接起来的点。下图说明了这一点。

欧拉用图表示柯尼斯堡问题的 7 座桥。从到这里的柯尼斯堡地图。欧拉的图片从这里

这张图代表了与问题相关的柯尼斯堡的基本要素。每个点对应于柯尼斯堡的一块陆地,如果相应的陆地由一座桥连接,则两个点由一条线连接。这个问题的简化描述可能看起来微不足道,但它让欧拉解决了问题,改变了数学。

拓扑数据分析(TDA)

TDA 的基本思想让人想起欧拉解决柯尼斯堡问题的七座桥。我们采用真实世界的数据(例如,柯尼斯堡的地图)并提取与我们的问题最相关的潜在形状(例如,代表柯尼斯堡的图形)。这样做的关键好处是我们将数据归结为它的核心结构,它(希望)对噪声不变。

管道

TDA 不是一种单一的技术。更确切地说,它是具有从数据中提取形状这一共同主题的方法的集合。夏萨尔和米歇尔在论文中描述了一种通用的 TDA 管道。该管道的直观概述如下所示。

基于夏萨尔和米歇尔 1 描述的基本 TDA 管道。图片作者。

管道从数据开始。通常,我们可以将任何数据集视为一个 N 维点云。这是因为将数据集中的 N 个变量视为数据点所在的 N 维空间的轴。

下一步是基于点云生成形状。有许多方法可以做到这一点,这区分了不同的 TDA 方法,我们将在本系列的下一篇博客中讨论。

一旦我们有了数据的形状,我们就可以描述它的拓扑特征。我们可以用多种方法来描述形状。例如,给定一个图表(如上图所示),我们可以计算点和线的数量。我们也可以求助于一种叫做同源性的东西,统计数据中“洞”的数。

最后一步,我们可以使用这些拓扑特征进行分析。这可能是基于拓扑特征的统计数据对数据进行分类这样简单的事情,也可能是更复杂的事情,例如使用拓扑特征作为机器学习模型的输入。

承诺

当我第一次接触 TDA 时,我真的很兴奋。我看到了超级酷的用例,如重新定义篮球位置发现 2 型糖尿病亚组。这些数据以引人入胜的可视化方式呈现,如下图所示,清晰地显示了数据中的模式。

TDA 的两个用例。(左)TDA 应用于体育分析。图片来自 Ayasdi 白皮书[ 2 ]。(右)TDA 用于识别糖尿病亚组。图片来自李等人的论文 3

https://medium.datadriveninvestor.com/the-mapper-algorithm-d0842f926658

问题(术语)

但是当我开始更多地了解 TDA 时,这种兴奋被抑制了。(对我来说)问题是大多数文献都充斥着数学证明和术语。我不是说这是一件坏事,只是说这让我更难理解这里发生了什么。这让我想到了这个系列的目标。

目标

在这个系列中,我的目标是捕捉 TDA 所做的事情的本质,而不是深入数学领域。我希望这第一个帖子已经让你对 TDA 有所了解。在以后的文章中,我将通过在 TDA 的保护伞下讨论两种具体的方法来进行更详细的讨论: 映射器算法持久同调 。每篇文章都将介绍这种方法,并通过代码介绍一个具体的、真实的例子。

资源

更上 TDA : 映射器算法 | 持久同调

连接 : 我的网站 | 预定电话 | 消息我

社交:YouTube|LinkedIn|Twitter

支持 : 给我买杯咖啡 ☕️ | 成为会员 ⭐️

https://shawhin.medium.com/membership

[1] 夏萨尔,f .,&米歇尔,B. (2021)。拓扑数据分析导论:数据科学家的基础和实践。人工智能前沿4 ,108。https://doi.org/10.3389/FRAI.2021.667963/BIBTEX

[2] Ayasdi (2013 年)。使用拓扑数据分析进行体育分析。http://www . ayas di . com/WP-content/uploads/_ downloads/Redefining _ Basketball _ Through _ topology _ Data _ analysis . pdf(2022 年 5 月 2 日访问)

[3]李,l .,程,W. Y .,格利克斯伯格,B. S .,戈特斯曼,o .,塔姆勒,r .,陈,r .,博廷格,E. P .,&达德利,J. T. (2015)。通过患者相似性的拓扑分析识别二型糖尿病亚组。科学转化医学7 (311),311ra174。https://doi.org/10.1126/scitranslmed.aaa9364

数据产品团队的拓扑结构

原文:https://towardsdatascience.com/topology-of-a-data-product-team-75dc5471fccf

您的数据网格之旅的成功将取决于您的数据产品团队结构,而不是您的技术选择。以下是组建数据产品团队需要了解的内容。

尤金妮亚·艾Unsplash 上的照片

设计高效的数据产品团队

我发现组织变革是企业数据网格之旅中最困难的部分。除非你为它们做好计划,并尊重改变人们行为的内在挑战,否则你的旅程将是漫长而艰难的。

在本文中,我将讨论数据网格中涉及的团队,并定义数据产品团队的结构和角色。

数据网格是一种“社会技术”方法

data mesh 的创始人扎马克·德格哈尼(Zhamak Dehghani)在她杰出的著作Data Mesh:deliver Data Driven Value at Scale中强调,Data Mesh 是一种共享和访问数据的“社会技术”方法。这意味着,虽然技术方面得到了很多关注(事实上,我的大多数文章讨论了数据网格的实际技术方面),但也有重要的组织(“社会技术”的“社会”部分)考虑。

想想数据网格带来的变化:数据所有权从集中转变为分散,体系结构从单一转变为分布式,随着组织从自上而下转变为联合治理模型,责任也发生了变化。

简单地说,数据网格的组织方面非常重要。这些变化指向一个简单的命题:您的企业数据网格之旅将改变数据团队的组织方式和工作方式。

团队的拓扑

Matthew Skelton 和 Manual Pais 的杰出著作Team topology,描述了交付软件所需的团队生态系统。Dehghani 也使用团队拓扑方法来识别团队。

首先,让我们介绍一下斯凯尔顿和派斯的团队:

  • 流程协调团队是主要的交付团队,负责软件产品或服务的端到端交付。每一个与流程一致的团队都与其他类型的团队(平台、授权和复杂的子系统团队,如下)相互作用。
  • 平台团队,提供工具、实用程序和技术服务,使流程协调团队更容易完成工作,通常提供“X 即服务”功能。
  • 使能团队,作为“顾问”帮助团队克服障碍,通常在短时间内协同互动。
  • 复杂的子系统团队,将需要独特技能或具有显著复杂性的工作交付从流对齐团队中卸载。我发现,在很多情况下,为这些子系统提供一个“包装器”是有意义的,这样可以使数据产品团队更容易使用。

数据产品团队的拓扑结构

现在我们已经奠定了基本的团队结构基础,让我们将这些概念应用到数据产品和更广泛的数据网格中。

数据产品团队是一个与流程一致的团队。它负责端到端的服务交付(接收、消费、发现、可观察性等)。)是数据产品所要求的。像一个与流一致的团队一样,数据产品团队有一个清晰的范围和界限(管理一个确定的数据库、一组表、文件等)。)、负责任的所有者以及提供必要功能的熟练团队。

图 1,数据产品团队

一个数据产品团队与几个团队相互作用:

  • 生产者团队,管理数据产品团队获取的数据源。这个团队的结构可以是传统的源系统团队,或者在企业数据网格中是与流一致的数据产品团队。
  • 消费者团队,访问和使用数据产品团队提供的数据。像生产者团队一样,这个团队可以是一个传统的数据分析团队,或者在企业数据网格中是一个与流一致的数据产品团队。
  • 平台团队提供“X 即服务”功能,使数据产品团队更容易获取、消费和共享数据。根据我的经验,在大型企业中,由几种类型的平台团队支持的数据产品团队非常常见,在许多大型组织中,这些平台团队可能包括云、API、安全和网络团队。
  • 使能团队,帮助数据产品团队克服短期障碍或解决特定需求;在许多大型组织中,这种支持团队可能包括指导小组、企业治理和架构小组,以及培训小组。
  • 复杂的子系统团队,解决需要深入知识的问题领域,这些领域不是单个数据产品团队能够建立和支持的;例如,大型企业可能包括处理主数据管理和大型机技术的团队。

数据产品团队的结构

但是一个数据产品团队是什么样子的呢?当然,没有“标准”的数据产品团队。每种数据产品可能需要特定于它们所使用的技术堆栈的技能,或者消费者要求的可互操作接口的类型,或者用于接收数据的管道技术。尽管如此,数据产品团队的规模通常在 8-15 人之间变化(Skelton 和 Pais 建议在任何与流一致的团队(如数据产品团队)中最多 15 人)。

数据产品团队由“数据产品所有者”领导。Dehghani 声明该角色“负责一个领域的数据产品在交付价值、满足和发展数据用户以及维护数据产品的生命周期方面的成功”。他们负责建立数据产品的方向和路线图,获取数据产品的资金,并确定和联络各种利益相关者和与数据产品团队互动的其他团队。简而言之,数据产品负责人是数据产品团队的代言人。

图二,数据产品团队架构

通常有几个向数据产品所有者报告的角色:

  • 元数据管理,为数据产品定义、控制和管理元数据。这个团队/角色将具有元数据存储库方面的专业知识,并将维护数据产品语义、术语表和知识图的完整性。
  • 数据管理和安全,管理、保护和控制数据产品中的数据;该团队/角色拥有关于业务领域、元数据和数据产品所管理的数据的安全需求的专业知识。
  • 消费服务,构建、支持和发展消费由数据产品管理的数据所需的服务。这个团队通常拥有开发由数据产品提供的可互操作接口的技能。
  • 摄取服务,构建、支持和发展摄取由数据产品管理的数据所需的服务。这个团队/角色拥有将数据导入数据产品的管道、SQL 和数据工程技能。
  • 发布管理,对数据产品的整体路线图和演进进行管理、沟通和社会化。这个团队/角色具有多种技能:与企业发布过程集成的开发人员技能,以及传播数据产品中的变更所需的沟通技能。

总结想法

构建您的团队和组织以取得成功对于加速您的数据网格之旅至关重要。希望本文为您提供了构建数据产品团队的组织构件。


本文假设您对数据网格有很高的理解。更多信息可在此处(数据产品)此处(数据网格模式)此处(数据网格架构)此处(数据网格原则)和此处(经验教训)。对于感兴趣的读者,我的全套数据网格文章可在这里获得。


除非另有说明,本文中的所有图片均由 Eric Broda(本文作者)创作。图像中使用的所有图标都是普通的 PowerPoint 图标和/或不受版权保护。

本文表达的观点仅代表我个人,不一定代表我的客户的观点。

Torch 和 Torchvision C++在 Linux 上的安装和调试

原文:https://towardsdatascience.com/torch-and-torchvision-c-installation-and-debugging-on-linux-263676c38fa2

Torchvision 中的 RoIAlign 调试示例

https://unsplash.com/@udayawal

介绍

在本教程中,我们将在 Linux 机器上安装 TorchTorchvision C++库来调试一个不是用 Python 而是用 C++编写的函数。因为我们感兴趣的函数是用 C++编写的,而不是用 Pytorch 编写的,所以我们不能从 Python API 到 Torchvision 调试它,因此我们需要深入研究 C++代码。如果你想知道更多关于 Python 和 C++如何链接以及如何从 Python 中调用 C++代码的信息,你可以参考我之前的文章这里

火炬安装

首先我们需要下载 Torchlib C++库,它提供了使用 Torch 所需的所有头文件和库的二进制发行版。这可以从 PyTorch 官方网站这里完成。我选择了以下下载配置:

作者图片—图 1

然后,我们为项目创建一个新文件夹,将。我们刚刚下载的 zip 文件夹,并在那里解压缩。

mkdir torchinstall
unzip libtorch-cxx11-abi-shared-with-deps-1.13.1+cpu.zip

从这里我们将参考 Torch 的官方文档来编译和构建依赖于 Torch 库的文件。首先让我们创建两个文件:

  • main.cpp — C++文件,我们将在其中编写一些代码,以确保我们可以使用安装火炬库,并且它在我们的机器上工作
  • CMakeLists.txt —包含 CMake 工具生成和构建文件的指令的文本文件

以及一个构建文件夹,我们编译的 main.cpp 文件将存储在其中

touch main.cpp
touch CMakeLists.txt

#################################################################
touch main.cpp file will contain the following code:

// import libraries 
#include <iostream>
#include <torch/torch.h>

int main(){
  torch::manual_seed(0); // set manual seed
  torch::Tensor x = torch::randn({2,3}); // create torch random tensor
  std::cout << x;} // print tensor

#################################################################
touch CMakeLists.txt file will contain the following:

cmake_minimum_required(VERSION 3.0)
# project name
project(debugfunc)

# define path to the libtorch extracted folder
set(CMAKE_PREFIX_PATH /home/alexey/Desktop/torchinstall/libtorch)

# find torch library and all necessary files
find_package(Torch REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")

# executable to add that we want to compile and run
add_executable(debugfunc main.cpp)
# link torch libraries to our executable
target_link_libraries(debugfunc "${TORCH_LIBRARIES}")
set_property(TARGET debugfunc PROPERTY CXX_STANDARD 14)
#################################################################

# create build folder
mkdir build

现在我们已经准备好编译、构建和运行我们的 main.cpp 文件。

# go into the build folder
cd build
# compile main.cpp file
cmake ..
# build it
make
# run the built file
./debugfunc

如果一切正常,您应该会看到以下输出:

作者图片—图 2

恭喜你,你现在可以构建和运行使用 torch C++库的文件了!下一步是安装 torchvision C++库。

火炬视觉装置

让我们回到我们的桌面目录,创建另一个名为火炬视觉的文件夹。首先从这里下载 zip torchvision C++库,放入 out torchvision 目录并解压。之后我们进入解压后的文件夹 vision-main ,创建一个 build 目录,打开 vision-main 中的 CMakeLists.txt 文件进行修改和添加一些东西。

mkdir torchvision
unzip vision-main.zip
cd vision-main

mkdir build

对我来说, CMakeLists.txt 文件的最终版本如下所示。我添加了 CMAKE_PREFIX_PATH ,关闭了所有选项像 WITH_CUDAWITH_PNGWITH_JPEGUSE_PYTHON

cmake_minimum_required(VERSION 3.12)
project(torchvision)
set(CMAKE_CXX_STANDARD 14)
file(STRINGS version.txt TORCHVISION_VERSION)

# added CMAKE_PREFIX_PATH
set(CMAKE_PREFIX_PATH /home/alexey/Desktop/torchinstall/libtorch;)

# turned off all the options
option(WITH_CUDA "Enable CUDA support" OFF)
option(WITH_PNG "Enable features requiring LibPNG." OFF)
option(WITH_JPEG "Enable features requiring LibJPEG." OFF)
option(USE_PYTHON "Link to Python when building" OFF)

if(WITH_CUDA)
  enable_language(CUDA)
  add_definitions(-D__CUDA_NO_HALF_OPERATORS__)
  add_definitions(-DWITH_CUDA)
  set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} --expt-relaxed-constexpr")
  # CUDA-11.x can not be compiled using C++14 standard on Windows
  string(REGEX MATCH "^[0-9]+" CUDA_MAJOR ${CMAKE_CUDA_COMPILER_VERSION})
  if(${CUDA_MAJOR} GREATER 10 AND MSVC)
    set(CMAKE_CXX_STANDARD 17)
  endif()
endif()

find_package(Torch REQUIRED)

if (WITH_PNG)
    add_definitions(-DPNG_FOUND)w
    find_package(PNG REQUIRED)
endif()

if (WITH_JPEG)
    add_definitions(-DJPEG_FOUND)
    find_package(JPEG REQUIRED)
endif()

if (USE_PYTHON)
  add_definitions(-DUSE_PYTHON)
  find_package(Python3 REQUIRED COMPONENTS Development)
endif()

function(CUDA_CONVERT_FLAGS EXISTING_TARGET)
    get_property(old_flags TARGET ${EXISTING_TARGET} PROPERTY INTERFACE_COMPILE_OPTIONS)
    if(NOT "${old_flags}" STREQUAL "")
        string(REPLACE ";" "," CUDA_flags "${old_flags}")
        set_property(TARGET ${EXISTING_TARGET} PROPERTY INTERFACE_COMPILE_OPTIONS
            "$<$<BUILD_INTERFACE:$<COMPILE_LANGUAGE:CXX>>:${old_flags}>$<$<BUILD_INTERFACE:$<COMPILE_LANGUAGE:CUDA>>:-Xcompiler=${CUDA_flags}>"
            )
    endif()
endfunction()

if(MSVC)
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4819")
  if(WITH_CUDA)
    set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=/wd4819")
    foreach(diag cc_clobber_ignored integer_sign_change useless_using_declaration
      set_but_not_used field_without_dll_interface
      base_class_has_different_dll_interface
      dll_interface_conflict_none_assumed
      dll_interface_conflict_dllexport_assumed
      implicit_return_from_non_void_function
      unsigned_compare_with_zero
      declared_but_not_referenced
      bad_friend_decl)
      string(APPEND CMAKE_CUDA_FLAGS " -Xcudafe --diag_suppress=${diag}")
    endforeach()
    CUDA_CONVERT_FLAGS(torch_cpu)
    if(TARGET torch_cuda)
      CUDA_CONVERT_FLAGS(torch_cuda)
    endif()
    if(TARGET torch_cuda_cu)
      CUDA_CONVERT_FLAGS(torch_cuda_cu)
    endif()
    if(TARGET torch_cuda_cpp)
      CUDA_CONVERT_FLAGS(torch_cuda_cpp)
    endif()
  endif()
endif()

include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

set(TVCPP torchvision/csrc)
list(APPEND ALLOW_LISTED ${TVCPP} ${TVCPP}/io/image ${TVCPP}/io/image/cpu ${TVCPP}/models ${TVCPP}/ops
  ${TVCPP}/ops/autograd ${TVCPP}/ops/cpu ${TVCPP}/io/image/cuda)
if(WITH_CUDA)
    list(APPEND ALLOW_LISTED ${TVCPP}/ops/cuda ${TVCPP}/ops/autocast)
endif()

FOREACH(DIR ${ALLOW_LISTED})
    file(GLOB ALL_SOURCES ${ALL_SOURCES} ${DIR}/*.*)
ENDFOREACH()

add_library(${PROJECT_NAME} SHARED ${ALL_SOURCES})
target_link_libraries(${PROJECT_NAME} PRIVATE ${TORCH_LIBRARIES})

if (WITH_PNG)
    target_link_libraries(${PROJECT_NAME} PRIVATE ${PNG_LIBRARY})
endif()

if (WITH_JPEG)
    target_link_libraries(${PROJECT_NAME} PRIVATE ${JPEG_LIBRARIES})
endif()

if (USE_PYTHON)
  target_link_libraries(${PROJECT_NAME} PRIVATE Python3::Python)
endif()

set_target_properties(${PROJECT_NAME} PROPERTIES
  EXPORT_NAME TorchVision
  INSTALL_RPATH ${TORCH_INSTALL_PREFIX}/lib)

include_directories(torchvision/csrc)

if (WITH_PNG)
    include_directories(${PNG_INCLUDE_DIRS})
endif()

if (WITH_JPEG)
    include_directories(${JPEG_INCLUDE_DIRS})
endif()

set(TORCHVISION_CMAKECONFIG_INSTALL_DIR "share/cmake/TorchVision" CACHE STRING "install path for TorchVisionConfig.cmake")

configure_package_config_file(cmake/TorchVisionConfig.cmake.in
  "${CMAKE_CURRENT_BINARY_DIR}/TorchVisionConfig.cmake"
  INSTALL_DESTINATION ${TORCHVISION_CMAKECONFIG_INSTALL_DIR})

write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/TorchVisionConfigVersion.cmake
  VERSION ${TORCHVISION_VERSION}
  COMPATIBILITY AnyNewerVersion)

install(FILES ${CMAKE_CURRENT_BINARY_DIR}/TorchVisionConfig.cmake
  ${CMAKE_CURRENT_BINARY_DIR}/TorchVisionConfigVersion.cmake
  DESTINATION ${TORCHVISION_CMAKECONFIG_INSTALL_DIR})

install(TARGETS ${PROJECT_NAME}
  EXPORT TorchVisionTargets
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  )

install(EXPORT TorchVisionTargets
  NAMESPACE TorchVision::
  DESTINATION ${TORCHVISION_CMAKECONFIG_INSTALL_DIR})

FOREACH(INPUT_DIR ${ALLOW_LISTED})
    string(REPLACE "${TVCPP}" "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}" OUTPUT_DIR ${INPUT_DIR})
    file(GLOB INPUT_FILES ${INPUT_DIR}/*.*)
    install(FILES ${INPUT_FILES} DESTINATION ${OUTPUT_DIR})
ENDFOREACH()

之后,我们进入构建文件夹,编译、构建并安装库。

cd build
cmake ..
make
sudo make install

如果您没有看到任何错误(警告不是错误!)那么一切应该都没问题。现在让我们测试一下我们可以在项目中导入 torchvision 库。回到 torchinstall 文件夹,进入 main.cppCMakeLists.txt 文件,修改如下:

// main.cpp we import torchvision library

#include <iostream>
#include <torch/torch.h>
#include <torchvision/vision.h>

int main(){
  torch::manual_seed(0);
  torch::Tensor x = torch::randn({2,3});
  std::cout << x;
}
cmake_minimum_required(VERSION 3.0)
project(debugfunc)

set(CMAKE_PREFIX_PATH /home/alexey/Desktop/torchinstall/libtorch)

find_package(Torch REQUIRED)
find_package(TorchVision REQUIRED)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")

add_executable(${PROJECT_NAME} main.cpp)
target_compile_features(${PROJECT_NAME} PUBLIC cxx_range_for)
target_link_libraries(${PROJECT_NAME} TorchVision::TorchVision)
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14)

现在像以前一样编译、构建和运行:

# compile main.cpp file
cmake ..
# build it
make
# run the built file
./debugfunc

您应该看不到错误,并再次看到相同的张量输出:

作者图片—图 3

酷,我们现在已经安装了火炬视觉库!

调试功能

现在,假设我们想从 C++的 torchvision 库中调试 roi_align 函数。我使用可视代码进行调试,因为我们使用 CMake,所以您需要在可视代码中安装一些依赖项,以便能够在其中进行调试。我发现这个视频上手挺有用的。

为了调试 roi_align 函数,我必须从这个路径复制粘贴一些位:torch vision/CSRC/ops/CPU以下面的 main.cpp 文件结束

#include <iostream>
#include <torch/torch.h>
#include <torchvision/vision.h>
#include <torchvision/ops/nms.h>
#include <torch/script.h>

#include <ATen/core/dispatch/Dispatcher.h>
#include <torch/library.h>
#include <torch/types.h>

#include <ATen/ATen.h>
#include <torchvision/ops/cpu/roi_align_common.h>

namespace vision {
namespace ops {

namespace {

template <typename T>
void roi_align_forward_kernel_impl(
    int n_rois,
    const T* input,
    const T& spatial_scale,
    int channels,
    int height,
    int width,
    int pooled_height,
    int pooled_width,
    int sampling_ratio,
    bool aligned,
    const T* rois,
    T* output) {a
  // (n, c, ph, pw) is an element in the pooled output
  // can be parallelized using omp
  // #pragma omp parallel for num_threads(32)
  for (int n = 0; n < n_rois; n++) {
    int index_n = n * channels * pooled_width * pooled_height;

    const T* offset_rois = rois + n * 5;
    int roi_batch_ind = offset_rois[0];

    // Do not using rounding; this implementation detail is critical
    T offset = aligned ? (T)0.5 : (T)0.0;
    T roi_start_w = offset_rois[1] * spatial_scale - offset;
    T roi_start_h = offset_rois[2] * spatial_scale - offset;
    T roi_end_w = offset_rois[3] * spatial_scale - offset;
    T roi_end_h = offset_rois[4] * spatial_scale - offset;

    T roi_width = roi_end_w - roi_start_w;
    T roi_height = roi_end_h - roi_start_h;
    if (!aligned) {
      // Force malformed ROIs to be 1x1
      roi_width = std::max(roi_width, (T)1.);
      roi_height = std::max(roi_height, (T)1.);
    }

    T bin_size_h = static_cast<T>(roi_height) / static_cast<T>(pooled_height);
    T bin_size_w = static_cast<T>(roi_width) / static_cast<T>(pooled_width);

    // We use roi_bin_grid to sample the grid and mimic integral
    int roi_bin_grid_h = (sampling_ratio > 0)
        ? sampling_ratio
        : ceil(roi_height / pooled_height); // e.g., = 2
    int roi_bin_grid_w =
        (sampling_ratio > 0) ? sampling_ratio : ceil(roi_width / pooled_width);

    // We do average (integral) pooling inside a bin
    // When the grid is empty, output zeros.
    const T count = std::max(roi_bin_grid_h * roi_bin_grid_w, 1); // e.g. = 4

    // we want to precalculate indices and weights shared by all chanels,
    // this is the key point of optimization
    std::vector<detail::PreCalc<T>> pre_calc(
        roi_bin_grid_h * roi_bin_grid_w * pooled_width * pooled_height);
    detail::pre_calc_for_bilinear_interpolate(
        height,
        width,
        pooled_height,
        pooled_width,
        roi_start_h,
        roi_start_w,
        bin_size_h,
        bin_size_w,
        roi_bin_grid_h,
        roi_bin_grid_w,
        pre_calc);

    for (int c = 0; c < channels; c++) {
      int index_n_c = index_n + c * pooled_width * pooled_height;
      const T* offset_input =
          input + (roi_batch_ind * channels + c) * height * width;
      int pre_calc_index = 0;

      for (int ph = 0; ph < pooled_height; ph++) {
        for (int pw = 0; pw < pooled_width; pw++) {
          int index = index_n_c + ph * pooled_width + pw;

          T output_val = 0.;
          for (int iy = 0; iy < roi_bin_grid_h; iy++) {
            for (int ix = 0; ix < roi_bin_grid_w; ix++) {
              detail::PreCalc<T> pc = pre_calc[pre_calc_index];
              output_val += pc.w1 * offset_input[pc.pos1] +
                  pc.w2 * offset_input[pc.pos2] +
                  pc.w3 * offset_input[pc.pos3] + pc.w4 * offset_input[pc.pos4];

              pre_calc_index += 1;
            }
          }
          output_val /= count; // Average pooling

          output[index] = output_val;
        } // for pw
      } // for ph
    } // for c
  } // for n
}

template <class T>
inline void add(T* address, const T& val) {
  *address += val;
}

at::Tensor roi_align_forward_kernel(
    const at::Tensor& input,
    const at::Tensor& rois,
    double spatial_scale,
    int64_t pooled_height,
    int64_t pooled_width,
    int64_t sampling_ratio,
    bool aligned) {
  TORCH_CHECK(input.device().is_cpu(), "input must be a CPU tensor");
  TORCH_CHECK(rois.device().is_cpu(), "rois must be a CPU tensor");
  TORCH_CHECK(rois.size(1) == 5, "rois must have shape as Tensor[K, 5]");

  at::TensorArg input_t{input, "input", 1}, rois_t{rois, "rois", 2};

  at::CheckedFrom c = "roi_align_forward_kernel";
  at::checkAllSameType(c, {input_t, rois_t});

  auto num_rois = rois.size(0);
  auto channels = input.size(1);
  auto height = input.size(2);
  auto width = input.size(3);

  at::Tensor output = at::zeros(
      {num_rois, channels, pooled_height, pooled_width}, input.options());

  if (output.numel() == 0)
    return output;

  auto input_ = input.contiguous(), rois_ = rois.contiguous();
  AT_DISPATCH_FLOATING_TYPES_AND_HALF(
      input.scalar_type(), "roi_align_forward_kernel", [&] {
        roi_align_forward_kernel_impl<scalar_t>(
            num_rois,
            input_.data_ptr<scalar_t>(),
            spatial_scale,
            channels,
            height,
            width,
            pooled_height,
            pooled_width,
            sampling_ratio,
            aligned,
            rois_.data_ptr<scalar_t>(),
            output.data_ptr<scalar_t>());
      });
  return output;
}

} // namespace

} // namespace ops
} // namespace vision

int main(){
  torch::manual_seed(0);

  // load tensors saved from Python 
  torch::jit::script::Module tensors = torch::jit::load("/media/sf_Linux_shared_folder/roialign/tensors.pth");
  c10::IValue feats = tensors.attr("cr_features");
  torch::Tensor feat_ts = feats.toTensor();

  c10::IValue boxes = tensors.attr("cr_proposal");
  torch::Tensor boxes_ts = boxes.toTensor();

  std::cout << boxes_ts << std::endl;

  double spatial_scale = 1.0;
  int64_t pooled_height = 2, pooled_width = 2, sampling_ratio = -1;
  bool aligned = false;

  at::Tensor out = vision::ops::roi_align_forward_kernel(feat_ts, boxes_ts, spatial_scale, pooled_height, pooled_width, sampling_ratio, aligned);

  std::cout << out;

}

你会注意到我加载了特性建议张量,我在这篇文章中使用了这些张量用于 roi_align。现在你可以在任何你想调试代码的地方放置断点,然后一行一行地查看发生了什么。

结论

在本文中,我们看到了如何在 Linux 机器上安装 torchtorchvision C++库,并调试我们无法在 Pytorch Python API 中直接调试的函数。如果你知道如何不用复制粘贴就能调试函数的简单方法,请在评论中告诉我。

咖啡中总溶解固体的测量会受到样品温度的轻微影响

原文:https://towardsdatascience.com/total-dissolved-solids-tds-in-coffee-is-slightly-affected-by-sample-temperature-929390babf2d

咖啡数据科学

收集数据以帮助定义协议

对咖啡进行量化很困难,但在咖啡行业的所有咖啡方法中,有一个常用的单一指标, 【总溶解固体量】 。TDS 是用折射仪测量的,它会告诉你杯子里有多少咖啡固体。从这个指标,你可以得出提取率(EY),以量化咖啡提取的效率。

许多人提议制定一个更严格的 T4 协议来收集 TDS 样本。我专门查看了样本温度。在 40 对数据样本中,我确实在热测量和冷测量中发现了统计上的显著差异,但这种差异很小,并且是线性相关的。

审查建议的 TDS 方案

一些人提出了具体而详细的 TDS 测量方案,让我们回顾一下主要组成部分:

  1. 将咖啡彻底混合
  2. 收集样本
  3. 在冷水下冲洗或让样品达到室温
  4. 用过滤注射器过滤
  5. 测量样品

这些步骤中的一些还没有被证明能提供更好的 TDS 测量。我之前对过滤样本有过异议。我不认为过滤已被证明能更好地衡量地面真相。

所有图片由作者提供

本文将关注第 3 步,即样本温度。我还没有看到数据显示,由于样品的冷热,TDS 发生了有统计意义的变化。我更喜欢测量热样品,我认为只要测量所有热样品,这个变量就是可控的。然而,我想知道它与较冷的样品相比如何。

数据

我在 40 杯浓缩咖啡中收集了 40 个样本。对于每个样本,我执行了以下方案:

  1. 立即读取 TDS 读数(热 TDS 样本)。
  2. 用移液管吸取样本液体。
  3. 倒置移液管。
  4. 放在冷水中。
  5. 收集了另一个 TDS 读数(冷 TDS 样本)。

以下是按热 TDS 值排序的数据:

以下是冷 TDS 和热 TDS 的散点图比较:

样本具有高相关性,最佳拟合趋势线具有高 R 值,但略有偏移。读数有 0.20 的微小差异,该值具有统计学意义,因为双尾 t 检验显示值为 0.0035(统计学显著性< 0.05)。

如果冷样品具有更高的 TDS,我将测试重量是否因蒸发而改变,但这并没有发生。

我对冷热 TDS 样本进行了测试比较,发现温度会导致测量值略有差异。这种差异具有统计学意义,但冷热样品之间有很好的线性拟合。这意味着,如果你有一个测量,你可以准确地预测另一个。

对我来说,0.2 的差别并不算多,因为我的浓缩咖啡有很高的 TDS。对于 TDS 读数较低的咖啡,这种差异可能更有影响。然而,只要线性相关性对于较低的 TDS 值是强的,对我来说结论将是相同的。

我的结论是,我不需要一个方案来冷却样品。不疼,但是比较费时间。只要我在收集所有热的或冷的样品,它们都是可比较的。甚至为了与其他人的 TDS 读数进行比较,人们只需要知道它是热的还是冷的。

TDS 是一个如此重要的指标,我希望对该设备有更好的了解可以消除一些障碍,使其在整个咖啡社区得到更广泛的采用。

如果你愿意,可以在推特、 YouTubeInstagram 上关注我,我会在那里发布不同机器上的浓缩咖啡照片和浓缩咖啡相关的视频。你也可以在 LinkedIn 上找到我。也可以关注我在订阅

我的进一步阅读:

我未来的书

我的链接

浓缩咖啡系列文章

工作和学校故事集

咖啡萃取

咖啡中总溶解固体量仪与研磨真相的比较

原文:https://towardsdatascience.com/total-dissolved-solids-tds-meter-compared-to-groundtruth-in-coffee-f01efc25b7d9

咖啡数据科学

发现未知的广度

几年来,我一直在用折光仪测量浓缩咖啡中的总溶解固体(TDS)。我一直很好奇 TDS 测量对地面真相的精确度。公开的信息不多,所以我决定收集一些。

我用了浓缩咖啡粉作为地面真相。浓缩咖啡粉是将浓缩咖啡脱水,直到只剩下溶解的固体。我的浓缩咖啡粉有点结块,所以我必须把它打碎。

所有图片由作者提供

以下是我遵循的协议:

  1. 打碎一些浓缩咖啡粉,用秤测量
  2. 加入热水并用秤称重(目标为某一 TDS)
  3. 用三个样品测量 TDS
  4. 使用中间样本

样品本身非常稳定。通常,当测量咖啡的 TDS 时,TDS 会有一些噪声。这些样本都没有经过过滤。然而,方差非常低,就好像它们被过滤了一样。

我有目的地收集样本,以达到特定的 TDS。当在相同的 TDS 下采集几个样本时,结果是相似的。最佳拟合线显示了测量中的微小误差,但是 R 值很高。如果我们使用 TDS 测量,那么地面实况测量稍高,具有非常强的线性相关性。

这些结果对我来说非常有趣,因为误差的绝对值在增加。以 15% TDS 测量的样品实际上可能接近 17%。这似乎表明,我的提取产量比我以前想象的还要高。这种差异也可以归因于不是所有的浓缩咖啡粉末都溶解在溶液中。这是许多实验中的一个,以了解我认为对咖啡来说仍然是美妙和重要的一个实验。

如果你愿意,可以在推特、 YouTubeInstagram 上关注我,我会在那里发布不同机器上的浓缩咖啡照片和浓缩咖啡相关的视频。你也可以在 LinkedIn 上找到我。也可以关注我在订阅

我的进一步阅读:

我的书

我的链接

浓缩咖啡系列文章

工作和学校故事集

断奏生活方式概述

基本统计 R 命令的全部解释

原文:https://towardsdatascience.com/total-interpretation-of-basic-statistical-r-commands-355a5f302858

R 系列中的统计

图片来自 Unsplash

简介

对于统计分析来说,r 是一种非常强大的编程语言。有几个用于统计分析的编程平台,但 R 在数据科学家和数据分析师中获得了真正的吸引力,因为它固有的能力比其他平台更好地执行统计任务,并且更美观地提供可视化。在本文中,我将演示在 r 中执行的非常基本的统计命令的解释。任何人都可以在其他几个平台上执行这些任务,但我们需要理解其执行背后的真正想法,因为这些统计概念是永恒的。软件、程序、版本——一切都可以更新,但统计分析背后的概念不会改变。

数据

为了进行演示,我将使用 2016 年收集的综合社会调查(GSS)数据。这些数据是从宗教数据档案协会下载的,由汤姆·w·史密斯收集。该数据集收集了近 3,000 名受访者的回复,并包含与若干社会经济特征相关的数据。例如,它有与婚姻状况、教育背景、工作时间、就业状况等相关的数据。让我们深入这个数据集,我对它有了更多的了解。

GSS 数据(2016 年)

婚姻和学位编码值的描述如下所示,因为我们将在后续分析中使用这些特征。

该数据集包括几个定量或分类的特征。分类数据也按顺序编码。例如,教育背景有六个不同的类别,每个类别被分配一个从 0 开始的数字。性别也是分类的,并且只为该特征分配两个值:“1”代表男性,“2”代表女性。还有几个量化数据例子年龄。要了解更多关于分配的数字,读者需要转到给定的链接,并找出哪个数字与哪个分类值相关联。我们将使用这些数据,对分类和定量数据执行以下命令,并解释输出。

这里还显示了库。我会用 Rstudio。目标是理解这些命令的输出,而不是强调语法。

分组依据

group_by 是用于任何分析的最基本和最广泛使用的命令之一。它根据给定的特征变量对数据进行分组。一旦这个 group_by 命令被执行并存储在一个变量中,我们就可以汇总该变量并显示所需的统计数据。

上面的命令显示了按不同性别分组的年龄的平均值、最大值、最小值和标准差,这些对于任何数据集都是非常重要的统计数据。

Group_by with descr

其他重要的统计数据可以通过结合使用 descr 命令和 group_by 来确定。

上面的快照显示数据按组 1 分组,它描述的变量是年龄。变量的类型是数字,总共有 1212 个数据点,空值的数量为 0。它的平均值为 51.57,标准偏差为 15.67。然后我们有一个标准误差,这里用 se 表示。标准误差是标准偏差除以数据点总数的平方根。在这种情况下,它是 15.67/平方根(1212)。接下来,我们得到的中值是 52。它说属于第一组的人的平均年龄是 52 岁。第一组是为已婚人士设立的小组。然后是调整后的范围,这里显示的是 51–80。它基本上消除了较低和较高数据点的百分比,但实际范围显示为 19-99。IQR 值被确定为 24.25,这是第三个四分位数和第一个四分位数之间的差值(Q3-Q1)。IQR 值非常便于确定盒状图的上限和下限,以消除异常值。最后,我们得到的偏斜值为 0.27。该值表示分布相当正常。任何大于 1 的值几乎都是右偏的,任何小于-1 的值都被认为是左偏的。

按所选特征统计

我们还可以使用不同的库来确定不同参数的各种统计数据。其中一个执行如下所示。

输出在第一行显示数据点的总数,在第二和第三行显示空值的总数。接下来,我们有最小值和最大值以及范围值。总和、中值、平均值和标准误差也显示在后续行中。我们还有 95%置信区间均值数据的值。然后,我们也有方差和标准偏差值,以及变异系数。方差是标准差的平方,方差系数是标准差除以平均值。标准差是确定所需参数范围的主要变量。然而,变异系数是另一种用平均值来衡量价差的方法。

表命令

Table 是一个非常强大的命令,可以直观地将数据分成两个不同的组。例如,在下图中,数据被分为两组:第一组是婚姻状况,第二组是学位状况。

由于分类变量是编码的,我们需要参考数据集的描述来理解潜在的关系。例如,行中的 0 表示受教育程度低于高中的人,列中的 1 表示已婚的人。因此,110 人的教育背景不到高中,已婚。随着教育背景的变化有不同的数字。

其他杂项命令

由 frq 表示的频率命令确定所选特征的重要统计。它还显示百分比值和累计百分比。

如果选择了多个因子,summary 命令会显示卡方检验输出。我们可以输入之前确定的 tab 变量。

我想从卡方检验中澄清这些数字。首先,tab 变量保存来自婚姻状况和教育背景状况的表数据。卡方检验所做的是,检查一个变量与另一个变量的独立性。在这里,卡方检验是检查学历是否与婚姻状况有关。

它根据假设检验计算 p 值。这里的零假设表明,感兴趣的变量(婚姻和学位)不相互依赖。另一种假设认为变量是相关的,可能存在某种相关性。在这种情况下,p 值非常小。通常的显著性水平是 5%。由于 p 值小于 0.05,我们可以拒绝零假设,得出教育背景与婚姻状况有关的结论。

addmargins 命令提供行和列的总和。

交叉表

Crosstable 命令是另一个非常强大的命令,用于可视化表格输出并获得更多统计信息。

除了数量(N)之外,它还提供了卡方分布、占每行和每列总数的百分比以及占总数的百分比。

我们还可以确定卡方值和相应的 p 值,如下所示。它还提供相同的统计数据。卡方值为 480.19,自由度为 25。在 crosstable 命令的输出中,您可以看到每个段对总卡方值 480.19 的贡献。自由度值通过乘以(行数-1)和(列数-1)来计算。

结论

我们已经介绍了统计分析所需的几个重要 R 命令的最基本解释。这些对于分类和定量数据分析都是必需的,尽管随后的步骤即回归可以不同地进行。

感谢阅读。

本文的 Youtube 演练

https://mdsohel-mahmood.medium.com/membership https://mdsohel-mahmood.medium.com/subscribe

R 中回归和 ANOVA 命令的全部解释

原文:https://towardsdatascience.com/total-interpretation-of-regression-and-anova-commands-in-r-ed8982c12473

R 系列中的统计

图片来自 Unsplash

简介

回归是统计学家首先执行的统计分析之一,以获得因变量对一个或多个自变量的依赖性细节。只有一个自变量的分析,称为简单线性回归,如果有多个自变量,则称为多元线性回归。使用 R,只需执行几行代码就可以获得与回归相关的必要统计数据。我们知道,多元线性回归受制于一些假设,这些假设在应用回归参数之前需要得到满足。读者可以在下面找到关于这个主题的文章。

简单线性回归也需要所有这些条件,但多重共线性除外,因为在这种情况下只有一个独立参数。

假设

  • 线性 —做第一个假设是相当明显和直接的。我们应该能够在我们试图拟合的变量之间保持线性关系。如果变量之间没有线性关系,可以将数据转换成线性形式。可以通过对响应数据采用对数函数或者通过对响应数据求平方根来转换响应数据。查看散点图是确定数据是否是线性的最佳和最简单的方法。
  • 同方差— 同方差假设也是对简单线性回归建模时要考虑的一个重要因素。为了使线性拟合有效,数据点的两侧需要具有相等的方差。如果不是这样,数据有可能是异方差的。这种异方差行为往往是由数据质量引起的。当响应变量呈现锥形分布,而不是线性增加或减少时,可以说模型中每一点的方差都不相等。
  • 多元正态— 基于这个假设,假设模型的残差具有正态分布。为了在确定模型的参数之后确定残差的分布,最好检查该分布。为了更好地理解分布,不仅要看一下分布的直观表示,还要看 Q-Q 图。我鼓励读者阅读下面的文章,以便他们熟悉 Q-Q 情节的基础知识,以及它是如何实现的。
  • 误差独立性 —除了这些情况,没有相关性假设,即残差散点图不应显示任何特定模式。特定位置的残差与其周围的残差之间不应存在相关性。在某些方面,这与恒定方差假设有关。

数据

出于解释 R 输出的目的,我将在 R 中生成随机数据用于回归分析。

随机生成的数据[图片由作者提供]

R 中的线性回归命令

在 r 中是单行执行,我们还可以查看模型的概要。

slm 总结(slm)

R 中的线性回归

让我们一行一行地解释这个输出。

  • 电话线路说明了该模型的全部内容。它用 x 来模拟 y。
  • 残差数据显示了误差的统计。误差是实际 y 数据点和拟合线值之间的差异。它还提供四分位值。
  • 系数块是提供拟合线细节的实际块。有对 x 变量以及截距的估计。一旦确定了标准误差,就可以通过将估计值除以标准误差来计算 t 值。相应的 p 值也显示在最右栏中。
  • 截距行的 p 值为 0.883,表明 t 值大于-0.147 小于 0.883。对于 x 变量,对应的 p 值几乎为 0,由 r 标记为三颗星。这意味着重要性代码为 0,这在下面的输出行中提到。因为它小于 0.05,我们可以拒绝零假设。在这种情况下,零假设表示预测 y 的 x 变量的估计值为 0,我们拒绝这一假设,因为很明显,x 在很大程度上决定 y,并且估计值与 0 显著不同。
  • 模型残差的标准误差为 0.5341,自由度= n–1–k = 1000–1–1 = 998。这里 k 是独立变量的数量,n 是观察值的总数。
  • 由于只有一个独立变量,调整后的 R 平方值与 R 平方值相似。添加多个要素将会降低校正后的 R 平方值,因为这不利于添加多个要素。
  • 最后提供 F 统计值和相应的 p 值。r 使用数据运行 f 检验,根据 p 值,我们可以决定是否应该拒绝零假设。这里的零假设说的是 x 这个单变量的回归系数为 0,备择假设说的是相反的(估计值与 0 显著不同)。在这里,p 值几乎为 0,因此,我们可以拒绝零假设,并得出结论,这个单变量模型可以很好地预测因变量。

方差分析

还可以对该数据进行方差分析,以确定来自模型和残差的方差水平。方差有两个来源:模型(SSM)和残差(SSR)。总方差(SST)是这两个方差的总和。

SSR(残差平方和)由实际值和预测值之间的平方差确定。SST(平方和)由实际输出和该变量平均值之间的平方差确定。SST 和 SSR 之间的区别是来自回归模型的 SSM。这可以通过预测值和该变量的平均值之间的平方差来计算。

这种计算可以在 excel 中完成。为了简单起见,我只进行了 5 次观察。这里,SST 和 SSM 被突出显示。SST=34.42,SSR=1.19,这基本上告诉我们,残差产生的方差很小,并且很大一部分是由模型平方和贡献的。

r 平方值是拟合优度或决定系数,基本上解释了来自自变量的可变性百分比。

r 平方= SSM/SST

在上述情况下,R 平方= 33.23/34.42 = 0.97,我们可以得出结论,97%的可变性由模型的独立参数决定。

在 R 中,当进行 1000 次观察时,我们得到以下输出。

这里,SSR=284.7,SSM=12893.4,这基本上告诉我们相同的故事,即使只考虑 5 次观察。“均方”列显示平均值的平方和。F 值与线性回归模型相同。F=12893.4/0.3。p 值同样告诉我们拒绝零假设。

结论

在本文中,我们解释了线性回归和 ANOVA 命令的 R 输出。ANOVA 通常在有分类因变量时使用,但为了从线性回归中的模型和残差中获得可变性的洞察力,ANOVA 也可以使用。

感谢阅读。

https://mdsohel-mahmood.medium.com/membership https://mdsohel-mahmood.medium.com/subscribe

用量子计算机解决最优化问题

原文:https://towardsdatascience.com/toward-solving-optimization-problems-with-a-quantum-computer-d1d2dedd2c26

实用量子机器学习

量子机器学习要不要入门?看看 动手量子机器学习用 Python

优化不仅是机器学习算法的重要组成部分。它本身也是许多工业问题的解决方案。需要从有限的事物集合中找到一个最佳对象的应用程序的例子无处不在。

量子计算在解决问题上以指数级的加速向我们招手。不过,有一个问题。不能随便把一个问题放到一个量子算法里,就万事大吉了。

为了使用量子算法,我们必须把我们的问题公式化,这样量子算法才能工作。我们必须把我们想要解决的问题编码成量子比特。

作者图片

但是,我们如何做到这一点?我们如何将一个优化问题编码成量子比特?

当然,有无数种方法可以做到这一点。一个选择是量子预言。

量子预言是一个未知量子转换门的占位符,代表你想要识别的东西。首先,您为每个可能的事物定义一个 oracle 实例。然后,您制作一个量子电路,为不同的 oracle 实例产生不同的结果。因此,您可以判断神谕是否代表了您要寻找的东西。

简单地说,甲骨文让你回答是或否的问题和多项选择的问题。

但是优化问题就不一样了。我们不去寻找正确的答案。我们不想给未知的东西贴上标签。但是我们的目标是在众多合适的解决方案中找到最好的。

这迫使我们采取不同的方法。我们必须将问题编码成量子位,这样我们才能找到解决方案,并评估它有多好。

那么,让我们来看看我们如何做到这一点。

量子位是一个量子力学系统,这意味着它根据亚原子世界的规则运行。亚原子的东西不同于传统的东西,它具有类波、类粒子的特性。这就是所谓的波粒二象性。

这并不意味着亚原子的东西,如电子,是一种波。但是,这是一种具有特定特征的粒子,在某些情况下,它的行为可以用通常用来描述波的函数来更好地解释。

那么,波是如何表现的呢?一般来说,波浪在行进时会上下移动。所以,它不是一个静态的东西。相反,它会随着时间而变化。一次,我们在特定的时间和地点看到波峰。然后,在另一个时间和地点,处于平均水平。

作者图片

所以,当你在一个点看一个波的时候,你可能会看到完全不同的东西。这正是我们在处理量子位时所经历的。当我们观察两个相似的量子位时,我们可能会在它们轨道上的不同点捕捉到它们,因此,将它们作为两个不同的值来测量。当我们看到一个量子位处于顶点时,它就是 1。当我们捕捉到第二个量子位的平均值时,它是 0。

我们看到的并不是完整的波。这是波浪的快照。这就是梅克斯·玻恩在 1926 年提出的假设:

作者图片

这是量子位状态标准化的直接结果。对于一个量子位状态,它说|α| +|β| = 1

𝛼和𝛽表示波在两个不同点的大小,它们的绝对平方指定了在该点捕捉到波的概率。这两点对应于一个量子位的计算基础——它的两个可能值,0 和 1。所有可能测量的概率必须为 1 (=100%)。

下图以图形方式对此进行了描述。𝛼和𝛽是基础国家的近邻。

作者图片

因此,使用量子位本来就是随机的。但这并不意味着它是随机的。相比之下,我们可以很好地处理量子位。我们使用量子算符将其置于特定测量比其他测量更有可能的状态。

量子算符将一种量子位状态转换成另一种。例如,让我们看看 NOT 运算符。

数学上,X 门量子算符是矩阵:

当我们将这个算符应用于不同的量子位状态时——我们将相应的变换矩阵乘以状态向量——我们可以看到它反转了|0⟩和|1⟩.的振幅

逆转|0⟩在|1⟩:的结果

逆转|1⟩在|0⟩:的结果

通常,它会反转任意状态:

此外,我们可以结合量子算符来创建任何任意状态——只要它是有效的量子位状态。我们可以创造一个量子位系统,展示我们喜欢的任何测量概率。

通常的方法是将解决方案编码成一个量子预言,稍微改变一下量子位的状态。尽管我们不知道神谕的确切例子,但我们知道它可能产生的影响。然后,我们使用量子门来放大这些微小的差异,最终得到不同的测量结果,让我们得出准确的 oracle 实例。

但是有一个大问题。神谕让我们区分解决问题的状态和没有解决问题的状态。这是一个是或否的问题。但是,在最优化中,我们寻找一整套合理解决方案中的最佳方案。

所以,我们需要遵循另一种方法。在这种方法中,我们将以不同的方式使用运算符。

在量子力学中,有一些特殊的算符。这些算符作用于量子态的方式对应于物理可观测性,例如粒子的位置、动量、自旋,以及最重要的能量。这就是所谓的对应原理。

例如,哈密顿算符就是这些算符之一。它描述了量子系统的可能能量。能量也不是布尔值。这是一个实数。因此,我们可以比较两种能量,决定哪种能量更大。

因此,当我们将我们旨在优化的目标函数公式化为哈密尔顿函数时,该系统的能量对应于解的性能。然后,优化是寻找系统的最低(或最高)能量。

https://pyqml.medium.com/membership

不要错过下一集,订阅我的子栈频道

量子机器学习要不要入门?看看 动手量子机器学习用 Python

免费获取前三章这里

用人工智能建立一个更公平的世界:本月和所有月份

原文:https://towardsdatascience.com/towards-a-fairer-world-with-ai-this-month-and-all-months-aec9d47ad176

人工智能/人工授精中的性别偏见

Unsplash 上拍摄的 ThisisEngineering RAEng

Divya Gopinath 和 Mesi Kebed 对本文有贡献。

妇女历史月是一个强有力的提醒,提醒我们记住并反思我们作为一个社会已经走了多远,也提醒我们还需要取得多少进步。作为一家专注于改善人工智能的技术公司的女性工程师,我们深刻意识到技术如何改变我们实现公平世界的进程。随着人工智能和机器学习(AI/ML)应用在现代社会中激增,算法不再是无论环境如何变化都重复执行其命令的静态函数;在某种程度上,AI/ML 模型有自己的思维和观点,它们随着时间的推移随着数据的变化而演变。出于这些原因,实现真正公平的社会需要专注于实现人工智能中的算法公平。

然而,当偏见如此普遍时,即使考虑打击偏见也是势不可挡的——Gartner 预测“到 2022 年,85%的人工智能项目将由于数据、算法或负责管理它们的团队的偏见而交付错误的结果。在这篇博客中,我们将试图通过识别算法“出错”的案例研究来揭开性别偏见的神秘面纱,并揭示如何打破 AI/ML 模型的一些不公平元素。

性别偏见无处不在——来自实地的案例研究

近年来,ML 模型已经被用来增强——在某些情况下取代——人类做出关键决策。亚马逊负责审查工作申请和提出招聘建议的人工智能模型被发现会惩罚女性候选人,因为它是根据有偏见的数据进行训练的。甚至在定向招聘广告中的角色/头衔对男性和女性来说也是截然不同的;脸书招聘秘书和幼儿教师的广告显示女性比例较高。

作者图片

不幸的是,在招聘信用卡审批执法大学招生以及许多其他方面,ML 模特表现出性别偏见的例子比比皆是。然而,如果不正确理解模型训练所依据的数据,以及它做出这些决定所依赖的特征,就可能导致对历史上代表性不足的群体的偏见永久化。不公平会以多种方式蔓延到人工智能/人工智能模型中,那么我们如何系统地解决偏见呢?

透明度是关键:为什么需要可解释性来停止偏见

回到 2019 年,许多申请苹果新信用卡的女性在推特上讨论一个奇怪的现象:她们的申请被拒绝,但她们的丈夫似乎获得了批准。尽管有混合财务,这些妇女仍然被拒绝,她们中的许多人问同样的问题:为什么与我的丈夫相比,我被拒绝?

该算法对其最终用户完全不透明,这意味着没有明显的理由来解释为什么给定的人被拒绝或批准。不仅财务状况相似的个人看起来有很大不同的结果,信用卡的发行者苹果和高盛也不能快速简单地解释算法是如何工作的,为什么它会产生不同的结果,以及这些结果是如何证明的。

可能很难克服明显的偏见。即使有一种算法有偏差的感觉,我们如何衡量这一点?而我们如何挖掘为什么有偏差的根本原因呢?如果不了解模型的决策,这些问题是不可能回答的。通过在我们的公司 TruEra 将人工智能可解释性作为一个解决方案,我们正在深入挖掘如何找到这些问题的答案。ML 模型可解释性是帮助我们回答这些关键问题的工具,因为它提供了对模型功能的最深刻的见解,这种见解阐明了对模型结果的主要影响,以及这些影响如何可能导致有偏见的结果。可解释性是对模型如何工作的分析,也可以指出为什么模型会产生有偏差的结果。

作者图片

超越性别:交叉公平的重要性

在进行公平性分析时,性别通常是一个方便使用的轴,特别是因为性别人口统计数据通常是作为一个二元变量收集的,可以根据该变量对数据进行分割。但是这个世界不是二元的,除了性别之外,还有一些属性也需要考虑。

Joy Buowamlini 和 Timnit Gebru 的著名论文揭露了商业面部识别技术如何在深色皮肤女性身上表现得比浅色皮肤男性差得多,这清楚地提醒了人们公平本质上是交叉的。根据定义,建立一个公平的世界必须包括每个人,因此我们不能只根据性别来考虑算法的公平性。必须考虑跨各种受保护特征(性别、种族、国籍、性取向等)的交叉群体。这可能听起来让人不知所措,但是分析不同数据属性之间的相互关系是可能的。例如,当您可以跨不同模型分析和比较不同的数据时,您就能够详细捕捉子组公平性的复杂性。

赋予数据科学家权力:传达不公平

模型开发人员如何传达模型对模型开发过程中的其他涉众不公平,比如验证人员或数据工程师?在 TruEra,我们经常考虑这一点,尤其是在设计可用于分享偏见分析的公平报告时:

公平性报告示例,显示混淆指标、数据集差异和公平性指标。(图片由 TruEra 提供。)

我们经常从数据科学家那里听到同样的担忧:公平对我很重要,但我如何让它对其他人也很重要?数据科学家需要获得授权,就模型的不公平性提交客观、详细的报告,这些报告是无可辩驳的证据,可以与其他非技术性的法律和业务利益相关方共享。鉴于新的法规,如欧盟人工智能法和纽约市关于公平雇佣的法律,这一点变得越来越重要,这将增加模特在内部的审查,以及增加希望了解模特如何工作以及如何证明它没有歧视的外部利益相关者的数量。即使在目前没有积极监管的国家或地区,被视为歧视的业务和声誉压力也在推动对模型公平性分析和报告的需求增加。对社会而言,这些最终都是积极的趋势,也会给企业带来更好的结果。

减轻不公平—这是可能的,尤其是通过根本原因分析

打破不公平的根源也带来了如何减轻它的清晰,而不是被难住了。根本原因分析至关重要,因为它可以精确定位可能导致偏差的数据或特征。通常,这个问题的答案——是什么导致了偏见? —不明显,因为偏见甚至可能发生在没有性别、宗教或种族等明确数据特征的模型中。根本原因分析确保团队可以快速找到通常微妙的问题,确保模型可以更快地实现更公平的结果。关于缓解的更多信息,请参见本文《走向数据科学》——“我的机器学习模型是如何变得不公平的?”

作者图片

公平是可以实现的——工具和流程已经存在

好消息是,有许多聪明的头脑在研究算法偏见的问题,从学术界到科技公司,再到希望人工智能更好地为银行、招聘、制造和无数其他用例中的客户服务的公司。对付它们的工具和技术已经存在,而且每天都在变得更加先进。在 TruEra,我们正在努力改进和提供更多工具,以满足自动化生产 ML 管道以及数据科学家报告等工具的需求,从各个方面应对这一问题。作为推动人工智能更加公平所需的人、过程和技术的更大组合的一部分,我们很自豪地尽了自己的一份力量。(那个组合长什么样?查看《走向数据科学》中的“为您的 ML 模型设计公平的工作流程”。)

随着我们朝着成为一个更公平的社会取得进展,我们所有人都必须共同努力——解决算法偏见不仅会带来一个更公平的世界,而且会带来更好的整体结果。因此,在未来,85%的模型有准确的结果,偏差是一个消失的问题。

朝向更适用的姿态估计

原文:https://towardsdatascience.com/towards-a-more-applicative-pose-estimation-bf18bc311228

为冥想者设计一个静止记分器——用 python 实现

照片由 @ericmuhrUnsplash 上拍摄。

在这篇博客中,我将讨论如何通过强调推理过程中的一个关键问题来提高姿态估计算法的效率,并讨论缓解这个问题的方法。我还演示了一个例子,在这个例子中,通过在 python 中实现姿势估计,使姿势估计更具应用性。

关键词:人体姿态估计,抖动,低通滤波器,信号。

人体姿态估计是计算机视觉中极具挑战性的问题之一,其目标是定位人体关键点(如臀部、肩膀、手腕等)。).它有无数的应用,包括 AR、基于 VR 的游戏(如微软 Kinect)、互动健身、治疗、动作捕捉等。结果的逐帧平滑对于这些应用的任何使用都是非常关键的。

https://arxiv.org/pdf/1902.09212.pdf

抖动问题

几乎所有的姿态估计算法在推理过程中都存在抖动的问题。表征噪声信号的关键点在一个点周围的高频振荡称为 抖动

图:使用 Movenet 模型的抖动问题示例。人坐着不动,但姿势估计是抖动的。作者 GIF。

抖动原因可归因于我们在整个视频输入的帧级别上执行这些推断的事实。并且这些连续的帧具有变化的遮挡(以及一系列复杂的姿态)。另一个原因可能是训练数据中注释的不一致性,这导致姿态估计的不确定性。抖动会带来以下问题:

  1. 故障和噪声数据将导致算法的不良性能。
  2. 关键点噪音太大,无法在生产环境中构建任何有用的功能和应用程序。
  3. 获得假阳性数据点的概率很高。
  4. 例如:假设您想要使用姿势估计来构建一个静止记分器(针对正在进行冥想的人);这些抖动会对分数产生很大影响。因此导致不准确和差的结果。

抖动问题的解决方案

信号处理提供了两种衰减信号中噪声的主要方法。 低通滤波器 : 衰减信号中低于指定阈值频率的所有频率并让其余信号不变通过的滤波器。

图:LPF(作者图片)

高通滤波器 : 衰减指定阈值频率以上信号中所有频率并让其余信号不变通过的滤波器。

图:HPF(作者图片)

我们的自然运动是低频信号,而抖动是高频信号。因此,为了解决抖动问题,我们可以使用一个低通滤波器来过滤所有较高频率的信号。

解决抖动问题的其他方法包括使用神经网络进行姿态细化。一个这样的例子是平滑网。然而,LPF 更容易实现和使用。LPF 的另一个变体是一欧元滤波器,它在实时过滤噪声信号方面也非常强大。

时差姿态估计

让我们从一些代码开始,让 LPF 在 python 中工作。为了在这篇博客中进行说明,我使用了 Tensorflow 的 Movenet 姿态估计模型。这个模型非常快速和准确。

现在,让我们考虑一些将用于推理的简单函数。tflite 模型可以从 这里 下载。在 tflite 上运行推理的 Python API 在 tf.lite 模块中提供。 (Ref: 使用 tflite 在 python 中加载并运行一个模型)。全部代码可以在我的 GitHub 资源库 这里 找到。

整个 Python 脚本可以在 这里 找到。使用以下命令在本地运行推理(首先,在克隆后执行" cd 运动检测"):python-m inference . movenet _ infer—路径 file.mp4—LPF n让我们来看一个使用 Movenet 模型的示例推理结果:

图 5:使用 Movenet 模型进行推断的示例。这个模型看起来既准确又快速。作者 GIF。

显然,推断看起来相当准确,延迟也很小。现在,让我们回到开头看到的抖动示例,看看如何解决抖动问题。为了演示的目的,我们使用 1€低通滤波器。我们还可以使用 Python 中一个流行的信号处理库——Scipy,它支持不同类型的低通滤波器(例如, signal.lfilte r 模块)。1€ LPF 的用法已在下面突出显示:

整个 Python 脚本可以在 这里 找到。使用以下命令在本地运行推理(使用 LPF):

python-m motion _ detection . inference . stilley _ scorer—路径 file.mp4—LPF y

图 5:显示中心抖动姿态估计的示例.LPF 解决了右边的抖动问题,估计相当平滑。作者 GIF。

应用示例

现在,让我们看一个非常简单的例子,在这个例子中,使用上面提到的概念,姿态估计可以变得稍微更适用。考虑下面的问题陈述:“根据身体静止给一个正在冥想的人打分。”

除了姿势估计之外,你能想到其他一些技术来解决这个问题吗?

普通图像处理

也许我们可以用简单的图像处理方法来解决这个问题。我们可以从减去视频流中的两个连续帧开始,然后我们可以应用二进制阈值来获得减去的掩模;这里,白色像素的数量将表示静止。

图 2:亚光掩模。使用简单的图像处理技术测量静止。如果人是静止的,白色像素的数量将小于指定的阈值。图片作者。

方法是好的,但是当背景中也有风扇或猫移动时,问题就出现了;在这种情况下,这种方法可能无效。因为移动的猫将成为减影蒙版的一部分。目标是想出一种专门适用于人类的方法。

图像(人)分割

用一些人体分割技术怎么样?我们可以使用分割来专门分割出人,然后我们取两个连续分割帧的差,并检查白色像素的数量。局限性:当分割区域内有运动时,这种方法不起作用。

姿态估计

这里,我们为所有(平滑的)关键点计算特定身体部位关键点跨连续帧的欧几里德距离。我们的最终得分是所有这些欧几里得距离的加权和。显然,如果一个人做了一些运动,关键点的欧几里德距离将会更高,反之亦然。

分数: 如果没有明显的动作,分数应该会低一些。较低的分数将意味着更好的冥想(基于身体静止,实际上有许多因素有助于良好的冥想,而不仅仅是静止)。注意,如果我们之前没有平滑姿态关键点,抖动会影响分数,导致糟糕和不准确的结果。下图显示了 y 轴上的运动分数与 x 轴上的时间。附带的代码可以在这里找到。首先,让我们看看在没有平滑的情况下乐谱是如何表现的。

图 3:不使用低通滤波器的静止记分器.该图是 y 轴上的运动分数对 x 轴上的时间。作者 GIF。

很明显,由于抖动,该图看起来有噪声。并且抖动也对分数有贡献。让我们看看分数如何使用 LPF。

图:使用低通滤波器的静止记分器。该图是 y 轴上的运动分数对 x 轴上的时间。作者 GIF。

在这里,图形这次看起来平滑干净。正如我们可以推断的那样,任何运动都对曲线下的面积有贡献。因此,平滑关键点在这样的应用中变得非常重要。

决赛成绩

我还在 android 中集成了一个低通滤波器,并在一个定制的姿势估计模型上运行它。我们得到了以下结果:

图 3:在自定义模型上使用 LPF 有平滑效果.作者 GIF。

参考

[1].曾爱玲,雷洋,宣菊,李洁峰,,徐强— SmoothNet:一个即插即用的网络,用于提炼视频中的人体姿势

[2]. MoveNet:超快速精确姿态检测模型

[3].Jaan Tollander de Balsch — 使用一个€滤波器进行噪声滤波

[4].博客中使用的 Python 脚本可以在这里找到。

我希望你喜欢使用低通滤波器来提高姿态估计的实用性。我希望这个例子足够合理,能够暗示在构建基于姿态估计的应用程序时,消除抖动是最关键的优化之一。

我很想知道任何阅读这篇文章的人的反馈。我很乐意回答对上述任何概念的疑问/问题。非常欢迎反馈。你可以通过 Linkedin 联系我。

谢谢你!

特别感谢@ Apurva Gupta 对博客的评论。

走向实用的数据网格路线图

原文:https://towardsdatascience.com/towards-a-practical-data-mesh-roadmap-90607fb967f4

通往企业数据网格的旅程可能充满挑战。但是通过使用一个实用的数据网格路线图,可以使它变得更容易和更快

苏哈什·维利在 Unsplash 上拍摄的照片

走向实用的数据网格路线图

实现企业数据网格既不简单也不直观。跨越多个维度(技术、组织和治理)的变革的深度、广度和速度使得企业的数据网格之旅既复杂又令人生畏。

然而,有了可靠的路线图,您的企业数据网格之旅可以变得更简单、更快速、成本更低。现在,不用说,每个公司的旅程都是独特的,但是在所有企业数据网格旅程中有几个共同的元素和考虑事项。

本文将阐述这些常见元素和注意事项,并提供:

  • 说明建立企业数据网格的主要工作流程的路线图,
  • 深入研究每个主要流程,以识别和排序可交付成果和结果

企业数据网格之旅

下面显示了一个让我的客户产生共鸣的企业数据网格之旅视图(图 1)。我使用“运输图”作为路线图类比,因为这可能是一种简单而直观的方式来显示关键流程和活动的宏观顺序。

图 1,企业数据网格之旅

如您所见,有几个工作流并行运行,以到达我们的企业数据网格目的地:

  • 策略流,它为我们的企业数据网格提供了更广泛的业务和技术愿景以及预期结果。
  • 技术流,它定义了我们的企业数据网格所需的技术基础和产业化活动。
  • 工厂流,它引入了可重复的流程和模板,允许快速扩展我们的企业数据网格。
  • 运营模型流,它定义了团队结构、交互和治理技术,以构建和运营企业数据网格。
  • 社交流,它不仅用于交流成功经验,还用于持续推动构建我们的企业数据网络。
  • 推广流,通过我们的企业数据网格加速数据产品的采用。

以下部分将进一步详细描述每个流。

战略流

我们的路线图从战略流开始,该战略流建立了关键的数据网格概念并创建了实施计划,同时描绘了我们的关键机会和风险。该流程通常可在 10–12 周内完成,在某些情况下,如果需要更多时间来获得管理层的支持,则时间会更长。

图 2,数据网格路线图——策略流

在这个流中创建了几个输出:

  • 数据网格简介 —“数据网格 101”宣传包——解释关键概念——数据产品、数据所有权、数据网格——这些概念构成了我们企业数据网格中实施的基本概念。
  • 架构,它描述了数据产品以及企业数据网格中的核心组件(更多详细信息请参见这里的这里的以及这里的)。
  • 路线图,它为我们的企业数据网格定义了实现计划(可能看起来像我们在本文中讨论的路线图)。
  • 结果,确定短期机会(在商业赞助下转化为 MVP 候选人)以及通过建立我们的企业数据网格预期的有形长期利益和结果。
  • 风险,识别可能阻碍我们进展的技术、运营和组织风险。高优先级风险通常在未来的概念验证中解决(稍后解释)。

这一阶段的成功结果不仅取决于创建一组可交付成果(尽管它们很重要),还取决于从不同的利益相关者那里获得认同。但是最好的方法是记住每一个策略都是在讲述一个故事。而且,就像任何好故事一样,我们的战略有一个广泛的叙事弧,它设定了舞台,确定了要克服的问题,并提供了应对我们挑战的英雄式解决方案。

然而,并不是每个人都是一个有成就的讲故事者。因此,这里有一个数据网格战略的执行摘要(简化)叙述示例,可以帮助您开始:


数据是现代企业的燃料 。它为我们的决策提供动力,帮助我们提供卓越的客户体验,并提供缩短上市时间和进入新市场所需的敏捷性和洞察力。

然而, 今天,我们的数据很难被发现、消费、分享、治理 。事实上,我们的内部研究表明,数据科学家和分析师将几乎 50%的时间花在尝试查找和获取数据上,而不是创造新的见解。因此,我们看到更慢、更不准确、更昂贵的决策和见解、失去的机会以及更差的客户体验也就不足为奇了。

我们建议使用一种 现代数据网格方法,使数据更容易查找、消费、共享和管理 来解决这个问题。过去需要我们的数据科学家和分析师花费数天时间才能完成的工作,现在将在几分钟内完成,让我们获得更好、更快、更便宜的见解,让我们快速利用稍纵即逝的机会,并帮助我们提供卓越的客户体验。

凭借我们新发现的速度和敏捷性,我们的人工智能/机器学习和分析团队中的数据科学家和分析师将能够 提供更好、更快、更便宜的见解 ,这些见解是提供进入新市场、利用新机遇和提供真正出色的客户体验所需的见解的基础。


技术流

技术流在 16-24 周内开始构建我们的技术基础。现在,这似乎是一个很短的时间,但我发现大多数数据网格技术堆栈(数据库、安全基础架构,以及某些情况下的 CDC 和事件流技术)已经在许多大型企业中可用并运行。显然,如果核心基础技术尚不可用,那么这项任务可能会延长。

技术流的目标是建立使数据易于查找、消费、共享和管理所需的基础技术能力。为了做到这一点,这种趋势为交互数据产品的生态系统创造了工业化的基础,我们称之为企业数据网。

图 3,数据网格路线图—技术流程

技术流中有两组活动:(a)技术基础组件的构建和(b)这些组件的产业化。

Foundation ”活动将设置以下一个或多个组件,这些组件对于单个数据产品以及更广泛的数据网格实现是通用的:

  • 注册表,每个数据产品中必不可少的一个组件,可以轻松地查找、发现、观察和操作数据产品
  • 联合查询平台,使消费和共享由数据产品管理的数据变得更加容易
  • API 平台,这使得通过 API 消费数据变得更加容易
  • 不可变日志,提供数据产品内活动、异常和警报的历史记录
  • 流媒体/活动平台,通过现代流媒体技术轻松共享数据产品中的数据

一旦构建了基础功能,我们的重点就转移到将数据网格组件集成到企业运营环境中的“工业化”活动。

在工业化阶段,通常会涉及几项功能:

  • 安全性,确保所有基础组件符合企业的安全状态;应解决的一组最低安全考虑事项包括数据加密(静态和动态)、使用身份管理的身份验证和授权、基于角色的访问控制、用于 API 访问的 OAUTH2 以及安全运行时环境;受监管行业的公司可能会选择更高等级的安全性,因为他们也会考虑更广泛的“零信任”技术。
  • 可操作性,使所有数据网格组件和数据产品都与企业的运营环境相集成;至少考虑日志收集和警报捕获,并转发到安全和操作控制台。
  • 可观察性,提供理解数据产品和数据网格组件的使用和内部操作所需的可见性,从而实现问题诊断和使用模式分析。
  • 支持,建立集成到企业技术支持环境中所需的流程(和支持自动化)。

工厂的溪流

与技术流并行,我们的工厂流从一系列概念证明(POC)开始,这些概念证明解决了在策略流中发现的任何风险。这些概念验证不仅提供了技术信息,还提供了工作流的运营模式。事实上,我发现执行 POC 来测试重要的运营模式概念非常有用,例如,包括“数据产品所有者”角色的试运行。POC 活动通常有 8 到 10 周的时间限制,这可以确保我们尽快过渡到通过 MVP 活动交付业务价值。

图 4,数据网格路线图—工厂流程

认识到数据网格在大多数企业中是一个相对较新的事物,公平地说,可能应该考虑一种“测试学习”的方法。因此,我们的第一步是创建几个“概念证明”(POC)。POC 的目的是明确地解决/减轻在我们的初始策略流中识别的风险,而不是为了投入生产。典型的 POC 可能会尝试对企业来说是新的工具,或者在试验的基础上执行新的角色或运营模式原则。根据我的经验,在活动的这个阶段,完成 3-5 个 POC(基本上可以并行执行)是很常见的。

接下来,我们使用技术流中构建的一些基础设施(通过我们的一个概念验证)来交付几个“最低可行产品”,即 MVP。为了清楚起见,MVP 执行端到端的交付流程,最终实现生产部署,这与很少投入生产的 POC 不同。理想的 MVP 将数据产品交付到生产中,并具有以下几个特征:

  • 是相应的,并提供可识别的商业利益。
  • 的风险和规模适中,从而增加了成功交割的概率。
  • 在商业、数据和技术领域拥有广泛的赞助商,他们可以克服任何重要交付项目中出现的不可避免的障碍。
  • 提供可应用于技术、数据和业务领域的重要知识

MVP 活动被确定为我们策略中的候选数据产品。每个 MVP 应选择在 5-7 周内交付,几个并行运行。由于每个 MVP 数据产品都经历了数据产品生命周期的每个阶段——从创建到交付到生产——每个 MVP 都应被视为学习和改进我们交付流程的机会。MVP 活动通常在 12–14 周内执行。

接下来,根据我们从几个 MVP 数据产品交付到生产中获得的经验,我们具备了建立工厂所需的洞察力,以及大规模交付数据产品所需的可重复流程。这一步很大程度上依赖于组织的 DevSecOps 能力,并在技术流的产业化步骤中应用于数据网格。如果这种能力成熟,那么建立一个工厂可以在 12–14 周内完成(显然,否则可能需要更长时间)。

一旦我们交付了几个 MVP,我们应该理解交付和操作一个数据产品需要什么。我们利用这些知识创建了一个“数据产品工厂”,可以大规模地构建数据产品。数据产品工厂建立:

  • 可重复的流程和模板,使构建数据产品变得容易。
  • DevSecOps 工具和管道,使数据产品的部署和管理变得更加容易。
  • 安全环境,使用“千篇一律”的流程构建,可以轻松构建安全的数据产品。

操作模型流

接下来,我们有操作模型流。在这个流程中,我们试图确定团队的类型,简化他们的交互,建立决策权,并定义高效和有效地交付数据产品所需的激励。

图 5,数据网格路线图——运营模式流

这一阶段的第一步是“领域分析”,确定我们将用来创建初始数据集的领域。有几个“提示”可以帮助识别重要的领域。例如,许多大公司的业务架构描述了对企业重要的领域和功能。在其他情况下,我看到企业使用行业特定的业务架构模型(金融服务的 BIAN,保险的 ACORD 等。)确定适合企业使用的关键行业功能。在这两种情况下,这些为确认您的企业数据环境提供了一个起点。最初的领域分析活动需要大约 8 周的时间。关于如何执行领域分析和识别候选数据产品的更多细节可以在我几个月前写的“剖析数据产品”一文中找到。

一旦定义了领域模型,更有趣的练习是识别您的第一个领域,或者更具体地说,您的第一个领域的数据产品。领域模型再次提供了一些提示,但是理想的数据产品应该是有实际的和公认的好处的。因此,有了域,我们现在可以匹配一个确定的数据集、一个定义的所有者和一个有形的利益。事实上,这很可能是我们第一批 MVP 的理想候选人!

该流程中的下一组活动是定义实际的数据产品操作模型。但是,究竟什么是运营模式呢?不同的人有不同的定义,但我的简单观点是,它定义了“谁做什么,和谁一起做?”。定义您的运营模式取决于您所在组织的动态和文化,但目标应该是在大约 14-18 周内完成。有关设计您的数据产品团队的更多信息,请参见我最近的“数据产品团队的拓扑结构”一文,有关定义您的数据产品运营模型的更多信息,请参见最近的另一篇“数据产品的运营模型”一文。

因此,在这个流中的操作模型任务中,我们定义:

  • 数据产品所有者,负责创建数据产品,并与数据生产者和消费者以及安全和运营人员合作,以确保数据产品的安全性、高性能和可操作性。
  • 为数据产品提供服务的使能团队,或者从数据产品接收服务的团队。
  • 所有权原则,概述了数据产品所有者的职责,以及管理与企业中其他团队的交互的原则。
  • 关键交互,确定管理数据产品和授权团队之间交互的方法、频率和过程;这些信息用于突出应该优化和区分优先级的重要或高频交互。

现在,有了运营模型,重点转向了数据网格治理——大致定义为“确保我们的数据产品以正确的方式做正确的事情”。不幸的是,大多数企业都有一个有些繁琐且过于手动的数据治理流程——数据网格和数据产品提供了一种新的方法和机会,可以将手动、受会议限制的官僚验证流程转变为自动化的“认证”流程。

这组活动建立了自动化和流程,支持数据产品的快速自动管理流程。大部分自动化来自于在我们的数据产品工厂中应用屡试不爽的可重复 DevSecOps 流程(如前所述),同时利用嵌入到每个数据产品中的内置可观察性、发现和使用/警报/日志操作信息(有关更多详细信息,请参见本文文章)。这种能力还让我们有机会将数据产品治理从手动、受会议约束的官僚流程转变为自动化、仅限例外的“认证”流程。

这项任务应该计划花费大约 12-14 周。但是,请注意,这项任务会影响组织的人员和流程,并且需要大量的管理层支持(您应该相应地进行规划)。

社会化潮流

接下来,我们有社会化流。毫无疑问,我能说的最重要的一点是,它经常被忽视。但是为什么呢?嗯,可能是因为我们倾向于解决那些我们可以立即控制和改变的事情。由于许多数据网格计划始于技术,我们倾向于关注核心技术考虑。

图 6,数据网格路线图——社会化流程

现在,可以公平地说,成功的数据网格项目是那些平等地处理其他流,并着重强调社会化的项目。就我们的目的而言,我认为社交是使用任何可用的交流工具——文章、博客、播客、演示文稿、“办公时间”会议、“午餐和学习”会议——来:

  • 让利益相关者参与进来,让他们不仅了解现状(所需的绝对最少沟通),而且能够消除障碍,找到并批准资金,并向管理层传达利益。
  • 找到并签约赞助商,因为他们听说了数据网格的好处,并内化了它如何为他们的团队或地区带来价值。
  • 建立势头,因为每个沟通机会都变成了在整个企业中广泛“销售”的机会。

有趣的是,社交流有很多用途。早期社会化在组织中围绕数据网格建立意识,并通过执行演示、会议和项目进展交流来完成。但是,随着我们的数据网格之旅的继续,我们可以开始向更广泛的内部受众传播数据网格机会,并在整个组织内建立势头。最后,随着数据产品的构建和成功的实现,我看到组织使用公共/外部通信的增加,这主要是因为企业在数据网格方面的经验被视为在热门技术市场上招聘人才的有利工具。

展示流

最后,我们有展示流。一旦基本技术、工厂能力得到充分实施和稳定,允许数据产品的交付规模扩大,这一流程就开始了。这个流程的全部重点是交付数据产品,以便实现业务成果和价值。这个流没有特定的端点,而是随着新数据产品的识别和构建而不断执行。

图 7,数据网格路线图——首次展示流

企业数据网格路线图

现在,让我们将所有这些整合到一个可执行的路线图中。每个流程都有一套可交付成果和/或结果,并以合理的方式排序。在前面的章节中,每一个里程碑/可交付成果都被粗略地映射到每一个流程/阶段,再加上前面的章节,将一个广泛的企业数据网格计划放在一起应该是一个(希望)容易管理的任务。

图 8,企业数据网格路线图

不言而喻,但是每个企业都是不同的,都有一些独特的需求(虽然也有材料上的共性),您需要考虑您企业的情况来创建自己的数据网格路线图。正如他们所说,你的里程可能会有所不同(但希望不会太多)。

总结想法

您可能知道,要让您的企业数据网格之旅顺利进行,需要处理许多任务和优先级。虽然我不能保证您的旅程没有挑战或问题,但我希望这篇文章为您提供了所需的洞察力,让您的企业的数据网格之旅变得更简单、更快、成本更低。


本文假设您对数据网格有很高的理解。如果您需要一些关于数据产品的背景信息,有许多文章可供参考:此处(数据产品)、此处(数据网格模式)、此处(数据网格架构)、此处(数据网格原则)和此处(经验教训)。对于感兴趣的读者,全套数据网格模式可在此处获得。


除非另有说明,本文中的所有图片均由 Eric Broda(本文作者)创作。图像中使用的所有图标都是普通的 PowerPoint 图标和/或不受版权保护。

本文表达的观点仅代表我个人,不一定代表我的客户的观点。

走向自动生成的模型

原文:https://towardsdatascience.com/towards-auto-generated-models-289497c14909

神经结构研究简史及其他

Unsplash 上的 Didssph 拍摄的照片

一篇有趣的论文于 2016 年在 arXiv 上悄然发布,作者是一群来自谷歌大脑的研究科学家,他们利用机器学习(ML)创建了新的 ML 模型。没有人预料到,它会引发关于 ML 研究的所有可能的争议,并在未来三年内将谷歌置于尴尬境地。然后,谷歌的一位图灵奖获得者又花了三年时间来全面分析这个问题,并做出正式回应。

作为一个博士,完成了这个课题的学位论文,我将用这篇文章带你走过这个领域发生的所有有趣的想法和戏剧。

突破:最初的论文

强化学习可以教会智能代理执行许多任务,如下棋或街机游戏。几乎任何东西,只要有一个清晰的反馈回路来评估代理人的表现,都可以被代理人学会。设计 ML 模型怎么样?我们可以很容易地评估一个机器学习模型。这就是这篇论文的想法。

论文题目为“带强化学习的神经架构搜索”,发表于 2016 年。它不是手动设计一种新型的神经网络架构,如 AlexNet、ResNet 或 DenseNet,而是使用强化学习来自动生成新的神经架构。如下图所示,一个代理,也是一个神经网络,被训练产生神经结构。每个神经架构都经过训练和评估。评估结果是对代理人的奖励函数。通过产生新的体系结构并学习每一个体系结构的性能,智能体逐渐学会如何产生好的神经体系结构。

作者图片

在该论文中,一种新型的神经网络 NasNet 是通过强化学习自动生成的,并且在图像分类任务上优于当时大多数其余的神经架构。

该论文还在 ML 中开辟了一个全新的研究领域,称为神经结构搜索(NAS),即使用自动化方法产生新型的神经结构。

这篇论文改变了游戏规则。表面上,这只是创造更好的神经结构的又一次尝试。然而,它试图使 ML 研究者的工作自动化。许多人担心他们的工作会被曼梯·里抢走。军情六处的研究人员不知道。相反,他们一直在努力用 ML 取代自己。如果这个想法可以实现,他们将开始生产 ML 研究人员无法企及的 ML 模型。

如此伟大的尝试是有代价的。由于训练和评估大量的神经架构,Google Brain 需要 800 个 GPU 来运行实验。如此高的费用让这个领域的大多数玩家望而生畏。没有任何其他团体立即发表关于这个主题的论文。

谷歌大脑通过将这种自动化设计思想扩展到 ML 过程的其他部分来延续这一研究路线,例如搜索激活功能搜索数据扩充

突破:降低成本

为了降低 NAS 消耗的计算资源,他们在最初论文发表一年后发表了一篇新论文。这篇新论文的标题是“通过参数共享的高效神经架构搜索”(ENAS)。它将 NAS 的成本降低到接近训练单个神经网络的成本。他们是怎么做到的?

由代理生成的神经架构彼此之间可能没有太大的不同。在之前的工作中,他们必须端到端地训练每一个神经架构,即使它们彼此非常相似。我们是否可以重新使用先前训练的神经架构中的权重来加速稍后生成的神经架构的训练?这就是本文的观点。

他们仍然使用代理来生成新的神经架构。通过改变它们训练每个神经架构的方式来提高效率。每个神经架构都是使用来自先前训练的神经架构的权重热启动的。通过这种改进,训练由代理生成的所有神经架构的总成本几乎等于训练大型神经架构的成本。

突破:神经架构是可区分的

在上述论文发表后不久,其他一些研究小组也开始加入这场游戏。他们的目标也是让 NAS 更高效,但是是从不同的角度。他们没有改进培训和评估,而是改进了代理人。

从离散数学中,我们知道图是离散的结构。神经架构是计算图形,所以是离散的。由于它们的离散性,代理可能不容易察觉不同神经架构和它们的性能之间的相关性。如果我们能让神经结构变得可区分呢?然后,我们不再需要一个代理来生成神经架构。我们可以直接使用梯度下降来优化神经架构,就像我们如何训练神经网络一样。

这听起来像是一个疯狂的想法,但“飞镖:可区分架构搜索”和“神经架构优化”的作者找到了方法来实现它们。这里我们就不细说了,但是欢迎你自己看报纸。

其他尝试

随着越来越多的研究人员致力于这一主题,在最初的 NAS 问题上取得突破变得越来越困难。他们开始基于这些可区分的解决方案进行改进,或者给问题添加约束。在这些论文中,有一些高质量的值得一读,包括 SNASProxylessNASMnasNet

争议:NAS 没有意义

当我们都认为这个话题已经到了它的顶峰,在这个领域不会发生什么大的事情时,一场巨大的争论出现了,摧毁了整个研究领域。

想象一下这种情况。如果我只允许代理生成与 ResNet 非常相似的神经架构,那么生成的神经架构肯定会执行得与 ResNet 相似。在这种情况下,我们能说智能体足够聪明来找到好的神经架构吗?不管代理人有多笨,只要研究人员足够聪明,能够将搜索空间限制在对好的神经架构的少量掌握中,结果就会很好。《国家科学院院刊》论文的作者使用了这种技巧吗?发表了一篇论文来验证这一点。

这篇论文的标题是“神经结构搜索的随机搜索和再现性”。他们用随机搜索算法取代了强化学习或 NAS 论文中使用的任何搜索算法。

结果令人震惊。随机搜索和其他搜索算法一样好,有时甚至更好。这个结论使 NAS 的整个研究领域无效。

如果论文中的结论是正确的,那么 NAS 只是人工设计神经架构的一种更奇特的方式。在 ML 模型设计中,它永远不能自给自足,因为如果没有经验丰富的 ML 研究者精心设计的搜索空间,它永远无法找到好的神经架构。

突破:从零开始发现模型

当我们都认为 NAS 研究已经结束时,它以另一篇改变游戏规则的论文“ AutoML-Zero:从零开始进化机器学习算法”引人注目地卷土重来,这篇论文为 ML 是否可以生成新的 ML 模型提供了新的线索。

与以前的 NAS 论文不同,神经架构不再局限于人类精心设计的搜索空间。它甚至不搜索神经结构。它从头开始构建 ML 模型。

它使用进化算法来组合基本的数学运算,如加法、乘法或均匀采样。使用这些组合作为 ML 模型,并评估它们在数据集上的性能以选择好的模型。通过这种设置,几乎所有的 ML 模型都包含在搜索空间中。

结果是惊人的。该算法产生了许多广泛使用的 ML 模型。例如,它重新发现了线性回归、随机梯度下降、ReLU 和 2 层神经网络。搜索过程就像重放 ML 的研究历史。

虽然论文没有提出更好的 ML 模型,但它证明了自动生成 ML 模型的概念。至少在基本水平上,ML 生成可用的 ML 模型是可能的。

争议:NAS 与环境

在之前的争议之后不久,一场更大的关于 NAS 的危机出现了,这场危机始于一篇名为“NLP中深度学习的能源和政策考虑”的论文。它被麻省理工科技评论重点报道,并吸引了很多关注。

该工作调查了进行深度学习研究,特别是为自然语言处理(NLP)训练大型深度学习模型的能耗和碳排放。文中提到的最大模型是基于 NAS 的变压器模型,它包含 2 亿个参数。训练这样一个模型所排放的二氧化碳相当于 300 名乘客从旧金山到纽约的往返旅程。

深度学习与环境。这是近年来深度学习以疯狂的速度前进时需要回答的一个基本问题。突然,出现了许多批评。谷歌被批评通过训练大型深度学习模型来损害环境。谷歌会成功解决这场公关危机吗?最重要的是,谷歌会承担起解决深度学习生态友好问题的责任吗?

作为回应,谷歌承诺其顶尖人才来解决这个问题。图灵奖获得者大卫·帕特森(David Patterson)带领一群天才研究科学家对这个问题进行了近三年的全面调查。最后,他们在 2022 年提出了一个有信心的回应。

论文的题目是“机器学习训练的碳足迹将趋于平稳,然后收缩”。他们提出了 4 种最佳实践,以减少训练深度学习模型的碳足迹和能耗。通过采用这些最佳实践,谷歌大幅减少了其深度学习相关活动的碳排放。2021 年减少的二氧化碳量相当于 2017 年训练一个变压器模型 700 次的二氧化碳排放量。

神经结构搜索不是自动的

在我们得出结论之前,我想解释一下 NAS 和 AutoML 之间的混淆,因为这两个术语经常一起出现。AutoML 甚至以“AutoML-Zero”的名义出现。然而,大多数 NAS 研究不是自动的。

人们称 NAS 为 AutoML,因为 NAS 是一种创建新 ML 模型的自动化方法。NAS 产生了新的 ML 模型,这些模型可以很好地推广到其他数据集和任务。然而,从从业者的角度来看,除了性能更好之外,它们与 ResNet 并没有太大的不同。如果他们想在实践中使用该模型,他们仍然必须进行数据预处理、后处理、超参数调整等等。

AutoML 不是关于生产新的 ML 模型,而是关于 ML 解决方案的易于采用。给定一个数据集和一个任务,AutoML 试图自动组装一个合适的端到端 ML 解决方案,包括数据预处理、后处理、超参数调优等等。从从业者的角度来看,采用 ML 来解决他们的问题极大地减少了知识需求和工程工作量。

结论

到目前为止,我们已经回顾了自动生成的 ML 模型的历史。现在我们需要回答这个问题:我们能依赖自动生成的 ML 模型吗?

从上面的讨论中,随着这个领域的发展,解决方案变得越来越好。尤其是 AutoML-Zero 出来的时候,我感觉已经走上正轨了。然而,仅仅为了找到一个简单的 2 层神经网络,它就已经耗尽了今天的计算能力。我无法想象需要多少计算资源才能生产出比当今最先进的模型更好的模型。此外,财务收益不像 GPT-3 或稳定扩散等其他 ML 研究那样明确。大公司不太可能为此投入大量资源。因此,我的回答是:短期内不可能实现。

更大的影响

除了上面的结论,这些努力对一般的 ML 研究有一些不可忽视的更大的影响。我们上面讨论的论文太暴力了。它们与典型的 ML 研究大相径庭。

这里的确切区别是什么?我们曾经用漂亮的数学方程和严格证明的定理建立 ML 模型。然而,NAS 算法根本不懂数学。他们将 ML 模型视为黑盒,仅通过实验对其进行评估。

ML 研究的方法论开始看起来像实验科学。就像实验物理学一样,我们基于实验发现新的发现。那么,我们应该像数学或实验科学一样进行 ML 研究吗?ML 模型背后的数学有必要吗?NAS 提出了这些问题让我们所有人来回答,这些问题将对未来的 ML 研究产生深远的影响。

在我看来,在没有强大数学支撑的情况下创建 ML 模型在未来可能是不可避免的。数学是人类建造的完美世界,每个结论都是通过严格的推导发现的。然而,随着数学世界的发展,它逐渐变得和现实世界一样复杂。最终,我们将不得不依靠实验方法来发现数学中的新发现,就像我们今天对现实世界所做的那样。

走向数据科学播客结局:人工智能的未来,以及随之而来的风险

原文:https://towardsdatascience.com/towards-data-science-podcast-finale-the-future-of-ai-and-the-risks-that-come-with-it-db4d29e77174

播客

杰里米·哈里斯谈建造人类级人工智能的高风险

苹果 | 谷歌 | SPOTIFY | 其他

编者按:TDS 播客由 Jeremie Harris 主持,他是 AI 安全初创公司Gladstone的联合创始人。每周,Jeremie 都会与该领域前沿的研究人员和商业领袖聊天,以解开围绕数据科学、机器学习和人工智能的最紧迫问题。

两年前,我告诉数据科学社区,我们将把这个播客引向一个不同的方向。在那之前,我们的客人和我们的谈话一直专注于机器学习和数据可视化的行业应用、数据科学职业发展战略和其他相关主题。这是有道理的:当时我正在经营一家名为sharpes minds的公司,该公司为数据科学家和机器学习工程师提供指导计划。我和我的兄弟艾德共同创立了 SharpestMinds,他在 T21 之前就已经上了播客。SharpestMinds 是我们一起建立的第三家公司,但重要的是,它是第一家真正运作的公司。我们很幸运,我们周围有一个很棒的团队,该公司成为了世界上最大的基于收入共享协议的数据科学和机器学习导师计划。

但是 2020 年初,一切都变了。那时 OpenAI 向世界宣布他们已经创造了 GPT 3 号,更重要的是,这一刻我们意识到 OpenAI 用来建造 GPT 3 号的配方很可能会被扩展得非常非常远——可能会一直扩展到建造通用人工智能,可能会在广泛的任务中满足我们超越人类的智能。

与此同时,艾德和我意识到了人工智能联盟社区的担忧,他们多年来一直认为这些广泛智能的人工智能系统最终可能变得不可控制,并带来灾难性的风险。尽管这些说法起初看起来很疯狂,但我们多年来越深入研究,就越难否认它们实际上是相当合理的。当我们开始与人工智能风险怀疑论者交谈时,我们非常失望,对他们的论点没有什么印象。

因此,一方面担心高级人工智能的潜在灾难性风险,另一方面又担心建立精确的这种系统的前景,我们觉得除了人工智能安全之外,我们没有理由做任何事情。所以我们做了一个艰难的决定,把 SharpestMinds 留给我们最早的两个员工,投入到人工智能安全的世界中,不知道从哪里开始。

大约在那个时候,我联系了《走向数据科学》的编辑团队,告诉他们我们的决定。他们提出了一个想法:也许我们可以使用 TDS 播客作为一个平台来探索人工智能的安全,并与更广泛的世界分享其中的一些想法,因为我们继续我们的人工智能校准之旅。

我喜欢这个概念。这就是为什么两年前,我们把播客推向了新的方向。从那以后,幕后发生了很多事情。例如,我和艾德与我们的一个好朋友共同创办了一家人工智能安全公司,他也一直在密切关注人工智能安全的故事,并且是美国国防界的一位高级领导人。我们将很快宣布一些令人兴奋的事情,我可以真诚地说,我从来没有想到我们能够这么快就在人工智能安全方面产生影响。

但是,让我们来到这里的担忧也变得更加突出。GPT-3 确实引发了人工智能能力的革命,该领域似乎正在形成这样的观点,即人工智能规模可能会让我们在很大程度上达到人类水平或超人的人工智能。与此同时,我们已经开始看到的经验证据,这表明我们应该预料到开发这种系统默认会带来灾难性的后果。

随着我们对这个领域的深入研究,我的时间越来越多地被消耗在跟上人工智能和人工智能安全的艺术状态上,这让我没有太多时间来探索播客上的其他主题。这很有挑战性,因为我知道我们的许多听众 TDS 社区——仍然希望听到其他事情。比如数据可视化、管道开发和数据科学工具。

因此,与人工智能的最新发展水平一样重要,与人工智能的安全性一样重要,我认为我必须要做的那些主题的更深层次的探索确实属于一个稍微不同的领域。因此,这将是 TDS 播客的最后一集,至少现在是这样。我将继续在新的 Gladstone AI 播客中探索这些主题,你可以在节目笔记中找到链接,我们将继续在 TDS 博客上发布这些剧集,但作为一个更适合探索这些具体想法的独立项目。如果你愿意跟我去那里,我很荣幸你能和我一起走完剩下的旅程。

在这最后一集,我将提供我对过去两年人工智能进展的看法,以及我认为这对从人工智能安全到人类未来的一切意味着什么。

你可以在下面一集找到我讨论的链接。

章节:

  • 0:00 介绍
  • 6:00 惨痛的教训
  • 10:00 介绍 GPT 3 号
  • 16:45 AI 灾难性风险(回形针示例)
  • 23:00 悬赏黑客
  • 27:30 接近智能
  • 32 点总结

面向关系数据库的深度学习

原文:https://towardsdatascience.com/towards-deep-learning-for-relational-databases-de9adce5bb00

走向深度关系学习

推广深度学习架构,实现与关系数据库原理和实践的自然整合。

借助PyNeuraLogic框架,你可以编写直接在关系数据库上运行的深度学习模型。(图片改编自 PixabayPyNeuraLogic )

我们现在非常习惯于阅读关于深度学习的内容,从视觉和图像生成到游戏玩等研究领域的各种突破成为头条新闻。然而,大多数深度学习方法距离日常商业实践仍然相当遥远。许多公司成功转型到数据驱动时代,收集大量有价值的数据作为其流程的一部分。虽然大多数这样的公司确实使用各种数据分析工具来从这些数据中提取洞察力,但我们很少看到实际的 深度学习 方法的参与,除非它们直接匹配业务领域(例如,图像数据处理公司)。

在这篇文章中,我们认为商业实践中缺乏神经网络的核心原因之一是几乎所有深度学习模型所假设的学习表示与日常实践中最常见的数据存储表示之间的差距——

为了缩小这一差距,我们引入了一种原则性的方法,即通过与每个关系数据库引擎底层的形式原则相集成,将最先进的深度学习模型推广到数据库上的直接应用。然后,我们用 Python 框架中的实用教程来实例化这种方法,该框架旨在轻松实现现有的和新的深度关系模型,以便直接使用数据库进行学习。**

学习表征

虽然在数百个框架和库中有无数现成的统计和机器学习模型,但它们的一个方面仍然基本通用——学习数据表示法。无论你是否擅长基本的逻辑回归,想要升级到树集成,或者创建高级深度学习模型,无论你是否选择用 SPSS 支付专有解决方案,或者用 Tensorflow 从头开始编程,你总是期望以数字张量的形式提供数据,即 n 维数字数组。**

摄取张量数据样本的典型(卷积)神经模型草图。(图片由作者提供)

这归结为传统的特征向量的学习表示,形成了这些张量的一维情况。历史上,无论学习领域如何,所有经典的机器学习模型都是为特征向量输入而设计的。在这里,作为一名领域专家,您需要在范围内设计问题的典型特征,将许多这些特征组合成一个向量,并对这些特征向量进行重复测量,以创建一个足够大的训练数据集。至少在深度学习革命带来其表示学习范式之前是如此,这在很大程度上消除了对这些输入特征的手动设计的需要,并代之以大量的原始数据。**

  • 这里的想法是,典型特征作为训练过程本身的一部分出现,通常称为嵌入,即嵌入到共享 n 维空间中的对象的数字矢量表示。**

然而,在庆祝从特征制作到神经架构制作的这一进步时,人们可能会注意到学习表示实际上仍然完全相同— 数字向量/张量

这不是一个巧合,因为使用这种学习表现形式背后有可以理解的原因——一部分是历史的,一部分是数学的,一部分是实用的(正如我们之前的文章中所解释的)。然而,这种表示远没有机器学习实践者看起来那么普遍。只需环顾四周,看看真实世界的数据是什么样的。它不是存储在数字向量或张量中,而是存储在互联网页面、社交网络、知识图表、生物、化学和工程数据库等的互连结构中。这些是固有的关系型数据,它们自然地以图表、超图以及最常见的关系型数据库的结构化形式存储。**

现实世界中很大一部分数据存储在关系数据库中。(图片来自 pixabay )

现在,一个显而易见的问题来了——难道我们不能将这些数据结构转化为我们的特征向量(数字张量),并直接利用我们已经开发的所有好的机器学习(深度学习)吗?虽然这很有诱惑力,但这种方法存在深层的问题:

1) 显然,没有办法在不丢失信息的情况下,将一个未绑定的关系数据结构转换成普通的固定大小的数值张量。

  • 顺便说一下,张量也是关系数据结构的一个例子(它是一个网格)。如果示例张量比预期的模型输入大,我们就有大问题了。**

2) 即使我们将自己限制在有界表示中,这种转换的模糊性也存在原则性问题,这源于关系结构的固有对称性。****

  • 为了简单起见,这里只假设图形数据结构。如果在图和张量之间有一个明确的内射映射,这将很容易解决(硬)图同构问题。

即使你只是不关心信息的丢失和歧义,这两者都会导致严重的学习效率低下,并决定将结构转化为向量,你还是会回到特征加工。

  • 实际上有许多方法可以做到这一点,例如聚合(计算)出对象、关系、各种模式(子图)及其统计数据,通常称为“命题化”(关系特征提取),也可以是自动化

第二个虽然在实践中有用,但这种关系特征加工可以说是不酷的,因为它与深度(表征)学习的核心思想不相容。那么,我们能否以某种方式解决这个问题,以一种有原则的方式将深度学习应用于关系结构?这将不受欢迎地需要超越常见深度学习补救措施的解决方案(例如将更大的数据扔进更大的转换器……)。

关系表示

这些关系表示是什么,我们为什么需要它们?先说学习数据流行的特征向量表示法。这样的数据也可以认为是一个 ,其中每一列对应一个特征(或目标标签),每一行对应一个单独的独立学习示例——一个特征向量。因此,我们可以很容易地用一个表将特征向量存储在任何数据库中。现在假设特征向量不再如此独立,并且一个特征向量中的一个元素实际上可以表示与另一个特征向量中的另一个元素相同的对象。这在实践中非常常见,人们使用这样的向量来表示时间序列数据中的重叠序列、句子中的单词、购物车中的物品或棋盘上的图形。在所有这些情况下,这些向量中的元素不再被认为是简单的独立值,而是 引用 到底层的对象,然后这些对象携带实际的特征。因此,从概念上讲,我们现在有两个表,其中第一个表包含对第二个表的对象引用(可能是重复的),第二个表包含(唯一的)对象的特征值。****

  • 在正式的数据库术语中,表也被称为 关系 ,因为它将列中的对象联系在一起。

一换句话说,这样的向量也可以被认为是物体的序列。然后,这允许我们考虑一般化为可变长度的向量,这可以利用序列模型,如递归神经网络。此外,这样的序列可以开始分支,导致数据表示,例如句子分析树数据,以及模型,例如递归神经网络。最后,我们可以推广到一般的图形结构数据,表示从分子到社会网络的任何东西,这是现代图形神经网络运行的表示。****

  • 这也是流行的转换器有效运行的表现形式——这些转换器虽然在技术上接受输入序列,但通过假设(自)注意模块内的所有成对元素关系,在内部将它们转化为完全连通的图。

所有这些模型都属于关系(数据库)形式主义吗?它们当然会——这些都是二元关系处理的例子。这意味着,为了在数据库中存储一个图(序列、树),创建一个单个表就足够了,该表具有与通过连接的两个节点相对应的 和两个 列。每个图就是这些边的集合,每个边存储在一个单独的行中。对于不同标记的图,相关属性可以像以前一样有效地存储在单独引用的表中。****

与标准 GNN 框架中使用的通用矩阵格式相比,以关系(数据库)格式存储类型化、属性化(分子)图具有更大的灵活性和更少的冗余。这也可以用来使 GNNs 模型更有效。(图片由作者提供)

请注意,这说明了由关系表示引入的另一个重要概括,即单行不再对应于单个学习实例,因为我们通常可以有不同大小和结构的示例,通过对象引用跨越多个表。最后,数据库不局限于二元关系,因为一个数据库表可以很容易地关联两个以上的对象(即,每个表是一个超图)。

这清楚地表明,我们可以很容易地在关系数据库中捕获所有常用的学习表示(但反之则不然)。这使得潜在的关系逻辑(代数)形式主义成为理想学习表示的非常有力的候选者!

  • 请注意,实践中使用的所有结构化数据存储和操作语言,如 SQL 和 ERM,都是从关系代数和逻辑发展而来的。

然而,虽然这些是数据操作和商业实践的标准形式,但不幸的是,它们似乎与机器学习中可用的表示相去甚远。然而,这只适用于普通的机器学习…

关系机器学习

几十年来,远离深度学习主流的聚光灯,研究人员实际上已经在一个被称为 关系学习 的利基子领域内开发了直接基于前述关系逻辑形式主义的的学习方法,在之前的文章中有所概述。简而言之,关系学习方法,如归纳逻辑编程 (ILP),为学习高度表达、高效和可解释的模型提供了一种非常优雅的方式。这种方法真实地展示了关系逻辑形式的一般性,它在这里不仅用于捕获数据和学习表示,还用于模型本身,同时提供了一种有效的方式来合并背景知识*和领域对称性。*****

所得到的模型自然允许从数据库中学习,其中不同的样本由不同类型和数量的对象组成,每个对象由不同的属性集表征,跨越多个相互链接的表。虽然这对于任何经典的机器学习算法来说都是一个噩梦般的场景,但它却是 ILP 的标准。

然而,除了这些有利的特征之外,这些方法还严重缺乏鲁棒性、准确性和可伸缩性——这些方面是深度学习最近主导整个领域的方面。

深度关系学习

自然,关系型和深度学习范式的互补优势要求它们的集成,我们称之为"深度关系型学习",我们在上一篇文章中详细介绍了其一般原则,随后是一个名为 PyNeuraLogic 的实用框架,在的后续文章中进行了描述。

简而言之,关键的本质是采用提升的建模范式,从 统计关系学习 中的关系图形模型中得知,并将其外推至深度学习设置。换句话说,这意味着引入一种新的、声明性的、基于关系逻辑的“模板化”语言,这种语言是可微分的,从而允许对深度学习模型进行编码,同时保持关系逻辑表示和推理的表达能力。**

由于这听起来非常抽象,让我们来看看一些熟悉的东西— 图形神经网络 s (GNNs),它可以被视为深度关系学习模型的一个简单示例。

  • gnn 是当前深度学习中最热门的话题之一,是药物发现、蛋白质折叠和一般科学中许多最新突破的基础。此外,变压器实际上也是一种类型的 GNNs

典型 GNN 的计算图,其中节点传播并聚合其邻居的表示,在表示甲烷分子的输入图上展开(灰色,左侧)。这些颜色表示每层内的权重分配(“卷积”)。单个卷积运算节点(粉色)之后是汇集运算(蓝色),这些运算构成了对输入图(浅棕色)的下一层表示(C)的输入。然后在更多层上重复相同的计算模式。最后,来自最后一层的节点表示被聚集(A^y)以形成最终预测(y)。(图片由作者提供)

示例:图形神经网络

所以现在我们已经知道,一个图只是一些节点(XY)之间的一组边(edge(X,Y))。任何 GNN 模型的本质都是简单地传播和聚集来自其邻居的节点的表示(又名“消息传递”)。在关系逻辑术语中,这个消息传递规则实际上可以放入一个逻辑规则中,如下所示:**

*message2(X) <= message1(Y), edge(X, Y)*

可以直观地理解为:

为了计算一个对象 X 的表示'消息 2 ',所有这样的对象 Y 的集合表示'消息 1* ',其中''在 XY 之间。***

现在让我们从正式的、声明性的、关系逻辑的角度来仔细看看这意味着什么。这里的逻辑谓词【消息 2】消息 1、【边缘】表示关系的名称,而逻辑变量“X”和“Y”表示对某些对象的引用。“消息 1”和“消息 2”都是一元关系,通常表示一个对象的一些属性,而“边”是一个二元关系,将两个对象联系在一起,即在这里用一条边连接图中的两个节点。“< =”运算符是一个蕴涵,在逻辑编程中通常从右向左书写,意思是右边部分(“规则的主体”)的(真)值隐含左边部分(“规则的头”)。最后,逗号“,”表示一个连词,意味着关系“消息 1(Y)”和“边(X,Y)”必须同时成立,即对于相同的对象 Y 和 X。****

现在让我们从数据库(SQL)的角度来看一下同样的原理,它从一个更熟悉、更实用的角度揭示了幕后发生的事情。我们已经知道逻辑关系对应于数据库中的。类似地,逻辑变量对应于它们的。规则“头部”(左侧)中的表格是隐含的(< =),即通过评估规则的“主体”(右侧)来创建。主体中的逻辑合取“”对应于各个表之间的一个连接,约束遵循各个变量绑定。例如,这里我们希望将表“message1”和“edge”连接到它们各自的列 Y 上,并将结果的列 X(投影)存储到一个名为“message2”的新表中。虽然可能有多个对象满足这样的约束,即多个 Y 具有来自特定 X 的“边”,但我们也需要通过 X 进行分组,同时聚合*相邻 Y 的属性(我们也可以聚合来自二元“边”的值)。因此,GNN 规则实际上也对应于一个简单的 SQL 查询,可以理解为:*****

在列 Y 上联接表“message1”和“edge ”,按 X 分组,并将结果值聚合到新表“message2”中。

如果你停下来想一想,这正是所有 GNN 模型下的“消息传递”图传播/聚集规则。

  • 在这里,您通常会看到表“边”以邻接矩阵的形式表示(而不是这个邻接表/表),表“消息 1”作为节点的特征/嵌入矩阵。传播步骤,即这里的连接和聚合,可以通过两者的矩阵相乘来表示。

现在,我们只需要给这种计算模式添加一些可学习的参数,以使其成为常识中的统计机器学习模型。这通过简单地将规则中的每个关系与可学习的(张量)权重相关联来完成。

最后,我们“仅仅”需要使这些逻辑规则,即 SQL 查询、可微分,以便高效地学习那些关联权重。虽然我们不会详细讨论这种语言的可微分解释的语义,但它在之前的一篇文章中有所概述,并在这篇论文中有更详细的描述。简而言之,底层查询评估的每个程序步骤都表示相应计算图中的一些操作,然后我们以类似于经典深度学习模型的方式反向传播。****

总之,我们刚刚展示了如何将经典的深度学习 GNN 模型表示为简单的参数化 SQL 查询。这不是很奇怪吗?虽然这听起来像一些抽象的概念,你可能在研究论文中读到过,但在实践中并不真正起作用,现在让我们通过下面关于创建一个 数据库内 GNN 的实用教程来明确我们的意思。

创建数据库内 gnn

现在让我们切换到一个实用的框架,它实例化了我们到目前为止讨论过的所有前述的深度关系学习原则。它叫做https://github.com/LukasZahradnik/PyNeuraLogic,你可以在之前的文章中读到更多关于它的内容。这里,让我们直接进入它的一个(最近的)模块,处理框架内部使用的关系逻辑表示和关系数据库之间的映射。**

与常见的以张量为中心的深度学习框架相反,PyNeuraLogic 将一切都建立在逻辑关系上。由于关系(表)是框架中的一等公民,因此不需要任何特别的(有问题的)张量变换,这使得它与关系数据库的互操作非常自然。特别是,PyNeuraLogic 框架配备了一组工具,用于直接关系表数据映射,直接在其上训练当代深度关系模型,甚至导出到普通 SQL 代码,以便您可以直接在数据库中评估训练的模型!

示例数据库

首先,让我们介绍一下我们将在这个简单的演示中使用的数据。我们的示例数据库包含分子的结构化信息。每个分子都有一些属性,由不同数量的原子组成。原子也有一些属性,可以和其他原子形成属性键。因此,我们的数据库由三个表组成——“分子”、“原子”和“键”。

教程使用的关系数据库图 (图片来自 PyNeuraLogic)

在这种情况下,我们的任务是确定分子的诱变性,这是关系学习和 GNNs 中最常用的基准之一。因此,我们的目标标签将是“分子”表中的“诱变”字段。现在,这 3 个表将自然地对应于 PyNeuraLogic 框架中的 3 个关系。然而,我们也可以对这种映射进行一些定制。例如,我们可能希望将“atom”表的每一行映射到一个关系“R.atom ”,仅将“atom_id”和“molecule_id”列作为关系的,将“charge”列作为关系的。****

  • 注意,将分配给关系(关系事实)超出了标准的关系逻辑形式,在标准的关系逻辑形式中,值被限制为真(存在)或假(不存在)。放松到全范围的(张量)值是 PyNeuraLogic 能够将深度学习功能集成到关系逻辑原则中的原因。**

将表映射到有值关系事实。我们将“atom_id”和“molecule_id”列映射到关系的项,但是“charge”列映射到其 用于演示。(图片来自 PyNeuraLogic)

请注意,这种映射非常灵活。我们当然可以将“charge”作为另一个术语(值将默认为 True 或“1”),也包括“element”和“type”列,或者我们甚至可以将表拆分成多个新定义的关系。**

为了实例化这个关系-表映射,我们创建一个“DBSource”对象的实例,将“关系名”、“表名”和“列名”(将被映射到术语)作为参数。为了简单起见,我们将只利用“键”和“原子”表中的数据:

**from neuralogic.dataset.db import DBSource, DBDataset

atoms = DBSource("atom", "atom", ["atom_id", "molecule_id"], 
                  value_column="charge")
bonds = DBSource("bond", "bond", ["atom1_id", "atom2_id", "type"],
                  default_value=1)**

接下来,对于监督训练,我们还需要查询标签——也就是简单的“分子”表中的“诱变”字段。由于这些是文本标签,我们只想将它们转换为标准(交叉熵)误差优化的数值,这也可以定制:**

**queries = DBSource("mutagenic", "molecule", ["molecule_id"], 
                    value_column="mutagenic",
                    value_mapper=lambda value: 1 if value == "yes" else 0
)**

最后,我们只是将这些映射放在一起,并通过一些兼容的数据库驱动程序(如 psycopg2 或 MariaDB)建立一个数据库连接,以创建一个关系型logic_dataset:

**import psycopg2

with psycopg2.connect(**connection_config) as connection:
    dataset = DBDataset(connection, [bonds, atoms], queries)
    logic_dataset = dataset.to_dataset()**
  • 请注意,这里没有隐藏预处理,比如转换成张量,这是通用框架所必需的。这只是表和关系之间非常直接的映射,然后可以通过适当的深度关系模型直接学习。**

GNN 模型模板示例

关系数据集已准备好;现在让我们来看看如何定义学习模板。我们有意避免学习“模型”这个常用术语,因为模板可以被看作是构建这种模型的高级蓝图。也就是说,单个关系模板可以对应于多个模型,即计算图,其将根据这里的每个示例结构及其目标查询自动定制。**

  • 这允许对输入数据的不同大小和结构的问题进行通用处理。例如,这里的单个示例分子很好地对应于“分子”表中的单个行,这可以直接用作标准模型(树、支持向量机、神经网络等)的输入。).但是同一个分子也跨越了“原子”和“键”表中不同数量的行,这对于标准模型来说是一个很大的问题,正如以前的一篇文章中所解释的。因此将“模型”概括为“模板”。

我们在这里定义的模板首先计算每种化学键的嵌入量(化学键类型只是它在range(1,8)中的多重性)。然后,我们添加两个消息传递规则(GNN 层),类似于本文前面描述的规则,用于在整个分子中传播原子和键的表示。最后,该模板定义了一个“读出”规则,该规则将所有层中所有节点的表示聚合成一个单一的“诱变”值,该值被传递到一个 sigmoid 函数中,并与诱变分类的二进制目标查询标签进行匹配。

  • 这是一个经典的 GNN 模型架构,具有跳过连接和附加边缘(结合)嵌入传播,类似于 GIN
**from neuralogic.core import Template, R, V, Transformation

template = Template()

template += [R.bond_embed(bond_type)[1,] for bond_type in range(1, 8)]

template += R.layer1(V.A)[1,] <= (
    R.atom(V.N, V.M)[1,], R.bond_embed(V.B)[1,], R._bond(V.N, V.A, V.B) )

template += R.layer2(V.A)[1,] <= (
    R.layer1(V.N)[1,], R.bond_embed(V.B)[1,], R._bond(V.N, V.A, V.B) )

template += (R.mutagenic(V.M)[1,] <= (
    R.layer1(V.A)[1,], R.layer2(V.A)[1,], R.atom(V.A, V.M)[1,] )
) | [Transformation.IDENTITY]

template += R.mutagenic / 1 | [Transformation.SIGMOID]**
  • PyNeuraLogic 用逻辑编程重载 Python,这样你就可以通过这样的参数化规则编写神经模型模板。R代表关系生成器,V代表变量[1,]是关联的权重维度(即这里的标量),而<=连接了从规则体(右侧)到规则头(左侧)的关系模式。可以附加诸如非默认激活功能的附加信息。如果这没有意义,请参见文档快速入门。****

最后,我们可以通过将此模板传递到“评估器”来构建和训练我们的模型,这看起来非常类似于经典的深度学习框架:

**from neuralogic.nn import get_evaluator
from neuralogic.core import Settings, Optimizer
from neuralogic.nn.init import Glorot
from neuralogic.nn.loss import CrossEntropy
from neuralogic.optim import Adam

settings = Settings(
    optimizer=Adam(), epochs=2000, initializer=Glorot(), 
    error_function=CrossEntropy(with_logits=False)
)

neuralogic_evaluator = get_evaluator(template, settings)
built_dataset = neuralogic_evaluator.build_dataset(logic_dataset)

for epoch, (total_loss, seen_instances) \ 
    in enumerate(neuralogic_evaluator.train(built_dataset)):

    print(f"Epoch {epoch}, total loss: {total_loss}, 
            average loss {total_loss / seen_instances}")**

将神经模型转换为 SQL

此外,只需几行代码,我们刚刚构建和训练的模型就可以变成(Postgres) SQL 代码。通过这样做,您可以直接在您的数据库服务器中对进一步的数据评估模型,而无需安装 NeuraLogic 甚至 Python。简单的 PostgreSQL 就可以了!**

我们所要做的就是创建一个转换器,它接受我们的模型、“表映射”和设置。对于关系和表之间的映射,表映射类似于前面描述的“DBSource ”:**

**from neuralogic.db import PostgresConverter, TableMapping

convertor = PostgresConverter(
    neuralogic_evaluator.model,
    [
        TableMapping("_bond", "bond", ["atom1_id", "atom2_id", "type"]),
        TableMapping("atom", "atom", ["atom_id", "molecule_id"], 
                      value_column="charge")
    ],
    settings,
)**

初始设置后(请参见文档,您可以将您的实际模型安装为 SQL 代码,只需调用“to_sql”即可检索该代码:

**sql = convertor.to_sql()**

现在,您已经做好了准备,可以直接在数据库中评估您训练好的模型,而不会留下任何数据。对于每个学习表示,在“neuralogic”命名空间中都会有一个对应的函数。比方说,我们想在一个 id 为“d150”的分子上评估我们的模型,这现在就像做一个 选择 语句一样简单:

**SELECT * FROM neuralogic.mutagenic('d150');**

类似地,我们可以通过使用“NULL”作为占位符来请求所有可推断的替换及其值,例如,在此请求所有的分子预测:

**SELECT * FROM neuralogic.mutagenic(NULL);**

以完全相同的方式,我们甚至可以检查模型的内部表示!比如我们可以从第一层查询 id 为“d15 _ 11”的化学原子*的值:*****

**SELECT * FROM neuralogic.layer1('d15_11');**

结论

总之,我们使用 PyNeuraLogic 框架从零开始声明了一个简单的 GNN 模型变体,它可以在具有多个相互链接的表的关系数据库上本地工作。此外,我们甚至将模型导出到普通 SQL 中,以便可以随时在数据库引擎中直接对其进行进一步评估,而无需任何外部库。**

这表明,现有的结构化数据的现代深度学习原则可以在(加权)关系逻辑的(数据库)表示形式下有效地捕获。然而,很明显,使用表达能力更强、可区分的关系逻辑形式的要点是,它允许您做的远不止是通过二元关系(gnn)进行简单的图形传播。

直接从 GNN 的例子中推断,没有什么可以阻止你扩展到更高层次的关系,不同的传播模式连接更多的表,并以新的方式将这些组合到层次逻辑(SQL)程序中。因此,不需要等到下一年的 NeurIPS 来介绍另一轮新的“深度超图”、“深度元图”、“深度推理”、“深度逻辑”和其他深度关系学习想法——你现在就可以开始在 PyNeuraLogic 中简单地宣布这些。

只需$pip install neuralogic开始将这些模型想法付诸实践,或者如果感兴趣,请联系我们!

  1. 在这篇文章中,我们没有在向量和张量表示之间进行太多的区分,因为你总是可以将一个转换为另一个,知道维度,这在标准的深度学习模型中总是已知/固定的。
  2. 当然,在关系数据库中使用递归自连接来遍历图并不是处理这些结构的最有效的方式(例如,有专门的图数据库来处理这些结构)。然而, NeuraLogic 使用定制的、高效的基于 CSP 的关系(逻辑)推理引擎,非常适合高度互联结构上的复杂结构化查询。
  3. 这种矩阵形式也可以说是非常优雅的,但这只适用于基本的 GCN 模型。转到更具表达力的 GNN 模型,利用例如图(子)结构和更高级的传播方案,矩阵代数形式很快变得混乱,而关系逻辑形式保持不变。

作者感谢Lukas Zahradnik校对这些帖子,创作了 教程 ,开发了PyNeuraLogic*。*

走向几何深度学习 I:站在巨人的肩膀上

原文:https://towardsdatascience.com/towards-geometric-deep-learning-i-on-the-shoulders-of-giants-726c205860f5

几何深度学习的起源

几何深度学习从对称性和不变性的角度处理了一大类 ML 问题,为多种多样的神经网络架构(如 CNN、gnn 和 Transformers)提供了一个通用蓝图。在一系列新的帖子中,我们研究了这些想法是如何从古希腊几何到图形神经网络的历史中出现的。

图片:基于 Shutterstock。

雪花和标准款有什么共同点?对称。在“走向几何深度学习系列”的第一篇文章中,我们讨论了对称性的概念如何帮助组织了 19 世纪的几何动物园,并彻底改变了理论物理。这篇文章基于 M. M .布朗斯坦、j .布鲁纳、t .科恩和 p .韦利奇科维奇、 几何深度学习 (在麻省理工学院出版社完成后出现)一书的介绍章节,并伴随 我们的课程 参加非洲机器智能大师赛(AMMI)。参见 第二部分 关于神经网络的早期历史和第一个【艾冬】 第三部分 研究第一个“几何”架构, 第四部分 致力于早期 GNNs,以及我们的 以前的帖子 总结几何深度学习的概念

过去十年见证了数据科学和机器学习的一场实验革命,深度学习方法是这场革命的缩影。事实上,许多以前被认为遥不可及的高维学习任务——计算机视觉、下围棋或蛋白质折叠——实际上在适当的计算规模下是可行的。值得注意的是,深度学习的本质是建立在两个简单的算法原则上的:第一,表示或特征学习的概念,其中适应的,通常是分层的,特征捕捉每个任务的规律性的适当概念,第二,通过梯度下降型优化进行学习,通常作为反向传播来实现。

虽然学习高维空间中的一般函数是一个糟糕的估计问题,但大多数感兴趣的任务并不是一般的,而是带有本质的预定义规则,这些规则来自底层的低维空间和物理世界的结构。几何深度学习关注的是通过统一的几何原理来揭示这些规律性,这些几何原理可以应用于广泛的应用领域。

利用一个大系统的已知对称性是对抗维数灾难的一种强有力的经典疗法,并且构成了大多数物理理论的基础。深度学习系统也不例外,从早期开始,研究人员就采用神经网络来利用物理测量中产生的低维几何,例如图像中的网格、时间序列中的序列或分子中的位置和动量,以及它们相关的对称性,如平移或旋转。

由于这些想法在科学中有着深厚的根基,我们将试图了解它们在历史上是如何演变的,最终形成一个可以应用于当今大多数流行的神经网络架构的通用蓝图。

秩序、美丽和完美

“对称,无论你定义它的含义有多宽或多窄,都是一种观念,古往今来人类一直试图通过它来理解和创造秩序、美和完美。”—赫尔曼·韦勒(1952 年)

伟大的数学家 Hermann Weyl [1]在他从普林斯顿高等研究院退休前夕的著作中给出了对称的这个有点诗意的定义。Weyl 追溯了对称性在古代科学和艺术中占据的特殊位置,从苏美尔人的对称设计到毕达哥拉斯人,毕达哥拉斯人认为圆是完美的,因为它具有旋转对称性。柏拉图认为今天以他的名字命名的五种正多面体是如此的基本,它们一定是塑造物质世界的基本构件。

然而,尽管柏拉图被认为创造了术语 συμμετρία ,字面意思是“相同的度量”,但他只是模糊地使用它来传达艺术中的比例之美和音乐中的和谐之美。德国天文学家和数学家约翰尼斯·开普勒首次尝试对水晶体的对称形状进行严格分析。在他的论文《论六角雪花》[2]中,他将雪花的六重二面角结构归因于粒子的六边形堆积
——这一想法虽然先于对物质如何形成的清晰理解,但今天仍然是结晶学的基础[3]。

柏拉图(左)认为对称的多面体(“柏拉图立体”)是自然的基本构件。约翰尼斯·开普勒(右)首次将水晶体的六重对称性归因于粒子的六边形堆积,这要早于现代结晶学。肖像:伊霍尔·戈尔斯基。

在现代数学中,对称性几乎是用群论的语言来表达的。这个理论的起源通常归功于 variste Galois,他创造了这个术语,并在 19 世纪 30 年代用它来研究多项式方程的可解性[4]。与群论相关的另外两个名字是 Sophus Lie 和 Felix Klein,他们相遇并一起卓有成效地工作了一段时间[5]。前者将发展今天以他的名字命名的连续对称理论(李群);后者在他的埃尔兰根计划中宣称群论是几何学的组织原则。鉴于 Klein 的计划是几何深度学习的灵感来源,因此值得在它的历史背景和革命性影响上花更多时间。

variste Galois(左)和他在致命决斗的前一天晚上写给朋友的描述群论的信。费利克斯·克莱因(右)和为他的教授任命准备的研究计划书的前页,该计划作为“埃尔兰根计划”进入了数学史。肖像:伊霍尔·戈尔斯基。

一个陌生的新世界

大约 2300 年前,古希腊的欧几里得在一篇名为《T2 元素》的论文中正式确立了现代几何的基础。欧几里得几何(在学校仍被称为“几何学”)是建立在五个直觉公理或公设上的一组结果。第五公设——声明只有一条平行于给定直线的直线可能通过该直线之外的一点——似乎不太明显,自古以来一群杰出的数学家竭尽全力试图证明这一点,但毫无结果。

“几何之父”欧几里得(左)和欧玛尔·海亚姆(右)和乔瓦尼·塞开里在试图证明第五公设时使用的结构。肖像:伊霍尔·戈尔斯基。

对平行线问题的早期处理方法出现在 11 世纪的波斯论文《关于欧几里得《几何原本》公设困难的评注》中,作者是欧玛尔·海亚姆[6]。18 世纪的意大利耶稣会牧师乔瓦尼·塞开里很可能从他自己作品的标题 判断出他之前的作品是欧几里得 ab omni nvo providus(“欧几里得清除了每一个污点”)。

像海亚姆一样,他考虑了边垂直于底边的四边形的顶角。锐角导致无限多条不相交的线可以穿过不在直线上的一点,这一结论似乎是如此反直觉,以至于他拒绝了这一结论,称之为‘repugnatis natural linrect’(‘与直线的本质相抵触’)【7】。

乔瓦尼·塞开里的《欧几里德证明》的卷首,以及拒绝双曲几何的段落,认为这是“对自然的反驳”

19 世纪已经意识到第五公设并不重要,人们可以根据不同的平行度概念来构造替代的几何图形。一个这样的早期例子是射影几何,顾名思义,出现在透视图和建筑中。在这种几何学中,点和线是可以互换的,没有通常意义上的平行线:任何线都在“无穷远点”相交。虽然射影几何的结果自古以来就为人所知,但吉恩·维克托·蓬斯莱在 1812 年首次系统地研究了它[8]。

第一次建立真正的非欧几何的功劳是有争议的。卡尔·弗里德里希·高斯在 1813 年左右研究了这个问题,但是没有发表任何结果。关于非欧几里得几何的第一个出版物是俄罗斯数学家尼古拉·罗巴切夫斯基的《几何的起源》。在这部著作中,他认为第五个公设是一个任意的限制,并提出了一个替代的公设,即超过一条线可以通过一个点,该点与一个给定的点平行。这样的构造需要一个负曲率的空间——我们现在称之为双曲空间——这个概念在当时还没有完全掌握[11]。

亚诺什·波尔约【1823 年 11 月 3 日用匈牙利语写给他父亲的信(左图),宣布他发现了双曲几何。尼古拉·罗巴切夫斯基(右)和他于 1829 年出版的著作《几何的起源》的第一页。肖像:伊霍尔·戈尔斯基。

罗巴切夫斯基的想法似乎是异端邪说,他被同事们公开嘲笑[12]。匈牙利人亚诺什·波尔约独立发现了一个类似的结构,他在 1832 年以“绝对几何”的名义发表了它在 1823 年写给他父亲的一封信中,他热情洋溢地描述了这一新发展:

“我发现了如此奇妙的东西,以至于我感到惊讶……从无到有,我创造了一个陌生的新世界。”亚诺什·波尔约(1823 年)

与此同时,新的几何图形像聚宝盆一样不断涌现。奥古斯特·莫比乌斯[13],以同名曲面闻名,研究仿射几何。高斯的学生 Bernhardt Riemann 在他的适应讲座中引入了非常广泛的一类几何——今天称之为Riemann是他的荣誉——随后以标题Uber die hypothesis en,welche der Geometrie zu Grunde liegen(‘论几何所基于的假设’)【14】出版。黎曼几何的一个特例是球面的“椭圆”几何,这是违反欧几里德第五公设的另一种构造,因为球面上没有一点可以画出一条与给定直线不相交的直线。

十九世纪下半叶,欧几里得对几何学的垄断被完全关闭了。新的几何类型(欧几里得、仿射、射影、双曲线、球面)出现并成为独立的研究领域。然而,这些几何图形之间的关系和它们的层次并不清楚。

正是在这种令人兴奋但又混乱的情况下,费利克斯·克莱因(Felix Klein)带着天才的洞察力,利用群论作为对称的代数抽象来组织“几何动物园”克莱因在被任命为埃尔兰根大学教授时年仅 23 岁,按照德国大学的惯例,他被要求提供一个名为Vergleichende Betrachtungenüber neuere geometricsche Forschungen(“近期几何研究的比较综述”)的研究项目,该项目已作为“埃尔兰根项目”载入数学史。

克莱因的突破性见解是将几何定义作为对不变量的研究,或者换句话说,在某种类型的变换(对称性)下保留的结构。Klein 使用群论的形式来定义这种变换,并使用群及其子群的层次来分类由此产生的不同几何。

Klein 的 Erlangen 程序将几何定义为具有一组变换的空间。这允许对不同类型的几何图形进行分类。

欧几里得几何似乎是仿射几何的一个特例,而仿射几何又是射影几何的一个特例(或者,就群论而言,欧几里得群是射影群的一个子群)。Klein 的 Erlangen 程序在某种意义上是几何的“第二代代数化”(第一代是勒内·笛卡尔的解析几何和以他的拉丁名 Cartesius 命名的坐标方法),它允许产生以前的方法不可能产生的结果。

更一般的黎曼几何被明确排除在克莱因的统一几何图景之外,又过了 50 年才得以整合,这在很大程度上要归功于埃利·卡坦在 20 世纪 20 年代的工作。此外,范畴理论,现在在纯数学中无处不在,用它的创造者塞缪尔·艾伦伯格和桑德斯·麦克兰恩的话来说,可以“被看作是克莱因·埃尔兰根计划的延续,在这个意义上,一个几何空间及其变换群被推广到一个范畴及其映射代数”[16]。

万物理论

克莱因认为射影几何是所有几何中最普遍的,他在他的《几何画卷》中抱怨道:

“数学物理学家是多么坚持不懈地忽视在许多情况下仅仅通过适度培养射影观点给他带来的优势。”费利克斯·克莱因(1872 年)

他提倡利用几何学和物理学中的对称原理,这预示着下一个世纪将是该领域真正的革命。

在哥廷根[18]中,克莱因的同事艾米·诺特[19]证明了物理系统作用的每一个可微对称性都有相应的守恒定律[20]。无论如何,这是一个令人震惊的结果:事先,需要细致的实验观察来发现基本定律,如能量守恒,即使这样,这也是一个来自任何地方的经验结果。诺特定理——用诺贝尔奖获得者弗兰克·维尔泽克的话说,是“20 世纪和 21 世纪物理学的指路明灯”——举例来说,它表明能量守恒来自时间的平移对称性,这是一个相当直观的想法,即实验的结果不应该取决于它是在今天还是明天进行。

赫尔曼·威尔(左)和一张 1918 年爱因斯坦寄来的明信片,讨论他最初提出的规范理论。艾米·诺特(右)和同年发表的包含她著名定理的文章。肖像:伊霍尔·戈尔斯基。

另一个与电荷守恒相关的对称性,电磁场的整体规范不变性,首先出现在麦克斯韦的电动力学公式中[21];然而,它的重要性最初并没有被注意到。同样是赫尔曼·韦勒,他对对称性写得如此摇摆不定,是他在 20 世纪初首次在物理学中引入规范不变性的概念[22],强调它作为一个可以推导出电磁学的原理的作用。几十年后,这一基本原理(以杨和米尔斯[23]开发的概括形式)被证明成功地提供了一个统一的框架来描述电磁和强弱力的量子力学行为,最终形成了标准模型,该模型捕捉了除重力之外的所有基本自然力。正如另一位获得诺贝尔奖的物理学家菲利普·安德森[24]所言,

“说物理学是对对称性的研究只是稍微夸大了一点。”——菲利普·安德森(1972)

一个不耐烦的读者可能会问,所有这些对几何学和物理学历史的探索,无论多么令人兴奋,与深度学习有什么关系?正如我们将在下一部分看到的,对称和不变性的几何概念甚至在早期进行“模式识别”的尝试中就已经被认为是至关重要的,公平地说,几何从一开始就伴随着人工智能的新生领域。

[1] H .韦勒,对称性 (1952),普林斯顿大学出版社。

[2]如题所示,开普勒于 1611 年将这本小册子作为圣诞礼物送给了他的赞助人和朋友约翰内斯·马特乌斯·瓦克尔·冯·瓦肯费尔斯。

[3] P .波尔,回顾:在六角雪花上 (2011),自然 480(7378):455–455。

[4]伽罗瓦著名地描述了群论的思想(他在寻找多项式方程的解的背景下考虑了群论),并在他的致命决斗前夕写给朋友的一封信中创造了术语“群”( groupe 法语)。他要求将他的想法传达给当时的杰出数学家,表示希望他们能够“破译所有这些混乱”。两天后,伽罗瓦因在决斗中受伤而去世,年仅 20 岁,但他的工作在数学领域产生了变革。

[5]参见 R. Tobies 的传记注释,Felix Klein——数学家、学术组织者、教育改革家 (2019),Felix Klein 的遗产5–21,Springer。

[6]如今,欧玛尔·海亚姆作为一位诗人和不朽名句“一瓶酒,一本诗集,你在我身旁”的作者而被人们铭记。"

[7]欧几里得的《为自己辩护》的出版需要宗教裁判所的批准,这是在 1733 年作者去世前几个月得到的。塞开里的工作在十九世纪被意大利微分几何学家尤金尼奥·贝尔特拉米重新发现,现在被认为是构建双曲几何的早期几乎成功的尝试。

[8]庞斯列是一名军事工程师,参加了拿破仑的俄国战役,在那次战役中他被俘虏并被囚禁,直到战争结束。正是在这段被囚禁的时间里,他写了《图形的投影》( 1822 年《关于图形的投影性质的论文》),恢复了人们对射影几何的兴趣。他的同胞热拉尔·德萨格斯在 1643 年完成了这个课题的早期基础工作。

[9]在他儿子的结果发表后,高斯在 1832 年写给法卡什·波尔约的信中写道:“赞美它就等于赞美我自己。因为这部作品的全部内容与我过去 30 年或 35 年来思考的问题几乎完全一致。”高斯也是第一个使用“非欧几里得几何”这个术语的人,他把严格意义上的称为他自己构建的双曲几何。参见
R. L. Faber,
欧几里德和非欧几里德几何的基础* (1983),德克尔和《康托的天堂》中的博文。*

[10] Н.И.лобачевский,началах,1829 年。

【11】Eugenio belt rami提出了一个称为伪球面的双曲几何模型,这是一个具有恒定负曲率的曲面,他还证明了双曲几何在逻辑上是一致的。“双曲几何”这个术语是费利克斯·克莱因引入的。

[12]例如,1834 年的一本小册子 T16 上只签了首字母“S.S”(有人认为这是罗巴切夫斯基的长期对手奥斯特罗格拉茨基的作品),声称罗巴切夫斯基从“数学中最轻松、最清晰的章节——几何学”中得出“一个晦涩、沉重的理论”,不明白为什么有人会出版这样的“荒谬的幻想”,并暗示这本书是一个“笑话或讽刺”

[13] A. F .莫比乌斯,《重心计算》(1827 年)。

[14] B .黎曼,über die Hypothesen,welche der geometrice zu Grunde liegen(1854)。参见英文翻译

[15]根据一种流行的观点,包括维基百科在内的许多来源都重复了这一观点,埃尔兰根计划是在 1872 年 10 月克莱因的就职演说中提出的。克莱因确实做过这样的演讲(虽然是在 1872 年 12 月 7 日),但那是给非数学听众的,主要是关于他的数学教育思想;参见[5]。“课程”的名称来自于已出版的小册子[17]的副标题:program zum ein tritt in die philosophische fakultt und den Senat der k . Friedrich-Alexanders-universit t zu Erlangen(“进入弗里德里希-亚历山大皇帝大学 Erlangen 学院哲学系和参议院的课程”)。

[16] S .艾伦伯格和 s .麦克莱恩,《自然等价通论》 (1945),译。AMS 58(2):231–294。另见 J.-P. Marquis,范畴理论和 Klein 的 Erlangen 程序(2009),从几何的观点9–40,Springer。

[17] F .克莱因,vergleichchende Betrachtungenüber neuere geometrische Forschungen(1872)。参见英文翻译。**

[18]当时,哥廷根是德国乃至世界首屈一指的数学中心。尽管埃尔兰根以与克莱因的联系而自豪,但他只在那里呆了三年,于 1875 年转到慕尼黑工业大学(当时称为技术大学),接着是莱比锡(1880 年),最后从 1886 年到退休在哥廷根定居。

[19]艾米·诺特被理所当然地认为是数学界最重要的女性之一和二十世纪最伟大的数学家之一。她不幸出生并生活在一个学术界仍根深蒂固地认为女性不适合科学的中世纪时代。她是数学界为数不多的不得不克服偏见和蔑视的女性之一,她的职业生涯确实具有开拓性。应该说,她的男同事中有些人试图打破规则,这是值得称赞的。当克莱因和戴维·希尔伯特第一次试图为诺特在哥廷根获得一个教职未果时,他们遇到了学术权威的强烈反对。据报道,希尔伯特讽刺性地反驳了在一次这样的讨论中提出的问题:“我不认为候选人的性别是反对她被承认为一等兵的理由。毕竟,参议院不是澡堂”(见 C. Reid,Courant in g ttingen and New York:一个不可思议的数学家的故事 (1976),Springer)。尽管如此,Noether 在她的亲密合作者和学生中享有很高的声望,她在哥廷根的男性同事亲切地称她为“Der Noether”,男性(参见 C. Quigg,座谈会:no ether 定理的一个世纪 (2019),arXiv:1902.01989)。

[20] E. Noether,不变量问题(1918 年),nig Gesellsch。维斯博士。祖·哥廷根,数学物理 235–257。参见英文翻译

[21] J. C. Maxwell,电磁场的动力学理论 (1865),伦敦皇家学会哲学汇刊 155:459–512。

[22] Weyl 在 1919 年首次(不正确地)推测,在标度或“规范”变化下的不变性是电磁的局部对称性。轨距这个术语,或在德语中称为 Eich ,是通过类比铁路的各种轨距而选择的。在量子力学发展之后,他修改了规范的选择,用 iH 中波相位的变化来代替标度因子。《电子与引力》( 1929 年),《物理学报》第 56 卷第 5-6 期:第 330-352 页。参见 N. Straumann,规范理论和弱相互作用的早期历史 (1996),arXiv:hep-ph/9609230。

[23] C.-N .杨和 R. L .米尔斯,同位素自旋守恒和同位素规范不变性 (1954),物理评论 96 (1):191。

[24] P. W .安德森,更多的是不同的 (1972),科学 177(4047):393–396。

本文中的肖像是由伊霍尔·戈尔斯基手绘的。几何深度学习的详细讲座资料可在 项目网页 获取。参见迈克尔的 其他帖子 在走向数据科学, 订阅 到他的帖子和 YouTube 频道 ,获取 中等会员 ,或者关注 迈克尔

走向几何深度学习 II:感知机事件

原文:https://towardsdatascience.com/towards-geometric-deep-learning-ii-the-perceptron-affair-fafa61b5c40a

几何深度学习的起源

几何深度学习从对称性和不变性的角度处理了一大类 ML 问题,为多种多样的神经网络架构(如 CNN、gnn 和 Transformers)提供了一个通用蓝图。在一系列新的帖子中,我们研究了可以追溯到古希腊的几何思想如何塑造了现代深度学习。

图片:基于 Shutterstock。

在“走向几何深度学习系列”的第二篇文章中,我们讨论了早期的神经网络模型,以及它们的批评如何产生了计算几何的新领域。这篇文章基于 M. M .布朗斯坦、j .布鲁纳、t .科恩和 p .韦利奇科维奇、 几何深度学习 (在麻省理工学院出版社完成后出现)一书的介绍章节,并伴随 我们的课程 参加非洲机器智能大师赛(AMMI)。参见 第一部分 讨论对称性, 第三部分 研究第一个“几何”架构, 第四部分 献给早期 GNNs,以及我们之前的 帖子 总结几何深度学习的概念。

虽然很难就“人工智能”作为一个科学领域诞生的具体时间点达成一致(最终,人类一直痴迷于理解智能并从文明的黎明开始学习),但我们将尝试一项风险较小的任务,看看深度学习的前身——我们讨论的主要话题。这段历史可以压缩到不到一个世纪。

感知器的兴衰

到了 20 世纪 30 年代,人们已经清楚意识存在于大脑中,研究工作转向从大脑网络结构的角度来解释大脑的功能,如记忆、感知和推理。麦卡洛克和皮茨[1]被认为是第一个对神经元进行数学抽象的人,展示了神经元计算逻辑功能的能力。就在创造了“人工智能”这个术语的传奇达特茅斯学院研讨会一年后,来自康乃尔航空实验室的美国心理学家 Frank Rosenblatt 提出了一类他称之为“感知机”的神经网络。

Frank Rosenblatt 和他的 Mark I 感知器神经网络是在康奈尔航空实验室开发的,用于简单的视觉模式识别任务。肖像:伊霍尔·戈尔斯基。

感知机首先在数字机器上实现,然后在专用硬件上实现,设法解决简单的模式识别问题,如几何形状的分类。然而,“连接主义”(从事人工神经网络研究的人工智能研究人员如何给自己贴标签)的迅速崛起受到了一桶冷水,这就是现在已经臭名昭著的马文·明斯基和西蒙·派珀特的书 Perceptrons

在深度学习社区,人们通常会回顾性地指责明斯基和帕佩特造成了第一个“人工智能冬天”,这使得神经网络在十多年里不再流行。一个典型的叙述提到了“ XOR 事件”,这是一个证据,证明感知机甚至不能学习非常简单的逻辑功能,这是它们表达能力差的证据。一些消息来源甚至添加了一些戏剧性的内容,回忆起罗森布拉特和明斯基曾就读于同一所学校,甚至声称罗森布拉特在 1971 年的一次划船事故中过早死亡是在同事们批评他的工作后自杀的。

颇具影响力的著作《感知机》的作者马文·明斯基和西蒙·派珀特这本书封面上的两个形状(其中一个是相连的)暗示了“宇称问题”。这本书考虑了简单的单层感知(左上),可能是最早的几何学习方法,包括群不变性的介绍(左下)。

现实可能更加平凡,同时也更加微妙。首先,美国“人工智能冬天”的一个更合理的原因是 1969 年的曼斯菲尔德修正案,该修正案要求军方资助“以任务为导向的直接研究,而不是基本的非直接研究”由于当时人工智能领域的许多努力,包括罗森布拉特的研究,都是由军事机构资助的,并没有显示出即时的效用,因此资金的削减产生了巨大的影响。第二,神经网络和人工智能总体上被过分夸大了:回想一下 1958 年《纽约客》的一篇文章称感知机为

《纽约客》(1958 年),“人类大脑有史以来第一个真正的对手”

和“非凡的机器”,它们“有能力思考”[5],或者过于自信的麻省理工学院夏季视觉项目期望“构建一个视觉系统的重要部分”,并在 1966 年的一个夏季学期中实现执行“模式识别”的能力[6]。研究界认识到,最初对“解决智力问题”的希望过于乐观,这只是一个时间问题。

早期炒作:1958 年《纽约客》的一篇文章称赞感知“能够思考”(左),1966 年,过于乐观的“麻省理工学院夏季视觉项目”旨在在几个月内构建一个“视觉系统的重要部分”。

然而,如果我们深入探讨这场争论的实质,很明显罗森布拉特所谓的“感知机”与明斯基和帕佩特所理解的“感知机”有很大不同。Minsky 和 Papert 将他们的分析和批评集中在他们称为“简单感知器”的一个狭窄的单层神经网络类别上(这在现代通常与该术语相关联),其计算输入的加权线性组合,后跟非线性函数[7]。另一方面,Rosenblatt 考虑了更广泛的一类架构,这些架构早于现在被认为是“现代”深度学习的许多想法,包括具有随机和本地连接的多层网络[8]。

如果 Rosenblatt 知道 Vladimir Arnold 和安德雷·柯尔莫哥洛夫[10-11]对第十三个希尔伯特问题[9]的证明,即一个连续的多元函数可以写成一个单变量连续函数的叠加,他可能会反驳一些关于感知器表达能力的批评。Arnold–Kolmogorov 定理是多层(或“深度”)神经网络的“通用逼近定理”的前身,它解决了这些问题。

W 虽然大多数人记得明斯基和帕佩特的书,因为它在削弱早期联结主义者的翅膀和哀叹失去的机会方面发挥了作用,但一个被忽视的重要方面是,它第一次提出了学习问题的几何分析。这一事实反映在书名中,副标题为《计算几何导论。在当时,这是一个全新的想法,一篇对这本书的评论12质疑道:

“计算几何”这门新学科是否会成长为一个活跃的数学领域;还是会在一堆死胡同里慢慢消失?”区块(1970 年)

前者发生了:计算几何现在是一个完善的领域[13]。

此外,Minsky 和 Papert 可能值得称赞的是,他们首次将群论引入了机器学习领域:他们的群不变性定理表明,如果神经网络对于某个群是不变的,那么它的输出可以表示为该群的轨道的函数。虽然他们使用这一结果来证明感知器可以学习的局限性,但类似的方法随后被 jun ' ichi Amari[14]用于模式识别问题中不变特征的构造。Terrence Sejnowski [15]和 John Shawe-Taylor[16–17]的著作中的这些思想的演变,不幸的是今天很少被引用,提供了几何深度学习蓝图的基础。

普适近似和维数灾难

前面提到的普遍近似的概念值得进一步讨论。该术语指的是以任何期望的精度逼近任何连续多元函数的能力;在机器学习文献中,这种类型的结果通常归功于 Cybenko [18]和 Hornik [19]。与 Minsky 和 Papert 批评的“简单”(单层)感知器不同,多层神经网络是通用的近似器,因此是学习问题的一种有吸引力的架构选择。我们可以将监督机器学习视为一个函数逼近问题:给定训练集(例如,猫和狗的图像)上某个未知函数(例如,图像分类器)的输出,我们试图从某个假设类中找到一个函数,该函数很好地符合训练数据,并允许预测以前看不见的输入的输出(“泛化”)。

走向普遍逼近:安德雷·柯尔莫哥洛夫和弗拉迪米尔·阿诺德证明的戴维·希尔伯特第十三个问题是第一批结果之一,表明多元连续函数可以表示为简单一维函数的组合和总和。George Cybenko 和 Kurt Hornik 证明了特定于神经网络的结果,表明具有一个隐藏层的感知器可以以任何期望的精度逼近任何连续函数。

通用逼近保证了我们可以通过多层神经网络来表达来自非常广泛的正则类(连续函数)的函数。换句话说,存在具有一定数量的神经元和一定权重的神经网络,其逼近从输入到输出空间(例如,从图像空间到标签空间)的给定函数映射。然而,通用逼近定理并没有告诉我们如何找到这样的权重。事实上,在早期,神经网络中的学习(即,寻找权重)一直是一个很大的挑战。

Rosenblatt 展示了一个只针对单层感知器的学习算法;为了训练多层神经网络,阿列克谢·伊瓦赫年科和瓦伦丁·帕拉【20】使用了一种叫做“数据处理分组法”的分层学习算法这使得 Ivakhnenko [21]能够钻到八层深处——这在 20 世纪 70 年代早期是一个非凡的壮举!

如何训练自己的神经网络?现在无处不在的反向传播只是在 20 世纪 80 年代大卫·鲁梅尔哈特的论文发表后才成为标准(尽管保罗·沃博斯和塞波·林奈马在更早的时候介绍过)。早在 20 世纪 70 年代初,Aleksey Ivakhnenko 的“数据处理分组方法”等早期方法就允许训练深度神经网络。

一项突破来自反向传播的发明,这是一种使用链规则计算权重相对于损失函数的梯度的算法,并允许使用基于梯度下降的优化技术来训练神经网络。截至今天,这是深度学习的标准方法。虽然反向传播的起源至少可以追溯到 1960 年[22],但这种方法在神经网络中的首次令人信服的演示是在被广泛引用的 Rumelhart、Hinton 和 Williams 的《自然》论文中[23]。这种简单有效的学习方法的引入是神经网络在 20 世纪 80 年代和 90 年代重返人工智能领域的一个关键因素。

通过近似理论的镜头来看待神经网络,导致一些愤世嫉俗者将深度学习称为“美化的曲线拟合”。我们将让读者通过尝试回答一个重要问题来判断这条格言有多正确:需要多少样本(训练样本)来精确地逼近一个函数?近似理论家会立即反驳说,多层感知器可以表示的连续函数类显然太大了:人们可以通过有限的点集合传递无限多种不同的连续函数[24]。有必要施加额外的规律性假设,如李普希茨连续性【25】,在这种情况下,可以提供所需样本数量的界限。

维数灾难是发生在高维空间中的一种几何现象。一种形象化的方法是查看单位超立方体中单位度量球的体积比例(后者代表特征空间,而前者可以解释为“最近邻”分类器)。体积比随尺寸成指数衰减:对于 d=2,该比值约为 0.78,对于 d=3,它下降到约 0.52,对于 d=10,它已经约为 0.01。图:改编自视觉假人。

不幸的是,这些界限随着维度呈指数级增长——这种现象俗称“维数灾难”[26]——这在机器学习问题中是不可接受的:即使是小规模的模式识别问题,如图像分类,也要处理数千维的输入空间。如果一个人必须只依赖近似理论的经典结果,机器学习将是不可能的。在我们的例子中,为了学会区分猫和狗,理论上需要的猫和狗图像的例子数量将比宇宙中的原子数量大得多[27]——周围没有足够的猫和狗来做这件事。

维数灾难:近似理论的标准结果与维数不成比例。因此,即使在简单的机器学习任务中,人们也会预测训练样本的数量远远大于实际可能的数量。

艾冬天来了

英国数学家詹姆斯·莱特希尔爵士(Sir James Lighthill)在一篇被人工智能历史学家称为“莱特希尔报告”的论文[28]中提出了机器学习方法向高维度扩展的问题,他在论文中使用了“组合爆炸”一词,并声称现有的人工智能方法只能解决玩具问题,在现实世界的应用中会变得难以处理。

“人工智能研究和相关领域的大多数工作者承认,他们对过去 25 年取得的成就明显感到失望。[……]在这个领域的任何一个领域,迄今为止的发现都没有产生当时所承诺的重大影响。”—詹姆斯·莱特希尔爵士(1972 年)

由于莱特希尔报告是由英国科学研究委员会委托评估人工智能领域的学术研究,其悲观的结论导致了整个池塘的资金削减。加上美国资助机构的类似决定,这相当于 20 世纪 70 年代人工智能研究的一个灾难。

F 对我们来说,经典泛函分析无法提供处理学习问题的适当框架,这一认识将促使我们寻求更强的几何形式的规律性,这种规律性可以在神经网络的特定布线中实现——例如卷积神经网络的局部连通性。公平地说,我们十年前目睹的深度学习的胜利重现至少部分归功于这些见解。

[1] W. S .麦卡洛克和 w .皮茨,神经活动中固有思想的逻辑演算 (1943),数学生物物理学通报 5(4):115–133。

[2]达特茅斯人工智能夏季研究项目是 1956 年在达特茅斯学院举办的一个夏季研讨会,被认为是人工智能领域的创始事件。

[3] F .罗森布拉特, 感知机,一种感知和识别自动机 (1957),康奈尔航空实验室。这个名字是“感知”和表示乐器的希腊后缀- 的组合。

[4] M. Minsky 和 S. A. Papert,感知器:计算几何导论 (1969),麻省理工学院出版社。

[5]这就是为什么我们只能对最近类似的关于深层神经网络的“意识”的说法一笑置之:אין כל חדש תחת השמש.

[6]原文引用,因为“模式识别”尚未成为正式术语。

[7]具体来说,Minsky 和 Papert 考虑了 2D 网格(他们的术语是“视网膜”)和一组线性阈值函数上的二元分类问题。虽然无法计算 XOR 函数一直是这本书的主要批评点,但大部分注意力都集中在几何谓词上,如奇偶和连通性。这个问题在书的封面上有所暗示,封面上有两个图案点缀:一个是相连的,另一个不是。即使对人类来说,也很难确定哪个是哪个。

[8] E. Kussul,T. Baidyk,L. Kasatkina 和 V. Lukovich,Rosenblatt 感知器用于手写数字识别(2001),IJCNN 表明,Rosenblatt 在 21 世纪硬件上实现的 3 层感知器在 MNIST 数字识别任务上达到 99.2%的准确率,与现代模型相当。

[9] 希尔伯特的第十三个问题是戴维·希尔伯特在 1900 年编制的 23 个问题之一,需要使用两个自变量的连续函数证明所有七次方程是否存在解。Kolmogorov 和他的学生 Arnold 展示了这个问题的一般化版本的解决方案,现在被称为Arnold-Kolmogorov 叠加定理

[10]在。还有。阿诺德,《关于用较少变量的连续函数叠加来表示多个变量的连续函数》(1956 年),苏联科学院报告 108:179–182。

[11]在。还有。阿诺德,《关于三个变量 T3 的功能》(1957 年),苏联科学院报告 114:679–681。

[12] H. D. Block,《国际法院案例汇编:国际法院案例汇编》

[13]《化学武器公约》第一. 3.5 条。

[14] S.-I. Amari,允许和检测不变信号变换的特征空间 (1978),模式识别联合会议。

[15] T. Sejnowski 等人,学习具有隐藏单元的对称群:超越感知器(1986),Physica D:非线性现象 22(1–3):260–275。

[16] J. Shawe-Taylor,将对称性纳入前馈网络(1989),ICANN。

[17] J. Shawe-Taylor,前馈网络结构中的对称性和可区分性(1993),IEEE Trans .神经网络 4(5):816–826。

[18] G. Cybenko,通过叠加 s 形函数的近似法 (1989),控制、信号和系统数学 2(4):303–314。

[19] K. Hornik,多层前馈网络的逼近能力 (1991)神经网络 4(2):251–257。

[20] А.Г.Ивахненко, В.Г.кибернетическиепредсказывающие(1965 年)。

[21] A. Ivakhnenko,复杂系统的多项式理论 (1971),IEEE Trans .系统、人和控制论 4:364–378。

[22]反向传播基于微分的链式法则,该法则本身可追溯到 1676 年微分学的共同发明者戈特弗里德·威廉·冯·莱布尼茨。H. J. Kelley 在《最佳飞行轨迹的梯度理论》( 1960 年)Ars Journal 30(10):947-954 中使用了反向传播的一个先驱,来完成复杂非线性多级系统的优化。在赫尔辛基大学 S. Linnainmaa 的芬兰硕士论文algorit min kumulativiinen pyoristysvirhe yksittaisten pyoristysvirheiden Taylor-kehitelmana(1970)中描述了今天仍在使用的有效反向传播。在神经网络中的最早使用是由于 P. J. Werbos,非线性灵敏度分析的进展的应用(1982),系统建模和优化762–770,Springer,这通常被引用为该方法的起源。参见 J. Schmidhuber,神经网络中的深度学习:概述 (2015),神经网络 61:85–117。

[23] D. E. Rumelhart 等人,通过反向传播误差学习表征 (1986),自然 323(6088):533–536。

[24]甚至还有连续无处可微函数的例子,如 Weierstrass (1872)的构造。

【25】粗略地说, Lipschitz-continuous 函数不会任意缩小或扩大定义域上各点之间的距离。对于可微函数,Lipschitz 连续性可以表示为梯度范数的上界,这意味着函数不会突然“跳跃”。

[26]第一个使用这个术语的是理查德·贝尔曼,他在 1957 年出版的《T4》一书的序言中称维度是“多年来笼罩在物理学家和天文学家头上的诅咒”

[27]在可观测的宇宙中,质子的数量,即所谓的爱丁顿数,是在 10⁸⁰.估算出来的

[28] J. Lighthill,人工智能:一般调查 (1973)人工智能 1–21,伦敦科学研究委员会。

罗森布拉特、明斯基和帕佩特的肖像是由伊霍尔·戈尔斯基手绘的。几何深度学习的详细讲座资料可在 项目网页 获取。参见迈克尔的 其他帖子 在走向数据科学, 订阅 到他的帖子和 YouTube 频道 ,获得 中等会员资格 ,或者关注 迈克尔 ,”

走向几何深度学习 III:第一几何架构

原文:https://towardsdatascience.com/towards-geometric-deep-learning-iii-first-geometric-architectures-d1578f4ade1f

几何深度学习的起源

几何深度学习从对称性和不变性的角度处理了一大类 ML 问题,为多种多样的神经网络架构(如 CNN、gnn 和 Transformers)提供了一个通用蓝图。在一系列新的帖子中,我们研究这些想法如何将我们从古希腊带到卷积神经网络。

图片:Shutterstock。

在“走向几何深度学习系列”的第三篇文章中,我们讨论了第一个“几何”神经网络:Neocognitron 和 CNN。这篇文章基于 M. M .布朗斯坦、j .布鲁纳、t .科恩和 p .韦利奇科维奇、 几何深度学习 (在麻省理工学院出版社完成后出现)一书的介绍章节,并伴随 我们的课程 参加非洲机器智能大师赛(AMMI)。参见 第一部分*第二部分 关于神经网络的早期历史以及第一部《艾冬》、《第四部分 献给早期的 GNNs。*

新“几何”类型的第一个神经网络架构的灵感来自神经科学。在一系列经典实验中,哈佛大学神经生理学家 David Hubel 和 Torsten Wiesel[1-2]揭示了大脑中负责模式识别的部分——视觉皮层——的结构和功能。通过向一只猫呈现变化的光模式,并测量其脑细胞(神经元)的反应,他们表明,视觉皮层中的神经元具有局部空间连接的多层结构:只有在其附近的细胞(“感受野”[3])被激活时,细胞才会产生反应。

获得诺贝尔奖的生理学家大卫·胡贝尔和托尔斯滕·威塞尔以及对他们经典实验的描述揭示了视觉皮层的结构。肖像:伊霍尔·高斯基。

此外,该组织似乎是分层的,其中'简单细胞对局部原始定向阶跃刺激的反应由'复杂细胞聚集,后者对更复杂的模式产生反应。有人假设,视觉皮层深层的细胞会对越来越复杂的由简单模式组成的模式做出反应,这半开玩笑地暗示了“T4 祖母细胞”的存在,这种细胞只有在看到祖母的脸时才会做出反应。

新克隆体

对视觉皮层结构的理解对计算机视觉和模式识别的早期工作产生了深远的影响,人们多次试图模仿它的主要成分。Kunihiko Fukushima,当时是日本广播公司的一名研究员,开发了一种新的神经网络架构[5]“类似于 Hubel 和 Wiesel 提出的视觉神经系统的层次模型”,被命名为 neocognitron [6]。

Kunihiko Fukushima 和 neocognitron,一种早期的几何深度学习架构和现代卷积神经网络的前身。

neocognitron 由交错的神经元的 C 层组成(这一命名惯例反映了它在生物视觉皮层中的灵感);每层中的神经元按照输入图像的结构(“视网膜主题”)排列成 2D 阵列,每层有多个“细胞平面”(现代术语中的特征图)。S 层被设计为翻译对称:它们使用共享的可学习权重聚集来自局部感受野的输入,导致单个细胞平面中的细胞具有相同功能的感受野,但位置不同。基本原理是挑选可能出现在输入中任何地方的模式。C 层是固定的,并执行局部汇集(加权平均),对模式的特定位置不敏感:如果其输入中的任何神经元被激活,则 C 神经元将被激活。

因为新认知的主要应用是字符识别,所以平移不变性是至关重要的。这一特性与早期的神经网络(如 Rosenblatt 的感知器)有着根本的区别:为了可靠地使用感知器,必须首先对输入模式的位置进行归一化,而在 neocognitron 中,对模式位置的不敏感性被嵌入到架构中。Neocognitron 通过将平移等变的局部特征提取层与池交错实现,创建了多尺度表示[8]。计算实验表明,福岛的建筑能够成功地识别复杂的图案,如字母或数字,即使存在噪声和几何失真。

neocognitron 输出的例子证实了它对位移、几何失真和噪声的不敏感性。图片来自[5]。

从该领域四十年进展的有利角度来看,人们发现新认知体已经具有现代深度学习架构的许多惊人特征:深度(Fukishima 在他的论文中模拟了一个七层网络)、局部感受域、共享权重和池化。它甚至使用了半整流器(ReLU)激活功能,这通常被认为是在最近的深度学习架构中引入的[9]。与现代系统的主要区别在于网络的训练方式:neocognitron 是一种以无监督方式训练的“自组织”架构,因为反向传播尚未在神经网络社区中广泛使用。

卷积神经网络

F ukushima 的设计由 Yann LeCun 进一步开发,他是巴黎大学的应届毕业生[10],博士论文是关于使用反向传播来训练神经网络。在贝尔实验室的第一个博士后岗位上,LeCun 和他的同事们建立了一个系统来识别信封上的手写数字,以使美国邮政服务能够自动发送邮件。

Yann LeCun 和合著者[11]首次引入卷积神经网络(尽管“卷积”这个名称后来才出现)。在 DSP 上实现,它允许实时手写数字识别。

在一篇现在已经很经典的论文[11]中,LeCun 等人描述了第一个三层卷积神经网络(CNN) [12]。与 neocognitron 类似,LeCun 的 CNN 也使用共享权重和池的本地连接。然而,它放弃了福岛更复杂的非线性滤波(抑制连接)而支持简单的线性滤波器,这种滤波器可以在数字信号处理器(DSP)上使用乘加运算有效地实现为卷积

这种设计选择,脱离了神经科学的灵感和术语,进入了信号处理领域,将在深度学习的成功中发挥至关重要的作用。CNN 的另一个关键创新是使用反向传播进行训练。

LeNet-5,五层卷积架构[14]。

LeCun 的工作令人信服地展示了基于梯度的方法在复杂模式识别任务中的强大功能,并且是首批基于深度学习的计算机视觉实用系统之一。这种架构的一个演变,一个五层的 CNN 被命名为 LeNet-5,是作者名字的双关语[14],被美国银行用来阅读手写支票。

然而,计算机视觉研究界的绝大多数人都避开了神经网络,走上了一条不同的道路。新千年第一个十年的视觉识别系统的典型架构是一个精心制作的特征提取器(通常检测图像中的兴趣点,并以一种对透视变换和对比度变化鲁棒的方式提供它们的局部描述[15]),然后是一个简单的分类器(最常见的是支持向量机(SVM),较少见的是一个小型神经网络)[16]。

2000 年代的典型“单词袋”图像识别系统[16],由一个局部特征检测器和描述符组成,后跟一个简单的分类器。

深度学习的胜利

然而,计算能力的快速增长和可用的带注释的可视数据的数量改变了力量的平衡。实现和训练越来越大和越来越复杂的 CNN 成为可能,这允许处理越来越具有挑战性的视觉模式识别任务[17],最终成为当时计算机视觉的圣杯:ImageNet 大规模视觉识别挑战。ImageNet 由美籍华人研究员费于 2009 年建立,是一项年度挑战,包括将数百万张人类标记的图像分类到 1000 个不同的类别。

ImageNet 大规模视觉识别挑战的结果。AlexNet 在 2012 年成为第一个击败“手工制作”方法的深度学习架构;从那以后,所有的获胜方法都是基于深度学习的。

Krizhevsky、Sutskever 和 Hinton [18]在多伦多大学开发的 CNN 架构成功地以较大优势击败了所有竞争方法,如基于该领域数十年研究的智能设计的特征检测器。AlexNet(这种架构是为了纪念其开发者 Alex Krizhevsky 而命名的)在参数和层数方面比它的老兄弟 LeNet-5 大得多[20],但在概念上是相同的。关键的区别是使用图形处理器(GPU)进行训练[21],这是现在深度学习的主流硬件平台[22]。

AlexNet 架构。图片:巴维什·辛格·毕斯特

TCNN 在 ImageNet 上的成功成为深度学习的转折点,并预示着它在接下来的十年中被广泛接受。数十亿美元的产业应运而生,深度学习成功用于商业系统,从苹果 iPhone 的语音识别到特斯拉的自动驾驶汽车。在对罗森布拉特的作品进行严厉评论四十多年后,联结主义者终于被证明是正确的。

[1] D. H. Hubel 和 T. N. Wiesel,猫的纹状皮层中单个神经元的感受野(1959),生理学杂志 148(3):574。

[2] D. H. Hubel 和 T. N. Wiesel,猫的视觉皮层中的感受野、双眼互动和功能性结构(1962),生理学杂志 160(1):106。

[3]术语“感受野”出现在 Hubel 和 Wiesel 之前,并且从二十世纪早期就被神经生理学家使用,参见 c .谢灵顿,神经系统的整合作用* (1906),耶鲁大学出版社。*

[4]“祖母细胞”这个术语很可能第一次出现在杰里·莱特文于 1969 年在麻省理工学院讲授的“感知和知识的生物学基础”课程中。类似的“诺斯替神经元”的概念在两年前由波兰神经科学家 J. Konorski 所著的《大脑的整合活动》一书中提出;跨学科方法 (1967)。参见 C. G. Gross,“祖母细胞”的谱系学 (2002),《神经科学家》8(5):512–518。

[5] K. Fukushima, Neocognitron:不受位置变化影响的模式识别机制的自组织神经网络模型 (1980),生物控制论 36:196–202。标题中提到了平移不变性。

[6]经常被拼错为“ neuro cognitron”,名称“neocognitron”表明它是 K. Fukushima 的早期架构的改进版本,Cognitron: a self-organizing 多层神经网络(1975),生物控制论 20:121–136。

[7]用作者自己的话来说,具有“仅取决于刺激模式的形状,而不受模式呈现位置的影响”的输出

[8]我们称这个原理为尺度分离,它和对称性一样,是许多物理系统的基本属性在卷积架构中,除了平移之外,尺度分离还允许处理更广泛的几何变换。

[9] ReLU 型激活至少可以追溯到 20 世纪 60 年代,之前已经在 K. Fukushima 的模拟阈值元件多层网络的视觉特征提取(1969)中使用过。系统科学和控制论 5(4):322–333。

[10]皮埃尔-玛丽-居里大学,现为索邦大学的一部分。

[11] Y. LeCun 等人,应用于手写邮政编码识别的反向传播(1989)神经计算 1(4):541–551。

[12]在 le Cun 1989 年的论文中,架构没有被命名;术语“卷积神经网络”或“convnet”将出现在 1998 年的一篇论文中[14]。

[13] LeCun 的第一个 CNN 是在一个 CPU(一个 SUN-4/250 机器)上训练出来的。然而,使用经过训练的 CNN 的图像识别系统在美国电话电报公司 DSP-32C(具有 256KB 存储器的第二代数字信号处理器,能够以 32 位精度每秒执行 125m 浮点乘加运算)上运行,每秒实现 30 次以上的分类。

[14] Y. LeCun 等人,基于梯度的学习应用于文档识别(1998),Proc .IEEE 86(11):2278–2324。

[15]最流行的特征描述符之一是由 David Lowe 于 1999 年提出的尺度不变特征变换 (SIFT)。这篇论文被多次拒绝,仅在五年后发表,D. G. Lowe,比例不变关键点的独特图像特征,(2004)IJCV 60(2):91–110。这是被引用最多的计算机视觉论文之一。

[16]一种典型的方法是“单词袋”,将图像表示为矢量量化的局部描述符的直方图。例如,参见 J. Sivic 和 A. Zisserman,视频谷歌:视频中对象匹配的文本检索方法(2003),ICCV。

[17]特别是,Jürgen Schmidhuber 的小组开发的深度大规模 CNN 模型赢得了多个视觉比赛,包括汉字识别(D. C. Ciresan 等人,用于手写数字识别的深度大简单神经网络(2010),神经计算 22(12):3207–3220)和交通标志识别(D. C. Ciresan 等人,用于交通标志分类的多列深度神经网络。神经网络32:333–338,2012)。

[18] A. Krizhevsky、I. Sutskever 和 G. E. Hinton,使用深度卷积神经网络的 ImageNet 分类(2012 年),NIPS。

[19] AlexNet 取得了比亚军小 10.8%以上的误差。

[20] AlexNet 有 11 层,在来自 ImageNet 的 1.2M 图像上进行训练(作为比较,LeNet-5 有 5 层,在 60K MNIST 数字上进行训练)。与 LeNet-5 相比,其他重要变化包括使用 ReLU 激活(代替 tanh)、最大汇集、退出规则和数据扩充。

[21]在一对 Nvidia GTX 580 图形处理器上训练 AlexNet 花了将近一周的时间,每秒能够进行大约 200G 的浮点运算。

[22]尽管 GPU 最初是为图形应用程序设计的,但它们最终成为了一个方便的硬件平台,用于通用计算(“gp GPU”)。第一个这样的作品展示了线性代数算法,例如参见 J. Krüger 和 R. Westermann 的《用于数值算法的 GPU 实现的线性代数算子》(2003),ACM Trans。图形 22(3):908–916。GPU 首次用于神经网络是由 K.-S. Oh 和 K. Jung,神经网络的 GPU 实现(2004),模式识别 37(6):1311–1314,比 AlexNet 早了近十年。

福岛的肖像是由伊霍尔·戈尔斯基手绘的。几何深度学习的详细讲座资料可在 项目网页 获取。参见迈克尔的 其他帖子 在走向数据科学, 订阅 到他的帖子和 YouTube 频道 ,获取 中等会员 ,或者关注 迈克尔

走向几何深度学习 IV:GNNs 的化学前体

原文:https://towardsdatascience.com/towards-geometric-deep-learning-iv-chemical-precursors-of-gnns-11273d74125

几何深度学习的起源

几何深度学习从对称性和不变性的角度处理一大类 ML 问题,为神经网络体系结构的“动物园”提供了一个公共蓝图。在我们关于几何深度学习起源系列的最后一篇文章中,我们看了图形神经网络的前身。

图片:Shutterstock。

在“走向几何深度学习”系列的最后一篇文章中,我们讨论了 20 世纪 60 年代化学领域中 gnn 的早期原型是如何出现的。这篇文章基于 M. M .布朗斯坦、j .布鲁纳、t .科恩和 p .韦利奇科维奇、 几何深度学习 (在麻省理工学院出版社完成后出现)一书的介绍章节,并伴随 我们的课程 参加非洲机器智能大师赛(AMMI)。参见 第一部分 讨论对称性, 第二部分 关于神经网络的早期历史和第一个“艾冬”,以及 第三部分 研究第一个“几何”架构。

如果说对称的历史与物理学紧密交织在一起,那么图形神经网络的历史,几何深度学习的“海报儿童”,则植根于自然科学的另一个分支:化学。

化学在历史上一直是(现在仍然是)数据最密集的学科之一。18 世纪现代化学的出现导致了已知化合物的快速增长和对其组织的早期需求。这一角色最初是由期刊扮演的,如《化学文摘》(Chemisches zentral blatt)[1]和《化学词典》(chemical dictionaries),如Gmelins Handbuch der anorganischen Chemie(1817 年首次出版的无机化合物早期简编[2])和Beilsteins Handbuch der organischen Chemie(有机化学的类似努力),所有这些最初都以德语出版,直到 20 世纪初,德语一直是科学界的主导语言。

在英语世界中,化学文摘社(CAS)创建于 1907 年,并逐渐成为世界上已发表的化学信息的中心储存库[3]。然而,庞大的数据量(仅 beil stein 一项就增长到 500 多卷,近 50 万页)很快就使得打印和使用这样的化学数据库变得不切实际。

格林无机化学手册卷,一个两个世纪前首次出版的早期化学数据库。在数字计算机开发之前,化学家必须手工搜索这种数据库,这个过程可能需要几个小时甚至几天。

落进草垛里的一根针(指:几乎不可能找到的东西)

自十九世纪中期以来,化学家们已经建立了一种普遍理解的方法,通过结构式来指代化合物,表示化合物的原子、原子间的键,甚至它们的三维几何结构。但是这种结构不容易恢复。

19 世纪德国化学家奥古斯特·凯库勒提出苯(C₆H₆)的结构式,以及苯环的现代描述。根据一个传说,凯库勒的洞察力来自于一个梦,他在梦里看到一条蛇在咬自己的尾巴。

在 20 世纪上半叶,随着新发现的化合物及其商业用途的快速增长,组织、搜索和比较分子的问题变得至关重要:例如,当一家制药公司试图为一种新药申请专利时,专利局必须验证以前是否存在类似的化合物。

为了应对这一挑战,20 世纪 40 年代引入了几种分子索引系统,为后来被称为化学信息学的新学科奠定了基础。一个这样的系统,以作者 Gordon、Kendall 和 Davison [4]的名字命名为“GKD 化学密码”,由英国轮胎公司 Dunlop 开发,用于早期基于穿孔卡的计算机[5]。本质上,GKD 密码是一种将分子结构解析成字符串的算法,这种算法更容易被人类或计算机查找到。

根据不同的系统,化合物及其密码的例子。图片来自[13]。

T2:然而,GKD 密码和其他相关的方法远不能令人满意。在化合物中,相似的结构往往导致相似的性质。化学家被训练发展直觉来发现这种相似性,并在比较化合物时寻找它们。例如,在 19 世纪,苯环与散发气味的特性的联系是“芳香化合物”这一化学类别命名的原因。

另一方面,当一个分子被表示为一个字符串时(例如在 GKD 密码中),一个单一化学结构的成分可以被映射到密码的不同位置。因此,两个含有相似子结构的分子(因此可能具有相似的特性)可能以非常不同的方式编码。

乔治·vlăduţ's 1959 年论文[13]中的一张图,显示了一个化学分子及其片段以及相应的 gkd-密码。请注意,这种编码系统破坏了分子中相连原子的空间局域性,因此无法通过简单的子串匹配在完整分子中找到片段密码。早期化学表示方法的这一缺点是寻找以图形表示分子结构的动机之一。

T 他的认识鼓励了“拓扑密码”的发展,试图捕捉分子的结构。陶氏化学公司[7]和美国专利局[8]首先完成了这类工作,这两家公司都大量使用化学数据库。其中最著名的一个描述符,被称为“摩根指纹”[9],是由化学文摘社的哈里·摩根[10]开发的,并一直使用到今天。

化学遇上图论

出生于罗马尼亚的苏联研究员乔治·vlăduţ[11]在开发搜索化学数据库的早期“结构”方法中发挥了关键作用。作为一名训练有素的化学家(他于 1952 年在莫斯科门捷列夫研究所捍卫了有机化学博士学位),他在大学一年级时经历了一次与庞大的《贝尔斯坦手册》的创伤性接触[12]。这将他的研究兴趣引向了化学信息学[13],这是一个他终生从事的领域。

Vlăduţ被认为是使用图论来模拟化合物的结构和反应的先驱之一。从某种意义上说,这并不令人惊讶:图论在历史上一直与化学联系在一起,甚至“图”这个术语(指的是一组节点和边,而不是一个函数的曲线)也是由数学家詹姆斯·西尔维斯特在 1878 年作为化学分子的数学抽象引入的[14]。

术语“图”(在图论中使用的意义)是由詹姆斯·西尔威斯特在 1878 年自然笔记【14】中首次作为分子模型引入的。

特别是,Vlăduţ主张把分子结构比较公式化为图形同构问题;他最著名的工作是将化学反应归类为反应物和产物分子的部分同构(最大公共子图)[15]。

Vlăduţ's 的工作启发了一对年轻的研究人员,Boris Weisfeiler(代数几何学家)和 Andrey Lehman 17。在一篇经典的联合论文[19]中,两人引入了一种迭代算法来测试一对图是否同构(即,这些图在节点重新排序之前具有相同的结构),这被称为魏斯费勒-雷曼(WL)测试 [20]。尽管两人从上学时就认识了,但他们在出版后不久就分道扬镳,并在各自的领域取得了成就[21]。

Weisfeiler 和 Lehman 最初猜想他们的算法解决了图同构问题(并在多项式时间内解决了这个问题),但这是不正确的:虽然 Lehman 通过计算证明了至多有 9 个节点的图[22],但一年后发现了一个更大的反例[23](事实上,一个未能通过 WL 测试的强正则图称为 Shrinkhande 图 甚至更早就为人所知[24])。

图同构检验是由 Andrei Lehman 和 Boris Weisfeiler 在 1968 年提出的。

Weisfeiler 和 Lehman 的论文已经成为理解图同构的基础。从历史的角度来看他们的工作,人们应该记得在 20 世纪 60 年代,复杂性理论仍然处于萌芽状态,算法图论才刚刚起步。正如雷曼在 20 世纪 90 年代末回忆的那样,

“在 60 年代,人们可以在几天内重新发现图形同构理论中的所有事实、思想和技术。我怀疑,“理论”这个词是适用的;一切都处于这样一个基本水平。”安德烈·雷曼,1999 年

他们的结果激发了许多后续工作,包括高维图形同构测试[25]。在图神经网络的背景下,Weisfeiler 和 Lehman 最近成为家喻户晓的名字,证明了他们的图同构测试等价于消息传递[26–27]。

早期图形神经网络

尽管化学家们已经使用类似 GNN 的算法几十年了,但很可能他们在分子表示方面的工作在机器学习社区中仍然几乎不为人知[28]。我们发现很难准确指出图形神经网络的概念是何时开始出现的:部分原因是大多数早期工作没有将图形作为一等公民,部分原因是图形神经网络只是在 2010 年代后期才变得实用,部分原因是该领域是从几个相邻研究领域的融合中出现的。

图形神经网络的早期形式至少可以追溯到 20 世纪 90 年代,例子包括亚历桑德罗·斯佩尔杜蒂的“标记 RAAM”[29],克里斯托弗·戈勒和安德烈亚斯·屈希勒尔的“通过结构的反向传播”[30],以及数据结构的自适应处理[31–32]。虽然这些工作主要关注的是对“结构”(通常是树或有向无环图)的操作,但在它们的架构中保留的许多不变性让人想起了今天更常用的 gnn。

走向图神经网络:从 20 世纪 90 年代开始的早期工作集中在一般结构的学习上,例如树或有向无环图。术语“图形神经网络”是在 Marco Gori 和 Franco Scarselli 的经典论文中引入的。

T 在 21 世纪之交,第一次对一般图形结构的处理进行了适当的处理(并创造了术语“图形神经网络”)。由 Marco Gori [33]和 Franco Scarselli [34]领导的锡耶纳大学团队提出了第一个“GNN”他们依赖于递归机制,需要神经网络参数来指定收缩映射,从而通过搜索固定点来计算节点表示——这本身就需要一种特殊形式的反向传播,并且完全不依赖于节点特征。所有上述问题都通过李[35]的门控 GNN (GGNN)模型进行了纠正,该模型带来了现代 RNNs 的许多好处,例如门控机制[36]和通过时间的反向传播。

Alessio Micheli 在同一时间提出的图形神经网络(NN4G)使用前馈而不是递归架构,实际上更像现代的 GNNs。

作者与 GNN 先锋马可·哥里和亚历桑德罗·斯佩尔杜蒂在 WCCI 2022。

另一类重要的图形神经网络,通常被称为“谱神经网络”,是由琼·布鲁纳和合著者[38]使用图形傅立叶变换的概念而产生的。这种结构的根源在于信号处理和计算谐波分析社区,在 2000 年代末和 2010 年代初,处理非欧几里德信号变得非常重要[39]。

来自 Pierre Vandergheynst [40]和 José Moura [41]团队的有影响力的论文普及了“图形信号处理”(GSP)的概念,以及基于图形邻接和拉普拉斯矩阵的特征向量的傅立叶变换的一般化。Michal Defferrard[42]和 Thomas Kipf 和 Max Welling [43]提出的依赖于光谱滤波器的图形卷积神经网络是该领域引用最多的网络。

回到原点

在一个有点讽刺意味的命运转折中,现代 gnn 被 David Duvenaud [44]作为手工制作的 Morgan 分子指纹的替代物,被 Justin Gilmer [45]以相当于 Weisfeiler-Lehman 测试[26–27]的信息传递神经网络的形式,成功地重新引入了它们起源的化学领域。五十年后,圆圈终于闭合。

随着大卫·杜文瑙德和贾斯汀·吉尔默的工作,现代版的图形神经网络成功地回到了化学领域。

图形神经网络现在是化学领域的标准工具,已经看到了在药物发现和设计管道中的应用。2020 年,GNN 发现了新的抗生素化合物[46],赢得了一项引人注目的荣誉。DeepMind 的 AlphaFold 2 [47]使用等变注意力(一种 GNN 形式,用于解释原子坐标的连续对称性)来解决结构生物学的“圣杯”——蛋白质折叠的问题。

1999 年,安德烈·雷曼写信给一位数学家同事说,他“很高兴得知‘魏斯费勒-莱曼’已经出名,并且仍然引起人们的兴趣。”基于他 50 年前的工作,他没能活着看到 GNNs 的崛起。乔治 Vlăduţ也没有看到他的想法的实现,在他有生之年,许多想法还停留在纸上。我们确信他们会为站在这个令人兴奋的新领域的起点而感到自豪。

[1]最初是Pharmaceutisches Central-Blatt,是 1830 年至 1969 年间出版的最古老的德国化学文摘期刊。

[2]以 1817 年出版第一版的利奥波德·格麦林命名的,格林斯手册最后一版出现在 20 世纪 90 年代。该数据库目前包含 1772 年至 1995 年间发现的 150 万种化合物和 130 万种不同的反应。

[3]1906 年,美国化学学会授权出版《化学文摘》,赋予它摘录世界化学文献的使命,并分配了一万五千美元的初期预算。在威廉·诺伊斯的指导下,第一份出版物于 1907 年出版。自成立以来的一个多世纪里,化学文摘社收录了自 19 世纪初以来出版物中披露的近 2 亿种有机和无机物质。

[4] M. Gordon,C. E. Kendall 和 W. H. T. Davison,化学加密:作为化学系统学辅助的通用代码 (1948),皇家化学研究所。

[5]Gordon-Kendall-Davison 小组结合他们的化学加密系统,提出了一种与穿孔卡片分类器一起使用的专用计算机(“电子结构相关器”),但从未建成。

[6]有几个同时代的系统相互竞争,参见 W. J. Wisswesser, 107 年的线公式符号 (1968),j . Chemical Documentation 8(3):146–150。

[7] A. Opler 和 T. R. Norton,一本为用于搜索有机化合物的机械化系统的计算机编程的手册 (1956),陶氏化学公司。

[8] L. C. Ray 和 R. A. Kirsch,通过数字计算机发现化学记录(1957 年),《科学》126 期(3278):814-819。

H. L .摩根。化学结构的独特机器描述的生成——化学文摘服务(1965)开发的技术,化学文献 5(2):107–113。

[10]关于哈里·摩根的传记资料不多。根据一则讣告,在发表了他著名的分子指纹论文后,他进入了 IBM 的管理层,并在那里一直呆到 1993 年退休。他于 2007 年去世。

[11]在俄文出版物中,Vlăduţ's 的名字以георгийэмильевичвлэдуц出现,音译为 VledutsVladutz 。我们坚持使用原始的罗马尼亚语拼写。

[12]据弗拉迪米尔·乌斯彭斯基说,Vlăduţ在美国化学学会接受帕特森-克莱恩奖的演讲中,讲述了他在大学有机化学的第一堂课上与贝尔斯坦相遇的轶事。参见в。А.труды(2002 年)。

[13] Г.Э.Влэдуц, В.В.Налимов, Н.И.стяжкин,научнаятехническаяинформациякакоднаиззадачкибеиинетикии(1959),уппехифизическихнаук69:1。

[14] J. J. Sylvester,化学和代数(1878),自然 17:284。

[15] G. E. Vleduts,关于有机反应的一个分类和编码系统(1963),信息存储和检索 1:117-146。

[16]我们找不到确凿的证据证明魏斯费勒和雷曼兄弟是否以及如何与 Vlăduţ有过互动,因为大多数认识他们的人都已经去世了。最有力的证据是他们的经典论文[19]中的一个评论,承认 Vlăduţ“阐明了问题”(“авторывыражаютблагодарностьв。Э.Влэдуцу за постановку задачи").还可以肯定的是,Weisfeiler 和 Lehman 知道化学社区开发的方法,特别是 Morgan 的方法[9],他们在论文中称 mor gan 为“类似的程序”。

[17]安德烈·雷曼的姓也经常被拼成雷曼,这是他自己更喜欢的一个变体,他在一封电子邮件中说前一种拼法来自德国出版商斯普林格的一本书,他认为“每个雷曼都是一个隐藏的雷曼”。因为雷曼自己承认他的家族有日耳曼血统,所以我们坚持用德语拼写。

[18]1971 年,Lehman 试图为一篇基于他在图形同构方面的工作的论文进行辩护,但没有成功,该论文由于论文委员会主席的个人敌意而被拒绝,并被裁定“它不是数学”对此,雷曼苦涩地回应道:“我不是数学家,我是程序员。”他最终在 1973 年为另一篇关于数据库主题的论文进行了答辩。

[19] Б.Вейсфейлер, А.каноническому、возникающая、этом(1968 年)информ.Сб.винити2(9):12–16(见英译本)。

[20]事实上,Weisfeiler-Lehman 测试有多种版本。最初的论文[19]描述了现在所谓的“2-WL 测试”,但它相当于 1-WL 或节点颜色细化算法。参见我们之前关于韦斯费勒-雷曼测试的博文

[21]由于关于我们昔日英雄的英文传记资料很少,我们将用这篇笔记来概述他们余下的职业生涯。这三个人最后都去了美国。乔治·vlăduţ在 1974 年申请移民,这让他的老板们感到震惊,并导致他从实验室负责人的职位上被降级(在苏联,移民被认为是“不可饶恕的大罪”——对于西方人来说,现在很难想象这对苏联公民来说曾经是多么伟大的努力)。Vlăduţ离开了家庭,在费城的科学信息研究所工作,直到 1990 年去世。作为犹太裔,鲍里斯·魏斯费勒(Boris Weisfeiler)在 1975 年决定移民,因为苏联官方的反犹主义日益严重——最后一步是拒绝出版他广泛研究的专著,因为太多作者有“非俄罗斯姓氏”。在普林斯顿高等研究院短暂停留后,他成为宾夕法尼亚州立大学的教授,从事代数几何的研究。作为一名狂热的登山爱好者,他于 1985 年在智利的一次徒步旅行中失踪。安德烈·雷曼于 1990 年离开苏联,随后在多家美国初创公司担任程序员。他于 2012 年去世(见谢尔盖·伊万诺夫的帖子)。

[22] А.некоторых(1970 年)

[23] G. M. Adelson-Velski 等人,没有自同构的传递群的图的例子(1969),Dokl。阿卡德。瑙克 185:975–976。

[24] S. S. Shrikhande,L₂协会方案的独特性(1959),数理统计年鉴 30:781-798。

[25] L. Babai,拟多项式时间内的图同构 (2015),arXiv:1512.03547。

[26]徐国光等,图神经网络有多强大? (2019),ICLR。

[27] C. Morris 等人, Weisfeiler 和 Leman go neural:高阶图神经网络 (2019),AAAI。

[28]在化学团体中,许多工作提出了类似 GNN 的模型,包括 D. B .基列耶夫,化学网络:一种新的基于神经网络的图形/属性映射方法(1995),化学信息和计算机科学杂志 35(2):175-180;巴斯金、帕尤林和泽菲洛夫。用于搜索化合物的结构和性质之间的直接相关性的神经装置(1997),化学信息和计算机科学杂志 37(4):715–721;以及 C. Merkwirth 和 T. Lengauer。用分子图网络自动生成互补描述符(2005),化学信息与建模杂志,45(5):1159–1168。

[29] A. Sperduti,通过标记 RAAM 编码标记图(1994),NIPS。

[30] C. Goller 和 A. Kuchler,通过结构反向传播学习任务相关的分布式表示(1996),ICNN。

31 a . sper duti 和 A. Starita。用于结构分类的监督神经网络(1997),IEEE Trans。神经网络 8(3):714–735。

[32] P. Frasconi、M. Gori 和 A. Sperduti,《数据结构自适应处理的一般框架》( 1998 年), IEEE Trans .神经网络 9(5):768–786。

[33] M. Gori、G. Monfardini 和 F. Scarselli,一种在图域中学习的新模型 (2005),IJCNN。

[34] F. Scarselli 等,图神经网络模型 (2008),IEEE Trans .神经网络 20(1):61–80。

[35] Y. Li 等,门控图序列神经网络 (2016).

[36] K. Cho 等人,使用用于统计机器翻译的 RNN 编码器-解码器学习短语表示(2014),arXiv:1406.1078。

[37] A. Micheli,图的神经网络:一种上下文构建方法 (2009),IEEE Trans .神经网络 20(3):498–511。

[38] J .布鲁纳等人,图的谱网络和局部连接网络 (2014),ICLR。

[39]值得注意的是,在计算机图形和几何处理领域,非欧几里得调和分析比图形信号处理至少早了十年。我们可以将流形和网格上的谱滤波器追溯到 G. Taubin、T. Zhang 和 G. Golub 的工作,(1996),ECCV。在 Z. Karni 和 C. Gotsman 的有影响力的论文网格几何图形的光谱压缩 (2000 年)、计算机图形和交互技术以及 B. Lévy 的拉普拉斯-贝尔特拉米本征函数朝向“理解”几何图形的算法 (2006 年)、形状建模和应用之后,这些方法在 21 世纪成为主流。

[40] D. I .舒曼等人,图中信号处理的新兴领域:将高维数据分析扩展到网络和其他不规则领域 (2013),IEEE 信号处理杂志 30(3):83–98。

[41] A. Sandryhaila 和 J. M. F. Moura,图形上的离散信号处理 (2013),IEEE Trans .信号处理 61(7):1644–1656。

[42] M. Defferrard、X. Bresson 和 P. Vandergheynst,具有快速局部频谱过滤的图上的卷积神经网络 (2016),NIPS。

[43] T. Kipf 和 M. Welling,使用图卷积网络的半监督分类 (2017),ICLR。

[44] D. K. Duvenaud 等人,用于学习分子指纹的图上的卷积网络 (2015),NIPS。

[45] J. Gilmer 等人,量子化学的神经信息传递 (2017),ICML。

[46] J. M. Stokes 等人,抗生素发现的深度学习方法 (2020)《细胞》180(4):688–702。

[47] J. Jumper 等人,用 AlphaFold 进行高度精确的蛋白质结构预测,Nature 596:583–589,2021。

这些肖像是由 Ihor Gorskiy 手绘的。我们感谢米哈伊尔·克林的历史评论,也感谢塞尔日·vlăduţ提供了他父亲的照片。几何深度学习的详细讲座资料可在 项目网页 上获取。参见迈克尔的 其他帖子 在走向数据科学, 订阅 到他的帖子和 YouTube 频道 ,获取 中等会员 ,或者关注 迈克尔

走向类人人工智能

原文:https://towardsdatascience.com/towards-human-like-ai-e1f448bd0733

试图用类似人类的能力和 GPT 使人工智能更通用

OpenAI 的 DALL-E 2 生成的图像,描绘了一个类似人类的 AI 和一些人类。图片由作者和 DALL-E 2 提供

概观

到目前为止,人类是宇宙中发现的唯一具有一般智能的例子。使用人类作为一般智能的存在证据,对于第一代人工一般智能来说,将有点像人类的系统作为目标似乎是一个合理的目标。人工一般智能不一定要像人类一样,但像人类一样的人工一般智能应该是可能的,这似乎是合理的,因为我们是可能的。

现在,似乎有史以来第一次有可能在软件中构建一个代理,展示出貌似真实的人类行为。在从 OpenAI 的 GPT 进展到 DeepMind 的最先进的 T2 强化学习方法之间,我们现在看到了在长期以来被认为是人类特有的领域中类似人类行为的证据。很难说我们第一次观察到了人工智能在长期以来被认为很难(如果不是不可能的话)实现的基准测试中的超人表现。这些领域不仅包括像围棋、星际争霸和 DOTA 2 这样复杂游戏中的表现,还包括像人类语言编程艺术这样的创造性领域。

这些模型中的每一个,虽然在特定领域取得了超人的成果,但它们本身无法实现人类一般能够做到的事情。然而,很明显,通过将这些特定的能力包装在一个更通用、更简单的控制框架中,一个智能体可以实现一些通用的类人行为。在这里,我想分享一个这样的控制框架的一些进展,我相信它显示了新颖的通用性和类似人类的智能体通过持续的反馈和与其环境的交互以在线方式学习的能力。这个框架考虑了一些类似人类的能力,这些能力对于一般的智能代理来说似乎很重要;例如构建和延续一系列思维的能力,从反馈中学习,保持和利用长期记忆,并根据从与人类和其他人工智能代理的互动中获得的知识,发展良知来判断和控制自己的行动。

通过整合使用反馈进行改进的能力,行动的有效性可以随着时间的推移而提高,并且代理的行动与反馈的一致性也可以随着时间的推移而提高。这意味着代理应该开始采取与提供反馈的人一致的行动,因为孩子学会采取与从父母和其他人那里收到的反馈一致的行动。通过引入良知,代理人可以学习如何提供自己的反馈,并在无人监督的情况下自我管理自己的调整,就像孩子随着时间的推移学习内化对自己行为的判断和管理一样。通常,强化学习代理以可能结果树的形式预测未来可能发生的事情,并使用树搜索算法沿着该树选择下一个最佳行动(通常使用蒙特卡罗树搜索)。通过保持向后延伸一段时间的思路,我们也可以将反馈应用于思考过程,教导代理进行规划,而不明确包括预测机制和未来状态树搜索,以隐式改进短期内的规划。这种感觉更像是人类的天性——我似乎不会预测给定数量的时间步长的所有未来状态,也不会选择最高价值的路径,从我的经验来看,我似乎有一些想法,并根据最近的想法和环境背景凭直觉采取行动(隐含的训练时间偏差,根据先前的反馈建立)。

此外,在未来的迭代中引入一些超人的能力似乎是合理的,包括智能体根据高等数学进行思考和推理的能力;从精神上看,是动态编程的结果;在因特网上搜索当前事件的背景;和 API 集成。

当前版本已经内置了几个超人的能力:

  1. 能够使用 GPT-3 在精神上参考人类书面知识的整个历史,这已经在整个互联网和
  2. 书面语言和代码之间的一般翻译,也使用 GPT-3

看起来很重要的人的能力

以下人员能力包含在当前的实施框架中,除非另外标注为“未来工作”:

解读环境

-解读内部环境

  1. 思想
  2. 记忆

-翻译书面或口头交流

  1. 解释直接反馈
  2. 解释环境的其他方面(未来工作)

采取行动

-作用于外部环境

  1. 通过书面语言或演讲进行交流
  2. 通过额外模式采取的其他环境行动(未来工作)

-作用于内部环境

  1. 产生想法
  2. 产生自我反馈(良心)

学习

  1. 对反馈的短期反应
  2. 从反馈中进行长期学习,以提高能力和规划
  3. 从反馈中进行长期学习,以调整良知

履行

为了实现这些功能,有必要为代理建立一个接口,以便与能够与代理对话并提供反馈的一个人或一组人进行交互。Slack 提供了一种与编程代理进行对话的简单方法,并被选择用于这个初始实现。此外,从头开始建立一个数据模型来表示每个过程的工件也很重要,这样它们就可以被控制框架操作和使用。

数据模型

输入

思绪

谨慎的想法由一个字符串表示,表示内部反映,在生产版本中,不会与和模型交谈的人共享。这些是人类内部思想的代表。

消息在

从对话中收到的消息表示为谨慎的字符串。

反馈于

反馈直接通过 Slack 中的表情符号给出。一个映射字典将每个表情符号映射到一个介于-1 和 1 之间的浮点值,以分别反映消极和积极的程度。

自我反馈

自我反馈由介于-1 和 1 之间的浮点值表示,分别反映消极和积极的程度。该值既是自己生成的输出,也用作其他创成式模型的输入。

输出

想法 —字符串,如上

Messages out —字符串,如上所述,当什么都不说是合适的时候可为空

自反馈 —浮动,如上

代表时间

短期记忆和反应

对于这些数据对象中的每一个,重要的是维护 n 个步骤的历史,其中 n 是可配置的。这里我维护了 n 个元素的列表来表示最近的 n 个想法、记忆、信息输入、信息输出、反馈和自我反馈。这些短期记忆代表最后 n 步的状态,并被用作模型在唤醒循环期间的每个时间步产生思想、信息和自我反馈的提示,如下图所示。

长期记忆和学习

当收到积极的反馈时,储存短期记忆是很重要的,这样信息创建和思想产生的模型可以改进,以更好地与反馈保持一致,并随着时间的推移变得更有能力。这种改进是通过在睡眠循环中微调相应的模型来实现的。

当自反馈在数学上接近接收到的反馈时,通过将短期记忆转储到一个文件来存储状态以微调自反馈模型,以便自反馈模型可以在睡眠循环期间微调,如下面的架构图所示。随着模型的成熟,反馈和自我反馈之间的“亲密度”阈值(这表明是时候储存长期记忆以进行微调)应该增加,这似乎很重要,就像当孩子长大时,他们开始在自己的良心中建立更多的信心和一致性,并且更难通过外部影响来改变。例如,在晚年比早年改变一个微调过的良心需要更多的例子。

下面概述的控制框架使用这些工件在唤醒循环期间反映和行动,并在睡眠循环期间微调模型。

控制框架

在每个时间步,代理通过 Slack API 获得新的消息和反馈,并从内存中读取自己的内部状态。

使用这些变量,代理调用三个微调的 GPT 模型来产生自我反馈、一个想法和一个行动(消息)。如果反馈对于短期记忆中的多个最近状态是非常负面或正面的,代理可以调整模型的默认温度,以更自由地探索随机响应或坚持每个模型认为最好的。这反映了当时人们对重复极端反馈的反应方式。

当收到积极反馈时,代理将当前状态存储到思想和行动转换器的长期训练文件中。当自反馈接近反馈时,代理将当前状态存储到自反馈(良心)转换器的长期训练文件中。

在睡眠循环期间,代理使用保存的长期记忆微调其所有的变压器。

该框架如下所示:

一个类似人类的人工智能系统的控制框架的结构图。作者图片

建立实验的一个挑战是冷启动问题。为了让代理不随机执行,我创建了一些手写状态,用作每个 transformer 模型的少量提示,直到存储了足够的长期内存来进行微调。这些为数不多的例子严重偏离了系统,应该在未来的迭代中进一步研究和优化。

早期结果

在捕捉重复响应并降低其可能性之前,在 Slack 中与 AI 系统进行对话(右)。这些可以通过足够多的例子训练出来,但是在这个版本中是显式处理的。进入人工智能系统操作的窗口(左)。think_prompt 代表 AI 在产生想法时所反映的内容,其中各种字符串的列表代表 n 个时间步长的体验,其中 len(list) = n. L 代表倾听,s 代表说,t 代表思考,f 代表反馈,sf 代表自我反馈。后来,我尝试改变这些列表标签,将它们扩展为完整的字符串“listened”、“thought”等,以便为 GPT-3 模型提供更多关于这些项目所代表的内容的上下文,这无疑提高了性能。作者图片

与 Slack 中的 AI 系统的对话(右),在为训练/思维链调整最大短期记忆之后。这里最大短期思维记忆= 6。反馈通过 Slack 表情符号提供给系统,这些表情符号被解析为 reaction_sum 浮动,范围为-1 到 1。一个进入人工智能系统操作的窗口(左),不太详细地打印了人工智能系统的思维状态。reaction_sum 表示在 AI 系统发送给用户的最后一条消息上收到的反馈,如果提供的话。作者图片

AI 系统的典型对话,2022 年 11 月初。作者图片

2022 年 11 月初,两个这样的代理相互讨论质数。作者图片

两个这样的代理人(试图)讨论意识,2022 年 11 月初。作者图片

两个这样的代理人讨论他们将如何帮助人类,2022 年 12 月。这些版本与上述示例的不同之处在于,在 2022 年 11 月下旬可用之后,它们使用了 text-davinci-003。作者图片

在对这个框架进行了几个月的试验之后,有一些关键的发现似乎挑战了一些最初的假设:

引入独立的思想流可能会对结果不利

在对思想流回顾范围、模型温度和少量例子进行多次排列后,当使用长的思想流时,产生的消息似乎比使用任意短的思想流时质量更差,尽管这需要更多的实验和良好的基准。直觉上这是有意义的,因为在互联网上训练的 GPT 在他们说或写一些东西之前,不会有很多关于人类在想什么的训练例子(至少在像这样的直接访问格式中)。我需要重新思考思想被整合的方式,或者它们是否可以被完全移除。也许思维是智力的一种自然属性,不需要明确地包括在内。

通过微调对长期记忆产生影响需要很长时间,或者至少有很多例子

对于对模型产生影响的微调示例,似乎需要成千上万个示例来真正移动指针,事实上,在命令行中,我收到了一个响应,询问我是否确定要进行微调,因为我的示例数量非常少。这种类型的量在代理的长生命周期中似乎是有用的——当人类从父母和周围的人那里学习时,他们肯定积累了数万个以上的例子。在短期内,除了微调方法之外,包含一个更明确的长期记忆存储和搜索模块似乎是有先见之明的,可以使代理更快地获得所学的东西。

将输入格式化为字符串列表似乎不如将它们格式化为脚本有用

网上有很多很好的例子,关于脚本式对话的少量训练可以带来很好的对话效果。至少在目前的状态下,GPT-3 似乎不太擅长从我作为例子和提示使用的字符串列表中推断类似脚本的结构。这些应该被转换成更自然的东西,可以在网上的训练数据中找到,比如对话的脚本。在使用 text-davinci-003 进行测试后,即使使用字符串列表方法,性能似乎也有所提高。

一般性和基准

共性

这个框架似乎可以通过长期记忆和良心模块进行一般性学习和调整,良心模块利用了一种形式的递归奖励模型。如果人类与它互动,它将学会做更多的事情,就像那些人类提供积极反馈的事情一样,还会建立自己的内在良知,随着时间的推移进行自我管理。其他输入和动作模式也应该在这个框架内工作,所以它不需要仅限于语音和思想。

基准

评估通用性的伟大基准并不多。传统的图灵测试在当时是有远见的,但是对于有用性来说是相当模糊的。雷·库兹韦尔提出了一个更严格的图灵测试版本。还不清楚用什么作为这类代理的基准。这个地区需要进一步勘探和开发。

下一次迭代的进一步研究

在下一次迭代中,我将结合我从这次尝试中获得的经验:

  1. 潜在地将思想流作为状态的管理部分移除,并假设只要我在状态中保留其他短期时间上下文元素(说、听、反馈、自我反馈),它对于短期计划是紧急的。
  2. 在推理时增加显式的长时记忆搜索。
  3. 可能将输入格式化为更自然的对话脚本,更典型地为 GPT 在互联网上遇到的训练数据。

此外,我计划添加一些额外的有用的背景模块。已经有一些很好的例子将数学模块、网络搜索、python 解释器和 API 集成独立地结合在一起(对于任意的 API 集成,有 Dust & Adept ,对于谷歌搜索,有 Ofir Press ,对于 Python 解释器和数学,有 Sergey Karayev ),但是我还没有看到一个代理将它们一起使用。给这个代理工具来扩展它的能力似乎是有用的,就像随着人类的成长,我们可以获得更多的工具来扩展我们与世界的交互界面并获得更多的知识。Andrej Karpathy 称之为给代理“小发明和小工具”以更好地与世界互动,因为它改变了 GPT 训练的静态,我认为这是一个优雅的类比。

我预测 GPT 4 号将会有许多开箱即用的小发明和小玩意。我的最佳猜测是,通过正在进行的良心构建进行在线比对仍然有用,即使我可以将 GPT-3 API 调用替换为 GPT-4 调用。

一些额外的探索领域

  • 人类作为随机代理的想法是来自几代人的反馈的集合,从一代到下一代有模糊的反馈传递,通过 DNA 通过大脑的初始权重传递。我们能否提供一种机制,将反馈从一代 AGI 人更有效、更直接地传递给下一代?
  • 多智能体繁殖有用吗?我们是否应该混合多个代理人的长期记忆来微调“后代”?
  • 探索死亡和失去特工——你如何决定哪些特工的长期记忆进入下一代特工?
  • 在繁殖过程中,你实际上是如何混合来自多个代理的长期记忆的?也许我们可以探索总共只取 n 个长期记忆的例子,通过随机循环选择记忆,为每一个新的世代附加来自父母代理的记忆,用于遗传混合。
  • 我们会在繁殖步骤中引入突变吗,就像在自然界中发现的那样?我们应该用 GPT 的说法改变记忆的子集吗?
  • 我们什么时候开始通过耳语、触摸、味觉和嗅觉向文本添加额外的形式,如音频、音频语音?
  • 最终,我们可能应该直接训练奖励函数,而不是微调,这可能比微调更有效,但成本更高。
  • 我们可能应该从人类对话中挖掘比我在这里使用的手写例子更好的初始化状态。
  • 我们可能应该使用best-of-n从 GPT 那里得到多个回应,然后使用自我反馈/良知为每个行动步骤选择最佳结果。这将允许代理实时自治。
  • 我们应该在睡眠循环中改变长期记忆(有点像做梦)来为计划创造更合理的路径吗?微调时,我们是否应该低估变异的记忆与真实的记忆?
  • 是否应该引入超人的视觉插值/想象/搜索(通过 DALL-E 或其他扩散模型)?
  • 我们是否应该在微调框架中引入一种版本的间隔重复——我们在训练数据中以越来越大的间隔重复长期记忆的精确副本或变体——来探索这种对人类有用的学习类型是否也能对 GPT 有用?
  • 我们是否应该将非自我主体和人类的名字以及他们的信息引入到数据框架中,以便行动和回忆可以与那些具体参与对话的人相关联?

关于 ChatGPT 的最后一点说明

我从大学时代开始就对人工智能充满热情,当时我学习计算机科学,但自 2010 年以来,我没有在该领域以任何正式或有偿的身份工作过。我尽最大努力跟上我觉得有趣的论文和研究人员,以及看起来新颖和有创意的概念。我做了大量的思想实验,从以太中提炼出一些关于 AGI 的原则性思想,甚至写了几行代码——如上所述。所有这些都是在深夜或清晨完成的,大多是在周末,这时家里的其他人都在睡觉。

在过去的几个月里,我有幸与 Shivon Zilis、Sam Altman、Wojciech Zaremba 和 OpenAI 的其他几个人讨论了这里讨论的一些主题和其他领域。我感谢他们的时间和谈话,特别是 Sam 在阅读了这篇文章的初稿后的积极反馈。

11 月 30 日,OpenAI 发布了 ChatGPT ,这是一个令人印象深刻的模型和聊天界面,可以通过拇指向上和拇指向下的表情符号与用户交谈并收集反馈,具有一些短期记忆,显然是跨多个领域的人类专家培训。说它很棒是一种保守的说法。虽然我确实希望我在 OpenAI 上说的或与团队分享的一些东西为这里使用的一个特性或方法提供了一些灵感,但我不会假装我对这项工作有任何影响。我相当肯定,在我与 OpenAI 开始任何对话之前,这方面的内容已经在飞行中很久了。

作者 ChatGPT chat.openai.com/chat,图片截图免费研究预览

相反,我分享这个背景,希望能激励那些可能阅读这篇文章的人。如果你对人工智能感兴趣,不要气馁或被这个领域吓倒!我有一个 10 年的计算机科学学位,每周最多花几个小时在这上面。这次经历告诉我,这些工具加上好奇心和学习热情可以让你走得很远。在这种情况下,我探索的主题与世界上一些顶级专家的工作相关,这无疑激励我继续投入时间进行学习和实验!这个领域总是需要更多的人才和汗水,让 AGI 的能力和调整正确是一个非常高风险的努力。如果你对人工智能感兴趣,我鼓励你投入进去!

朝向量子测量误差减轻

原文:https://towardsdatascience.com/towards-quantum-measurement-error-mitigation-e6f134883f34

如何将 CDR 与量子态层析连接起来

量子机器学习要不要入门?看看 动手量子机器学习用 Python

量子计算机是惊人的设备。然而,它们也容易出错。因此,我们需要实现量子误差缓解方法来减少误差对我们的计算结果的负面影响。

在之前的一系列帖子中,我们学习了 Clifford 数据回归方法,并在模拟环境真实量子计算机上减少了错误。

结果令人鼓舞。然而,当我试图用它参加 IBM 的量子开放科学奖时,出现了一个意想不到的障碍。

IBM 要求我们使用 Trotterization 模拟一个三粒子海森堡哈密顿量。不,这不是问题。问题是,他们通过量子态断层扫描来评估任何提交物。这是一种通过测量重建量子态的方法。更具体地说,问题是他们在 Qiksit 内部使用了StateTomographyFitter。这种实现建立在实验计数的基础上。但是 CDR 方法适用于期望值。

让我稍微说明一下这个问题。下图描述了一个 1 量子位量子电路的简单情况。

作者图片

每当我们看一个量子位,它不是 0 就是 1。就是这样。哪一个取决于几率和内部量子态。假设量子位在|+⟩.状态在这种状态下,测量 0 和 1 具有相同的概率。但是,当量子电路只运行一次时,我们不能对概率下结论。

但是当我们重复运行它,比如说 1000 次,我们会看到 0 次和 1500 次,除了微小的统计差异。

不幸的是,目前的量子计算机是嘈杂的设备。我们有时用零来衡量一,反之亦然。所以,结果变得模糊。例如,我们将测量 0 412 次,而不是 500 次。

运行量子电路的原始结果是测量。因为我们几乎总是多次执行电路,所以我们对测量进行计数。

那么,我们来看看这样一个电路的 Qiskit 中的源代码。

我们定义了一个具有单个量子位的量子电路,并将哈达玛门应用于它。这个转换门将量子位(从初始状态|0⟩)放入状态|+⟩.在电路的末端,我们测量量子位。下图显示了电路图。

作者图片

让我们运行这个电路 1000 次。我们通过获取一个backend(这里是一个无噪声的统计模拟器)并调用execute函数来实现这一点。

我们得到一个 Qiskit 结果对象( Qiskit 引用)。这个物体的基本功能是get_counts,因为它告诉我们在观察量子位时看到了什么。

{'1': 499, '0': 501}

这是一个简单的 Python 字典,将测量结果作为键,将我们观察到这个结果的次数作为值。现在轮到我们来解释这些数字并做一些有意义的事情了。从这里看,这些结果和其他统计数据一样好。我们可以用它们来计算进一步的值,比如期望值。这是实验测量的概率期望值。它类似于经典的期望值。例如,考虑投掷一枚公平的硬币,正面和反面着地的概率相等。如果将值 1 赋给正面,0 赋给反面,则期望值为 0.5∫1+0.5∫0 = 0.5。这对于|+⟩.的量子位也是一样的

通常,当你看到量子计算中期望值的计算时,它看起来像这个⟨𝜓|𝑍|𝜓⟩.字母“psi”(𝜓)表示量子态,中间的 z 象征可观测。在这种情况下,它是 Z 轴。

这里重要的是,这个符号引入了可观测的概念。当我们之前在 Qiskit 中测量我们的量子位时,我们隐含地选择了 Z-observable,因为这是 Qiskit 中量子位的默认测量基础。所以,我们本质上谈论的是同一个概念。在这篇文章中,我们更详细地观察了可观察到的现象。我们需要知道的一件事是,不只有一个可观测的,而是很多个。想象一个像地球一样的球体。可观察点是你观察地球的特定点。从不同的角度看世界是不同的,然而,这是同一个世界。

作者图片

本质上,计数和期望值是紧密联系在一起的。他们都有他们的用途。虽然计数包含有关不同测量的更多信息,但是期望值更适合使用,因为它是一个单一的数字。

这是我在之前的帖子中描述的奋斗点。虽然量子错误缓解方法 CDR 使用了期望值的简单性,但是 IBM 用来评估错误缓解性能的量子状态层析成像与计数一起工作。

为了参与 IBM 的挑战,现在我们的工作是将两者整合起来。

我选择让 CDR 适应不变状态层析,因为后者是 IBM 的评估方法。我相信乱用他们的评估工具可能会取消我的参赛资格。

因此,我们需要更改 CDR 方法来更改计数字典,而不是单个数字。

让我们简单回顾一下 CDR。

作者图片

CDR 方法有三个步骤。首先,我们生成训练数据。然后,在这一步,我们运行我们的量子电路两次。一旦在经典计算机上获得可观察的期望值的精确值。一次是在真实的量子计算机上产生噪声值。

在第二步中,我们创建噪声值和精确值之间关系的线性模型。从一组数据点构建线性模型称为回归。因此得名 CDR —克利福德数据回归。

最后,我们使用该模型,通过预测无噪声值,将有噪声的期望值转化为减轻的期望值。

所有这些步骤都需要配合 Qiskit 的实验结果。但是,问题是这是 Qiskit execute函数创建的对象。它以只读方式存储大部分数据,我们无法再对其进行更改。

但是,我们可以运用一个小技巧。我们编写自己的Result类,允许我们在以后更改计数。

从概念上讲,我们创建了一个新的 Python 类,它服务于状态层析使用的一个函数。这是get_counts功能。因此,当状态层析函数查询计数时,它会得到一个响应。但是由于我们实现了这个新类,我们也可以提供一个覆盖计数的函数。

下面的清单描述了我们的OwnResult类的源代码。

该类将现有的 Qiskit 结果作为初始化参数。此外,我们将_counts指定为一个成员变量,用一个空字典对其进行初始化。这将保存我们更改的计数。功能代码除了两个小东西,都是从原源代码复制的。首先,每当我们引用结果的属性时,比如data,我们需要查看self._result.data而不是self.data。第二,在第 41-45 行,我们研究了实际计数的自定义成员函数。如果它们存在(if str(key) in self._counts.keys()if str(key) in self._counts.keys()),我们返回改变的计数(self._counts[str(key)]self._counts[str(key)])。如果它们不存在,我们返回原始计数(self._result.data(key)["counts"])

让我们来看看它是如何工作的。

original result:  {'1': 499, '0': 501}
Changed counts:   {'0': 100, '1': 900}

所以,让我们看看是否可以在状态层析成像中使用我们的OwnResult

在下面的代码片段中,我们创建了与之前使用的电路相同的简单电路。唯一的区别是我们省略了测量,因为我们需要从中创建state_tomography_circuits。然后,我们在无噪声的Qasm-Simulator上运行这些电路,并存储其结果。

所以,现在我们准备好了激动人心的部分。我们循环通过实验列表中的电路(st_qcs)。对于每个电路,我们将计数设置为具有任意值的固定字典。我们现在不关心这些值,因为我们只想验证StateTomographyFitter是否与我们的OwnResult一起工作。

最后,我们根据原始结果和更改后的结果计算保真度。

original fidelity: 0.49800015998080377
changed fidelity:  0.7886751345948128

输出显示,我们根据更改的计数计算的保真度与我们根据原始计数计算的保真度有很大不同。显然,StateTomographyFitter与我们的自定义计数一起工作。这为在下一步中减少错误创造了先决条件。

量子机器学习要不要入门?看看 动手用 Python 学习量子机器

在这里可以免费获得前三章。

解决 IBM 的量子开放科学奖

原文:https://towardsdatascience.com/towards-solving-ibms-quantum-open-science-prize-cb6688878779

今天,我们满足了参赛条件

量子机器学习要不要入门?看看 动手量子机器学习用 Python

如何发现是否从事量子计算的职业?大约三个月前,我声称最好的方法是研究 IBM 的量子开放科学奖。

这正是我们所做的。在我之前的文章中,我们讨论了这个挑战的本质细节。IBM 希望我们使用 Trotterization 在 IBM Quantum 的 7 量子位雅加达系统上模拟一个三粒子系统的海森堡模型哈密顿量。首先,我们了解到真正的挑战不是模拟一个三粒子系统的海森堡模型哈密顿量。相反,它是关于如何在一个嘈杂的设备上做它。因此,我们建立了我们的开发环境,查看了如何使用真正的量子计算机,并且向我们介绍了量子错误缓解方法

我们选择了 Clifford 数据回归(CDR)方法。在 CDR 中,我们使用可以经典模拟的量子电路来训练噪声模型。这个噪声模型让我们从有噪声的值中预测无噪声的值。

作者图片

我们用 Qiskit 和 Mitiq 实现了这种方法,在本地模拟真实量子计算机上,结果都很有希望。不幸的是,我们认识到我们不能使用 CDR 方法,除非我们重写 IBM 评估我们解决方案性能的方式。我们没有这样做,因为这可能会取消我们提交的资格。相反,我们决定改变我们的方法。

因此,我们研究了如何减轻噪声以满足 IBM 的期望和【在测量级别减轻噪声】。

所以,我们现在准备把它放在一起。

从概念上讲,我们遵循 CDR 方法的方法。

  1. 生成培训数据
  2. 训练一个噪声模型
  3. 从有噪声的测量值预测无噪声的测量值

生成培训数据

我们的训练数据由成对的测量值组成。每对由同一量子电路的有噪和无噪测量组成。为了创建这些训练数据,我们需要各自的运行时环境。

  • 无噪声(经典)模拟器
  • 一个嘈杂的量子设备或一个嘈杂的模拟器

今天,我们使用 Qiskit 的QasmSimulator作为两种环境。首先,我们初始化没有任何参数的QasmSimulator Python 类,以获得无噪声模拟器。第二,我们使用我们的 IBM Quantum 帐户创建一个基于 Jakarta 设备噪声特征的模拟后端。

下一步,我们需要准备量子训练电路。这里的挑战是使用代表问题的电路,但经典的模拟。最初的 CDR 方法通过建立电路的有噪声和无噪声期望值之间的线性关系来实现可表示性。此外,它使用由 Clifford 门组成的电路。这些是经典的可模拟的门。

不幸的是,我们不能使用期望值,但我们需要减轻测量级别的噪声。我们不能在有噪声和无噪声值之间建立线性关系。此外,海森堡哈密顿模拟的问题是它的潜在规模。因此,即使它完全由 Clifford gates 组成,对于任何给定特定大小的经典计算机来说,整个电路都变得难以处理。因此,虽然一个三粒子的海森堡哈密顿量是小菜一碟,但一个五十粒子的海森堡哈密顿量是不可能经典模拟的。

因此,我们需要重新思考我们的训练数据。我们从 IBM 提供的 trotter 化算法开始。该算法包含至少四个三态门。在之前的帖子中,我们了解到,trotterization 门越多,无噪声性能越好。然而,我们使用越多的 trotterization 门,算法对噪声就变得越敏感。如果不采取缓解措施,噪声的负面影响将超过性能提升。但是对于缓解,使用多于最小数量的四个三态门可能是有意义的。

然而,对于训练来说,即使是四个 trotterization 门也太大了。我们需要更短的线路。幸运的是,每个 trotter gate 由三个子电路组成,XXYYZZ门。因此,我们的计划是构建一个训练电路,在一个 tterization 门中只包含三个子电路中的两个子电路。

下面的函数为我们提供了这些电路。

总的来说,这是 IBM 不变的 trotter 化电路。get_circuit函数提供了一个可参数化的接口,以从中创建训练电路。这个想法是,我们可以通过参数XYZ定制我们想要包含的子电路。除非我们包括所有三个子电路,否则我们只增加一个 tterization 门。例如,如果我们有XXYY门,该函数用这些门为单个 trotter 步骤创建一个电路。有必要提一下,我们需要使用预定的量子化步骤数,因为我们使用这个数作为量子位旋转的参数化。所以,具有不同快步数的电路是完全不同的。

我们现在准备创建训练回路。让我们用 12 个快步。如果你喜欢,你可以玩不同数量的步骤。

我们创建了三组电路。这些电路具有

  • XXYY闸门
  • YYZZ闸门
  • ZZXX

当然,你也可以玩门的组合。

此外,我们不是每个都创建一个单独的电路,而是 27 个!原因是 IBM 用来评估我们的模拟性能的量子态断层扫描。量子态层析成像通过从所有专有角度观察量子系统来重建量子态。对于三量子位系统,这些是 3^3=27 角。每个角度都会导致稍微不同的量子电路。但是这些微小的差异会显著影响测量结果。本质上,我们分别对待这些电路。

因此,在下面的步骤中,我们为每个指定的组合创建了 27 个回路。

在执行所有这些电路之前,我们创建了两个辅助函数。简而言之,sorted_counts函数对来自已执行电路的测量计数进行排序,并确保所有可能的状态都存在,即使它们的计数为零。

get_modifiers函数获取一个电路,在我们的无噪声和有噪声模拟器上执行,并计算一个修改量列表。我们的电路可以产生八分之一的状态。这些范围从000111。每个值都有一个修饰符。因此,每个电路有八个修改器。修改量是一个数字,当我们乘以它时,它将噪声计数变为正确的无噪声计数。

通过应用get_modifiers功能,我们将所有电路转换成各自的修改器。变量modifiers_xymodifiers_yzmodifiers_zx分别是 27 个电路的列表。每个元素是八个修饰符的列表。

我们zip将这些放入一个单独的列表(modifiers_zipped)。结果是包含 8 个修饰符的三项元组的 27 个回路的列表。

在下一步中,我们计算每个回路的最终修改量。我们在mult函数中这样做。该函数采用上述回路修饰符的元组。通过压缩这些元组,我们得到一个包含八个条目的列表,每个条目对应三个修饰符。实际上,我们对修饰符进行了排序,使它们都在一个对应于特定计数的列表中。

我们将最终修饰符计算为这样一个列表中所有修饰符到 trotter 步骤一半的乘积。

综上所述,我们创建了三个小型经典可仿真电路,代表我们想要降低其测量值的整体电路。对于这三个电路中的每一个,我们都计算出一个修正因子列表,告诉我们有噪计数与无噪计数的偏差。最后,我们将对应于一个计数的所有修饰符相乘,从而将它们组合起来。

总的来说,每个小回路都有三分之二的快步步。所以,这三个小电路结合起来表示两个快步走。为了计算与整个电路相对应的修改量,我们需要多次进行乘法运算。这是快步数除以二。

最后,我们没有单个整体电路,而是 27 个电路,因为我们的目标是使用状态层析成像。

让我们看看我们的最终修改器有多好。我们重用了前几篇文章中创建的两个助手。这些是OwnResult Python 类和基于该类计算最终状态层析的state_tomo函数(参见本文)。

noisy state tomography fidelity = 0.2861 ± 0.0000
noise-free state tomography fidelity = 0.9699 ± 0.0000
mitigated state tomography fidelity = 0.7518 ± 0.0000

总体结果显示出显著的改善。有了 12 个快步,最好的状态层析成像保真度大约是0.97。这就是无噪声量子计算机所能达到的目标。

然而,由于未减轻的(模拟的)噪声,状态层析成像下降到0.29。但是一旦我们用我们的修改器减轻噪声,我们就得到一个0.75的状态层析成像保真度。参加 IBM 量子开放科学奖的参赛标准是0.3的保真度。所以,我想说我们很好。

查看统计数据可以发现我们方法的有效性。我们减少了大约 68%的噪音。

Error (unmitigated): 0.6838963295732885
Error (mitigated): 0.21813650699579556
Relative error (unmitigated): 0.7050850779029165
Relative error (mitigatedR): 0.22489489909174665
Error reduction: 68.1%.

量子机器学习要不要入门?看看 动手用 Python 学习量子机器。

在这里免费获得前三章。

走向可持续的生成人工智能革命

原文:https://towardsdatascience.com/towards-sustainable-generative-ai-revolution-a9786de586cb

面对成长的烦恼:如何驾驭超级潜意识的狂野新时代

由生成式人工智能生成的图像

不可阻挡的生成性人工智能革命正在拉伸人类的创造性肌肉。通过使用文本和其他类型的提示,人们使用这项技术来生成令人惊叹的图像、视频、3D 形状、VR 环境等。然而,成长的烦恼开始出现在各种事情上,从在世艺术家的权利到艺术竞赛、艺术平台、股票图书馆等人工智能一代的存在。

我是这场革命开始时推出的第一批生成式人工智能平台之一的联合创始人(https://geniverse.co)。我也做了很长时间的多学科艺术家。

作为一个在这两个领域(生成人工智能和艺术)都非常活跃的人,我打算思考这些问题中涉及的许多角度和观点。

不过,首先,我们将一起进行一次有趣的旅程,以便从基本原则出发,回顾这项令人兴奋的技术的本质,将它与人类创造力以及创意人员和艺术家的思想联系起来。

然后,我们将探索这场革命当前状态中好的、棘手的和房间里的大象。最后,我将思考我们如何超越这些快节奏的初始阶段,为实现更可持续的发展做出贡献。

系好安全带,在这篇文章中,我们将从关于人工智能的隐喻到潜在空间、艺术家的思维、智能生成环境和其他未来场景、创意者的权利、内容真实性倡议(CAI)标准和方法等。我们开始吧。

回家

让我们用一个简单的比喻来探索生成式人工智能革命带来了什么,以及它对创意人员、艺术家和全人类意味着什么。

曾几何时,你坠入了生命的海洋。这是一个相当广阔的海洋,一个信息的海洋。

哈维尔·伊达米| ideami.com 制图

让我们想象你是由两个视角或部分组成的:你的潜意识和你的有意识的 T21 视角。让我们把你的潜意识想象成一个厨房的锅,漂浮在信息的海洋上。

在这片海洋上,你的首要任务是生存,希望能茁壮成长。为此,你需要信息。所以你要把足够多的高质量的原料带进你的锅里,并把这些原料结合和重组,以便产生帮助你达到目标的知识和想法。

哈维尔·伊达米| ideami.com 制图

在你的潜意识锅上面,有这个弥漫的神秘闪亮的球体,它代表着我们的意识(对此我们仍然知之甚少)。

哈维尔·伊达米| ideami.com 制图

所以,你在这里。漂浮在生命的海洋上,你神秘的意识有时会为你潜意识中的烹饪过程提供方向。

一直以来,潜意识都在不断地组合、混合和再混合通过我们的感官到达它的各种成分(信息)。

有时,这些组合可能会成为新思想的种子。打个比方,我们可以想象在烹饪过程中出现的脆弱、微妙的气泡,从潜意识上升到意识。而且,如果我们的头脑中有空间,如果它们不是充满噪音,我们可能会感知到那些脆弱的泡沫,然后:找到了!一个想法!

哈维尔·伊达米| ideami.com 制图

哈维尔·伊达米| ideami.com 制图

但是,这里有一个问题。这片海洋上有太多的信息,太多的复杂性。而我们潜意识的锅,大小有限。它不是刚性的。它在某种程度上是灵活的,可延展的。但是它的尺寸仍然有限。

因此,大自然进化出一种机制来解决处理生命海洋的巨大复杂性的问题:压缩和解压过程

我们的大脑能够接受通过我们的感官获得的信息,并将其压缩成一种更少细节、更多抽象的形式。

压缩漏斗|贾维尔·艾达米的作品| ideami.com

让我们开始想象这个非常重要的轴,细节抽象轴。当我们压缩生活的复杂性时,我们从高细节(和高维空间)到高抽象(在低维空间内)。

哈维尔·伊达米| ideami.com 制图

因此,在我们的潜意识里,我们收集了这个世界复杂性的压缩表现,我们有时称之为:潜在空间

哈维尔·伊达米| ideami.com 制图

这些潜在空间容纳了不同信息领域的抽象本质。我们去掉了无信息的细节,保留了许多降维,每个降维都记录了与数据所属的信息领域相关的有用因素。

哈维尔·伊达米| ideami.com 制图

我们的大脑也可以做相反的过程。它可以执行解压缩、并从高抽象到高细节。

"想象一头大象!"我们听到这些话,一只大象的形象就会浮现在我们的脑海里。我们只是运行了相反的过程,将高抽象表示(大象)解压缩成我们头脑中高度详细的可视化。

哈维尔·伊达米| ideami.com 制图

我们刚刚探索的过程与人工智能网络中发生的过程非常相似。我们训练人工智能网络学习将高维域(如自然图像的域)压缩到潜在空间中,这些空间将这些域的抽象本质保留在更少的维度中。

并且我们还训练他们将那些潜在空间内的任何点解压缩成属于原始信息域的相应高维表示。

哈维尔·伊达米| ideami.com 制图

当我们探索复杂的生成式人工智能系统时,从 DALLE-2 (OpenAI)到 Imagen (Google),稳定扩散** (Stability.ai)以及更远,我们发现不同的中间阶段,例如,它们可能在模态之间转换,执行扩散过程,缩放输入和输出等;但是所有这些系统的共同基础是这些压缩和解压缩过程,它们允许我们在高细节和高抽象之间双向移动。**

人工智能系统的细节取决于我们的目标。我们可能想要提升图像,或者锐化它们,或者根据文本提示生成全新的图像,或者这些事情一起做,或者一些完全不同的事情。这将决定我们使用什么样的培训目标和数据集,以及最终架构不同部分的精确细节。

当今领先的生成式人工智能系统使用的关键策略是基于我们所说的扩散。例如,稳定扩散系统使用类似于 U-Net 的架构,该架构已经被训练(利用大型数据集)来预测已经添加到图像中的噪声。

一旦被训练,相同的网络能够在许多步骤中从图像+噪声(包括来自完全随机噪声)的不同组合回到高质量图像。

它也可以从一个图像到另一个图像,通过在初始图像中添加一些噪声,然后执行与之前相同的过程。

为了让这些代朝着正确的方向前进,它们受到我们输入的文本提示的压缩表示的制约(注入到 U-Net 架构的不同部分)。

技术细节说够了。我们继续。

艾要回家了

因此,随着生成性人工智能革命的到来,我们正越来越接近我们的本质,因为人类能够执行会聚和发散(压缩和解压缩)的互补过程,通过我们的分析和创造性肌肉来表达。

在我们逐渐扩展和进化深度学习人工智能系统的融合能力(能够预测、推荐、分类、识别等)的十年之后,生成式人工智能革命通过添加超人的发散能力(能够创造和生成)来完成循环。艾要回家了。

人工智能回家了|图片作者:ideami.com

潜在空间的魔力

但是,当我们谈论潜在空间或抽象压缩表示时,我们真正的意思是什么?通过一个非常简单的例子,我们在自己身上找到了答案。

我在大自然中散步。当我回来时,我的朋友问我散步怎么样。我说:“太棒了,我看到了一只美丽的蝉!”。她问我:“蝉长什么样?”

比尔·尼诺在 Unsplash 上拍摄的照片

那时,我在脑海中想象那只蝉。让我们假设我的视觉化是用 1000 x 1000 个光点的网格来表达的。那是一个一百万维的空间。如果这些点有颜色,那么它们中的每一个都有一个红色、绿色和蓝色的成分(3 倍的维度)。

所以我可以这样开始向我的朋友描述这只蝉:“嗯,在我的视觉化图像左上角的第一个光点有 15 的红色强度,25 的绿色强度和 77 的蓝色强度。它右边的下一个点有 145 的红色强度,55 的绿色强度…等等,下一个点有..等”。我可以一直这样穿过一百万个光点。这种方法的问题显而易见。

我可能要花一个月的时间来描述这只蝉,到那时,我的朋友早就走了。零效率。但主要问题甚至不是这个。

知道这一百万个点中的一个具有 155 的红色强度是没有多大用处的。的细节往往不提供相关信息。这就是为什么我会做一些不同的事情。

我将把蝉的所有复杂和丰富的细节压缩成几个维度,30、50、100 个因子(无论如何都是个小数字),来解释我所看到的本质。

照片由 Saryu Mae(https://inaturalist.nz/taxa/342384-Kikihia-ochrina|抄送人:https://creativecommons.org/licenses/by/4.0/)|图片由 Javier ideami | ideami.com

我会告诉我的朋友:看,它有一个宽阔的脑袋,结实的绿色身体和透明的薄膜翅膀。四个翅膀,翅膀上有这样的图案。它有很大的复眼,有这么多眼睛,六条腿,腿是这样的,等等。我已经将高细节的表现压缩到少量的维度上,这些维度传达了重要和相关的信息。

现在,我的朋友听到这个,她做了相反的过程,解压

她转换这些表达我所看到的本质的压缩维度,并在她的脑海中膨胀它们,以在脑海中想象与本质相对应的高细节表示,一只蝉的形象(这将与我想象的不同,因为压缩-解压缩过程以及所涉及的系统和我们每个人对相关场景的先前知识之间的其他差异)。

照片由 Saryu Mae(【https://inaturalist.nz/taxa/342384-Kikihia-ochrina】|抄送人:【https://creativecommons.org/licenses/by/4.0/】)|使用生成式人工智能创建的变体进行修改|图片由 Javier ideami | ideami.com 制作

因此,在某种程度上,每次我们回忆起一些事情,我们都在重建它,重新想象它,从我们储存的本质中重新创造它(这一过程的精确度在很大程度上取决于相关潜在空间的丰富程度以及参与其创造的感官形式的数量,以及其他因素)。

以下是我几个月前制作的一张关于 DALLE-2 如何工作的信息图,将它的过程与人类大脑中发生的事情进行了比较。

Javier ideami | ideami.com |在 https://github.com/javismiles/dalle2-inference下载超高分辨率版本的信息图

小锅,巨锅

我们大脑内部和这些人工智能网络内部发生的事情有许多不同之处,但打个比喻来说,与本文特别相关的一个不同之处是潜意识锅的大小。

我们的潜意识来源于我们在生活中的经历。当我们与人交谈时,当我们体验世界时,我们丰富了它的内容。最终,它的烹饪过程会在我们的脑海中产生新的想法、视觉效果、声音等等。

人工智能网络(在训练时)由庞大的数据集喂养。生成式人工智能系统使用的数据集是由从互联网上收集的信息组成的。我们谈论的是海量数据。

所以,一方面,我们有我们人类,有我们潜意识里的小锅。

另一方面,我们有这些巨大的人工智能罐子,从互联网上收集数据。有些数据是公开的。但不是全部。稍后我们会讨论这意味着什么。

哈维尔·伊达米| ideami.com 制图

哈维尔·伊达米| ideami.com 制图

深度电梯

是时候把前面所有的板块和艺术和人类艺术家联系起来了。现在,定义什么是艺术家是一项不可能的任务。相反,我将专注于探索历史上许多伟大创意者共有的事物

还记得我在上面讨论的那个轴** ( 细节到抽象)吗?在我几年前出版的一本书中,我写了我想到的另一个比喻,我称之为“深度电梯”。**

想象一条垂直的线,电梯穿过这条线。在这条线的底部,我们有高维度和高细节的领域。这是生命海洋的复杂性得到充分表达的地方。

在这条线的顶端,我们有压缩的低维潜在空间的领域,它保存了较低领域的抽象本质(例如,这里生活着我们的语言)。

欧文坎农在 Unsplash.com 的照片。作者:哈维尔·伊达米| ideami.com

艺术家是以敏捷、灵活和动态的方式驾驭这种深度电梯的大师。让我们更深入地研究这个问题。

当我们还是小婴儿,以及后来的孩子时,我们大部分时间都呆在深度电梯的底部,与宇宙的丰富多彩和细节互动。我们的分析心智模块还没有完全开发出来。现在是我们的探索阶段。

相反,大多数成年人倾向于通过重新利用他们头脑中已经建立的思维模式来关注效率(这也有助于我们防止浪费我们宝贵的燃料,为我们的大脑提供动力的葡萄糖)。这是我们的开发阶段。因此,成年人在深度电梯顶部狭窄的象牙塔中度过了大量时间。

在深度提升器的两半部分花费的时间之间达到一个良好的平衡是一个健康的目标。在收敛发散之间,在压缩和解压缩之间,在抽象和细节之间取得良好的平衡。

这两极(无论哪个方向)之间缺乏平衡会在成年人身上产生不同类型的问题。我已经写了很多关于这些问题的文章,但这不是本文的主题。让我们回到艺术家身上。

重复性精神劳损| ideami.com 制图

许多伟大的艺术家都有以下共同点。他们能够以敏捷灵活的方式操纵这个深度电梯。他们能够下到电梯底部的深处,那里有丰富的宇宙在等待着他们。

关键的一点是,他们不会踮起脚尖就离开。相反,它们能够在水下呆很长时间,探索那些泥泞、荒凉和不确定的水域。

他们还能够将这种丰富性具体化为不同的解释和表示,这些解释和表示可以在从细节到抽象的整个轴的不同层次上表达自己。

而表象本身,或者相反,它们的解释或者它们交流的方式,也位于更接近深度电梯的顶部。

这与大多数时间呆在电梯顶部或接近顶部的典型成年人形成了鲜明的对比。你也猜到了原因。

因为在电梯顶部的抽象象牙塔上,比在那个包含宇宙复杂细节的轴的泥泞底部航行要舒服得多(并且需要更少的燃料)(打个比喻,我们也可以说,这比在电梯底部探索下面的野生游乐场要舒服得多)。

这里我们到达另一个关键点。像历史上许多伟大的艺术家一样,需要努力。这需要时间毅力。而且,在某种程度上,这违背了我们成年人高效思维和避免浪费宝贵燃料的天性。

高效创新烹饪流程的要求|作者:哈维尔·艾达米| ideami.com

关于这一点,有必要指出一些平台目前正在禁止生成性人工智能艺术(或将其放在一个单独的类别或领域),因为他们认为它是:【低努力】艺术。

是的,找到正确的提示来指导生成式人工智能架构需要一些努力。但是,这一过程所需的努力和时间无法与之前描述的掌握这一过程所需的数年甚至数十年相比。在本文的稍后部分,我们将更深入地探讨这一点和其他相关问题。届时,我们还将思考此类难题的潜在解决方案。

因此,通过在深度电梯中进行这种灵活的导航,伟大的艺术家和创意人员能够以新颖的方式表达宇宙的丰富性。

选择生活中的任何东西,比如说,木头。你可能会以一种非常超然、抽象的方式体验木头。或者你可以深入细致地探索木材的所有错综复杂之处。如果你能够灵活地在两极之间移动,你就处于一个更好的位置来创造一些与宇宙元素相关的新奇和不同的东西。

哈维尔·伊达米| ideami.com 制图

伟大的创意者也能够理解位于轴底部的广阔海洋的不同区域的不同互联方式,跨越这些水域的不同层,也通过深度电梯的顶层。

例如,当一个伟大的创意经历节奏时,她可以超越学科、技术、工具和华而不实的术语。一个伟大的创意看到和感受到节奏无处不在。在窗帘投射的灯光和阴影中,在眼泪落下的声音和动作中,在星星的舞蹈中,在我们思想的缝隙中,以及更远的地方。

哈维尔·伊达米| ideami.com 制图

几十年来,伟大的创意者扩展并巩固他们潜意识中的潜在空间。

他们还改进了导航深度电梯的方式,这使他们能够以强大的方式将细节与抽象联系起来,从而丰富他们的创作过程。

此外,艺术家和创意人员经常与其他人合作。这样做,不同的潜意识锅可能会互相充实。

哈维尔·伊达米| ideami.com 制图

哈维尔·伊达米| ideami.com 制图

哈维尔·伊达米| ideami.com 制图

所以,如果你研究历史上一些最伟大的创意者和艺术家,你会发现他们都有话要说,有信息,有愿景。而且,这种愿景,以及他们表达的方式,与他们几十年来培养的能力密不可分,他们以流畅的方式驾驶这些深度电梯,探索宇宙丰富的深度,以及抽象的象牙塔和两极之间的许多领域。

最后,关于那些深度电梯,下一步将不是把它们想象成孤立的实体,而是在多维空间中相互连接的多个漏斗。

下面这张折纸的图片,试图表现隐喻延伸的一小部分。

然而,现在是时候停下电梯继续前进了,以便专注于对生殖式人工智能革命的现状进行审查,以及解决其当前成长烦恼的方法。

深度电梯折纸|贾维尔·艾达米| ideami.com

因此,利用我们上面所探讨的,让我们考虑一下今天和未来的情况,以及对此可以做些什么。

好的,狡猾的,房间里的大象

让我们来探索从这个生成性人工智能革命的初始阶段衍生出的许多后果。

好人

超级潜意识时代| ideami.com 的图解

  • 把这项技术想象成一系列不同的钢铁侠套装,它们将增强你的潜意识,并增强你的创意肌肉。
  • 不同的钢铁侠套装会有不同的风格、特点和个性。
  • ****提示工程师是将成为从这些钢铁侠套装中获得最佳效果的专家的人。他们会知道来龙去脉,各自的优缺点。
  • 当与这些强大的放大器互动时,他们也将成为运用人类经验和直觉的大师,以达到期望的结果。
  • 因此,这些提示专家将在未来几年受到高度重视。他们的角色将成为就业市场上的重要角色。我们将会看到大量的课程、出版物和系统来教育和帮助人们训练这种技能。
  • 今天我们的提示是自然语言和图像。但是由于多模态架构,提示将很快成为我们想要用来指导这些架构的任何类型的数据(不同的系统将被设计来吸收不同类型的指导输入)。
  • 最初的文本到图像阶段现在已经过渡到文本到视频和文本到 3D 功能。最终,我们将能够使用定制系统输出各种数据,这些系统将针对特定垂直行业的需求。
  • 接下来,我们将见证多模态输出能力,这将最终允许我们制作,例如,包括视觉、对话、音乐等的完整电影。
  • 这项技术将激发出我们还无法想象的新艺术形式。多模态生成人工智能即将引发结合深度电梯探索和未探索领域的新方法的出现,这些方法最终可能成为备受推崇的新艺术表达形式。
  • 生殖人工智能将影响大量行业。它将用于通过合成世代扩展科学数据集,革新头脑风暴过程,以仅在几个月前还无法想象的方式个性化品牌,加速实时动态“只为你”营销和广告的兴起,并通过在各种演示文稿周围放置以令人印象深刻的方式匹配其内容的媒体,将各种演示文稿带入一个新时代。从图片库到设计精品店,整个媒体领域都将争相采用这项技术。
  • VR & AR (一般来说,所有形式的 XR )这样的尖端技术都将结合这项技术(实验已经在进行中),最终我们将见证沉浸式空间的实时生成,这些空间通过跟踪用户的目光以智能的方式再生(考虑这些实验和唐纳德·霍夫曼的理论之间的联系很有趣)。
  • 这项技术也将加速许多创新过程的探索和实验阶段。从概念设计到产品设计,角色设计和原型阶段,跨越了广泛的领域,生成式人工智能将允许我们在更短的时间内做更多的事情,尝试各种新的方向,并更深入地探索深度电梯的每个级别。
  • 对许多人来说,所谓的“元宇宙”仍然是一个乌托邦,它的体面实现似乎还遥遥无期。如果元宇宙有朝一日成为有用的现实,它可能会发生在生成性人工智能技术的肩上,这可能是加速其实现的关键。
  • 在更远的未来,我们将见证智能生成环境(SGE)** 的崛起,它会根据我们的需求或情绪状态而变异。房屋、活动场所和其他环境将开始通过匹配和相似其内容的意图和情感来类似有机生命体。他们将以多式联运的方式这样做。最终,我们将能够与这些环境交流,它们将成为我们心理平衡和健康的重要支撑。**
  • 生殖人工智能与越来越强大的传感模型相结合,能够解释我们表情和行为的每一个细微差别,这将使我们能够对我们的情绪和心理状态进行实时多模式解释。当与脑电波读取技术(脑电图、脑磁图等)的新迭代相结合时,这将迎来一种新的创造性表达,将真正使用我们最亲密的领域作为画笔,产生对人类状况的非凡再现。
  • 尽管一些工作正处于并将处于危险之中,但我们还无法想象的新角色也很有可能会从管理和与这项技术互动的需求中出现。
  • 与此同时,许多受影响的工作和角色将通过拥抱这个新时代并使其流程适应这一新技术所提供的内容而生存下来,甚至茁壮成长。
  • 许多人可能不是专业艺术家,但他们天生就有锻炼创造力的素质,他们将会在这项新技术的帮助下茁壮成长。他们会以更快更容易的方式强化这些肌肉,他们会享受新的机会来增强和放大他们的创造潜力。
  • 我们将像开始时一样结束这一部分。提醒我们所有人,生成式人工智能不会取代人类的创造力。它会增强它。并且,锻炼我们的创造性肌肉将会继续成为同样被强烈推荐的活动。在我们发散和收敛、压缩和解压的能力之间达到一个良好的平衡,在可预见的未来对我们的精神和心灵健康将继续是非常重要的。

棘手的

  • 我们,人类,有一个有限且相对小的潜意识锅。生殖性的人工智能系统被训练成能容纳包含大部分互联网知识的巨大罐子。
  • 正因为如此,人类创意应该与生成性人工智能系统竞争,这似乎不公平,也不符合道德。
  • 当机器在下棋方面战胜人类时(这是一个没有这次那么重要的事件),没有人认为继续探索人类与机器的象棋比赛会有很大的乐趣(除了那些表明我们输掉了战斗的比赛)。我们承认他们更好。然后我们就各奔东西了。
  • 人类棋手使用人工智能训练自己,然后变得更好(类似于生成式人工智能系统提供的这些隐喻钢铁侠套装的增强和放大能力)。
  • 下棋或下围棋的人工智能系统有时会做出人类永远不会想到的非常漂亮的棋步。他们有自己特殊的视角(当然,基于对未来的巨大预见能力)。然而,很少有人对机器对机器的比赛感兴趣。人类更喜欢看其他不完美的人类玩耍。
  • 在任何情况下,关键是它们将两个领域分开。机器帮助人类棋手训练,变得更好。他们也可以在一起玩。人类各自在自己的比赛中比赛。
  • 我相信,最终类似的事情可能会发生在生殖人工智能上(当然,有一些不同,因为这些是非常不同的领域)。
  • 另一个需要考虑的棘手问题是这项技术目前令人兴奋的背后的一个关键因素。我将在本文的最后一节详细阐述这个问题。现在,让我们来介绍一下。
  • 在许多人看来,格雷格·鲁特考斯基是当今最好的幻想艺术插图画家之一,如果不是最好的话。最近,他的名字出现在大量用于制作一些最令人印象深刻的生成性人工智能艺术的提示中。
  • 因此,在所有由格雷格·鲁特考斯基(Greg Rutkowski)所画的令人惊叹的艺术作品引发的多巴胺热潮消退后,在这些多巴胺热潮消退后,许多人将会剩下成百上千个人工智能生成的图像或视频,然后,他们会问自己:“现在,什么?”
  • 大多数情况下答案是“没有”。因为这些人中的大多数人并没有真正锻炼他们与任何深层的有意义的内部驱动相关的创造性肌肉;他们使用这项技术,就像一个人买了一部新的 iPhone,以一种强迫性的方式,跟随闪亮的最新技术。
  • 当这种冲动消失时,他们会感到某种空虚。因为大多数留下来的东西不是他们的,而是属于格雷格·鲁特科夫斯基和他的风格,这是他几十年努力的结果(举个例子,还有许多活着的艺术家,他们的作品推动了这些网络)。
  • 无论如何,让我们现实一点。事情发展得太快了,人们需要时间来赶上是有道理的。目前的情况可能有许多解决方案。我将在下一节的最后讨论其中的一些。

明摆着的难题

在 Geniverse 生成的图像(生成人工智能)

  • 人工智能生成系统之所以成为可能,仅仅是因为用来训练它们的巨型数据集
  • 人工智能生成架构由大量数据集训练而成,这些数据集由图像、视频、文本以及其他类型的数据组成。
  • 这些数据通常是由创建这些数据集的团队从互联网上提取的。
  • 这些数据集中使用的数据中的一些公共域 数据。使用这样的数据来创建这些数据集似乎是公平的。
  • 但是,这些数据集中使用的大部分数据属于活着的艺术家,他们没有声明这些数据是公共领域的数据。这些艺术家通过出售这些数据谋生=出售他们几十年的辛勤工作,这些工作产生了一种特定的风格和一系列的作品。
  • 这些艺术家确实是这场革命迅速崛起的基础
  • 因此,越来越多的在世艺术家对此表示不满。他们中的一些人表示,在世艺术家的作品不应该包含在这些数据集中。据一些人说,他们的抱怨被置若罔闻。他们大多被忽视了(至少到目前为止)。
  • 如果我们忽视这些活着的艺术家的抱怨,我们就是在忽视我们自己。今天,我们在讨论视觉艺术,但明天,它可能是音乐、小说、法律著作,或者我们的职业或领域。
  • 让我们再次从许多人在使用这些系统时的体验的角度来思考这一切。当一个人创作出与 Rutkowski 先生的风格和作品极其相似的令人惊叹的数字艺术时,他可能会产生多巴胺的冲动,这种冲动是建立在谁的肩膀上的呢?当然是在 Rutkowski 先生的手机上。更具体地说,是几十年来 Rutkowski 先生为创造这种风格和作品所付出的极大努力和坚持。
  • 一种风格和一系列作品现在给了那个人如此强烈的多巴胺冲动,当他们花一些时间想出一个包括鲁特科夫斯基名字的提示,然后点击一个按钮,用最少的努力产生一个与他的艺术如此相似的结果。
  • 有些人可能会说:“但是我花了 50 个小时才想到这个提示”。
  • 不管这是不是一个夸大的数字,它都不能改变一个事实,即任何人对语言提示的几分钟或几小时的探索,都无法与 Rutkowski 先生等人投入数十年的工作相提并论。
  • 这也不能改变这样一个事实,Rutkowski 先生从未明确允许他的作品被包含在这些人工智能架构使用的数据集中。
  • ****提示工科是艺术+科学。它将逐渐成为一种有声望的技能和学科。
  • 关于这个问题将会有大量的书籍和课程。伟大的提示工程师将知道许多不同的人工智能架构的来龙去脉、优势和弱点,同时能够将他们的人类直觉应用于从人机交互中提取最佳结果的提示的生成。确实如此。
  • 但这仍然不是践踏人类同胞和在世艺术家权利的借口。在本文的下一部分,也是最后一部分,我将更详细地讨论我们可以做些什么来解决这个问题和其他相关问题。
  • 让我们再次强调以下几点:这场革命进展如此之快,人们需要时间来赶上这一切是可以理解的。追赶和寻找更可持续发展方案的过程正处于初始阶段。
  • 我将永远支持生成性人工智能,但最重要的是,我将支持和捍卫我的创意伙伴(因为人和他们的生命永远比技术更重要)。这是一个伦理和道德的问题(法律方面不是本文的一部分。这些将由其他人来解决,我认为伦理和道德应该是这件事的首要指南。

这是一场奇妙的革命,将给人类带来许多好处。但是正如我们所看到的,在这些初始阶段也有一些棘手的方面需要考虑。让我们讨论一下如何解决其中的一些问题。

在 Geniverse 生成的图像(生成人工智能)

引领革命

我将从道德和伦理的角度来阐述这最后一部分。

预计最终,许多机构和团体将引入与这些系统相关的不同形式的监管,公司也将引入自己的保障和控制措施。但是,这些以及其他法律观点需要时间来确立。

虽然可能没有我们预期的那么多时间。在下一节的最后,我将评论一下内容真实性倡议(蔡)一个开放标准,Adobe 创立。蔡已经有数百家公司加入,其中一些已经计划在他们的平台上实现它。****

这将允许他们追踪数字内容来自哪里,如果生成性人工智能已经被用于制作它,以及与错误信息和保护创作者权利相关的其他因素。

现在让我们思考如何让这场革命更可持续。

一位在世的艺术家,花了几十年时间发展一种风格和一套作品,其权利完全属于我们正在考虑的艺术家,如果这位艺术家的作品被纳入这些大规模生成性人工智能数据集,他应该有发言权和/或得到补偿。

否则,就好像,举例来说,你在一个画廊里展示一件艺术品,有人来拿走它,拿走它,并从中获利。有一种被普遍称为版权的东西,它并没有在生成式人工智能革命开始时神奇地消失。

有些人会以 YouTube 为例,说在开始阶段,YouTube 有点像挥舞着这些问题的手,否则他们永远不会起飞。众所周知,现在和很长一段时间,YouTube 在其平台内采用了一套非常严格的版权保护机制。事实是,生成式人工智能已经大规模爆发。因此,最初的“管它呢”阶段是可以理解的,但那个阶段现在已经过去了。因此,像 YouTube 和其他类似平台必须做的那样,开始保护创作者权利的时刻就是现在。

最后,我们需要讨论一个超级重要的问题,即灰色地带。为此,让我们快速回顾一下我们在前面几节中提到的一点。

让人类和机器在同一个艺术比赛、艺术平台之类的地方竞争,这是不公平的。人类潜意识的锅很小。人工智能系统有大量的。人类的潜意识保存着他们生命的有限经验,一个生命的有限经验。人工智能系统拥有数百万或数十亿人类的知识。让我们现实一点。让他们互相竞争是不公平的,也是不道德的。

相反,就像国际象棋一样,我们可以想象艺术竞赛和艺术平台中的独立部分。人类创造的艺术。艾的艺术。这已经在世界各地的许多平台上发生了。但是这一点最终把我们带到了灰色地带。

灰色地带。

“等等,这东西还没有完全由人工智能生产出来,你看。我使用人工智能制作了部分作品,是的,没错,但后来我对它进行了润色,我在它的基础上进行了构建,因此,它是合法的,对吗?”

我们会听到很多这样的话。因此,解决这种情况至关重要。

美国版权局最近就人工智能作品的注册请求做出裁决,称“人类作者身份是美国版权保护的先决条件,因此作品不能注册。”关于这项裁决的详细讨论可以在这里找到。****

但是,我们将要面对的(并且已经发生的)是灰色地带。介于两者之间。我相信的答案就在— 公有领域 vs 非公有领域— 的讨论中。****

因为,在某种程度上,一切都变了但同时什么都没变。我们开始吧:

  • 在生殖人工智能爆发之前,你可以去谷歌搜索,找到一些公共领域的图像、视频或任何类型的数据,并将它们融入你的创作过程,一切都很公平和美好。****
  • 在生殖人工智能爆发之前,你不能去谷歌搜索,从某个活着的艺术家那里找到一些非公共领域的图像、视频或任何类型的数据,并在未经许可的情况下将它们合并到你的作品中(显然是在试图从他们的作品和你的作品的组合中获利时)。我们在这里讨论的不是你只是私下使用一些在线艺术品进行实验,而不寻求从中获利的情况)。****

好吧,你猜怎么着。这就是答案。没什么新鲜的。答案是,同样的标准可以继续适用。

  • 当我们在这场生成性人工智能革命中导航时,当它与仅使用公共领域数据(或来自在世艺术家的数据,这些艺术家明确允许他们的创作在这些数据集中使用)的数据集连接时,使用这项技术应该是可以的。我们再次只提到寻求从使用这种技术中获利的场景。****
  • 如果您打算将结果用于任何商业目的,在使用包含非公共领域数据的数据集时,完全或部分使用该技术是不合适的。你可以为自己的个人用途进行实验,就像现在有些人从一位著名的在世艺术家那里下载艺术品一样,但肯定不是为了商业目的。

我认为,这些想法是基于常识。但是其他人可能会想出新的想法来补偿艺术家,这可能为解决这个难题提供新的途径。YouTube 再次提供了解决这些问题的一些替代方法的线索(更多信息见下文)。

因此,艺术竞赛、艺术平台、股票图像平台等可以要求参与者披露:

  • 如果他们使用了生成式人工智能技术。
  • 如果是,他们使用了哪一种,什么数据集在推动该技术。
  • 如果支持这项技术的数据集只包含公共领域的数据,那么他们可能会选择向这项工作敞开大门。
  • 如果所涉及的数据集也包含非公共领域的数据,那么他们可以决定关闭这些作品的大门,或者把它们放在一个单独的部分。
  • 当然,人们可能会撒谎。因此,我们也将见证自动系统的崛起,这些系统能够识别你的部分作品是否与版权受到保护的在世艺术家的作品相匹配。

这正是像 YouTube 这样的平台今天所使用的,例如,与人们上传的视频音乐相关的。会有很多假阳性之类的。就像 YouTube 现在使用的系统一样。这是保护活着的创意者和艺术家的权利所要付出的代价。

扩展这些机制来解释各种数据,以及比音频更复杂、更高维的数据,并不容易。但是肯定已经有人在做这些事情了。

如果我们再看看 YouTube,我们也可以看到平台可以处理基于非公共领域数据的生成性人工智能艺术的各种方式(预计平台最终将能够检测到这一点,要么是因为用户声明了它,要么是因为它们的自动系统检测到了它,要么是因为像 CAI 标准提出的技术有助于检测它)。

平台可能会在这些作品中添加广告,并与受影响的艺术家分享利润。或者他们可能会在受艺术家或创作团体相关版权影响的地区封锁部分或全部作品。或者他们会把它们放在单独的特殊类别中(远离人类创造的事物),而这些场景会得到进一步的澄清。我们也可能会目睹各种各样的方式来处理由人类+由公共领域数据驱动的人工智能系统产生的创作。总之,一旦检测系统变得足够好,将有许多方法来处理这些灰色地带。

那些探测系统的工作已经开始。通过使用智能元数据和其他工具, CAI 标准将很快开始在世界各地的公司和平台上实施。让我们简单探讨一下它的作用。

负责任的 AI 和内容真实性倡议(CAI)

许多公司和团体已经在研究和设计可以用来处理灰色地带和错误信息的系统。

这些系统中的一个是由 Adobe 启动的内容真实性计划。实际上是在 2019 年开始的,因为 Adobe 等公司预计到需要一个标准来处理人工智能工具产生错误信息和其他相关问题的可能性。

用他们的话来说, CAI 成员是:“一个由媒体和科技公司、非政府组织、学术界和其他人组成的社区,致力于推动采用内容真实性和出处的开放行业标准”。(现任成员名单)

该组织的成员资格是免费的,提供开源工具,允许在从捕获到分发的整个过程中跟踪数字内容的来源和属性。

最终目标是确保创意人员的工作得到认可,并且人们和平台能够理解他们正在处理的内容的制作所涉及的来源和方法是什么。

要强调的关键是,CAI 标准将使人们能够知道,生成式人工智能是否以及如何被用来创建某一段内容。

这是一个好迹象,表明有大公司正在努力推广他们所谓的“负责任的人工智能”。系统正在到位,这将允许我们知道每一个数字内容来自哪里,如果生成性人工智能参与其生产或没有,内容附带什么版权,等等。

需要强调的是,为了保护摄影记者和其他创作者的隐私和安全,这些创作者可以选择在使用这些系统时是保留署名还是保持匿名。

全世界都在关注。在最近的 视觉第一届 会议(成像生态系统的首要会议,在三藩市举行,由 Hans Hartman 和 Alexis Gerard 主持)上,生成性人工智能是谈话的一大部分。在活动开始的炉边谈话中,我有幸与汉斯和亚历克西斯进行了一次精彩的讨论。

视觉技术专家像 保罗·梅尔彻 正在做一项伟大的工作,将最新的生成式人工智能带给全世界的观众。

世界各地的教育者们,从像 T2 的 fast.ai 到 T4 的人工智能硕士项目,拥有成千上万追随者的 YouTubers 和 prompt 工程的专家们,正在记录和解释这场革命的每一个阶段。

数据集领域,我们也发现了非常有趣的公司和项目,如datasetshop.com,由虚拟驱动,是合法清洁合成股票媒体的先驱,也是世界上最大的可授权生物统计发布的真实生活数据集的创造者。

同样,这是一个好消息,我们正在见证“负责任的人工智能”和“合法清洁的”数据集等术语的兴起。

作为一个在生殖人工智能和艺术这两个领域都非常活跃的人,我试图在这篇文章中给你一个在这些动态早期阶段所涉及的一些观点的高层次概述。

让我们提醒自己,在一个快速发展的背景下,这些确实是早期阶段,所以**让我们尽可能温和地对待彼此,因为我们尽最大努力**在鼓励将为人类带来许多好处的技术与保护创意和艺术家权利的需要之间找到正确的平衡。****

未来会怎样

至于未来的时代,在我看来,简单地说:

  • 艺术家会继续做艺术家。正如本文试图解释的那样,成为或不成为艺术家与特定的工具或技术无关。相反,它与我们与之前探索的深度电梯互动的方式有很大关系。
  • 工程师会继续做工程师
  • 研究者将继续做研究者
  • 提示工程师(一个新段),将是那个,提示工程师。
  • 以及艺术家和创意人员,专业与否(以下同样适用于专业创意人员或那些天生倾向于锻炼其创意肌肉的人)将生成性人工智能技术和即时工程融入他们的过程中,将有更好的机会领导他们的领域,并可能成为更伟大的艺术家和创意人员,因为他们将在这些强大的钢铁侠套装(巨大的潜意识罐)的帮助下孵化他们的想法,并使用同样的技术来加速他们的创意生产过程。
  • 最后,懒人会一直做懒人。

让我们一起努力吧

艾肯定要回家了。为了尽可能造福人类,我们必须齐心协力,让这场革命发挥最大的作用。

为了完成这篇文章,我们已经探索了相当复杂的问题,让我们以一种更轻松的语气结束,用一些音乐来赞颂这一奇妙的技术

以下是女高音科瓦东加·冈萨雷斯·贝尔纳多的一小段表演,表演了一首由不同人工智能系统和我自己合作创作的歌曲。GPT 架构用于歌词,音乐变压器用于旋律+和弦,VQGAN 用于视觉效果。(这个小片段中没有出现视觉效果)。这是由人工智能研究所 @ iia.es,提出并组织的一个项目,我在那里做过几次演讲。

哈维尔·伊达米| ideami.com 的视频

接下来,一个简单的小钢琴 improv 致力于生成性 AI 回家的主题,更接近人类的潜能。

哈维尔·伊达米| ideami.com 的视频

最后,一点时间旅行的乐趣。我们能否都意识到,我们今天在生成式人工智能方面所经历的一切,在几十年前可能会被解释为一个奇迹?让我们回到 1950 年的西班牙:)

哈维尔·伊达米| ideami.com 的视频

好好对待每个人,最重要的是,保持人性。

收场白

关于我的最后一句话,“保持人性”。

有时,人们问我:我认为 30 年、40 年或 50 年后,当人工智能在系统 2 能力(推理、规划等)方面表现出色时,会发生什么?

系统 1 和系统 2 是我们心目中不同类型的思维模式

系统 1 指的是快速、潜意识、同时、直觉的过程,这是人工智能正在达到超人能力的领域。

系统 2 指缓慢的、逻辑的、理性的、系统的、精确的、顺序的那种思维。掌握第二种模式仍然远远超出了我们的人工智能系统。(参见丹尼尔·卡内曼的书思考快与慢”展开系统 1 vs 系统 2 的思考)。

关于现在和将来与人工智能相关的系统 2 能力的讨论,将会占满一整篇这样大小甚至更大的文章。所以我下次再讲。让我们回到这个结语开始时提出的问题。

我通常会回答,这个问题在几十年后可能不再有意义。为什么不呢?

因为今天AI 和人类之间有一个分离。AI 在那里。我们在这里。

但是几十年后,那种分离将不再存在。想想 Neuralink 公司这些天已经在做什么了。这只是未来的开始。

在几十年内,我们的技术,包括人工智能,和我们的生物学,将会在很多方面融合。

然后,新的问题可能是:“既然我们在一起了,接下来我们要去哪里?”****

感谢您的阅读。

凯莉·西克玛和 Firmbee.com 在 Unsplash 上的照片|贾维尔·伊达米的文字| ideami.com

用探测器 2 和 51 训练一个自定义物体探测器

原文:https://towardsdatascience.com/train-a-custom-object-detector-with-detectron2-and-fiftyone-4dc451839958

将 FiftyOne 的数据集管理与 Detectron2 的模型训练相结合,轻松训练自定义检测模型

图像 71df582bfb39b541 来自开放图像 V6 数据集( CC-BY 2.0 )在第五十一次可视化

近年来,机器学习(ML)生命周期的每个方面都有工具开发,使定制模型更容易从想法变为现实。最令人兴奋的部分是社区倾向于开源工具,如 PytorchTensorflow ,允许模型开发过程更加透明和可复制。

在这篇文章中,我们来看看如何集成两个开源工具来处理一个 ML 项目的不同部分: 第五十一个检测器 2 Detectron2 是由脸书人工智能研究所开发的一个库,旨在让您轻松地在自己的数据上训练最先进的检测和分割算法。FiftyOne 是一个工具包,旨在让您轻松地可视化您的数据,管理高质量的数据集,并分析您的模型结果。

总之,您可以使用 fiftone 来管理您的自定义数据集,使用 Detectron2 在您的 fiftone 数据集上训练模型,然后在 fiftone 中评估 Detectron2 模型结果,以了解如何改进您的数据集,继续循环,直到您有一个高性能的模型。这篇文章紧跟官方检测器 2 教程,对其进行扩充以展示如何使用 51 个数据集评估

跟随 Colab!

请在你的浏览器中查看这本笔记本并关注这篇文章。

Colab 笔记本截图(图片由作者提供)

设置

首先,我们需要安装51 个探测器 2

# Install FiftyOne
pip install fiftyone # Install Detectron2 from Source (Other options available)python -m pip install 'git+https://github.com/facebookresearch/detectron2.git'
*# (add --user if you don't have permission)*

*# Or, to install it from a local clone:*
git clone https://github.com/facebookresearch/detectron2.git
python -m pip install -e detectron2

*# On macOS, you may need to prepend the above commands with a few environment variables:*
CC=clang CXX=clang++ ARCHFLAGS="-arch x86_64" python -m pip install ...

现在让我们用 Python 导入 FiftyOne 和 Detectron2。

准备数据集

在本帖中,我们展示了如何使用自定义的 51 数据集来训练 Detectron2 模型。我们将从 COCO 数据集上预先训练的现有模型中训练一个车牌分割模型,该数据集可在 Detectron2 的模型动物园中获得。

由于 COCO 数据集没有“车辆登记牌照”类别,我们将使用来自51 数据集 Zoo开放图像 v6 数据集的车牌分割来训练模型识别这一新类别。

注意:开放图像 v6 数据集中的图像受 CC-BY 2.0 许可。

对于这个例子,我们将只使用数据集的官方“验证”分割的一些样本。为了提高模型性能,我们也可以从官方的“训练”分割中添加更多的数据,但这将花费更长的时间来训练,因此在本演练中我们将只坚持“验证”分割。

当从动物园下载数据集时,指定一个classes将确保只存在具有给定类之一的样本。然而,这些样本可能仍然包含其他标签,因此我们可以使用 FiftyOne 强大的过滤功能轻松地仅保留“车辆牌照”标签。我们还将取消这些样本的“验证”标签,并从中创建我们自己的拆分。

接下来,我们需要将数据集从 51 的格式解析为探测器 2 的格式,以便我们可以将其注册到相关的探测器 2 目录中进行训练。这是集成 51 和 Detectron2 最重要的代码片段。

注意:在这个例子中,我们特别将分割解析成边界框和折线。此函数可能需要根据被定型的模型及其预期的数据进行调整。

让我们来看一些示例,以确保所有内容都被正确加载:

在 51 中可视化 Open Images V6 训练数据集(图片由作者提供)

加载模型并训练!

官方探测器 2 教程之后,我们现在在 51 数据集上微调 COCO 预训练的 R50-FPN 掩模 R-CNN 模型。如果使用链接的 Colab 笔记本,这将需要几分钟的时间。

*# Look at training curves in tensorboard:*
**tensorboard** --logdir output

Tensorboard 训练指标可视化(图片由作者提供)

使用训练好的模型进行推理和评估

既然模型已经训练好了,我们可以在数据集的验证分割上运行它,看看它的表现如何!首先,我们需要将训练好的模型权重加载到检测器 2 预测器中。

然后,我们对验证集中的每个样本生成预测,并将 Detectron2 的输出转换为 fiftone 格式,然后将它们添加到我们的 fiftone 数据集。

让我们把预测形象化,看看这个模型做得怎么样。我们可以单击“val”标签旁边的眼睛图标,查看我们运行推理的所有验证样本。

探测器 2 的预测在 51 年显现。所示图片授权为 CC-BY 2.0 (图片由作者提供)

从这里开始,我们可以使用 FiftyOne 提供的内置评测方法。使用use_masks=True参数,evaluate_detections()方法可用于评估实例分段。我们也可以用它来计算 mAP,选项有 COCO 风格的(默认)或开放图像风格的 mAP 协议。

我们可以使用这个results对象来查看地图打印评估报告绘制 PR 曲线绘制混淆矩阵等等。

 precision    recall  f1-score   support

Vehicle registration plate       0.72      0.18      0.29       292

                 micro avg       0.72      0.18      0.29       292
                 macro avg       0.72      0.18      0.29       292
              weighted avg       0.72      0.18      0.29       292

51 中生成的精确召回曲线(图片由作者提供)

从 PR 曲线中,我们可以看到该模型没有生成很多预测,从而导致很多假阴性,但生成的预测通常相当准确。

我们还可以创建一个数据集视图来查看高可信度的假阳性预测,以了解模型哪里出错了,以及如何在未来潜在地改进它。

在 51 中发现不正确的预测,显示的图片由 2.0 授权 CC-BY(图片由作者提供)

有几个样本出现了像这样的假阳性,这些样本中含有非拉丁字母的字符。这表明我们可能希望将更多国家的图像引入训练集。

从这里,我们可以利用这些发现迭代数据集,改进样本和注释,然后重新训练模型。这种管理、训练和评估的循环需要反复进行,直到模型对于您的任务来说具有足够的质量。

摘要

Detectron2FiftyOne 是两个流行的开源工具,分别用于帮助 ML 模型开发的模型和数据集方面。只需几个自定义 Python 函数,您就可以使用 51 个精选数据集来训练 Detectron2 模型,并在 51 个中评估结果,从而让您比以往任何时候都更容易地为计算机视觉任务开发模型!

关于体素 51

披露:我在 Voxel51 工作,是 五十一 的开发者

总部位于密歇根州安阿伯市,由密歇根大学教授杰森·科尔索博士和布莱恩·摩尔博士于 2016 年创立, Voxel51 是 FiftyOne 背后的人工智能软件公司,fifty one 是一个用于构建高质量数据集和计算机视觉模型的开源工具包。

fiftyone.ai 了解更多!

用 PyTorch 训练神经网络检测乳腺 MRI 肿瘤

原文:https://towardsdatascience.com/train-a-neural-network-to-detect-breast-mri-tumors-with-pytorch-250a02be7777

医学图像分析实用教程

来自我们数据集的乳腺 MRI 扫描示例。

大多数具有深度学习的计算机视觉研究都是在常见的自然图像数据集上进行的,如 MNISTCIFAR-10ImageNet 。然而,计算机视觉的一个重要应用领域是医学图像分析,其中深度学习已用于癌症检测、器官分割、数据协调和许多其他示例等任务。然而,与自然图像数据集相比,医学图像数据集通常更容易“插入”深度学习系统。在这里,我提供了一个实用的分步指南,介绍如何使用深度学习来完成一个简单的医学图像分析任务,从数据采集一直到模型测试。

在这篇文章中,我将展示如何使用 PyTorch 训练一个神经网络分类器来检测乳腺 MRI 图像中的肿瘤。在我之前的文章中(在我实验室的博客上找到了,我介绍了我实验室公开的乳腺 MRI 数据集,以及如何使用 Python 与原始医学成像数据进行交互。我演示了如何以一种格式和标签提取和排序图像文件,这将有助于用 PyTorch 训练和测试我们的模型。该数据集最初出现在论文中:

Saha,a .,Harowicz,M.R .,Grimm,L.J .,Kim,C.E .,Ghate,S.V .,Walsh,r .和 Mazurowski,M.A .,2018。 乳腺癌放射基因组学的机器学习方法:对 922 名受试者和 529 个 DCE-MRI 特征的研究。 《英国癌症杂志》,第 119 卷第 4 期,第 508–516 页。(这篇论文的免费版本可以在这里找到:PMC 6134102)

有了我们的数据,我们可以继续构建、训练和测试我们的深度分类器。除了在计算机视觉中测量分类器性能(总预测精度)的典型方法之外,我还将展示如何使用医学图像分析常用的度量来进一步分析我们的模型的性能。

本教程的所有代码可以在这里找到;需要一些 Python 方面的经验,PyTorch 知识是有帮助的,但不是必需的。

(1)建立数据加载管道

深度学习是数据驱动的,因此拥有一个可靠的框架来处理(图像)数据至关重要。py torch(Python 中的torchtorchvision库)允许对数字矩阵进行有效的操作和管理,是最流行的深度学习框架之一(因为神经网络通过许多矩阵乘法和加法进行操作和学习)。图像也可以用大的数字矩阵来描述,其中矩阵的维数对应于图像的大小,矩阵的每个元素是一个像素强度值。因此,使用 PyTorch 对所有图像数据加载/处理和神经网络操作进行抽象是非常有帮助的,py torch 附带了无数方便的模块和工具来实现这些功能。

我们将使用的中心对象是torch.utils.dataDatasetDataLoader。虽然Dataset允许轻松存储和索引数据样本和标签,但DataLoader使我们能够以一种与我们将如何训练和测试神经网络非常好地集成的方式轻松访问这些样本。详情请见 PyTorch 的教程。首先,让我们导入所需的库和对象:

接下来,让我们定义一些常数:

数据集

首先,我们必须为 DBC 数据集定义我们自己的Dataset,称为DBCDataset。总之,DBCDataset中定义的重要方法有:

  1. create_labels()方法为数据集中的每个图像分配一个易于访问的标签,
  2. normalize()方法将图像标准化到像素值范围[0,255],因为标准化数据对于深度学习很重要,
  3. __getitem__()方法是Dataset所必需的,它描述了如何从带有一个(或多个)索引的数据集中获取数据

查看下面的代码块,我在其中添加了注释来解释每一步。

从这里,我们可以简单地创建一个数据集实例:

输出:

building DBC dataset labels. 
5200

训练集、验证集和测试集:区别是什么?

为了开发我们的分类模型,我们需要将数据集分成训练集、验证集和测试集。对于数据点中的每个图像,都有一个我们希望分类模型预测的关联标签。但是这些数据子集之间有什么区别呢?

  1. 定型集用于为模型提供如何进行预测的示例;这就是模型“学习”的内容。学习算法只是修改神经网络参数,以最小化训练集的平均预测误差。
  2. 验证集用于评估模型在预测未学习的新数据标签方面的表现(开发该模型的最终目标,也称为泛化)。此验证预测误差用于选择我们希望在训练中的哪一点保存模型:我们希望在验证误差最低时保存模型。您也可以使用验证集来选择超参数或不是从训练集中学习的训练算法设置。
  3. 测试集和验证集一样,也用于估计神经网络对新数据的泛化能力;但是,这必须与验证集分开,因为验证集本身是用来选择最终模型的,我们需要对泛化能力的无偏估计

对于 2600 + 2600 = 5200 的数据集大小,用于将数据集划分为训练/验证/测试的一组典型百分比可能是 80%/10%/10%,这导致训练集大小为 4160,验证和测试集大小分别为 520。实际上,我们可以使用有用的函数torch.utils.data.random_split()从我们的数据集中提取这些子集,该函数随机地将整个数据集分成子集:

输出:

5200 
4160 520 520

数据加载器

我们已经创建了 PyTorch Dataset用于模型训练、验证和测试,这是我们数据加载管道的大部分工作。最后,我们需要创建 PyTorch Dataloader来方便地访问数据集中的图像。但是首先,快速注意一下批次大小

批量大小和计算设备

虽然我们可以一次对一张图像训练神经网络,但这将非常慢,因为它们通常需要多次从数百或数千张图像中学习。相反,我们可以同时对多幅图像进行训练,受限于我们计算处理设备的存储容量;例如,GPU(图形处理单元),它是专门为图像处理而设计的。

下面,我们将为三个数据子集分别创建Dataloaders。对于训练集,我们将使用 200 的批量大小,但这在很大程度上取决于您用于计算的 CPU 或 GPU 硬件。对于大多数现实的计算机视觉应用程序来说,GPU 是必需的,因为 CPU 非常慢;因此,我们将使用 8 GB 的英伟达 GTX 1070。我们将在其上加载数据的设备可以通过以下方式指定:

输出:

running on cuda

现在,让我们创建我们的数据加载器:

接下来,为了确保我们的结果具有可重复性,我们将使用以下方法修复所有随机种子:

有了这些,我们就可以开始介绍和构建我们的分类神经网络了!

(2)加载神经网络

神经网络实际上只是具有许多许多参数的函数(也就是拨号调谐)。这些参数是从大量数据中学习到的来调整网络,以最佳地逼近我们试图模拟的功能。例如,像我们将使用的图像分类神经网络,被训练以图像作为输入,并输出图像的正确类别身份,例如,乳房图像是否是癌性的。神经网络的许多连续计算允许它们学习非常复杂的功能,这实际上是不可能手工设计的。

卷积神经网络是专门为学习检测图像中的空间模式而设计的,因此特别适合我们的任务。今天,我们将使用一种非常流行的现代神经网络架构,称为残差网络,简称为 ResNet 。事实上,根据谷歌学术的说法,最初的 ResNet 论文是有史以来被引用最多的论文之一,截至 2022 年 6 月已被引用超过 120,000 次。我们将使用 ResNet 模型的一个特定版本,称为 ResNet-18,其细节超出了本教程的范围。ResNet-18 和类似的模型可以很容易地用 PyTorch 的torchvision.models库加载(未经训练),如下所示:

这里我们也导入了 PyTorch 的神经网络库torch.nn。接下来,我们将加载一个 ResNet-18 来使用(因为resnet18是一个类):

ResNets 设计用于处理彩色三通道图像。然而,我们的 MRI 切片是单通道的,所以我们需要修改我们的net来接受单通道输入。这可以通过将net输入层修改为:

最后,我们需要将网络加载到我们的计算设备上:

这样,我们的网络就可以接受训练,对我们的图像进行分类。让我们建立一个培训管道!

(3)为培训做准备

神经网络通过最小化对整个训练集进行预测的平均误差来“学习”。在训练集上的每次迭代,或时期,调整参数以便在下一次迭代中表现得更好。每个参数的变化由反向传播算法决定,该算法调整每个参数,使给定迭代的误差在平均值上最大程度地降低(该过程被称为随机梯度下降或“SGD”)。

为了实现这一点,我们需要定义几件事情。首先,我们必须定义这个预测误差,也称为损失。对于分类的任务,我们需要的损失是nn.CrossEntropyLoss(),随着网络预测训练集中更多不正确的图像分类,损失增加。这是我们在训练中要尽量减少的;我们可以将其定义为:

接下来,我们要定义我们将使用的误差最小化算法;同样,这个是随机梯度下降,或 SGD 当然还有其他的,但是 SGD 是最基本的,也很好。当创建一个 SGD 实例时,我们需要告诉它我们将最小化哪些参数(参数net,和学习率)。学习率(lr)是一个固定的常数,它基本上决定了在学习过程中对参数进行调整的大致大小。根据任务、数据、网络和其他因素,可以选择不同的学习速率,但现在,我们将选择lr=0.001

最后,让我们将训练时期的数量(通过整个训练集)设置为 100:

(4)训练和验证你的模型!

我们现在拥有了训练分类模型所需的一切。如前所述,在每个训练时期,我们可以评估验证数据集上的模型,以估计它在看不见的数据上的表现如何。然后,我们将最终训练的模型保存为在训练期间在验证集上发现具有最佳性能/分类准确性的模型。

为了在实践中做到这一点,我们可以创建我们的培训模型net的副本,并将其保存为一个单独的网络net_final。让我们继续初始化它:

最后,我们可以用下面的代码(每一步都有注释)创建并运行我们的训练循环。在实践中,我们将使用分类准确度作为预测误差的度量,即给定数据集中被网络正确分类的图像的百分比。需要处理的一个微妙之处是,网络实际上输出了输入图像在每个类别中的概率。同样地,单个预测类仅由最高概率类给出。

我们还可以为训练集和验证集存储我们的精度与时期数据,以便观察模型如何通过训练演变。

好吧,让我们开始训练我们的模型吧!这可能需要一些时间,取决于您的计算设备的强度。我还包含了一些代码来记录训练的每一步。

输出:

### Epoch 0:
21it [00:16,  1.30it/s]
Training accuracy: 0.23557692307692307
100%|████████████████████████████████████████████████████████████████| 52/52 [00:01<00:00, 29.09it/s]Validation accuracy: 0.5153846153846153
Validation accuracy improved; saving model.### Epoch 1:
21it [00:15,  1.37it/s]
Training accuracy: 0.5454326923076923
100%|████████████████████████████████████████████████████████████████| 52/52 [00:01<00:00, 28.46it/s]Validation accuracy: 0.551923076923077
Validation accuracy improved; saving model.

…(未显示线路)…

### Epoch 98:
21it [00:14,  1.40it/s]
Training accuracy: 0.9992788461538461
100%|████████████████████████████████████████████████████████████████| 52/52 [00:01<00:00, 29.27it/s]Validation accuracy: 0.925
Validation accuracy improved; saving model.### Epoch 99:
21it [00:15,  1.39it/s]
Training accuracy: 0.9992788461538461
100%|████████████████████████████████████████████████████████████████| 52/52 [00:01<00:00, 28.57it/s]Validation accuracy: 0.9230769230769231

让我们通过matplotlib用一个简单的图表来看看我们的模型的性能是如何随着时间的推移而发展的:

输出:

一旦完全训练,该模型获得了 92.5%的验证准确性,这意味着在 520 个图像的验证集中,它正确地将其中的大约 480 个分类为癌症或非癌症。

您可能还会注意到模型过度适应了训练集。这可以通过某种正则化来缓解,但是这超出了本入门教程的范围。

这种性能很好,但是我们只有通过在测试集上对模型进行评估,才能知道模型对新数据进行分类的真正能力,如下所示。

(5)测试你的最佳模型

现在我们的模型已经训练好了,它在测试集上表现如何?我们可以用下面的代码来测试这一点,这里我还展示了一些分类的例子;这与我们在验证集上的评估非常相似。

医学图像分析中分类器性能的度量

在医学图像分析中,为了更好地分析分类器的表现,除了单独的分类精度之外,通常还要报告更多的性能指标。假阳性 (FP)是当分类器将阴性(无癌症)图像错误分类为阳性时,而真阳性 (TP)是当阳性图像被正确分类时。让我们在代码中也估算一下:

输出:

Example Images: 
Target labels: [0, 0, 0, 1, 1, 1, 0, 0, 1, 0] 
Classifier predictions: [0, 0, 0, 1, 1, 1, 0, 0, 1, 0] 
Test set accuracy: 0.9442307692307692
238 true positive classifications, 19 false positive classifications

在我们的 520 个未知样本的测试集上,我们得到了癌症检测任务的 94.4%的预测准确率,或者只有大约 30 个错误分类!在 257 个阳性(癌症)检测中,238 个或约 93%是真阳性(正确),而 19 个(约 7%)是假阳性(不正确)。

讨论

为医疗成像等安全关键型应用设计自动化方法时,检查可能的风险和限制至关重要。这方面的一个例子是假阳性的可能性:如果像这样的癌症检测模型被用于临床,阳性检测将立即保证对患者的进一步研究,因此假阳性可能是误导的。一个相关的可能性是假的阴性:肿瘤被检测模型完全遗漏。虽然我们的模型总体上具有很高的预测准确性,但它并不完美,因此不应该完全信任所有的诊断决策。这就是为什么计算机辅助诊断(CAD)设备的开发目标的常见范例是帮助而不是取代放射科医师。

同样重要的是要记住,用深度学习训练的模型完全是数据驱动的:它们完全根据训练集的标签进行学习。例如,在本教程中,我选择通过将 3D MRI 扫描的每个 2D 切片分配到阳性(包含乳腺肿瘤注释)或阴性类别来标记数据集。然而,即使来自 3D 扫描的一些切片被发现是阴性的,这并不而不是表明整个扫描/患者的癌症是阴性的:扫描中可能有其他切片是阳性的。这是一个例子,说明计算机辅助设计系统所做的所有预测都应该清楚地、可量化地表述出来。

有许多可能的补充可以用来改进这个检测模型。正如我们在第(4)节的训练演化图中看到的,我们的模型似乎过度适应训练集(由训练准确性和验证准确性之间的差距来指示)。这可以通过一些技术来减轻或防止;参见这篇教程,它很好地介绍了如何在 PyTorch 中做到这一点。我们可以做的另一个改进是训练我们的模型,不要将每个 2D MRI 切片分类为在某处有肿瘤,而是精确地定位切片内任何可能的肿瘤;在计算机视觉中被称为物体检测的任务。我在这篇文章中没有探讨这个问题,因为对象检测是一个比分类更微妙的问题,但它肯定可以用我们的数据集来实现,因为它包含肿瘤位置标签/边界框。快速 R-CNN 对象检测模型的 PyTorch 实现可能是一个很好的起点。

结论

在本教程中,我展示了如何在我们的 DBC-MRI 数据集上使用 PyTorch 通过深度学习来训练乳房 MRI 分类模型。

在我的实验室博客上的前一篇文章中,我介绍了 DICOM 医学成像数据类型,展示了如何从癌症成像档案中获取数据,以及如何从数据中提取对 PyTorch 有用的图像。

在这篇文章中,我展示了如何在真实的乳腺 MRI 数据上加载、训练和测试分类神经网络。

我写这些博客文章是为了提供一个介绍性的例子,说明如何将神经网络用于医学图像分析的实际应用。这仅仅触及了深度学习的广泛医学图像分析(MIA)应用的表面。对于有兴趣了解更多信息的人,请查看:

  1. MICCAI 会议的最新会议记录。
  2. 医学影像分析医学影像汇刊期刊。
  3. 我实验室的网站,以及我实验室的导师本人的学术出版物。
  4. 我的推特我实验室的推特

感谢阅读!

使用亚马逊 SageMaker 上的 PyTorch 训练和部署微调的 GPT-2 模型,以对新闻文章进行分类

原文:https://towardsdatascience.com/train-and-deploy-fine-tuned-gpt-2-model-using-pytorch-on-amazon-sagemaker-to-classify-news-articles-612f9957c7b

亚马逊 SageMaker 上使用 GPT-2 进行文本分类的教程

照片由 帕特里克·托马索

文本分类是自然语言处理中非常常见的任务。它可以用于许多应用,从垃圾邮件过滤、情感分析到客户支持自动化和新闻分类。使用深度学习语言模型进行大规模文本分类任务最近在业界变得相当流行,尤其是近年来随着变形金刚的出现。因为这些变压器模型的规模往往太大,无法在本地机器上训练,所以通常使用云计算平台(例如 GCPAWSAzureAlibabacloud )。因此,在这篇博客中,我想展示如何使用 Amazon SageMaker 来训练和部署一个用于文本分类任务的微调的 GPT-2 模型。

1.介绍

1.1 变形金刚:GPT-2 vs 伯特

GPT-2 属于深度学习模型家族,名为“变形金刚”。变压器是当前最先进的 NLP 架构的构建模块。在这里不可能用一段话来解释变形金刚是如何工作的,但总结一下,变形金刚使用了一种“自我关注”机制,通过“学习”句子中不同位置的单词之间的关系来计算序列的表示。典型的变压器设计包含两个部分,编码器解码器,两者都作为单词关系的矢量化表示。

GPT-2伯特分别是 2018 年和 2019 年发布的两款知名变形金刚型号。从那时起,有更新更好的模型发布(例如,2019 年的罗伯塔和 2020 年的 GPT-3 ),然而,这两个仍然非常受许多工业应用的欢迎,直到现在,由于它们伟大的可用性和性能。GPT-2 和伯特之间的关键区别在于,GPT-2 本质上是一个生成模型,而伯特不是。这就是为什么你可以发现很多技术博客使用 BERT 进行文本分类任务,使用 GPT-2 进行文本生成任务,但是很少使用 GPT-2 进行文本分类任务。这就是我决定在这里使用 GPT-2 的原因——它更具挑战性!

1.2 亚马逊 SageMaker

Amazon SageMaker 是一个很好的工具,可以通过 AWS 提供的完全托管的基础设施,在云实例上训练和部署深度学习模型。几分钟内,您就可以在 Jupyter 笔记本中构建、训练和部署模型,而不必担心环境设置,因为它附带了许多预构建的 Conda 环境和 Docker 容器。对于像我这样的数据科学家来说,这是一个巨大的救命稻草。

值得一提的是,SageMaker 还可以用于 Streamlit app 开发。这对于产品原型非常有用,因为在模型训练之后,您可以直接在同一个实例上构建应用程序。您将在本文中看到这一点。

2.系统需求

由于大多数模型培训和部署都将在 AWS 上进行,因此对您的本地机器没有任何系统要求。这是你需要的一切:

  • AWS 帐户(在此注册)
  • 一个 Google Drive 帐户(可选,用于 Colab 笔记本培训)
  • 本地 bash/zsh 终端(可选,用于 Streamlit 应用程序部署)

3.资料组

我们将在这个项目中使用的数据集是带有公共许可证的 BBC 新闻分类数据集 。你可以从 Kaggle 下载数据集

这个数据集是 CSV 格式的,它有两列:文本类别。它包含了 2226 个不同的文本,每个文本都被归入 5 个类别之一:娱乐体育科技商业政治

作者图片

4.演示

我使用运行训练好的模型的 Streamlit 构建了一个在线新闻分类器。您可以在这里输入或粘贴任何新闻,它将非常准确地生成新闻类别的预测。这个应用程序看起来很简单,但它运行着一个非常强大的深度学习模型!

看看这里: GPT-2 新闻分类器

(更新 2022.11.11:由于服务器成本,我关闭了这个应用的 AWS 服务器,并录制了一段 YouTube 视频作为这个应用的演示。不好意思!)

作者图片

5.在 SageMaker 上训练和部署 GPT-2

5.1.创建一个 Amazon SageMaker 笔记本实例

按照 AWS 的这个实践教程创建一个 Amazon SageMaker 笔记本实例。使用“gp T2-新闻分类器作为实例名,使用“ ml.t2.medium 作为实例类型

作者图片

5.2.培训和部署

当笔记本状态变为在用时,选择打开 Jupyter,上传该 Git 文件夹中的所有文件,结构如下:

├── gpt2-news-classifier-sagemaker-train-deploy.ipynb #main notebook
├── utils.py               # utility functions used by main notebook
├── code                   # separate PyTorch script folder
│   ├── requirements.txt   # libraries used by train_deploy.py
│   └── train_deploy.py    # PyTorch training/deployment script
├── data                   # data folder to be uploaded to S3 bucket
│   ├── test               # test data
│   │   └── test.csv
│   ├── train              # train data
│   │   └── train.csv
│   └── val                # validation data
│       └── val.csv
└── streamlit_app          # Streamlit app folder
    ├── Dockerfile         # Dockerfile for the app (container)
    ├── requirements.txt   # libraries used by app.py
    └── src                
        └── app.py         # main code for the Streamlit app

在 SageMaker 上运行这个笔记本来训练和部署 GPT-2 模型。通读它以获得关于实现的更多细节。

5.3.培训 _ 部署. py

由于我们在这个项目中构建和训练的是 PyTorch 模型,所以SageMaker Python SDK建议准备一个单独的train_deploy.py脚本来构建和存储 SageMaker 使用的模型函数。有两个基本功能,SimpleGPT2SequenceClassifiertrain

train_deploy.py 中的SimpleGPT2SequenceClassifier类负责在预训练的 GPT-2 模型之上构建一个分类器。这里的技巧是在 GPT-2 的 12 层解码器上添加一个线性层,其输出维度等于我们的标签数量。这样,我们可以使用 GPT-2 来输出 5 个数字,这 5 个数字对应于我们的 5 个新闻类别!

train_deploy.py 中的train函数在给定输入数据的情况下构建分类器的训练循环。

一个重要的注意事项:GPT-2 是一个文本生成模型,它的最后一个标记嵌入预测后续标记。因此,与使用第一个标记嵌入的 BERT 不同,在输入文本的标记化步骤中,我们应该使用最后一个标记,如下所示。( George Mihaila 在他的文章“使用拥抱脸变形金刚进行文本分类的 gp T2”中提供了一种优雅的方法,这就是我在这里使用的方法。)

6.Colab 笔记本培训

当谈到在云笔记本上训练深度学习模型时,亚马逊 SageMaker 的一个方便的替代品是谷歌的 Colab 笔记本。它在 AWS 中跳过所有你需要的云服务设置,最重要的是,它为模型训练提供免费的 CPU/GPU 实例(尽管有 12 小时的限制)!要使用它,只需打开你的 Google Drive ,选择新建- >更多- > Google 协同实验室。如果想用 GPU 加速训练,选择运行时- >改变运行时类型- > GPU ,就可以在那里写你的代码了!

我的 Colab 笔记本 以及资料可以在这里 找到

7.使用 Amazon EC2 和 Docker 进行部署

尽管模型部署可以在 SageMaker Notebook 实例中完成,正如我刚才所展示的,但是在实际的应用程序开发实践中,为了简单性和可再现性,通常建议将培训和部署分离。因此,我还使用 Docker 在 Amazon EC2 实例上部署了我们训练过的 GPT-2 模型。

7.1.创建 Amazon EC2 实例

按照 AWS 的教程创建并启动 Amazon EC2 实例。此项目的一些自定义设置:

  • 步骤 1:选择一个亚马逊机器映像(AMI) 中,选择深度学习 AMI (Ubuntu) AMI 。使用这个映像确实会引入一些额外的开销,但是,它保证我们会预装 git 和 Docker,这就省去了很多麻烦。
  • 步骤 2:选择实例类型中,选择 t2.large 以确保我们有足够的空间来构建和运行我们的 Docker 映像。
  • 步骤 6:配置安全组中,选择添加规则并为端口 8501 创建自定义 tcp 规则,以使我们的 streamlit 应用程序公开可用。
  • 点击启动后,选择创建新的密钥对,输入“ ec2-gpt2-streamlit-app ,点击“下载密钥对”将ec2-gpt2-streamlit-app.pem密钥对保存到本地。

7.2.在云中运行 Docker 容器

启动 EC2 实例后,使用 SSH 连接到该实例:

ssh -i ec2-gpt2-streamlit-app.pem ubuntu@your-instance-DNS-address.us-east-1.compute.amazonaws.com

然后,使用git将我的代码复制到云中:

git clone [https://github.com/haocai1992/GPT2-News-Classifier.git](https://github.com/haocai1992/GPT2-News-Classifier.git)

然后,进入ec2-docker-deploy文件夹构建并运行映像:

cd ec2-docker-deploy/
docker image build -t streamlit:gpt2-news-classifier-app .
docker container run -p 8501:8501 -d streamlit:gpt2-news-classifier-app

现在,您可以在http://<EC2 public IP address>:8501访问 Streamlit 应用程序(EC2 公共 IP 地址可以在 AWS 控制台的“IPv4 公共 IP”下找到)!

8.摘要

我希望你能从这篇文章中了解到,使用亚马逊 SageMaker 训练和部署一个深度学习模型一点也不复杂。无论如何,还有更简单的替代方案,比如 Google Colab 培训和 Amazon EC2 部署。希望这篇文章对你有用。

所有的源代码都可以在这个 Github 回购中找到:https://github.com/haocai1992/GPT2-News-Classifier

https://github.com/haocai1992/GPT2-News-Classifier

9.参考

接触

用 60 行代码训练用于目标检测的掩模 R-CNN 网络

原文:https://towardsdatascience.com/train-mask-rcnn-net-for-object-detection-in-60-lines-of-code-9b6bbff292c3

使用最少代码的循序渐进教程

对象检测和实例分割是识别和分割图像中的对象的任务。这包括为每个对象找到边界框、覆盖确切对象的遮罩和对象类。屏蔽 R-CNN 是实现这一点最常见的方法之一。

本教程旨在解释如何用最少的代码(60 行,不包括空格)训练这样一个网络。

对象检测/实例分割的例子。图像出现在左侧,对象及其类出现在右侧。

代码可在:https://github . com/sagieppel/Train _ Mask-RCNN-for-object-detection-In _ In _ 60 _ Lines-of-Code

该项目将使用 Pytorch 1.1 和 OpenCV 包。

请注意,PyTorch MaskRCNN 的实现可能与较新的 PyTorch 版本有一些问题,因此 PyTorch 1.1 是一个安全的选择。

Pytorch 安装说明可从以下网址获得:

https://pytorch.org/get-started/locally/

OpenCV 可以通过以下方式安装:

pip install opencv-python

接下来,我们需要一个数据集进行训练。我们将使用可以从这里下载的 LabPics V2 数据集:

https://Zeno do . org/record/4736111/files/labpicschemistry . zip?下载=1

该数据集在麻省理工学院的许可下可以免费使用。

我们将训练网络来检测图像中的所有血管。

现在我们可以开始写代码了。

首先,让我们导入包并定义主要的训练参数:

import random
from torchvision.models.detection.faster_rcnn import FastRCNNPredictor
import numpy as np
import torch.utils.data
import cv2
import torchvision.models.segmentation
import torch
import osbatchSize=2
imageSize=[600,600]device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')

imageSize=[Width,height] 是用于训练的图像的尺寸。训练过程中的所有图像都将调整到这个大小。

batchSize: i s 将用于每次训练迭代的图像数量。

批次大小宽度高度将与训练的内存需求成比例。根据您的硬件,可能有必要使用较小的批处理大小或图像大小来避免内存不足的问题。

请注意,由于我们只使用单一的图像大小进行训练,因此训练后的网络很可能仅限于使用这种大小的图像。在大多数情况下,您想要做的是改变每个训练批次的大小。

设备:自动设置网将要运行的设备(GPU 或 CPU),在实践训练中没有强大的 GPU 是极其缓慢的。

接下来,我们创建数据集中所有图像的列表:

trainDir="LabPicsChemistry/Train"

imgs=[]
for pth in os.listdir(trainDir):
    imgs.append(trainDir+"/"+pth +"//")

TrainDir: 是 LabPics V2 数据集训练文件夹。

是训练集中所有图像的列表

接下来,我们创建一个数据加载器函数,它允许我们加载一批随机图像及其数据用于训练。数据将包含图像:

图像

和图像中所有对象的遮罩。每个蒙版将被保存为黑白(0/1)图像:

图像中不同血管的遮罩。

完整的数据加载器功能代码是:

def loadData():
  batch_Imgs=[]
  batch_Data=[]
  for i in range(batchSize): idx=random.randint(0,len(imgs)-1)
        img = cv2.imread(os.path.join(imgs[idx], "Image.jpg"))
        img = cv2.resize(img, imageSize, cv2.INTER_LINEAR) maskDir=os.path.join(imgs[idx], "Vessels")
        masks=[]
        for mskName in os.listdir(maskDir):
            vesMask = cv2.imread(maskDir+'/'+mskName, 0)
            vesMask = (vesMask > 0).astype(np.uint8) 
            vesMask=cv2.resize(vesMask,imageSize,cv2.INTER_NEAREST)
            masks.append(vesMask) num_objs = len(masks)
        if num_objs==0: return loadData() boxes = torch.zeros([num_objs,4], dtype=torch.float32)
        for i in range(num_objs):
            x,y,w,h = cv2.boundingRect(masks[i])
            boxes[i] = torch.tensor([x, y, x+w, y+h])
        masks = torch.as_tensor(masks, dtype=torch.uint8)
        img = torch.as_tensor(img, dtype=torch.float32) data = {}
        data["boxes"] =  boxes
        data["labels"] =  torch.ones((num_objs,), dtype=torch.int64)   
        data["masks"] = masks batch_Imgs.append(img)
        batch_Data.append(data)  

  batch_Imgs=torch.stack([torch.as_tensor(d) for d in batch_Imgs],0)
  batch_Imgs = batch_Imgs.swapaxes(1, 3).swapaxes(2, 3)
  return batch_Imags, batch_Data

这个函数的作用是加载一组图像,对于每一幅图像,它加载一组图像中血管的掩模。然后,它为每个对象生成边界框和类。

让我们一行一行地看看这个函数:

idx=random.randint(0,len(imgs)-1)
img = cv2.imread(os.path.join(imgs[idx], "Image.jpg"))
img = cv2.resize(img, imageSize, cv2.INTER_LINEAR)

首先,我们从列表中选择一个随机图像( idx),加载图像,并将其调整到标准大小( imageSize )。

接下来,我们加载对象的遮罩。这些遮罩是与 RGB 图像大小相同的图像,其中对象实例的区域标记为 1,其余标记为 0。

maskDir=os.path.join(imgs[idx], "Vessels")
masks=[] # list of all object mask in the image
for mskName in os.listdir(maskDir):
            vesMask = cv2.imread(maskDir+'/'+mskName, 0) # Read mask
            vesMask = (vesMask > 0).astype(np.uint8) #convert to 0-1
            vesMask=cv2.resize(vesMask,imageSize,cv2.INTER_NEAREST)
            masks.append(vesMask) # add to the mask list

maskDir: 是储存血管实例贴图的子文件夹。

我们首先阅读面具。

vesMask = cv2.imread(maskDir+'/'+mskName, 0)

遮罩图像以 0–255 格式存储,并转换为 0–1 格式:

vesMask = (vesMask > 0).astype(np.uint8)

最后,遮罩被调整到标准图像大小,并被添加到遮罩列表中。

vesMask=cv2.resize(vesMask,imageSize,cv2.INTER_NEAREST)
masks.append(vesMask) 

接下来,我们使用遮罩为每个对象生成一个边界框。

 boxes = torch.zeros([num_objs,4], dtype=torch.float32)
for i in range(num_objs):
            x,y,w,h = cv2.boundingRect(masks[i])
            boxes[i] = torch.tensor([x, y, x+w, y+h])

幸运的是,OpenCV 具有从遮罩生成边界框的功能:

x,y,w,h = cv2.boundingRect(masks[i])

x,y: 是包围盒的顶部坐标。

w,h: 是边框的宽度和高度。

掩模 RCNN 边界框格式需要该框的左上和右下坐标,由: [x,y,x+w,y+h]给出。

boxes[i] = torch.tensor([x, y, x+w, y+h])

最后,我们将关于图像的所有信息堆叠到一个字典中。

 data = {}
data["boxes"] =  boxes
data["labels"] =  torch.ones((num_objs,), dtype=torch.int64)   
data["masks"] = masks

请注意,对于标签,我们只是为所有内容选择一个。这意味着我们只是把所有对象的类都看作是相同的(1)。

我们结束了。我们只需要将图像数据加载到训练批次中,并将其转换为 PyTorch 格式。

 batch_Imgs.append(img)
        batch_Data.append(data)  
batch_Imgs= torch.stack([torch.as_tensor(d) for d in batch_Imgs], 0)
batch_Imgs = batch_Imgs.swapaxes(1, 3).swapaxes(2, 3)
feturn batch_Imags, batch_Data

batch_Imgs,batch_Imgs: 是用于训练的图像批次(列表)及其数据。

现在我们有了数据加载器,我们可以开始构建网络了。首先,我们加载一个已经在 COCO 数据集上进行了预训练的掩模 RCNN 模型:

model=torchvision.models.detection.maskrcnn_resnet50_fpn(pretrained=True) 

使用现有知识的预训练模型可以比之前未训练的模型更快地学习新任务和数据集。

COCO 数据集包含 100 多个类。在我们的例子中,我们只需要两个类。因此,我们将改变网络的最终层,以预测两个类别:

in_features = model.roi_heads.box_predictor.cls_score.in_features 
model.roi_heads.box_predictor=FastRCNNPredictor(in_features,num_classes=2)

最后,我们将模型加载到训练设备 GPU 或 CPU:

model.to(device)

我们现在可以定义优化器,它将决定净重在训练期间的变化方式:

optimizer = torch.optim.AdamW(params=model.parameters(), lr=1e-5)

我们使用 AdamW,它是最新的优化器,具有标准的学习速率 lr=1e-5

我们将模型设置为训练模式:

model.train()

我们已经准备好编写主要的训练循环:

for i in range(10001):
   images, targets = loadData()
   images = list(image.to(device) for image in images)
   targets=[{k: v.to(device) for k,v in t.items()} for t in targets]

   optimizer.zero_grad()
   loss_dict = model(images, targets)
   losses = sum(loss for loss in loss_dict.values())

   losses.backward()
   optimizer.step()

   print(i,'loss:', losses.item())
   if i%200==0:
           torch.save(model.state_dict(), str(i)+".torch")
           print("Save model to:",str(i)+".torch")

我们正在为 10001 次迭代进行训练。

第一部分是使用我们刚刚定义的数据加载器函数加载数据:

images, targets = loadData()

接下来,我们将数据加载到训练设备(CPU/GPU)中

images = list(image.to(device) for image in images)
targets=[{k: v.to(device) for k,v in t.items()} for t in targets]

我们获取图像和数据,并通过我们的神经网络来计算损失:

loss_dict = model(images, targets)

损失由几个部分组成:类损失、边界框损失和遮罩损失。我们将所有这些部分相加,得出一个单一数字的总损耗:

losses = sum(loss for loss in loss_dict.values())

一旦我们有了损失,我们可以使用反向传播来更新神经网络的权重。

losses.backward()
optimizer.step()

我们希望每 500 步保存一次训练好的模型,以便以后使用。

if i%500==0:
    torch.save(model.state_dict(), str(i)+".torch")

仅此而已。经过 4-10k 的训练迭代,应该开始有不错的效果了。

完整代码可以在这里找到:https://github . com/sagieppel/Train _ Mask-RCNN-for-object-detection-In _ In _ 60 _ Lines-of-Code/blob/main/Train . py

一旦我们完成培训,我们想测试我们的模型。

为此,我们将使用此处提供的评估脚本:https://github . com/sagieppel/Train _ Mask-RCNN-for-object-detection-In _ In _ 60 _ Lines-of-Code/blob/main/test . py

该脚本类似于培训脚本。第一部分只是像以前一样加载网络。

device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')  
model=torchvision.models.detection.maskrcnn_resnet50_fpn(pretrained=True) 
in_features = model.roi_heads.box_predictor.cls_score.in_features 
model.roi_heads.box_predictor=FastRCNNPredictor(in_features,num_classes=2)model.load_state_dict(torch.load("10000.torch"))
model.to(device)# move model to the right devic
model.eval()

唯一的区别是我们还添加了一行来加载保存的模型,并将模型设置为评估状态而不是训练状态:

model.load_state_dict(torch.load("10000.torch"))
model.eval()

接下来,我们加载一个图像,将其调整为标准大小,并将其转换为 PyTorch 格式:

images = cv2.imread(imgPath)
images = cv2.resize(images, imageSize, cv2.INTER_LINEAR)
images = torch.as_tensor(images, dtype=torch.float32).unsqueeze(0)
images=images.swapaxes(1, 3).swapaxes(2, 3)
images = list(image.to(device) for image in images)

我们在网上运行图像:

with torch.no_grad():
    pred = model(images)

这将通过网络运行图像,并获得图像中对象的预测。注意,我们不是在训练网络,所以我们不需要收集梯度(no_grad ),这使得网络运行得更快。

预测由几个部分组成:“掩模”,对应于图像中每个对象的掩模(区域)。“分数”对应于预测的掩码正确的可能性。此外,我们有预测的边界框和类,但我们不会使用它们。

我们将检查所有的预测,并且只显示那些“分数”大于 0.8 的对象:

im= images[0].swapaxes(0, 2).swapaxes(0, 1).detach().cpu().numpy().astype(np.uint8)im2 = im.copy()for i in range(len(pred[0]['masks'])):
    msk=pred[0]['masks'][i,0].detach().cpu().numpy()
    scr=pred[0]['scores'][i].detach().cpu().numpy()
    if scr>0.8 :
        im2[:,:,0][msk>0.5] = random.randint(0,255)
        im2[:, :, 1][msk > 0.5] = random.randint(0,255)
        im2[:, :, 2][msk > 0.5] = random.randint(0, 255)
cv2.imshow(str(scr), np.hstack([im,im2]))
cv2.waitKey()

请注意,预测的对象“遮罩”以与图像相同的大小保存为矩阵,每个像素具有与它是对象的一部分的可能性相对应的值。

我们可以假设只有值大于 0.5 的像素可能是物体的一部分。我们通过为每个对象用不同的随机颜色标记这些像素来显示这一点:

im2[:,:,0][msk>0.5] = random.randint(0,255)
im2[:, :, 1][msk > 0.5] = random.randint(0,255)
im2[:, :, 2][msk > 0.5] = random.randint(0, 255)

结果可以在这里看到:

左边是原始图像,右边是预测对象区域。

完整的测试代码可以在这里找到:

https://github.com/sagieppel/Train_Mask-RCNN-for-object-detection-in_In_60_Lines-of-Code/blob/main/test.py

使用 PyTorch 屏蔽 RCNN 的教程:

https://py torch . org/tutorials/intermediate/torch vision _ tutorial . html

原版掩模 RCNN 论文可从这里下载:

并行训练和预测 Sci-Kit 学习模型

原文:https://towardsdatascience.com/train-predict-sci-kit-learn-models-in-parallel-510aee478426

在 Sci-Kit Learn 上并行化您的模型训练和预测

图片由马克·卡吉尔从 Unsplash 拍摄

本文将概述如何在 sci-kit learn 上并行训练和调优某些模型,以优化时间。我还将概述如何并行化这些模型的预测过程。我将介绍如何将数据划分为多个部分,并为每个部分生成预测,以及如何将整个数据集传递到多个模型中。我以前写过一篇关于多重处理以及如何将它用于单参数和多参数函数的文章。你可以在这里阅读它,因为我们将为这篇文章的内容使用多重处理模块。以下是这篇文章的提纲:

目录

  • Sci-Kit 学习并行化
  • 数据
    -需求
    -生成数据
  • 训练模式
    -正常训练
    -平行训练
  • 并行模型评估(交叉验证)
    -正常实施
    -并行实施
  • 并行模型预测—单一模型
    —架构
    —正常实现
    —并行实现
  • 并行模型预测—多模型
    —架构
    —正常实现
    —并行实现
  • 结束语
  • 资源

Sci-Kit 学习并行化

大多数机器学习项目有 4 个主要部分,需要大量的计算能力和时间。

  1. 模型训练
    -在各种列车测试分段上训练多个 ML 模型
  2. 模型的超参数调整
    -调整与模型相关的各种超参数,以最大化模型性能,而不过度拟合原始数据
  3. 模型评估
    -通过各种评估方法评估模型,如交叉验证、准确性、分类报告等。
  4. 模型预测
    ——为模型生成预测,使得推理时间很短。
    -与机器学习模型相关的推理时间是指模型处理输入数据并生成预测所需的时间。
    -您希望在最小化推理时间的同时最大化模型性能。推理时间短有助于生产环境中的可扩展机器学习。

这 4 个组件对于数据科学管道至关重要,每个组件都扮演着重要角色,并且每个组件都需要大量时间。令人欣慰的是,当通过 sci-kit learn(一个用于模型开发的开源库)进行机器学习建模时,大量的并行化已经内置于您训练的许多常见函数和模型中。sklearn 中函数的n_jobs参数指定了运行该函数时要使用的内核数量。

n_jobs是一个整数,指定并发运行的工作线程的最大数量。如果给定 1,则根本不使用 joblib 并行,这对调试很有用。如果设置为-1,则使用所有 CPU。对于低于-1 的n_jobs,使用(n _ CPU+1+n _ jobs)。例如使用n_jobs=-2,除了一个 CPU 之外,所有的 CPU 都被使用。
n_jobs默认为None,表示未置位;一般会解释为n_jobs=1
【1】https://scikit-learn.org/stable/glossary.html#term-n-jobs

请注意,并非所有的函数和模型都可以使用该参数,这意味着并非 sklearn 模块的所有特性都是并行的。例如,随机森林K 近邻等模型具有 n_jobs 参数,而弹性网梯度提升等模型则没有。要确定该参数是否可用于您正在使用的 sklearn 中的功能,您可以查阅与该功能相关的文档,并检查n_jobs是否在该功能的参数部分。

来自knighborsclassifier的 n_jobs 参数。图片由作者提供。

数据

我们将为下面的教程合成数据。我将强调如何生成一些假数据,以常规方式并通过并行化来训练、调整、评估和预测机器学习模型。在本教程中,我们将引用的主要模块是sklearnmultiprocessingpandasnumpy。以下是本教程中必须遵循的版本和要求。如果只是想参考与本教程相关的 Jupyter 笔记本,可以在我的 GitHub 这里找到。

要求

Python>=3.8.8
pandas>=1.2.4
numpy>=1.20.1
sklearn=0.24.1

我们也将依赖于multiprocessingrandomitertools库。不要担心,因为这些库已经预装了 Python。

生成数据

上面的函数将随机生成一个与图书相关数据相关的 CSV。数据将用于生成两个模型,一个通常没有并行化,另一个通过并行化。不会对数据进行任何特征工程或预处理,因为本文的范围是强调如何在 sklearn 模型上进行训练和预测。上面的函数应该产生如下所示的样本数据帧:

生成样本书数据。图片由作者提供。

培训模型

正常训练

梯度推进分类器没有n_jobs参数,因此您无法并行化该模型的模型训练过程。

平行训练

随机森林分类器有n_jobs参数,因此您可以将它指定为您想要使用的内核数量。

并行模型评估(交叉验证)

正常交叉验证

平行交叉验证

并行模型预测—单一模型

我们将把传递给模型的输入数据分成多个批次。这些批处理的大小相同,对应于您要用于并行化预测的内核数量。

架构

模型架构,用于将输入数据并行化为多个分区,并将每个分区并行传递给模型。图片由作者提供。

正常执行

并行实现

对于并行实现,我们将利用我们在正常实现期间创建的函数,并进行优化,以便使用 numpy 提供的array_split函数将 1 个参数分成 n 个分区。

并行模型预测—多个模型

现在,我们的目标是将两个单独的模型传递到两个不同的核心中,第一个模型将是我们上面生成的体裁模型,第二个将是语言模型。我们将把相同的数据传递到这些模型中的每一个,并并行地为这两个模型生成预测。

架构

将相同的数据并行传递给多个模型的架构。每个模型将属于它自己的核心。图片由作者提供。

正常执行

我们将从创建model_data开始,这是一个包含模型、特性列和目标名称的嵌套列表。我们可以迭代地传递输入数据和相关特征来生成预测。

并行实现

我们可以再次利用来自numpyarray_split函数来分割我们上面创建的model_data,并将每个模型数据传递到一个核心中。每个内核本质上都将运行上述正常实现中概述的multi_prediction功能。

结束语

本文概述了如何通过并行处理将 sci-kit learn 中花费在训练、调整和预测模型上的时间减到最少。sci-kit learn 已经在内部完成了并行训练模型的大部分繁重工作。

我提供了一个深入的教程,展示了并行生成预测的不同方法。概述的一种方法是,当您有多个模型时,您希望将数据传递给每个模型以生成预测。您试图预测的每个模型都将作为独立的进程并行运行。概述的另一种方法是当您有一个大型数据集,您想要更快地生成预测。在这种方法中,您可以将数据集划分为多个较小的段(您应该拥有的最大段数相当于您想要使用的最大内核数)。您可以将每个部分与模型一起传递,以并行生成预测,并将结果合并在一起。

请注意,这在您拥有大量内核和大型数据集时非常有用。当在少量数据上运行该过程时,正常(非并行)实现将在与并行实现相似的时间内运行。与该存储库相关的笔记本运行在少量数据上以提高效率,因为我没有太多可用的内存或内核。但是,您可以轻松地增加生成的数据量,从而增加为训练、评估和预测组件传递的数据量。

另一种优化模型预测时间的方法是通过稀疏矩阵。这个概念超出了本文的范围,但是如果您感兴趣,您可以在这里阅读相关内容。

如果你想了解与本文相关的代码,你可以查看我的 GitHub,我把笔记本放在这里

如果你想转型进入数据行业,并希望得到经验丰富的导师的指导和指引,那么你可能想看看最敏锐的头脑。Sharpest Minds 是一个导师平台,导师(他们是经验丰富的实践数据科学家、机器学习工程师、研究科学家、首席技术官等。)将有助于你的发展和学习在数据领域找到一份工作。点击这里查看。

资源

如果你喜欢读这篇文章,你可能会发现我写的关于数据科学和机器学习的其他文章也很有趣。下面来看看吧。

深度学习中的训练测试拆分

原文:https://towardsdatascience.com/train-test-split-in-deep-learning-e1b1fed01989

机器学习的黄金法则之一是将数据集分成训练集、验证集和测试集。了解如何绕过最常见的警告

我们这样做的原因很简单。如果我们不将数据分成不同的集合,模型将根据它在训练期间看到的相同数据进行评估。因此,我们可能会在不知不觉中遇到过度拟合等问题。

在使用深度学习模型之前,我们经常使用三个不同的集合。

  • 一个训练组用于训练模型
  • 用于在训练过程中评估模型的验证集
  • 用于在部署前评估最终模型准确性的测试集

我们如何使用训练、验证和测试集?

通常,我们使用如下不同的集合:

  1. 我们将数据集随机地分成三个子集,称为训练验证测试集。分割比例可以是 60/20/20 或 70/20/10 或任何你想要的比例。
  2. 我们使用训练组训练一个模型。
  3. 在训练过程中,我们在验证集上评估模型。
  4. 如果我们对结果不满意,我们可以更改超参数或选择另一个模型,然后再次进入第 2 步
  5. 最后,一旦我们对验证集上的结果感到满意,我们就可以在测试集上评估我们的模型。
  6. 如果我们对结果满意,我们现在可以再次使用我们最后导出的超参数在训练验证集上训练我们的模型。
  7. 我们可以在测试集上再次评估模型的准确性,如果我们满意,可以部署模型。

大多数 ML 框架为数据集的随机训练/测试分割提供了内置方法。最知名的例子就是 scikit-learn 的 train_test_split 函数。

使用非常小的数据集有什么问题吗?

是的,这可能是个问题。对于非常小的数据集,测试集将会很小,因此单个错误的预测会对测试准确性产生很大影响。幸运的是,有一种方法可以解决这个问题。

这个问题的解决方案叫做交叉验证。我们基本上创建了数据集的分区,如下图所示。我们总是拿出一套进行测试,并使用所有其他数据进行训练。最后,我们从测试集中收集并平均所有结果。我们基本上训练了 k 个模型,并使用这个技巧设法获得在完整数据集上评估模型的统计数据(因为每个样本都是 k 个测试集之一的一部分)。

来自维基百科的插图展示了 k 倍交叉验证是如何工作的。我们迭代地混合用于训练和测试的数据,并评估整体统计数据。

这种方法在最近的深度学习方法中很少使用,因为训练一个模型 k 次非常昂贵。

随着深度学习的兴起和数据集规模的大规模增长,对交叉验证或拥有单独验证集等技术的需求已经减少。其中一个原因是实验非常昂贵,而且需要很长时间。另一个原因是,由于大数据集和大多数深度学习方法的性质,模型受过度拟合的影响较小。

过拟合仍然是深度学习中的一个问题。但是过拟合 50 个具有 10 个特征的样本比过拟合 100k 个具有数百万像素的图像要快

有人可能会说,研究人员和从业人员变得懒惰/马虎。再次看到最近研究这种效应的论文会很有趣。例如,在过去的几年中,研究人员可能严重地过度适应了 ImageNet 的测试集,因为一直在努力改进它,使其成为最先进的。

我应该如何选择我的训练集、验证集和测试集?

天真地,人们可以手动将数据集分成三个块。这种方法的问题是,我们人类非常有偏见,这种偏见会被引入到三个集合中。

在学术界,我们知道我们应该随机选择他们。随机分成三组保证了所有三组遵循相同的统计分布。这就是我们想要的,因为 ML 是关于统计的。

从完全不同的分布中导出三个集合会产生一些不希望的结果。如果我们想用猫的图片来给花分类,那么在猫的图片上训练一个模型是没有多大价值的。

我应该如何选择我的训练集、验证集和测试集?

然而,随机分割的基本假设是初始数据集已经与我们想要解决的问题的统计分布相匹配。这意味着,对于自动驾驶等问题,我们的数据集涵盖了各种城市、天气状况、车辆、季节、特殊情况等。

正如你可能认为的那样,这个假设对于大多数实际的深度学习应用来说实际上是不成立的。每当我们在不受控制的环境中使用传感器收集数据时,我们可能不会得到理想的数据分布。

但是这很糟糕。如果我无法收集到我试图解决的问题的代表性数据集,我该怎么办?

你要寻找的是围绕发现和处理领域差距分布转移、数据漂移的研究领域。所有这些术语都有其特定的定义。我把它们列在这里,这样你可以很容易地找到相关的问题。

对于,我们称之为数据域,作为我们使用的数据的来源和类型。有三种前进的方式:

  • 通过收集更具代表性的数据来解决数据缺口
  • 使用数据监管方法使已经收集的数据更具代表性
  • 专注于构建一个足够健壮的模型来处理这样的领域差距

后一种方法侧重于为分发任务建立模型。

为分配外的任务选择训练测试分割

在机器学习中,每当我们的模型必须在新输入数据来自不同于训练数据的分布的情况下表现良好时,我们就称之为非分布。回到我们之前的自动驾驶示例,我们可以说,对于一个只在阳光明媚的加州天气下训练的模型,在欧洲进行预测是不合理的。

现在,对于这样的任务,我们应该如何分割数据集?

由于我们使用不同的传感器收集数据,因此我们还可能拥有关于每个样本来源的附加信息(样本可以是图像、激光雷达帧、视频等。).

我们可以通过以下方式分割数据集来解决这个问题:

  • 我们根据列表 A 中城市的一组数据进行训练
  • 并对来自列表 B 中城市的一组数据评估该模型

Yandex research 发表了一篇很棒的文章,介绍了他们解决数据集分布变化的新数据集。

可能出错的事情

验证集和测试集的准确性相差很大

您很可能将您的模型过度适应验证集,或者验证集和测试集非常不同。但是怎么做呢?

您可能会反复调整参数,以挤出模型在验证集上能够产生的最后一点准确性。验证集不再发挥其作用。此时,您应该放松一些超参数或引入正则化方法。

在导出我的最终超参数后,我想在发货前在完整数据集上重新训练我的模型(训练+验证+测试)

不,不要这样做。超参数已经针对训练(或者训练+验证)集进行了调整,当用于完整数据集时,可能会产生不同的结果。此外,当测试集不再存在时,你将无法回答你的模型实际表现有多好的问题。

我有一个视频数据集,想将这些帧随机分成训练集、验证集和测试集

由于视频帧很可能是高度相关的(例如,两个相邻的帧看起来几乎相同),这是一个坏主意。这与我们根据训练数据评估模型几乎是一样的。相反,您应该将数据集拆分为多个视频(例如,视频 1、3、5 用于训练,视频 2、4 用于验证)。您可以再次使用随机训练测试分割,但这次是在视频级别而不是帧级别。

Igor 联合创始人
Lightly.ai

https://medium.datadriveninvestor.com/the-advantage-of-self-supervised-learning-bd6fddc8f345

用 4 个简单的步骤在 Amazon SageMaker 中训练 XGBoost 模型

原文:https://towardsdatascience.com/train-xgboost-models-in-amazon-sagemaker-in-4-simple-steps-4eb3e104ee61

如何使用 SageMaker 训练和部署 XGBoost 模型作为端点

拉拉·阿兹利Unsplash 上的照片

开始使用 Amazon SageMaker 可能具有挑战性,因为 AWS 希望您知道许多技巧……反过来,一旦您掌握了这些技巧,您就可以显著加快 ML 模型的部署,而不必担心 Docker 和设置计算资源。

这篇文章的目标是尽可能简化 SageMaker 的入门,并向您快速展示部署 XGBoost 分类器需要什么,就像您在行业设置中通常会做的那样。大多数教程都是对 AWS 文档的直接背诵,如果您想根据实际问题定制模型,这些教程并不太适用。例如,使用样本 XGBoost 客户流失笔记本只能预测一个类别的概率,而不能预测单个类别(0 或 1)本身。

我们要建造什么

如果你像我一样,想要一只小狗,但由于空间的限制,现在还不能,我们至少可以做一些有它们参与的项目,对吗?让我们构建一个简单的 XGBoost 模型,告诉人们应该根据他们的家有多大来选择小猎犬还是德国牧羊犬。

来源:左[1]和右[2]

更具体地说,我们将使用一个虚拟数据集,它由代表房屋面积平方英尺的 X 变量和为 0(小猎犬)或 1(德国牧羊犬)的 y 目标变量组成。为简单起见,我们将 Beagle 设定为最适合小于 500 平方英尺的住宅,将德国牧羊犬设定为最适合大于 500 平方英尺的住宅

来源:左[1]和右[2]

在我们开始之前,你可能想知道这个 SageMaker 学习要花我多少钱?根据 AWS 定价页面,假设您将在美国东部 1 区工作,编写培训脚本需要大约4 小时,模型培训需要0.5 小时,测试终端需要1 小时,那么最终花费将少于 $1

**On-demand Notebook Instance**
(ml.t2.medium): $0.0464/hr * 4hr  = $0.2**Training Instance**
(ml.m4.xlarge): $0.24/hr * 0.5hr  = $0.12**Real-time Inference**
(ml.m4.xlarge): $0.24/hr * 1hr    = $0.24**Total**                               **<$1**

另一件有趣的事情是,大多数 SageMaker 教程希望您神奇地知道他们的基础设施是如何建立的。为了减轻这种情况,这里有一个简化版的一般工作流程,以及它将如何应用到我们的项目中:

作者图片

👉步伐

  1. 需要供应笔记本电脑实例
  2. 将培训/验证数据存储在 S3 存储桶中
  3. 训练和输出 ML 模型工件到 S3 桶
  4. 部署和测试 SageMaker 推理端点

1.创建 SageMaker (SM) Jupyter 笔记本实例

给它起个名字:

您可以保留默认的 IAM 角色,以允许 SM 访问您的 S3 存储桶:

一旦提供了笔记本实例,您就可以启动 Jupyter 实验室并启动一个 Conda Python 3 环境。

旁注(如果生活只有这么简单)

我们通常如何在本地训练 XGBoost

然而,这在 SageMaker 中不起作用,因为他们希望我们使用他们自己的估计器类,而不是直接导入 XGBoost 库,并且必须将我们的训练和测试数据集存储在 S3 中,作为 SageMaker 工作流的一部分。但是一定要在笔记本内部运行上面的代码片段来查看输出。

2.在 S3 存储数据

对于这一步,我们将重用我们的df _ train&df _ test(来自上面)并将其存储在默认的 S3 桶中,该桶将与我们的笔记本实例相关联。

让我们转到 S3 存储区,以确保我们的培训和验证数据集已正确存储:

太棒了,数据集已经成功加载到 S3,我们已经为下一步做好了准备。

3.训练和存储 ML 模型工件

我们可以检索预配置的 SageMaker 容器,其中包含 XGBoost(而不是直接导入 XGBoost ),并使用 TrainingInput 类加载数据集。

在超参数中,我们必须使用目标函数“multi:soft max”而不是“binary:logistic”,因为它只产生概率,而不是二进制值本身(0 或 1)。

4.部署和测试端点

我们准备将 XGBoost 模型部署为一个端点,然后它可以进行预测。

如果一切顺利,应该会看到这样的输出:

你可以在这里找到完整的 Jupyter 笔记本代码。

最后的话

像这样部署 ML 模型是非常好的,但是我们现在如何让互联网上的每个人都能够调用该端点,并找出适合他们特定房子的完美小狗呢?

简答:使用 Lambda & API 网关。

如果您想了解更多信息,请阅读我的下一篇文章,我们将详细介绍如何编写 Lambda 函数来处理输入请求(即房屋面积)并使用 API Gateway 创建一个 REST API 来接受来自客户端的请求。

但是如果你只是想测试 SageMaker,请遵循下面的清理步骤。

清理以停止产生费用!

1。通过运行删除已部署的端点

xgb_predictor.delete_endpoint()

2。停止 SageMaker 笔记本实例

感谢您的阅读,如果这篇文章帮助您节省了时间或解决了问题,请务必点击下面的按钮!总是非常感谢。

图像来源

[1]https://commons . wikimedia . org/wiki/File:Beagle _ puppy _ cadet . jpg

[2]https://pxhere.com/en/photo/1003603

使用 Python 训练 YOLO 在自定义数据集上进行对象检测

原文:https://towardsdatascience.com/train-yolo-for-object-detection-on-a-custom-dataset-using-python-e4fe5eb94673

非洲的野生马赛洛(图片由作者提供)

了解 Yolov4 和 Darknet 来训练自定义对象检测器

介绍

我最近开始从事计算机视觉领域的工作。在这些早期,我正在研究物体检测的各种算法如何工作。其中最知名的有 R-CNN快 R-CNN快 R-CNN 当然还有 YOLO

在本文中,我想重点讨论最后提到的算法。YOLO 是物体探测领域的尖端技术,YOLO 有无数的应用案例。然而,今天我不想告诉你 YOLO 是如何工作的,也不想告诉你它的架构,但是我想简单地向你展示如何启动这个算法,并做出你的预测。此外,我们还将了解如何在自定义数据集上对其进行训练,从而使其适应您的数据。如果你也想看我写的一篇关于 YOLO 内部运作的文章,请跟我来,因为我打算在未来几天内写这篇文章。

黑暗网络

我不认为有比你在他们的网站上找到的定义更好的方式来描述 Darknet。

Darknet 是用 C 和 CUDA 编写的开源神经网络框架。速度快,安装方便,支持 CPU 和 GPU
计算。你可以在 GitHub 上找到源代码,或者你可以在这里阅读更多关于 Darknet 可以做什么的内容。

所以我们要做的就是学习如何使用这个开源项目。

你可以在 github 上找到暗网代码。看一看它,因为我们将使用它在我们的自定义数据集上训练 YOLO。

克隆暗网

我将在下面这篇文章中展示的代码是要在 Colab 上运行的,因为我没有带 GPU 当然你也可以在笔记本上重复这段代码。偶尔会改变的是路径。

所以首先我们去克隆 darknet GitHub 库。如果我们使用 %%bash 命令,Colab 允许我们编写 bash 命令。

%%bash
git clone https://github.com/AlexeyAB/darknet

一旦你克隆了 repo,你会在你的工作目录中看到很多文件,放松,它看起来比实际上更复杂。
现在我们需要重新配置 makefile 。不知道 makefile 是什么?简而言之,它是一个使你的代码编译变得容易的文件。

如果你曾经用 C 语言编写过代码,你会知道实际的做法是写一个文件 file.c ,然后你用一个命令来编译它,比如 g++ etc…
这个命令用来编译在大型项目中可能会很长,因为它必须考虑依赖关系等等。

因此,每次通过重写 g++ etc…
进行编译都会非常费力,然后我们要做的是创建一个 makefile,其中已经包含了这个写好的命令,我们要做的就是启动 makefile 来编译代码
makefile 通常包含用户可以根据需要设置的配置变量

也就是说,我们要做的是设置一些在暗网 makefile 中找到的变量。
因此,请确保您有可用的 GPU,并运行以下单元。

%%bash
cd darknet
sed -i 's/OPENCV=0/OPENCV=1/' Makefile
# In case you dont have a GPU, make sure to comment out the
# below 3 lines
sed -i 's/GPU=0/GPU=1/' Makefile
sed -i 's/CUDNN=0/CUDNN=1/' Makefile
sed -i 's/CUDNN_HALF=0/CUDNN_HALF=1/' Makefile

在这个单元中,例如第一行中的命令 sed -i 允许您将 OPENCV 变量从 0 更改为 1。

我们在前一个单元格中设置的设置允许我们在 GPU 而不是 CPU 上启动 YOLO。
现在我们将使用 make 命令启动 makefile。

%%bash
#compile darkent source code
cd darknet

现在我们安装了一个库,它将在 YOLO 探测到的物体周围绘制边界框。

%%capture
!pip install -q torch_snippets

下载数据集

我将使用包含卡车和公共汽车图像的对象检测数据集。Kaggle 上有很多物体检测数据集,你可以从那里下载一个。

如果你不知道如何直接从 Colab 下载 Kaggle 数据集,你可以去看看我以前的一些文章。

所以我下载并解压数据集。

!wget - quiet link_to_dataset
!tar -xf open-images-bus-trucks.tar.xz
!rm open-images-bus-trucks.tar.xz

下图描述了下载的数据集的结构。

作者图片

下载 YOLO

显然,你不必从头开始做 YOLO 训练,而是直接从网上下载重量。
使用以下命令从 YOLO4 下载权重。

!wget - quiet https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights

要查看一切是否正常,请运行以下命令。

%%bash
#I had to use the flag -dont_show cause wasnt working. Try to run wiithout it
cd darknet
./darknet detector test cfg/coco.data cfg/yolov4.cfg ../yolov4.weights data/person.jpg -dont_show

在这个命令中,我们刚刚运行了

  • 我们指定我们想要 YOLO4: cfg/yolov4.cfg 的配置
  • 我们指定使用刚刚下载的权重:../yolov4.weights
  • 我们将对克隆了回购协议后获得的 coco 数据集进行预测: cfg/coco.data
  • 而我们做的预测如下图: data/person.jpg

准备数据集

YOLO 希望找到正确设置的某些文件和文件夹,以便在您的自定义数据集上进行训练。
首先,你需要在 darknet/data/obj.names 路径中打开你写标签的文件。
在 Colab 中,我们可以使用魔法命令通过单元格直接写入文件。magic 命令下的所有东西都会被复制
到指定的文件中。

%%writefile darknet/data/obj.names
bus
truck

现在我们需要修改另一个文件来告诉 YOLO 需要多少个类,在哪里可以找到训练和
验证的路径,以及在哪里可以找到带有标签名称的文件。我们可以简单地使用 magic 命令和下面几行代码来完成。

%%writefile darknet/data/obj.data
classes = 2
train = darknet/data/train.txt
valid = darknet/data/val.txt
names = darknet/data/obj.names
backup = backup/

所以为了理解它,你的 train txt 文件应该看起来像你在下图中看到的那样(类似于验证)。

其中每行指示在哪里找到训练图像。

但是我们指定的文件仍然是空的。因此,我们将下载的数据集文件夹中的数据复制到 Darknet 中的默认文件夹中。

!mkdir -p darknet/data/obj
!cp -r open-images-bus-trucks/images/* darknet/data/obj/
!cp -r open-images-bus-trucks/yolo_labels/all/{train,val}.txt darknet/data/
!cp -r open-images-bus-trucks/yolo_labels/all/labels/*.txt darknet/data/obj/
#add prefix 'darkent/' in front of each row in darkent/data/train.txt
!sed -i -e 's/^/darknet\//' darknet/data/train.txt
!sed -i -e 's/^/darknet\//' darknet/data/val.txt

就像我们之前下载 YOLO 的权重一样。这次我们拿 yolov4-tiny 比之前的快。
然后我们将权重复制到 Darknet 中适当的文件夹。

!wget - quiet https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v4_pre/yolov4-tiny.conv.29
!cp yolov4-tiny.conv.29 darknet/build/darknet/x64/

现在让我们重命名负责配置 yolov4 tiny 架构的配置文件。
之后,我们将编辑一些参数来设置批次数量、类别数量和其他参数。

%%bash
cd darknet
# create a copy of existing configuration and modify it in place
cp cfg/yolov4-tiny-custom.cfg cfg/yolov4-tiny-bus-trucks.cfg
# max_batches to 4000 (since the dataset is small enough)
sed -i 's/max_batches = 500200/max_batches=4000/' cfg/yolov4-tiny-bus-trucks.cfg
# number of sub-batches per batch
sed -i 's/subdivisions=1/subdivisions=16/' cfg/yolov4-tiny-bus-trucks.cfg
# number of batches after which learning rate is decayed
sed -i 's/steps=400000,450000/steps=3200,3600/' cfg/yolov4-tiny-bus-trucks.cfg
# number of classes is 2 as opposed to 80
# (which is the number of COCO classes)
sed -i 's/classes=80/classes=2/g' cfg/yolov4-tiny-bus-trucks.cfg
# in the classification and regression heads,
# change number of output convolution filters
# from 255 -> 21 and 57 -> 33, since we have fewer classes
# we don't need as many filters
sed -i 's/filters=255/filters=21/g' cfg/yolov4-tiny-bus-trucks.cfg
sed -i 's/filters=57/filters=33/g' cfg/yolov4-tiny-bus-trucks.cfg

训练模型!

现在我们准备好了,剩下的就是启动模型火车了

!./darknet/darknet detector train darknet/data/obj.data ./darknet/cfg/yolov4-tiny-bus-trucks.cfg yolov4-tiny.conv.29 -dont_show -mapLastAt

对我来说,这个训练花了大约一个小时。
现在你可以在你的图像上运行预测来得到类和边界框。

from torch_snippets import Glob, stem, show, read
# upload your own images to a folder
image_paths = Glob('images-of-trucks-and-busses')
for f in image_paths:
 !./darknet detector test \
 data/obj.data cfg/yolov4-tiny-bus-trucks.cfg\
 backup/yolov4-tiny-bus-trucks_4000.weights {f}
 !mv predictions.jpg {stem(f)}_pred.jpg
for i in Glob('*_pred.jpg'):
 show(read(i, 1), sz=20)

最后的想法

正如我们所见,使用 YOLO 并不复杂。我们可以克隆一些高效的实现,并将其用于我们的用例。就我而言,我只是用它来对我今年夏天去非洲旅行时拍的一些照片进行预测,以此取乐。😁

我还没有详细介绍这个算法是如何工作的,因为我想在以后的文章中使用自顶向下的方法来详细介绍。所以我希望你现在也能像我一样使用 YOLO 和玩它!

结束了

马赛洛·波利蒂

LinkedinTwitterCV

用 Linux 屏幕在远程终端上通宵训练你的模型

原文:https://towardsdatascience.com/train-your-model-overnight-on-remote-terminal-with-linux-screen-7fd68d812717

简单的 Linux 命令,继续在后台进行深度学习训练

图片由 HuperUnsplash

在本教程中,我将介绍一种在 Linux 终端上进行模型训练的方法,这将非常方便,尤其是当你需要通宵训练的时候。

另外,这个简短的教程假设读者了解简单的 Linux 命令,比如目录导航和文件复制。

接触机器学习有一段时间了,我对训练预测模型并不陌生。众所周知,有些模型需要很长的处理时间。特别是在深度学习中,预处理和训练神经网络模型有时需要几个小时,甚至几天才能执行。这通常是由于两个主要原因:

  1. 大量数据需要处理(大数据)
  2. 复杂的神经架构(例如变压器)

在本地机器上训练一个大模型可能很麻烦,因为这意味着除了消耗宝贵的计算资源之外,你可能还得让机器通宵开机。幸运的是,可以在私有服务器甚至云服务器上的远程 Linux 终端上训练您的模型,并保持训练过程在后台运行,即使在注销后也是如此。

1.远程服务器连接和文件传输

要从本地机器终端访问远程服务器 Linux 终端,请键入以下命令:

$ ssh remote_username@remote_IP_address

此外,当您想要退出 SSH 会话并返回到本地机器终端时,只需键入:

$ exit

远程私有服务器或云服务器本身是一台全新的机器。有时你需要安装不同的依赖和软件包,或者设置新的 python 虚拟环境,或者安装 Nvidia 驱动程序,如果你需要 GPU 来训练你的模型等等。完成所有这些工作后,就可以将数据集和代码从本地机器移植到远程服务器了。导航到本地机器终端上的数据集/代码目录。有两种方法可以转移。第一种方法是递归传输所有文件(一个接一个):

$ scp -r local_folder username@IP_address:/path/to/remote/folder

然而,这可能需要很长时间,尤其是如果有很多文件。在第二种方法中,我们可以先将本地文件夹压缩成 tar.gz 文件:

$ tar -czvf name-of-archive.tar.gz local_folder

然后通过 scp 将 tar.gz 文件传输到远程服务器,不使用-r 标记:

$ scp archive.tar.gz username@IP_address:/path/to/remote/folder

最后,导航到远程服务器上包含 tar.gz 文件的目录,并将其解压缩:

tar -xzvf archive.tar.gz

现在,我们准备开始在远程服务器终端上执行 python 脚本进行训练!

2.使用 Linux 屏幕进行背景培训

Screen 或 GNU Screen 是一个终端多路复用器。换句话说,这意味着您可以启动一个屏幕会话,然后在该会话中打开任意数量的窗口(虚拟终端)。当窗口不可见时,在屏幕中运行的进程将继续运行,即使您断开连接。

https://linuxize.com/post/how-to-use-linux-screen/

在终端上,您可以通过键入以下命令来启动屏幕会话。请注意,“会话名称”是您附加到屏幕会话的标签。

$ screen -S session_name

在该命令之后,终端上的屏幕会话将立即开始,就像您已经启动了一个新的终端一样。然后,您可以导航到模型目录以执行 python 命令来运行模型脚本:

$ python model.py

在屏幕会话中开始 NLP 深度学习模型的培训。图片作者。

现在,想象一下训练需要很长时间,你希望关掉电脑去睡觉。关闭终端意味着终止 SSH,模型训练也将终止。要让屏幕会话在后台运行,您应该在键盘上键入以下内容:

Ctrl+a+d

在屏幕会话期间键入 Ctrl+a+d 后的终端输出。图片作者。

该命令有效地分离屏幕会话,并将终端返回到原始状态。此时,您可以退出 SSH 会话,甚至关闭终端,您的 python 程序仍将在远程服务器的屏幕会话中继续执行。

几个小时后,您打开本地机器并通过 SSH 连接到远程服务器。要恢复屏幕会话并检索模型训练结果,只需应用以下命令即可:

$ screen -r session_name

恢复屏幕会话后,NLP 深度学习模型的培训已完成。图片作者。

3.最后的想法

就是这样!在远程终端训练一个模型就是这么简单!希望这篇教程对你有用。我知道一些崭露头角的数据科学家更熟悉 Jupyter 笔记本上的培训。但随着经验的积累,你可能会想要建立大型深度学习模型并将其生产出来。因此,有必要住在终点站。关闭 SSH 后,在远程机器上的背景中训练模型的这种做法带来了额外的好处。要了解更多关于 screen 命令的其他用法,您可以查看:

https://aditya-kumar130901.medium.com/linux-screen-work-from-home-made-easy-e83fa8575f2d

如果您对 Linux 终端、bash shell 和其他命令不熟悉,请订阅我的邮件列表,及时阅读我的文章。

感谢阅读!如果您喜欢这些内容,请在https://tanpengshi.medium.com/上阅读我的其他文章,并在LinkedIn上关注我。

支持我! —如果你没有订阅 Medium,并且喜欢我的内容,请考虑通过我的推荐链接加入 Medium 来支持我。

*https://tanpengshi.medium.com/membership *

为计算叉积的模型定型

原文:https://towardsdatascience.com/training-a-model-to-compute-cross-product-8c9390541fc9

如何使用 PyTorch 训练模型来计算叉积

照片由马特·里姆斯Unsplash 上拍摄

有很多关于使用 PyTorch 训练神经网络的教程。为此,我们在此提交一篇关于训练一个非神经网络模型的文章,重点是探索 PyTorch 的“pythonic 式”方面。

这里的任务是训练一个模型来计算两个三维向量的叉积。虽然点积和矩阵乘法在深度学习中被广泛使用,但叉积并不常见。下图展示了这个概念。

来源:https://www . khanacademy . org/math/multivariable-calculus/thinking-about-multivariable-function/x786f 2022:vectors-and-matrix/a/cross-products-MVC

我更喜欢用张量形式定义叉积:

这里ϵ是李维-西维塔张量。我们在这里使用指数符号或简化的爱因斯坦符号,这意味着对于重复的指数求和是隐含的。

这是我们模型的基础,张量ϵ是模型的一个可训练参数,我们期望它与 Levi-Civita 张量相匹配。

监督学习

首先,我们将使用监督学习方法。我们将运行提供两个随机向量的模型,然后将预测与预期叉积进行比较。

损失与步数的关系

4.906782535840648e-09print(ep)Parameter containing:
tensor([[[ 1.0955e-05,  2.9630e-05, -3.7728e-05],
         [ 1.4276e-05,  8.8082e-05,  9.9998e-01],
         [-9.9078e-06, -1.0000e+00,  1.8971e-05]], [[ 8.3094e-06,  1.7124e-06, -9.9999e-01],
         [ 2.7287e-05, -1.4629e-05, -1.5764e-05],
         [ 9.9996e-01, -3.1703e-05, -3.2365e-06]], [[ 2.5212e-05,  9.9996e-01,  2.0671e-05],
         [-9.9997e-01, -3.3963e-05,  1.0797e-05],
         [-3.0542e-05,  3.7616e-05, -6.0207e-05]]], requires_grad=True)

我们来讨论一下上面的代码:

  1. 在我们的例子中,模型是一个具有形状(3,3,3)的参数ep。它被初始化为随机值,但是我们期望它收敛到 Levi-Civita 张量。
  2. 我们不批量处理向量,因此我们只迭代步骤,不迭代时期。这也意味着没有一个张量有批量维度,这当然更容易理解。
  3. 函数torch.einsum()是我在深度学习中最喜欢的工具之一。我已经提到了索引,或爱因斯坦符号。einsum代表爱因斯坦和。它象征性地显示了张量乘法是如何工作的,求和是通过哪些索引发生的,以及结果的预期维数是多少。我喜欢它,因为当我处理多维张量时,我不必担心转置或置换,我可以清楚地看到求和是如何完成的。
  4. 这里的损失是预测值和实际叉积之差。如你所见,训练快速收敛,并且训练的结果张量ep非常接近 Levi-Civita 符号。

使用叉积的属性为模型定型

在上一节中,我们使用监督学习来学习 Levi-Civita 张量和三维向量的叉积。对我来说,这感觉像是欺骗。我们是否可以根据一些一般原则,而不是通过比较预测值和期望值,来推导叉积?

我们将训练我们的模型来满足这些标准:

  1. 叉积运算是反对称的,即

2.它是标准化的,也就是

都等于一。

3.叉积与两项正交,即点积为零:

这些标准仍然不足以保证我们正确地学习叉积函数,因为我们有可能学习负叉积函数。换句话说,这个模型会产生ϵ或者−ϵ

1.2659466847253498e-05epParameter containing:
tensor([[[-1.5880e-05,  4.7683e-05,  5.3528e-05],
         [-4.6085e-07,  4.7272e-05, -9.9767e-01],
         [-2.9965e-05,  9.9688e-01, -4.0021e-05]], [[-4.0523e-05,  1.7235e-05,  9.9770e-01],
         [-3.0135e-07, -1.1027e-05, -6.7566e-05],
         [-9.9676e-01,  1.5644e-05,  5.9592e-05]], [[-7.9570e-06, -9.9768e-01, -1.1900e-05],
         [ 9.9689e-01, -4.3567e-05, -3.2372e-05],
         [-7.1624e-06,  3.8180e-05,  6.8536e-05]]], requires_grad=True)

代码块几乎完全相同,但损失的计算方式不同。损失的第一部分不利于学习的操作不是反对称的情况。

为了计算损失的第二部分,我们计算单位矢量上的张量运算。对于叉积,我们期望单位向量的叉积长度为 1。我们计算三个张量运算 e1e2e1e3e2e3 ,并试图使它们的长度为 1,因为它应该用于叉积。

对于损失的第三部分,我们取预测和向量 ab 的点积,并惩罚非零结果。让我们回顾一下结果:

tensor([ -5.2354,  88.7160, -26.9144], grad_fn=<ViewBackward0>)
tensor([  5.2500, -89.0000,  27.0000])

我们可以看到,我们确实学习了负叉积。实际上,叉积的符号是约定俗成的,即 e1e2 的叉积是 e3 而不是 -e3 。我邀请读者修正损失函数,以便它更喜欢叉积的正确符号。

结论

您可能注意到了,这段代码看起来多么“pythonic 化”。我们不需要创建一个计算损耗的函数(尽管这可能是一个好主意)或者一个自定义层(对于更复杂的模型我们应该这样做)。我们甚至不需要创建一个模型类,因为我们唯一需要训练的是一个单一的参数。

虽然本教程非常简单,但它有很多改进的机会。例如,我们可以考虑三维以上向量空间的叉积,创建一个模块,甚至一个封装功能的层类。这里用到的所有代码都可以在 my github repo 上找到。

手动训练神经网络

原文:https://towardsdatascience.com/training-a-neural-network-by-hand-1bcac4d82a6e

神经网络背后的数学导论

网络图片——作者克林特·王茂林

介绍

在本文中,我们将讨论训练一个解决回归问题的简单神经网络背后的数学原理。我们将使用输入变量 x 来预测输出变量 y。我们将手动训练两个模型,然后使用 Python 训练最终模型。

在开始之前,最好了解一点多元微积分、线性代数和线性回归,以便完全理解本文中解释的数学过程。如果没有,我会考虑探索可汗学院,因为他们在这些主题上有一些很棒的课程。

让我们首先定义一些数据点来训练模型。

1.超级简单神经网络

第一个神经网络将具有带有单个节点的输入层和带有单个节点的输出层。输出层将具有线性激活函数。这是你能得到的最简单的神经网络,但是从这个模型开始会使数学变得非常直观。我们将从初始化模型开始,权重为 0.5,偏差为 0。

初始化模型参数最简单的方法是用 0 到 1 之间的值随机化权重,并用 0 初始化偏差值。设置起始参数的其他方法包括 He 初始化和 Xavier 初始化,旨在减轻爆炸/消失梯度并加速收敛,但这些超出了本文的范围。

前进传球

第一步是通过模型传递我们的输入变量来衡量它的表现。这叫做向前传球。

简单神经网络初始参数—作者

在上图中,a(x)是该节点输入的线性组合,h(x)是转换 a(x)的激活函数。当我们使用线性激活函数时,输入的线性组合不会改变。

整个正向传递由以下函数表示。这可能看起来很熟悉,因为这是一条直线的方程。

因此,通过插入每个数据点,我们可以求解方程来获得我们的初始模型预测。

然后,我们使用一个误差函数来确定我们的预测有多好。在这种情况下,我们将使用 1/2 * MSE(均方误差)。我们乘以因子 1/2 的原因是,它减少了我们在反向传播期间计算的链式偏导数中的系数数量。如果这没有意义,不要担心,我将在文章的后面解释它。1/2 * MSE 的公式和计算如下所示。

然后,我们可以使用 matplotlib 可视化初始预测。在下图中,蓝色点是真实标注,橙色点是预测标注。蓝线显示了神经网络如何对 0-1 之间的其他 x 值进行分类。重要的是要注意,这条线有一个恒定的斜率,这是预期的,因为模型方程正是直线方程。

简单神经网络初始预测-作者

反向传播

看着上面的图表,你可能会想,你可以选择一个 y 轴截距和斜率来进行更好的预测。你可能是对的。在这一节中,我们将使用反向传播向正确的方向迈出一步。

在反向传播期间,我们对模型中的每个权重和偏差取误差函数的偏导数。误差函数在其方程中不包含任何权重或偏差,因此我们使用链式法则来实现。这样做的结果是每个参数应该被调整的方向和幅度,以最小化误差函数。这个概念叫做梯度下降。

重量的链式导数

让我们从计算误差相对于重量值的偏导数开始。我喜欢大声读出链式偏导数,因为它使过程更容易理解。例如,在下面的链式导数中,我们取“误差函数相对于激活函数 h11 的偏导数,然后我们取激活函数 h11 相对于线性组合 a11 的偏导数,然后我们取线性组合 a11 相对于权重 w11 的偏导数。”

我们将计算的第一偏导数是误差函数相对于激活函数 h11 的偏导数。这就是我们看到使用 1/2 * MSE 的好处的地方。通过乘以因子 1/2,我们在所得的偏导数中消除了所有系数(除了 1)。

接下来,我们取激活函数 h11 相对于线性组合 a11 的偏导数。由于激活是线性的,这实质上是一个函数对自身的偏导数,也就是 1。

最后,我们求线性组合 a11 相对于权重 w11 的偏导数。

把所有这些放在一起,我们得到下面的等式。我们可以通过这个等式传递所有点,并取平均值来确定我们应该如何改变 w11 参数以最小化误差函数。这被称为批量梯度下降。如果我们使用数据点的子集,这将被称为小批量梯度下降。

偏差的链式导数

我们还没做完偏导数呢!我们还必须调整偏差值。除了链中的最终导数之外,该参数以与重量非常相似的方式更新。谢天谢地,在上一节中,我们已经计算了除一个导数以外的所有导数。

偏差项的链式导数如下所示。注意它和重量的链式导数是多么的相似。

我们需要计算的唯一偏导数是线性组合 a11 相对于偏差 b11 的偏导数。

将所有这些放在一起,我们可以求解每个数据点的方程,并获得我们应该对 b11 做出的平均变化。

更新重量

现在我们已经计算了重量的偏导数,我们可以更新它的值。权重变化的幅度取决于一个称为学习率的参数。如果学习率太低,达到最佳模型参数将需要大量的历元。如果学习率太高,我们会不断超调最佳参数组合。在本文中,我们将使用学习率 1。学习率通常在 0-1 的范围内。

更新每个权重的公式如下。注意,学习率由α表示。

更新偏差

然后我们可以对偏差做同样的处理。用于更新它的公式本质上与用于权重的公式相同,变化的幅度也取决于学习速率。

又一次向前传球

现在我们已经更新了网络的权重和偏差,它应该可以做出更好的预测。

简单神经网络更新参数—按作者

让我们执行另一个向前传递来确认这种情况。

然后我们用 1/2 * MSE 来评估预测有多好。

哇!我们能够在一个时期内将误差函数从大约 0.08 改善到大约 0.02。理论上,我们会不断更新权重和偏差,直到我们停止改进误差函数。在现实世界中还有其他需要考虑的事情,例如过度拟合训练数据和使用验证集,但我们现在将跳过这一点。让我们想象 1 个纪元后的预测。

简单神经网络更新预测-作者

我之前简单提到过这个模型是一个简单的线性回归模型。这是因为我们使用了线性激活函数、单输入和单输出节点。如果我们将输入节点的数量增加到 x 的递增幂,我们可以建立任何程度的线性回归模型。这很酷,如果你已经理解了线性回归模型,这是一个过渡到神经网络的好方法。

2.稍微复杂一点的神经网络

在本节中,我们将拟合一个具有两个输入节点(x 和 x)和一个输出节点的神经网络。虽然仍然是一个简单的网络,这个模型将显示如何使用神经网络创建一个二阶线性回归模型。

SMC 神经网络初始参数—作者

前进传球

在这个网络中,向前传球的公式比前一个模型稍微复杂一些。

使用我们的训练数据,我们可以解决每个数据点的方程。x1 就是 x,x2 是 x 的平方。

然后,正如我们对之前的模型所做的那样,我们用误差函数(1/2 * MSE)评估预测。

在下图中,我们可以看到,由于我们添加了第二个输入参数,这条线(向上的曲线)有一点凸起。

SMC 神经网络初始预测—作者

反向传播

现在我们已经做出了初步的预测,我们可以反推计算我们应该如何改变权重和偏差。我们需要计算的三个偏导数链如下。

上面三个方程的前两个偏导数与我们用之前的模型计算的完全相同。

每条链的最终偏导数如下。

然后我们就可以把每个导数链放在一起,对每个数据点求解,对每个链取平均值!

接下来,我们使用与之前相同的公式更新权重和偏差。

我们将再次使用学习率 1。这触发了参数的大跳跃,并且有利于在 1 个时期之后可视化模型中的变化。通常,您会设置一个较低的学习速率,并执行多个时期。

又一次向前传球

最后,我们可以执行另一个向前传递,看看模型改进了多少!

厉害!我们将误差函数从大约 0.06 降低到大约 0.01。在下面的单元格中,我们看到了这种改进。我们对模型训练得越多,我们就应该越接近精确拟合数据点。蓝线是更新的模型,灰线是初始模型。

SMC 神经网络更新预测-作者

3.用代码训练神经网络

现在我们已经完成了所有的数学,我想向你展示如何使用 Python 训练一个模型。我们上面所做的计算可以由计算机每秒钟完成数千次。下面的代码块为模型定义了一个神经网络类。我鼓励你浏览类函数和代码注释来确认这一点。

首先,我们实例化该类并传入 x 和 y 值。然后,我们可以迭代地执行前向传递和后向传播来更新模型参数。在下面的例子中,我们为 3000 个时期训练模型,并且每 500 个时期记录模型预测。

带代码的 SMC NN 按作者

正如我们所见,该模型不断改进其预测,经过 2500 个时代后,我们得到了一个高度准确的模型。由于该模型反映了二阶线性回归模型,因此它仅限于凸函数,其缩放和变换取决于模型参数。训练数据点并不完全是凸函数,因此我们需要增加输入节点的数量来完美地拟合数据。

最后的想法

我认为神经网络背后的数学非常棒。希望本文中的几个例子和一些样本数据有助于展示这一点。从线性回归模式的神经网络开始是一个很好的起点,但当您添加多个层和非线性激活函数时,神经网络的真正预测能力就会释放出来。

这篇文章的代码可以在这里找到。

资源

  1. 训练神经网络——杰瑞米·乔登
  2. 激活函数及其导数——Lakshmi Panneerselvam
  3. 与 RELU 的反向传播—堆叠交换讨论
  4. 权重初始化技术— Saurabh Yadav
  5. 深度学习偏差反向传播——Enes Zvornicanin
  6. 逐步反向传播—哈尼族 M. K.

在 TFRecord 文件上训练神经网络

原文:https://towardsdatascience.com/training-a-neural-network-on-tfrecord-files-8bff3b6e9ff4

TensorFlow 的格式可能不容易开始,但它非常适合模型训练

TFRecord 格式是 Google 用于高效存储和读取数据的数据格式。虽然潜在的想法很简单——将对象打包到盒子里——但第一步有点神秘。我在之前的一篇文章中已经介绍了这个想法,并开始以这种格式存储各种数据类型。

这篇文章延续了以前的工作,并进一步展示了在自定义 TFRecord 数据集上训练神经网络,这是以前没有的。就本文的范围而言,我们创建的数据集非常简单:红色、绿色和蓝色图像的集合。首先,我们导入所有必需的包:

作为上述代码的一部分,我们还直接设置了图像的大小。这些图像只有一种颜色,所以尺寸小于所选的 250×250 像素也可以。然而,与前一篇文章一样,这篇文章同时展示了如何将一个(自定义)数据集分布在多个 TFRecord 文件中。如果我们设置更小的图像尺寸,例如 32 乘 32,所有的数据将更容易放入一个文件中。

数据集创建

也就是说,下面的函数为我们生成了给定形状的 n 幅图像。每个数据样本根据其颜色进行标记:0 代表红色,2 代表绿色,3 代表蓝色。要创建的图像的颜色是随机选择的,只需先画出标签,然后相应地着色即可:

下面是我们如何创建和检查返回的数据:

创建 TFRecords

我们的下一步是将自定义数据集写入 TFRecord 格式。为此,我们将首先定义四个辅助函数:

下一步将使用这些函数来准备写入磁盘的数据。根据我们想要编码的信息,我们选择了效用函数:

下一步,我们构建中央数据写入函数。它接受图像、它们的标签、要写入数据的文件名、每个 TFRecord 文件的最大样本数和一个输出目录。

在这个方法中,我们迭代分割(即,我们想要分割数据的文件数量)并用图像-标签对填充它们。这一步调用我们之前的函数(第 27 行):

要开始将数据写入 TFRecord 格式,我们使用以下命令调用该函数:

根据图像大小、要解析的图像数量以及底层机器的计算能力,这个步骤需要几秒钟。TQDM 库(pip install tqdm)通过保持整洁的进度条来显示进度。

从 TFRecords 中读取

我们现在倾向于加载函数来训练数据集上的神经网络。从我的 TFRecords 实用指南可以看出,我们可以考虑将数据存储在带标签的桶中。当我们想要读回数据时,我们遍历这些桶,并为每个例子请求图像数据和相应的标签。以编程方式,此步骤由以下函数处理:

仅仅使用这个函数,我们不会走得很远。我们还需要一个(小的)方法来查找所有的 TFRecord 文件,并在数据加载期间通过数据提取方法输入每个样本。此任务通过以下函数完成,该函数返回 TensorFlow 数据集:

为了获得数据集,我们调用这个函数。此外,我们对数据进行批处理,并将每个图像(在下面的代码中命名为 x )归一化到 0.0 到 1.0 的范围内。这种重新调整是标准做法:

让我们用下面的代码来可视化一些示例:

输出是一个三乘三的矩阵,包含来自数据集的九个样本:

来自我们三色数据集的九个示例及其标签。图片由作者提供。

训练神经网络

下一步,我们创建神经网络。我选择了一个简单的架构。对于其他问题/数据集,可能需要更复杂的网络):

与模型一起,我们创建了损失、指标和优化器。我把自己限制在标准的选择上;请随意尝试:

最后一步是培训的开始:

因为我们简单的数据集,网络可以快速区分不同的颜色。要达到完美的训练分数和零损失,少于五个纪元是必要的。虽然我们没有单独的验证和测试集,但我相信对这些子集的评估会产生同样完美的分数。如果你想验证这一点或者重现上面的任何结果,你可以在 GitHub 上找到代码。

摘要

在本实践指南中,我们介绍了如何根据 TFRecord 数据训练神经网络。我们的第一步是创建一个人工的三色图像数据集。这些数据随后存储在 TFRecord 文件中,在数据集创建过程中使用这些文件。我们最后的步骤是初始化模型,最后,训练它达到完美的分类精度。

用几行简洁的代码训练一个神经网络

原文:https://towardsdatascience.com/training-a-neural-network-with-a-few-clean-lines-of-code-b688da064bd5

可重用、可维护且易于理解的机器学习代码

照片由米拉德·法库里安Unsplash 拍摄——由作者编辑

较少的代码通常会产生易于理解和维护的可读代码。Python 编程语言已经在机器学习社区中非常流行,与其他编程语言相比,它允许您用更少的代码获得更好的结果。

PyTorch 是一个流行的 Python 深度学习框架,它有一个干净的 API,并允许您编写真正像 Python 一样的代码。因此,用 Python 中的 PyTorch 创建模型和进行机器学习实验真的很有趣。

在本文中,我将向您展示训练一个识别手写数字的简单分类器所需的基本步骤。您将看到如何

  • 用 PyTorch 的数据加载器加载 MNIST 数据集(用于机器学习的“Hello World”数据集)
  • 声明我们模型的架构
  • 选择优化程序
  • 实施培训循环
  • 确定训练模型的准确性

我想让一切尽可能简单。因此,我不涉及过拟合、数据预处理或不同的度量来评估我们的分类器的性能。我们将只实现训练分类器所需的基本构件,这些构件可以很容易地在其他机器学习实验中重用。

所以让我们开始写一些代码。

我们需要做的第一件事是导入必要的包。因为我们使用 PyTorch,所以我们需要导入包torchtorchvision

import torch
import torchvision as tv

加载数据

现在,我们可以通过 torchvision 加载我们的训练和验证数据集。

t = tv.transforms.ToTensor()mnist_training = tv.datasets.MNIST(
    root='/tmp/mnist',
    train=True,
    download=True,
    transform=t
)mnist_val = tv.datasets.MNIST(
    root='/tmp/mnist', 
    train=False, 
    download=True, 
    transform=t
)

首先,我们创建一个ToTensor()的实例,用于将从datasets包中获得的图像转换成张量。我们需要这一步,因为所有 PyTorch 函数都在张量上运行。如果你不了解张量,这些基本上只是多维数组的一个花哨名字。张量有秩。例如,秩为 0 的张量是标量,秩为 1 的张量是向量,秩为 2 的张量是矩阵,等等。

然后,我们加载我们的训练和验证数据集。使用root,我们可以指定用于在光盘上存储数据集的目录。如果我们将train设置为真,则训练集被加载。否则,加载验证集。如果我们将download设置为 true,PyTorch 将下载数据集并将它们存储到通过root指定的目录中。最后,我们可以指定应该应用于训练和验证数据集的每个示例的转换。在我们的情况下,它只是ToTensor()

指定我们模型的架构

接下来,我们指定模型的架构。

model = torch.nn.Sequential(
    torch.nn.Linear(28*28, 128),
    torch.nn.ReLU(),
    torch.nn.Linear(128, 10)
)

选择优化器和损失函数

接下来,我们指定优化器和损失函数。

我们正在使用 Adam 优化器。通过第一个参数,我们指定了优化器需要优化的模型参数。通过第二个参数lr,我们指定了学习率。

在第二行中,我们选择CrossEntropyLoss作为损失函数(常用的损失函数的另一个词是标准)。此函数获取输出层的非标准化(N x 10)维输出(N 是我们批次的样本数),并计算网络输出和目标标签之间的损失。目标标签被表示为包含输入样本的类别索引的 N 维向量(或者更具体地,秩为 1 的张量)。如您所见,CrossEntropyLoss 是一个非常方便的函数。首先,在我们的网络末端,我们不需要像 softmax 这样的标准化层。第二,我们不必在不同的标签表示之间转换。我们的网络输出分数的 10 维向量,并且目标标签被提供为类别索引的向量(0 到 9 之间的整数)。

接下来,我们为训练数据集创建一个数据加载器。

loader = torch.utils.data.DataLoader(
    mnist_training, 
    batch_size=500, 
    shuffle=True
)

数据加载器用于从数据集中检索样本。我们可以使用数据加载器来轻松地迭代一批样本。这里,我们创建一个加载器,它在每次迭代中从训练数据集中返回 500 个样本。如果我们设置shuffle为真,样本将在批次中被混洗。

训练机器学习模型

现在,我们有了训练模型所需的一切。

for epoch in range(10):
    for imgs, labels in loader:
        n = len(imgs)
        imgs = imgs.view(n, -1)
        predictions = model(imgs)  
        loss = loss_fn(predictions, labels) 
        opt.zero_grad()
        loss.backward()
        opt.step()
    print(f"Epoch: {epoch}, Loss: {float(loss)}")

我们使用 10 个历元来训练我们的网络(第 1 行)。在每个时期,我们对加载器进行迭代,以在每次迭代中获得 500 张图像及其标签(第 2 行)。变量imgs是形状的张量(500,1,28,28)。变量labels是具有 500 个类别索引的秩为 1 的张量。

在第 3 行,我们将当前批次的图像数量保存在变量n中。在第 4 行中,我们将形状(n,1,28,28)的张量imgs整形为形状(n,784)的张量。在第 5 行中,我们使用我们的模型来预测当前批次的所有图像的标签。然后,在第 6 行,我们计算这些预测和事实之间的损失。张量predictions是形状(n,10)的张量,而labels是包含类别索引的秩为 1 的张量。在第 7 行到第 9 行中,我们重置了网络所有参数的梯度,计算了梯度并更新了模型的参数。

我们还在每个时期之后打印损耗,以便我们可以验证网络在每个时期之后变得更好(即损耗减少)。

确定准确度

现在,我们已经训练了网络,我们可以确定模型识别手写数字的准确性。

首先,我们需要从验证数据集中获取数据。

n = 10000
loader = torch.utils.data.DataLoader(mnist_val, batch_size=n)
images, labels = iter(loader).next()

我们的验证数据集mnist_val包含 10000 张图片。为了得到所有这些图像,我们使用一个数据加载器,并将batch_size设置为 10000。然后,我们可以通过从数据加载器创建一个迭代器,并在迭代器上调用next()来获取第一个元素,从而获得数据。

结果是一个元组。这个元组的第一个元素是形状张量(10000,1,28,28)。第二个元素是秩为 1 的张量,它包含图像的类别索引。

现在,我们可以使用我们的模型来预测所有图像的标签。

predictions = model(images.view(n, -1))

在我们能够向我们的模型提供数据之前,我们需要重塑它(类似于我们已经在训练循环中所做的)。我们模型的输入张量需要具有形状(n,784)。当数据具有正确的形状时,我们可以将其用作模型的输入。

结果是形状的张量(10000,10)。对于我们的验证集的每个图像,这个张量存储了十个可能标签中每个标签的分数。标签的分数越高,样品越有可能属于相应的标签。

通常,样本被分配给具有最高分数的标签。我们可以通过张量的argmax()方法很容易地确定标签,因为这个方法返回最大值的位置。

predicted_labels = predictions.argmax(dim=1)

我们对维度 1 的最大值感兴趣,因为每个样本的分数都存储在这个维度上。结果是秩为 1 的张量,它现在存储预测的类索引而不是分数。

现在,我们可以将预测的类索引与基础事实标签进行比较,以计算验证数据集的准确性。准确度被定义为已经被正确预测的样本的分数,即正确预测的样本数除以样本总数。

获得这个度量的技巧是对预测标签和实际标签进行元素比较。

torch.sum(predicted_labels == labels) / n

我们比较predicted_labelslabels是否相等,得到一个布尔向量。如果同一位置的两个元素相等,则该向量中的一个元素为真。否则,元素为 false。然后,我们使用sum来计算为真的元素的数量,并将该数量除以 n

如果我们执行所有这些步骤,我们应该可以达到大约 97%的准确率。

GitHub 上也有完整的代码。

结论

作为一名软件工程师,我喜欢干净的代码。有时候,我会在一些小代码前坐半个小时甚至更长时间,只是为了让它更优雅、更漂亮。

PyTorch 是一个非常棒的深度学习框架,它允许您编写易于理解并且感觉像 Python 的干净代码。我们已经看到,只用几行代码就可以生成表达性代码来创建和训练最先进的机器学习模型。

我们在这个简单演示中使用的构建模块可以在许多机器学习项目中重用,我希望它们也能在您的机器学习之旅中对您有所帮助。

用强化学习训练能量决策智能体

原文:https://towardsdatascience.com/training-an-energy-decision-agent-with-reinforcement-learning-a7567b61d0aa

费德里科·贝卡里在 Unsplash 上的照片

设置、培训过程和结果的高级概述

现实世界的强化学习应用很难找到。本文给出了构建一个 RL 代理的高层次概述,该代理旨在优化能源使用。本文分为以下几个部分:

  1. 问题设置 —明确问题和目标。
  2. 构建模拟环境 —描述如何构建培训环境,包括代理的观察空间、行动空间和奖励。
  3. 训练过程 —训练中使用的框架、算法和训练过程的图表。
  4. 行动中的代理 —一个训练有素的代理如何做出决策的例子。
  5. 结论 —最终想法。

问题设置

我们有一个家庭用 12 kWp 单元产生自己的太阳能,并且能够将这种能量存储在家用电池中(容量为 13 kWh 的特斯拉 Powerwall 2),这可以通过 API 来控制。该户的电力合同基于日前市场价格,该存储装置也可用于参与 备用/备用 市场

我们的目标是培训一个代理,通过 控制电池考虑能源市场(日前市场、频率市场)、当地条件(例如,家庭的基本负荷)和用户偏好(例如,电池水平不能低于某个阈值)来最小化家庭的能源成本。

构建模拟环境

在强化学习中,主体通过在环境中做出动作、接受对这些动作的奖励/惩罚并相应地修改其动作模式(策略)来学习。

人们可以使用真实环境(真实的家庭和能源市场)或模拟环境。在这个项目中,建立了一个模拟环境,使用 OpenAI Gym 作为框架。

模拟环境是真实物理环境的数字表示,用于训练强化学习代理(图片由作者提供)。

开发能源决策代理的模拟环境包括以下步骤:

  1. 用数字表示环境的当前情况(状态)。状态表示需要包含我们的代理培训所需的所有信息。
  2. 用数字表示可能的行为(我们的代理可以用我们的电池做的事情)。表示和更新家用电池的当前状态。
  3. 发展一种逻辑,说明在环境中采取特定行动意味着什么。换句话说,表示当代理执行特定动作时,家庭、电池和能源成本会发生什么。

总之,我们环境的程序表示包括大约 700 行代码(包括助手函数)。接下来,我将解释环境的一些关键部分。

代表当前状态/观察

状态/观察是当前情况的数字表示。在我们的项目中,这意味着代表能源市场、家庭和资产的当前状态。

当前状态的初始表示

我们的初始(未修改的)观察空间由以下信息组成:

  • 未来一天能源市场价格的 12 小时预测,
  • afrr_up 频率市场价格的 12 小时预测,
  • 家庭消费的 12 小时预测,
  • 当地太阳能生产的 12 小时预报,
  • 关于电池的信息(长度为 4 的向量):电池的容量(例如 13k wh);电池的当前充电水平(例如 2 千瓦时);最大充电功率(例如 5kw);允许的最低充电水平(例如 1 千瓦时)。

下面的代码块代表未修改的观察组件的一个示例:我们有 12 个前一天和后一天市场价格的预测值,相同数量的相应基本负载和 pv 产品值,以及 4 个代表电池信息的值。

'day_ahead': array([ 4, 6, 12, 41, -12, 18, 46, 69, 41, 65, 64, 22], dtype = int32)
'afrr_up': array([ 0, 78, 62, 0, 0, 0, 0, 0, 0, 0, 0, 87], dtype=int32)
'baseload': array([ 2, 10, 10, 4, 4, 3, 5, 4, 4, 4, 4, 9], dtype=int32)
'pv': array([ 0, 1, 2, 4, 10, 4, 12, 6, 10, 5, 9, 0], dtype=int32)
'bat': array([13., 2., 15., 1.], dtype=float32)

修改的观察空间

初始观察表示被修改,以便使它更容易被我们的代理用于学习的神经网络处理。每个观察值都经过了归一化(在 0 和 1 之间表示)和平坦化(作为单个向量而不是五个不同的向量给出)。修改后的观察结果如下所示:

array([0.159375, 0.175 , 0.10625 , 0.09375 , 0.13125 , 0.084375, 0.096875, 
0.121875, 0.078125, 0.103125, 0.09375 , 0.19375 , 0.3 , 0.34375 , 0.0625 , 
0.0625 , 0.0625 , 0.0625 , 0.0625 , 0.0625 , 0.0625 , 0.365625, 0.375 , 
0.0625 , 0.5625 , 0.625 , 0.125 , 0.125 , 0.0625 , 0.0625 , 0.0625 , 
0.125 , 0.0625 , 0.6875 , 0.5625 , 0.375 , 0\. , 0.0625 , 0\. , 0\. , 
0\. , 0\. , 0\. , 0\. , 0\. , 0.125 , 0.0625 , 0.5 , 0.8125 , 0.125 , 
0.9375 , 0.0625 ])

行为空间

动作空间表示代理可以做出的决策(动作)。我们的能量决策代理具有长度为 6 的离散动作空间。

0: 'bat_from_grid' #battery is charged from the grid
1: 'bat_to_grid' #battery sends energy to the grid 
2: 'bat_to_home' #battery fulfills household’s energy need 
3: 'bat_from_pv' #battery charges from solar panels production
4: 'bat_afrr_up' #battery participates in afrr frequency market 
5: 'bat_idle' #battery doesn’t do anything (stays idle)

每个值(从 0 到 5)对应于代理可以对电池执行的操作之一。每个动作都会影响电池的充电状态,并具有相应的成本/收益。

复杂性:一集是 24 小时,每小时我们有 6 个动作可以选择。我们有4 738 381 338 321 616 896(4.7 万亿)种可能的方式在一集里使用这个电池。

报酬

代理人在每一步都获得奖励,奖励等于家庭经历的能源成本。例如,如果代理决定行动值为 0:“bat _ from _ grid”,则最大可能数量的能量从电网充入电池,代理收到的奖励等于:充电成本+家庭基本负载成本+光伏生产收入+ …

代理人的目标是最大化 24 小时时间跨度的回报(即:24 小时被定义为一集)。

培训过程

在培训阶段,代理人在模拟环境中采取行动,并试图找到对家庭最有利的行动计划。在这个项目中,代理由 IMPALA 算法的 RLLIB 实现来表示。IMPALA 能够同时训练多个 CPU 内核的代理。该项目中的设置包括 4 个核心/工作人员和每个工作人员 3 个环境。

下图显示了培训过程中每集的平均奖励(以 100 集的平均值计算)。我们可以看到,代理进化得非常快,但在最初的两百万步训练中,策略(其决策模式)的稳定性相当低。在培训的最后阶段,我们的代理能够持续获得每集 1.5-1.6€的平均报酬。

经纪人培训过程中的平均剧集奖励。平均回报代表家庭 24 小时的能源成本。正回报是指住户通过向电网售电挣钱(图片由作者提供)。

行动中的代理

作为最后一步,让我们看看我们的代理为示例 24 小时期间建议的操作(下图)。“前一天”和“后一天”列代表这些小时的市场价格。基本负荷和光伏代表家庭的常规消耗和光伏生产(单位为 kWh)。“行动”栏显示我们的能源决策代理建议的行动/决策,“SoC”栏显示一小时结束时(执行建议的行动后)的电池电量(单位为 kWh)。

表中第一个突出显示的区域显示了我们的代理如何在高价时段(21、22、0 小时)在 afrr-up 市场上分配电池,并在当天价格较低的时段(28 和 4 小时)从电网充电。

经过培训的代理人的决策示例——我们可以看到,我们的代理人能够在不同的市场价格之间进行套利(作者列表)。

第二个突出显示的区域表明了我们代理人的纯市场价格套利——在高价时段(第 3 和第 5 小时)放电,在低价时段(第 4 和第 6 小时)充电。

结论

最后,我想强调以下几个方面:

  • 强化学习可以用来训练能量决策智能体。
  • 构建强化学习的现实应用的关键在于构建一个与物理世界非常相似的训练环境。
  • RL 代理不能保证最优性,并且对环境中的微小变化非常敏感。
  • 好好想想。也许你的问题可以用更简单的方法解决!

使用 S5cmd 从云存储进行培训

原文:https://towardsdatascience.com/training-from-cloud-storage-with-s5cmd-5c8fb5c06056

如何使用数百万个小的、单一的样本文件进行训练

鲁本·米什丘克在 Unsplash 上拍摄的照片

在典型的深度学习训练管道中,数据样本从存储位置迭代加载,并馈入机器学习模型。模型从这些样本中学习,并相应地更新其参数。因此,每个训练步骤的速度以及建模收敛的总时间直接受到从存储中加载数据样本的速度的影响。数据加载速度又会受到多种因素的影响,包括:

  1. 数据位置:数据的位置及其与训练机器的距离会影响数据加载的延迟。
  2. 带宽:存储位置和训练机器之间的通信信道的带宽将决定数据可以被拉取的最大速度。
  3. 样本大小:每个数据样本的大小会影响需要传输的总字节数。
  4. 压缩:注意,虽然压缩您的数据会减少样本数据的大小,但它也会在训练实例上添加一个解压缩步骤。
  5. 数据格式:样本存储的格式会直接影响数据加载的开销。
  6. 文件大小:组成数据集的文件大小会影响从数据存储中提取的数量。大小可以由分组到文件中的样本数量来控制。
  7. 软件堆栈:从存储器中提取数据时,软件实用程序表现出不同的性能行为。除其他因素外,这些行为还取决于系统资源的利用效率。

您选择存储数据的方式会对您的训练工作量的运行时性能产生有意义的影响,因此应该进行相应的设计。

我们以前的几篇文章已经致力于存储训练数据的不同选项(例如这里的)和将它流式传输到训练会话中(例如这里的、这里的和这里的)。像以前一样,我们将假设我们的数据集如此之大,以至于将其全部下载到训练实例上是不切实际的,甚至是不可能的。

在我们之前的帖子中,我们遵循了将样本分组到大约 100 兆字节大小的文件中的传统智慧,作为优化从云存储中提取数据的一种方法。我们在这篇文章中的意图是评估消除这一限制的成本。具体来说,我们将探索在将数据保存在小的单个样本对象文件中而不是将它们组合在一起时可以实现的运行时性能。

虽然我们将进行的实验将使用 AWS 提供的云服务(亚马逊 S3亚马逊 EC2亚马逊 SageMaker ),并将使用 PyTorch(版本 1.12)进行编程,但我们将得出的结论也适用于其他云环境和其他培训框架。我们将演示几个将单个样本文件从亚马逊 S3 流式传输到培训会话的选项。我们提到的这种或那种方法不应被解释为认可。其他方法可能表现出更好的性能,我们提到的方法的性能可能会随着 API 的增强和优化而改变。此外,请记住,运行时性能可能会因项目细节而有很大差异,我们将分享的比较结果可能不会应用到您自己的项目中。简而言之——对我们写的所有东西都要有所保留,并确保在做出任何设计决定之前进行自己的全面评估。

特别感谢 Nadav Shaag 对本帖的贡献。

动机——为什么要存储单独的训练样本?

您可能希望以单个样本的形式维护数据,而不是将它们分组到大文件中,原因有很多。

原始数据格式

让我们面对现实吧——采用一种能够满足所有数据消费者需求和愿望的文件格式确实令人头疼。单独存储数据样本使您能够以原始格式维护它们。以下是坚持原始格式的一些优势:

  • 数据格式转换通常意味着数据丢失。例如,如果出于训练目的转换数据,您可以选择忽略每个样本的某些属性,只保留训练任务所需的属性,但随后会发现不同的任务需要其中一个被忽略的属性。通过以原始格式维护您的数据,您可以确保数据的完整性并保持最大的灵活性。
  • 作为开发过程中的一个额外步骤,数据格式转换的过程会增加代码的复杂性和出错的可能性。此外,无论何时选择添加或更新数据样本,都需要重新运行格式转换步骤,然后才能使用新数据。去除格式转换步骤可以简化你的开发流程并减少延迟。
  • 有时,您可能会发现自己需要维护多种重叠的数据格式,以满足多个数据消费者的需求。除了这种冗余带来的麻烦之外,它还会显著增加您的存储成本。以原始格式维护数据的单一副本可以简化数据管理并降低成本

随机存取

当您的数据样本单独存储时,很容易随机访问它们中的任何一个。相比之下,当样本被分组到文件中时,随机访问其中的任何一个都是困难的。您选择的文件格式可能不支持这种随机访问,即使支持,也可能需要您仔细记录您的样本是如何分组的。此外,从大文件中提取单个记录会产生开销,可能会对运行时性能产生负面影响。在深度学习训练工作负载中,对数据进行随机访问的需求是常见的,尽管有一些方法可以解决在将样本分组到更大的文件中时缺乏这种需求的问题(参见此处的),但这些方法并不完美。

减少数据重复

我们已经提到了以一种或多种格式维护数据的多个重叠副本所导致的数据重复。当每个训练样本(即输入到模型中的每个样本)由多个原始样本组成时,就会出现另一个潜在的重复源。例如,如果您正在处理一个计算机视觉模型,该模型正在被训练以根据视频中的帧序列进行预测(例如,光流或运动结构),任何给定的帧(原始样本)都可能出现在序列中不同位置的多个训练样本(帧序列)中。如果你的序列长度是 N ,你可能会发现你的训练数据的大小是你的原始数据总大小的 N 倍。相比之下,如果您的数据存储为单个样本(帧)文件,您的存储成本将降低 N 倍。在这种情况下,组成 N 序列的各个帧将在训练期间被加载并分组在一起。

当然,将数据保存为单独的文件也有其缺点。根据单个样本的大小,存储中的文件数量可能会急剧增加。如果管理不当,这可能导致节流问题、运行列表查询的延迟(例如 aws s3 ls )等。如果您之前在每个文件中分组了 N 个样本,您将需要在培训期间下载 N 倍数量的文件。这增加的潜在开销可能会降低数据加载管道的速度,并在您的培训中引入瓶颈。在接下来的几节中,我们将探索从单样本文件进行训练的几种选择,并将它们的性能与推荐的将样本分组到大约 100 兆字节的文件中的方法进行比较。

方法

我们在这篇文章中探讨的选项包括将数据直接从云存储传输到训练循环中。其他选项超出了本文的范围,可能需要建立一个由一个或多个服务器组成的集群,专门管理对您的数据存储的访问(例如 AIStore ),或者使用额外的专用数据检索服务来增强您的云架构(例如 Amazon FSx )。虽然这种选择可能导致更快的培训吞吐量,但是它们也需要更高的成本,并且需要更大的努力来设置、配置和维护。

Boto3

将文件从亚马逊 S3 流式传输到您的训练循环中最直接的方法是使用 Boto3 Python 库。下面的代码块演示了如何将文件数据的内容提取到本地内存的字节流中。假设样本是成对的图像和标签文件。

from torch.utils.data import Dataset
import boto3, io, re, os
class BotoSingleSampleDataset(Dataset):
    def __init__(self):
        super().__init__()
        self.base_path = <path to data in S3>
        self.client = boto3.client("s3") def __len__(self):
        return 100000

    def get_bytes_io(self, path):
        byte_io = io.BytesIO()
        _, bucket, key, _ = re.split("s3://(.*?)/(.*)$", path)
        self.client.download_fileobj(bucket, key, byte_io)
        byte_io.seek(0)
        return byte_io

    def __getitem__(self, index: int):
        image_path = f'{self.base_path}/{index}.image'
        label_path = f'{self.base_path}/{index}.label'
        image = self.get_bytes_io(image_path).read()
        label = self.get_bytes_io(label_path).read()
        return {"image": image, "label": label}def get_dataset_and_sampler():
    ds = BotoSingleSampleDataset()
    return ds, None

亚马逊 SageMaker 快速文件模式

亚马逊 SageMaker 提供了一个基于 FUSE 的解决方案,用于访问 S3 的文件,称为快速文件模式 (FFM)。当您对 SageMaker 作业进行编程以使用快速文件输入模式时,S3 路径会挂载到预定义的本地文件路径上。在最近的一篇文章中,我们扩展了这个输入模式选项,演示了它的用法,并讨论了它的优缺点。下面的代码块演示了如何基于使用 Amazon SageMaker 快速文件模式访问的单个数据样本创建 PyTorch 数据集:

from torch.utils.data import Dataset
import os
class FFMSingleSampleDataset(Dataset):
    def __init__(self):
        super().__init__()
        self.base_path = os.environ['SM_CHANNEL_TRAINING']

    def __len__(self):
        return 100000

    def get_from_files(self, image_path, label_path):
        image_file = open(image_path, 'rb')
        label_file = open(label_path, 'rb')
        image = image_file.read()
        label = label_file.read()
        image_file.close()
        label_file.close()
        return {"image": image, "label": label}

    def __getitem__(self, index: int):
        index = index%10000
        image_path = os.path.join(self.base_path, f'{index}.image')
        label_path = os.path.join(self.base_path, f'{index}.label')
        return self.get_from_files(image_path, label_path)def get_dataset_and_sampler():
    ds = FFMSingleSampleDataset()
    return ds, None

S5cmd

S5cmd 是一个命令行工具,用于从亚马逊 S3 获取对象。用 Go 编程语言编写的 S5cmd 非常依赖多线程和多个 TCP 连接的使用来加速来自 S3 的数据传输。查看这个信息丰富的博客了解更多关于 s5cmd 如何工作及其性能优势的细节。

在下面的代码块中,我们定义了一个自定义 PyTorch 采样器,它运行一个后台进程,一次对 1000 个样本异步调用 s5cmd。

from torch.utils.data import Dataset
from torch.utils.data import SequentialSampler
import os, threading, shlex, time
from subprocess import Popen**samples_per_call = 1000** rank = 0 # in case of multi-gpu, get the local ranklocal_path = f'/tmp/{rank}' # local path to download files to
base_path = <path to files in S3>

class S5cmdSampler(SequentialSampler):
    def __init__(self, data_source, shuffle=False):
        super().__init__(data_source)
        self.shuffle = shuffle def load_sample_files(self, handle, indices):
        all_files = []
        for i in indices:
            all_files.append(f'{local_path}/{i}.image')
            all_files.append(f'{local_path}/{i}.label')
        cmd_txt = os.path.join(local_path, f'{handle}.txt')
        with open(cmd_txt, "w") as f:
            for fp in all_files:
                c = f'cp {fp} {fp.replace(base_path,local_path)}\n')
                f.write(c) # add command to list of commands
        s5cmd = f's5cmd --log error run {cmd_txt}'
        p = Popen(shlex.split(s5cmd))
        return p

    def __iter__(self):
        n = len(self.data_source)
        if self.shuffle:
            import torch
            r = torch.empty((), dtype=torch.int64).random_()               
            seed=int(r.item())
            generator = torch.Generator()
            generator.manual_seed(seed)
            slist = torch.randperm(n, generator=generator)
            slist = slist.tolist()
        else:
            slist = list(range(n))
        procs = [None, None]
        sublists = [None, None]
        proc_index = 0
        list_index = 0
        end_index = min(list_index + **samples_per_call**, n)
        sublists[proc_index] = slist[list_index:end_index]
        procs[proc_index] = self.load_sample_files(
                                 handle=proc_index, 
                                 indices=sublists[proc_index])
        while list_index < n:
            list_index = end_index
            if list_index < n:
                *# extract next batch* end_index = min(list_index + **samples_per_call**, n)
                sublists[1-proc_index] = slist[list_index:end_index]
                procs[1-proc_index] = self.load_sample_files(
                                handle=1-proc_index,
                                indices=sublists[1-proc_index])
            counter = 0
            while procs[proc_index].poll() is None:
                counter = counter + 1
                time.sleep(0.1)
                if counter == 10:
                    print('data starvation')
            sublist = sublists[proc_index]
            proc_index = 1 - proc_index
            yield from sublistdef release_files(file_list):
    def delete_files(files):
        for file in files:
            if os.path.exists(file):
                os.remove(file)
    threading.Thread(target=lambda: delete_files(file_list)).start()class S5cmdDataset(Dataset):
    def __init__(self):
        super().__init__() def __len__(self):
        return 100000 def get_from_files(self, image_path, label_path):
        image_file = open(image_path, 'rb')
        label_file = open(label_path, 'rb')
        image = image_file.read()
        label = label_file.read()
        image_file.close()
        label_file.close()
        return {"image": image, "label": label} def __getitem__(self, index: int):
        index = index % 10000
        image_path = os.path.join(local_path, f'{index}.image')
        label_path = os.path.join(local_path, f'{index}.label')
        ret = self.get_from_files(image_path,label_path)
        release_files([image_path, label_path])
        return retdef get_dataset_and_sampler():
    ds = S5cmdDataset()
    sampler = S5cmdSampler(ds)
    return ds, sampler

在上面的例子中,我们将每个 s5cmd 调用的样本数设置为 1000,并依赖于 s5cmd 的默认设置。很可能可以通过调整一些控制设置来进一步优化代码,特别是num workers(控制并行 S3 命令的数量)和 并发 设置(控制如何分解单个文件的上传/下载)。

在我们分享的示例中,我们选择将文件下载到本地磁盘(/tmp),然后从同一位置加载它们。可以想象,您可以通过将文件对象直接放入内存来减少读写磁盘的开销。一种方法是使用 tmpfs (例如/dev/shm)。

请注意,s5cmd 所采用的高度并行处理可以用其他方式实现(包括 Python)。然而,达到与 s5cmd 相同的性能水平可能并不那么简单。

实验

在本节中,我们使用一个 Amazon EC2 c5.4xlarge 实例(有 16 个 vCPUs)对一个玩具示例进行了一些实验。

为了只关注数据流的性能,我们将测量空训练步骤情况下的吞吐量,如下面的代码块所示。

*import torch, time
from statistics import mean, variancedataset, sampler = get_dataset_and_sampler()
dl = torch.utils.data.DataLoader(dataset, sampler=sampler, 
                                 batch_size=4, num_workers=16)
stats_lst = []
t0 = time.perf_counter()
for batch_idx, batch in enumerate(dl, start=1):
    if batch_idx % 100 == 0:
        t = time.perf_counter() - t0
        print(f'Iteration {batch_idx} Time {t}')
        stats_lst.append(t)
        t0 = time.perf_counter()
mean_calc = mean(stats_lst[1:])
var_calc = variance(stats_lst[1:])
print(f'mean {mean_calc} variance {var_calc}')*

请记住,虽然这种比较测量可能会让我们很好地了解每种方法可以支持的最大吞吐量,但它可能无法很好地预测您选择的方法将如何影响实际的培训吞吐量:

  1. 您选择的方法可能不会影响您的整体训练步骤时间。例如,如果您的培训步骤是计算密集型的,那么从 S3 提取一批样本需要 1 秒钟还是 10 秒钟可能没有区别。
  2. 一个典型的培训步骤将包括许多额外的操作,这些操作可能会影响您的实际培训量。特别是,一些操作可能会争用从 S3 传输数据的相同资源。

作为比较的基准,我们将使用我们在这篇文章中描述的相同的 WebDataset 示例。我们还使用相同的代码块来生成一个玩具图像数据集和相关的每像素标签。

*import webdataset as wds
import numpy as np
from PIL import Image
import ioout_tar = 'wds.tar'
sink = wds.TarWriter(out_tar)
im_width = 1024
im_height = 1024
num_classes = 256
for i in range(100):
    image = Image.fromarray(np.random.randint(0, high=256,
                  size=(im_height,im_width,3), dtype=np.uint8))
    label = Image.fromarray(np.random.randint(0, high=num_classes,
                  size=(im_height,im_width), dtype=np.uint8))
    image_bytes = io.BytesIO()
    label_bytes = io.BytesIO()
    image.save(image_bytes, format='PNG')
    label.save(label_bytes, format='PNG')
    sample = {"__key__": str(i),
              f'image': image_bytes.getvalue(),
              f'label': label_bytes.getvalue()}
    sink.write(sample)*

结果

这些结果旨在让您对可能看到的比较结果有所了解。请记住,根据许多项目细节,包括样本大小、批量大小等,结果会有很大差异。该表包括平均报告的步骤时间以及平均 CPU 利用率。CPU 利用率给出了在真实(非空)训练循环的情况下选择的方法将引入 CPU 资源争用的可能性的一些指示。

比较速度和 CPU 利用率(按作者)

毫不奇怪,基于单个样本数据集的解决方案无法与基于 WebDataset (WDS)的最佳结果(超过 FFM)相媲美。根据您的模型的细节,这可能意味着较低的训练吞吐量。与此同时,s5cmd 的价值非常明显,相比其他单个样品选项,其通量性能提高了约 58%。使用 tmpfs 代替本地磁盘并没有带来任何额外的好处。使用 s5cmd 可以节省大约 58%的培训成本。另一方面,在真实的训练循环中,CPU 利用率增加 2.6 倍(与 FFM 相比)可能会减少整体节省。

摘要

虽然单独存储数据样本比将数据样本分组到文件中有很多优点,但是您的训练吞吐量可能会因此而下降。它是否下降,以及下降的程度,可能取决于您用于将单个样本流式传输到您的训练实例的方法。如本文所示,s5cmd 是一个强大的命令行实用程序,用于从 S3 提取数据,相对于评估的其他方法,它可以产生显著更高的吞吐量。

如需更正、评论或问题,请随时联系我们。

训练隐马尔可夫模型

原文:https://towardsdatascience.com/training-hidden-markov-models-831c1bdec27d

Baum-Welch 和向前向后算法

在我的上一篇文章中,我介绍了隐马尔可夫模型(HMMs)——对有噪声的序列数据建模的最强大(但未被充分重视)的工具之一。如果你有一个 HMM 来描述你的过程,维特比算法可以把一个嘈杂的观察流变成一个对每个时间步发生的事情的高度可信的猜测。

然而,这是假设您已经有了一个所有参数都已经调好的 HMM。有时候情况就是这样——我记得我在谷歌的时候,我们有一个非常奇特的模型来模拟英语的词序——但更多时候你只有原始数据,你必须自己拟合一个 HMM。这篇文章将讨论这种情况。

TLDR 是这样的:如果你真的没有标记数据,也不知道任何事情,你可以使用 Baum-Welch 算法来拟合 HMM。但是由于技术原因,Baum-Welch 算法并不总是给出正确的答案。另一方面,如果你确实有一些知识和一点点时间,那么有无数种方法可以破解培训过程。

训练的两个部分:马尔可夫链和观察值

回想一下上一篇文章,HMM 有两个部分:

  • 描述您在不同状态之间转换(或停留在同一状态)的可能性的底层马尔可夫链。通常这种潜在的状态是你真正感兴趣的东西。如果在 HMM 中有 k 个状态,那么马尔可夫链由 1)k*k 矩阵和 2)k 长度向量组成,k * k 矩阵表示你从 S1 状态转移到 S2 状态的可能性,k 长度向量表示你从每个状态开始的可能性。
  • 一个允许您计算 Pr[O|S]的概率模型-如果我们假设基础状态为 S,则看到观察值 O 的概率。与具有固定格式的马尔可夫链不同,Pr[O|S]的模型可以是任意复杂的。但是在许多 hmm 中,Pr[O|S]非常简单:每个状态 S 是一个不同的装载骰子,Pr[O|S]是它在每一边着陆的概率。

在很大程度上,这两个运动部分可以独立考虑。你甚至可能有外部知识告诉你其中一个是什么,而不是另一个。例如,假设您正在尝试制作一份音频记录的抄本;状态是英语单词,观察是声音的模糊。您可以使用现有的英语文本语料库来训练您的马尔可夫模型,然后只在训练 HMM 时调整 Pr[O|S]的参数。

如果你有大量的标记数据——你有一系列的观察结果和一个潜在状态的知识——训练 HMM 实际上分解成两个独立的问题。首先,您使用标签来训练马尔可夫链。然后,根据观察值所处的状态对它们进行划分,并为每个状态 S 训练 P[O|S]。如果我们的数据有可靠的状态标签,那么训练 HMM 就很简单。

但实际上,我们通常只有一系列的观察结果,而没有系统处于何种状态的可靠知识。直觉是这样的:我们猜测州标签是什么,并使用这些猜测训练一个 HMM。这将是一个相当可怜的嗯,但它可能会有一些位真正的模式,即使只是运气不好。然后,我们使用训练好的 HMM 在这些状态下做出更好的猜测,并根据这些更好的猜测重新训练 HMM。这个过程一直持续到训练好的 HMM 稳定下来。这种来回——在使用 HMM 猜测状态标签和使用这些标签拟合新的 HMM 之间——是 Baum-Welch 算法的本质。

鲍姆-韦尔奇算法:细则

我给你的关于 Baum-Welch (BW)算法的直觉需要澄清两点。

首先,我们通常从猜测 HMM 的参数开始,而不是从数据中的潜在状态开始。这让我们可以确保 HMM 中存在模式,并且后续的迭代可以确定哪些模式是真实的。如果你愿意,你可以从猜测状态开始,但是这样会收敛得更快。此外,通常您会对 HMM 参数有很好的猜测,您可以使用这些参数进行明智的初步猜测。

第二点比较微妙。一旦我们有了一个 HMM,我们所说的“猜测状态”是什么意思呢?在上一篇文章中,我们谈到了维特比算法,该算法采用一系列观察值,并为我们提供一个最佳状态序列。但问题是,其中一些状态可能会被可靠地猜测出来,而其他状态可能会非常模糊——维特比算法无法区分高置信度和低置信度的猜测。

为了解决第二个问题,我们放弃了维特比算法和它的假置信度。相反,我们使用其不太为人所知的表亲向前向后算法,它给我们提供了概率猜测,可以用来衡量信心。

向前向后算法

让我们谈一分钟技术问题。维特比算法不只是“解码观察”。它解决了一个非常具体的数学问题:给定 o o …个观察值序列,它会找到最大化这些状态和观察值的组合概率的单个状态序列 s …:

Pr[s…]* Pr[o o…| s…]

它针对整个状态序列进行优化,而不是针对任何一个特定的状态。但是让我们说,我们只对一个特定的州感兴趣,s⁵.可能是状态的单个最佳序列——由维特比算法找到的序列——具有 s⁵=0,但是有许多稍微差一些的序列,对于这些序列,s⁵=1.在这种情况下,稍微差一点的序列相加,孤立的 s⁵的最佳猜测是 1。

向前-向后算法为每个时间步长寻找最佳猜测状态。一般来说,这些状态将不同于维特比状态,尽管实际上它们通常非常接近(例如:在我现在处理的数据中,它们有 5%的时间不一致,我很惊讶它会那么高)。

为了我们的目的,前向-后向算法的价值不在于它与维特比算法的不同之处。事实是,它严格计算每个时间步在每个状态的概率。这个就是我们用于鲍姆-韦尔奇算法的!我们并不在一系列我们确定知道的状态上训练我们的 HMM:我们训练我们的 HMM,使得它平均起来是所有这些概率猜测的最佳拟合。

这里就不给出 Baum-Welch 算法的伪代码了。相反,我将注意到这是 EM 算法的一个特例,当存在未知的“隐藏变量”(在这种情况下,哪个状态在哪个时间戳)时,EM 算法用于拟合模型,这些未知的“隐藏变量”可以通过概率进行猜测。Baum-Welch 算法的致命弱点与困扰 EM 算法的问题是一样的:解决方案只是局部最优的。

大恶魔:局部最优

我提到 Baum-Welch 算法的第一步是猜测 HMM 的参数。这意味着随机初始化参数(对于 hmm 来说,dirichlet 分布是一种流行的选择,但这超出了我们的范围)。但问题是,不同的随机起点可以汇聚到不同的最终 hmm 上——不管起点如何,都没有唯一的最佳答案。

您可能收敛到的各种 hmm 被称为“局部最优”。取一个局部最优 X——你可以把它想象成高维向量空间中的一个点,其中维度是 hmm 的不同参数。X 比在它的一定距离内的任何其他 HMM 都好,并且如果您的初始猜测足够接近 X,那么 Baum-Welch 算法将收敛于 X。但是很容易存在比 X 好但远离它的另一个 X′。

我最近在自己的工作中遇到了一个有趣的例子。我正在模拟一个人在每个时间点使用 7 个桌面应用程序中的哪一个,并试图用一个双态 HMM 来拟合它。我的希望是找到一种“自然”的行为模式,让他们在几个应用之间快速切换。相反,我安装了两次 HMM,每次都做了一个饼状图,显示用户在每个州的每个应用上花费的时间。以下是两次运行的结果:

Baum-Welch 算法中不同的初始条件,即使是对相同的数据进行训练,由于存在许多局部最优值,也会产生非常不同的最终输出。

你可以看到,一次紫色应用程序与棕色和粉色应用程序合并在一个州,而另一次它与橙色/蓝色/红色/绿色应用程序合并在一起。额外的运行产生了其他结果。我一直发现某个应用程序几乎只在一个州内使用。但是有 7 个应用程序要在两个州之间分配,每种分配方式都有自己的局部最优方案。

没有通用的方法来避免这个问题——拟合 HMM 是所谓的“非凸”问题,并且通常会遭遇局部最优。但是,有几种方法可以减轻这种影响:

  • 你可以简化你的 HMM。局部最优值的数量会随着 HMM 中参数的数量呈指数增长。如果减小参数大小,就可以减少陷入局部最优的次数。这可能意味着使用 2 态 HMM 而不是 3 态 HMM。如果你的观察值是多项式,这可能意味着减少可能的观察值。
  • 利用商业直觉得到一个与你预期的最终结果相似的初始 HMM。不同的局部最优解之间通常有很大的质量差异,就像我遇到的例子一样,所以从总体上看,你最终收敛的 HMM 很可能类似于你开始时的那个。不过,一定要确保你的猜测是部分随机的——可能有几个与你的商业直觉一致的局部最优值,如果是这样,你就想知道它。

注意,局部最优与过拟合是不同的问题(这当然也适用!).在我遇到的例子中,无论我有多少训练数据,各州之间的每个应用程序分发都将是其自己的局部最优。

离别赠言

我不想撒谎:使用一个经过训练的 HMM 比一开始就去拟合它要简单得多。另一方面,至少如果你像我一样,这也是乐趣的一部分!在对客户数据应用 hmm 时,我们在 Zeitworks 经常遇到这种情况。我们需要一个足够简单的模型来减轻局部最优,但又足够复杂来描述我们正在研究的过程。开箱即用的工具通常不能处理像部分已知的基本事实这样的边缘情况,我们经常发现自己在修补核心算法。

另一方面,这种复杂性与你可能考虑的其他技术相比相形见绌,比如递归神经网络。此外,hmm 更容易理解业务,更容易调试,如果训练数据有限,它们通常表现得更好。它们不能解决所有问题(没有什么能),但它们是武器库中不可替代的工具。

来自亚马逊 S3 的 PyTorch 培训

原文:https://towardsdatascience.com/training-in-pytorch-from-amazon-s3-6156d5342d1

如何最大化数据吞吐量并节省资金

照片由 Guillaume JailletUnsplash

在以前的帖子中(例如这里的和这里的我们讨论了从亚马逊 S3 到 TensorFlow 培训课程的不同数据流选项。在本帖中,我们重温了 S3 的培训主题,这次重点是 PyTorch 培训。

正如在我们以前的帖子中,我们处理的场景是我们的数据集如此之大,以至于它:

  1. 不能全部下载到培训实例上,或者
  2. 下载它会给我们的训练带来很大的延迟。

应对这一挑战有不同的方法。一种方法(不在本文讨论范围之内)是建立某种形式的持久存储系统,该系统镜像 S3 数据,并且一旦我们的训练实例启动,该系统就随时可用和可访问。用亚马逊 FSx 来实现这一点的一种方法是。虽然这种方法有其优点(如本文所述,但它可能需要大量额外的维护和成本。我们在这篇文章中采用的方法是将数据直接从 S3 流入我们的训练循环。

来自亚马逊 S3 的数据流

虽然将亚马逊 S3 的数据直接传输到训练循环听起来很简单,但如果设计不好,它可能会成为你训练管道的瓶颈。在这种不希望出现的情况下,当系统等待来自 S3 的数据到达时,系统的计算资源将处于空闲状态。我们的目标是最大限度地利用系统资源,进而提高训练速度。有许多因素控制来自 S3 的流数据可能影响训练步骤时间的程度,包括以下因素:

  1. 实例类型的网络输入带宽的大小。这是您选择的训练实例类型的属性。
  2. 训练步骤所需的数据总量(以字节为单位)。您应该通过只对训练所需的数据进行流式处理并考虑不同的压缩技术来努力减小每个数据样本的大小。(但是,您也应该考虑解压缩所需的额外计算。)
  3. 选择存储数据的文件格式。例如,与需要下载整个文件以便能够打开和解析它们的格式相比,使用诸如 WebDatasetTFRecord 格式的顺序文件格式可能会更好。
  4. 存储数据的单个文件的大小也会影响数据流的性能。例如,将每个数据样本存储在一个单兆字节大小的单独文件中会增加 S3 的事务开销。我们努力将我们的数据存储在多个文件中,每个文件有几百兆字节的大小,每个文件包含多个数据样本的序列。应该注意的是,以这种方式存储你的数据会带来其他挑战,我们已经在之前的文章中解决了这些挑战。
  5. 用于执行数据流的工具,将在本文中讨论。

在这篇文章中,我们将探索一些从 S3 训练的方法。请不要把我们提到或没有提到这种或那种方法解释为赞同或拒绝。我们认为熟悉多种方法非常重要。每一种都有自己的优点和缺点,最佳选择可能取决于项目的细节。

随着机器学习领域的不断发展,许多支持框架和库也在不断发展。请记住,我们提到的一些 API 和工具在你阅读这篇文章的时候可能已经过时了。我们强烈建议您掌握最新的可用工具,因为这些工具可能包括大量的增强和优化。

虽然我们的重点将是使用 PyTorch(版本 1.10 和 1.11)和来自亚马逊 S3 的培训,但我们所说的许多内容也同样适用于其他培训框架和其他对象存储服务。

特别感谢伊扎克·李维帮助他创建了这个帖子。

测量吞吐量

在接下来的部分中,我们将回顾从 S3 流式传输数据的不同方法。我们将通过计算训练吞吐量来比较这两种方法,训练吞吐量是通过每秒输入训练循环的数据样本数量来衡量的。为了只关注数据流的性能,我们将测量空训练步骤情况下的吞吐量,如下面的代码块所示。

import torch, time
from statistics import mean, variancedataset=get_dataset()
dl=torch.utils.data.DataLoader(dataset, batch_size=4, num_workers=4)stats_lst = []
t0 = time.perf_counter()
for batch_idx, batch in enumerate(dl, start=1):
    if batch_idx % 100 == 0:
        t = time.perf_counter() - t0
        print(f'Iteration {batch_idx} Time {t}')
        stats_lst.append(t)
        t0 = time.perf_counter()mean_calc = mean(stats_lst[1:])
var_calc = variance(stats_lst[1:])print(f'mean {mean_calc} variance {var_calc}')

重要的是要记住,虽然这种比较测量可能会让我们很好地了解每种方法可以支持的最大吞吐量,但它可能无法很好地预测您选择的方法将如何影响实际的培训吞吐量,原因有两个:

  1. 您选择的方法可能不会影响您的整体训练步骤时间。例如,如果您的培训步骤是计算密集型的,那么从 S3 提取一个文件需要 1 秒钟还是 10 秒钟可能没有区别。
  2. 典型的训练步骤将包括许多可能影响实际训练量的附加操作。特别是,一些操作可能会争用从 S3 传输数据的相同资源。

我们经常使用的另一种测量数据流对整体训练速度的影响的技术是,测量在缓存的数据样本上运行而不是在流数据样本上运行时步长时间如何变化,如下所示。

import torch, time
from statistics import mean, variancedataset=get_dataset()
dl=torch.utils.data.DataLoader(dataset, batch_size=4, num_workers=4)**batch = next(iter(dl))** t0 = time.perf_counter()
for batch_idx in range(1,1000):
 **train_step(batch)**    if batch_idx % 100 == 0:
        t = time.perf_counter() - t0
        print(f'Iteration {batch_idx} Time {t}')
        t0 = time.perf_counter()

玩具示例— WebDataset

出于演示的目的,我们将使用一个由随机图像和图像分割组成的合成数据集,这些图像和图像分割以 WebDataset 文件格式存储,这是一种基于 tar 文件的格式,专门设计用于大型数据集的训练。具体来说,我们使用以下代码块生成了多个 400 兆字节的 tar 文件:

import webdataset as wds
import numpy as np
from PIL import Image
import ioout_tar = 'wds.tar'
sink = wds.TarWriter(out_tar)
im_width = 1024
im_height = 1024
num_classes = 256for i in range(100):
    image = Image.fromarray(np.random.randint(0, high=256,
                  size=(im_height,im_width,3), dtype=np.uint8))
    label = Image.fromarray(np.random.randint(0, high=num_classes,
                  size=(im_height,im_width), dtype=np.uint8))
    image_bytes = io.BytesIO()
    label_bytes = io.BytesIO()
    image.save(image_bytes, format='PNG')
    label.save(label_bytes, format='PNG')
    sample = {"__key__": str(i),
              f'image': image_bytes.getvalue(),
              f'label': label_bytes.getvalue()}
    sink.write(sample)

来自亚马逊 S3 的流媒体

在这一节中,我们将回顾一些工具和技术,从亚马逊 S3 流数据。这项审查绝非详尽无遗;还有许多其他工具我们没有在这里介绍。我们将使用上面显示的 WebDataset 示例演示一些选项。我们将解决方案大致分为两种类型,一种是我们将数据从 S3 系统中明确提取到训练环境中的解决方案,另一种是向应用程序公开文件系统风格的接口的解决方案。

文件对象下载

亚马逊 S3 的许多培训解决方案都涉及到将数据明确下载到本地培训环境中。

使用 AWS CLI 下载对象:
从 S3 获取文件的最简单方法之一是使用 AWS 命令行界面工具。以下命令将下载存储在 S3 的目标文件:

aws s3 cp s3://<path in s3>/wds0.tar -

用本地路径替换连字符将导致文件保存到本地磁盘。有关该工具使用的更多详细信息,请参见此处的。

WebDataset 库支持从使用 AWS S3 cp 命令提取的文件中通过管道传输字节流。我们在下面的代码块中演示了如何以这种方式创建 PyTorch 数据集:

import io, webdataset
def get_dataset():
    urls = [f's3://<path in s3>/{i}.tar' for i in range(num_files)]
    # add awscli command to urls
    urls = [f'pipe:aws s3 cp {url} -' for url in urls]
    dataset = (
           webdataset.WebDataset(urls, shardshuffle=True)
            .shuffle(10)
    )
    return dataset

用 Boto3 下载对象: Boto3 是一个 Python 库,可以从 S3 下载对象文件。下面的函数演示了如何将文件数据的内容提取到本地内存的字节流中。

import boto3, io, webdataset, re
client = boto3.client("s3")def get_bytes_io(path):
    byte_io = io.BytesIO()
    _, bucket, key, _ = re.split("s3://(.*?)/(.*)$", path)
    client.download_fileobj(bucket, key, byte_io)
    byte_io.seek(0)
    return byte_io

尽管 WebDataset 不包含对这种用法的本机支持,但我们可以通过覆盖 webdataset 中的 url_opener 函数来轻松添加它。

import webdataset
from webdataset.handlers import reraise_exceptiondef url_opener(data, handler=reraise_exception, **kw):
    for sample in data:
        url = sample["url"]
        try:
            stream = get_bytes_io(url)
            sample.update(stream=stream)
            yield sample
        except Exception as exn:
            exn.args = exn.args + (url,)
            if handler(exn):
                continue
            else:
                break**webdataset.tariterators.url_opener = url_opener**def get_dataset():
    urls = [f's3://<path in s3>/{i}.tar' for i in range(num_files)]                                     
    dataset = (
           webdataset.WebDataset(urls, shardshuffle=True)
            .shuffle(10)
    )
    return dataset

SageMaker 管道模式 :
亚马逊 SageMaker 是 AWS 提供的一项托管服务,用于大规模执行基于云的机器学习。它提供的众多实用工具包括专用 API,用于与存储在亚马逊 S3 的训练数据进行交互。 SageMaker 文档详述了支持的不同数据输入模式。在之前的一篇文章中,我们扩展了 SageMaker 管道模式的一些属性。管道模式是另一种将数据从 S3 显式提取和流式传输到本地培训环境的方式。使用管道模式时,通过专用的 Linux FIFO 管道获取训练数据。

with open(fifo_path, ‘rb’, buffering=0) as fifo:
    # read and parse data stream to yield samples

管道模式的一个缺点是它需要解析传入的数据流。这意味着它的使用仅限于支持这种解析方式的文件格式。在之前的一篇文章中,我们演示了以这种方式构建训练输入管道。

S3 接入解决方案

虽然应用程序通常被编程为与文件系统一起工作,但亚马逊 S3 是一个对象存储,而不是文件系统。许多解决方案旨在通过向亚马逊 S3 公开类似接口的文件系统来弥合这一差距。

S3Fs:
S3Fs 是几个基于 FUSE 的 Python 解决方案之一,用于将 S3 桶挂载为文件系统。虽然 WebDataset 不包含对使用 S3Fs 的本机支持,但我们可以覆盖 webdataset.tariterators 中的 url_opener 函数来使用它。注意,要将 S3Fs 与 PyTorch 一起使用,我们需要将多处理启动方法设置为“spawn”

***torch.multiprocessing.set_start_method('spawn')***import s3fs, webdataset
from webdataset.handlers import reraise_exceptionfs = s3fs.S3FileSystem()def url_opener(data, handler=reraise_exception, **kw):
    for sample in data:
        url = sample["url"]
        try:
            stream = fs.open(url.replace("s3://", ""), mode='rb')
            sample.update(stream=stream)
            yield sample
        except Exception as exn:
            exn.args = exn.args + (url,)
            if handler(exn):
                continue
            else:
                breakwebdataset.tariterators.url_opener = url_openerdef get_dataset():
    urls = [f's3://<path in s3>/{i}.tar' for i in range(num_files)]                                     
    dataset = (
           webdataset.WebDataset(urls, shardshuffle=True)
            .shuffle(10)
    )
    return dataset

查看这篇很酷的帖子了解更多基于 FUSE 的提取 S3 数据的方法,包括 s3f 的替代方法,如 goofysrclone

https://joshua-robinson.medium.com/object-storage-via-fuse-filesystems-ea2cc8094e2c

亚马逊 S3 PyTorch 插件 :
去年 AWS 宣布发布一个专用库,用于将数据从 S3 拉入 PyTorch 培训环境。这个插件的细节,包括使用说明,可以在这个 github 项目中找到。应该注意的是,作者最近宣布弃用这个库,并计划在 TorchData 库中用 S3 IO 支持来取代它。(下面将详细介绍。)下面的代码块演示了使用 S3 PyTorch 插件,用我们的 toy WebDataset 文件创建一个可迭代的 PyTorch 数据集。

from awsio.python.lib.io.s3.s3dataset import S3IterableDatasetclass S3_Dataset(torch.utils.data.IterableDataset):
    def __init__(self, urls):
        self._s3_iter_dataset = S3IterableDataset(urls, True) def data_generator(self):
        try:
            while True:
                image_fname, image_fobj = next(self._s3_iter)
                label_fname, label_fobj = next(self._s3_iter)
                yield {
                    'image': image_fobj,
                    'label': label_fobj
                } except StopIteration:
            return def __iter__(self):
        self._s3_iter = iter(self._s3_iter_dataset)
        return self.data_generator()def get_dataset():
    urls = [f's3://<path in s3>/{i}.tar' for i in range(num_files)]                                     
    dataset = S3_Dataset(urls)
    return dataset

SageMaker 快速文件模式 :
亚马逊 SageMaker 提供了一个额外的基于 FUSE 的解决方案,用于在 S3 访问文件调用快速文件模式 (FFM)。当您对 SageMaker 作业进行编程以使用快速文件输入模式时,S3 路径会挂载到预定义的本地文件路径上。在最近的一篇文章中,我们扩展了这个输入模式选项,演示了它的用法,并讨论了它的优缺点。采用我们的 WebDataset 来使用 FFM 非常简单:

import os, webdataset
def get_dataset():
    ffm = os.environ['SM_CHANNEL_TRAINING']
    urls = [os.path.join(ffm, f'{i}.tar') for i in range(num_files)]
    dataset = (
           webdataset.WebDataset(urls, shardshuffle=True)
            .shuffle(10)
    )
    return dataset

请注意,在撰写本文时,FFM 性能可能取决于文件数量以及预定义 S3 路径中的分区数量。

结果

下表包括我们在 EC2 c5.xlarge 实例上的不同数据集上运行空训练循环时得到的平均步进时间。这些结果是作为您可能获得的比较性能结果类型的示例提供的。我们警告不要从这些结果中得出任何关于您自己项目的结论,因为性能很可能高度依赖于训练模型和数据的细节。

每 100 步的平均时间(按作者)

使用 TorchData 管道进行流式传输

TorchData 是一个令人兴奋的新 PyTorch 库,用于创建 PyTorch 数据集。它目前作为 beta 产品发布,需要 PyTorch 版(或更高版本)。官方发布预计在未来几个月。 TorchData gihub 项目页面包括关于库设计及其 API 文档和示例的信息。TorchData 包含许多用于创建数据管道的构建块模块,包括用于加载以 WebDataset 格式存储的数据集的模块和用于从 S3 提取数据的模块。

在下面的部分中,我们将展示 TorchData 库支持的一些解决方案。请记住,在正式发布库之前,有些 API 可能会进行修改。

使用 IoPathFileOpener:
IoPathFileOpener支持直接从云存储中加载文件。它依赖于 iopath I/O 抽象库。下面的代码块演示了它的用法:

from torchdata.datapipes.iter import IoPathFileOpener, IterableWrapperdef get_dataset():
    urls = [f's3://<path in s3>/{i}.tar' for i in range(num_files)]
    urls = IterableWrapper(urls).shuffle().cycle()
 **tars = IoPathFileOpener(urls, mode="rb").load_from_tar()**    samples = tars.groupby(lambda x:     
                               os.path.basename(x[0]).split(".")[0],
                           group_size=2, guaranteed_group_size=2)
    dataset = samples.map(lambda x: 
                  {'image': x[0][1].read(),
                   'label': x[0][1].read()})
    dataset = dataset.shuffle(buffer_size=10)return dataset

使用 FSSpecFileOpener:
FSSpecFileOpener支持类似的功能,这次基于 S3Fs 库。下面的代码块演示了它的用法:

from torchdata.datapipes.iter import FSSpecFileOpener, IterableWrapperdef get_dataset():
    urls = [f's3://<path in s3>/{i}.tar' for i in range(num_files)]
    urls = IterableWrapper(urls).shuffle().cycle()
 **tars = FSSpecFileOpener(urls, mode="rb").load_from_tar()**    samples = tars.groupby(lambda x:     
                               os.path.basename(x[0]).split(".")[0],
                           group_size=2, guaranteed_group_size=2)
    dataset = samples.map(lambda x: 
                  {'image': x[0][1].read(),
                   'label': x[0][1].read()})
    dataset = dataset.shuffle(buffer_size=10)
return dataset

使用 SageMaker FFM :
在使用 Amazon SageMaker 进行培训时,我们也可以通过使用 FFM 并指向本地文件挂载来使用标准的 FileOpener 类。

import os
from torchdata.datapipes.iter import FileOpener, IterableWrapperdef get_dataset():
    ffm = os.environ['SM_CHANNEL_TRAINING']
    urls = [os.path.join(ffm, f'{i}.tar') for i in range(num_files)]       
    **tars = FileOpener(urls, mode="rb").load_from_tar()
**    samples = tars.groupby(lambda x:     
                               os.path.basename(x[0]).split(".")[0],
                           group_size=2, guaranteed_group_size=2)
    dataset = samples.map(lambda x: 
                  {'image': x[0][1].read(),
                   'label': x[0][1].read()})
    dataset = dataset.shuffle(buffer_size=10)
return dataset

使用 S3FileLoader :
这是亚马逊 S3 PyTorch 插件的翻版, S3FileLoader 是 AWS 专门创建的用于从 S3 加载数据的数据管道。在撰写本文时,它还没有包含在默认的 torchdata 包中,需要一些安装步骤,如这里的所述

from torchdata.datapipes.iter import S3FileLoader, IterableWrapperdef get_dataset():
    urls = [f's3://<path in s3>/{i}.tar' for i in range(num_files)]
    urls = IterableWrapper(urls).shuffle().cycle()
 **tars = S3FileLoader(urls).load_from_tar()**    samples = tars.groupby(lambda x:     
                               os.path.basename(x[0]).split(".")[0],
                           group_size=2, guaranteed_group_size=2)
    dataset = samples.map(lambda x: 
                  {'image': x[0][1].read(),
                   'label': x[0][1].read()})
    dataset = dataset.shuffle(buffer_size=10)
return dataset

结果

同样,当在使用新的 TorchData 库创建的不同数据集上和在 EC2 c5.xlarge 实例上运行相同的空训练循环时,我们共享平均步骤时间。

每 100 步的平均时间(按作者)

虽然我们仍然对从这些结果中得出任何有意义的结论持谨慎态度,但似乎新的 TorchData 不仅在功能上,而且在从 S3 传输的速度上提供了升级。

摘要

在这篇文章中,我们回顾了从亚马逊 S3 到训练环境的数据流的几种选择。这份清单并不全面;还有许多额外的工具和技术。

我们认为让自己熟悉几种技术是至关重要的,因为你可能会发现你的首选要么与你的项目不相关,要么它的性能不令人满意。

如果有任何意见、更正或问题,请随时联系我。

使用 Rust 张量流绑定训练 Keras 模型

原文:https://towardsdatascience.com/training-keras-models-using-the-rust-tensorflow-bindings-941791249a7

如何创建 Keras 模型并在 Rust 中用于训练和预测

(图片来自 Pixabay)

Rust 变得越来越受欢迎。它的安全执行和超快的运行时间,加上强大的社区支持,使它成为 c 等语言的一个有吸引力的替代语言。几乎没有开销,它就可以在微设备上运行 Rust,并且在边缘计算的环境中,当在边缘部署神经网络时,可能是一个不错的选择。

虽然有很多例子可以将预训练的 TensorFlow 模型与 Rust 绑定或 TensorFlow-C API 一起使用,但很少或根本没有关于如何在 Rust 中直接训练模型的例子。因此,在这个简短的教程中,我将概述这样做的方法。

在这个演示中,我们将创建一个非常简单的模型,它只接收一个具有两个元素和一个目标值的张量。这个想法只是为了让模型学会将这两个值相加。

模型架构(图片由作者提供)

理解 TensorFlow 内部将模型存储为图形很重要,就像上图中的图形一样。图形的这种表示将被绑定使用,因此它将与使用 Python 的模型完全不同。

创建自定义的 Keras 模型

作为第一步,我们需要创建一个从keras.Model类继承的类。在这个类中,我们将指定三种方法。所需的__init__()方法、call()函数(将用于预测)和train()函数(将用于训练)。

注意,我们将@tf.function装饰器添加到了calltrain函数中。这是为了将它们存储为图形。默认情况下,Python 中的 TensorFlow 以急切执行方式运行,用于绑定,但是我们需要图形。

这个新创建的custom_model类的任何实例都将能够使用所有已知的 Keras 函数,比如fit()predict()compile()。我们现在将创建一个custom_model的实例并编译它。

在保存模型以在 Rust 中使用它之前,我们必须分配我们创建的自定义函数。否则,我们以后在图形上操作时将无法访问它们。因此我们必须得到具体的函数。TensorFlow 中的具体函数是一种独特的图形函数表示,其中输入和输出都有精确的定义。为了创建这样一个具体的函数,我们指定输入和输出(形状和数据类型),以便为每个函数创建一个图。因为 Python 支持多态性(几种数据类型),所以对于不同形状或数据类型的每个可能的输入,都会有一个新的图形。这被称为跟踪。为了防止跟踪,我们创建了具体的函数,因此定义了输入和输出特征,并且可以保存一个唯一的图形表示,它只接受特定的输入,并且总是返回相同的指定输出。然后,这些具体的函数可以与图形一起保存,并通过绑定进行访问。

这里我们指定函数的具体输入为TensorSpecs。这为函数的输入和输出分配了具体的形状和数据类型,并创建了一个符合这些规范的图形表示。我们给输入节点一个名称,以便我们能够从 Rust 环境中访问它们。注意,训练输入由两个凸部的元组组成,一个用于输入,一个用于目标,这将用于训练步骤。

接下来,我们使用 keras save()方法保存模型。在这里,我们指定签名,为每个签名分配一个唯一的名称,以便从 Rust 访问它们。

通过这种方式,函数与模型一起保存,并且可以使用我们传递给save()方法的字典中的相关名称进行访问。

使用绑定访问模型并对其进行训练

运行 Python 代码后,模型将被保存,然后可以在 Rust 中作为图形加载。绑定的工作方式是我们将变量输入到图中,运行它并从输出节点获取变量(这里的函数也是有输出节点的图)。然而,我们不知道函数的输出节点名,因为它们是由 Keras 指定的。请记住,我们在创建具体函数时给了输入名称。因此,我们已经知道了输入节点的名称。不幸的是,据我所知,没有办法命名输出节点。他们将自动获得指定的名称,但是这些名称在架构被定义之后将保持不变。所以我们只需要检索一次名字。获取输出名称的一种方法是在终端中使用saved_model_cli命令。

该命令的(部分)输出如下所示:

(图片由作者提供)

对于我们的信号predtrain,您可以找到输出节点的名称。在这种情况下,两者都被命名为output_0。现在我们有了在 Rust 中使用该模型所需的所有信息。

我们将创建两个张量,一个作为训练输入,一个作为训练目标,并且只运行一个训练步骤。为此我们创建了两个张量。

接下来,我们从保存模型的路径将模型作为图形加载。

这是作为一个包加载的,我们将在其上创建一个会话。

现在,我们从图中加载训练计算的签名。

这样做之后,我们可以使用我们用于输入的名称和我们用saved_model_cli命令检索的用于输出的名称从签名中获得输入和输出。从这些我们分别创建输入和输出操作。

这些操作表示图形中的节点,该图形表示产生输出的计算。

设置好这些东西后,我们就可以开始计算了。正如我之前所说的,我们将把图形的输入输入到它的输入节点,并从输出节点获取输出。方法是使用一个SessionRunArgs对象。

通过指定输入张量使用的运算来添加输入张量。换句话说,在哪个节点喂养它们。之后,发出一个获取请求,我们使用另一个操作来指定哪个节点将返回结果。

为预测操作提供和获取张量(图片由作者提供)

现在我们可以运行会话了。这将在图上执行计算。

结果现在将存储在SessionRunArgs对象中。剩下的就是找回它。

在这种情况下,我们让训练函数返回损失。我们可以在那里返回任何值,甚至不返回任何值。因为可能输出多个值,所以我们必须对结果进行索引。这里我们取索引 0 处的值,只是因为只存在一个值。

这就结束了一个训练步骤。当然,这是一个非常简单的演示,但我的目标是展示一种训练张量流模型的方法,所以我应该尽可能保持简单。

为了完整起见,下面是用我们的模型进行预测的代码。如您所见,这与培训非常相似。

所有代码都可以在https://github.com/Grimmp/RustTensorFlowTraining找到

我希望这篇教程有助于理解如何在 Rust 中训练 TensorFlow 模型。

训练神经网络像人类一样创造文本

原文:https://towardsdatascience.com/training-neural-networks-to-create-text-like-a-human-23bfdc23c28

递归神经网络可以生成与人类书写难以区分的文本。这里有一个亚马逊产品评论数据的例子。

由 mauricio SANTOS 在 Unsplash 上拍摄的照片

语言建模使用各种技术来确定特定语言的句子中单词序列的概率。它在很大程度上借鉴了 Yoshua Bengio 及其合作者的工作(例如,参见 Bengio 等人,2003 )中的神经概率语言模型)。

事实上,语言模型被用于人们日常使用的应用程序中。语音识别系统,如亚马逊的 Alexa,将语音转换为文本,其关键组件之一是其语言模型(拉朱,2019 )。此外,目前帮助在所有主要语言之间直接翻译句子的谷歌翻译(Google Translate)由深度学习语言模型支持(【吴等人,2016 ,展示了其原始架构)。

本文将说明神经语言模型如何生成人们无法从人类书写中识别的文本。我们将探索 TensorFlow 中的实现,并将使用和神经网络编写产品评论。产品评论可以作为非常好的训练数据,因为它们通常比书籍或诗歌在语法上更简单,这样,深度神经网络应该可以很好地预测文本。

数据

朱利安·麦考利从他的网站收集的亚马逊产品评论数据被用作训练数据。通过在亚马逊上填写评论,客户授予亚马逊权利“使用、复制、修改、改编、出版、表演、翻译、创作衍生作品、在全球范围内以任何媒体发布和展示这些内容。” ( 数据使用条件编于何、麦考利,2016 )。**

这里有几个例子:

作者图片

当生成文本时,我们不需要验证数据集,并将使用 100 %的数据进行训练。我们将仅使用训练数据来预测单词序列。没有过度拟合的风险,没有一般化,不需要训练测试分割。

本文使用 TensorFlow 和 Pandas 版本,此处指定。要复制文章,请在虚拟环境中按照这些要求运行代码。

建立语料库

从实现开始,有必要参考一下 Laurence Moroney 在 TensorFlow 开设的 NLP 基础课程。我遵循了他的指导方针,但是在必要的地方对 python 代码做了一些修改。

我们将遵循这个方案:

图片作者(来源:draw.io)

我不会过多地讨论几个概念的细节。请使用 这篇文章 来刷新这些术语的含义:标记化、填充、文本到序列。

此功能删除特殊字符、标点和数字,并准备一个干净的评论列表。我们需要熊猫和熊猫。

接下来,我们通过创建一个 tokenizer 对象并使其适合清理后的数据,对数据进行标记化。Tokenizer 将文本语料库矢量化,将其转换为单词及其索引的字典。

对于每个评论,我们准备 n-grams 来使用作为训练的输入序列。

我们将训练模型来预测所有可能的单词组合;因此,单个有序审查的 n 元语法如下所示:

作者图片

最后,我们填充测序数据并定义预测值标签。我们使用预测器来猜测序列中的下一个单词是什么,并使用标签来纠正模型的预测。

模特培训

为了训练模型,我们需要 TensorFlowKeras :

顺序模型包括六层:第一层将文本输入矢量化到 240 个维度。第二层是一个 LSTM,然后是一个辍学层做一些正规化。两个密集层跟随另一个 LSTM,在最后一个中具有 softmax 激活功能。

这项任务需要对模型进行多次训练,以获得良好的准确性。让我们也在准确度达到某个阈值(在我们的例子中是 93 %)时设置一个回调,并将其传递给fit方法。

我们在大约 140 个时期内达到了 93 %的准确率。这是沿着训练时期的准确度和损失的图:

作者图片

训练数据与生成的文本

现在,让我们看看客户评论和用神经网络生成的评论,看看我们是否能发现任何差异。

作者图片

生成的评论中有一些不完美之处:

  1. 没有逗号,但训练数据中的许多“真正的”评论也漏掉了逗号。
  2. 除了句子中的第一个单词,预测不处理大写字母。同样,在“我”的地方有“我”。

否则,很难发现任何差异。

我们是怎么做到的?

该模型基于我们指定为输入的种子文本来预测下一个单词。下面是我们要求神经网络完成的句子的五个开头:

我们之前适合训练数据的标记器现在用于对种子文本(前两个单词)进行排序,然后填充种子文本并使用model.predict_classes.预测下一个单词。然后,循环将预测的单词附加到一个句子中,并以相同的方式继续,直到我们获得一个包含 12 个单词的大写句子(种子文本+ 10 个预测的单词)。

如果我们想解决“I”的问题,我们可以在代码中用“I”替换“I ”,如下所示:

if output_word == ‘i’:
 output_word == ‘I’

结论

这篇文章展示了一个简单的神经网络如何产生一个很难从人类书写中识别的文本。亚马逊评论是很好的训练范例。当然,一个主要的区别是,递归神经网络只是一种应用的统计方法,并且不理解它被训练的文本。但是,将人类编写的文本和程序生成的文本进行比较真的很令人兴奋,这两者看起来非常相似。

jupyter 笔记本的完整代码可以在我的 GitHub 上找到。

PS:你可以订阅我的 邮件列表 在我每次写新文章的时候得到通知。如果你还不是中等会员,你可以在这里加入https://medium.com/@petrkorab/membership。****

免责声明: 本文使用的数据仅作为 TensorFlow 中教学文本生成的训练示例,适合这种特定的深度学习应用。作者不同意在生产中使用生成的数据,或者暗示任何不道德或法律禁止的行为。

参考资料:

一个神经概率语言模型。 J 机器学习研究杂志,2003 年第 33 期,第 1137–1155 页。

拉朱,A. 如何使神经语言模型在语音识别中实用亚马逊科学博客,2019 年 8 月 29 日。**

何,r .,麦考利,J. 沉浮:用一类协同过滤建模流行趋势的视觉演变国际万维网大会。2016 年 4 月 11 日至 15 日,加拿大魁北克省蒙特利尔。**

训练人工智能创作诗歌。 Youtube NLP 零到英雄课程,第 6 部分。

Mayo,M. 使用 TensorFlow & Keras 进行标记化和文本数据准备。 KDnuggets 教程。

Habana Gaudi 的 AWS 培训

原文:https://towardsdatascience.com/training-on-aws-with-habana-gaudi-3126e183048

利用专用 DNN 训练芯片的力量—第 2 部分

安东尼·高迪设计的圣家族大教堂的中殿,由维德·昆乔罗Unsplash 上拍摄的照片

今年十月,AWS 宣布亚马逊EC2 DL1 实例类型的到来。DL1 由 8 个 Habana Gaudi 加速器驱动,是第一个包含专用 AI 加速器的 AWS 实例类型,这些加速器是而不是GPU。Habana Gaudi 以著名的加泰罗尼亚建筑师Antoni Gaudi的名字命名,是一款全新的人工智能 ASIC,专门为深度学习工作负载而从头设计。这提供了提高资源利用率和降低培训成本的潜力。事实上,DL1 实例已经向全世界发布,并承诺“比当前一代基于 GPU 的实例的性价比高 40%”。

在这篇博文中,我们将评估 DL1 实例,并展示它的一些独特属性。这是上一篇文章的续篇,在那篇文章中,我们讨论了使用专用人工智能芯片的潜力以及采用它们的一些潜在挑战。在那里,我们建议将您的训练应用程序迁移到新的人工智能芯片的任务分解为四个步骤:

  1. 高级兼容性分析:尽早评估您的工作负载特性是否符合芯片规格和支持软件堆栈。
  2. 调整您的模型以在新芯片上运行:您可能需要对您的模型进行一些调整,例如替换专用人工智能芯片不支持的操作。
  3. 优化新芯片的运行时性能:为了充分利用芯片,您需要分析并最大化其利用率。
  4. 调整模型以在新芯片上收敛:可能需要对模型超参数进行一些修改,以确保及时收敛。

这些步骤在我们之前的帖子中有详细描述。在本帖中,我们将按照这些步骤评估 DL1 实例。

这篇博文和我们包含的代码片段是基于撰写本文时可用的最新软件栈,版本 1.2.0 。鉴于 Habana Gaudi 产品的相对新颖性,新版本可能会包括重要的增强和优化。您必须使用最新的可用软件堆栈,并确保相应地重新评估我们的一些陈述。
虽然我们将专注于tensor flow2.7 版本,但我们写的大部分内容也同样适用于 Habana Gaudi 支持的其他机器学习框架。

1.高级兼容性评估

此步骤的目的是收集尽可能多的公开信息,以便评估 DL1 产品是否满足了您的培训需求。这包括以下在线资源:

  • 系统架构规格:DL1 硬件细节以及 Habana Gaudi 架构指南应该能让你对机器的训练能力有一个大致的了解。特别是,您可以验证内存、计算和其他硬件资源是否符合您的需求。
  • 软件文档 : Habana Gaudi 附带了一个名为 SynapseAI 软件套件的综合软件堆栈。开发者文档包括支持的框架和版本API 限制等细节。有几个用户指南演示了如何使用 API 套件的许多特性。
    使用软件文档来验证支持的框架、版本和操作是否满足您的机器学习项目的需求。
  • 基准测试报告:哈伯纳在各种流行的模型架构上分享了性能基准测试结果。你可以将这些与其他人工智能加速器厂商的性能结果进行比较。您还可以查看 MLPerf ,这是一个流行的人工智能培训基准套件,可以比较多个人工智能加速器(包括 Habana Gaudi)在各种工作负载上的性能。最新的 MLPerf 报告摘要(在撰写本文时)可在这里找到。
    基准测试结果可以让你了解高迪擅长的车型类型。然而,正如我们在之前的帖子中所警告的,除非您正在训练的模型与基准报告中包含的模型之一相同,否则根据报告的基准来预测您自己的模型的性能可能不那么容易。这是因为模型中的小变化会对其运行时性能产生有意义的影响。

与任何其他新颖的硬件产品一样,要真正感受 DL1 的功能,除了开始使用它之外,没有其他更好的方法了。是的,您确实面临着投资进入潜在死胡同的风险,但我们相信,即使您最终没有在 DL1 上培训您当前的模型,您在此过程中积累的知识和技能也会很好地为您服务。

在下面的项目中,我们总结了与其他人工智能加速器和训练实例相比,基于高迪的 DL1 产品的一些主要亮点。接下来是一些潜在的担忧。这些都是基于我们自己的个人印象。我们的列表并不全面,也不应该被视为官方文件的替代品。

  • 异构架构:单个 Gaudi 内核,有时被称为 HPU (Habana 处理单元),由一群张量处理内核(TPC)和可配置矩阵数学引擎(GEMM)组成。GEMM 擅长矩阵乘法,而非线性和元素运算在 TPC 上运行。这种异构性使 Gaudi 能够在各种各样的工作负载上实现高效率。通过有效地平衡资源之间的负载,可以实现最大的利用率。
  • 高规模训练:架构设计特别注重高迪处理器之间的数据吞吐速度。这使得高迪能够展示当将训练扩展到多核时,出色的、接近线性的结果。
  • 框架支持:SynapseAI API 包括对 TensorFlowPyTorch 的支持,这是目前使用的最流行的两个机器学习框架。它还支持 Horovod ,这是一个流行的分布式培训框架。这些产品使得现代机器学习开发人员非常容易为 Gaudi 创建模型。
  • 丰富的模型花园:Habana SW 产品包括各种各样的参考模型——已经移植并优化用于在 Gaudi 上运行的流行模型的实现。
  • 定制内核创建:与其他一些专用 AI ASICs 相反,SynapseAI SW 套件包括用于实现定制 Gaudi (TPC)内核的工具。与用于 GPU 内核开发的 CUDA 工具包类似,这一功能使用户能够设计、开发和优化专门针对其工作负载需求的低级操作。
  • 运行并行试验:SW 套件支持在 DL1 实例上的八个底层 Gaudi 加速器的不相交子集上运行并行工作负载。一种方法是使用训练管弦乐队,比如 kubernetes。我们将演示如何利用这种能力来并行化超参数调优试验。
  • CPU 与 Gaudi 计算比率:在一个标准的机器学习项目中,计算将在 CPU 资源和 AI 加速器之间分配。通常,输入数据预处理管道将在 CPU 上运行,模型计算图(向前向后传递)将在 AI 加速器上运行。在理想情况下所有的培训资源都将被充分利用。但是最大化利用率对于 AI 加速器资源是最重要的,这些资源通常是系统中最强大和最昂贵的资源。在某些情况下,你可能会发现 CPU 跟不上人工智能加速器的速度,导致 CPU 瓶颈和人工智能加速器的利用不足。CPU 瓶颈的可能性由整体 CPU 计算能力和整体加速器计算能力之间的比率决定。DL1 实例具有相对较高的 CPU 与 Gaudi 计算比率,从而降低了 CPU 瓶颈和加速器利用不足的可能性。事实上,DL1 实例包含与 p4d.24xlarge EC2 实例相同的 CPU 计算能力(96 个第二代英特尔至强可扩展 CPU 内核),尽管其 AI 加速器 A100 被认为比 Habana Gaudi 更强大。
  • 批量灵活性:与其他人工智能加速器相反,Habana Gaudi 能够在很大的批量范围内实现高利用率,而其他人工智能加速器可能需要特别高的批量培训,以便充分利用硬件的价格优势。这使得高迪成为可能无法适应大批量生产的模型的可行选择。

以下是您应该考虑的几点:

  • API 限制:确保仔细阅读 SynapseAI 软件套件的限制。正如在撰写本文时在文档中明确指出的那样,“并非所有的模型在 Gaudi 上都得到支持”。如果您不能在 DL1 上编译您的模型,您可以尝试调整您的模型以符合 API 支持,或者探索创建定制操作的选项。或者,您可以简单地报告您的发现并跟踪synapse ai 版本的未来版本
  • 每个 DL1 实例八个加速器:在撰写本文时,唯一基于 Gaudi 的 AWS 实例产品包括八个加速器。这意味着,为了充分利用这个系统,你需要或者运行并行实验,或者将你的训练分布在所有的加速器上。如果这两个选项都不适合您,那么 DL1 实例可能不是您的最佳选择。
  • 性价比:你可能会发现你的型号支持的,但是你最初的试用并没有达到你预期的性价比。在这种情况下,您可以使用 Habana 优化指南性能分析指南自定义 op 创建指南和其他资源来提高性能。如果尽管你尽了一切努力,你还是不能达到足够的性价比,你最好的选择可能是报告你的发现,并等待 SynapseAI 套件的更新版本。

2.调整您的模型以在 DL1 上运行

在本节中,我们将讨论在 DL1 实例上启动和运行模型所需的一些步骤。这些都基于 Habana 官方文档,尤其是 TensorFlow 迁移指南。更多详情请见此处。

系统设置

有多种方法可以启动一个 Amazon EC2 实例和建立一个 DL1 运行时环境。最适合您的选择将取决于您/您组织的整体云架构。

加载 Habana 模块

调整 TensorFlow 模型以在 Habana Gaudi 上运行只需要两行代码,如下面摘自 Habana TensorFlow Hello World 示例的代码片段所示。

import tensorflow as tf
**from habana_frameworks.tensorflow import load_habana_module
load_habana_module()**(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0model = tf.keras.models.Sequential([
            tf.keras.layers.Flatten(input_shape=(28, 28)),
            tf.keras.layers.Dense(10),
])
loss = tf.keras.losses.SparseCategoricalCrossentropy(
                                           from_logits=True)
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)model.compile(optimizer=optimizer, loss=loss, metrics=['accuracy'])model.fit(x_train, y_train, epochs=5, batch_size=128)

运行脚本时,确保使用适当的 python 可执行文件。这取决于您选择的设置,如这里的所示。

检查设备放置

当运行你的脚本时,你要做的第一件事就是验证你的模型确实运行在 Gaudi 加速器上。高迪运行时环境包括 hl-smi 工具,它报告八个高迪内核的资源利用情况。它的外观和感觉类似于用于 GPU 的 nvidia-smi 工具。您可以使用该工具来验证运行您的训练脚本是否增加了第一个 Gaudi 内核的内存和计算资源。
除了断言正在使用 Gaudi 内核之外,您还会希望确保您的训练计算图的所有操作都在 Gaudi 上运行,而不是在 CPU 上运行。Gaudi 不支持的操作被卸载到 CPU 上,这可能会导致很高的事务开销,并大大降低您的培训速度。
检查器件布局的一种方法是使用TF . debugging . set _ log _ device _ placement函数。当设置为 True 时,该例程将生成一个日志,记录程序中所有 TensorFlow 操作的设备位置。高迪核心在 TensorFlow 中注册为“HPU”设备。如果你所有的训练任务都分配给“HPU ”,你的情况就很好。如果你的任何训练运算被分配给“CPU ”,你可能需要调整你的计算图,我们将在下一小节讨论。
此处记录了分析 op 布局的另一种方法

示例—使用不支持的数据类型:在下面的代码片段中,我们添加了对TF . math . arg max的调用,后跟 tf.equal

*import tensorflow as tf
from habana_frameworks.tensorflow import load_habana_module
load_habana_module()
**tf.debugging.set_log_device_placement(True)** (x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()x_train, x_test = x_train / 255.0, x_test / 255.0model = tf.keras.models.Sequential([
            tf.keras.layers.Flatten(input_shape=(28, 28)),
            tf.keras.layers.Dense(10),
            tf.keras.layers.Lambda(lambda x: 
               tf.where(tf.expand_dims(**tf.equal**(
                  **tf.math.argmax**(x,axis=-1),2),-1),
                  x,
                  tf.math.square(x)))])
loss =  tf.keras.losses.SparseCategoricalCrossentropy(
                                          from_logits=True)
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
model.compile(optimizer=optimizer, loss=loss, metrics=['accuracy'])
model.fit(x_train, y_train, epochs=5, batch_size=128)*

tf.math.argmax 的默认输出为 tf.int64 类型,然而,截至本文撰写之时,int64 并不在 HPU 支持的数据类型列表中。结果是TF . equal操作将在 CPU 上运行。器件放置调试日志将包括以下几行:**

**sequential/lambda/ArgMax: (ArgMax): /job:localhost/replica:0/task:0/device:HPU:0
sequential/lambda/Equal: (Equal): /job:localhost/replica:0/task:0/**device:CPU**:0**

在这个玩具示例中,修复方法是简单地将TF . math . arg maxoutput_type 设置为 tf.int32。

模型调整

在 HPU 上训练模型可能需要对模型进行一些更改。所需的模型调整在复杂程度上会有所不同。在某些情况下,它们就像指定底层数据类型一样简单,如上例所示。在其他情况下,您可能需要修改数据流或替换操作序列。例如,SynapseAI 1.2.0 版本的发行说明中包含了“Gaudi 目前不支持 tf.condtf.while_loop 等控制流操作”的限制。在撰写本文时,Gaudi 不支持的另一个操作示例是 tf.numpy_function ,这是一个允许在计算图中包含任意 python 代码(例如用于度量计算)的例程,有时用于绕过本机 TensorFlow API 施加的限制。如果您的模型包含这样的操作,您将需要设计一个替代流程,或者接受让它们在 CPU 上运行的性能损失。

您需要为高迪进行模型调整的三个重要资源是 HPU 支持的 TensorFlow 操作的列表、模型参考目录定制内核创建指南

支持的 TensorFlow 操作 :使用本文档在图形中查找高迪对操作的支持。

模型参考目录 :哈瓦那高迪产品包括各种常见机器学习模型架构的参考实现。这些实现已经过修改和调整,可以在高迪上运行。如果您正在使用其中一种实现的架构,您应该认为自己很幸运。但是,即使您使用的是不同的模型架构,模型参考目录中也可能包含您认为有用的计算层或计算块。例如,如果您正在研究变压器架构,最好查看一下变压器块的高迪特定实现,要么照原样使用,要么深入了解如何对您自己的变压器块进行适当的调整。

自定义内核创建:Habana Gaudi 区别于市场上其他一些专用 AI ASICs 的特性之一是其可由最终用户编程。Habana 提供了关于创建定制 HPU 内核用 TensorFlow 操作符包装它们的全面指南。也可以看看这个详细的例子和这个视频教程

预处理流水线**:需要注意的是,虽然将你的模型移植到 Gaudi 可能需要改变运行在加速器上的训练计算图,但是需要调整运行在 CPU 内核上的预处理流水线。这与其他一些人工智能加速器相反,正如我们在过去看到的。

关于 DL1 的分布式培训

当然,要充分利用 DL1 资源,仅将其移植到单个 HPU 上运行是不够的;您将希望利用所有八个 hpu。一种方法是使用数据分布式训练在所有八个 hpu 上并行训练。Habana Gaudi 软件堆栈提供了两种实施分布式培训的机制。第一个使用了 Habana Gaudi 流行的 Horovod 框架的具体实现。第二个使用了一个定制的TF . distribute . strategyAPI 实现。分布式培训指南包括两个选项的详细信息。
选择 Horovod 选项的优势在于,如果您已经使用 Horovod for GPUs 实施了分布式培训,则无需更改代码即可在 hpu 上运行。您需要做的只是验证 habana-horovod 套件的正确安装。事实上,与其他定制 AI ASIC 产品相比,Horovod 支持是 Habana 产品的优势之一。

请注意,在撰写本文时,遵守导入命令的特定顺序很重要,如摘自 Habana Gaudi 文档的这段代码所示。

**import tensorflow as tf
from habana_frameworks.tensorflow import load_habana_module
***# ensure that load_habana_module() needs to be called before
# import horovod***
load_habana_module()
import horovod.tensorflow.keras as hvd
*#Initialization of Horovod.* 
hvd.init()**

Horovod 框架也可用于在多个 DL1 实例上并行训练

3.在 DL1 上优化您的模型性能

此时,您应该能够在 DL1 上成功运行一个培训周期。接下来是性能分析和优化的关键步骤。正如我们在上一篇文章中强调的,人工智能加速器的好坏取决于它为性能分析和优化提供的工具。如果你不能分析和优化性能,你就不能充分利用人工智能芯片。

Habana 为性能分析和优化提供了三个重要的资源:最佳实践列表(T0)、T2 性能优化指南(T3)和 T4 性能分析器(T5)。应该详细研究这些指南并经常参考。我们将对每一个提供一些简短的评论。

高迪培训的最佳实践

这个页面包括关于高迪培训的一般(框架不可知)指南。虽然这个列表很紧凑(在撰写本文时只有 7 点),但是每一项都可以对模型性能产生有意义的影响。有两点值得一提:

  1. ****动态形状:不鼓励使用返回未确定大小的形状的操作符。参见我们之前的帖子,在其中我们演示了如何替换使用一个这样的函数,TF . boolean _ mask
  2. ****张量形状:有些项目建议张量形状的选择(如批量大小和特征/通道数量)遵循一定的公式。这对于一个专门的人工智能加速器(或者任何芯片,就此而言)来说并不罕见。正如我们在第 1 节中提到的,其他 AI 芯片需要使用大批量来最大化利用率。在这方面,高迪为用户提供了更大的自由/灵活性。

性能优化指南

本页主要关注 TensorFlow 框架的优化指南。其中一个建议是利用高迪内置的对 bfloat16 的支持,使用 TensorFlow 的混合精度 API。在训练期间使用低精度浮点(16 位)可以潜在地减少存储器使用和训练步骤时间。有两种低精度浮点格式,float16 和 bfloat16 ,bfloat16 具有许多属性,使其成为机器学习的首选格式。
需要注意的是,虽然使用混合精度时内存利用率的降低几乎是可以保证的,但步长时间的降低以及模型的收敛能力仍需验证。

性能分析器

Profiler 用户指南包含关于 SynapseAI Profiler 的大量文档,包括其设置、执行和分析工具。还有这个有用的视频教程
正如我们在之前的帖子中详细讨论的那样(例如这里的和这里的),描述您的培训绩效对于最大限度地利用您的培训资源、加速您的培训和降低培训成本至关重要。

Habana 性能分析器的主要工件是分析图。与 TensorBoard 跟踪查看器类似,该图显示了不同系统资源上发生的不同事件的时间线,特别是 DMA、MME 和 TPC。下面是一些您可能遇到的资源使用模式的例子,以及从中可以学到什么:

  1. ****数据输入管道上的瓶颈:HPU 上训练步骤之间的大间隔可能表示 HPU 在等待 CPU 传递训练数据时处于空闲状态。在这种情况下,您应该致力于优化您的数据输入管道。(此处见。)
  2. ****将操作卸载到 CPU 上:在训练步骤中间的 HPU 空闲与增加的 DMA 活动相结合,可能表明一些图形操作正在被卸载到 CPU 上。在这种情况下,您应该重新检查图形操作的设备位置。
  3. ****MME 利用率和 HPC 利用率之间的不平衡:您可能会在训练步骤中发现 MME 空闲而 HPU 非常繁忙的时段,反之亦然。在这种情况下,您可以通过改善资源之间的负载平衡来减少步骤时间。这可以通过编程/设计等效的设备特定内核来实现,如这里建议的。

在撰写本文时,Habana Gaudi 性能分析器的使用需要 Gaudi 特定的配置步骤和工具。我们的预期是,即将发布的版本将包括对分析器使用的改进,包括将其完全集成到 TensorFlow 分析 API 和 TensorBoard 中。

4.调整您的模型以收敛于 DL1

此时,您的模型已经被调整到您满意的程度,您可以开始训练了。您可能需要对模型进行一些更改,这需要重新调整超参数以确保模型收敛。此类更改可能包括替换某些操作、更改控制流或更改底层数据类型。即使你没有对你的模型做任何改变,你也应该确保你的训练收敛在新的 AI ASIC 上。这是因为不同的硬件加速器以不同的方式实现,并且可能在它们的行为中表现出微小的数值差异。在一个 ASIC 上的收敛并不保证在另一个上的收敛。

示例 DL1 上的超参数调谐

在本例中,我们展示了如何利用八个 HPU 内核在超参数调整环境下运行八个并行实验。超参数调整指的是为您的模型搜索最佳超参数的任务。 Ray Tune 是一个流行的 python 库,用于自动化超参数调整,支持各种最先进的优化算法。虽然默认版本只将 CPU 和 GPU 视为可能的“培训资源”,但它也可以扩展为使用 HPU。在下面的代码块中,我们通过将 hpu 注册为 GPU 来演示一种相当简单的方法。在下面的代码片段中,它基于 Ray Tune 记录的 mnist 示例,我们突出显示了两个必需的更改:

  1. 通过光线初始化命令显式注册八个 GPU。这是必需的,因为当前版本的 Ray 不能识别 HPU 加速器。
  2. 进入列车功能后,根据 CUDA_VISIBLE_DEVICES 环境变量的值设置 HABANA_VISIBLE_DEVICES 环境变量。这将确保每个进程在单独的 HPU 上运行。
**import os
import ray
from ray import tune
from ray.tune.schedulers import AsyncHyperBandScheduler
from ray.tune.integration.keras import TuneReportCallbackdef train_mnist(config):
 **os.environ['HABANA_VISIBLE_DEVICES'] = \
        os.environ['CUDA_VISIBLE_DEVICES']**    import tensorflow as tf
    from habana_frameworks.tensorflow import load_habana_module
    from tensorflow.keras.datasets import mnist
    from filelock import FileLock
    load_habana_module() with FileLock(os.path.expanduser("~/.data.lock")):
        (x_train, y_train), (x_test, y_test) = mnist.load_data()
    x_train, x_test = x_train / 255.0, x_test / 255.0 model = tf.keras.models.Sequential([
            tf.keras.layers.Flatten(input_shape=(28, 28)),
            tf.keras.layers.Dense(10)])
    loss = tf.keras.losses.SparseCategoricalCrossentropy(
                          from_logits=True)
    optimizer = tf.keras.optimizers.SGD(learning_rate=config['lr'])
    model.compile(optimizer=optimizer,
                  loss=loss, 
                  metrics=['accuracy'])
    model.fit(x_train, y_train, epochs=5, batch_size=128,
              verbose=0, validation_data=(x_test, y_test),
              callbacks=[TuneReportCallback({
                 "mean_accuracy": "accuracy"})])def tune_mnist(num_training_iterations):
    sched = AsyncHyperBandScheduler(
        time_attr="training_iteration", max_t=400, grace_period=20)
 **# explicitly init ray with number of accelerators set to 8** 
 **ray.init(num_gpus=8)**    analysis = tune.run(
        train_mnist,
        name="exp",
        scheduler=sched,
        metric="mean_accuracy",
        mode="max",
        stop={
            "mean_accuracy": 0.9,
            "training_iteration": num_training_iterations
        },
        num_samples=8,
        resources_per_trial={
            "cpu": 12,
            "gpu": 1
        },
        config={
            "lr": tune.uniform(0.001, 0.1),
        })
    print("Best hyperparameters found were: ", analysis.best_config)if __name__ == "__main__":
    tune_mnist(num_training_iterations=1000)**

摘要

新的训练实例选项的可用性总是令人兴奋的消息,尤其是当它基于专用的 AI ASIC 时。为 DL1 实例提供动力的 Habana Gaudi 产品似乎具备了当今市场上其他人工智能加速器的所有有价值的替代物。特别是,其附带的软件堆栈在设计和优化机器学习工作负载方面为用户提供了极大的灵活性。与此同时,重要的是要记住,Habana Gaudi 相对较新,因此应该以适当的心态来对待。达到你的最佳结果可能需要耐心和韧性。但是它值得潜在的回报。在我们自己的车型上,性价比的增长达到甚至超过了公布的 40%大关。

这篇文章仅仅介绍了 DL1 实例培训的几个方面。请务必参考丰富的在线文档以了解更多详细信息。

在这篇博文的研究过程中,我发现“高迪”在德语中是“有趣”的意思。我想不出更好的方式来描述我迄今为止在 DL1 上的经历。我所能希望的是,你也有“高迪”和你的高迪。

tf.keras .应用程序的培训规则

原文:https://towardsdatascience.com/training-regnets-for-tf-keras-applications-c9bcdc70755

这篇博文是关于分享我为tf.keras.applications训练 24 个 RegNet 模型的经验。

Paola blaskovi 在 Unsplash 上的照片

序言

tf.keras.applications是 TensorFlow-Keras 中的一组内置模型。它们在 ImageNet-1k 上进行了预训练,只需一次函数调用。这使得大联盟成员的生活更加轻松,因为他们有现成的模型可供使用。regnet是脸书人工智能研究所(FAIR)提出的高效可扩展模型。它们被用在像 SEER 这样的工程中,这些工程需要可以扩展到亿万个参数的模型。在向 Keras 提交 PR 的过程中,我实现并训练了 24 个不同复杂程度的 RegNet 模型给tf.keras.applications

尽管我负责 PR 的主要开发工作以及培训模型,但我从社区获得了很大的帮助,这使它真正具有协作性。

我用这些模型进行了几个实验,因为使用本文提供的超参数无法重现报告的精度。这篇博文记录了我尝试的这些实验以及它们的结果。

致谢:

我真诚地感谢 Keras 团队允许我添加这些模型。非常感谢 TPU 研究小组(TRC) 在整个项目期间提供 TPU,没有他们,这一切都是不可能的。非常感谢Fran ois Chollet允许这一点并在整个过程中指导我。感谢Scott Zhu在虚拟机上从源代码构建 Keras 的指导。感谢 Matt Watson 对分组卷积的支持。特别感谢 Lukas Geiger 对代码的贡献。最后但同样重要的是,非常感谢 Sayak Paul 不断的指导和鼓励。

基础知识

关于报纸

论文“设计网络设计空间”旨在从一个没有约束的模型空间出发,系统地推导出最佳模型群体。该文件还旨在找到一个最佳模型群体,而不是像在 NASNet 这样的作品中找到一个单一的最佳模型。

该实验的结果是一系列网络,其包括具有各种计算成本的模型。用户可以根据需要选择特定的架构。

关于模型

RegNet 系列的每个模型都包含四个阶段。每个阶段由许多块组成。该模块的架构是固定的,并且该模块有三种主要变体:X 模块、Y 模块、Z 模块。在论文中可以看到其他变体,并且作者声明模型推导方法是稳健的,并且 RegNets 很好地推广到这些块类型。

每一级的块数及其通道宽度由文中提出的简单量化规则决定。更多信息请见博客。由于其卓越的扩展能力,正则网络已经成为 SEER 等自监督方法的首选网络。

拉取请求:

在打开需要大量工作的“拉”请求之前,建议先咨询团队,这样就不会有利益冲突。在得到 Keras 团队的可靠确认后,我开始编写代码。你可以点击查看我们的讨论。以下是我们对话中的一小段:

问题#15240 的摘录

Franç ois Chollet 和 Keras 团队给予了极大的支持,使合并 PR 成为一个顺利的过程。我对团队的帮助表示衷心的感谢。

尽管我要实现 24 个模型,但基本代码相当简单。因此,我能够用代码创建一个 PR,并很快得到团队的评论。点击查看公关

训练模型:

一般设置

我主要用 TPU v3–8 节点进行训练。它有一个 96 核虚拟机,大约 335 GB 内存,可以轻松处理繁重的预处理。经过预处理后,原始图像被调整到 224x224 的大小,如文中所述。我同时使用多个 TPU 节点,以便并行运行多个实验。这大大减少了实验时间。

我用来训练的代码可以在这里得到。

在这一部分,我简单地记下了我实现这一表现的要点和方法。

1.输入管道

我在强大的 TPU-v3 上训练这些模型(感谢 TRC)。这意味着我不得不使用一个快如闪电的输入管道。此外,输入管道必须是静态的,这意味着我不能在运行时突然改变预处理图(因为预处理函数是使用 AutoGraph 优化的)。根据 TPUs 的要求,我将 ImageNet-1k TFRecords 存储在一个 GCS 存储桶中,并采用了一种交叉读取数据集的方法。

学习要点:重要的是以最有效和最稳定的方式实施扩增,并在此过程中尽量减少缓慢和冗余的操作。

这里有一个例子,说明如何避免执行图中的动态变化。我已经为盗梦风格的裁剪创建了几个函数,最初的盗梦文件推广了这个函数。有趣的是,在图形执行中不允许使用break语句,因为它们会动态地改变图形。

一些代码块是重复的,但是这保证了函数保持纯净。这里的纯粹仅仅意味着没有break语句,否则会导致图形任意变化。例如,我们还可以看到,在整个函数调用中,变量w_crop恰好被转换为tf.int32一次。进行这样的优化很重要,因为我们一次处理一个图像,而不是一批图像。你可以在这里查看代码。为了简洁起见,实际的代码没有包含在这个博客中。

除了初始风格的裁剪,其余输入管道的实现相当简单。总之,我使用了初始裁剪、通道式 PCA 抖动、水平翻转和混音

PCA 抖动增强代码

混合增强代码

水平翻转增强代码

论文中提出了 PCA 抖动和随机水平翻转,而添加 mixup 则受到了论文 Revisited ResNets 的启发。

2.体重衰减对训练的影响

权重衰减是一种正则化技术,我们对过大的权重进行惩罚。权重衰减是一种久经考验的方法,经常在训练深度神经网络时使用。一个小注意,我使用解耦权重衰减,而不是权重衰减的传统实现。

我看到增加过多的权重衰减会使模型难以收敛。然而,小的重量衰减导致模型在最后的时期具有接近恒定的精度。这些观察表明,重量衰减是一个强正则化,特别是对于较小的模型。受论文“重温结果:改进的训练和缩放策略”的启发,我保持大模型的权重衰减不变,因为混合同时增加。

学习点:权重衰减是强正则化。对于大型模型,建议减少权重衰减或保持其不变,同时使用其他增强或正则化。

最后,我对所有模型使用了 5e-5 的恒定重量衰减,这是原始论文中建议的。

3.作为模型大小函数的正则化

根据经验,增加正则化的增强会导致更好的性能。与此一致,随着模型尺寸的增加,我逐渐增加了混合增强的强度。我看到使用这个简单的技术效果很好。

学习点:增加模型规模时,增加扩充和正则化。

4.较小的模型很难训练

我必须训练 RegNetX 和 RegNetY 的 12 个变种。这包括小模型,它们没有大模型那么多参数。据推测,这些模型根本没有足够的容量来保存给定的信息。它们往往会出现不足,解决方案很少像增加功能那样简单。在大多数情况下,最好的起点是低正则化和中等增强。我可以从那里调整其余的超参数。这些模型需要花费大量时间进行微调和训练,而较大的模型具有更大的灵活性。较小的模型对正则化或增强中的微小变化很敏感。

学习点:做一个小模型的超参数搜索。随着模型尺寸的增加,重复搜索。

5.值得注意的学习:

答:如有可能,使用数据的多个副本

据观察,训练会突然停止,并在一个时期结束时停滞不前。我使用了tf.data.Dataset.interleave方法,它同时从多个 TFRecords 中读取数据。在此读取操作期间,TFRecords 对其他进程不可用。我曾经并行训练多个模型,因此它们经常需要从同一个桶中读取数据。因此,为了解决这个问题,我创建了 TFRecords 的多个副本,并将它们保存在不同的桶中。这减少了碰撞,问题也大大减少了。

b .在单一位置转储日志

在训练多个模型时,维护日志可能会失控。在我看来,最好的办法是把所有的原木都倒在一个地方。在我们的例子中,我使用训练的时间和日期来组织模型的日志和检查点。这使得在需要的地方定位和使用检查点变得更加容易。以下是相同的快照:

我的圆木桶。虽然有点乱,但确实管用:)

c .使用自动化来减少认知负荷

同时快速管理多个实验成为一项艰巨的任务。从一开始就将你需要重复做的事情自动化是一件非常有用的事情。例如,可以使用权重和偏差(W&B)来自动跟踪所有实验。将超参数与运行一起记录在 W&B 中是有用的,而不是手动输入它们。这些看起来很小的事情减少了大量的认知负荷,所以你可以专注于重要的事情——进行实验。以下是我们运行的快照:

d .获得模型如何对超参数的某些变化做出反应的直觉

在一个架构上工作了几天或几个月之后,您可能会注意到模型性能的模式。这有助于建立模型如何对超参数的不同变化做出反应的直觉。利用这种新发现的直觉,你可能会想出有助于提高性能的主意。例如,对 RegNetY004 使用稍高的权重衰减会导致运行结束时准确度突然增加,然后降低,但使用较低的权重衰减会使这种情况变平。这意味着,在这种情况下,使用更积极的增加策略和更低的体重下降可能有助于训练。以类似的方式,人们可以发现导致显著改善的超参数的变化。

最后,这里是结果。在下面的表格中,我将我们的结果与论文进行了比较。最后一列具有不同于原始实现的超参数。

X 变种

Y 变体

结论

为了这次公关,我一共训练了 24 个模特。这是一次丰富的经历,我希望这些模型将被许多开发人员使用。通过这次经历,我学到了很多东西,我希望在不久的将来继续为 TensorFlow & Keras 做出贡献。

在稳定基线 3 中培训 RL 代理很容易

原文:https://towardsdatascience.com/training-rl-agents-in-stable-baselines3-is-easy-9d01be04c9db

(作者 GIF)

动机

大约 2 年以来,强化学习成了我的一个爱好。我特别喜欢在游戏上训练代理人。这些年来,我面临的一个大问题是缺乏一个可靠的 python 强化学习库,我不得不自己编写最先进的算法,或者在 github 上找到一个好的资源。对我来说,在我发现稳定基线 3 库的那一天,一切都变了。

你能期待什么

我将带你了解 stable-baselines3 和 openai gym 的整个安装过程。然后,我将向您展示如何在横拉杆环境中训练一个代理,并在屏幕上显示一些经过训练的代理的运行情况。我还想让你知道保存和加载模型。稳定基线 3 还支持同时在多个环境中进行培训。最后,我将向您展示如何在更复杂的 LunarLander-v2 环境中训练一个近似策略优化(PPO)代理,以及如何在 atari 突破环境中训练一个 A2C 代理。

装置

稳定基线 3 库提供了最重要的强化学习算法。它可以使用 python 包管理器“pip”来安装。

pip install stable-baselines3

我将使用 openai gym 环境演示这些算法。安装它来跟随。

pip install gym

用 cartpole 环境测试算法

培训 PPO 代理人

稳定基线库包含许多不同的强化学习算法。在下面的代码中,我将展示如何使用近似策略优化算法训练一个可以击败 openai cartpole 环境的代理。

(作者代码)

你可以很容易地将我使用的算法与稳定基线 3 库提供的任何其他强化学习算法进行交换。你只需要改变第 1 行和第 7 行,用你选择的算法替换 PPO。

将策略设置为“ MlpPolicy ”意味着我们将给出一个状态向量作为模型的输入。这里只有两个其他的政策选择。如果您提供图像作为输入,请使用“ CnnPolicy ”。还有用于处理多输入的“多输入策略”。由于 cartpole 环境不能输出图像,稍后我将展示一个“CnnPolicy”在其他体育馆环境中的用例。

保存和加载模型

要保存模型,请使用下面的代码行。

您可以将保存的模型加载回 python 中

下面的代码展示了为 cartpole 环境训练、保存和加载 PPO 模型的整个过程。请确保仅在训练模型后保存它。

(作者代码)

多种环境下的平行培训

您还可以非常容易地同时在多个环境中训练一个代理(即使是在 cpu 上训练)。这加快了代理的培训过程。

我们可以使用 stablebaselines3 库的 make_vec_env 函数创建并行环境。

我们以同样的方式使用它,我们使用了 openai 健身房功能来创建一个新的环境。但是我们告诉函数我们想要创建多少个并行环境。

因为您只训练了一个代理,所以您可以像以前一样保存模型。

但是与前一个案例的一个重要区别是,当我们测试我们训练有素的代理时,对终端状态的处理。如果 epsiode 在其中一个环境中结束,它会自动重置。在测试之前,代理看起来像这样:

现在,它变短了:

以下代码同时在 4 个环境中训练 PPO 代理:

(作者代码)

使用其他健身房环境

为了运行大多数其他健身房环境,您必须安装 python 的 Box2D 库。这在 mac 和 linux 上非常容易,但在 windows 上却非常困难。

安装 Box2D

Box2D 是 2D 物理学的开源物理引擎,许多体育馆环境用它来处理物体的碰撞。

Linux/OSX

据我所知,在 linux 和 mac 电脑上直接安装 Box2D 没有任何问题。

pip install box2d-py

视窗

在 windows 上,Box2D 环境的安装过程经常会出现问题。然而,我们可以使用 swig 单独安装它。这解决了问题。使用 anaconda 安装 swig 非常简单

conda install swig

如果不使用 anaconda,可以在这里下载 swig

还需要 Microsoft Visual C++ 14.0 或更高版本。如果没有安装,Box2d 安装会失败。因此,请到这里下载最新的 microsoft C++构建工具。

https://visualstudio.microsoft.com/visual-cpp-build-tools/

您可以在这里安装构建工具。

(图片由作者提供)

安装完“buildtools”后,打开 visual studio 安装程序(它可能在安装“buildtools”后已经打开)。

(图片由作者提供)

然后可以使用 pip 为 python 安装 Box2D。

pip install box2d-py

击败 LunarLander-v2

我现在将向您展示如何使用 stable_baselines3 库击败 lunarLander-v2 环境。代理人的任务是将着陆舱降落在两个黄色球门柱之间。

(作者 GIF)

这是一个比 cartpole 环境更复杂的任务。以向量的形式给代理以下信息。

  • (连续):距离目标位置 X 距离
  • (连续):距目标位置的 Y 距离
  • (连续):X 速度
  • (连续):Y 速度
  • (连续):船的角度
  • (连续):船的角速度
  • (二进制):左腿接地
  • (二进制):右腿接地

所以我们也必须使用 MlpPolicy

我选择 PPO 算法来训练代理,因为我发现它在 LunarLander 环境中学习速度非常快。代理人花了 200 万步训练才达到平均分数 233 。这场比赛的平均分数为 200 分就被认为失败了。

(作者代码)

雅达利突破像素

现在是时候让我们的代理仅使用屏幕上的像素来解决“雅达利突破”了。

(作者 GIF)

gym 的标准安装中不包含 breakout 环境,因此您必须安装一个 gym 版本,其中包含 atari 集合。

pip install gym[atari]

仅给定一张图片,代理人无法判断球的速度和方向。使用 VecFrameStack 包装器,我们同时给代理一些帧作为输入,这样他就可以学习球的移动。

也要意识到一个事实,那就是你现在必须知道使用“ CnnPolicy ”。我用 A2C 算法为500 万时间步长训练代理,并使用 16 个并行环境

(作者代码)

(作者 GIF)

正如你所看到的,代理人已经学会了在砖块上打洞并在墙后投篮的技巧。然而,它很难射击最后几块砖,因此无法完成游戏。这很可能是因为代理没有在砖块较少的情况下接受过足够的培训。通过增加培训持续时间,代理应该能够战胜环境。

结论

我想花一点时间介绍一下关于稳定基线 3 库的最重要的信息。当您的环境向代理提供一个带有信息的向量时,则使用 MlpPolicy 。如果它给出完整的图像,则使用 CnnPolicy 。您可以并行使用多个环境来加速训练。但是他们都训练同样的一个特工。有了几千个时间步长的数据,cartpole 环境很容易被击败。LunarLander-v2 环境更加复杂,需要 200 万个时间步才能超越 PPO。雅达利突破将通过像素来解决,这使得它变得更加困难。有了 500 万个时间步长,我几乎可以击败使用 A2C 的环境。

想联系支持我?

LinkedIn
https://www.linkedin.com/in/vincent-m%C3%BCller-6b3542214/
脸书
https://www.facebook.com/profile.php?id=100072095823739
Twitter
https://twitter.com/Vincent02770108
中型
https://medium.com/@Vincent.Mueller
成为中型会员并支持我(你的部分会员费直接归我)

https://medium.com/@Vincent.Mueller/membership

相关故事

其他故事

训练 YOLO?像这样选择定位框

原文:https://towardsdatascience.com/training-yolo-select-anchor-boxes-like-this-3226cb8d7f0b

回顾 YOLOv5 和 YOLOv7 中的自动锚点选择算法

原图作者修改

一些卷积神经网络,包括后来版本的 YOLO,依赖于锚点。因此,在开始训练你的网络之前,你需要决定你将使用什么锚,并根据你所拥有的数据做出这个决定。锚集就像是你传递给模型的一个常量,就像是一个先验,它包含了数据集中对象大小的性质。

根据 MathWorks :

锚定框是一组具有一定高度和宽度的预定义边界框。这些框被定义为捕获您想要检测的特定对象类的比例和纵横比,并且通常基于您的训练数据集中的对象大小来选择。”

选择好的锚点很重要,因为 YOLO 不是直接预测边界框,而是预测锚点框的位移。自然,神经网络比大位移更好(更准确)地预测小位移。因此,你选择的锚盒越好,神经网络做的“工作”就越少,模型产生的准确度就越高。

自动锚定算法是在 YOLOv5 库中引入的,后来被复制粘贴到 YOLOv7 库中,没有做任何修改。该算法的思想如下:

在训练之前,脚本检查提供的锚点与数据的匹配程度,如果不匹配,脚本将重新计算它们;并且用新的、更合适的锚来训练模型。听起来是一个非常有用的特性,不是吗?

的确如此。这篇文章致力于自动锚定算法:它是如何工作的,它背后的直觉是什么。如果你有兴趣—继续阅读:)

在回顾了自动锚定代码之后,我相信最好将其解释为一个 4 步算法:

第一步。从步骤 2 的训练数据中获取边界框尺寸。选择一个指标来定义锚定适应性
步骤 3。进行聚类以获得锚的初始猜测
步骤 4。进化主播,提高主播体能

第一步。从训练数据中获取边界框大小

您需要的是所有列车图像中所有边界框(标签)的高度和宽度。注意,对于已经调整大小的图像(调整到模型输入大小),高度和宽度应该以像素计算。

默认情况下,YOLOv5 和 YOLOv7 的模型输入大小为 640x640,这意味着图像较大一侧的大小调整为 640,纵横比保持不变,较短一侧填充。见下面的可视化。

边界框的高度和宽度应根据模型输入尺寸重新计算。原图来自 COCO 数据集 ,可视化由作者创作。

第二步。选择一个指标来定义锚点适合度

接下来,我们需要一个度量来比较锚盒集,并了解哪一个更适合数据。

理想情况下,度量应该与损耗函数(特别是盒损耗)相关联:度量越好,损耗越低。并且如果使用该度量选择锚盒,则模型已经以较低的损失开始训练。完美!

这个指标将用于进化算法中,这意味着你可以使用任何指标,而不用考虑一些优化算法可能强加的约束。

YOLO 自动锚定算法中使用的度量是棘手的,也许你不需要知道那么多细节,但对于那些感兴趣的人,解释如下:

  • 有一个阈值定义为超参数(称为 anchor_t ,默认为 4;有时用作 1/anchor_t ,为 0.25)。这个阈值意味着,如果锚定框比边界框标签大或小不超过 4 倍,我们就认为它是一个好的锚定框。
  • 我们希望每个边界框标签尽可能靠近至少一个定位框。我们希望它接近阈值(不超过 4 倍大或小)。
  • 平均而言,达到了良好的适应度,这意味着一些边界框(可能是离群值)可能仍然远离锚点。
  • 对于每个边界框,我们选择最好的锚点,但是我们从最差的拟合边开始计算它的拟合度(希望这样有意义)。

如果您还想了解指标是如何计算的,我真的建议您仔细阅读下面的计算。

如何在 YOLOv5 和 YOLOv7 中计算适应性指标。本例中有 3 个锚点,在 YOLOs 中默认为 9 个锚点。图片作者。

第三步。进行聚类以获得锚的初始猜测

YOLOv2 中,仅使用 k-means 聚类算法计算锚盒。k-means 的典型距离度量是欧几里德距离,然而,对于该距离,较大的框比小的度量产生更多的误差,因此作者利用 1-IoU(并集上的交集)作为距离度量。顺便说一下,IoU 与 YOLO 损失函数的关系比欧氏距离更密切。

只做 k-means 聚类已经是一个很好的方法,它会给你比手工挑选锚盒更好的结果。然而,后来 YOLO 版本的作者决定走得更远:

  • K-means(具有简单的欧几里德距离)用于获得锚盒的初始猜测。
  • 使用进化算法(在步骤 4 中有更多描述)来寻找相对于先前在步骤 2 中选择的度量的最佳锚集。

如何选择集群的数量?默认情况下,YOLOv5 和 YOLOv7 使用 9 个锚框,因此簇的数量应为 9。

初学者注意事项 。K-means 算法在来自训练集的所有包围盒标签上运行。用于聚类的特征-以像素为单位的宽度和高度。最终聚类中心是锚盒。

K-means 聚类算法用于找到锚盒的初始猜测。本例中有 3 个锚点,在 YOLOs 中默认为 9 个锚点。图片作者。

第四步。进化主播,提高主播体能

进化算法的灵感来源于自然,简单而美丽。我们从 k-means 中取出锚集,稍微随机改变一些锚盒的高度和宽度(变异),然后计算适合度。如果新的变异锚集更好,则对新的锚集执行下一次变异,否则,使用旧的锚。如果你更喜欢视觉消费信息,下面是这种进化算法的工作原理。

在 YOLOv5 和 YOLOv7 中,evolution 运行 1000 次迭代(默认情况下),可能会大量更改初始锚集。

进化算法在 YOLOv5 和 YOLOv7 中的自动锚定。图片作者。

最后一句话

现在你知道 YOLO 自动锚是如何工作的了,所有的细节。我计划在未来回顾 YOLO 的其他地方,所以如果你感兴趣——订阅并保持更新。

同时,我鼓励你看看我的其他一些帖子:

使用空间划分的轨迹查询

原文:https://towardsdatascience.com/trajectory-queries-using-space-partitioning-773167d4184e

怎样才能快速找到重叠的轨迹?

照片由 Unsplash 上的延斯·勒列拍摄

当穿越空间时,一个物体描绘了一条轨迹。我们可以把轨迹看作是时间的函数,它输出空间位置。从概念上讲,轨迹是连续的函数,尽管我们实际上使用它们的离散形式。离散轨迹是空间中点的时间有序集合,其中我们隐含地假设每个点之间的线性插值。这种表示使得在数据库中存储离散轨迹非常容易和直观。

本文介绍了一种使用空间划分机制从关系数据库中高效查询轨迹的方法。在这里,我们使用方形分区和我在上一篇文章中使用的扩展车辆能源数据集 (EVED)来解决这个问题。

EVED 包含了从 2017 年 11 月到 2018 年 11 月一整年期间在密歇根州安阿伯收集的超过三万二千条这样的轨迹。EVED 论文的作者用几个额外的功能增强了数据集,即地图匹配的 GPS 坐标。地图匹配是一个使用车辆的噪声 GPS 数据流来推断车辆行驶过哪些道路的过程。这个过程需要访问该地区的数字地图,对于这个数据集,论文作者使用了 OpenStreetMap 公共数据和 Valhalla 地图匹配引擎。

地图匹配过程将每个采样的 GPS 位置“捕捉”到最可能的街道或道路。该过程使用复杂的概率算法,从采样位置序列中推断出最可能的地图路径。您可以在源数据集中看到这方面的证据,其中每个样本都包含两个位置,即高噪声位置和地图匹配位置。在本文中,我们将只使用第二组。

下面的图 1 说明了地图匹配过程如何将采样的 GPS 位置捕捉到最可能的道路网络边缘。

图 1 —地图匹配过程将嘈杂的 GPS 测量捕捉到最可能的道路网络边缘。在这里,您可以看到对该过程的描述,其中标有“n”的圆圈表示道路网络节点,标有“e”的箭头表示有向边。绿色的采样 GPS 位置与弧线上的另一个位置相匹配,并记录在数据库中。但是没有关于匹配边缘的信息。(图片来源:作者)

注意,数据集只包含匹配的点;它没有扩展到包括匹配的边。边缘信息的缺失使得查询过程变得更加困难但是有趣。

查询轨迹

查询一个轨迹是什么意思?在本文的上下文中,查询轨迹意味着使用输入轨迹来查询轨迹数据的数据库。我们从查询轨迹开始,可能是从地图提供商那里获得的,然后使用它从数据库中检索特定的信息。在这种情况下,我们将检索完整的轨迹或相交的轨迹段

图 2 —轨迹是轨迹段的集合,上面用箭头表示。箭头顶点是采样的 GPS 位置。轨迹段不必与现有的道路网络重合。(图片来源:作者)

地图匹配轨迹可确保其结点位于路网边缘,但不必与路网结点重合。

例如,我们可以用查询结果实现行程时间估计。如果所查询的轨迹包含能量消耗信息,那么我们可以使用这些信息来预测未观察到的轨迹的消耗。你可以为轨迹查询想出更多的用例。

问题

我想解决的问题是查询数据集,寻找与覆盖区域上的任意查询轨迹相匹配的轨迹段完整轨迹轨迹段是连接给定轨迹上两个连续位置的测地线。轨迹是连续轨迹段的集合,如图图 2 所示。轨迹查询应该检索与输入最匹配的轨迹段,并排除方向相反的轨迹段。

解决办法

我在这里的解决方案使用了四键来分割地理空间以实现更快的查询,并建立在我在以前的文章中使用的类似技术的基础上。请参考该材料作为当前讨论的介绍。

我设计的解决方案需要扩展数据库中的信息,将轨迹离散为四键线。我们稍后使用这些四键索引来匹配四键离散化轨迹查询。

让我们看看解决方案是如何工作的。

数据准备

如果您遵循上一篇文章中的过程,我们创建了一个支持的 SQLite 数据库,其中包含一个包含所有采样信号的表。我们需要在现有数据库中创建三个新的支持表,以支持更快的轨迹索引。

第一个表格模拟轨迹,这很容易做到。原始数据已经包含由车辆行程标识符唯一识别的轨迹信息。图 3 中的代码显示了简单的表格结构。

图 3 —上面的 SQL 代码创建了包含所有记录轨迹的表格。(图片来源:作者)

下图 4 显示了如何从现有信号表中的数据填充轨迹表。

图 4 —上面的代码显示了如何从信号中填充轨迹表。(图片来源:作者)

我们为轨迹中的每对不同位置创建一个链接(一个轨迹段)。每个链接都包含信号对的标识符和我们在上一篇文章中计算的方位的信息。下图 5 显示了表格结构。

图 5 —链接表包含包含轨迹和信号端点的标识符信息。方位与最终信号的方位相同,出于性能原因复制到这里,因为它避免了额外的连接。(图片来源:作者)

最后,我们为链接端点的线创建包含单个四键的表。下面的图 6 显示了创建该表的 SQL 代码。

图 6 —上表中的每一行包含一个整数四键代码,对应一个行像素。当查询轨迹链接时,我们使用这个四键代码作为匹配目标。(图片来源:作者)

请注意,我们将在四键代码列上创建一个索引,以支持轨迹查询。这个索引列将把查询轨迹与轨迹链接相匹配,并且可能与轨迹本身相匹配。

数据准备过程的最后一步也是最长的一步,因为它需要列举所有轨迹,确定所有联系,最后在它们的端点之间画线。下面的图 7 显示了填充这两个表的代码。

图 7 —上面的函数填充了链接表和相应的“像素”行。每个“像素”都是一个四键代码,用于以后的查询。(图片来源:作者)

该功能首先将所有数据库轨迹加载到包含轨迹、车辆和行程标识符的元组列表中。下面的图 8 显示了加载所有轨迹的简单代码。

图 8 —上面的代码从数据库加载所有轨迹。(图片来源:作者)

接下来,我们迭代轨迹列表并处理每一项,从加载轨迹的点开始(图 7 中的第 7 行)。这里我们需要解决数据库中连续重复位置的问题。这种情况可能是由于 GPS 位置变化之间产生的信号的不同采样周期而发生的。下图 9 显示了如何在这些情况下加载轨迹的点。

图 9 —上面的代码加载轨迹中的所有点,确保没有重复的位置。(图片来源:作者)

现在我们有了所有唯一的轨迹点,我们迭代每个连续的对(图 7 ,第 10 行)并创建相应的链接。请记住,链接连接数据库中两个连续的车辆位置。下面图 10 中的代码显示了如何插入一个新链接并检索新生成的标识符。

图 10 —插入新的链接时,我们重新使用先前计算的方位值。插入最新数据后,上面的函数返回新生成的标识值,以备后用。(图片来源:作者)

插入链接后,我们可以使用与上一篇文章相同的方法在端点之间画出四键线。使用四键和位图像素之间的类比,我们可以很容易地绘制一条连接任意两点的线(图 7,第 16 到 18 行)。生成的行是我们插入到数据库中的四键代码的简单列表。下面图 11 中的代码说明了该过程。

图 11 —上面的代码将四键代码批量插入数据库。(图片来源:作者)

一旦完成,我们需要创建一些支持索引,我们准备好开始查询轨迹的数据库。请参考 GitHub 库文件中的完整源代码。

查询轨迹的方法

查询包括将查询轨迹离散化为一组四键代码,然后将它们与先前离散化的链接四键进行匹配。我们将从两个不同的角度来探讨这个问题。第一种观点涉及使用任意轨迹作为查询,而第二种观点使用数据库中的现有轨迹。例如,最后一种方法可能驱动轨迹聚类算法。

请使用已出版的 Jupyter 笔记本和支持的图书馆代码来跟随这个讨论。

使用任意轨迹进行查询

我们从第一种方法开始,使用两个随机地址定义一个任意查询。下面的图 12 显示了我们将使用的查询轨迹。

图 12 —上图描绘了从地理编码地址计算出的随机查询轨迹。较暗的蓝点代表道路网络节点。(图片来源:作者使用了 Folium 和 OpenStreetMap 图像)

我们使用图 13 中的简单代码片段生成上述路线。首先,我们实例化一个对象,帮助我们查询在现有道路网络上定义的任意轨迹。这里,我们使用密歇根州安阿伯市的定义。接下来,我们使用来自同一城市的两个随机地址生成查询路由。生成的路径由包含相应道路网络节点的列表组成。请注意,这些位置不一定与数据库中的位置匹配。

图 13 —上面的代码加载安阿伯的道路网络,并从两个任意地址生成一条路线。请注意,图形路由对象保留了函数 return 的副本以供将来使用。(图片来源:作者)

正如我前面提到的,查询任意轨迹需要将其离散化为四键,以便进行后续的数据库搜索。图 14 中列出的功能显示了如何实现这一点。该函数为每对道路网络结点生成一条四键线以及相应的方位角。我们将使用该列表通过执行精确的四键匹配和近似的方位比较来查询轨迹数据库。

图 14 —上面的函数将生成的路线转换成一列四键和方位对。(图片来源:作者)

下一步是将生成的路径四键和方位列表与数据库中的轨迹记录进行比较。下面的图 15 中列出的函数就是这样做的,并返回链接和相应的轨迹标识符。为了方便和以后使用,该函数还返回相应范围的信号标识符。

图 15 —对于每个查询轨迹四键和方位对,我们向链接表发出一个查询,返回匹配的链接和轨迹标识符。(图片来源:作者)

使用重叠链路标识符,我们可以用数据库中的匹配轨迹段来补充图 12 中的图(见图 16 )。请注意,我们仅在方位上过滤这些查询,但也可以将这些查询扩展到一天中的时间或一周中的某一天,如在上一篇文章中。

图 16 —上图用红色显示了数据库中所有匹配查询轨迹的轨迹链接。我们可以使用这些链接的属性来推断查询轨迹的属性。(图片来源:作者使用了 Folium 和 OpenStreetMap 图像)

我们现在可以扩展练习并显示与查询轨迹最匹配的完整轨迹。为了验证匹配质量,我使用了 Jaccard 相似度度量来衡量四键集的相似程度。下面的图 17 显示了使用 Python 集合实现这个指标是多么容易。

图 17 —上面的代码显示了 Jaccard 相似性的简单实现。(图片来源:作者)

为了计算这种相似性,我们必须加载所有匹配轨迹的四键,并使用 Jaccard 相似性将它们与查询进行比较。图 18 中的代码描述了这个过程。

图 18 —为了计算轨迹与查询的相似性,我们必须首先从数据库加载四键并比较两组,如上所述。该函数返回包含轨迹标识符和与查询轨迹的 Jaccard 相似性的元组列表。(图片来源:作者)

有了这些信息,我们现在可以过滤相似性最低的轨迹。在这种情况下,我们保留前 5%。

图 19 —上面的代码使用前一个函数的结果来选择前 5%的最佳匹配轨迹。(图片来源:作者)

图 20 中的结果图显示了匹配轨迹的前 5%。

图 20 —上面的地图显示了最佳轨迹匹配的前 5%。(图片来源:作者使用了 Folium 和 OpenStreetMap 图像)

使用数据库轨迹进行查询

第二种查询方法涉及使用现有的数据库轨迹作为查询。使用这种方法,我们不必求助于道路网络,也不必将数据库作为唯一的信息来源。更好的是,我们只需要一个功能强大的函数来检索匹配的链接。下面的图 21 显示了允许我们检索与查询轨迹匹配的链接和轨迹的 SQL 查询。注意,这个函数返回与查询轨迹相对应的链接。正如您将看到的,消费函数允许从响应中过滤查询轨迹数据。

图 21 —上面描述的有些复杂的数据库查询检索所有与给定查询轨迹匹配的链接和各自的轨迹。(图片来源:作者)

一旦我们从上面的函数中得到结果,我们就可以确定最佳的匹配轨迹。这个过程包括计算轨迹查询四键集和所有其他匹配轨迹的四键集之间的 Jaccard 相似性。下面图 22 中描述的函数就是这样做的,并使用百分位数排序提取最佳匹配轨迹。

图 22 —上面的代码检索顶部匹配轨迹。该函数允许最高百分比截止点以及排除查询轨迹。请注意该流程如何使用 Jaccard 相似性函数对所选结果进行排序。(图片来源:作者)

下面的图 23 显示了带有查询轨迹和前 5%最佳匹配轨迹的地图。

图 23 —上面的地图用蓝色显示查询轨迹,用红色显示前 5%的匹配轨迹。请注意,生成的轨迹会完整显示。(图片来源:作者使用了 Folium 和 OpenStreetMap 图像)

我们也可以只显示匹配的链接,我们可以使用下面的图 24 中的函数进行查询。

图 24 —为了得到一个查询轨迹的所有匹配链接,我们只需要从图 21* 中的函数中提取链接标识符。(图片来源:作者)*

下图图 25 中的地图显示了与图 23 中相同的查询轨迹的所有匹配轨迹段。

图 25 —上图显示了与图 23* 中相同的查询轨迹的匹配轨迹段。(图片来源:作者使用了 Folium 和 OpenStreetMap 图像)*

结论

从数据库中查询轨迹是一个相对复杂的过程,通常涉及专门的索引和支持逻辑。本文讨论了使用四键通过空间离散化从数据库中查询轨迹的方法。方形四键分区通过将轨迹减少到整数集来简化空间查询。该方法包括将轨迹离散为四键线,然后使用轨迹段方位进行匹配。不需要专门的地理空间索引,所以简单的数据库引擎就足够了。

相关文章

*

参考

必应地图磁贴系统——必应地图|微软学习

GitHub 库

gsoh/VED: VED(车辆能源数据集):用于车辆能耗研究的大规模数据集。(IEEE 智能交通系统汇刊,2020)(github.com)

扩展的车辆能量数据集(eVED):一个增强的大规模数据集,用于车辆出行能量消耗的深度学习

Zhang sl 2013/eVED:VED 数据集的扩展版本,是用于车辆能量分析的大规模数据集。(github.com)

笔记

  1. 数据集在 Apache 2.0 许可下获得许可(参见 VEDEVED GitHub 库)。请注意,这也适用于衍生作品,比如本文中构建的数据库。

joo Paulo Figueira 在葡萄牙里斯本的TB . LX by Daimler Trucks and bus担任数据科学家。*

大数据世界中的交易

原文:https://towardsdatascience.com/transactions-in-a-data-world-609ebe9384b2

为什么酸支持对模型预测再现性至关重要?

图:大数据交易(基于来自 PexelsAndrea Piacquadio 的图片)

摘要。带有 ACID 保证的事务曾经是数据库管理系统的支柱。然而,随着流媒体和 NoSQL 的出现,交易被认为过于严格,难以在大数据平台上实施。最终的一致性成为了这类平台的标准,其中一些分布式节点之间可能是不一致的——返回不同的值;所有节点在稍后的时间点收敛到相同的值。

然而,大数据平台/框架现在已经成熟,我们看到了提供 ACID 支持的平台的复兴,例如三角洲湖、胡迪和冰山。在本文中,我们为大数据世界中的事务提供了案例,为如何在这种场景中实现事务提供了必要的背景。我们展示了一个具体的应用,说明了 ACID 事务如何在实现数据历史化方面发挥关键作用。

处理

事务可被视为由操作 Begin 和 Commit/Abort 封装的一组操作,具有以下属性(ACID):

  • 原子性:要么所有操作都执行,要么都不执行。在失败(中止)的情况下,属于该事务的任何操作的效果都被取消(回滚)。
  • 一致性:每个事务将系统从一种一致状态转移到另一种一致状态。
  • 隔离:为了提高性能,通常会同时执行几个事务。隔离要求这种并发执行的效果等同于串行执行的效果。这是通过确保事务的中间结果在成功完成(提交)之前不会被外部化来实现的。
  • 持久性:一旦事务提交,其效果是持久的,即它们不应被任何系统或软件崩溃所破坏。

例如,让我们考虑一下传统的银行交易 t_b ,它涉及到从一个账户 A 向另一个账户 B 转账。该交易由两个操作组成——第一个操作从账户 A 中取钱,第二个操作将钱存入账户 B 。不用说,事务的任何部分执行都会导致不一致的状态。原子性属性确保提取和存放操作要么都成功,要么都失败。隔离属性确保对两个帐户 AB 的更改对其他事务不可见,直到 t_b 提交。原子性和隔离性共同保证了系统的一致性(账号 AB )。

负责实现事务的软件通常被称为事务管理器(TM)。我们可以将 TM 的功能分为以下几个部分:

  • 并发控制管理器(CCM):CCM 确保隔离属性。并发控制机制允许以受控的方式在并发事务之间共享资源。
  • 恢复管理器(RM):RM 负责在出现故障或软件/硬件崩溃时提供原子性和持久性属性。
  • 日志管理器(LM):LM 负责将执行细节写入稳定存储。虽然日志在恢复中起着重要的作用,但它也用于分析和提高系统性能和效率。

虽然事务已被接受为提供容错和可靠性的标准手段,但当我们试图在分布式环境中应用它们时,新的挑战出现了。

分布式事务— 2PC

分布式事务由在通过通信网络连接的不同地点执行的操作组成。分布式事务起源于一个站点(也称为主/根站点),逐渐涉及其他站点,在这些站点中,属于事务的操作被转发以供执行。集中式和分布式系统中事务处理的主要区别如下:

  • 决策制定:提交/中止事务的决策不限于单个 TM。相反,需要根据所有相关地点的 TMs 的决定做出集体决定。
  • 多点故障:对于集中式系统,系统要么工作,要么不工作。然而,在分布式系统中,我们可能会遇到部分故障,即一些相关站点发生故障,而其他站点仍在工作。

因此,我们需要一种协议来确保在所有涉及的站点一致地执行相同的决策(提交/中止),而不管部分故障。两阶段提交(2PC)协议可能是针对上述问题的最广泛接受的解决方案。主站点的 TM 充当协调者,而所有其他相关站点的 TM 承担参与者的角色。顾名思义,2PC 协议包括两个阶段。在第一阶段,协调器 TM 向所有参与者 TM 发送准备消息。每个参与者 TM 根据它是否想要提交/中止来投票赞成/反对。如果协调器 TM 从其所有参与者 TM 接收到“是”,那么它通过向所有参与者 TM 发送提交消息来开始协议的第二阶段。然而,如果它从至少一个参与者 TM 接收到“否”,则它通过向所有参与者 TM 发送中止消息来启动第二阶段。最后,协调器 TM 等待来自参与者 TMs 的确认,以完成第二阶段。

补偿—传奇

虽然上述协议对于紧密耦合的分布式应用程序工作良好,但是它对于长时间运行和松散耦合的应用程序的适用性是有限的。为了确保 ACID 属性(在集中式场景中),需要持有锁,直到事务提交。

从性能角度来看,这并不是一个理想的情况,尤其是对于长时间运行的事务——必须持有锁,直到所有涉及的(协调者和参与者)站点都准备好提交。

对上述限制的一个优雅的解决方案是嵌套事务的概念[1]。嵌套事务允许相关站点的 TMs 通过以受控方式外部化中间结果,在事务本地完成后立即释放它们的锁。基本上,全局事务(提交给根 TM)被分成许多可以并发执行的子事务。虽然保证了全局事务的 ACID 属性,但是子事务并没有完全隔离,因为它们的结果向它们的父事务公开。甚至不能保证子事务的持久性,因为如果其父事务中止,可能需要取消它的效果(在提交后)。

虽然嵌套事务的概念在某种程度上解决了性能问题,但它仍然需要相关的 TMs 的某些保证。然而,考虑到松散耦合的分布式系统的自治性和异构性需求,这样的保证可能并不总是可行的。Sagas [2]或开放嵌套事务[3]通过允许子事务产生的中间结果不受任何限制地公开来缓解这个问题。

Sagas 依靠补偿事务的概念[4]来确保失败时的原子性。基本上,对于每个事务 t,指定了能够在语义上消除事务 t 的影响的补偿事务 t_c。

在失败的情况下,通过以与它们各自事务的原始执行顺序相反的顺序执行补偿事务来保证原子性。补偿交易的典型例子是“取消预订”或“撤销”,分别能够撤销“预订票”或“存款”交易的效果。在这里,记住补偿并不总是可能的,尤其是对于现实生活中的交易。

总的来说,不同级别的补偿可能会有不同的成本。

例如,让我们考虑经典的旅行预订场景(图 1)。如果酒店或航班预订需要补偿,那么可以通过分别在酒店或航班预订站点调用补偿(取消)操作,或者通过在复合旅行预订站点调用补偿操作(取消旅行)来实现。现在,如果我们假设用户是复合旅游预订网站的高级会员,并因此在所有取消费用上获得 15%的折扣,那么(从用户的角度来看)在复合旅游预订网站调用取消旅游操作是有益的。

图 1:补偿事务场景(作者图片)

大数据环境中的交易

在本节中,我们将介绍一些提供 ACID 支持的关键数据平台/框架。然后,我们展示了一个具体的应用程序,它支持 upsert / merge 操作,这对于实现数据历史化至关重要。

Delta Lake 是一个开源框架,为 Apache Spark 和大数据工作负载带来了 ACID 事务。人们可以下载开源的 Delta Lake,在 HDFS 内部使用。该框架允许从任何支持 Apache Spark 数据源的存储系统读取数据,并写入 Delta Lake,Delta Lake 以 Parquet 格式存储数据。有关技术细节,请参考[5]。

ACID 事务提供了 Delta Lake 的关键“时间旅行”功能,允许探索特定时间点的数据,支持访问和回滚到对审计和模型预测再现性至关重要的数据的早期版本。

这里可以利用的替代数据平台/框架包括 Apache 胡迪和 Apache 冰山胡迪遵循传统的基于“事务日志”的方法,使用带有时间戳的数据文件和日志文件来跟踪数据文件中记录的变化。 Iceberg 使用以下元数据层次结构提供 ACID 支持:

  • 表“元数据文件”
  • 对应于表快照的“清单列表”
  • 定义数据文件组的“清单”,这些数据文件可以是多个快照的一部分

表写入会创建一个新的快照,它可以与并发查询并行运行(返回最后一个快照值)。并发写入遵循乐观并发控制协议,提交的第一个事务成功;导致所有其他冲突并发事务的重启。

我们展示了 ACID 事务如何在数据历史化中发挥关键作用。

数据历史化

历史化是跟踪数据随时间变化的过程。它适用于数据平台的所有层(图 2):摄取到“原始”(青铜)中的源数据,到“精炼”(银)中的净化数据,到“精选”(金)中的转换数据。

图 2:分层数据架构(图片由作者提供)

主要有两种数据历史化方法:

  • 渐变维度类型 2 ( SCD2 ):每次一个或多个列值发生变化时,变化历史都会为标识符添加一条新记录。例如,关于分别在 AWS 和 Oracle 云平台上实现 SCD2 的详细信息,请参考[6,7]。
  • 快照历史每当来自源系统的数据交付到达时,添加一个新的标识符记录,无论它是否包含更改。
    原始的&暂存层),易于实现和对晚到达数据的鲁棒性。

混合方法:

原始/暂存层的快照历史 : 实现一个永久暂存区,作为源数据交付的永久存档。这允许在对源数据进行显式建模之前对其进行加载和历史记录,并作为一种预防管理层/聚合数据存储中的建模错误的措施。

利用 SCD2 管理层/聚合数据存储:

对于策划层来说,SCD2 仍然是最流行的历史化技术。创建新记录时,前一个记录需要过期。这包括多个操作(参见下面的示例表进行说明):

  • 在当前数据集中查找记录,将现有记录的 eff_end_data 设置为新记录的 eff_start_date,并将现有记录的 is_current 标志设置为“false”
  • 插入新记录。

Delta Lake /胡迪/ Iceberg 对 ACID 事务的支持使得以可靠和可伸缩的方式执行这种 Upsert (合并)操作成为可能。

参考

  1. T.E.B .莫斯。嵌套事务:一种可靠的分布式计算方法。麻省理工学院计算机科学实验室博士论文,1981 年。
  2. H.加西亚.莫利纳和 k .塞勒姆。传奇。在斯通布雷克,医学博士。数据库系统阅读,旧金山,加州,1987,290-300。
  3. G.维库姆,执事,沙德,谢克。联邦数据库系统中的开放式嵌套事务。IEEE 数据工程通报,16(2):4–7,1993 年 6 月。
  4. D.比斯瓦斯。Web 服务组合世界中的补偿。在:语义 Web 服务和 Web 过程组合。SWSWPC 2004。计算机科学讲义,第 3387 卷。https://doi.org/10.1007/978-3-540-30581-1_7
  5. 米(meter 的缩写))阿姆布鲁斯特等人。艾尔。Delta lake:云对象存储上的高性能 ACID 表存储。过程。VLDB 捐赠。13,12(2020 年 8 月),3411–3424。https://doi.org/10.14778/3415478.3415560
  6. D.格林施泰因。在亚马逊 EMR 上用阿帕奇 Spark 和阿帕奇胡迪构建缓变维度类型 2(SCD 2),2021,https://AWS . Amazon . com/blogs/big-data/Build-缓变维度类型 2-SCD 2-with-Apache-Spark-and-Apache-胡迪-on-amazon-emr/
  7. A.杜武里。Oracle 云基础设施(OCI)数据集成中的缓变维度(SCD)类型 2 实施,2020,https://blogs . Oracle . com/Data Integration/post/slow-Changing-Dimensions-SCD-Type-2-Implementation-in-Oracle-Cloud-infra structure-OCI-Data-Integration

用 OpenAI 的耳语转录音频文件

原文:https://towardsdatascience.com/transcribe-audio-files-with-openais-whisper-e973ae348aa7

用 OpenAI 的耳语转录音频文件

威尔·弗朗西斯在 Unsplash 上拍摄的照片。

penAI 最近开源了一个名为 Whisper 的神经网络。它允许你离线转录(大)音频文件,如 mp3。OpenAI 声称 Whisper 在英语语音识别中接近人类水平的鲁棒性和准确性。

由于已经有现有的(开源)模型或包,如 VoskNVIDIA NeMo ,我想知道 Whisper 能够转录音频文件的能力如何。

本文向您展示了如何使用 Whisper,并将其性能与另一个离线开源语音识别工具包 Vosk 进行了比较。

TL;博士;医生

  • Whisper 是 OpenAI 的一个开源、多语言、通用的语音识别模型。
  • 转录一个(mp3)音频文件只需要三行代码。
  • 与 Vosk(另一个开源工具包)的快速比较表明,Whisper 转录播客摘录的音频稍好一些。主要区别在于 Whisper 提供了标点符号。这使得转录更容易理解。
  • 如果您仅对代码感兴趣,向下滚动至“耳语”或点击此处的(要点)。

先决条件

在我们开始转录和比较这两个模型之前,我们必须确保满足一些先决条件。

安装 ffmpeg

为了能够读取音频文件,我们必须先安装一个名为ffmpeg的命令行工具。根据您的操作系统,您有以下选择:

# **Ubuntu or Debian**
sudo apt update && sudo apt install ffmpeg

# **MacOS** using *Homebrew* (https://brew.sh/)
brew install ffmpeg

# **Windows** using *Chocolatey* (https://chocolatey.org/)
choco install ffmpeg

# **Windows** using *Scoop* (https://scoop.sh/)
scoop install ffmpeg

安装耳语

使用以下 pip 安装命令下载 Whisper。

pip install git+https://github.com/openai/whisper.git

安装 Vosk(可选)

因为这篇文章比较了 Whisper 和 Vosk,所以我也将向您展示如何安装和配置 Vosk。如果你只对使用 Whisper 感兴趣,可以跳过这一部分。以下命令安装 Vosk:

pip install vosk

安装 pydub(可选)

要使用 Vosk,我们首先必须用一个通道(单声道)和16000hz 采样率.wav文件中的音频文件转换。Whisper 也做这种转换,但是我们不需要额外编码。下面的命令安装pydump:

pip install pydump

对于 Mac 用户:安装证书

Whisper 将加载特定的语言模型来转录音频。如果您是 Mac 用户,稍后您可能会收到以下消息:

URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)>

要解决此问题,请进入 python 应用程序的文件夹(通常是 Applications> Python 3.x)并运行“Install Certificates.command”文件。更多信息可在这里找到。

音频文件

为了比较这两种方法,我将使用我在关于 Vosk 的文章中使用的相同音频源:随机播客片段。

“Opto Sessions -非凡投资者访谈”播客中的音频文件。spotify 上的第 69 集。

请注意:这是一个随机的选择,我与创作者没有任何联系,也没有因为命名他们而获得报酬。如果您在此处看到错误(例如,502 坏网关),请重新加载页面。

由于 68 分钟播客会议的转录结果会很长,我决定切掉 60 秒(否则,这篇文章包含的转录文本会比解释更多)。这里的挑战是,前 30 秒主要是引子的一部分,包含来自不同音频源的引用。

如果你只是想看看如何用耳语转录音频文件,你不必应用下面的代码。可以直接用 Whisper 读取. mp3 文件。

抄本

有了我们准备好的音频文件,我们可以使用 Whisper 和 Vosk 开始转录它。

低语

在我们转录相应的音频文件之前,我们必须先下载一个预先训练好的模型。目前,提供五种型号尺寸(表 1)。

表 1。Whisper 不同型号的概述(Whisper 的 GitHub 页面)。

作者在他们的 GitHub 页面上提到,对于纯英文应用程序来说,.en模型往往表现更好,尤其是对于tiny.enbase.en模型,而对于small.enmedium.en模型来说,差异会变得不那么显著。

Whisper 的 GitHub 页面包含了更多关于他们模型性能的信息。

下面的代码显示了如何下载语言模型并运行转录:

只用 3 行代码,我们就能转录一个音频文件。转录花了 65 秒,可以在下面看到。

我使用的是 2015 年年中的旧 Macbook Pro(2.2 GHz 四核英特尔酷睿 i7 和 16GB 内存)。

Right, that's the number one technical indicator. You do best by investing for the warm return. If you can't explain what the business is doing, then that is a huge red flag. Some technological change is going to put you out of business. It really is a genuinely extraordinary situation. Hi everyone, I'm Ed Goffam and welcome to OptoSessions where we interview the top traders and investors from around the world uncovering the secrets to success. On today's show, I'm delighted to introduce Beth Kindig, a technology analyst with over a decade of experience in the private markets. She's now the co founder of I.O. Fund, which specialises in helping individuals gain a competitive advantage when investing in tech growth stocks. How does Beth do this? She's gained hands on experience over the years. Here's fast eye Organul..

转录的结果是非常好的和全面的。如上所述,播客的介绍包含来自不同来源的质量不同的音频片段(例如,引用)。然而,Whisper 可以很好地转录音频,还可以处理标点符号(例如,逗号、句号和问号)。

沃斯克

和 Whisper 类似,我们也要为 Vosk 下载一个预先训练好的模型。所有可用型号的列表可在这里找到。我决定用最大的一个(1.8GB): vosk-model-en-us-0.22

下面的代码显示了如何使用 Vosk:

尽管 Whisper 也有类似的方法(滑动 30 秒窗口),但我们必须在这里做更多的手工编码。

首先,我们加载我们的音频文件(line 5)和我们的模型(lines 10-11)。然后我们读取前 4000 帧(line 17)并把它们交给我们加载的模型(line 20)。该模型返回(以 JSON 格式)结果,该结果作为 dict 存储在 result_dict 中。然后,我们只提取文本值,并将其附加到我们的转录列表中(line 24)。

如果没有更多的帧需要读取(line 18),循环就停止,我们通过调用 FinalResult() 方法(line 27)来捕捉最终结果。此方法还会刷新整个管道。

35 秒后,创建了以下结果:

the price is the number one technical indicator you do best by investing for the longer term if you can't explain what the business is doing then that is a huge red flag some technological changes puts you out of business it really is a genuine be extraordinary situation hi everyone i am a gotham and welcome to opto sessions where we interview top traders and investors from around the world uncovering the secrets to success on today's show i'm delighted to introduce beth can dig a technology analyst with over a decade of experience in the private markets she's now the co-founder of iowa fund which specializes in helping individuals gain a competitive advantage when investing in tech growth stocks how does beth do this well she's gained hands-on experience over the years whilst i

为了更好地与 Whiper 的输出进行比较,我再次将它粘贴到这里:

Right, that's the number one technical indicator. You do best by investing for the warm return. If you can't explain what the business is doing, then that is a huge red flag. Some technological change is going to put you out of business. It really is a genuinely extraordinary situation. Hi everyone, I'm Ed Goffam and welcome to OptoSessions where we interview the top traders and investors from around the world uncovering the secrets to success. On today's show, I'm delighted to introduce Beth Kindig, a technology analyst with over a decade of experience in the private markets. She's now the co founder of I.O. Fund, which specialises in helping individuals gain a competitive advantage when investing in tech growth stocks. How does Beth do this? She's gained hands on experience over the years. Here's fast eye Organul..

我们可以看到,沃斯克在正确抄写大部分单词方面做得很好。但是,它最大的弱点是不使用标点符号。这使得很难阅读转录。

结论

让 Whisper 开源对整个机器学习社区非常有益。与 Vosk 等现有开源解决方案相比,Whisper 只需要几行代码,支持标点符号,并能更好地转录单词。因此,当离线转录(大)音频文件时,我更喜欢 Whisker 而不是 Vosk。

如果你对 Whisper 项目、架构以及他们不同模型的性能和相关论文更感兴趣,你应该访问他们的 GitHub 页面

来源

耳语 GitHub 页面:【https://github.com/openai/whisper】T4

沃斯克车型:https://alphacephei.com/vosk/models

我之前的文章: 用 Vosk 离线转录大音频文件:https://towardsdatascience . com/register-large-audio-files-offline-with-Vosk-a 77 ee 8 f 7 aa 28

使用 Vosk 离线转录大型音频文件

原文:https://towardsdatascience.com/transcribe-large-audio-files-offline-with-vosk-a77ee8f7aa28

为您的下一个 NLP 项目转录大型音频文件

乔纳森·贝拉斯克斯在 Unsplash 上拍摄的照片。

我受分析 reddit 数据的自然语言处理(NLP)项目的启发,我想到了使用播客数据的想法。然而,由于播客是(大)音频文件,人们需要先将它们转录成文本。这个过程也被称为 A 自动SpeechRecognition(ASR)或Speech-to-text(STT)。

Google、Azure 或 AWS 等提供商提供了出色的 API 来完成这项任务。但是,如果您想要离线转录,或者出于某种原因,您不被允许使用云解决方案,该怎么办?

TL;博士;医生

  • Vosk 是一个允许你离线转录音频文件的工具包
  • 它支持 20 多种语言和方言
  • 音频必须首先转换为波形格式(单声道,16Hz)
  • 大型音频文件的转录可以通过使用缓冲来完成
  • Colab 笔记本可以在这里找到

目标

这就是为什么我写这篇文章来给你一个备选方案以及如何使用它们的概述。

这个想法是使用提供预训练模型的包或工具包,这样我们就不必先自己训练模型。

在这篇文章中,我将重点介绍 Vosk。还有很多类似于 Moziall 的 DeepSpeech 或 SpeechRecognition 的软件包。然而,DeepSpeech 的未来是不确定的,SpeechRecognition 除了在线 API 之外,还包括使用 Vosk 的 CMUSphinx。

我假设我们要转录的数据在 youtube 上不可用。如果有,我强烈推荐去看看[youtube-transcript-api](https://pypi.org/project/youtube-transcript-api/)套餐。它允许你为一个给定的视频获得生成的脚本,这比我们在下面要做的要少得多。

先决条件:以正确的格式输入数据

在我们进入转录部分之前,我们必须首先将数据转换成正确的格式。播客或其他(长)音频文件通常是 mp3 格式。然而,这不是包或工具包可以使用的格式。

更具体地说,我们需要将我们的(mp3)音频转换为:

  • 波形格式(。wav)
  • 单声道的
  • 16,000 赫兹采样速率

转换非常简单。首先我们必须安装ffmpeg,它可以在https://ffmpeg.org/download.html下找到。

Mac 用户可以使用 brew 下载并安装它:

brew install ffmpeg

接下来我们安装pydub包:

pip install pydub

下面的代码片段将 mp3 转换成所需的 wav 格式。它将输出存储在与给定 mp3 输入文件相同的目录中,并返回其路径。如果我们想跳过几秒钟(例如介绍),我们可以通过设置我们想跳过的秒数来使用 skip 参数。如果我们想先尝试一下,我们可以将摘录参数设置为以仅获取音频文件的前 30 秒。

使用这个功能,我们现在可以将我们的播客文件转换成所需的 wav 格式。

为了有一个(互动)的例子,我选择转录以下播客插曲:

请注意:播客是随机选择的。我与创造者没有任何联系,也没有因为说出他们的名字而获得报酬。

由于前 37 秒是介绍,我们可以使用 skip 参数跳过它们。

对于第一个例子,我们也将参数摘录设置为:

mp3_to_wav('opto_sessions_ep_69.mp3', 37, True)

我们的新文件opto _ sessions _ EP _ 69 _ extract . wav现在有 30 秒长,从 0:37 到 1:07 开始。

现在我们可以开始转录了!

沃斯克

Vosk 是一个支持 20 多种语言(如英语、德语、印度语等)的语音识别工具包。)和方言。它可以离线工作,甚至可以在树莓 Pi 这样的轻量级设备上工作。

它的便携式型号每个只有 50Mb。然而,还有更大的型号。所有可用型号的列表可以在这里找到:https://alphacephei.com/vosk/models

拨打以下电话即可轻松安装 Vosk:

pip install vosk

安装了 Vosk 之后,我们必须下载一个预先训练好的模型。我决定选择最大的一个:vosk-model-en-us-0.22

现在我们已经拥有了我们需要的一切,让我们打开我们的 wave 文件并加载我们的模型。

在我们深入研究转录过程之前,我们必须熟悉一下 VOSKs 的输出。

VOSK 返回 JSON 格式的转录,如下所示:

{
    "text" : "cats are dangerous"
}

如果我们也想知道 VOSK 对每个单词有多自信,并且想知道每个单词的时间,我们可以使用SetWords(True)。例如,一个单词的结果如下所示:

{
   "result":[
      {
         "conf":0.953349,
         "end":6.090000,
         "start":5.700000,
         "word":"cats"
      },
      {
         etc.
      },
      etc.
   ],
   "text":"cats are dangerous"
}

因为我们想要转录大的音频文件,所以通过逐块转录 wave 文件来使用缓冲方法是有意义的。以下代码显示了转录方法:

我们读入前 4000 帧(第 7 行)并将它们交给我们加载的模型(第 12 行)。该模型返回(以 JSON 格式)结果,该结果作为 dict 存储在 result_dict 中。然后,我们只提取文本值,并将其附加到我们的转录列表中(第 14 行)。

如果没有更多的帧要读取(第 8 行),循环停止,我们通过调用 FinalResult() 方法来捕捉最终结果。此方法还会刷新整个管道。

结果应该是这样的:

to success on today show i'm delighted to introduce beth kinda like a technology analyst with over a decade of experience in the private markets she's now the cofounder of io fund which specializes in helping individuals gain a competitive advantage when investing in tech growth stocks how does beth do this well she's gained hands on experience over the years was i were working for or analyzing a huge amount of relevant tech companies in silicon valley the involved in the market

注意:如果你对更“时尚”的解决方案感兴趣(使用进度条),你可以在这里找到我的代码。

用于离线转录的其他包或工具包

正如在简介中提到的,还有更多可用的包或工具包。然而,它们的实现不像 Vosk 那么容易。不过如果你有兴趣,我可以推荐英伟达的 NeMo

英伟达尼莫

NeMo 是为从事自动语音识别、自然语言处理和文本到语音合成的研究人员构建的工具包。和 VOSK 一样,我们也可以从一堆预先训练好的模型中进行选择,这些模型可以在这里找到。

实现需要更多的时间和代码。基于 Somshubra Majumdar 的 笔记本我创建了一个精简版,可以在这里找到

结论

Vosk 是一个很棒的离线转录工具包。与我测试的其他离线解决方案相比,Vosk 是最容易实现的。唯一缺少的东西是标点符号。到目前为止,还没有整合 it 的计划。但是,与此同时,如果需要,可以使用外部工具。

将知识图表转移到 Doctor.ai

原文:https://towardsdatascience.com/transfer-knowledge-graphs-to-doctor-ai-cc21765fa8a6

用 Hetionet,STRING,KEGG 扩展 Doctor.ai

本文展示了如何:

1.将三个公共知识图谱整合成一个医疗聊天机器人——doctor . ai。

2.通过 AWS Lex 使用自然语言向 Doctor.ai 询问病史、病原体、药物和基因。

帕特里克·托马索在 Unsplash 上的照片

正在进行的新冠肺炎疫情给我们上了许多宝贵的一课。其中之一是,我们需要使我们的医疗保健系统现代化,让所有人都能享受到。世界各国政府已经投入巨资进行数字化建设(这里这里这里)。但是进入疫情两年后,像德国这样的富裕国家仍然在他们的医院里使用传真和漏洞百出的软件来传输数据。这一明显的技术差距付出了生命的代价。

2021 年 12 月,我和四名 Neo4j 工程师基于 eICU 数据库创建了一个名为 Doctor.ai 的聊天机器人(阅读详情此处此处)。Doctor.ai 可以为患者和医生管理海量的病历。通过 AWS Lex,用户可以快速查询自己的病史,而医生甚至可以要求治疗建议。该数据库包含许多不同类型的数据:人口统计信息、ICU 就诊详情、实验室结果、病原体鉴定、诊断和治疗。即便如此,我们还是能够将它们全部放入一个 Neo4j 知识图中。与其他基于表的数据库不同,该图让我们可以自由地轻松构建和执行高度复杂的查询。

但是这个第一版的 Doctor.ai 知识范围非常有限——只有 eICU 记录和一些预定义的医学常见问题。那么如何才能让它更有知识呢?我们可以将新的数据放入它的图表中。Medium 的很多教程都教我们使用自然语言处理(NLP)来抓取维基百科等网站进行自动知识图构建。尽管 NLP 可以快速生成草图,但需要严格的控制和事实检查来确保其正确性。在医疗保健领域,正确性最为重要,在这个领域,准确的信息往往是生死攸关的问题。

图一。作者将三幅医学知识图转换为 Doctor.ai. Image。

但是我们可以有第二个更简单的方法。互联网上有一些公开的、精心策划的知识图谱,比如 HetionetSTRINGKEGG 。为什么不直接把这些数据转移到 Doctor.ai 里?然后,Doctor.ai 将在其所有医疗记录的基础上获得关于药物-药物相互作用、药物副作用、基因-基因相互作用的知识。在这篇文章中,我将向您展示如何将这三个数据库集成到 Doctor.ai 中。您可以在我的存储库中找到这些数据和我的代码。

https://github.com/dgg32/transfer_kg

集成知识图转储在这里:

https://1drv.ms/u/s!Apl037WLngZ8hhj_0aRswHOOKm0p?e=7kuWsS

1.数据源

Hetionet 数据库是一个全面的医学知识图表。它是由丹尼尔·希梅尔斯坦和旧金山加利福尼亚大学巴兰兹尼实验室的合作者开发的。它连接了 47031 个节点和 24 种不同类型的 2250197 条边:基因、疾病、化合物、解剖、副作用等等(图 2)。在本文中,我将使用 Hetionet 作为主干。

图二。Hetionet 的元图。图片来自https://het.io/about/metagraph.png

然而,Hetionet 本身也需要更新。Hetionet 上一次更新是在 2018 年。它的 Neo4j 包是 3.x 格式的。我们还可以借助一些外界数据极大地丰富它的基因-基因相互作用。最后,它只包含 137 种疾病。完全没有关于传染病及其病原体的数据。

为此,我将引入两个数据库:STRING 数据库和 KEGG 疾病数据库。字符串数据库收集关于蛋白质-蛋白质相互作用的数据。它包含 6700 万个蛋白质和 200 亿个相互作用。 KEGG 疾病数据库目前包含超过 2500 种疾病,我之前在 Neo4j 也调查过。它还包含有关传染病及其病原体的数据,包括新冠肺炎病毒。最后,KEGG 还将药物和基因整合到其知识图中。

Hetionet 发布为 CC0STRING 可以在“4.0 知识共享”许可下免费获得,而学术用户可以免费使用 KEGG 网站

2.整合三个数据源

整合不同的知识图并不容易,因为它们可以使用不同的标识符来描述同一概念。在我们的例子中,Hetionet 数据库用 DOID 索引疾病,用 DrugBank ID 索引化合物,用 Entrez Gene ID 索引基因。KEGG 和 STRING 数据库都创建了它们的唯一标识符。幸运的是,生物医学研究人员已经逐渐就受控词汇达成一致,并对基因、病原体和其他概念的命名进行了标准化。出于这个原因,我将基于节点的name属性而不是它们的原始标识符来合并节点。所以我首先在三个数据源(我的存储库中的源代码)之间标准化名称。

图 3。整合计划。绿色箭头表示不同类型节点之间的交互。红色箭头表示数据库之间的节点将如何合并。其他类型未在图中示出。图片作者。

我尝试按照本教程中的每一步来导入 Hetionet 的 Neo4j 数据转储。但是每次都失败,并显示“数据库没有完全关闭”的错误。然后我决定下载它的 JSON 。事实证明这是一个更好的解决方案,因为我可以编辑它的内容。我已经将节点name设置为标识符,并相应地修改了边定义。

然后我把这个修改过的 Hetionet 导入到 Neo4j 4.3.6 中。220 万关系的导入花了几个小时才完成。我建议您在 AWS EC2 上这样做(CloudFormation 模板在我的存储库中)。不要忘记为这个 4.3.6 版本创建一个转储作为备份。

导入后可以看到 Hetionet 中有 20943 个基因,137 种疾病,1552 个化合物。

接下来,下载智人 的两个字符串数据集。

图 4。为人类下载字符串数据。图片作者。

字符串数据库基于不同的证据渠道,如实验、共表达、同源性等,为每个蛋白质-蛋白质相互作用分配分数。0.5 的分数将指示大约每隔一次的交互可能是错误的(即,假阳性)。然而在下载的links数据中,分数被乘以 1000。在这个项目中,我在导入之前删除了与低于 900 的combined_scores的连接。

图 5。Hetionet、STRING 和 KEGG 整合后的知识图图式。图片作者。

表 1。STRING-KEGG 整合前后 Hetionet 4 中的标记数量。

KEGG 疾病数据库的整合更加复杂。我已经通过 KEGG API 下载了数据,如我之前的项目中所述。这一次,我需要用名称而不是 KEGG 标识符来链接实体。之后,我将数据导入知识图。Hetionet 吞噬 STRING 和 KEGG 后,其在“疾病”、“化合物”和“病原体”中的节点数量大幅增加(表 1)。连接的数量也增加了。已经创造了 123577 对STRING基因-基因相互作用。treats关系的数量从 755 增加到 3363,causes的数量从 138944 增加到 139376。

3.将知识图谱与 Doctor.ai 连接起来

现在我的“Hetionet + STRING + KEGG”知识图就完成了。是时候将它与 Doctor.ai 连接起来了。我通过 CloudFormation 设置了 AWS 基础设施,如我的上一篇文章中所述(模板在我的存储库中)。Doctor.ai 中的原始替身数据是 eICU 数据集。申请者必须完成在线课程,然后等待批准。在本文中,我将基于 eICU 数据创建两个虚构的患者来演示新医生。ai。1 号患者 Lucy 患有 Kyasanur Forest 病,而 2 号患者 Mark 患有 Christianson 综合征(图 6)。

图 6。作者笔下艾医生形象中的两个虚构病人。

一旦他们的病历被导入 Doctor.ai,我就进行了以下两次对话(图 7)。

图 7。Doctor.ai 截图知识图谱转移后,Doctor.ai 可以检索到更多关于疾病的细节,比如病原体、基因等。图片作者。

如图 7 所示,Doctor.ai 首先找到了他们的病历。多亏了新的知识图表,它也可以提供关于这些疾病的更多细节。在第一种情况下,它报告了病原体,而在第二种情况下,它可以说 SLC9A6 基因与克里斯蒂安森综合征有关。

图 8。艾医生回答关于新冠肺炎的问题。图片作者。

接下来,我向艾医生询问了这两年的话题——新冠肺炎。正如你所看到的,Doctor.ai 不仅能说出致病病原体新型冠状病毒的名字,还能列出对抗这种疾病的药物清单。所有这些数据都来自 KEGG 数据库。

在引擎盖下,我们可以看到 AWS Lex 的局限性。目前,Lex 的内置插槽类型Alphanumeric不能识别开箱即用的空格。所以“葡萄球菌感染”或“单纯疱疹病毒感染”并没有被正确地引出(见这里)。我通过定义自己的槽类型并输入所有 2000 种疾病名称作为候选值来解决这个限制。

结论

当他们在网络中时,事情更容易学习。而这个小项目有效地将 Doctor.ai 插入到通用医学知识宇宙中(图 9)。与其马上用 NLP 从头构建一个,为什么不先集成现有的呢?Doctor.ai 是一个聊天机器人,它管理一种特定类型的数据——医疗记录。在首次亮相时,Doctor.ai 在 AWS Kendra 的帮助下回答了一些事实性的问题,后者可以检索预定义的答案给用户。它也很贵(每月 810 美元)。通过嵌入 Hetionet、STRING 和 KEGG 的研究数据,它非常经济地获得了一般医学知识。有了这些扩大的知识,Doctor.ai 不仅可以向患者和医生报告过去医院就诊的详细信息,还可以为他们提供有关病原体、药物、副作用和基因的信息。虽然这仍然不能使 Doctor.ai 成为一个开放域的聊天机器人,但它是朝着这个方向迈出的坚实的第一步。

图 9。Doctor.ai 与医学知识图谱的集成。来自 Doctor.ai 的数据位于图表的右侧,而 Hetionet、STRING 和 KEGG 数据位于图表的中央和左侧。图片作者。

尽管还有改进的空间。这个项目中的数据集成是初级的。可以进一步清除数据条目。例如,Hetionet 和 KEGG 的许多疾病没有 ICD-10 分类。这使得数据合并变得困难。由于 ICD-11 已经于 2022 年 1 月 1 日生效,KEGG 已经采纳了这一新标准,我们最好尽快适应未来。

你也可以扩展 Doctor.ai。目前,我们的数据集中只有非常少的关于精神疾病的数据。事实上,与身体疾病相比,互联网上关于精神健康的数据随处可见。因此,精神障碍患者长期得不到足够的服务。患者数量众多:2020 年,近五分之一的美国成年人患有精神疾病。所以我们迫切需要收集更多这方面的数据。此外,药物-药物相互作用可以用来自药物库的数据进一步增强。卡抗生素耐药性数据也是一个不错的整合候选。综上所述,Doctor.ai 的拓展方向有很多。

最后,将特定和一般知识图相结合的想法并不局限于 Doctor.ai for healthcare。有了合适的数据,我们可以在其他领域使用相同的基础设施:从兽医到林业,从银行到人力资源,从物流到制造业。然而,在这些新的使用案例中,决策者不仅需要考虑技术,还需要考虑伦理和法律。

更新:在 这篇新文章 中,我把 Doctor.ai 做成一个基于症状或基因突变的诊断工具,数据来自这些转移的知识图。

本文 采用 GPT-3 作为 NLU,提高性能,减少开发时间,收缩代码。

https://dgg32.medium.com/membership

基于 Flux.jl 的迁移学习和孪生网络图像分类

原文:https://towardsdatascience.com/transfer-learning-and-twin-network-for-image-classification-using-flux-jl-cbe012ced146

利用数据加载器、Metalhead.jl 和双网络设计解决挑战

卢卡·布拉沃在 Unsplash 上的照片

今年早些时候,我在 PyTorch 从事一个项目,旨在创建一个深度学习模型,可以检测未知物种中的疾病。最近,我决定在 Julia 中重建该项目,并将其作为学习flux . JL【1】的一个练习,这是 Julia 最受欢迎的深度学习包(至少按 GitHub 上的星级数评级)。但是在这样做的时候,我遇到了一些挑战,这些挑战我在网上或文档中找不到好的例子。因此,我决定写下这篇文章,作为任何想做和我类似事情的人的资源。

这是给谁的?

因为 Flux.jl(以下简称“Flux”)是一个深度学习包,所以我写这篇文章主要是为了让熟悉迁移学习等深度学习概念的受众。

虽然我也是带着一个半新手(像我一样)的想法来写这篇文章的,但是其他人可能会觉得这篇文章很有价值。请记住,我写这篇文章并不是为了全面介绍或指导 Julia 或 Flux。为此,我将尊重其他资源,如正式的朱莉娅和通量文件,分别。

最后,我与 PyTorch 做了几次比较。理解我的观点并不需要 PyTorch 的经验,但是有 PyTorch 经验的人可能会觉得特别有趣。

为什么是朱莉娅?还有为什么是 Flux.jl?

如果你已经使用了 Julia 和/或 Flux,你可以跳过这一节。此外,许多其他人已经写了很多关于这个问题的帖子,所以我会很简短。

最终是我喜欢朱莉娅。它擅长数值计算,编程是一种真正的乐趣,而且速度很快。本机速度快:不需要 NumPy 或其他封装底层 C++代码的包装器。

至于为什么是 Flux,那是因为它是 Julia 中最流行的深度学习框架,用纯 Julia 编写,可与 Julia 生态系统组合。这个项目看起来和任何最终学习通量的项目一样好。

项目本身

好了,现在我已经无耻地说服了朱莉娅,是时候了解一下这个项目本身了。我使用了三个数据集——plant village【2】、plant leaves【3】和plant aek【4】——涵盖了许多不同的物种。我使用 PlantVillage 作为训练集,另外两个组合作为测试集。这意味着模型必须学习一些对未知物种通用的东西,因为测试集将包含未经训练的物种。

了解这一点后,我创建了三个模型:

  1. 使用 ResNet 迁移学习的基线
  2. 具有定制 CNN 架构的双(又名,连体)神经网络
  3. 具有迁移学习双路径的双神经网络

这篇文章的其余部分将详细介绍处理数据以及创建和训练模型的一些挑战和难点。

处理数据

第一个挑战是数据集的形式不正确。我不会在这里详述我是如何预处理它们的,但简单来说,我创建了两个图像目录, traintest 。两者都写满了一长串的图片,分别叫做img0.jpgimg1.jpgimg2.jpg等等。我还创建了两个 CSV——一个用于训练集,一个用于测试集——包含一列文件名,一列二进制标签。

上面的结构很关键,因为总的数据集超过 10 GB,肯定不适合我的 PC 的内存,更不用说我的 GPU 的内存了。正因为如此,我们需要使用一个DataLoader。(如果你用过 PyTorch,你会很熟悉;这和 PyTorch 中的概念基本相同。)

要在 Flux 中做到这一点,我们需要创建一个自定义结构来包装我们的数据集,以允许它成批地加载数据。为了让我们的自定义结构能够构造一个数据加载器,我们需要做的就是为这个类型定义两个方法:lengthgetindex。下面是我们将用于数据集的实现:

本质上,它的工作方式是当 Flux 试图检索一批图像时,它会调用getindex(dataloader, i:i+batchsize),这在 Julia 中相当于dataloader[i:i+batchsize]。因此,我们的自定义getindex函数获取文件名列表,获取适当的文件名,加载这些图像,然后处理它们并将其重塑为适当的HEIGHT × WIDTH × COLOR × NUMBER形状。对标签进行类似的操作。

然后,我们的培训、验证和测试数据加载器可以非常容易地完成:

制作一些模型

数据加载器准备就绪后,下一步是创建模型。其中第一个是基于 ResNet 的迁移学习模型。这实际上被证明是相对具有挑战性的工作,虽然希望它会很快得到解决。

Metalhead.jl 包中——包含用于迁移学习的计算机视觉通量模型——创建一个带有预训练权重的 ResNet18 模型应该像model = ResNet(18; pretrain = true)一样简单。然而,至少在撰写本文时,创建预训练模型会导致错误。这可能是因为 Metalhead.jl 仍在添加预训练的权重。终于在 HuggingFace 上找到了 .tar.gz 文件,里面包含了这里的权重。提取 tarball 后得到一个普通的。bson 文件,我们可以使用以下代码来加载权重,并创建我们自己的自定义通量模型,具有单个二进制输出:

(注:如果有比这更优雅的方式来改变 ResNet 的最后一层,请告诉我。)

随着预训练迁移学习模型的建立,只剩下两个孪生网络模型。然而,与迁移学习不同,我们必须学习如何手动创建模型。(如果你习惯了 PyTorch,这就是 Flux 与 PyTorch 大相径庭的地方。)

使用 Flux 文档和其他在线资源创建 CNN 相对容易。然而,Flux 没有内置层来表示具有参数共享的孪生网络。它最接近的是Parallel层,这个层使用参数共享。

然而,Flux 确实有文档在这里关于如何创建定制的多输入或输出层。在我们的例子中,我们可以用来创建自定义Twin层的代码如下:

首先注意,它以一个简单的结构Twin开始,有两个字段combinepathpath 是我们的两个图像输入将经过的网络,combine是最终将来自path 的输出组合在一起的功能。

然后,使用Flux.@functor告诉 Flux 像对待常规 Flux 层一样对待我们的结构,并且(m::Twin)(Xs::Tuple) = m.combine(map(X -> m.path(X), Xs)…)定义向前传递,其中元组 Xs 中的所有输入 X 都通过path馈送,然后所有输出都通过combine传递。

要创建具有定制 CNN 架构的 Twin 网络,我们可以执行以下操作:

在这种情况下,我们实际上使用Flux.Bilinear层作为combine,这实质上创建了一个完全连接到两个独立输入的输出层。以上两个输入是path的输出,即自定义 CNN 架构。或者,我们可以以某种方式使用hcatvcat作为combine,然后在最后添加一个Dense层,但是这个解决方案对于这个问题来说似乎更优雅。

现在,要使用 ResNet 创建 Twin 网络,我们可以执行以下操作:

请注意我们如何使用与之前相同的技巧,使用一个Flux.Bilinear层作为combine,并使用一个与之前类似的技巧来使用预训练的 ResNet 作为path

训练时间

现在我们已经准备好了数据加载器和模型,剩下的就是训练了。通常在 Flux 中,我们可以使用一个简单的一行程序,@epochs 2 Flux.train!(loss, ps, dataset, opt),用于训练循环,但是我们确实有一些定制的东西想要用我们的来做。

首先,非孪生网络的训练循环:

这里要展开的内容很多,但本质上它做了几件事:

  1. 它创建了一个助手结构,用于跟踪我们想要的任何验证指标。在这种情况下,每个历元的损失和精度。
  2. 它只选择最后一层参数进行训练。如果我们想的话,我们可以训练整个模型,但是那会在计算上更加费力。这是不必要的,因为我们用的是预训练的砝码。
  3. 对于每个历元,它遍历训练集的所有批次进行训练。然后,它计算整个验证集(当然是分批的)的准确性和损失。如果历元的验证精度得到提高,则可以省去模型。如果没有,它继续到下一个纪元。

请注意,我们在这里可以做得更多,例如,提前停止,但以上足以获得大致的想法。

接下来,双网络的训练循环非常相似,但略有不同:

首先注意,我们使用了一个同名的函数,train!,但是函数签名略有不同。这使得 Julia 能够根据我们训练的网络类型分配正确的功能。

还要注意,Twin ResNet 模型冻结了它的预训练参数,而我们训练所有的 Twin 自定义 CNN 参数。

除此之外,训练循环的其余部分基本相同,只是我们必须使用两个训练数据加载器和两个验证数据加载器。这为我们提供了每批的两个输入和两组标签,我们将其适当地输入到孪生模型中。最后,请注意,孪生模型预测两个输入图像是否具有相同的标签,而常规非孪生网络仅直接预测标签。

这样,为所有三个模型的测试集构建测试循环应该不会太难。因为这篇文章的目的是讨论我在网上找不到例子的主要难点,所以我将测试部分留给读者作为练习。

最后的想法

他们所说的 Julia 生态系统的现状有一定的真实性,即它可能不成熟,人们需要愿意处理有限的文档和/或稀缺的例子。

最大的挑战是弥合从相对容易、简单的示例到更高级的技术之间的差距,对于这些技术来说,示例很少。但是这也揭示了 Julia 的一个优势:因为它天生就很快,所以搜索一个包的源代码来找到答案通常非常容易。有几次,我发现自己在浏览 Flux 源代码,寻找一些东西是如何工作的。每次我都能非常轻松快捷地找到答案。我不确定我是否有足够的勇气为 PyTorch 尝试类似的事情。

另一个挑战是 Metalhead.jl 的不成熟状态,这在 Julia 生态系统中肯定不是唯一一个功能不完整的。

我上一个挑战实际上是一个心态挑战。Python 和 Julia 生态系统之间的一个根本区别是许多重要包的规模。例如,PyTorch 因为其内部的 C++需要做所有的事情,而纯 Julia 包可以轻松地互操作和组合。因此,你不会看到 Flux 有 PyTorch 那么多的特性。相反,你会在其他包中看到很多这样的功能,比如 MLUtils.jl、CUDA.jl、BSON.jl、Metalhead.jl 以及其他无数的包。记住这一点,无论何时用 Julia 编程,你都可以节省一些时间和精力。

作为最后一个想法,我发现通量是相当愉快和优雅的…一旦我掌握了它。我以后肯定会用 Flux 做更多的深度学习。

参考

[1] M. Innes,Flux:优雅的机器学习与 Julia (2018),《开源软件杂志》

[2] Arun Pandian J .和 G. Gopal,数据用于:使用 9 层深度卷积神经网络识别植物叶部病害(2019),Mendeley 数据

[3] S. S. Chouhan、A. Kaul 和 U. P. Singh,《叶片图像数据库:植物病理学植物保护实践》( 2019 年), Mendely Data

[4] V. P. Kour 和 S. Arora,PlantaeK:查谟和克什米尔本地植物叶数据库(2019 年),Mendeley 数据

灰度图像的迁移学习:如何微调黑白数据集的预训练模型

原文:https://towardsdatascience.com/transfer-learning-on-greyscale-images-how-to-fine-tune-pretrained-models-on-black-and-white-9a5150755c7a

您需要了解的一切,以理解为什么通道数量很重要以及如何解决这个问题

随着深度学习领域的不断成熟,在这一点上,人们普遍认为迁移学习是计算机视觉快速取得良好结果的关键,尤其是在处理小数据集时。虽然从预训练模型开始会产生的差异部分取决于新数据集与原始训练数据的相似程度,但可以认为从预训练模型开始几乎总是有利的。

尽管越来越多的预训练模型可用于图像分类任务,但在撰写本文时,其中大多数都是在某个版本的 ImageNet 数据集上训练的;其中包含彩色图像。虽然这通常是我们正在寻找的,但在某些领域,如制造业和医学成像,经常会遇到黑白图像数据集。

由于彩色图像和黑白图像之间的差异对我们人类来说是微不足道的,所以您可能会认为微调预训练模型应该开箱即用,但这很少发生。因此,尤其是如果您在图像处理方面的背景知识有限,可能很难知道在这些情况下采取什么样的最佳方法,

在本文中,我们将尝试通过探索 RGB 和灰度图像之间的差异,以及这些格式如何影响卷积神经网络模型完成的处理操作,来消除黑白图像微调时需要考虑的所有因素,然后再演示如何将灰度图像用于预训练模型。最后,我们将检查在一些开源数据集上探索的不同方法的性能,并将其与灰度图像上的从头训练进行比较。

图片取自公开的豆类数据集

RGB 和灰度图像有什么区别?

虽然彩色和灰度图像可能与我们非常相似,因为计算机只将图像视为一组数字,但这可能会对图像的解释产生巨大的影响!因此,为了充分理解为什么灰度图像可能对预训练网络构成挑战,我们必须首先检查计算机如何解释彩色和灰度图像的差异。

作为一个例子,让我们使用来自豆子数据集的图像。

RGB 图像

通常,当我们在深度学习中处理彩色图像时,这些图像是以 RGB 格式表示的。在高层次上,RGB 是加色模型,其中每种颜色由红、绿和蓝值的组合来表示;这些通常存储为单独的“通道”,因此 RGB 图像通常被称为 3 通道图像。

我们可以检查图像的模式——一个定义图像中像素类型和深度的字符串,如这里的所描述的——以及检查可用的通道,使用 PIL 如下所示。

这证实了 PIL 已经认识到这是一个 RGB 图像。因此,对于每个像素,存储在这些通道中的值(称为强度)构成了整体颜色的一个组成部分。

这些组件可以用不同的方式表示:

  • 最常见的是,组件值存储为 0 到 255 范围内的无符号整数;单个 8 位字节可以提供的范围。
  • 在浮点表示法中,值可以用 0 到 1 来表示,其间可以有任何小数值。
  • 每个颜色分量值也可以写成从 0%到 100%的百分比。

将我们的图像转换为 NumPy 数组,我们可以看到,默认情况下,图像被表示为一个无符号整数数组:

检查阵列的形状,我们可以看到图像有 3 个通道,这符合我们的预期:

为了将我们的图像数组转换成浮点表示,我们可以在创建时显式指定数组的dtype。让我们看看当我们转换和绘制我们的图像时会发生什么。

哦不!

从可以通过检查数据来确认的警告消息中,我们可以看到图像不能正确显示的原因,因为输入数据不在浮点表示的正确范围内。为了纠正这一点,让我们将数组中的每个元素除以 255;这应该确保每个元素都在范围[0,1]内。

绘制我们的标准化数组,我们可以看到图像现在显示正确!

了解成分强度

通过调整每种成分的强度,我们可以使用 RGB 模型来表现各种颜色。

当每个分量的 0%强度被组合时,没有光产生,所以这产生了黑色(最暗的颜色)。

当所有成分的强度都相同时,结果是灰色的阴影,根据强度的大小而变暗或变亮。

当其中一种成分的强度比其他成分强时,最终的颜色更接近具有最强成分的原色(红色、绿色或蓝色):

当每个成分的 100%强度被组合时,这产生白色(最浅的可能颜色)。

虽然这有望提供 RGB 图像的概述,但关于 RGB 颜色模型的更多细节可以在这里找到。

灰度图像

现在,我们已经研究了如何使用 RGB 颜色模型来表示彩色图像,让我们研究一下灰度图像与此有何不同。

灰度图像是一种简单的图像,其中仅有的颜色是不同的灰色阴影。虽然我们在日常对话中经常将这样的图像称为“黑白”,但真正的“黑白图像”将只由这两种不同的颜色组成,这种情况很少发生;使“灰度”成为更准确的术语。

由于灰度图像没有颜色信息表示,每个像素需要存储的信息更少,并且不需要加色模型!对于灰度图像,我们需要的唯一信息是代表每个像素强度的单一值;该值越高,灰色越浅。因此,灰度图像通常由一个通道组成,其中每个像素强度只是一个从 0 到 255 的单一数字。

为了进一步探索这一点,我们可以使用 PIL 将我们的图像转换成灰度,如下所示。

像以前一样,我们可以使用 PIL 检查模式和图像通道。

PIL 的文档中,我们可以看到L指的是单通道、灰度图像。同样,我们可以通过将该图像转换为数组并检查形状来确认这一点。

注意,因为我们只有一个通道,所以默认情况下通道维度被完全删除;这可能会给一些深度学习框架带来问题。我们可以使用 NumPy 的expand_dims函数显式添加通道轴。

在 PyTorch 中,我们可以使用unsqueeze方法完成同样的事情,如下所示:

为什么这会影响预训练模型?

在观察了 RGB 和灰度图像之间的差异后,我们可能开始理解这些表示法是如何给模型带来问题的;尤其是如果该模型已经在图像数据集上进行了预训练,而该数据集的格式与我们当前训练的格式不同。

目前,大多数可用的预训练模型都是在 ImageNet 数据集的版本上训练的,该数据集包含 RGB 格式的彩色图像。因此,如果我们对灰度图像进行微调,我们提供给预训练模型的输入与之前遇到的任何输入都有很大不同!

在撰写本文时,卷积神经网络(CNN)是视觉任务最常用的预训练模型,我们将把重点限制在理解 CNN 如何受图像中通道数量的影响;其他架构超出了本文的范围!这里,我们假设熟悉 CNN,以及卷积是如何工作的——因为有优秀的资源详细介绍了这些主题——并关注改变输入通道的数量将如何影响这一过程。

就我们的目的而言,要记住的关键信息是,CNN 的核心构建模块是卷积层,我们可以将其视为应用一组滤波器(也称为内核)的过程,其中滤波器只是一个小矩阵,通常为 3×3,作为图像上的滑动窗口;在对结果求和之前执行逐元素乘法。在这里可以找到一个很好的工具来理解这是如何工作的

通道数量如何影响过滤器?

在深度学习之前的计算机视觉中,过滤器是出于某些目的而手工创建的,例如边缘检测、模糊化等。例如,让我们考虑一个用于检测水平线的手工制作的 3×3 滤波器:

虽然在滑动窗口操作期间在整个图像上使用相同的滤波器“权重”,但是这些权重并不在通道之间共享;这意味着滤波器必须始终具有与输入相同数量的通道。因此,我们想要应用于 3 通道 RGB 图像的任何滤镜也必须有 3 个通道!过滤器拥有的通道数量有时被称为“深度”。

考虑到我们上面定义的水平线过滤器,为了将其应用于 3 通道图像,我们需要增加该过滤器的深度,使其为 3x3x3。由于我们希望每个通道具有相同的行为,在这种情况下,我们可以简单地沿通道轴复制 3×3 滤波器。

我们可以这样做,如下所示:

现在,过滤器的深度与通道的数量兼容,我们能够将此过滤器应用于 3 通道图像!

为此,对于每个通道,我们将图像的滑动窗口部分的元素乘以相应滤波器的元素;这将产生 3×3 矩阵,该矩阵表示对应于每个通道的当前滤波器位置的特征。这些矩阵然后可以被求和以获得我们的输出特征图的相应部分。

这个过程如下图所示:

注意,特征图左上角的像素对应于内核中心像素的位置。由于我们无法计算图像每个边缘上最外层像素的完整卷积,这些像素将不会包含在特征图中。

我们可以重复这个过程,在图像上移动过滤器的位置,以获得完整的输出特征图。注意,不管输入图像的通道数是多少,当每个通道的特征被加在一起时,特征图将总是具有深度 1。

卷积神经网络

既然我们已经探讨了如何将手动定义的滤波器应用于 3 通道图像,此时,您可能想知道:CNN 是如何做到这一点的?

CNN 背后的一个关键思想是,这些过滤器可以随机初始化,而不是让专家手动定义过滤器,我们相信优化过程可以确保这些过滤器在训练期间学会检测有意义的特征;CNN 学习的过滤器类型的可视化在这里探讨。因此,除了这些过滤器是学习的而不是定义的,整体过程在很大程度上是相同的!

在 CNN 中,每个卷积层包含与将要学习的滤波器相对应的参数;初始化的随机过滤器的数量是我们可以指定的超参数。正如我们在上面的例子中看到的,每个滤波器都会产生一个单通道特征图,因此卷积层初始化的滤波器数量将决定输出通道的数量。

例如,假设我们有一个单通道图像,我们想创建一个学习单个 3×3 滤波器的卷积层。我们可以如下所示指定这一点:

这里,我们希望滤波器的尺寸与我们之前定义的单通道水平线滤波器相同。让我们通过检查该层的“权重”属性来确认这一点:

回想一下 PyTorch 默认情况下首先存储通道数,并注意到出于计算目的添加了一个批次维度,我们可以看到该层已经初始化了一个 3x3 过滤器,正如我们所预期的那样!

现在,让我们创建另一个卷积层,这一次指定我们有 3 个输入通道,以便能够处理 RGB 图像,并检查权重。

类似于当我们扩展我们手动定义的过滤器时,初始化的过滤器现在具有与输入通道的数量相同的深度;这给出了 3x3x3 的尺寸。

然而,当我们扩展手动定义的过滤器时,我们只是复制了相同的权重。这里,关键的区别是每个通道的 3×3 权重将是不同的;使得网络能够检测每个信道的不同特征。因此,每个内核根据输入图像的每个通道学习特定的特征!

我们可以通过直接检查重量来确认这一点,如下所示:

由此,我们可以看到,将应用于每个通道的 3×3 滤波器的权重是不同的。

虽然在创建新的卷积层时,基于我们的输入来调整初始化的滤波器维度是容易的,但是当我们开始考虑预训练的架构时,这变得更加困难。

作为一个例子,让我们检查一个来自 PyTorch 图像模型(timm)库Resnet-RS50 模型的第一个卷积层,它已经在 ImageNet 上进行了预训练;如果你对 PyTorch 图像模型不熟悉,想了解更多,我以前在这里探索过这个库的一些特性。

由于该模型是在 RGB 图像上训练的,我们可以看到每个滤波器都需要一个 3 通道输入。因此,如果我们试图用一个单一的通道在灰度图像上使用这个模型,这是行不通的,因为我们丢失了重要的信息;过滤器将试图检测不存在的频道中的特征!

此外,在我们之前的例子中,我们考虑了学习单个滤波器的卷积层;这在实践中很少发生。通常,我们希望每个卷积层有多个滤波器,这样每个滤波器都能够专门识别输入的不同特征。根据任务的不同,有些人可能学会检测水平边缘,有些人可能学会检测垂直边缘,等等。这些特征可以由后面的层进一步组合,使模型能够学习越来越复杂的特征表示。在这里,我们可以看到 ResNet-RS50 模型的卷积层有 32 个输出通道,这意味着它已经学习了 32 个不同的滤波器,每个滤波器都需要一个 3 通道输入!

如何在预训练模型中使用灰度图像

既然我们理解了为什么通道数量减少的灰度图像与在 RGB 图像上训练的预训练模型不兼容,那么让我们探索一些可以克服这一点的方法吧!

根据我的经验,有两种常用的主要方法:

  • 向每个灰度图像添加附加通道
  • 修改预训练网络的第一卷积层

在这里,我们将探索这两种方法。

向灰度图像添加附加通道

可以说,使用灰度图像和预训练模型的最简单的方法是根本避免修改模型;相反,复制现有的通道,使每个图像有 3 个通道。使用我们之前看到的相同的灰度图像,让我们来探索如何做到这一点。

使用 NumPy

首先,我们需要将图像转换成一个 NumPy 数组:

正如我们之前观察到的,因为我们的图像只有一个通道,所以通道轴还没有创建。同样,我们可以使用expand_dims函数来添加这个。

现在我们已经为渠道维度创建了一个额外的轴,我们需要做的就是在这个轴上重复我们的数据;为此我们可以使用repeat方法,如下所示。

为了方便起见,让我们将这些步骤总结成一个函数,以便在需要时可以轻松地重复这个过程:

def expand_greyscale_image_channels(grey_pil_image):
    grey_image_arr = np.array(grey_image)
    grey_image_arr = np.expand_dims(grey_image_arr, -1)
    grey_image_arr_3_channel = grey_image_arr.repeat(3, axis=-1)
    return grey_image_arr_3_channel

将这个函数应用到我们的图像,并绘制输出,我们可以看到结果图像显示正确,虽然现在它有 3 个通道。

使用 PyTorch

如果我们做的是深度学习,那么探索如何直接使用 PyTorch 进行这种转换可能会更有用,而不是使用 NumPy 作为中介。虽然我们可以在 PyTorch 张量上执行与上述类似的一系列步骤,但作为训练过程的一部分,我们可能希望在我们的图像上执行额外的变换,如 TorchVision 中定义的数据扩充操作。因为我们希望 3 通道转换发生在我们的增强管道的开始,并且一些后续的转换可能期望 PIL 图像,所以直接操纵张量可能不是这里的最佳方法。

令人欣慰的是,虽然有些违反直觉,但我们可以使用 TorchVision 中现有的灰度转换来完成这一转换!虽然这种变换需要 torch 张量或 PIL 图像,但我们希望这是我们管道中的第一步,所以我们在这里使用 PIL 图像。

默认情况下,这种转换将 RGB 图像转换为单通道灰度图像,但是我们可以通过使用num_output_channels参数来修改这种行为,如下所示。

现在,让我们看看如果我们把这个变换应用到灰度图像上会发生什么。

乍一看,虽然一切都变了,但看起来并不像。但是,我们可以通过检查 PIL 图像的通道和模式来确认转换已经按预期工作。

由于添加了额外的通道,我们可以看到 PIL 现在将该图像称为 RGB 图像;这正是我们想要的!

因此,通过这种方法,使用灰度图像的训练脚本所需的唯一修改是将该变换预先添加到增强管道中,如下所示。

修改预训练网络的第一卷积层

虽然如上所述,将单个通道图像扩展到 3 个通道是方便的,但是这样做的潜在缺点是需要额外的资源来存储和处理额外的通道;在这种情况下没有提供任何新的信息!

一种不同的方法是修改模型以适应不同的输入,在大多数情况下,这需要修改第一卷积层。虽然我们可以用一个新的层来替换整个层,但这将意味着丢弃模型的一些学习到的权重,除非我们冻结后续层并孤立地训练新层,这需要额外的努力,否则来自这些新的、随机初始化的权重的输出可能会负面地扰乱一些后面的层。

或者,回想卷积层中的每个滤波器都有单独的通道,我们可以沿通道轴将这些通道相加。下面我们来探讨一下如何做到这一点。我们将再次使用 PyTorch 图像模型中的 Resnet-RS50 模型。

首先,让我们创建我们的预训练模型:

正如我们所料,根据我们之前对滤镜和通道的探索,如果我们试图在开箱即用的单通道图像上使用此模型,我们会观察到以下错误。

让我们通过调整第一个卷积层的权重来解决这个问题。对于该模型,我们可以如下所示进行访问,但这将因所用模型而异!

首先,让我们更新这个层的in_channels属性来反映我们的变化。这实际上不会修改权重,但是会更新打印模型时看到的概述,并确保我们能够正确地保存和加载模型。

现在,让我们执行实际重量更新。我们可以使用sum方法做到这一点,确保将keepdim参数设置为True以保留维度。唯一需要注意的是,由于一个新的张量作为sum操作的结果被创建,我们必须将这个新的张量包装在nn.Parameter中;以便新的权重将被自动添加到模型的参数中。

现在,使用单通道图像的模型,我们可以看到正确的形状已经返回!

使用 timm

虽然我们可以在任何 PyTorch 模型上手动执行上述步骤,但 timm 已经包含了为我们执行这些步骤的功能!要以这种方式修改 timm 模型,我们可以在创建模型时使用in_chans参数,如下所示。

比较开源数据集上的性能

现在我们已经研究了两种方法,我们可以使用灰度图像与预训练的模型,你可能想知道使用哪一个;或者简单地在灰度图像上从头开始训练模型是否更好!

然而,由于可以使用的模型、优化器、调度器和训练策略的几乎无限的组合,以及数据集中的差异,为此确定通用规则是极其困难的;“最佳”方法可能会因您正在调查的特定任务而异!

尽管如此,为了大致了解这些方法的执行情况,我决定在三个开源数据集上训练我最喜欢的模型-优化器-调度器组合之一,以查看不同方法之间的比较。虽然改变培训政策可能会影响不同方法的表现,但为了简单起见,培训过程保持相对一致;基于我发现行之有效的实践。

实验设置

对于所有实验运行,以下保持一致:

  • 型号 : ResNet-RS50
  • 优化器 : AdamW
  • LR 调度器:余弦衰减
  • 数据扩充:图像尺寸调整为 224,训练时使用了水平翻转
  • 初始 LR : 0.001
  • 最大段数 : 60

所有训练都是使用单个 NVIDIA V100 GPU 进行的,批量大小为 32。为了处理训练循环,我使用了 PyTorch 加速库

使用的数据集有:

  • 豆子 :豆子是用智能手机相机在田间拍摄的豆子图像数据集。它包括 3 个类别,2 个疾病类别和健康类别。
  • 石头剪子布 (RPS) :双手玩石头剪子布游戏的画面。
  • 牛津宠物:37 类宠物数据集,每类大约有 200 张图片。

对于每个数据集,我探索了以下处理灰度图像的方法:

  • RGB :使用 RGB 图像作为基线,对模型进行微调。
  • 带有 3 个通道的灰度图像:灰度图像被转换为 3 个通道的格式。
  • 灰度 w/ 1 通道:模型的第一层被转换成接受单通道图像。

在与每种方法相关的地方,我使用了以下培训策略:

  • Finetune :使用预训练模型,首先训练模型的最后一层,然后解冻和训练整个模型。解冻后,学习率降低 10 倍。
  • 微调整个模型:训练整个预训练模型,不冻结任何层。
  • 从零开始:从零开始训练模型

下面提供了用于运行该实验的培训脚本,使用的包版本有:

  • PyTorch: 1.10.0
  • py torch-加速:0.1.22
  • timm: 0.5.4
  • 火炬度量:0.7.1
  • 熊猫

结果

这些运行的结果如下表所示。

从这些实验中,我的主要观察结果是:

  • 使用预先训练的模型,并使其适应灰度图像,似乎比从头开始训练更容易获得好的结果。
  • 对这些数据集的最佳方法似乎是修改图像中的通道数,而不是修改模型。

结论

希望这已经提供了一个合理的全面概述如何微调灰度图像上的预训练模型,以及理解为什么需要额外的考虑。

克里斯·休斯上了 领英

参考

使用的数据集

迁移学习:提升你的 ML 模型的秘密武器

原文:https://towardsdatascience.com/transfer-learning-the-secret-weapon-for-boosting-your-ml-models-2fc35c83709a

释放预训练模型的力量,提高性能,缩短训练时间

稳定扩散生成的图像

机器学习模型的开发涉及在大型(已标记)数据集上训练算法,这可能是耗时和资源密集型的。因此,我们需要一些技术,比如分布式培训或迁移学习,让我们能够更快地迭代,减少从研究到上市的时间。

迁移学习是机器学习中一种强大的技术,它允许您利用从解决一个问题中获得的知识,并将它应用到另一个相关的问题中。换句话说,迁移学习使您能够将知识从以前训练的模型“迁移”到新的模型,从而节省您从头训练模型所需的时间和资源。

近年来,迁移学习在机器学习社区变得越来越流行,这是有原因的。事实证明,它可以显著提高模型的性能,尤其是在处理小型数据集或希望针对特定任务对模型进行微调时。它还被证明可以显著减少培训时间,使其成为及时部署机器学习模型的组织的一个有吸引力的选择。

在本文中,我们将更详细地探讨迁移学习的概念。我们将介绍它在计算机视觉和 NLP 领域的基本工作原理,并看看如何使用 PyTorch 或 Keras 在自己的项目中实现它。

到本文结束时,你将会很好地理解迁移学习如何使你的 ML 项目受益,以及你如何利用它来达到更好的结果。

Learning Rate 是为那些对 AI 和 MLOps 的世界感到好奇的人准备的时事通讯。你会在每个月的第一个星期六收到我关于最新人工智能新闻和文章的更新和想法。订阅这里

计算机视觉中的迁移学习

迁移学习是一种强大的技术,可用于计算机视觉中,以提高机器学习模型的性能并减少训练时间。正如我们之前看到的,它涉及到使用从先前训练的模型中获得的知识,并将其应用于新的相关问题。

稳定扩散生成的图像

在计算机视觉的背景下,迁移学习可以用于在新的数据集上微调预训练的模型,或者使用较小的数据集训练新的模型。这在处理小型或专门的数据集时特别有用,在这种情况下,由于缺少数据,很难从头开始训练模型。

例如,假设您想要训练一个模型将动物图像分类到特定类别。你可以从使用预先训练好的图像分类模型开始,比如在 ImageNet 上训练的卷积神经网络(CNN ),作为你的基础。然后,您必须更改模型的输出图层,以符合数据集中的类别或标注。这允许您利用从预训练模型中获得的知识,并将其应用于您的特定问题。

或者,您可以使用较小的数据集,通过迁移学习来训练新模型。在这种情况下,您可以从一个预先训练好的模型开始,并将其作为新模型的起点。这允许您使用更少的数据点来训练模型,从而可能减少训练时间并允许您更快地部署模型。

自然语言处理中的迁移学习

迁移学习也广泛用于自然语言处理(NLP),这是一个专注于分析和解释人类语言的机器学习领域。在 NLP 中,迁移学习可以用来提高模型的性能并减少训练次数,类似于它在计算机视觉中的使用。

稳定扩散生成的图像

迁移学习在自然语言处理中的一个常见应用是语言建模。给定前面单词的上下文,语言模型用于预测单词序列中的下一个单词。这些模型通常在大型文本数据集上训练,如书籍或文章。当你训练这样一个模型时,你会得到一个非常理解人类语言的系统。

下一步是使这种模型的任务更加具体;例如,针对语言翻译、文本生成和文本摘要等任务对其进行微调。杰瑞米·霍华德等人在 NLP 的开创性论文中推广了这一技术:用于文本分类的通用语言模型微调

用 Pytorch 迁移学习

让我们看一个 PyTorch 使用迁移学习的例子。我们将在 CIFAR-10 数据集上训练一个简单的图像分类模型:

首先,我们将从安装 PyTorch 开始:

pip install torch
pip install torchvision

然后,下载 CIFAR-10 数据集:

import torch
import torchvision
import torchvision.transforms as transforms

train_dataset = torchvision.datasets.CIFAR10(
  root='.', train=True, download=True,
  transform=transforms.Compose([transforms.ToTensor()]))

接下来,我们将定义一个简单的卷积神经网络(CNN)作为我们的基础模型。我们将使用 torchvision 库中预训练的 VGG-16 模型作为基础模型,并在顶部添加几个额外的层用于分类:

import torch.nn as nn
import torch.optim as optim

class TransferLearningModel(nn.Module):
  def __init__(self, num_classes=10):
    super(TransferLearningModel, self).__init__()

    # Use a pre-trained VGG-16 model as the base
    self.base_model = torchvision.models.vgg16(
      weights=torchvision.models.VGG16_Weights.DEFAULT)

    # Replace the classifier layer with a new one
    self.base_model.classifier = nn.Sequential(
      nn.Linear(in_features=25088, out_features=4096, bias=True),
      nn.ReLU(inplace=True),
      nn.Dropout(p=0.5, inplace=False),
      nn.Linear(in_features=4096, out_features=4096, bias=True),
      nn.ReLU(inplace=True),
      nn.Dropout(p=0.5, inplace=False),
      nn.Linear(in_features=4096, out_features=num_classes, bias=True))

  def forward(self, x):
    return self.base_model(x)

model = TransferLearningModel()

然后,我们可以使用标准 PyTorch API 来定义用于训练和评估的损失函数、优化器和数据加载器:

# Define a loss function and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)
# Define a data loader for the training set
train_loader = torch.utils.data.DataLoader(
    train_dataset, batch_size=32, shuffle=True)

最后,我们可以使用标准 PyTorch 训练循环来训练模型:

# Train the model
for epoch in range(10):
  for inputs, labels in train_loader:
    # Clear the gradients
    optimizer.zero_grad()

    # Forward pass
    outputs = model(inputs)
    loss = criterion(outputs, labels)

    # Backward pass
    loss.backward()
    optimizer.step()

该训练循环训练 10 个时期的模型,其中时期是训练数据集的完整过程。在每个历元中,模型成批处理训练数据,使用优化器根据计算的梯度更新模型的权重。

使用 Keras 进行迁移学习

这是一个使用 Keras 和 TensorFlow 的迁移学习在 CIFAR-10 数据集上训练简单图像分类模型的示例。

首先,我们将从安装 TensorFlow 开始:

pip install tensorflow

然后,我们需要下载 CIFAR-10 数据集:

import tensorflow as tf

(X_train, y_train), (X_test, y_test) = tf.keras.datasets.cifar10.load_data()

接下来,我们将定义一个简单的卷积神经网络(CNN)作为我们的基础模型。我们将使用来自 Keras 应用程序库的预训练 VGG-16 模型作为基础模型,并在顶部添加几个额外的层用于分类:

# Load the VGG-16 model
base_model = tf.keras.applications.VGG16(weights='imagenet', include_top=False, input_shape=(32, 32, 3))
# Add a few layers on top of the base model
model = tf.keras.Sequential([
  base_model,
  tf.keras.layers.GlobalAveragePooling2D(),
  tf.keras.layers.Dense(1024, activation='relu'),
  tf.keras.layers.Dropout(0.5),
  tf.keras.layers.Dense(10, activation='softmax')])
# Freeze the base model's layers
for layer in base_model.layers:
  layer.trainable = False

然后,我们可以使用标准的 Keras API 来编译模型,并定义损失函数和优化器:

# Compile the model
model.compile(loss='sparse_categorical_crossentropy',
  optimizer='adam',
  metrics=['accuracy'])

最后,我们可以使用fit方法训练模型:

# Train the model
model.fit(X_train, y_train, epochs=10, batch_size=32)

这为 10 个时期训练模型,其中一个时期是训练数据集的一次完整通过。在每个历元中,模型成批处理训练数据,使用优化器根据计算的梯度更新模型的权重。

结论

总之,迁移学习是机器学习中的一项强大技术,它允许您利用从先前训练的模型中获得的知识,并将其应用于新的相关问题。事实证明,它可以显著提高模型的性能并减少训练时间,对于希望及时部署机器学习模型的组织来说,这是一个有吸引力的选择。

迁移学习在计算机视觉和自然语言处理(NLP)中被广泛用于各种任务,包括图像分类、对象检测、语言建模和文本生成。

在本文中,我们看到了什么是迁移学习,以及如何使用 PyTorch 或 Keras 实现迁移学习的应用。

关于作者

我叫迪米特里斯·波罗普洛斯,我是一名为阿里克托工作的机器学习工程师。我曾为欧洲委员会、欧盟统计局、国际货币基金组织、欧洲央行、经合组织和宜家等主要客户设计和实施过人工智能和软件解决方案。

如果你有兴趣阅读更多关于机器学习、深度学习、数据科学和数据运算的帖子,请在 Twitter 上关注我的 MediumLinkedIn@james2pl

所表达的观点仅代表我个人,并不代表我的雇主的观点或意见。

posted @ 2024-10-18 09:40  绝不原创的飞龙  阅读(195)  评论(0)    收藏  举报