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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

挖掘新冠肺炎·卡格尔竞赛科学论文以建立对病毒的理解

原文:https://towardsdatascience.com/building-an-understanding-of-viruses-by-mining-covid-19-scientific-corpus-bdd7427d6a8a?source=collection_archive---------61-----------------------

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

图片鸣谢:https://upload . wikimedia . org/Wikipedia/commons/thumb/8/82/新型冠状病毒 _ 无 _ 背景. png/1200 px-新型冠状病毒 _ 无 _ 背景. png

在新冠肺炎疫情,艾伦人工智能研究所(Allen Institute for AI)与白宫和其他各方合作,发表了一场关于 Kaggle 的比赛,他们为这场比赛准备了超过 16.7 万篇关于冠状病毒的科学论文(其中 79 万篇提供了全文)。伴随着数据,17 个任务被发布;组织者要求参赛者探索科学语料库,并回答关于各种冠状病毒(新冠肺炎、SARS、火星等)潜伏期的问题(以及其他许多问题)。)、传播的季节性、病毒的物理性质,如粘附在表面或病毒脱落、环境的作用等等(完整列表可在此处获得:https://www . ka ggle . com/Allen-institute-for-ai/CORD-19-research-challenge/tasks)。

方法

当我第一次开始考虑回答这些问题时,我认为某种问答引擎可能会很有趣:一个在语料库上训练的 ML 模型,当被问及以下问题时,它能够找到论文(和/或相关段落)的模式和聚类:使人对感染冠状病毒免疫的抗体水平是多少?病毒在空气中存活多久?各种冠状病毒的死亡率是多少?…

显然,当一个人想要分析一个文本语料库时,他需要一个 NLP(自然语言处理)工具。一种常见的方法是通过使用一些单词嵌入技术(word2vec 非常流行)来降低维度并提供语料库的密集单词表示,然后使用 LDA 进行主题挖掘(本质上是构建分段模型)。这里可以找到一种将这两种方法联系在一起的有趣方法:https://multithreaded . stitchfix . com/blog/2016/05/27/LDA 2 vec/# topic = 26&lambda = 0.86&term =

在这个系列中,我们将采取一种略有不同的方法:为了减少维度并提供更好的单词表示,我们将训练来自谷歌的 BERT(来自变压器的双向编码器表示)模型。一旦训练完成,我们将从模型中提取嵌入层来替代 word2vec。

由于我们正在使用深度学习模型,为了保持在同一领域内并相对容易地重用来自 BERT 的嵌入层,我们将在 PyTorch 中开发一个 SOM(自组织地图,也称为 Kohonen 网络),它将处理我们任务的无人监管部分——论文分割。

硬件

BERT base 有 1.1 亿个参数,在每一批提交给网络后都会进行调整,由于训练神经网络需要大量的矩阵计算,GPU 是一个显而易见的选择。虽然我通常使用 NVIDIA 的 Titan RTX (我非常喜欢这款硬件…),但我最近收到了一台联想的 ThinkPad P53 移动工作站机器进行测试,我对这台机器在我离开 Titan 时所做的事情感到非常惊讶…我不会提供这台机器的详细规格,只是说它可以配置 NVIDIA Quadro RTX 5000 w/16GB RAM,这对我们的目的来说应该足够了(更多详细规格,我将参考我最近的)

在软件栈方面,我们将使用 PyTorch、NVIDIA RAPIDS 和 Python 宇宙中的其他工具来帮助我们完成任务。

该系列

由于我们将从零开始训练 BERT,然后在 PyTorch 中从零开始构建 SOM,我认为将整个大故事分成一系列小故事比编写一个单一的整体文本更有意义。因此,下面是我如何看待这个系列的大纲(可能会有变化,因为有时我会忘乎所以,我可能需要进一步打破东西);我们将遵循构建任何机器学习模型的黄金流程:

  1. 在下一个故事中,我们将首先熟悉数据。我们还将看看需要多少清理工作;我在处理数据时的第一条规则是与“无罪推定”的方法截然相反的:在我检查数据之前,我从不相信它,尤其是如果有人告诉我它已经是干净的了;有罪直到被证明是无辜的!
  2. 一旦我们熟悉了数据(而且是干净的!)然后,我们将转到构建字典并准备用于训练的数据集:标记文本并准备标签;在这种方法中,我们将预测句子中被屏蔽的单词。
  3. 准备好训练(和测试)数据集后,在下一个故事中,我们将介绍如何训练和测试 BERT。
  4. 接下来是从训练好的模型中提取嵌入层,然后SOM 附加到嵌入层上,以构建我们的分割模型。
  5. 最后,我们将准备用于推理的模型,其中它应该用语料库中包含与所提问题相关的信息的段落列表进行回复。

敬请期待!

通过挖掘新冠肺炎科学语料库建立对病毒的理解

原文:https://towardsdatascience.com/building-an-understanding-of-viruses-by-mining-covid-19-scientific-corpus-f1d27c33b48?source=collection_archive---------42-----------------------

第 1 部分:熟悉数据

在我发表这篇文章的时候,我们正进入新冠肺炎冻结世界以来的第九个月。自 1 月初以来,我们都有不同的经历:我们中的一些人很幸运,被锁在自己的房子里,能够远程工作,过着相对不变的生活,我们中的一些人没有这样的奢侈,一些人不幸去世。

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

来源:https://unsplash.com/photos/EAgGqOiDDMg/download?force=true

冠状病毒已经存在了几十年,但迄今为止很少有像新冠肺炎病毒这样致命和容易传播的。今年早些时候,AI2 艾伦人工智能研究所(Allen Institute for AI)和一个由研究机构组成的联盟与白宫一起策划了一个自 19 世纪以来发表的关于冠状病毒的科学论文语料库,并提供了一个 Kaggle 竞赛来分析它并回答一些关于病毒不同方面的问题,如它如何传播,或它如何影响活的有机体。

虽然我没有直接参加挑战本身,这个系列试图通过建立深度学习 BERT-EM-SOM 模型(与自组织地图相关的 BERT 嵌入层)来更好地了解冠状病毒。正如在宣布这个系列的的帖子中提到的,在这一期中,我们将专注于理解论文的语料库,并将清理元数据,以便我们可以在一个干净的基础上工作。

数据

这些数据可以从几乎每天都在更新的 AI2 S3 数据库中下载。下面的代码片段下载数据并将其提取到数据目录中。

在本例中,我们使用 2020 年 8 月 24 日发布的数据集。阅读这一天的元数据显示,应该有 233,539 篇论文讨论冠状病毒相关的主题。我们将测试数据集是干净的这一假设,即所有 233,539 个数据集都在作为归档一部分的 JSON 文件中找到,我们没有任何重复项,也没有丢失信息。

但首先,让我们熟悉一下数据集的基础知识。

基础数据探索

在这个故事的剩余部分,我们将在使用 NVIDIA RAPIDS 的原生 cuDF 和使用 T2 BlazingSQL 的 SQL 之间进行常规切换。大部分时间我都在用泰坦 RTX 卡。然而,我很幸运仍然拥有租借的联想 P53 移动工作站和 NVIDIA Quadro RTX 5000 GPU ,所以当我最近和我的孩子露营时(适当地保持社交距离并戴上面具!)我仍然能够创作这个故事。这是另一款出色的硬件,我强烈推荐给所有想要在旅行或向客户或朋友展示工作时使用 RAPIDS、BlazingSQL 或 CUDA 的 GPU 爱好者。看看这个美女!

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

来源:联想,经许可使用

作为一个完整的披露——这篇文章不是由英伟达或联想赞助的,我也没有从他们那里得到报酬——我只是在测试他们借给我进行这项研究的设备。为此我非常感激!

这个故事和我其他故事中的所有代码都可以在 github 上找到。

metadata.csv 文件中有 19 列;下面是一个例子。

大多数列都是 id,比如 cord_uiddoi 等等。然而,对我们来说更有趣的是,我们将关注

  • 标题摘要作者我们将使用来查看是否有重复
  • 显示文章发表时间的
  • source_x 显示文章的来源
  • 期刊栏列出了发表文章的期刊
  • pdf_json_files 显示带有论文正文的文件的位置;我们将使用它来查看我们是否有任何丢失的文件,以便我们可以排除它们。

首先,让我们看看 AI2 研究人员收集这些文章的最常见来源是什么。

上面的代码片段简单地获取元数据 cuDF 数据帧,按 source_x 列分组,并打印出一个表。

因此,最常见的来源是世卫组织,其次是 Medline 和 PMC。接下来,我们将看到通过 Elsevier、MedRxiv、ArXiv 和 BioRxiv 发布的文章。这些将占语料库中所有论文的大部分。

顺便说一下,可以使用 BlazingSQL 用 SQL 创建相同的表。

这显示了 RAPIDS 生态系统的美妙之处:如果你熟悉 pandas 或 SQL,你就拥有了在数据上释放 GPU 巨大能力所需的所有工具,甚至不用多想(因为你没有时间…看这个:https://www . LinkedIn . com/posts/tome KD _ blazingsql-notebooks-private-preview-activity-6710308422451126272-wXCb!).

现在让我们来看看这些论文是在哪里发表的。

因此,许多文章都是在 bioRxiv 上预先发表的,但我们也在《BMJ》、《公共科学图书馆综合版》、《病毒学杂志》、《柳叶刀》和《自然》上看到了很多。换句话说,不出所料。

好吧,时间呢?让我们看看论文是什么时候发表的。

上面的代码片段生成了下面的图表。

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

来源:作者

有趣但并不令人意外的是,在 2002/2003 年左右发表的论文数量有所上升,因为这很可能与 SARS 疫情有关。

你可能想知道为什么我把 2020 年排除在外……好吧,我最初把它放在图表上,但它实际上是让其余时间序列的相形见绌。我认为下面的图表应该解释为什么。

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

来源:作者

自 1816 年至 2019 年(含),作为该语料库一部分发表和报告的论文总数约为 9 万篇。在 2020 年的近 9 个月里,全球研究人员发表了超过 14 万篇关于冠状病毒的论文和其他信息。因此,我决定,排除 2020 年的报告论文数将使上面的时间序列图更清晰。

清除

现在是我们查看数据本身的时候了。我喜欢对任何数据集首先做的是检查缺失的观察值。

遗漏的观察

每个数据集都有一些。这些可能是简单的遗漏或遥测问题(我们可以估算或删除它们),也可能是我所说的有效缺失值,即根本不应该存在的值。有效缺失观察的一个例子是,在这个特定的数据集中,以及当论文没有在 arxiv 上发表时的 arxiv_id

使用 SQL 创建一个包含丢失值百分比的表非常容易。我是这样做的。

代替解释这里发生了什么:我使用了在上面要点的第 3–7 行中创建的两个 SQL 查询。如果您将这些查询打印出来,它们将如下所示。

最终的 SQL 查询只是返回列的列表及其相应的缺失值百分比。

正如所料,许多 ID 列有许多遗漏的观察值,但是我们不会在后面的分析中用到这些,所以不要担心。然而,缺少 pdf_json_files 列几乎有 60%的值丢失……这绝对是一个问题,因为我们需要能够找到论文的主体。因此,我们应该删除这些遗漏的观察。

在上述操作之后,我们在语料库中得到大约 94,000 篇论文。重新运行前面的查询会产生以下每列缺失值百分比的细分。

我们仍然错过了一些标题、作者或摘要,但这没关系——这不应该妨碍我们的方法。更重要的是,我们可以找到这个文件,然后用 cord_uid 链接它,返回相关的文件。

复制

接下来,我们将把目光转向寻找重复,这是任何数据集的另一个常见问题(我还没有找到一个没有重复的原始数据集)。查询元数据表,我在每一列中得到如下数量的重复记录。

因此,在 pdf_json_files 栏中,我们有超过 1200 个重复的标题、282 个重复的摘要和 6 个重复的链接。让我们从那些开始。

查看上表,我们可以清楚地看出前 3 篇论文不是重复的——它们只是错误地指向同一个 json 文件。然而,剩下的文件肯定是重复的。因为本专栏总共只有 6 个重复项,所以我们将使用。来自 cuDF 的 dropna()功能。

接下来,让我们看看重复的标题。允许我们创建重复行的快速列表的查询如下所示,以及标题重复的前 10 条记录。

你可以看到,这些是真正的重复记录:不知何故,它们与 doi 标识符不同,但标题、摘要和作者大多匹配。但是,由于有超过 1200 个重复的记录,我们不想删除所有这些记录,将使用。drop_duplicated()方法从每个副本中保留一条记录。

数据文件夹中缺少 JSON 文件

最终检查:让我们看看是否真的可以在 data 文件夹中找到 metadata.csv 文件中列出的所有文件。为了尽可能提高效率,我们将采用的方法是列出data/2020–08–24/document _ parses/pdf _ JSON目录中的所有文件,从这些文件中创建一个 cuDF/BlazingSQL 表,然后将它们与我们已有的重复数据删除数据集连接起来。

因此,实际上非常令人惊讶的是,我们在 metadata.csv 文件中有链接到的 12.5k 文件,但在磁盘上找不到,还有存在于磁盘上但在 metadata.csv 文件中无法引用的 5k 文件。在这种情况下,我决定丢弃所有丢失的文件,从而只保留我在 metadata.csv 文件和磁盘上都能找到的 87,438 个文件。

有罪直到被证明无罪

这部分到此结束。正如我在本系列的介绍中提到的,我总是以怀疑的态度对待我得到的每个数据集,直到我向自己证明它足够干净,可以用于进行分析或构建 ML 或 DL 模型。

在下一期文章中,我们将着眼于从磁盘中读取文件,并使用来自 RAPIDS 的 subword_tokenizer 来标记文本,为第 3 部分中的 BERT 训练做准备。

此外,如果您想尝试本系列中介绍的任何代码,请访问 https://app.blazingsql.com/的并发布一个免费集群!

用 Kaggle 构建分析管道

原文:https://towardsdatascience.com/building-analysis-pipelines-with-kaggle-c745671d273e?source=collection_archive---------42-----------------------

不仅仅是竞争

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

卢克·切瑟在 Unsplash 上的照片

Kaggle 是最受欢迎的数据科学和机器学习入门网站之一。数据科学界的大多数人都使用过或者至少听说过它。Kaggle 是一个众所周知的举办机器学习竞赛的网站,虽然这是该平台的一大部分,但它可以做得更多。

今年有了新冠肺炎开放研究数据集(CORD-19) ,我有机会更加一致地使用这个平台。老实说,Jupyter 笔记本和基于 GUI 的开发并不是我的首选方法(Vim 对我来说已经足够好了)。但是在过去的几个月里,我对这个平台的能力印象深刻。本文概述了 Kaggle 笔记本、Kaggle API,并演示了一种构建自动化分析管道的方法。

笔记本电脑

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

Kaggle 笔记本

Kaggle Notebooks 是一个云托管的 Jupyter 笔记本环境。笔记本可以用 Python 或 r 构建。笔记本在 Docker 容器中执行,我们可以把它们看作一个逻辑包。笔记本可以包含数据分析项目的所有逻辑,也可以链接在一起构建模块化组件。笔记本可以公开共享,也可以保密。

笔记本电脑可以访问多个 CPU 内核和大量内存。另外还可以增加GPUTPU,可以加速深度学习模型的训练。对于一项免费服务来说,可用的资源是非常可观的。在一家大型云提供商上安装一台类似的主机是一笔相当大的成本。

笔记本使用几种不同的方法读取数据。主要途径是通过数据集。任何拥有帐户的人都可以上传数据并创建自己的数据集。Kaggle 上已经有大量公开的数据集。与笔记本电脑一样,数据集可以公开共享,也可以保密。笔记本可以有一个或多个数据集作为输入。此外,其他笔记本的输出可以用作输入,从而允许构建笔记本链。

创建新笔记本

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

Kaggle 笔记本副本

可以使用上图中显示的“新建笔记本”按钮创建空白笔记本。一旦创建了一个笔记本,就会有一个编辑器可以用来构建逻辑。本例将复制一个现有的笔记本,重点介绍运行笔记本的方法。

我们将使用 CORD-19 报表生成器笔记本。点击参考链接后,我们可以通过“复制和编辑”按钮复制笔记本。这将创建一个笔记本作为 <你的 Kaggle 用户名>/cord-19-report-builder。请注意,以下所有链接将显示大卫·梅泽蒂作为用户名,请替换为您的 Kaggle 用户名。

执行笔记本

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

Kaggle 笔记本编辑

复制笔记本会把我们带到编辑笔记本的界面。在该屏幕上,我们还可以添加/删除输入、修改设置以及保存/运行笔记本。

上面的示例显示了从另一个笔记本导入实用程序脚本。这是一个强大的功能,允许在笔记本之间共享功能,避免复制/粘贴样板代码。该示例有两个输入数据集和一个笔记本作为输入。

点击“保存版本”按钮将执行笔记本中的逻辑并保存一个新版本。有多种选择:

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

Kaggle 笔记本保存

如果在编辑时笔记本已经完全运行,“快速保存”工作良好。否则,应使用“保存并运行全部”。

Kaggle API

如果我们有几个笔记本,我们希望在添加额外的逻辑时偶尔更新,那么已经描述的内容通常就足够了。

对于更复杂的情况或频繁使用的情况,Kaggle 有一个全功能 Python API 可用。Kaggle API 可以通过 PyPi 获得:

pip install kaggle

API 有关于如何设置授权和创建访问密钥以启用使用的文档。一旦设置了 API,下面显示了一个通过 API 运行笔记本的简单示例:

kaggle kernels pull *davidmezzetti*/cord-19-report-builder -p cord-19-report-builder -mkaggle kernels push -p cord-19-report-builder

这运行两个命令。第一个是提取 cord-19-report-builder 笔记本,将它和它的元数据存储在一个名为 cord-19-report-builder 的目录中。第二个运行笔记本。

一旦运行了上面的命令,我们就可以到 Kaggle 来监控作业的进度。下图显示了版本屏幕,从中我们可以看到笔记本电脑的新版本正在运行。点击版本文本(在右上角突出显示)即可调出该屏幕。

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

Kaggle 笔记本新版本

自动化管道

Kaggle API 功能强大,允许在主 web 界面之外运行笔记本(以及许多其他功能)。可以围绕它构建脚本,以支持更复杂的功能以及与外部流程的交互。

有了 CORD-19 数据集,支持这项工作的笔记本电脑数量增加到了 10 多台,每次有新数据进来时都需要刷新。最重要的是,数据集移动到了每天更新的程度,笔记本电脑相互依赖(即一个需要在另一个运行之前运行)。

对于这个用例,完全自动化显然是必要的。为了实现自动化管道,NeuML 创建了 kernelpipes 项目

内核管道可以通过 pip 安装:

pip install git+https://github.com/neuml/kernelpipes

kernelpipes 使用 Kaggle API 顺序或并行执行一系列笔记本。可以添加检查,以便仅在更新了源时才允许运行管道。此外,管道有一个内置的 cron 调度特性来支持连续执行。下面是 YAML 的一个简单管道例子。

# Pipeline name                       
name: pipeline# Pipeline execution steps
steps:
  - kernel: *davidmezzetti*/cord-19-report-builder                       
  - status: 2.5m

假设上述内容保存在名为 pipeline.yml 的文件中,它可以如下运行:

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

pipeline.yml 执行

这个简单的管道每 2.5 分钟执行一次记事本并检查完成状态。一旦内核完成,进程将退出。

基本管道配置

名字

name: <pipeline name>

必填字段,命名管道

日程安排

schedule: cron string

允许通过调度程序运行作业的可选字段。根据偏好,可以使用 System cron 来代替它。与系统 cron 相比,内部调度程序的一个优点是,在前一个作业正在运行时,不会产生新的作业。例如,如果某个作业计划每小时运行一次,而一次运行需要 1.5 小时,它将跳过第二次运行,并在第三个小时重新开始。

步伐

支票

check: /kaggle/dataset/path

允许根据数据集更新状态有条件地运行管道。检索数据集元数据,并将最新版本与上次运行的版本进行比较,仅当数据集已更新时才允许处理继续进行。如果数据集没有本地元数据,将继续运行。

核心

kernel: /kaggle/kernel/path

返回在/kaggle/kernel/path 指定的内核

状态

status: <seconds|s|m|h>

在指定的持续时间内检查前面内核步骤的状态。

持续时间示例:10 代表 10 秒,30 代表 30 秒,1 代表 1 分钟,1 代表 1 小时。

更复杂的例子

为了给出一个复杂用例的概念,下面是一个用于处理 CORD-19 数据集的完整管道。

# Pipeline name
name: CORD-19 Pipeline# Schedule job to run @ 12am, 10am, 3pm local time
schedule: "0 0,10,15 * * *"# Pipeline execution steps
steps:
  - check: allen-institute-for-ai/CORD-19-research-challenge
  - kernel: davidmezzetti/cord-19-article-entry-dates
  - status: 1m
  - kernel: davidmezzetti/cord-19-analysis-with-sentence-embeddings
  - status: 15m
  - kernel: davidmezzetti/cord-19-population
  - kernel: davidmezzetti/cord-19-relevant-factors
  - kernel: davidmezzetti/cord-19-patient-descriptions
  - kernel: davidmezzetti/cord-19-models-and-open-questions
  - kernel: davidmezzetti/cord-19-materials
  - kernel: davidmezzetti/cord-19-diagnostics
  - kernel: davidmezzetti/cord-19-therapeutics
  - kernel: davidmezzetti/cord-19-risk-factors
  - status: 2.5m
  - kernel: davidmezzetti/cord-19-task-csv-exports
  - kernel: davidmezzetti/cord-19-study-metadata-export
  - kernel: davidmezzetti/cord-19-most-influential-papers
  - kernel: davidmezzetti/cord-19-report-builder
  - kernel: davidmezzetti/cord-19-forecasting-articles
  - kernel: davidmezzetti/cord-19-mice-trials
  - kernel: davidmezzetti/cord-19-bcg-vaccine
  - kernel: davidmezzetti/cord-19-digital-contact-tracing-privacy
  - status: 2.5m

上面的例子一天运行 3 次。在执行之前,它将数据集的版本与前一次运行的版本进行比较,如果没有变化,则该过程退出。否则,笔记本会一直启动到状态步骤。此时,kernelpipes 将等待所有笔记本完成后再继续。

在上面的配置中,cord-19-article-entry-dates 开始,kernelpipes 将每分钟检查一次,直到完成,然后启动 cord-19-analysis 笔记本,每 15 分钟检查一次完成情况。一旦完成,下一个系列的笔记本会并行启动,kernelpipes 会等待所有操作完成,以此类推。

每次 CORD-19 数据集更新时,该管道都会刷新,无需任何用户操作。它有效地使一系列“活”笔记本随着新的新冠肺炎文章的增加而不断更新。

结论

Kaggle 平台在许多不同的领域带来了很多东西,本文只是触及了表面(微型课程看起来也很棒)。总的来说,我对这套功能印象非常深刻,并且能够设计一个复杂的全自动数据分析管道。将来用 Kaggle 构建时,请记住这些特性!

使用 Flask、SQLAlchemy 和 Heroku 构建和部署登录系统后端

原文:https://towardsdatascience.com/building-and-deploying-a-login-system-backend-using-flask-sqlalchemy-and-heroku-8b2aa6cc9ec3?source=collection_archive---------16-----------------------

有了 Heroku Postgres 数据库

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

作者图片

现在几乎所有的网站都有登录系统,如果你是新用户,你可以注册,如果你是现有用户,你可以登录。如果您试图为您的应用程序从头开始构建这个系统,可能会有许多移动的部分。本文给出了为登录系统创建和部署 REST API 的逐步概述,但一般来说,它可以扩展到任何 REST API。

与本文相关的所有代码都可以在下面的 repo 中找到:

[## aakanksha-ns/flask-heroku-log in

用 Flask 编写的 API 使用 Heroku Postgres 数据库注册用户并登录帐户。部署在 Heroku …

github.com](https://github.com/aakanksha-ns/flask-heroku-login)

1)创建一个 Heroku 账户并创建一个新的应用程序

你需要做的第一件事是在 Heroku 上创建一个账户,如果你还没有的话。

登录您的帐户,选择Create new app选项创建一个新的 Heroku 应用程序。

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

仪表板->新建->创建新应用程序(按作者分类的图片)

2)将 Heroku Postgres 添加到应用程序

现在您需要将 Postgres 添加到应用程序中。导航到您刚刚创建的应用程序页面,选择Configure Add-ons选项,搜索Postgres并提供它。

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

仪表板->“您的应用程序”->配置附加组件(图片由作者提供)

3)安装 Heroku CLI、PostgreSQL 和 PopSQL

Heroku CLI

为了能够从命令行与 Heroku 交互,您必须使用以下命令安装 Heroku CLI(假设您已经安装了 Homebrew ):

$ brew tap heroku/brew && brew install heroku

PostgreSQL 和 PopSQL

**为什么我们需要它们:**你可以从你的 Flask 应用程序中创建你的数据库表。然而,在我的实现中,我使用 PostgreSQL 在本地创建了数据库和表,并将其推送到 Heroku,因为我发现与 SQLAlachemy 相比,使用普通的 SQL 编辑器(我使用了 PopSQL)创建表更简单。我只使用 Flask 和 SQLAlchemy 向数据库添加元素或从中检索元素。

安装 Postgres : brew install postgres

启动 PostgreSQL 服务器:

创建数据库和用户: Postgres 设置了一组默认用户,但他们是超级用户帐户——他们可以做任何事情,包括删除数据库。最好创建只能访问特定数据库的新用户:

$ psql postgresCREATE ROLE aakanksha WITH LOGIN PASSWORD ‘blah’;
CREATE DATABASE bookstore;
GRANT ALL PRIVILEGES ON DATABASE bookstore TO aakanksha;

安装 PopSQL: PopSQL 是一款非常流行且易于使用的 SQL 编辑器。从https://popsql.com/下载应用程序并安装。

**将 PopSQL 连接到数据库:**您必须提供类似port number (postgres 默认使用 5432)、database name等细节。为了让 PopSQL 能够访问您的 PostgreSQL 数据库。您只需输入以下详细信息:

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

(图片由作者提供)

4)创建表并将数据库推送到 Heroku

在 PopSQL 草稿栏上创建表:

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

只有在创建时出现错误时,才执行“删除表格”命令

推到 Heroku:

$ heroku pg:push bookstore DATABASE --app example-app-medium

5)安装所需的库

既然数据库已经设置好了,我们可以继续 API 部分了。确保安装了所有必需的库。您可以将我使用过的以下库列表存储到一个文本文件(requirements.txt)中,并执行它后面的命令:

certifi==2020.4.5.1
click==7.1.1
Flask==1.1.2
flask-heroku==0.1.9
Flask-SQLAlchemy==2.4.1
itsdangerous==1.1.0
Jinja2==2.11.1
MarkupSafe==1.1.1
psycopg2==2.8.5
SQLAlchemy==1.3.16
Werkzeug==1.0.1
gunicorn==19.5.0
flask_cors

pip install -r requirements.txt

6)设置环境变量以访问 Heroku 数据库

因为您必须通过 flask 应用程序访问 Heroku 上的远程数据库,所以要建立到它的连接,您需要数据库 URL。因为远程数据库的 URL 可能由于许多原因而改变,所以最好的做法是在应用程序启动时总是从相应的 Heroku 应用程序获取数据库 URL 配置变量。您可以通过设置环境变量来实现这一点。

因为这个 URL 是特定于一个特定项目的,而这个项目被限制在一个特定的目录中,所以把它添加到全局环境变量中是没有意义的。这就是 direnv 的用武之地。这是一个环境切换器,允许根据当前工作目录加载/卸载环境变量。

要为 Flask 应用程序设置变量,您必须将以下命令添加到名为.envrc的新文件中,并将其放在项目的根目录下:

export DATABASE_URL=$(heroku config:get DATABASE_URL -a example-app-medium)

创建.envrc文件后,运行$ direnv allow激活变量。

5)设置烧瓶应用程序配置

下面是您在根目录下的config.py文件中需要的一些基本配置:

import osclass Config(object):SQLALCHEMY_TRACK_MODIFICATIONS = True
SECRET_KEY = os.urandom(24)
SQLALCHEMY_DATABASE_URI = os.environ['DATABASE_URL']

6)设置 application.py 和 app 目录

以下是我的文件夹结构:

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

(图片由作者提供)

默认情况下,Flask 将一个应用命名为“应用”,所以你需要一个application.py文件来运行这个应用。如果您愿意,您可以更改应用程序的名称(使用$ export FLASK_APP = ‘your file name'.py)

我喜欢把所有与 Flask 相关的代码放在一个叫做app的子目录中,而不是放在根目录下。

我的[application.py](https://github.com/aakanksha-ns/flask-heroku-login/blob/master/application.py)长得像:

from app import application

在 app 子目录中,有我的[__init__.py](https://github.com/aakanksha-ns/flask-heroku-login/blob/master/app/__init__.py)(将磁盘上的目录标记为 Python 包目录的初始化脚本):

from flask import Flask
from config import Config
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import create_engine# Initialization
application = Flask(__name__)
application.config.from_object(Config)DB_URI = application.config['SQLALCHEMY_DATABASE_URI']
engine = create_engine(DB_URI)from app import routes

API 代码位于routes.py文件中。

7)创建 API 并在本地测试

要查看完整的routes.py代码,请点击以下链接:

https://github . com/aakanksha-ns/flask-heroku-log in/blob/master/app/routes . py

对于登录系统,您需要两种方法:

注册

该方法在account表中为新用户创建一个条目。您可以进行额外的检查,以确保usernameemail不在表格中。

因为出于安全考虑,将原始密码存储在数据库中是不安全的,所以您可以使用[werkzeug](https://techmonger.github.io/4/secure-passwords-werkzeug/)库生成一个密码散列,并存储该散列而不是真正的密码。

签到

这个方法只是检查输入的密码是否与给定用户名的原始密码匹配

完成后,您可以使用$ flask run启动 flask 服务器,并使用 Postman 测试您的 API:

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

(图片由作者提供)

8)创建过程文件

Procfile 是一种机制,用于声明 Heroku 平台上应用程序的 dynos 运行哪些命令。

您可以使用[gunicorn](https://vsupalov.com/what-is-gunicorn/)来运行您的 web 应用程序的多个实例,确保它们是健康的,并根据需要重新启动它们,在这些实例之间分配传入的请求,并与 web 服务器通信。

web: gunicorn application:application

9)将代码推送到 Github Repo,将 Repo 连接到 Heroku app

要部署您刚刚创建的 API,最简单的方法是将您的代码推送到 Github repository,并将这个 repo 连接到您的 Heroku 应用程序:

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

(图片由作者提供)

9)部署 Flask 应用

您可以设置自动部署或从 Heroku 仪表板手动部署 Flask 应用程序。如果在部署过程中有任何错误,它们将显示在构建日志中。部署完成后,您可以使用 Postman 点击 API,并看到它按预期工作。如果部署后出现错误,您可以这样查看日志:

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

(图片由作者提供)

10)创建用户界面

如果您有兴趣为您的登录系统创建一个前端,您可以查看我的基于 React 和 Redux 的 UI:

[## aakanksha-ns/书店

这个项目是用 Create React App 引导的。在项目目录中,您可以运行:在…中运行应用程序

github.com](https://github.com/aakanksha-ns/book-store)

下面是我已经构建的应用程序的一些截图:

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

(图片由作者提供)

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

(图片由作者提供)

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

(图片由作者提供)

参考资料:

构建和部署字母识别系统

原文:https://towardsdatascience.com/building-and-deploying-an-alphabet-recognition-system-7ab59654c676?source=collection_archive---------14-----------------------

使用 Anvil 将卷积神经网络(CNN)模型部署到网站中

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

部署后

在本文中,我将向您展示如何使用卷积神经网络(CNN)构建一个字母识别系统,并使用 nvil.works 部署它。在这篇文章的最后,你将能够创建一个如上所示的系统的精确复制品。

目录

卷积神经网络

CNN 实施

砧座集成

卷积神经网络

我们先来了解一下卷积神经网络到底是什么。卷积神经网络(CNN)是一种广泛用于图像识别和分类的神经网络。

CNN 是多层感知器的规则版本。多层感知器通常意味着全连接网络,即一层中的每个神经元都与下一层中的所有神经元相连。

CNN 由以下几层组成:

**卷积层:*一个大小为 3×3 或 5×5 的“内核”通过图像,并计算原始像素值与内核中定义的权重的点积。然后,该矩阵通过激活函数“ReLu”*,该函数将矩阵中的每个负值转换为零。

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

Shervine Amidi 解释卷积层操作的图像

汇集层:一个大小的“汇集矩阵”例如 2X2 或 4X4,经过矩阵以减小矩阵的大小,从而仅突出图像的重要特征。**

有两种类型的池操作:

  1. 最大汇集 是一种汇集类型,其中汇集矩阵中存在的最大值被放入最终矩阵中。
  2. 平均池是一种池,计算池内核中所有值的平均值,并放入最终矩阵中。

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

通过堆栈溢出解释最大和平均池的图像

(注意:在 CNN 架构中可以有多个卷积和池层的组合来提高其性能。)

****全连通层:最后的矩阵再展平成一个一维向量。这个向量然后被传递到神经网络中。最后,输出层是附加到图像的不同可能标签的概率列表(例如,字母 a、b、c)。获得最高概率的标签是分类决策。

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

Shervine Amidi 显示全连接层的图像

CNN 实现

让我们从导入 Jupyter 笔记本中的库开始实现,如下所示:

***import** **numpy** **as** **np**
**import** **matplotlib.pyplot** **as** **plt**
**from** **keras.preprocessing.image** **import** ImageDataGenerator
**from** **keras.preprocessing** **import** image
**import** **keras**
**from** **keras.models** **import** Sequential
**from** **keras.layers** **import** Conv2D, MaxPooling2D, Flatten, Dense, Activation
**import** **os**
**import** **pickle***

然后,让我们导入包含从 az 的图像的 2 个数据集,用于训练和测试我们的模型。你可以从下面链接的我的 GitHub 库下载数据集。

*train_datagen = ImageDataGenerator(rescale = 1./255,
                                   shear_range = 0.2,
                                   zoom_range = 0.2,
                                   horizontal_flip = **True**)

test_datagen = ImageDataGenerator(rescale = 1./255)

train_generator = train_datagen.flow_from_directory(
    directory = 'Training',
    target_size = (32,32),
    batch_size = 32,
    class_mode = 'categorical'

)

test_generator = test_datagen.flow_from_directory(
    directory = 'Testing',
    target_size = (32,32),
    batch_size = 32,
    class_mode = 'categorical'

)*

ImageDataGenerator 生成批量的张量图像数据,通过使用 rescale 以 1/255 的因子进行缩放,将 0–255 范围内的 RGB 系数转换为 0 到 1 之间的目标值。

剪切范围用于随机应用剪切变换

zoom_range 用于图片内部随机缩放。

水平翻转用于随机水平翻转一半图像。

然后我们使用从目录中一个接一个地导入图像。flow_from_directory* 并对其应用 ImageDataGenerator。***

然后,我们将图像从其原始大小转换为我们的 target_size ,并声明 batch_size count,其中表示一次迭代中使用的训练样本的数量。

然后,我们将 class_mode 设置为分类,表示我们有多个类(a 到 z)要预测。

接下来,我们建立我们的 CNN 架构。

*model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape = (32,32,3), activation = 'relu'))
model.add(MaxPooling2D(pool_size = (2, 2)))

model.add(Conv2D(32, (3, 3), activation = 'relu'))
model.add(MaxPooling2D(pool_size = (2, 2)))

model.add(Flatten())
model.add(Dense(units = 128, activation = 'relu'))
model.add(Dense(units = 26, activation = 'softmax'))

model.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])

model.summary()*

我们首先创建一个顺序模型,允许我们使用逐层定义 CNN 架构。增加功能。**

我们首先在输入图像上添加一个带有 32 个大小为 3X3 的过滤器的卷积层*,并将其通过“relu”激活函数。***

然后,我们使用大小为 2X2 的池执行 MaxPooling 操作。

然后再次重复这些层,以提高模型的性能。

最后我们展平我们的合成矩阵,并将其通过由 128 个节点组成的密集层。然后连接到由 26 个节点组成的输出层,每个节点代表一个字母表。我们使用 softmax 激活将分数转换为归一化的概率分布,具有最高概率的节点被选为输出。**

一旦我们的 CNN 架构被定义,我们使用 adam optimizer 编译模型。

最后,我们训练我们的模型如下。

*model.fit_generator(train_generator,
                         steps_per_epoch = 16,
                         epochs = 3,
                         validation_data = test_generator,
                         validation_steps = 16)*

模型训练后达到的准确率为:93.42%

现在让我们试着测试我们的模型。但在此之前,我们需要定义一个函数,该函数为我们提供与结果相关联的字母表。

***def** get_result(result):
    **if** result[0][0] == 1:
        **return**('a')
    **elif** result[0][1] == 1:
        **return** ('b')
    **elif** result[0][2] == 1:
        **return** ('c')
    **elif** result[0][3] == 1:
        **return** ('d')
    **elif** result[0][4] == 1:
        **return** ('e')
    **elif** result[0][5] == 1:
        **return** ('f')
    **elif** result[0][6] == 1:
        **return** ('g')
    **elif** result[0][7] == 1:
        **return** ('h')
    **elif** result[0][8] == 1:
        **return** ('i')
    **elif** result[0][9] == 1:
        **return** ('j')
    **elif** result[0][10] == 1:
        **return** ('k')
    **elif** result[0][11] == 1:
        **return** ('l')
    **elif** result[0][12] == 1:
        **return** ('m')
    **elif** result[0][13] == 1:
        **return** ('n')
    **elif** result[0][14] == 1:
        **return** ('o')
    **elif** result[0][15] == 1:
        **return** ('p')
    **elif** result[0][16] == 1:
        **return** ('q')
    **elif** result[0][17] == 1:
        **return** ('r')
    **elif** result[0][18] == 1:
        **return** ('s')
    **elif** result[0][19] == 1:
        **return** ('t')
    **elif** result[0][20] == 1:
        **return** ('u')
    **elif** result[0][21] == 1:
        **return** ('v')
    **elif** result[0][22] == 1:
        **return** ('w')
    **elif** result[0][23] == 1:
        **return** ('x')
    **elif** result[0][24] == 1:
        **return** ('y')
    **elif** result[0][25] == 1:
        **return** ('z')*

最后,让我们按如下方式测试我们的模型:

*filename = r'Testing\e\25.png'
test_image = image.load_img(filename, target_size = (32,32))
plt.imshow(test_image)
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis = 0)
result = model.predict(test_image)
result = get_result(result)
print ('Predicted Alphabet is: **{}**'.format(result))*

该模型正确预测输入图像字母为‘e’。

砧座整合

Anvil 是一个允许我们用 python 构建全栈 web 应用的平台。它让我们更容易将机器学习模型从 Jupyter 笔记本变成 web 应用程序。

让我们从在 anvil 上创建一个帐户开始。完成后,用材料设计创建一个新的空白应用程序。

点击此链接,了解如何使用 anvil 的分步指南。

右边的工具箱包含了所有可以拖动到网站上的组件。

所需组件:

  1. 2 个标签(标题和副标题)
  2. 图像(显示输入图像)
  3. 文件加载器(上传输入图像)
  4. 突出显示的按钮(预测结果)
  5. 标签(查看结果)

拖放这些组件,并根据您的要求进行排列。

为了添加标题和副标题,选择标签并在右侧的属性部分,转到名为“文本”的选项,如下所示(以红色突出显示),并键入标题/副标题。

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

完成用户界面后,进入如上所示的代码部分(以绿色突出显示),并创建一个新函数,如下所示

*def primary_color_1_click(self, **event_args):
      file = self.file_loader_1.file
      self.image_1.source = file
      result = anvil.server.call('model_run',file)
      self.label_3.text = result
      pass*

当我们按下预测按钮时,该功能将执行。它将从文件加载器上传输入图像,并将其传递给 jupyter 笔记本的“model_run”功能。该函数将返回通过标签组件(label_3)显示的预测字母表。

现在剩下要做的就是将我们的 anvil 网站连接到 jupyter 笔记本上。

这需要实施如下两个步骤:

  1. 导入 Anvil 上行密钥:点击设置按钮然后点击上行,点击启用上行密钥并复制密钥。

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

在您的 jupyter 笔记本中粘贴以下内容:

***import** **anvil.server**
**import** **anvil.media**
anvil.server.connect("paste your anvil uplink key here")*

2.创建一个函数“模型运行”,预测网站上传的图像。

*@anvil.server.callable
**def** model_run(path):
    **with** anvil.media.TempFile(path) **as** filename:
        test_image = image.load_img(filename, target_size = (32,32))
        test_image = image.img_to_array(test_image)
        test_image = np.expand_dims(test_image, axis = 0)
        result = model.predict(test_image)
        result = get_result(result)
        **return** ('Predicted Alphabet is: **{}**'.format(result))*

而且,是的!!!!现在你可以回到 anvil,点击运行按钮,发现一个完全完成的字母识别系统。

您可以在我的 GitHub 资源库中找到源代码和数据集。

*** [## sakshibutala/CNN _ 字母识别

该算法与 anvil 网站集成,anvil 网站识别给定输入图像中存在的字母表。…

github.com](https://github.com/sakshibutala/CNN_AlphabetRecognition)

参考

[## 卷积神经网络教程:从基础到高级- MissingLink.ai

卷积神经网络卷积神经网络架构是深度学习的核心,它是…

missinglink.ai](https://missinglink.ai/guides/convolutional-neural-networks/convolutional-neural-network-tutorial-basic-advanced/) [## CS 230 -卷积神经网络说明书

你想看看你母语的备忘单吗?可以在 GitHub 上帮我们翻译一下!卷积…

stanford.edu](https://stanford.edu/~shervine/teaching/cs-230/cheatsheet-convolutional-neural-networks) [## Keras 文档:图像数据预处理

从目录中的图像文件生成 tf.data.Dataset。如果您的目录结构是:然后调用…

keras.io](https://keras.io/api/preprocessing/image/)***

构建和部署端到端假新闻分类器

原文:https://towardsdatascience.com/building-and-deploying-end-to-end-fake-news-classifier-caebe45bd30?source=collection_archive---------59-----------------------

变更数据

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

罗马克拉夫特在 Unsplash 拍摄的照片

在这个智能手机和互联网的数字时代,假新闻像野火一样传播,它看起来就像真新闻,对社会造成了很大的损害。因此,在本教程中,我们将构建一个假新闻分类器,并将其作为一个 web 应用程序部署在云上,以便任何人都可以访问它。它不会像谷歌或 facebook 的假新闻分类器那样好,但根据从 Kaggle 获得的数据集,它会相当不错。

在我们开始之前,为了让你有动力,让我向你展示一下在本教程结束时你将能够构建的 web 应用程序 假新闻分类器 **。**现在你已经看到了最终产品,让我们开始吧。

:我假设你熟悉基本的机器学习技术、算法和软件包。

我将本教程分为三个部分:

  1. 探索性数据分析
  2. 预处理和模型训练
  3. 在 Heroku 上构建和部署 Web 应用程序

现在,如果您是初学者,我建议您安装 Anaconda 发行版,因为它附带了数据科学所需的所有软件包,并设置了一个虚拟环境。

如果你想跟随这个教程,这里是我的 GitHub 上的源代码链接:https://github.com/eaofficial/fake-news-classifier

你可以在这里获得数据集或者你可以克隆我的 GitHub 库。

1.探索性数据分析

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

照片由元素 5 数码Unsplash 上拍摄

在项目目录中创建一个名为 eda.ipynb 或 eda.py 的文件。

我们将首先导入所有需要的包。

**#Importing all the libraries*
**import** **warnings**
warnings.filterwarnings('ignore')
**import** **numpy** **as** **np**
**import** **pandas** **as** **pd**
**import** **matplotlib.pyplot** **as** **plt**
**import** **seaborn** **as** **sns**
**import** **nltk**
**import** **re**
**from** **wordcloud** **import** WordCloud
**import** **os***

现在,我们将首先使用pd.read_csv()读取假新闻数据集,然后我们将探索该数据集。

在上述笔记本的单元格 4 中,我们统计了每个主题中的样本假新闻的数量。我们还将使用 seaborn count plot sns.coountplot()绘制其分布图。

我们现在将绘制一个词云,首先将所有新闻连接成一个字符串,然后生成标记并删除停用词。文字云是一种非常好的可视化文本数据的方式。

正如您在下一个单元格中看到的,现在我们将 true.csv 作为真实新闻数据集导入,并执行与我们在 fake.csv 上执行的步骤相同的步骤。您会注意到真实新闻数据集中的一个不同之处是,在列中,有一个出版物名称,如 WASHINGTON (Reuters) ,由连字符(-)分隔。**

看起来真实的新闻是可信的,因为它来自一家出版社,所以我们将从新闻部分中分离出出版物,以使本教程的预处理部分中的数据集一致。现在,我们将只探索数据集。

如果您继续下去,可以看到新闻主题列在真实和虚假新闻数据集中的分布是不均匀的,所以我们稍后将删除该列。我们的 EDA 到此结束。

现在我们可以用你们期待已久的东西弄脏我们的手了。我知道这部分令人沮丧,但 EDA 和预处理是任何数据科学生命周期中最重要的部分

2.预处理和模型训练

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

卡洛斯·穆扎Unsplash 上的照片

在这一部分中,我们将对我们的数据执行一些预处理步骤,并使用之前从 EDA 中获得的见解来训练我们的模型。

预处理

要按照本部分中的代码操作,请打开 train ipynb 文件。所以,不再多说,让我们开始吧。

像往常一样导入所有的包并读取数据。我们将首先从真实数据文本栏中删除路透社。由于有些行没有路透社,所以我们将首先获得这些指数。

从文本中删除路透社或推特信息

  • 文本只能在“—”处拆分一次,它总是出现在提及出版物来源之后,这给了我们出版物部分和文本部分
  • 如果我们没有得到文本部分,这意味着没有给出该记录的出版细节
  • Twitter 上的推文总是有相同的来源,一个最长 259 个字符的长文本
***#First Creating list of index that do not have publication part*
unknown_publishers = []
**for** index,row **in** enumerate(real.text.values):
    **try**:
        record = row.split(" -", maxsplit=1)
        *#if no text part is present, following will give error*
        record[1]
        *#if len of publication part is greater than 260*
        *#following will give error, ensuring no text having "-" in between is counted*
        **assert**(len(record[0]) < 260)
    **except**:
        unknown_publishers.append(index)**

用一行代码总结一下,上面的代码所做的是获取真实数据集中不存在发布者的 text 列的索引。

现在我们将把路透社从文本栏中分离出来。

***# separating publishers from the news text*
publisher = []
tmp_text = []
for index,row **in** enumerate(real.text.values):
    if index **in** unknown_publishers:
        *#add text to tmp_text and "unknown" to publisher*
        tmp_text.append(row)

        publisher.append("Unknown")
        continue
    record = row.split(" -", maxsplit=1)
    publisher.append(record[0])
    tmp_text.append(record[1])**

在上面的代码中,我们遍历 text 列并检查 index 是否属于,如果是,那么我们将文本添加到 publishers 列表中。否则,我们将文本分为出版商和新闻文本,并添加到各自的列表中。

***#Replace existing text column with new text*
*#add seperate column for publication info*
real["publisher"] = publisher
real["text"] = tmp_text**

上面的代码非常简单明了,我们添加了一个新的 publisher 列,并用不带 Reuter 的新闻文本替换了 text 列。

我们现在将检查真实和虚假新闻数据集中的文本列中是否有任何缺失值,并删除该行。

如果我们检查假新闻数据集,我们会看到有许多行缺少文本值,整个新闻都出现在title列中,因此我们将合并titletext列。

**real['text'] = real['text'] + " " + real['title']
fake['text'] = fake['text'] + " " + fake['title']**

接下来,我们将向数据集添加类,删除不必要的列,并将数据合并为一个。

***# Adding class info* 
real['class'] = 1 
fake['class'] = 0*# Subject is diffrent for real and fake thus dropping it* *# Also dropping Date, title and Publication* real.drop(["subject", "date","title",  "publisher"], axis=1, inplace=**True**) fake.drop(["subject", "date", "title"], axis=1, inplace=**True**)*#Combining both into new dataframe* data = real.append(fake, ignore_index=**True**)**

删除停用字词、标点符号和单字符字词。(在任何 NLP 项目中非常常见和基本的任务)。

模特培训

矢量化:Word2Vec

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

尼克·莫瑞森在 Unsplash 拍摄的照片

Word2Vec 是使用浅层神经网络学习单词嵌入的最流行的技术之一。它是由托马斯·米科洛夫于 2013 年在谷歌开发的。单词嵌入是最流行的文档词汇表示。它能够捕捉文档中单词的上下文、语义和句法相似性、与其他单词的关系等。

如果你想了解更多,点击 这里

让我们创建我们的 Word2Vec 模型。

**#install gensim if you haven't already
#!pip install gensim
import gensim*#Dimension of vectors we are generating*
EMBEDDING_DIM = 100
*#Creating Word Vectors by Word2Vec Method*
w2v_model = gensim.models.Word2Vec(sentences=X, size=EMBEDDING_DIM, window=5, min_count=1)*#vocab size*
len(w2v_model.wv.vocab)
*#We have now represented each of 122248 words by a 100dim vector.***

这些向量将被传递给 LSTM/GRU,而不是单词。1D-CNN 可以进一步用于从向量中提取特征。

Keras 有一个名为“嵌入层的实现,它将创建单词嵌入(向量)。因为我们是用 gensim 的 word2vec 做的,所以我们会将这些向量加载到嵌入层中,并使该层不可训练。

我们不能将字符串传递给嵌入层,因此需要用数字来表示每个单词。

记号赋予器可以用数字来表示每个单词

***# Tokenizing Text -> Repsesenting each word by a number*
*# Mapping of orginal word to number is preserved in word_index property of tokenizer**#Tokenized applies basic processing like changing it yo lower case, explicitely setting that as False*
tokenizer = Tokenizer()
tokenizer.fit_on_texts(X)X = tokenizer.texts_to_sequences(X)**

我们创建了单词索引和向量之间的映射矩阵。我们用它作为嵌入层的权重。嵌入层接受单词的数字符号,并向内层输出相应的向量。它向下一层发送一个零向量,用于将被标记为 0 的未知单词。嵌入层的输入长度是每个新闻的长度(由于填充和截断,现在是 700)。

现在,我们将创建一个序列神经网络模型,并在嵌入层中添加从 w2v 生成的权重,还添加一个 LSTM 层。

***#Defining Neural Network*
model = Sequential()
*#Non-trainable embeddidng layer*
model.add(Embedding(vocab_size, output_dim=EMBEDDING_DIM, weights=[embedding_vectors], input_length=maxlen, trainable=False))
*#LSTM* 
model.add(LSTM(units=128))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])**

现在让我们使用sklearn train_test_split方法将数据集分成训练集和测试集。

让我们使用model.fit(X_train, y_train, validation_split=0.3, epochs=6)来训练模型。这需要一些时间,在我的机器上花了大约 40 分钟,所以坐下来喝点咖啡,放松一下。

训练完成后,我们将在test数据集上进行测试,并使用classification_report()方法生成报告。

哇,我们获得了 99%的准确性,具有良好的精确度和召回率,因此我们的模型看起来很好,现在让我们将它保存在磁盘上,以便我们可以在我们的 web 应用程序中使用它。

3.构建和部署 web 应用程序

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

照片由沙哈达特·拉赫曼Unsplash 上拍摄

在这一部分,我不会讲太多的细节,我建议你仔细阅读我的代码,它非常容易理解。如果你一直坚持到现在,你必须有相同的目录结构,如果没有,那么只需改变app.py文件中的路径变量。

现在将整个目录上传到 GitHub 存储库中。

我们将在 Heroku 上托管我们的 web 应用程序。如果你还没有,在 Heroku 上创建一个免费帐户,然后:

  1. 点击创建新应用程序
  2. 然后选择一个名称
  3. 选择 GitHub,然后选择您想要保留的存储库
  4. 点击部署。

嘣,它完成了,你的假新闻分类器现在是活的。

结论…

如果您已经完成了,那么恭喜您,现在您可以构建和部署一个复杂的机器学习应用程序了。

我知道这很难理解,但你能走到这一步还是值得称赞的。

****注意:该应用程序适用于大多数新闻,只需记住粘贴整段新闻,最好是美国新闻,因为数据集被限制为美国新闻。

如果我们还没有见过面,我是 Eish Kumar 你可以在 Linkedin 上关注我:https://www.linkedin.com/in/eish-kumar/

关注我更多这样的文章。

建立和评估分类 ML 模型

原文:https://towardsdatascience.com/building-and-evaluating-classification-ml-models-9c3f45038ef4?source=collection_archive---------21-----------------------

必须阅读建立良好的分类 ML 模型

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

马丁·桑切斯在 Unsplash 上的照片

机器学习中有不同类型的问题。有些可能属于回归类(有连续的目标),而另一些可能属于分类类(有离散的目标)。有些可能根本没有目标,您只是试图通过创建聚类,根据数据点的固有特征来区分数据点,从而了解数据的特征。

然而,这篇文章不是关于机器学习的不同领域,而是关于一件很小但很重要的事情,如果不小心,它可能会对您的可操作化分类模型以及最终的业务造成“谁知道是什么”的影响。因此,下一次当工作中有人告诉你她/他的模型给出了~93.23%的准确率时,在问出正确的问题之前,不要上当。

那么,我们如何知道什么是正确的问题呢?

这个问题问得好。让我们通过研究如何以正确的方式构建和评估分类模型来尝试回答这个问题。每个研究机器学习的人都知道所有经常使用的分类指标,但只有少数人知道用来评估分类模型性能的正确指标。

因此,为了让您能够提出正确的问题,我们将详细讨论以下概念(对于分类模型):

  1. 数据分发(培训、验证、测试)
  2. 处理阶层失衡。
  3. 模型评估指标的正确选择

数据分布

在为训练集、验证集和测试集拆分数据时,应该始终记住这三者必须代表相同的总体。例如,在所有数字图像都是灰色(黑白)的 MNIST 数字分类数据集中,您对其进行了训练,并实现了几乎 90%的验证准确性,但是您的测试数据具有各种颜色的数字图像(不仅仅是黑白)。现在,你有一个问题。无论你做什么,总会有数据偏差。你不能完全摆脱它,但是你能做的是在你的验证和测试数据集中保持一致性。这是验证集和测试集分布不同的一个例子。

分割数据的正确策略

您的测试数据集必须始终代表真实世界的数据分布。例如,在二元分类问题中,假设您要检测一种罕见疾病(1 类)的阳性患者,其中整个数据集的 6%包含阳性病例,那么您的测试数据也应该具有几乎相同的比例。确保您遵循相同的分布。这不仅仅是分类模型的情况。它适用于所有类型的 ML 建模问题。

培训、验证和测试拆分的正确顺序

应该首先提取测试数据集,而不将任何数据泄漏到剩余数据中,然后,验证数据必须遵循测试数据中的分布。这两次分裂后剩下的部分进入训练。因此,将整个数据集划分为训练集、验证集和测试集的正确顺序是从整个数据集中按特定顺序获取测试集、验证集和训练集。

正确的比例

在机器学习社区中有 70-20-10 的比例,但这只是在你拥有平均数据量的情况下。例如,如果您正在处理一个图像分类问题,并且您有大约 1000 万张图像,那么进行 70–20–10 分割将是一个坏主意,因为数据量如此之大,以至于要验证您的模型,甚至 1%到 2%的数据就足够了。因此,我宁愿选择 96–2–2 分割,因为您不希望通过增加大小来增加不必要的验证和测试开销,因为在验证和测试中使用总数据的 2%就可以实现相同的分布表示。此外,在进行分割时,确保不要用替代品取样。

处理阶级不平衡

在任何分类问题的情况下,对模型性能影响最大的是每个类别对总成本贡献的损失量。某一类别的实例数量越多,该类别的总损失贡献就越高。一个类别对总成本的损失贡献与属于该类别的实例数量成正比。这样,分类器更加集中于正确地分类那些对损失函数的总成本贡献更多的实例(即,来自多数类的实例)。

以下是我们解决阶级不平衡的方法:

  1. 加权损失
  2. 重采样

加权损失

在二元交叉熵损失中,我们有以下损失函数:

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

二元交叉熵损失

该模型输出给定示例属于正(y=1)类的概率。并且,基于上述二元交叉熵损失函数,计算每个示例的损失值,最后,总成本被计算为所有示例的平均损失。让我们通过编写一个简单的 python 脚本进行一个简单的模拟来更好地理解它。让我们生成 100 个地面真相标签,其中 25 个属于正(y=1)类,其余的是负(y=0)类,以说明我们微小实验中的类不平衡。此外,我们将为每个示例生成属于正类的随机概率值。

import numpy as np
import random***# Generating Ground truth labels and Predicted probabilities***
truth, probs = [], []
for i in range(100):
    ***# To maintain class imbalance***
    if i < 25:
        truth.append(1)
    else:
        truth.append(0)
    probs.append(round(random.random(),2))
print("Total Positive Example Count: ",sum(truth))
print("Total Negative Example Count: ",len(truth) - sum(truth))
print("Predicted Probability Values: ",probs)**Output:**
Total Positive Example Count:  25
Total Negative Example Count:  75
Predicted Probability Values:  [0.84, 0.65, 0.11, 0.21, 0.31, 0.05, 0.44, 0.83, 0.19, 0.61, 0.28, 0.36, 0.46, 0.79, 0.74, 0.58, 0.65, 0.8, 0.05, 0.39, 0.08, 0.45, 0.4, 0.03, 0.41, 0.75, 0.46, 0.49, 0.94, 0.57, 0.38, 0.7, 0.07, 0.91, 0.85, 0.91, 0.72, 0.28, 0.0, 0.55, 0.61, 0.55, 0.81, 0.98, 0.9, 0.36, 0.65, 0.91, 0.26, 0.1, 0.99, 0.48, 0.34, 0.96, 0.68, 0.21, 0.28, 0.37, 0.8, 0.27, 0.87, 0.93, 0.03, 0.95, 0.25, 0.63, 0.2, 0.45, 0.05, 0.7, 0.91, 0.85, 0.56, 0.61, 0.4, 0.35, 0.6, 0.27, 0.08, 0.85, 0.14, 0.82, 0.22, 0.41, 0.85, 0.72, 0.91, 0.5, 0.55, 0.89, 0.39, 0.92, 0.24, 0.07, 0.52, 0.88, 0.01, 0.01, 0.01, 0.31]

现在,我们有了基本事实标签和预测概率,使用上述损失函数,我们可以计算两个类别的总损失贡献。在计算对数值之前,在预测概率中加入了一个非常小的数字,以避免由于未定义的值而产生的误差。[log(0) =未定义]

***# Calculating Plain Binary Cross-Entropy Loss***
pos_loss, neg_loss = 0, 0
for i in range(len(truth)):
    ***# Applying the binary cross-entropy loss function***
    if truth[i] == 1:
        pos_loss += -1 * np.log(probs[i] + 1e-7)
    else:
        neg_loss += -1 * np.log(1 - probs[i] + 1e-7)
print("Positive Class Loss: ",round(pos_loss,2))
print("Negative Class Loss: ",round(neg_loss,2))**Output:**
Positive Class Loss:  29.08
Negative Class Loss:  83.96

正如我们可以看到的,两个类别的总损失有很大的差异,负类别在损失贡献方面领先,该算法在技术上更关注负类别,以从根本上减少损失,同时将其最小化。这时,我们通过使用以下加权损失函数为总损失计算分配一个权重,来欺骗模型,使其相信不真实的情况:

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

加权二元交叉熵损失

这里,“Wp”和“Wn”分别是分配给正和负类别损失的权重,可以计算如下:

Wp =负样本(y=0)总数/样本总数

Wn =正(y=1)例总数/例总数

现在,让我们通过将权重添加到计算中来计算加权损失:

***# Calculating Weighted Binary Cross-Entropy Loss***
pos_loss, neg_loss = 0, 0***# Wp (Weight for positive class)***
wp = (len(truth) - sum(truth))/len(truth)***# Wn (Weight for negative class)***
wn = sum(truth) / len(truth)for i in range(len(truth)):
   ** *# Applying the same function with class weights.***
    if truth[i] == 1:
        pos_loss += -wp * np.log(probs[i] + 1e-7)
    else:
        neg_loss += -wn * np.log(1 - probs[i] + 1e-7)
print("Positive Class Loss: ",round(pos_loss,2))
print("Negative Class Loss: ",round(neg_loss,2))Output:
Positive Class Loss:  21.81
Negative Class Loss:  20.99

太神奇了!不是吗?通过分配正确的权重,我们成功地显著减少了两个类别之间的损失贡献差异。

重采样

这是另一个你可以用来对抗阶级不平衡的技术,但是这不应该是你使用的第一个技术。重采样有三种方式:

  1. 通过过采样少数类
  2. 或者通过欠采样多数类
  3. 或两者各适量

过采样可以通过对替换的少数类进行随机采样来实现,也可以通过使用 SMOTE 等技术综合生成更多的样本来实现。过采样在一定程度上是有帮助的,因为在一定量之后,您将复制数据中包含的信息。这可能会给你两个类的理想损失贡献,但在验证和测试时会失败。但是,如果你有大量的数据和不平衡,你应该选择欠采样而不替换多数类。

有时,当数据量一般,并且类别不平衡不严重时,人们会同时使用这两种技术。因此,他们对少数类进行过采样,对多数类进行一定量的欠采样,以达到平衡。

现在,你知道当有人来找你,说我有大约 93.23%的准确率时,你应该思考并询问数据中的类别比例以及使用的损失函数的类型。然后,你应该想知道仅仅测量准确性是否是正确的方法。或者还有别的!

度量标准的正确选择

至少当你在研究一个机器学习模型时,总会有更多的东西,但只有当你有东西可以比较时,才可能知道你什么时候想要更多。一个标杆!一旦你有了一个基准,你就知道你想要多少改进。

但是为了提高性能,您需要知道在您试图解决的业务问题中,哪个度量是正确的性能指标。例如,如果您试图解决一个肿瘤检测问题,其目标是检测肿瘤是恶性的(y=1)还是良性的(y=0)。在这种情况下,你需要明白在现实世界中良性病例比恶性病例多。因此,当你得到数据时,你会有一个很大的阶级不平衡(当然,除非你真的很幸运)。因此,准确性作为一个衡量标准是不可能的。现在的问题是,什么更重要?以检测患者是否患有恶性肿瘤或良性肿瘤。这是一个商业决策,你应该总是咨询领域专家(在这种情况下,专家医生),通过问这样的问题来理解业务问题。如果我们更关心有效地检测恶性肿瘤,即使我们有一些假阳性(基础事实:良性,模型预测:恶性),但我们需要尽可能少的假阴性(基础事实:恶性,模型预测:良性),那么回忆应该是我们选择的度量标准,但如果反之亦然(在这个特定的情况下永远不可能),精确度应该是我们的选择。

有时,在商业环境中,存在需要对两个类别进行有效分类的问题,因此您可能希望优化 F1 分数。为了解决这个权衡,我们应该尽可能地最大化精确召回曲线下的区域。

此外,结果必须以具有度量上限和下限的置信区间的形式传达,以便使用在各种样本上进行的所有实验,对模型在总体上的行为有一个公平的想法。

总结一下,下面是这篇文章的主要内容:

  • 在构建分类模型时,数据分布是至关重要的,人们应该总是首先正确地开始测试分布,然后按照这个顺序进行验证和训练。
  • 应该适当地处理类不平衡,以避免对实时数据产生非常糟糕的结果。
  • 只有当你选择正确的度量标准来评估你的模型时,你才能正确地评估它的性能。从业务专业知识到模型本身的技术细节,有很多因素可以帮助我们决定正确的指标。

感谢您阅读文章。

建立和管理数据科学团队

原文:https://towardsdatascience.com/building-and-managing-data-science-teams-77ba4f43bc58?source=collection_archive---------25-----------------------

由于数据数量和种类的大幅增加,大多数组织已经开始使用数据科学来了解其业务绩效并做出运营决策。一些组织刚刚开始研究数据科学,而另一些组织已经进行了大量投资,数据科学团队遍布全球业务部门。无论您的组织成熟度如何,挑战仍然存在,即如何最好地构建和管理数据科学团队,以便他们能够扩展以满足您组织不断增长的需求。

这篇文章是关于我在建立和管理一个数据科学团队的过程中所学到的东西,既有我自己在过去几年的经验,也有向该领域其他人学习的经验。

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

去飞溅

数据科学团队

重要的是要认识到,建立一个数据科学团队并不像雇用数据科学家并让他们获得数据那么简单。尽管对于机器学习(ML)模型的初始原型来说,这似乎已经足够了。但是,要使模型在真实环境中工作,您需要注意使模型生产就绪所需的其他部分。机器学习工作流可能涉及许多相互依赖的步骤,从数据准备和分析,到训练,到评估,到部署等等。数据科学团队涉及许多跨职能技能,以使其从原型阶段成为现实世界的解决方案。为了做到这一切,数据科学团队由数据科学家、数据架构师/工程师、机器学习工程师和软件开发人员组成。让我们简单讨论一下这些角色。

角色

数据科学团队中有许多角色和职责重叠的名称,但大致可以分为:

数据科学家利用机器学习和数据挖掘技术解决商业问题。数据科学家还负责使用统计方法、流程和算法从数据中提取见解。任务包括数据预处理,分析,实验,可视化和交流结果。

机器学习工程师结合了软件工程和建模技能。训练、监控和维护模型的一切都是 ML 工程师的工作。

数据架构师/工程师- 负责实施、测试和维护大数据和大型分布式系统的基础设施组件。

软件开发人员负责获取一个已部署的模型,并准备好通过 REST API 提供服务,还可能涉及一些前端接口,因此软件开发人员可以帮助完成所有这些任务。

数据注释和质量保证(QA)- 数据是任何数据科学团队成功的关键。拥有一支训练有素的数据标注团队可以提供显著的价值,尤其是在迭代机器学习模型测试和验证阶段。机器学习是一个迭代的过程。您需要验证模型预测,还需要准备新的数据集并丰富现有数据集以改进算法的结果。您可以雇佣或外包数据注释,但挑战仍然是在标记数据和验证结果方面保持一致性。

研究科学家- 如果你的团队在一些核心人工智能领域工作,如对话式人工智能、计算机视觉、机器人、强化学习、图形模型等。你可能需要雇佣有博士或核心研究背景的人。

数据科学经理- 负责招聘和建立数据科学团队,展示团队能力,与高级管理层沟通,开发团队可以遵循的流程,帮助团队沟通并保持事情进展。

简而言之,目标是建立一个跨职能的数据科学团队,使您的组织能够从数据中获得洞察力,并构建生产就绪模型。

管理数据科学团队

管理数据科学团队不同于典型的软件开发团队,这是因为数据科学需求往往会因为任务的探索性而更加模糊。精确地计划一个项目的时间或最终结果是非常困难的。

以下是成功管理数据科学团队需要应对的一些关键挑战。

  1. **壮大团队:**最初你可能需要一个小团队,主要从事一些分析工作,或者想出一些你可以向高级管理层推销的想法。但是你很快就会意识到,要把这个想法变成一个产品,你的团队还需要很多其他的技能。目标应该是将数据科学团队发展成为负责设计、实施和维护产品的完整产品团队。作为一个产品团队,数据科学团队可以试验、构建并直接为公司增加价值。
  2. **区分工作的优先级:**我发现团队不时会收到大量的分析报告或其他数据处理请求。这些临时请求耗费大量时间,并影响长期项目和其他关键交付。重要的是区分工作的优先次序,并为这些特别的任务分配正确的优先级。在我们的团队中,我们创建了一个特别的请求积压,并增加了这些任务的优先级。然后,团队可以更好地管理这些紧急请求,而不会牺牲重要任务的时间。
  3. 数据质量:第一个问题是:你得到的数据是否正确?您可能有大量可用的数据,但这些数据的质量并不确定。为了创建、验证和维护高性能机器学习模型的生产,您必须使用可信、可靠的数据来训练和验证它们。你需要检查数据的准确性质量。数据标注的准确性衡量标注与事实的接近程度。数据标注的质量关乎整个数据集的准确性。确保所有标注器的工作看起来相同,并且标注在数据集上一致准确。
  4. 工具:工具扮演着重要的角色,因为它们允许你自动化。您应该使用相关工具来完成繁重的工作,运行脚本来自动执行查询和处理数据,以节省一些时间,这些时间反过来可以用于提高团队的工作效率。数据科学团队致力于解决挑战性问题。自动化重复性的每周报告可以帮助工程师专注于一些新的挑战性问题。在我们的团队中,我们制作了一个标记数据的工具,并向数据注释团队公开了该工具。这确实有助于我们检查数据的一致性,并在不同成员之间共享工作,快速完成贴标任务。
  5. **流程:**数据科学团队项目以研究为导向,或者从大量研究活动开始,很难预测他们需要多长时间才能完成。此外,建模、数据处理等许多活动通常由一个人完成,因此传统的协作工作流不适合。你必须确定一种最适合你的团队的方法。就像在我们的案例中,我们在 JIRA 混合使用看板和 Scrum 板。对于研究活动,数据探索/分析,探索 ML 模型采用看板模式,而作为模型的产品化,你可以作为一个 Scrum 团队工作。所以基本上你的数据科学家、研究科学家和 ML 工程师大多以看板模式工作,而数据工程师、软件工程师则以 Scrum 模式工作。评估各种选项,看看什么最适合您的团队和项目。

及时处理好这些挑战是很重要的,否则会导致团队的低积极性、低生产率,并可能导致人员流失。

建立和管理数据科学团队是一个持续的学习曲线,因为行业仍在寻找建立有效和标准方法和流程的方法。

感谢阅读!

使用 DAX 在 PowerBI 中构建和优化多元线性回归

原文:https://towardsdatascience.com/building-and-optimizing-multiple-linear-regression-in-powerbi-using-dax-ed468e1ec2ae?source=collection_archive---------17-----------------------

本文主要介绍如何在 PowerBI 中使用 DAX 完成多元线性回归进行时间序列分析。接下来,我将把“岭回归”和“套索回归”的思想引入模型优化。

多重线性的公式推导

多元线性回归公式如下:

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

图片由 维基

DAX 不能执行矩阵运算,所以回归公式参考了克利姆定律。以二元回归为例,其原理是通过计算数据集,得到β0,β1,β2 的最优解。公式推导如下:

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

图片由 百科

我们只能通过根据这个公式在 DAX 中创建新的度量来完成回归。

关于本文的数据集

本文数据集来自 Tableau 论坛(Superstore。xls)

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

作者图片

其中“订单日期”将是第一个自变量,“销售额”将是因变量(即预测目标)。

构建多元线性回归

从下图可以看出,销售数据是以年为单位形成的,所以我们可以用“月”作为第二个自变量。

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

作者图片

基于上述线性回归公式,代码如下:

Binary Linear Regression = 
VAR VT =
FILTER (
SELECTCOLUMNS(
SUMMARIZE(ALLSELECTED('Date'),'Date'[Date],'Date'[Month Number]),
"VT[X1]", 'Date'[Date],
"VT[X2]", 'Date'[Month Number],
"VT[Y]",'Orders'[Qty]
),
AND (
NOT ( ISBLANK ( VT[X1] ) ),
AND(
NOT ( ISBLANK ( VT[X2] ) ),
NOT ( ISBLANK ( VT[Y] ) )
))
)
VAR Average_X1 =
AVERAGEX ( VT, VT[X1] )
VAR Average_X2 =
AVERAGEX ( VT, VT[X2] )
VAR Average_Y =
AVERAGEX ( VT, VT[Y] )
VAR Sum_X1_2 =
SUMX ( VT, (VT[X1] - Average_X1) ^ 2 )
VAR Sum_X2_2 =
SUMX ( VT, (VT[X2] - Average_X2) ^ 2 )
VAR Sum_X1Y =
SUMX ( VT, (VT[X1] - Average_X1) * (VT[Y] - Average_Y))
VAR Sum_X2Y =
SUMX ( VT, (VT[X2] - Average_X2) * (VT[Y] - Average_Y))
VAR X12 = 
SUMX( VT, (VT[X1] - Average_X1)*(VT[X2] - Average_X2))
VAR Beta1 =
DIVIDE (
Sum_X1Y*Sum_X2_2 - sum_x2y*X12,
Sum_X1_2*Sum_X2_2 - X12 ^ 2
)
VAR Beta2 =
DIVIDE (
Sum_X2Y*Sum_X1_2 - sum_x1y*X12,
Sum_X1_2*Sum_X2_2 - X12 ^ 2
)
VAR Intercept =
Average_Y - Beta1 * Average_X1 - Beta2 * Average_X2
VAR RESULT = 
SUMX (
SUMMARIZE('Date','Date'[Date],'Date'[Month Number]),
Intercept + Beta1 * 'Date'[Date] + Beta2 * 'Date'[Month Number]
)
RETURN
RESULT

你可以看到下图中有一条红色的曲线:这是我们刚刚建立的二元线性回归模型。

评价模型

现在模型已经建立,我们需要评估它。

我引入两个指标:

1.RMSE(均方根误差)—越小越好

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

图片由 维基百科

2.r(拟合优度)—通常越接近 1 越好

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

图像由 维基 组成

根据上面的公式,可以完成如下代码。

RMSE = 
VAR 
VT =
SUMMARIZE(
ALLSELECTED('Date'),'Date'[Date],'Date'[Month Number])
RETURN
SQRT(
divide(
SUMX(VT,
    ('Orders'[Binary Linear Regression] - 'Orders'[Qty]) ^ 2),
COUNTROWS(VT)))--------------------------------------------------------------------------------------------------
R^2 = 
VAR 
VT =
SUMMARIZE(ALLSELECTED('Date'),'Date'[Date],'Date'[Month Number])
VAR
ESS = 
SUMX(VT,POWER('Orders'[Binary Linear Regression]-AVERAGEX(VT,[Qty]),2))
VAR
TSS = 
SUMX(VT,POWER([Qty]-AVERAGEX(VT,[Qty]),2))
RETURN
DIVIDE(ESS,TSS)

运行代码后,我们知道模型的拟合效果并不乐观。

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

作者图片

优化模型

我们知道线性回归优化主要有两种方法:套索回归和岭回归。这两种方法分别在模型中加入了 L1 & L2 正则化。我们不谈复杂的统计,我们只关心如何用 DAX 高效的解决模型优化的问题。

实际上,这两种方法都是通过增加一个惩罚项来降低模型的某些系数。前者可以直接把不重要的系数压缩到 0。所以这个算法本质上是对模型中每个β系数的选择性压缩。另外,DAX 本身并不是算法的语言。因此,考虑到代码运行的性能,我们可以简单地将模型的系数乘以一个变量来达到效果,而不需要进行复杂的求导计算。在 PowerBI 中创建参数作为该变量的值,这样我们就可以在可视化界面中调整该变量的值,实现模型的手动优化。因此,我们修改了原始回归模型的代码:

Manual Binary Regression = 
VAR R = '_Slope'[Regular factor Value]
VAR A = 'α'[α Value]
VAR B = 'β'[β Value]
VAR VT =
FILTER (
SELECTCOLUMNS(
SUMMARIZE(ALLSELECTED('Date'),'Date'[Date],'Date'[Month Number]),
"VT[X1]", 'Date'[Date],
"VT[X2]", 'Date'[Month Number],
"VT[Y]",'Orders'[Qty]
),
AND (
NOT ( ISBLANK ( VT[X1] ) ),
AND(
NOT ( ISBLANK ( VT[X2] ) ),
NOT ( ISBLANK ( VT[Y] ) )
))
)
VAR Average_X1 =
AVERAGEX ( VT, VT[X1] )
VAR Average_X2 =
AVERAGEX ( VT, VT[X2] )
VAR Average_Y =
AVERAGEX ( VT, VT[Y] )
VAR Sum_X1_2 =
SUMX ( VT, (VT[X1] - Average_X1) ^ 2 )
VAR Sum_X2_2 =
SUMX ( VT, (VT[X2] - Average_X2) ^ 2 )
VAR Sum_X1Y =
SUMX ( VT, (VT[X1] - Average_X1) * (VT[Y] - Average_Y))
VAR Sum_X2Y =
SUMX ( VT, (VT[X2] - Average_X2) * (VT[Y] - Average_Y))
VAR X12 = 
SUMX( VT, (VT[X1] - Average_X1)*(VT[X2] - Average_X2))
VAR Beta1 =
DIVIDE (
Sum_X1Y*Sum_X2_2 - sum_x2y*X12,
Sum_X1_2*Sum_X2_2 - X12 ^ 2
) * A 
VAR Beta2 =
DIVIDE (
Sum_X2Y*Sum_X1_2 - sum_x1y*X12,
Sum_X1_2*Sum_X2_2 - X12 ^ 2
) * B
VAR Intercept =
Average_Y - Beta1 * Average_X1 - Beta2 * Average_X2
VAR Result = 
SUMX (
SUMMARIZE('Date','Date'[Date],'Date'[Month Number]),
Intercept + Beta1 * 'Date'[Date] + Beta2 * 'Date'[Month Number]
)
RETURN
Result * (1-1/R)

代码运行如下(注意:调整后的模型显示在深蓝色曲线中,RMSE 和 R 也被更改为该模型的评估值):

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

作者图片

(注:“α”用于调整第一个参数;“β”用于调整第二个参数)

到目前为止,我们已经完成了二元线性回归模型的手动优化,我们可以调整参数,然后通过观察 RMSE 和 R 来评估结果。

本文本该到此结束,但后来觉得这种手动参数调整有点盲目,我们应该对调整参数有一个直观科学的参考,以提高使用效率。所以我做了一个模型优化参考图,我们以第一个自变量(订单日期)为例,以它的参数为自变量(X 轴),R 和 RMSE 为因变量(Y 轴),这样,我们可以直观地为模型优化提供如下参考:

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

作者图片

(注:由于 RMSE 的值远大于 R 的值,上图中的 RMSE 值被压缩为原来的十分之一,以使 RMSE 和 R 更容易观察到。当然也可以考虑用两轴图)

摘要

到目前为止,我们已经知道如何使用 DAX 进行多元线性回归和模型优化。代码虽然长,但也不难理解。你可能会奇怪为什么我们不用 R 语言做线性回归?是的,在 PowerBI 中使用 R 语言进行回归更容易。但是 PowerBI 服务目前只支持部分 R 库,如果使用报表服务器版本,截至 2019 年 4 月,Power BI 服务(RS 版)不支持任何 R 库(包括用 R 语言开发的自定义 visual)。除非只需要使用桌面版,否则只能选择使用 DAX 来完成所有建模工作。另外,这是加深你对 DAX 和线性回归理解的好机会。

如果你有更好的方法用 PowerBI 实现时间序列预测,希望得到你的分享。

附:三元线性回归代码

Ternary Linear Regression = 
VAR VT =
FILTER (
SELECTCOLUMNS(
SUMMARIZE(
    ALLSELECTED('Date'),
    'Date'[Date],'Date'[Month Number],
    DateFactorTable[DateFactor]),
"VT[X1]", 'Date'[Date],
"VT[X2]", 'Date'[Month Number],
"VT[X3]", 'DateFactorTable'[DateFactor],
"VT[Y]",'Orders'[Qty]
),
AND (
NOT ( ISBLANK ( VT[X1] ) ),
AND(
NOT ( ISBLANK ( VT[X2] ) ),
AND(
NOT ( ISBLANK ( VT[X3] ) ),
NOT ( ISBLANK ( VT[Y] ) )
))
))
VAR N =
COUNTROWS ( VT )
VAR L11 = 
SUMX(VT,'VT'[X1]^2)-DIVIDE(SUMX(VT,'VT'[X1]^2),N)
VAR L22 = 
SUMX(VT,'VT'[X2]^2)-DIVIDE(SUMX(VT,'VT'[X2]^2),N)
VAR L33 = 
SUMX(VT,'VT'[X3]^2)-DIVIDE(SUMX(VT,'VT'[X3]^2),N)
VAR L12 = 
SUMX(VT,'VT'[X1]*'VT'[X2])-DIVIDE(SUMX(VT,'VT'[X1]*'VT'[X2]),N)
VAR L13 = 
SUMX(VT,'VT'[X1]*'VT'[X3])-DIVIDE(SUMX(VT,'VT'[X1]*'VT'[X3]),N)
VAR L32 = 
SUMX(VT,'VT'[X3]*'VT'[X2])-DIVIDE(SUMX(VT,'VT'[X3]*'VT'[X2]),N)
VAR L10 = 
SUMX(VT,'VT'[X1]*'VT'[Y])-DIVIDE(SUMX(VT,'VT'[X1]*'VT'[Y]),N)
VAR L20 = 
SUMX(VT,'VT'[X2]*'VT'[Y])-DIVIDE(SUMX(VT,'VT'[X2]*'VT'[Y]),N)
VAR L30 = 
SUMX(VT,'VT'[X3]*'VT'[Y])-DIVIDE(SUMX(VT,'VT'[X3]*'VT'[Y]),N)VAR D4 = 
L30*L12*L11*L22-L30*L12^3-L11*L22*L13*L20+L13*L20*L12^2-
L11*L20*L30*L22+L11*L20^2*L13+L12*L10*L30*L22-L12*L10*L13*L20
VAR D3 = 
L32*L13*L11*L22-L32*L13*L12^2-L12*L33*L11*L22+L12^3*L33-
L30*L22*L12*L13+L13^2*L20+L11*L32*L20*L22-L11*L32*L13*L20VAR BETA3 = 
DIVIDE(D4,D3)VAR D2 = 
(L12*L13-L11*L32)*BETA3+L11*L20-L12*L10
VAR D1 = 
L11*L22-L12^2VAR BETA2 = 
DIVIDE(D2,D1)VAR D0 = 
L30-BETA2*L32-BETA3*L33VAR BETA1 = 
DIVIDE(D0,L13)VAR Intercept =
AVERAGEX(VT,VT[Y]) - BETA1 * AVERAGEX(VT,VT[X1]) - 
BETA2 * AVERAGEX(VT,VT[X2]) - 
BETA3 * AVERAGEX(VT,VT[X3])
VAR Result = 
SUMX (
SUMMARIZE('Date','Date'[Date],'Date'[Month Number],
    DateFactorTable[DateFactor]),
Intercept + 
BETA1* 'Date'[Date] +
BETA2 * 'Date'[Month Number] + 
BETA3 * 'DateFactorTable'[DateFactor]
)
RETURN
RESULT

结束~

在 R 中构建和测试股票投资组合

原文:https://towardsdatascience.com/building-and-testing-stock-portfolios-in-r-d1b7b6f59ac4?source=collection_archive---------11-----------------------

利用数据科学做出更明智的投资决策

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

照片由 Unsplash 上的 Aditya Vyas 拍摄

在本文中,我们将研究如何获取股票数据,分析数据以做出投资决策,并将结果可视化。

随着最近进入市场的散户投资者激增,新交易员拥有通过分析股票长期表现来比较股票的工具比以往任何时候都更重要。在本帖中,我们将使用三家熟悉的公司——星巴克、嘉年华和苹果——的股票数据来构建一个投资组合,考察其历史表现,并将其与标准普尔 500 指数进行比较。

安装库

R 中三个非常有用的财务分析包是quantmod,从雅虎财经中提取股票数据;PerformanceAnalytics,构建和测试投资组合;和dygraphs,来制作我们数据的交互式和信息可视化。如果您没有安装这些包,您可以使用下面的代码将它们安装并加载到您的 R 环境中。

安装和加载所有必需的软件包

编写一个计算股票收益的函数

一旦我们安装并加载了软件包,我们就可以编写一个函数来获取我们个股的月度回报数据。我们的函数有两个参数:ticker,股票的符号,和base_year,我们想要开始分析数据的年份。

使用雅虎财经数据计算股票月回报率的函数

如果您不熟悉 R 及其软件包,这个函数可能会显得有点复杂。下面是每一行的解释:

  • 第 4 行: 将我们的股票代码传递给getSymbols()函数,以从 Yahoo Finance 获取我们的股票数据

  • 第 10–12 行: 使用 R 的内置paste0()Sys.Date()函数来创建一个字符串,我们可以在括号之间传递该字符串,以便只选择我们的基准年和今天日期之间的观测值

  • 第 15 行: 计算我们调整后的收盘价数据的月度算术回报

  • 第 18 行: 将我们的月度回报数据分配给 R 的全球环境,以确保我们以后可以通过其股票代码访问它

使用我们的函数并可视化返回结果

写完函数后,现在我们可以计算三只股票的月收益率了。我们需要调用我们的函数四次——一次针对我们想要分析的每只股票,一次针对标准普尔 500——这样我们就有了一个基准来判断每只股票的月度表现。然后,我们可以将我们所有的月度回报合并到一个时间序列对象中,并使用dygraphs软件包查看每个对象最近几年的表现(点击这里查看交互式版本)。最后一行打印过去五个月的返回数据,其输出如下所示。

获取单个股票数据,将其合并,并生成可视化结果

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

为我们的三只股票和标准普尔 500 绘制月收益图

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

我们新创建的 returns 对象的最后五行

分析投资组合构成

从我们的returns数据集,我们可以了解到每只股票在过去几年中相对于标准普尔 500 指数的表现。例如,2020 年 3 月,当新冠肺炎蔓延的消息搅动金融市场时,标准普尔 500 指数下跌约 12.5%,而嘉年华公司当月市值损失超过 60%。相比之下,苹果的亏损只有 7%左右。使用corrplot::corrplot(cor(returns), method = number)生成一个关联矩阵来表示这些股票的收益如何相互关联。

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

使用 corrplot 包生成的相关矩阵

投资组合管理的一个基本原则是,你应该选择彼此相关性低的股票。你不会希望你投资组合中的所有股票总是一起涨跌——这可能会让你面临你可能想要避免的过度波动,特别是如果这是一个退休账户,其中保本是你的主要关注点。由高度相关的股票组成的投资组合会受到非系统性风险的影响,这种风险源于每只股票固有的公司特有风险。

从我们的相关矩阵中,我们观察到我们所有的股票都是正相关的,尽管程度不同。苹果和星巴克的相关性很弱(0.27),但是嘉年华和标准普尔 500 的相关性很高(0.71)。重要的是,我们所有的股票都与市场有着相当高的正相关性,这意味着它们在大多数月份都会随市场波动。

构建我们的投资组合并评估绩效

我们可以使用PerformanceAnalytics软件包为我们的股票分配权重,并根据它们建立一个假设的投资组合。在下面的代码中,我们假设我们将三分之一的资金投资于星巴克,三分之一投资于嘉年华,三分之一投资于苹果,暂时不包括 S & P 500。Return.portfolio()函数允许我们从returns对象传入我们的个股数据以及它们的权重。我们可以将wealth.index参数设为 TRUE,以显示 2015 年投资于我们投资组合的 1 美元将如何随时间增长。然后,我们可以对标准普尔 500 遵循同样的过程,排除weights论点。在将我们的数据合并到一个xts对象中后,我们可以使用另一个图表将我们的投资组合与标准普尔 500 指数进行对比(交互式版本此处为):

构建我们的投资组合

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

将我们的投资组合与基准进行比较

如果我们在 2015 年初向我们的星巴克-嘉年华-苹果投资组合投资 1 美元,并且没有动它(即,没有重新平衡),我们的投资组合价值将几乎翻倍(92.31%)。这超过了标准普尔 500 指数的表现,该指数在同一时期的回报率仍高达 73%左右。当然,我们可以对我们的代码做一些小的调整,以改变投资组合的权重,增加额外的股票(或其他资产,如政府债券和贵金属),并尝试重新平衡。有了 R 和它的库,我们构建和测试投资组合的能力实际上是无限的。

结论

我希望我已经让获取和分析股票数据的过程不那么可怕了。使用上面的代码,我们能够导入大量的财务信息,构建投资组合,检查其组成,并分析相对于基准的历史表现。在以后的文章中,我将探索使用 R 及其库分析财务数据的其他方法。

感谢阅读!

关于我

我叫克里斯蒂安·金凯,在马里兰大学帕克分校学习金融和经济学。如果你喜欢这个帖子,可以考虑一下 跟随我 上媒!

用 Python 构建 Android 应用程序:第 1 部分

原文:https://towardsdatascience.com/building-android-apps-with-python-part-1-603820bebde8?source=collection_archive---------1-----------------------

使用 Python 构建 Android 应用程序的分步指南

介绍

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

Unsplash 上由 Hitesh Choudhary 拍摄的照片

你是否对开发 android 应用但 Java 不是你的伴侣感到好奇?Android universe 主要是使用 Java、Kotlin、Flutter 和 Corona 使用 Lua 脚本语言(主要是游戏引擎,用于愤怒的小鸟等游戏)构建的,但最近,Python 已经进入了每个领域,Android 也不例外。在这一系列文章中,我们将看看如何设置所需的环境,开发 android 应用程序的基础,参考文档,以及如何推进您的项目。

基维——教父

Python 中的 Android 开发之所以成为可能,仅仅是因为一个用于开发移动应用和其他多点触控应用软件的开源 Python 库,这个库就是 **Kivy。**2011 年首次发布,2019 年稳定发布!Kivy 不仅支持 android 应用程序开发,而且其应用程序可以在 IOS、Linux、OS X、Windows 和 Android 上运行。它是用 Python 和 Cython 编写的,大部分核心开发人员来自俄罗斯。

我们将在应用程序的前端大量使用 Kivy,但使用另一个包,我们为什么需要这个包将很快被涵盖。

设置环境

为新项目建立一个新的环境通常是一个好的实践,如下所示:

  1. 它有助于维护不同库的不同版本。例如,ML flow 需要较低版本的 Numpy,当您尝试在基本目录中安装 ML flow 时,它会与预安装的库冲突,并使管理不同版本变得困难。
  2. 有助于隔离定制代码,并使在任何平台上部署应用程序变得更加容易。

我使用 Conda 包管理器来创建和管理我的环境。您可以使用任何其他的包管理器,但是为了跟随我,您可以使用 Conda(参见这个指南来设置 Conda 和 anaconda )。打开 Conda 终端,键入:

conda create -n name-of-env python=version

将“环境名称”替换为您的自定义名称和您选择的“版本”,但要大于 3.5。我会用 Python 3.7。要列出所有 Conda 环境,请键入:

conda info --envs

输出如下所示:

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

作者图片

这里是 Conda 备忘单的链接,如果你有兴趣了解更多的话。现在,检查完这里的名称后,像这样激活环境:

conda activate nameofenv

我们准备安装所需的库。当我们使用 python 时,pip 是安装和管理 python 包的好方法。要安装 Kivy 及其依赖项,请逐个键入以下命令:

pip install kivy
pip install kivy-deps.angle
pip install kivy-deps.glew
pip install kivy-deps.gstreamer
pip install kivy-deps.sdl2

**一个额外的提示:**创建一个名为 requirements.txt 的文件,将上面几行复制到该文件中,将该文件放在一个已知的位置并运行终端:

pip install requirements.txt

它将一次性安装所有的依赖项!

我们准备开发一些很棒的应用程序,但是这里有一个问题。一开始,我告诉过你我们需要一个额外的包来和 Kivy 一起使用。现在只需安装它,我们将在文章的后面讨论为什么。

pip install kivymd

我们来编码吧!

你期待已久的部分来了。我使用 Pycharm IDE 进行编码,因为它对我来说很容易,但是您可以根据自己的意愿使用 VSCode、Sublime 或 spyder。在开始之前,我们需要了解以下几点:

  1. 一个 android 应用程序有一个前端(UI/UX)或交互部分,用户在那里与你的应用程序交互,所有的输入都通过这一层给出。
  2. 输入被**传送到后端层,**是我们的 python 代码。这个后端层控制流、处理输出和屏幕上显示的内容。
  3. 在这里,面向对象编程被大量使用,大部分编程将使用这一概念来完成,所以如果你缺乏这方面的知识,那么我建议你观看 Keith Galli 在 OOP 上的视频

现在,快速打开您的 IDE,从 Hello World 的基本代码开始!

运行该程序后,您将看到以下输出:

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

首次输出

让我一行一行地解释这段代码:

  1. 第一行从 Kivy 库中导入基础应用程序。
  2. 现在,我们需要在屏幕上显示一些文本,为了显示任何文本,我们使用标签功能,正如我所说,这些是 UI/UX 的东西,我们将从“kivy.uix”目录中导入它们。
  3. 代码的第三行(忽略空白)是我们的 OOP 概念发挥作用的地方。我们从“kivy.app”导入的应用程序是该应用程序的基类。这意味着 Kivy 设置了运行我们的应用程序的所有必要的东西,我们需要继承这个应用程序类,改变它,并构建我们的应用程序。这个类的名字应该以大写字母开头,它也可以作为应用程序的名字,以后可以更改,所以你可以给它起任何你想要的名字。
  4. def 构建功能是 app 的切入点。这里定义的所有东西都将首先构建,第一个屏幕或主屏幕在这里传递。它返回标签,并且它有一个值为“Hello World”的文本属性。点击阅读更多关于标签的信息。
  5. 然后最后一行调用这个主类并运行它。

基维的问题

这就是我们如何构建我们的第一个应用程序,但你有没有注意到一件事,背景自动是黑色的,文本是白色的?我甚至没有在代码中提到这一点。Kivy 默认取。现在我们进入有趣的部分,让我们用 Kivy 构建一个简单的没有增强的按钮:

它的输出如下:

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

一个简单的按钮在基维

这是一个非常没有吸引力的外观,想象你正在使用一个有这样界面的应用程序。我会卸载该应用程序,甚至不会评价它!在 Kivy 中增强特性是一个乏味的过程,需要大量代码。不相信我?查看代码,创建一个放置在中心的矩形平面按钮,带有蓝色边框、蓝色文本和白色背景:

使用 Kivy 的矩形扁平按钮。来源:阿特雷·巴特

不要理解代码,因为这已经超出了您的范围,现在只需看看输出:

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

作者图片

现在看起来是不是很好看!

Kivymd 简介

现在我们已经谈了很多关于 Kivy 的内容,我们知道它提供了构建应用程序的平台。KivyMD 是一个材质设计兼容小部件的集合,可以与 Kivy 一起使用,并且尽可能接近 Google 的材质设计规范,而不会牺牲易用性或应用程序性能。它基于 Kivy,更容易编码。它与 Kivy 非常相似,只是在每个元素和小部件的开始处添加了 MD,此外它还有各种各样的其他新元素。现在看看 Kivymd 中生成相同输出按钮的代码:

尝试运行这个脚本,您将看到与长 Kivy 代码返回的输出相同的输出。

更多需要考虑的事情

  1. **性能问题:**你将开发的应用程序在你的本地机器上可以完美运行,但当你试图在 android 上运行它时,动画就不那么流畅了。此外,因为它仍然作为 python 的实例运行,所以速度很慢。
  2. 转换为 android: 其中一个主要任务是将 python Kivy 应用程序转换为 android 包(APK),这只能在 Linux 操作系统上完成。像 python-to-android、Android SDK、推土机这样的附加包很重,需要大量时间来构建和调试应用程序。所有的 Kivy 和 Kivymd 库都被转换成 Cython,这些被 Android 系统使用。这个过程通常以高精度完成。
  3. **仍在开发中:**这是一个开源项目,仍有大量工作在进行中。总是尝试更新软件包,这样你就不会面临任何问题。

结论和下一步

这是用 python 构建 android 应用程序的入门课。我们学习了什么是 Kivy,为什么,以及如何使用环境,用 Kivy 构建了一个基本的应用程序,用一个按钮代码的例子比较了 Kivy 和 Kivymd。在下一篇文章中,我们将继续我们的旅程,探索 Kivymd 中的各种其他关键元素。如果你喜欢这篇文章,请在 medium 上关注我,这样你就会收到关于即将发布的部分的通知。说完了,再见!

你可以在这里找到我:
LinkedIn: 链接

GitHub: 链接

更新:第二部分在这里:

[## 用 Python 构建 Android 应用程序:第 2 部分

使用 Python 构建 Android 应用程序的分步指南

medium.com](https://medium.com/swlh/building-android-apps-with-python-part-2-1d8e78ef9166)

用 Python 构建 Android 应用程序:第 3 部分(结论)

原文:https://towardsdatascience.com/building-android-apps-with-python-part-3-89a455ee7f7c?source=collection_archive---------8-----------------------

使用 Python 构建 Android 应用程序的分步指南

在前两部分中,我们已经看到了 Kivy 和 Kivymd 如何让使用 Python 开发应用程序变得超级容易,尽管它也有缺点。我们已经介绍了应用程序开发的基础知识,如何显示文本、接受输入以及使用按钮使我们的应用程序具有交互性。我们还看到了 Kivy 支持的各种 UI/UIX 元素,以及如何使用 Kivy 字符串构建器轻松实现它们,Kivy 字符串构建器以分层格式编写,不需要任何显式的导入语句。如果你没有读过前面的部分,我建议你看一看,以便更好地理解。

[## 用 Python 构建 Android 应用程序:第 2 部分

使用 Python 构建 Android 应用程序的分步指南

medium.com](https://medium.com/swlh/building-android-apps-with-python-part-2-1d8e78ef9166) [## 用 Python 构建 Android 应用程序:第 1 部分

使用 Python 构建 Android 应用程序的分步指南

towardsdatascience.com](/building-android-apps-with-python-part-1-603820bebde8)

在这一部分中,我们将涵盖 Kivymd 中所有剩余的常用元素,在另一部分中,我们将构建我们的 capstone 应用程序,该应用程序将使用 weather API 获取天气相关信息,将该应用程序转换为 Android APK,并将其部署在在线平台上。这不是很酷吗?

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

迈克·什切潘斯基在 Unsplash 上的照片

MDDialog

上次我们构建了一个基本的应用程序,它将密码作为输入,与我们的关键字“root”进行比较,并在屏幕上以文本形式显示成功或失败的消息。如果弹出一个对话框,不仅显示操作的结果,还给出更多的选项,该怎么办?这种类型的功能可以在 MDDialog 的帮助下完成。让我们看看它的实现:

查看进行比较时对话框是如何调用的

输出如下所示:

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

作者 GIF

可以在对话框中修改各种属性,如:

  1. 各种类型的事件,包括 on_pre_open、on_open、on _ pre _ dissolve、on _ dissolve
  2. 对话框的“标题”。在示例中,密码检查是框的标题。
  3. 框的“文本”。这里我们以成功或失败为文本。
  4. 控制盒子的“半径”,使其为圆形、椭圆形。
  5. 添加按钮,列表,使它成为一个可以接受输入的表单,等等。

点击阅读更多关于这些功能的信息。

MDList(一行、两行和三行列表项目)

列表是应用程序开发中最常用的实体之一。它是带有图像的文本的垂直连续索引。MDList 与滚动视图和列表项相结合,构成一个功能列表。Kivymd 中有不同类型的列表项,从 OneLineListItem 到 ThreeLineAvatarIconListItem。以下示例涵盖了列表中所有类型的项目:

看看它的输出:

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

所有不同类型的列表项

头像和图标之间的基本区别是,图标大多是预定义的,免费提供,它们不需要通过源代码明确引用。头像更多的是一个被引用到个人资料的图像,虽然它也可以用在列表项目中。这些项目包含可以使用 MDLabel 的文本属性进行修改的文本。

MDDataTables

数据表用于以行和列的形式显示表格数据。这是 Kivymd 提供的一个简单而强大的工具。它可以与按钮或任何其他动作相链接。行项目可以与复选框相结合,以表格格式制作待办事项列表。您可以添加分页,控制要显示的行数。让我们检查它的代码:

有趣的结果是:

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

作者 GIF

MDToolbar

你们都已经看到在 android 应用程序中,我们有一个顶部剥离的部分,在那里应用程序的名称被提到,在左边有三行,在右边有三个点。它被称为工具栏,在应用程序中,让它更容易访问和组织不同的操作是非常重要的。像往常一样,Kivymd 带有选项,这个也有两个选项:顶部工具栏和底部工具栏。两者都有各自的优势和特点,但是在这个系列中,我们将关注顶部工具栏。如果您想了解底部工具栏的更多信息,请点击此链接。一个简单的工具栏编码如下:

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

作者图片

现在,如果你点击 3 点菜单,它会崩溃的应用程序,因为它需要一个回调。回调定义了应该对特定事件采取什么操作。要做一个功能菜单,我们需要一个叫导航抽屉的东西,我们来看看是什么。

MDNavigationDrawer

这就是事情变得有趣的地方。现在,我们终于可以在我们的应用程序中构建一个包含不同部分的菜单来浏览了。导航抽屉使我们可以在应用程序中访问不同的目的地。在我展示代码解释之前,这里还有一个概念。Kivymd 提供了不同类型的布局。布局是一种可以安排所有元素的蓝图。MDToolbar 通常放置在 BoxLayout 中。点击了解更多关于布局的信息。现在仔细看看这段代码:

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

作者 GIF

在这里,我将 MDToolbar 放在了一个 BoxLayout 中,而在 MDNavigationDrawer 中,我使用了一个 AnchorLayout,这样我就可以在菜单栏中有一个简介部分。在这一部分之后,我们有了包含两个目的地的 MDList,Home 和 About。现在我们已经在 android 应用程序的旅程中走了这么远,让我们看看如何使用不同的屏幕并使用相同的 MDNavigation bar。

切换屏幕(屏幕管理器)

顾名思义,ScreenManager 是用来管理我们希望包含在应用程序中的所有屏幕的。它用一个唯一的 id 保存所有的屏幕,这个 id 可以用来在动作上切换屏幕。为了在所有屏幕中使用相同的工具栏,我们将把屏幕管理器和 NavigationDrawer 放在 **NavigationLayout 中。**现在,如果我们转到导航栏并点击“关于”或“信息”,什么也不会发生,但我们可以将其绑定到切换屏幕。只需参考屏幕管理器的 id,将当前屏幕更改为您想要的屏幕。请看这里的例子:

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

作者 GIF

结论和下一步

在本系列的这一部分中,我们讨论了应用程序开发中使用的更多元素。我们学习了如何使用对话框使应用程序交互,如何创建工具栏,以及在特定的动作/事件上切换屏幕。在接下来的一篇文章中,我将制作一个应用程序,将其转换为 APK 并部署在云平台上,请继续关注那篇文章。如果您喜欢这个开发系列,请务必在 medium 上关注我,这样您就可以收到关于即将发布的文章的通知,如果您有任何疑问,请发表评论,就这样说吧,再见!

LinkedinGithub

更新:Kivy apps 的转换/部署文章现已上线!

[## 将 Python 应用程序转换为 APK 的 3 种方法

结束构建 Python 系列的 Android 应用程序!

towardsdatascience.com](/3-ways-to-convert-python-app-into-apk-77f4c9cd55af)

在稀疏的热编码数据上构建自动编码器

原文:https://towardsdatascience.com/building-autoencoders-on-sparse-one-hot-encoded-data-53eefdfdbcc7?source=collection_archive---------14-----------------------

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

维罗妮卡·贝纳维德斯在 Unsplash 上的照片

适用于在 PyTorch 中嵌入稀疏独热编码数据的损失函数的实践回顾

自 1986 年引入以来[1],通用自动编码器神经网络已经渗透到现代机器学习的大多数主要部门的研究中。自动编码器已经被证明在嵌入复杂数据方面非常有效,它提供了简单的方法将复杂的非线性依赖关系编码成简单的矢量表示。但是,尽管它们的有效性已经在许多方面得到了证明,但它们通常不能再现稀疏数据,尤其是当列像热编码一样相关时。

在这篇文章中,我将简要讨论一个热编码(OHE)数据和通用自动编码器。然后,我将介绍使用自动编码器对一个热编码数据进行训练所带来的问题的用例。最后,我将深入讨论重建稀疏 OHE 数据的问题,然后讨论我发现在这些条件下工作良好的 3 个损失函数:

  1. 共同嵌入损失
  2. 索伦森-戴斯系数损失
  3. 个体 OHE 成分的多任务学习损失

—解决上述挑战,包括在 PyTorch 中实现它们的代码。

一个热编码数据

One hot 编码数据是一般机器学习场景中最简单但经常被误解的数据预处理技术之一。该过程将具有‘N’个不同类别的分类数据二进制化为 N 列二进制 0 和 1,其中在第‘N’个类别中出现 1 表示观察值属于该类别。使用sci kit-Learn onehotencode 模块,这个过程在 Python 中很简单:

**from** sklearn.preprocessing **import** OneHotEncoder
**import** numpy **as** np# Instantiate a column of 10 random integers from 5 classes
x = **np.random.randint**(5, size=10).reshape(-1,1)**print**(x)
>>> [[2][3][2][2][1][1][4][1][0][4]]# Instantiate OHE() + Fit/Transform the data
ohe_encoder = **OneHotEncoder**(categories="auto")
encoded = ohe_encoder.**fit_transform**(x).**todense**()**print**(encoded)
>>> matrix([[0., 1., 0., 0., 0.],
           [0., 0., 0., 1., 0.],
           [0., 0., 1., 0., 0.],
           [0., 0., 0., 1., 0.],
           [0., 0., 1., 0., 0.],
           [1., 0., 0., 0., 0.],
           [0., 0., 1., 0., 0.],
           [0., 0., 1., 0., 0.],
           [0., 0., 0., 1., 0.],
           [0., 0., 0., 0., 1.]])**print**(**list**(ohe_encoder.**get_feature_names()))** >>> ["x0_0", "x0_1", "x0_2", "x0_3", "x0_4"]

虽然简单,但是如果你不小心的话,这种技术会很快变质。它很容易给数据增加额外的复杂性,并改变某些数据分类方法的有效性。例如,转换为 OHE 向量的列现在是相互依赖的,这种交互使得在某些类型的分类器中很难有效地表示数据的各个方面。例如,如果您有一个包含 15 个不同类别的列,则需要一个深度为 15 的决策树来处理这个热编码列中的 if-then 模式。如果你感兴趣,可以在这里找到这些问题的一个很好的例子。类似地,由于列是相互依赖的,如果您使用带有 bagging(Bootstrap Aggregating)的分类策略并执行特征采样,您可能会完全错过独热编码列,或者只考虑其部分组件类。

自动编码器

自动编码器是无监督的神经网络,用于将数据嵌入到有效的压缩格式中。它通过利用编码和解码过程将数据编码成更小的格式,然后将该更小的格式解码回原始输入表示来实现这一点。通过获取模型重建(解码)和原始数据之间的损失来训练模型。

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

A. Dertat 在他的 TDS 文章中提供:应用深度学习——第 3 部分:自动编码器

实际上用代码表示这个网络也很容易做到。我们从两个函数开始: 编码器 模型,和 解码器 模型。这两个“模型”都被打包到一个名为 Network 的类中,该类将包含我们培训和评估的整个系统。最后,我们定义了一个函数 Forward ,PyTorch 使用它作为进入网络的入口,该网络包装了数据的编码和解码。

**import** torch
**import** torch.nn **as** nn
**import** torch.nn.functional **as** F
**import** torch.optim **as** optim**class** **Network**(nn.Module):
   **def** **__init__**(self, input_shape: int):
      **super**().**__init__**()
      **self**.**encode1** = nn.**Linear**(input_shape, 500)
      **self**.**encode2** = nn.**Linear**(500, 250)
      **self**.**encode3** = nn.**Linear**(250, 50)

      **self**.**decode1** = nn.**Linear**(50, 250)
      **self**.**decode2** = nn.**Linear**(250, 500)
      **self**.**decode3** = nn.**Linear**(500, input_shape) **def** **encode**(**self**, x: torch.Tensor):
      x = F.**relu**(**self**.**encode1**(x))
      x = F.**relu**(**self**.**encode2**(x))
      x = F.**relu**(**self**.**encode3**(x))
      **return** x **def decode**(**self**, x: torch.Tensor):
      x = F.**relu**(**self**.**decode1**(x))
      x = F.**relu**(**self**.**decode2**(x))
      x = F.**relu**(**self**.**decode3**(x))
      **return** x **def** **forward**(self, x: torch.Tensor):
      x = **encode**(x)
      x = **decode**(x)
      **return** x **def** **train_model**(data: pd.DataFrame):
   net = **Network**()
   optimizer = optim.**Adagrad**(net.parameters(), lr=1e-3, weight_decay=1e-4)
   losses = [] **for** epoch **in** **range**(250):
     **for** batch **in** **get_batches**(data)
        net.**zero_grad**()

        # Pass batch through 
        output = **net**(batch)

        # Get Loss + Backprop
        loss = **loss_fn**(output, batch).sum() # 
        losses.**append**(loss)
        loss.**backward**()
        optimizer.**step**()
     **return** net, losses

正如我们在上面看到的,我们有一个编码函数,它从输入数据的形状开始,然后随着它向下传播到 50 的形状,减少它的维数。从那里,解码层获得嵌入,然后将其扩展回原始形状。在训练中,我们从解码器获取重构,并获取重构相对于原始输入的损失。

损失函数的问题

现在我们已经介绍了自动编码器的结构和 One Hot 编码过程,我们终于可以谈谈在自动编码器中使用 One Hot 编码的相关问题,以及如何解决这个问题了。当自动编码器将重构与原始输入数据进行比较时,必须对建议的重构与真实值之间的距离进行一些评估。通常,在输出的值被认为彼此不相交的情况下,将使用交叉熵损失或 MSE 损失。但是在我们的 One Hot 编码的情况下,有几个问题使得系统更加复杂:

  1. 一列中出现一意味着其对应的 OHE 列中必须有一个零。 即列不相交
  2. OHE 向量输入的稀疏性会导致系统 选择简单地为大多数列返回 0 的 以减少误差

这些问题结合起来导致上述两个损失(MSE,交叉熵)在重建稀疏 OHE 数据时无效。下面我将介绍三个损失,它们提供了上述一个或两个问题的解决方案,以及在 PyTorch 中实现它们的代码:

余弦嵌入损失

余弦距离是一种经典的向量距离度量,通常在比较 NLP 问题中的单词包表示时使用。距离的计算方法是找出两个向量之间的余弦角,计算公式如下:

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

作者图片

这种方法被证明在量化稀疏 OHE 嵌入的重构中的误差方面是很好的,因为它能够考虑各个列中二进制值的偏差来评估两个向量的距离。这个 loss 是 PyTorch 中最容易实现的,因为它在torch . nn . cosinembeddingloss中有一个预构建的解决方案

loss_function = torch.nn.**CosineEmbeddingLoss**(reduction='none')# . . . Then during training . . . loss = **loss_function**(reconstructed, input_data).sum()
loss.**backward**()

骰子损失

骰子损失是索伦森骰子 系数【2】的一种实现,在分割任务的计算机视觉领域非常流行。简单地说,它是两个集合之间重叠的度量,并且与两个向量之间的 Jaccard 距离有关。dice 系数对向量中列值的差异高度敏感,并且在图像分割中很流行,因为它利用这种敏感性来有效地区分图像中的像素边缘。骰子损失遵循以下等式:

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

作者图片

想了解更多关于索伦森骰子系数的信息,你可以看看杜的这篇博文

PyTorch 没有内部实现的骰子系数 。但是可以在 Kaggle 的损失函数库——Keras&py torch[3]中找到一个很好的实现:

class **DiceLoss**(nn.Module):
    def __init__(self, weight=None, size_average=True):
        super(DiceLoss, self).__init__()

    def **forward**(self, inputs, targets, smooth=1):

        *#comment out if your model contains a sigmoid acitvation*
        inputs = F.**sigmoid**(inputs)       

        *#flatten label and prediction tensors*
        inputs = inputs.view(-1)
        targets = targets.view(-1)

        intersection = (inputs * targets).sum()                            
        dice = (2.*intersection + smooth)/
               (inputs.sum() + targets.sum() + smooth)  

        return 1 - dice

不同 OHE 列的个体损失函数

最后,您可以将每个热编码列视为其自己的分类问题,并计算每个分类的损失。这是一个多任务学习问题的用例,其中自动编码器正在解决重建输入向量的各个分量。当您的输入数据中有几个/全部 OHE 列时,这种方法最有效。例如,如果您有一个编码列,前七列是 7 个类别:您可以将其视为多类别分类问题,并将损失视为子问题的交叉熵损失。然后,您可以将子问题的损失组合在一起,并将其作为整个批次的损失向后传递。

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

作者图片

下面你会看到这个过程的一个例子,有三个 One Hot 编码列,每个列有 50 个类别。

from torch.nn.modules import _Loss
from torch import argmaxclass **CustomLoss**(_Loss):
  **def** **__init__**(self):
    **super**(CustomLoss, self).__init__() def **forward**(self, input, target):
    """ loss function called at runtime """

    # Class 1 - Indices [0:50]
    class_1_loss = F.**nll_loss**(
        F.**log_softmax**(input[:, 0:50], **dim**=1), 
        **argmax**(target[:, 0:50])
    ) # Class 2 - Indices [50:100]
    class_2_loss = F.**nll_loss**(
        F.**log_softmax**(input[:, 50:100], **dim**=1), 
        **argmax**(target[:, 50:100])
    ) # Class 3 - Indices [100:150]
    class_3_loss = F.**nll_loss**(
        F.**log_softmax**(input[:, 100:150], **dim**=1), 
        **argmax**(target[:, 100:150])
    ) **return** class_1_loss **+** class_2_loss **+** class_3_loss

在上面的代码中,您可以看到如何对重构输出的子集进行单个损失,然后在最后合并为一个总和。这里我们使用一个 负对数似然损失 ( nll_loss ),它对于多类分类方案是一个很好的损失函数,并且与 交叉熵损失相关。

谢谢大家!

在本文中,我们浏览了 One Hot Encoding 分类变量的概念以及自动编码器的一般结构和目标。我们讨论了一个热编码向量的缺点,以及尝试在稀疏的一个热编码数据上训练自动编码器模型时的主要问题。最后,我们讨论了解决稀疏热编码问题的 3 个损失函数。尝试训练这些网络没有更好或更坏的损失,在我介绍的功能中,没有办法知道哪一个适合您的用例,直到您尝试它们!

下面我已经包括了一堆深入到我上面讨论的主题的资源,以及一些我提出的损失函数的资源。

来源

  1. D.E. Rumelhart,G.E. Hinton 和 R.J. Williams,“通过错误传播学习内部表征”并行分布式处理。第一卷:基础。麻省理工学院出版社,剑桥,麻省,1986 年。
  2. 特伦森(1948 年)。“在植物社会学中基于物种相似性建立等幅群的方法及其在丹麦公共地植被分析中的应用”。 孔格里格丹斯克5(4):1–34。 骰子,李 R. (1945)。“物种间生态关联数量的度量”。生态学26(3):297–302。
  3. Kaggle 的损失函数库:https://www . ka ggle . com/bigiron sphere/Loss-Function-Library-keras-py torch

提到的其他有用资源

  1. OHE 数据的问题:https://towards Data science . com/one-hot-encoding-is-making-your-tree-based-ensembles-worse-heres-why-d64b 282 b 5769
  2. 装袋背景:https://towards data science . com/ensemble-methods-Bagging-boosting-and-stacking-c 9214 a 10 a 205
  3. 关于骰子系数的一篇大文章:https://medium . com/ai-salon/understanding-Dice-loss-for-crisp-boundary-detection-bb 30 C2 e 5 f 62 b

使用 Matplotlib 构建条形图

原文:https://towardsdatascience.com/building-bar-charts-using-matplotlib-c7cf6db3e728?source=collection_archive---------7-----------------------

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

图片鸣谢:https://www . can va . com/design/DADvjWtEzNo/snhmmyko 16 hhxicldcexxq/edit?category=tACFakiSKJ8

如何使用条形图展示数据的指南

条形图是一种数据可视化技术,可用于表示数据集中的数值,以显示不同数据点之间的差异。它使用一根棒作为量值的度量。条形越大,数字越高。例如,如果一个人在比较财富,条形图中较大的条形比较小的条形意味着更多的钱。

使用 Jupyter 笔记本构建条形图的分步指南

加载数据集

英超联赛 2019/20 赛季中期最高进球得分数据集是使用 IBM Watson Studio 上的 Jupyter Notebook 加载的。

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

英超联赛 2019/20 赛季中期前五名射手

导入数据可视化包

为了运行将生成条形图的代码,导入了一个名为 matplotlib 的数据可视化包。下面是一组用于导入条形图的代码。python 编程语言中使用 Matplotlib 作为绘图库。

*## Import data visualization packages*
**import** **matplotlib.pyplot** **as** **plt**
%matplotlib inline

创建条形图

条形图是在安装包后通过运行下面的代码集构建的。

plt.bar("Player", "Stat", data = df_goal, color = "blue")
plt.xlabel("Players")
plt.ylabel("Goal Scored")
plt.title("Highest goal scorers in the Premier league 2019-20 by mid-season")
plt.show()

plt.bar("Player “,” Stat ",data = df_goal,color = "blue ")用于表示希望绘制一个条形图,使用 Player 列作为 x 轴,Stat 列作为 y 轴,使用 df_goal 数据集,并且条的颜色为蓝色。plt.xlabel(“球员”)和 plt.ylabel(“进球”)分别用于标注 x 轴和 y 轴。plt.title(“英超联赛 2019-20 赛季中期最高进球者”)用于为图表制作标题。plt.show()用于使用前面的命令生成图形。

上面运行的代码的结果可以在下面看到。

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

显示英超 2019/20 赛季中期进球最多球员的条形图。

在上面的条形图中可以看到,x 轴刻度无法正常显示。因此,x 轴记号在旋转后会变得可见。下面是一组修改条形图的代码。

plt.bar("Player", "Stat", data = df_goal, color = "blue")
plt.xlabel("Players")
plt.xticks(rotation = 90)
plt.ylabel("Goal Scored")
plt.title("Highest goal scorers in the Premier league 2019-20 by mid-season")
plt.show()

通过添加 plt.xticks(旋转= 90°),条形图可以转换为:

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

一个改进的条形图显示了英超 2019/20 赛季中期的最高进球得分者。

这是一个更清晰的条形图,x 轴刻度现在垂直且可见。

创建水平条形图

也可以通过将前一组代码中的 plt.bar 更改为 plt.barh 来构建水平条形图。

plt.barh("Player", "Stat", data = df_goal, color = "red") plt.xlabel("Players") 
plt.ylabel("Goal Scored") 
plt.title("Highest goal scorers in the Premier league 2019-20 by mid-season")
plt.show()

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

显示英超 2019/20 赛季中期最高进球得分者的水平条形图。

条形图和水平条形图都可以修改,看起来更漂亮。

美化条形图

可以通过运行下面的代码集来修改条形图。

df_goal2 = df_goal[['Player', 'Stat']].sort_values(by = 'Stat', ascending = **True**)
ind = df_goal2.set_index("Player", inplace = **True**)
*## A modified bar graph*
bar = df_goal2.plot(kind='bar',figsize=(30, 16), color = "blue", legend = **None**)
bar
plt.yticks(fontsize = 24)
plt.xticks(ind,fontsize = 18)
plt.xlabel("Players", fontsize = 20)
plt.ylabel("Goal scored", fontsize = 20)
plt.title("Higehst goal scorers in the premier league mid-season of 2019/20", fontsize=32)
bar.spines['top'].set_visible(**False**)
bar.spines['right'].set_visible(**False**)
bar.spines['bottom'].set_linewidth(0.5)
bar.spines['left'].set_visible(**True**)
plt.show()

与构建条形图的常规代码相比,增加了一些内容。从上面可以看出,使用新形成的数据集 df_goal2 创建了一个名为 bar 的对象,用代码 bar = df_goal2.plot(kind='bar ',figsize=(30,16),color = "blue ",legend = None )设计了一个条形图。ind 用于存储将由 x 轴表示的索引。

顶部和右侧的书脊被移除,但底部和左侧的书脊仍然可见,使用代码:bar.spines[‘top’]。set_visible( False ),bar.spines[‘右’]。set_visible( False ),bar.spines[‘bottom’]。set_linewidth(0.5)和 bar.spines[‘left’]。set_visible( True )。

这些代码的结果可以在下面看到。

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

一个漂亮的条形图,显示了英超 2019/20 赛季中期的最高进球得分者。

美化水平条形图

美化条形图的相同过程适用于水平条形图。下面是构建美化版的一组代码。

*## A modified horizontal bar graph*
barh = df_goal2.plot(kind='barh',figsize=(30, 16), color = "red", legend = **None**)
barh
plt.yticks(fontsize = 24)
plt.xticks(ind,fontsize = 18)
plt.xlabel("Goal scored", fontsize = 22)
plt.ylabel("Players", fontsize = 22)
plt.title("Higehst goal scorers in the premier league mid-season of 2019/20", fontsize=32)
barh.spines['top'].set_visible(**False**)
barh.spines['right'].set_visible(**False**)
barh.spines['bottom'].set_linewidth(0.5)
barh.spines['left'].set_visible(**True**)
plt.show()

运行代码后,结果显示为下面的水平条形图:

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

一个漂亮的水平条形图,显示了英超 2019/20 赛季中期的最高进球得分者。

对美化的条形图中的脊线进行的相同观察也可以对该图中的脊线进行。

条形图在多种数字应用中非常有用,例如显示人们的健康改善如何随着时间的推移而变化,描绘财富如何增加以及其他有趣的概念。

这里可以找到用于这个项目的完整版本的代码

使用 TensorFlow Hub 构建更好的人工智能应用

原文:https://towardsdatascience.com/building-better-ai-apps-with-tf-hub-88716b302265?source=collection_archive---------49-----------------------

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

来源:tensorflow.org

人工智能最大的好处之一就是你有很多开源内容,我们经常使用它们。我将展示 TensorFlow Hub 如何简化这一过程,并允许您在应用程序中无缝地使用预先训练的卷积或单词嵌入。然后,我们将了解如何使用 TF Hub 模型执行迁移学习,以及如何将其扩展到其他用例。

这篇博文中用于演示的所有代码都可以在这个 GitHub repo-上获得

[## 里希特-达格利/GDG-纳什克-2020

我在谷歌开发者小组 Nashik 2020 的会议。通过创造……为里希特-达格利/GDG-纳西克-2020 的发展做出贡献

github.com](https://github.com/Rishit-dagli/GDG-Nashik-2020)

我也在 GDG(谷歌开发者组织)Nashik 发表了一个关于这个的演讲,在这里找到录音版本-

TF Hub 背后的动机

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

来源:me.me

我们都使用开源代码,我们试着做一些调整让它变得更好,也许让它为我们工作。我觉得这就是社区的力量,你可以和世界各地的人分享你的作品。

  • 让使用开源代码变得简单

所以这是 TF Hub 关注的主要问题,让开源代码、模型和数据集的使用变得超级简单。

  • 更快地构建应用程序

由于使用了预构建的内容,您可以更快地开发应用程序,因为现在您可以访问其他人已经完成的工作并利用这些工作。

  • 构建更好的应用程序

不是每个人都有机会使用高功率 GPU 或 TPU,并在几天内训练模型,您可以通过使用迁移学习构建开源内容开始,我们将看到您如何利用这一点。比方说,假设你想建立一个模型,将你收到的关于你的产品的所有评论,看看它们是好评论还是坏评论。你可以使用维基百科数据集上训练的模型中的单词嵌入,并在一段时间内做得很好。这是一个非常简单的例子来解释它,我们将在后面看到更多。

什么是 TF Hub

  • 建模是一个重要的部分

建模是任何机器学习应用程序的重要部分,你会想要投入相当多的时间和精力来做好这件事。另外请注意,我并不是说建模是唯一重要的事情,事实上,有很多事情就像建立管道,为模型服务,但我们不会在这篇博客中探讨它们。TF Hub 帮助您更好、更快、更容易地完成模型部分。

  • 一种轻松发现模型的方法

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

tfhub.dev

你可以在 tfhub.dev 看到一个 GUI 和一个友好版本的 TensorFlow Hub,你可以在这里看到 Hub。您可以根据想要解决的问题类型、需要的模型格式以及发布者来筛选模型。这无疑使模型发现过程变得更加容易。

  • 最先进的模型

你可以在 TF Hub 上找到很多经过良好测试的最先进的模型。TF Hub 上的每个模型都有很好的文档记录,并且经过了全面的测试,所以作为开发人员,您可以充分利用它。TF Hub 上的许多模型甚至有示例 Colab 笔记本来展示它们是如何工作的。

  • 易于使用和集成模型 API

更好的是,您可以轻松地将其与您的模型 API 集成,因此您希望在构建模型时具有灵活性,TF Hub 可以帮助您做到这一点。然后你也会看到 TF Hub 与 Keras 或核心 TensorFlow APIs 的集成有多好,这真的让它变得超级简单。

  • 众多的出版商

这可能不是你想考虑 TF Hub 的第一件事,但了解 TF Hub 的大量发行商也很有好处,一些主要发行商在下图中列出。

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

TF Hub 上的一些出版商

  • 没有代码依赖性

因此,很多时候,你的代码库变得非常依赖或耦合,这会使实验和迭代过程慢很多,所以 Hub 为你定义了不依赖于代码的工件,这样你就有了一个允许更快迭代和实验的系统。

  • 各种平台

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

演职员表:桑迪普·古普塔

TF Hub 的另一个优点是,无论您使用高级 Keras APIs 还是低级 API 都没有关系。您还可以在生产级管道或系统中使用它,它与 TensorFlow Extended 也能很好地集成。您还可以将 TF.js 模型用于基于 web 的环境或节点环境。Edge 正在起飞,TF Hub 也在这方面为您提供了帮助,您可以使用 TF Lite 预训练模型直接在您的移动设备和低功耗嵌入式系统中运行您的模型。您还可以找到 Coral Edge TPUs 的模型。它本质上只是 TF Lite,并将其与强大的 edge TPU 相结合。

理解使用 TF Hub 背后的想法

让我们从迁移学习说起,它赋予了 TF Hub 强大的力量。你可能还知道,从头开始制作任何模型都需要良好的算法选择和架构、大量数据、计算,当然还有领域专业知识。那看起来很多。

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

使用 TF Hub 背后的想法

所以你用 TF Hub 做的事情是,有人把所有需要做模型的东西从零开始,做一个所谓的模块,然后取出模型中可以重复使用的部分。所以在文本的情况下,我们使用单词嵌入,这给了它很大的能力,并且通常需要相当多的计算来训练。就图像而言,它可能是特征。因此,您可以从 TF Hub repo 的一个模块中获得这个可重用的部件。有了迁移学习,这个可重复使用的部件可以用在你不同的模型中,它甚至可以服务于不同的目的,这就是你使用 TF Hub 的基本方式。因此,当我说不同的目的时,它可能是在一千个标签上训练的分类器,但你只是用它来预测或区分 3 个类别。这只是一个例子,但你现在可能明白了。

为什么使用迁移学习?

  • 一般化

迁移学习允许您对数据进行归纳,这在您想要对真实数据运行模型时特别有用。

  • 数据较少

因为你已经预先学习了嵌入、权重或卷积,所以你可以用很少的数据训练高质量的模型。当您无法获取更多数据或者获取更多数据的成本太高时,这非常有用。

  • 训练时间

我们之前已经讨论过,迁移学习需要更少的训练时间。

实践中的 TF Hub

  • 安装 TF 轮毂

我们不会在这里集中安装 TF Hub,它非常简单,在这里找到安装步骤。

  • 装载型号

你可以很容易地用这段代码加载你的模型-

MODULE_HANDLE = '[https://tfhub.dev/google/imagenet/inception_v3/classification/4](https://tfhub.dev/google/imagenet/inception_v3/classification/4)'module = hub.load(MODULE_URL)

当然,您可以为您需要的模型更改MODULE_HANDLE URL。

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

因此,当您调用model. load方法时,TF Hub 会为您下载它,您会注意到这是一个保存的模型目录,并且您的模型是一个 protobuf 文件,它会为您进行图形定义。

  • 保存的模型 CLI

还有一个很棒的界面叫做保存模型 CLI,我觉得它非常有用。这为您提供了许多关于已保存模型的有用信息,如操作签名和输入输出形状。

!saved_model_cli show --dir [DIR] --all

以下是显示该工具提供的信息的示例输出-

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

保存的模型 CLI 输出

  • 推理

现在,您可以直接对您加载的模型执行推理。

tf.nn.softmax(module([img]))[0]

但是这是一个糟糕的方法,因为你没有推广你的模型。

对图像进行推理

很多时候使用图像特征向量更好。它们将最终分类图层从网络中移除,并允许您在此基础上训练网络,从而实现更高的泛化能力,进而提高现实数据的性能。

你可以简单地用这种方式来做-

model = tf.keras.Sequential([ hub.KerasLayer(MODULE_HANDLE, input_shape=IMG_SIZE + (3,), output_shape=[FV_size], trainable=True), tf.keras.layers.Dense(NUM_CLASSES, activation='softmax')])

所以你可以看到我现在使用hub.KerasLayer创建我的模型作为 Keras 层,我也设置trainableTrue,因为我想执行迁移学习。

因此,我们可以让我们的模型在它之后添加一个Dense层,这样您就可以让模型添加您自己的层,然后用您拥有的数据对它进行重新训练,当然,您可以在此基础上添加多个层,甚至卷积层。然后你可以像其他 Keras 模型一样编译它。装配和编译过程保持不变,这向我们展示了 TF Hub 的集成水平。

使用基于文本的模型

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

将文本转换为数字时,我们需要解决的一个主要问题是,您需要以保留文本的含义或语义的方式进行转换。我们经常使用所谓的单词嵌入来做到这一点。如你所见,单词向量顾名思义就是向量,语义相似的单词有相似的向量方向。向量大小的维数也称为嵌入维数。培训的大部分是关于学习这些嵌入。

我会加载嵌入这样的东西-

embedding = "URL"hub_layer = hub.KerasLayer(embedding, input_shape=[], 
                           dtype=tf.string, trainable=True)

加载部分是事情变得有点不一样的地方,所以你可以这样做来指定你正在加载嵌入,然后你就可以在你的神经网络中使用它了,就像我们之前做的一样。所以在实践中没有太大的区别,但是知道如何处理单词嵌入是很好的

另一件要考虑的事情

事实上,这还有另外一个特点。假设我正在使用一个返回 20 维嵌入向量的嵌入层。这意味着如果你传入一个单词,它会返回一个 1 乘 20 的数组。

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

单字嵌入

假设我传递了两个句子,我想让你们看看它的输出形状 2 乘 20,2 当然是因为我传递了一个有两个条目的列表,但是为什么我有一个 20。每个单词都应该有 20 维的输出向量,那么为什么一个完整的句子有 20 维的向量呢?它会智能地将这些单词嵌入转换成句子嵌入,你不再需要担心保持形状不变之类的问题。

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

两个句子的嵌入

尝试一些例子!

我强烈建议您亲自尝试这些示例,它们可以在 Colab 中运行。在这篇文章的 GitHub repo 中找到它们-

[## 里希特-达格利/GDG-纳什克-2020

我在谷歌开发者小组 Nashik 2020 的会议。通过创造……为里希特-达格利/GDG-纳西克-2020 的发展做出贡献

github.com](https://github.com/Rishit-dagli/GDG-Nashik-2020)

  1. 神经类型转移

一个神经类型的传递算法理想地需要相当多的计算和时间,我们可以使用 TensorFlow Hub 来轻松地完成这个任务。我们将从定义一些辅助函数开始,将图像转换成张量,反之亦然。

然后你可以将图像转换成张量,创建一个任意的图像风格化模型模型,我们可以马上开始构建图像!

hub_module = hub.load('https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2')combined_result = hub_module(tf.constant(content_image_tensor[0]), tf.constant(style_image_tensor[1]))[0]tensor_to_image(combined_result)

有了这个,你现在可以创建一个像这样的图像(GitHub repo 中的图像)

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

神经风格转移的输出

2.文本分类

我们现在来看看如何利用迁移学习来建立一个模型。我们将在 IMDB 数据集上尝试预测评论是正面还是负面的。我们可以使用在 130 GB 谷歌新闻数据上训练的gnews-swivel嵌入。

所以,我们可以像这样简单地加载我们的模型-

embedding = "https://tfhub.dev/google/tf2-preview/gnews-swivel-20dim/1"

hub_layer = hub.KerasLayer(embedding, input_shape=[], dtype=tf.string, trainable=**True**)

我们可以在此基础上建立一个模型-

model = tf.keras.Sequential([
        hub_layer,
        tf.keras.layers.Dense(16, activation='relu'),
        tf.keras.layers.Dense(1, activation='sigmoid')])

然后你可以像训练其他 Keras 模型一样训练你的模型

关于我

大家好,我是里希特·达利

推特

网站

如果你想问我一些问题,报告任何错误,建议改进,给我反馈,你可以发邮件给我

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值