TowardsDataScience-博客中文翻译-2020-七十九-

TowardsDataScience 博客中文翻译 2020(七十九)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

迷失在密林中:用简单的代码对机器学习中稀疏性的直觉!

原文:https://towardsdatascience.com/lost-in-a-dense-forest-intuition-on-sparsity-in-machine-learning-with-simple-code-2b44ea7b07b0?source=collection_archive---------34-----------------------

为什么 ML 需要稀疏性?理解稀疏性的核心概念。

Sebastian Unrau 在 Unsplash 上的照片

看看这片美丽的森林吧!现在,想象你有机会对这片美丽的森林进行数据分析。

当前的任务是找出在森林中的每一个区域的熊猫数量与树木的数量之比。成功执行分析后,您意识到树木的密度比熊猫的种类要大得多。

将其转换为矩阵形式后,您会得到一个类似下图的图像:

作者备用矩阵。来自 freepik.com图片

在这里,我们可以注意到有一些可爱的熊猫分散在各处,但矩阵的密度主要由树木组成。让我们假设 trees 的值= '0 ',panda 的值=任何非零值比如说' 1 '。这个图像将形成一个由 0 和 1 组成的矩阵。这意味着整个矩阵密度将包括大多数为 0 的和极少数为 1 的 T10

这种类型的矩阵主要由 0 和较少的非零数字组成,称为稀疏矩阵

无论是机器学习还是深度学习,我们都会遇到很多稀疏性。它们经常出现在数据计数、单词编码中,并且主要出现在自然语言处理领域中,在对单词进行矢量化的过程中,会用到单词包、tf-idf、word2vec 等概念。

这是否意味着稀疏是一件好事?

可惜没有!稀疏并没有多大帮助。反而导致一定的问题。让我们在下一节讨论这些问题是什么。

稀疏矩阵的问题:

  • 稀疏矩阵在计算上是昂贵的,因为矩阵结构中存在大量的冗余零。具有大尺寸的问题极大地增加了空间复杂性,并且解决这些问题变得具有挑战性。机器学习算法将不会像预期的那样有效地工作,这是由于不断增长的规模以及可能由于缺乏穷尽的资源。
  • 引起的其他重要问题是有效计算矩阵的速度时间减少,以及机器学习算法的计算处理速度降低,这最终导致总体时间复杂度不好或者有时甚至糟糕的关键问题。出现这个问题的原因是因为计算过程花费的时间较长。

下一节将讨论解决这些问题和应对这些挑战的解决方案。

处理稀疏矩阵的方法:

假设我们有一个矩阵 X,它很大并且很稀疏,这意味着与非零值相比,它填充了许多零值,如下图所示:

作者图片

解决这些问题背后的主要思想必须是使用一种替代方法来解决它们,因为添加零会增加空间和时间的复杂性。处理它们的主要方法必须是使用一个用非零数字表示值的键字典,或者使用一个可以表示这些值的列表。该过程可以从下表中完成:

作者图片

上表向我们展示了解决这个问题的一个很好的方法。使用这种方法,我们可以形成一个简化的方程,其中只包含有用的非零数字。下面两种方法可以用来有效地表示稀疏矩阵。

  1. 压缩稀疏行矩阵:这种转换方法利用了上表所示的方法,即行和列分别为一个元组,后跟一个非零值来表示稀疏矩阵。
  2. 压缩稀疏列矩阵:这种转换方法利用了上表所示的方法,即分别用一个列和行的元组,后跟一个非零值来表示稀疏矩阵。

压缩稀疏矩阵和压缩稀疏列矩阵是有效表示稀疏矩阵的两种最佳方法。我会推荐 CSR 矩阵而不是 CSC 矩阵,因为这是我个人的偏好,而且它通常是用于表示的标准符号。然而,我将使用 python 中的 scipy 模块展示 CSR 和 CSC 转换的代码。你们可以自由选择最适合自己的方案。

大部分理论部分已经完成,让我们从编码开始吧!

用稀疏矩阵编码;

好吧,那我们开始吧!计算上图所示矩阵所需的两个机器学习库是 numpy 和 scipy。这些可以通过使用一个简单的 pip install 命令来安装。安装过程完成后,我们将根据需要构建矩阵,并将其赋给一个变量。

下面是代表库导入和创建稀疏矩阵过程的代码块。还提供了相应输出的图像。

下一步是将这个稀疏矩阵转换成压缩行矩阵(CSR)形式。这个输出类似于前面显示的表格。这个转换的代码块如下所示。另外,请参考下图,注意一个(行,列)元组,后跟一个非零数字。

如果您想将其转换回稀疏矩阵,那么只需使用 todense()函数,如下一个代码块所示。

如果您想知道如何对压缩的稀疏列矩阵进行相同的处理,那么可以通过下面的代码块来完成。

这个过程完成了理解稀疏性核心概念的所有要求。😃

我希望这能够给稀疏性和稀疏矩阵的概念一个更好的直觉。前进到结论部分!

德文郡在 Unsplash 拍摄的照片

结论:

至此,我们结束了关于稀疏性的讨论。稀疏矩阵在机器学习中非常常见,了解它们可能导致的问题以及如何准确地解决这些问题是非常重要的。

关于稀疏性的直觉是必须知道的,特别是如果你正在处理自然语言处理、计算机视觉项目、推荐系统和任何有很少非零和很多零的数据结构中的复杂任务。顺便说一下,这些情况不仅在机器学习中常见,在深度神经网络中也常见。

你可以通过下面的链接查看我最近的文章:

[## Python 从头编码:没有任何机器学习库的矩阵乘法!

从零开始了解如何在没有任何机器学习库的情况下实现矩阵乘法!

towardsdatascience.com](/python-coding-from-scratch-matrix-multiplication-without-any-machine-learning-libraries-463624fe8726) [## 10+牛逼 Python 编辑器的简明指南,以及如何选择最适合你的编辑器…

帮助您在各种 python 开发环境中进行选择的简明指南

towardsdatascience.com](/a-concise-guide-of-10-awesome-python-editors-and-how-to-choose-which-editor-suits-you-the-best-465c9b232afd) [## 5 个常见的 Python 错误以及如何避免它们!

从初学者到专家,每个人在 python 和机器学习中都容易出现这些错误。

towardsdatascience.com](/5-common-python-errors-and-how-to-avoid-them-63d9afc1a58f)

谢谢大家看完这篇文章,祝大家有美好的一天!

迷失在(机器)翻译中

原文:https://towardsdatascience.com/lost-in-machine-translation-3b05615d68e7?source=collection_archive---------44-----------------------

使用拥抱脸的 MarianMT 版本和脸书的 Fairseq,小批量机器翻译 30 行以下代码的演讲和新闻文章(英文到中文/泰米尔语,反之亦然)。

插图:蔡展汉

*** 2020 年 12 月 30 日更新*** :

脸书最近发布了最近发布了其英语到泰米尔语的机器翻译模型(反之亦然),我渴望尝试一下,因为泰米尔语是机器学习中服务最差的语言之一,相关的语言对很难找到。

新的笔记本和玩具数据集在回购中。或者,点击此处观看演讲和新闻文章的英语-泰米尔语翻译演示,点击此处观看同类材料的泰米尔语-英语翻译。

翻译的质量在某些部分有明显的问题。但在我看来,机器翻译完成了大约 70-80%的工作,让人工翻译的工作效率更高。

新闻文章的英语到泰米尔语翻译的输出示例。

如今,机器翻译并没有像自然语言处理中的其他新兴领域那样令人兴奋,部分原因是像谷歌翻译这样面向消费者的服务自 2006 年 4 月以来就已经存在了。

但是最近的进展,特别是拥抱脸在使变形金刚模型更容易理解和使用方面的工作,为那些希望翻译不仅仅是零碎句子或文章的人开辟了有趣的新可能性。

例如,多种语言的小批量翻译现在可以在台式机或笔记本电脑上非常有效地运行,而不必订阅昂贵的服务。毫无疑问,神经机器翻译模型翻译的作品没有(目前)熟练的人类翻译的作品那么巧妙或精确,但在我看来,它们完成了 60%或更多的工作。

这可以为时间紧迫的工作场所节省大量时间,例如新闻编辑室,更不用说缺乏熟练的人工翻译了。

的三个短笔记本中,我将概述一个使用抱抱脸版 MarianMT 批量翻译的简单工作流程:

在这里下载输出文件

1.数据集和翻译输出

这篇文章有两个数据集。第一个由四种语言(英语、马来语、汉语和泰米尔语)的 11 篇演讲组成,摘自新加坡总理办公室的网站。第二个数据集由 2020 年 3 月发表在新加坡新闻媒体 CNA 网站上的五篇关于新冠肺炎的随机英语新闻组成。

带有机器翻译文本和原始副本的输出 CSV 文件的结果可在此处下载

在撰写本文时,你可以在拥抱脸的模型中枢上点击超过 1300 个开源模型进行机器翻译。由于到目前为止还没有发布用于英语-马来语和英语-泰米尔语(反之亦然)的 MarianMT 型号,所以这个系列的笔记本暂时不会处理这两种语言。当模型可用时,我会再次访问它们。

我不会深究机器翻译背后的技术细节。拥抱脸的 MarianMT 版本的广泛细节可以在这里找到,而那些对机器翻译历史感兴趣的人可以从这篇最近的文章开始。

2A。3 篇演讲稿的英汉机器翻译

我选择了三篇英语演讲进行机器翻译,字数从 1352 到 1750 不等。它们技术含量不高,但涵盖了足够广泛的话题——从新冠肺炎到新加坡政治和国内问题——从而扩展了模型的功能。

这篇文章被轻描淡写地清除了。为了获得最佳效果,一次翻译一个句子(如果您通过模型运行整个语音,而不在句子级别进行标记,您会发现翻译质量显著下降)。笔记本在我的 2015 年末 iMac (32Gb 内存)上运行只需几分钟——但可能会因硬件而异。

多亏了 Hugging Face 的 MarianMT 实现,批量机器翻译变得容易了

机器翻译的一些常见问题很明显,尤其是某些术语、短语和习语的直译。

May Day, for instance, was translated as “五月节” (literally May Festival) instead of 劳动节. A reference to “rugged people” was translated as “崎岖不平的人”, which would literally mean “uneven people”. Clearly the machine translation mixed up the usage of “rugged” in the context of terrain versus that of a society.

这里有一个与谷歌翻译的对比,用的是第二次演讲的片段。在我看来,“拥抱脸”的结果——Marian mt 模型与谷歌翻译的结果相当吻合:

To be sure, neither version can be used without correcting for some obvious errors. Google’s results, for instance, translated the phrase “called the election” to “打电话给这次选举”, or to literally make a telephone call to the election. The phrasing of the translated Chinese sentences is also awkward in many instances.

在这一点上,一个熟练的人类翻译肯定会做得更好。但是我认为公平地说,即使是一个经验丰富的翻译也不可能在几分钟内翻译完三篇演讲。

目前,机器翻译吸引力似乎在于规模和相对速度,而不是精确度。让我们在不同体裁的写作中尝试同样的模式,看看它的表现如何。

2B。5 篇新闻文章的英汉机器翻译

演讲更倾向于对话,所以我随机挑选了五篇关于新冠肺炎的新闻文章(发表于 2020 年 3 月),看看这个模型在更正式的写作风格下表现如何。为了简单起见,我选择了 500 字以下的文章。

二审中的工作流程与一审完全相同,除了额外的文本清理规则和文章标题以及正文的翻译。下面是输出 CSV 文件的样子:

在此下载上述CSV 的副本。

让我们将其中一个例子与谷歌翻译的结果进行比较:

谷歌和 MarianMT 都在开头的一段上犯了错误,这一段又长又复杂。这两个模型在较短的句子/段落上表现稍好,但是简单短语笨拙的直译仍然是一个问题。

For instance, the phrase “as tourists stay away” was translated by the MarianMT model as “游客离家出走” or “tourists ran away from home”, while Google translated it as “游客远离了当地” or “tourists kept away from the area”.

这些问题可能导致对事实的误解,并造成混乱。我还没有进行全面的测试,但根据我迄今为止所做的测试,MarianMT 和 Google Translate 似乎在处理更具对话性质的文本方面做得更好,而不是更正式的写作形式。

2C。DASH 应用

Plotly 已经发布了许多基于 transformer 的 NLP 任务的示例交互应用,其中包括一个与 Hugging Face 版本的 MarianMT 一起工作的应用。在 Colab 上试用,或者通过 Github 试用(我在下面的演示 gif 中编辑了应用的标题)。

3.3 篇演讲的汉英机器翻译

中文文本到英文的机器翻译通常是一个更加棘手的任务,因为大多数 NLP 库/工具都是基于英文的。例如,在 NLTK 中没有直接的句子标记器。

我用解霸汉普顿做了实验,但是没有走多远。作为一个临时的解决办法,我采用了一个函数来将 dataframe 列中的中文文本分割成单独的句子,然后通过中英互译模型运行它们。

但即使采用了有些笨拙的变通方法,这三篇中文演讲的批量翻译也只花了大约 5 分钟。请注意,这三篇演讲是前三篇英语演讲的官方中文版本。两套演讲稿涵盖了相同的领域,但在中文演讲稿的内容上有一些细微的差异,这不是英文版本的直接逐字翻译。

你可以在这里下载输出 CSV 文件。让我们来看看第三次演讲和谷歌翻译的结果如何比较:

谷歌翻译版本读起来更好,没有把“国庆节”翻译成“7 月 4 日”的明显错误。总的来说,汉译英机器翻译的结果似乎(至少对我来说)比英汉翻译的结果好得多。但一个可能的原因是,我样本中的中文演讲写得更简单,没有那么努力地推动神经机器翻译模型。

4.引人深思的事

虽然拥抱脸使机器翻译变得更容易理解和实现,但一些挑战仍然存在。一个明显的技术问题是针对特定市场的神经翻译模型的微调。

例如,中国、新加坡和台湾在使用中文书写形式上有很大的不同。同样地,马来语和印度尼西亚语即使听起来/看起来和不说话的人一样,也有明显的不同。为这种微调组装正确的数据集将不是一项简单的任务。

就公开可用的模型所能达到的结果而言,我认为机器翻译的英汉和汉英文本还不能公开发表,除非有一名熟练的翻译在场进行检查和修改。但这只是一个用例。在翻译的文本是不需要出版的更大的内部工作流程的一部分的情况下,机器翻译会非常方便。

例如,如果我的任务是追踪中国或俄罗斯国家行为者在社交媒体上的虚假信息活动,那么试图手动翻译大量推文和 FB 帖子就没有意义。对这些短句或段落进行批量机器翻译,在试图获得自动账户所兜售信息的广泛含义方面,效率会高得多。

同样,如果你在多语言市场跟踪新产品或政治活动的社交媒体反馈,批量机器翻译可能是监控从 Instagram、Twitter 或脸书收集的非英语评论的更有效方式。

最终,机器翻译越来越多的使用将受到语言技能广泛下降的推动,即使是在新加坡这样名义上的多语言社会。你可能会对上面的一些机器翻译文本嗤之以鼻,但大多数经历过新加坡双语教育系统的在职成年人,如果被要求自己翻译文本,不太可能做得更好。

这个帖子的 Github repo 可以在这里找到。这是 NLP 新工具实际应用系列的第四篇。早期的帖子/笔记侧重于:

如果你在这篇文章或我之前的文章中发现了错误,请联系我:

卢万算法

原文:https://towardsdatascience.com/louvain-algorithm-93fde589f58c?source=collection_archive---------11-----------------------

一种用于社区发现的算法

Louvain 是一种无监督算法(在执行前不需要输入社区的数量和大小),分为两个阶段:模块优化和社区聚集[1]。第一步完成后,接着是第二步。两者都将被执行,直到网络中不再有变化并且实现最大模块化。

𝐴𝑖𝑗是表示连接节点𝑖和𝑗的边的权重的邻接矩阵条目,𝑘𝑖 = ∑𝑗 𝐴𝑖𝑗是节点𝑖的度,𝑐𝑖是它所属的社区,𝛿-function 𝛿(𝑢,如果=则为 1,否则为 0。𝑚 = 1 ∑𝑖𝑗 𝐴𝑖𝑗 2 是图中所有边的权重之和。

模块化优化

在模块优化中,Louvain 将随机排列网络中的所有节点。然后,它将一个接一个地移除和插入不同社区𝐶中的每个节点,直到模块性(输入参数)没有显著增加被验证:

设𝛴𝑖𝑛是𝛴𝑡𝑜𝑡𝐶内的链接的权重之和,到𝑘𝑖𝐶的节点的所有链接的权重之和,到𝑘𝑖,𝑖𝑛𝑖的节点的所有链接的权重之和,从𝑖节点到社区中的节点的链接的权重之和是图中所有边的权重之和。

进一步提高算法性能的一种方法是通过简化(2)并计算 ∆𝑀𝑚 而不是完整的表达式:

虽然需要为每个试验社区计算𝑘𝑖,𝑖𝑛和σ𝑡𝑜𝑡,但是【k𝑖/(2m】特定于正在分析的节点。这样,只有在模块化优化中考虑不同的节点时,才重新计算后一个表达式。

社区聚集

完成第一步后,属于同一个社区的所有节点合并成一个巨型节点。连接巨型节点的链接是先前连接来自相同不同社区的节点的链接的总和。这一步还会生成自循环,它是一个给定社区中所有链接的总和,然后被折叠到一个节点中(图 1)。

图 1 卢万算法的步骤顺序。改编自[1]。

因此,通过在第一遍之后对社区的社区进行聚类,它固有地考虑了网络中分层组织的存在。算法 1 中的伪代码。

参考

[1] V. D. Blondel,J.-L. Guillaume,R. Lambiotte 和 E. Lefebvre,“大型网络中社区的快速展开”, J. Stat .机甲战士。(2008) P10008,2008 年第 12 页。

自然语言处理的 Lovecraft 第 1 部分:基于规则的情感分析

原文:https://towardsdatascience.com/lovecraft-with-natural-language-processing-part-1-rule-based-sentiment-analysis-5727e774e524?source=collection_archive---------42-----------------------

使用 Python 中基于规则的情感分析库 VADER,将 H. P. Lovecraft 的故事从最黑暗到最不黑暗排序。

图片由 F-P 来自 Pixabay

我已经考虑做一个自然语言处理项目有一段时间了,我最终决定对一个取自文献的语料库进行综合分析。我认为古典文学是 NLP 的一个非常有趣的应用,你可以展示从字数统计和情感分析到神经网络文本生成的广泛主题。

我选择了 H. P .洛夫克拉夫特的故事作为我分析的主题。他是 20 世纪初的美国作家,以怪异和宇宙恐怖小说闻名,对现代流行文化有着巨大的影响。如果你想了解更多为什么我认为他是这样一个项目的最佳选择,看看我之前的文章,我也描述了我是如何准备我们现在要分析的文章的。

在 NLP 系列的第一篇文章中,我们将仔细研究基于规则的情感分析。在 NLP 的世界里,更广泛的情感分析肯定不是最好的第一步,然而,基于规则的情感分析的好处是它需要最少的前期工作。我想用一些可以立即玩的东西来开始这个项目,而不会被符号化和词条等技术细节所困扰。

我们将运用 VADER 情感分析法对洛夫克拉夫特的作品进行排序,从最消极的到最积极的。根据 GitHub 的页面,VADER“特别适应社交媒体上表达的情绪”。换句话说,这个图书馆是在一个现代的、俚语很多的语料库上训练出来的。这应该很有趣,因为洛夫克拉夫特从心底里憎恶三样东西:

  • 来自其他维度的邪术生物;
  • 没有受过良好教育的盎格鲁撒克逊男性;
  • 俚语。

情感分析

先来一个快速总结。情感分析是 NLP 的一种,处理基于文本数据的情感分类。你输入一个文本,算法告诉你它有多积极或消极。有两种主要的方法可以采用:

  • 机器学习:算法从一个数据中学习。例如,您有 10,000 条电影评论,以及用户给出的星级数和文本评论。可以以文本为特征,以星数为目标变量,训练一个分类模型。(当然,将非结构化文本数据转换成可测量的特征将是一个挑战,但幸运的是这不在本文的范围之内。)
  • 基于规则的:算法根据一组手动创建的规则计算情感得分。例如,您可以计算某人在评论中使用“棒极了”的次数,并增加每个人的估计情绪。这听起来非常简单,但这就是正在发生的事情,只是规模更大。

在我们当前的项目中,我们将采用基于规则的方法,接下来让我们更仔细地看看我们的库!

VADER

VADER 代表价感知词典和情感推理机。从本质上来说,这是一个情感词典,他们从 9000 多个特征(单词、表情、表情符号)开始,并要求人们在-4 到+4 的范围内对它们进行评分,从最消极到最积极。然后,他们取这些评分的平均值,排除那些被认为是中性的,并将它们收集在一个有 7520 个元素的字典中。(GitHub repo 还有一个搞笑、全面的表情集合。)

除了这个词汇,还有一些有趣的调整。例如,“极度”这个词没有内在的消极或积极情绪,它只是增加了这个词的强度。也有降低强度的词,标点符号有意义,像“不太好”中的“不”这样的否定会抵消或逆转原来的情绪,等等。

它是如何工作的

让我们先来看几个例子。

安装库,并导入我们将要使用的方法:

pip install vaderSentimentfrom vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer

接下来,我们创建一个 SentimentIntensityAnalyzer 对象:

sentiment_analyzer = SentimentIntensityAnalyzer()

还记得那个包含 7520 个令牌的文本文件吗?你可以在 Python 中查看它们,让我们看看“装饰”这个词是如何评分的:

token_scores = sentiment_analyzer.lexicon
token_scores['adorned']

结果是 0.8。不管上下文如何,这就是这个词的积极意义。我们不打算使用单独的分数,那会很乏味,polarity_scores方法为我们聚合了文本信息。

比如这句话:

sentiment_analyzer.polarity_scores('I feel good')

被评为:

{'neg': 0.0, 'neu': 0.408, 'pos': 0.592, 'compound': 0.4404}

前三个值是文本中阴性、自然或阳性的部分。在我们的例子中,0.592 被认为是正的,0.408 是中性的。复合得分是总体消极或积极得分,标准化,范围从-1 到+1。

现在,有一个机会,你,和我一样,会假设两件事:1)部分以某种方式连接到单词的数量或字符的数量,2)复合分数可以从部分和单独的分数计算出来。这两个理由你都错了。

窗帘后的一瞥

我花了相当多的时间试图弄清楚份额和复合分数是如何精确计算的。例如,如果您对词典中得分为 0.8 的“decorated”运行polarity_score方法,您将得到以下结果:

{'neg': 0.0, 'neu': 0.0, 'pos': 1.0, 'compound': 0.2023}

前三个数字看起来还行,毕竟正文只有一个字,而且是正的。但是复分从何而来?它接近于 0.8 / 4,这是通过将原始的 0.8 分归一化到-1 和+1 之间的范围而得到的,但它并不精确。与前面“我感觉很好”的例子类似的问题,你会假设“我”和“感觉”是中性词,“好”是一个积极的词,但是 0.408–0.592 的分裂来自哪里呢?

如果你感兴趣的话,在 StackOverflow 上有一个关于分数如何计算的详细描述。就我个人而言,我在这里画了一条线,关于我想花多少时间来研究一些最终只是一个有趣的思想实验背后的代码。

然而,当我在那里的时候,我仔细查看了 GitHub 上的代码,有一些有趣的小细节:

  • 像“非常”和“几乎”这样的积极和消极调整被分配给两组,并且它们以相同的因子±0.293 增加/减少强度,这意味着例如“相当”和“非常”是可互换的;
  • 有很多硬编码的解决方案,看看 _negation_check 方法的例子;
  • 最奇怪的是 normalize 函数中看似随机的 alpha = 15 平滑参数,据我所知,这是我无法复制复合分数的原因之一。

为了证明用如此简单的规则来衡量人类交流的细微差别是多么荒谬,猜猜哪个句子被评价得更负面:“”和“汤难吃了”。

是的,有汤的那个被评为更消极。其实第一句的评分是完全中立的。

不要误会我的意思,VADER 是一个非常令人印象深刻的图书馆,而且工作相当普遍,正如我们很快就会看到的。但就像许多机器学习算法一样,你越仔细看,它似乎就越不神奇。

好了,现在开始洛夫克拉夫特!

用 Lovecraft 测试词典

我们将进行一些测试,以确保该库能够处理 20 世纪早期的文本。

从《白色的船》( 1919)中选取这样的描述:

然后我们来到了一个愉快的海岸快乐的各种颜色的花朵,在内陆我们可以看到太阳下晒可爱的小树林和辐射凉亭。

运行polarity_scores返回以下结果:

{'neg': 0.0, 'neu': 0.733, 'pos': 0.267, 'compound': 0.8807}

听起来还行,是很正面的文字。然而,我很好奇这个分数在词典中的依据是什么。通过拆分文本,我们可以收集句子中词典中的单词:

result = []for word in text_to_analyze.split():
    if word in token_scores:
        result.append((word, token_scores[word]))

打印完result后我们得到:

[('pleasant', 2.3), 
('lovely', 2.8), 
('radiant', 2.1)]

很有趣,对吧?所有的文字,这三个词决定了情绪,就像那里没有别的东西,没有“开着各种颜色的花”。

让我们来看一个更典型的洛夫克拉夫特序列,来自 Dagon (1917):

我说过,连绵起伏的平原的连续不断的单调令我隐隐感到恐惧;但是,当我登上土堆的顶峰,从另一边向下望去,看到一个无法估量的深坑或峡谷时,我觉得我的恐惧更大了,因为月亮还没有升到足够高的高度来照亮这些深坑或峡谷。我觉得自己在世界的边缘;从边缘窥视永恒之夜的无尽混乱。在我的恐惧中,充满了对失乐园的好奇回忆,以及对撒旦可怕地爬过过时的黑暗王国的回忆。

这一部分的估计情绪:

{'neg': 0.186, 'neu': 0.692, 'pos': 0.121, 'compound': -0.8074}

文本的 0.186 被认为是否定的,0.121 是肯定的。然而,总复合分数-0.8074 接近负极限,这意味着负片段的强度更强。

同样,我们可以收集具有指定非中性分数的单个单词:

[('vague', -0.4),
 ('horror', -2.7),
 ('horror', -2.7),
 ('greater', 1.5),
 ('gained', 1.6),
 ('chaos', -2.7),
 ('terror', -2.4),
 ('curious', 1.3)]

和第一个例子一样,我们可以看到大部分信息没有被处理。列表中没有“连续单调”或“永夜”。我们也可以看到有一些分类错误。例如,表达式“我的恐惧更大”中的单词“更大”得到+1.6 分,但它意味着消极性的增加。但最重要的是,它在某种程度上把握住了整体情绪。

总的来说,我对目前的表现相当满意:总的分数似乎反映了人们对文本的看法。剩下唯一要做的事情就是将它应用到完整的语料库中!

洛夫克拉夫特全集排名

在我们进入排名之前,我想再次强调,我们正处于思想实验领域。我认为,基于规则的情感分析充其量是一种高级近似,而 VADER 是为了分析现代的、简短的、非正式的文本而创建的,这些文本对洛夫克拉夫特的作品来说都不是真实的。

随着警告的出现,没有进一步的麻烦,我使用下面的代码来处理写作,并将结果保存在列表中。列表filenames包含各个故事的名称。

neg_portion = []
neu_portion = []
pos_portion = []
compound_score = []for filename in filenames:
    print("Processing " + filename)
    my_file = open(txt_adjusted_folder + filename + '.txt')
    raw_text = my_file.read()
    sent_score = sentiment_analyzer.polarity_scores(raw_text)
    neg_portion.append(sent_score['neg'])
    neu_portion.append(sent_score['neu'])
    pos_portion.append(sent_score['pos'])
    compound_score.append(sent_score['compound'])

然后,我从这些列表中创建了一个熊猫数据框架对象。4 个分数的统计:

Lovecraft 情感分析统计

我们可以得出的一个明确结论是,这些作品大多是负面的。复合得分的第 75 百分位仍然为负,平均情绪为-0.5025。在 63 篇作文中,只有 16 篇获得了总体正面分数。

好吧,让我们看看名单。根据综合得分,最积极的五篇文章是:

The White Ship (1919)
The Quest of Iranon (1921)
The Whisperer in Darkness (1930)
The Dream-Quest of Unknown Kadath (1927)
Celephaïs (1920)

这里有一个非常有趣的共同因素:所有这些故事都涉及到主角“梦想”自己进入神奇的幻想世界,它们大多是对风景和城市的描述,没有多少行动发生在其中。毫无疑问,他们使用了相当积极的语言,我们之前在《白船》中看到了一个例子,但这些故事的整体基调相当忧郁,没有人类读者会将它们归类为“快乐”。然而,非常有趣的是,情感分析算法成功地将这组故事与“非常黑暗”的故事区分开来。

(顺便说一句,如果你有兴趣,你可以在这个参考书目中了解更多的故事。)

5 种最消极的写法是:

The Dreams in the Witch House (1932)
The Shadow over Innsmouth (1931)
The Dunwich Horror (1928)
The Colour out of Space (1927)
The Lurking Fear (1922)

这里的共同主题是,这些故事更重情节(相对而言),更长,更复杂的作品。它们也很有名,这五部作品中有三部是洛夫克拉夫特最有影响力的作品。如果你想知道,他的大多数其他著名故事,如《疯狂之山》(1931)、《赫伯特·威斯特——复活者》(1922)、《查尔斯·德克斯特·沃德的案子》(1927)也在十大最黑暗故事之列。克苏鲁的召唤(1926)是第 16 首。

有趣的是,在统计表中可以看到,所有文章中的大部分文本都是中性的,中性部分占文本的 71.4%到 90.5%。这将支持这样一个概念,即尽管整体基调压抑,洛夫克拉夫特作品中的叙述通常是平静而遥远的,除了偶尔的“恐怖,恐怖,难以形容的恐怖!”章节。但这也可能是因为该词典的大部分内容不在 VADER 词典中。

如果您想查看所有的结果,您可以在这里通过一个 CSV 文件访问它们。还有大图表显示的综合得分的文本部分

未来可能的分析

关于这个语料库,我们还可以对 VADER 做一些额外的分析。例如,你可以把故事分成几个句子,然后看看它们在故事过程中有多消极。有没有相对中性的起点,然后中间有一个峰值,或者反过来?看到这些肯定会很有趣。

我希望这篇文章对你有所帮助,在下一篇文章中,我们将更深入地了解符号化和单词分析。

参考

休顿,C.J .和吉尔伯特,E.E. (2014 年)。VADER:基于规则的社交媒体文本情感分析的简约模型。第八届网络日志和社交媒体国际会议。密歇根州安阿伯,2014 年 6 月。

霍布森、科尔和汉尼斯(2019 年)。自然语言处理实践:理解、分析和用 Python 生成文本。曼宁出版,2019。

洛夫克拉夫特全集:

[## 面向 Nook 和 Kindle 的免费 H.P. Lovecraft 全集

在 2010 年 12 月初,我用一个来自澳大利亚古腾堡项目的文件创建了一个大多数 Lovecraft 的 EPUB

arkhamarchivist.com](https://arkhamarchivist.com/free-complete-lovecraft-ebook-nook-kindle/)

自然语言处理的 Lovecraft 第 2 部分:标记化和字数统计

原文:https://towardsdatascience.com/lovecraft-with-natural-language-processing-part-2-tokenisation-and-word-counts-f970f6ff5690?source=collection_archive---------32-----------------------

使用 Python NLP 库 spaCy 分析 H. P. Lovecraft 小说中的词汇用法。

图片由 LUM3N 来自 Pixabay

这是我从自然语言处理的角度分析 H. P. Lovecraft 作品系列的第二篇博文。在的第一个帖子中,我们通过分析故事的整体情绪来开始。我们不能再推迟了,我们必须讨论所有 NLP 分析的基础:标记化。我觉得把这个问题和一个特定的问题联系起来会很有趣,所以在这篇文章中,我们将找出洛夫克拉夫特在每个故事中使用最多的词,以及在他的文学作品中使用最多的词。

阅读《Lovecraft》时,你记忆最深的一件事是奇怪的语言。他倾向于使用很多负面的词,恐怖,疯狂,沮丧,尤其是用形容词:不可名状,不可描述,不可描述的恐怖无处不在,对吗?《局外人》(1921)中有这样一段话:

上帝知道它不属于这个世界——或者不再属于这个世界——然而令我恐惧的是,我在它被侵蚀和露出骨头的轮廓中看到了对人类形体的恶意的、令人憎恶的嘲弄;在它发霉腐烂的衣服里,有一种说不出的特质,让我更加不寒而栗。

这让洛夫克拉夫特尖叫。在阿卡姆档案馆(我下载文章的网站),有一个单独的页面专门用于字数统计,人们提交建议,收集故事的人统计它们。我很好奇,想知道这个概念是否可以被“科学地”观察到。这些故事有我们想象的那么消极吗?用的最多的形容词是什么,是“恐怖”“未知”“古老”吗?动词是关于知识和/或发疯的吗?他有没有用过“女人”这个词?好吧,让我们来看看!

我们将从一个快速的理论背景开始,在文本上应用一些实际的准备工作,看一看空间中的几个例子,然后最后继续字数统计。

理论

首先,让我们看一下我们将在这个项目中使用的几个概念。

文本准备

当我第一次为这个项目做文本准备工作时,我怀疑我将不得不返回并做一些额外的调整,这被证明是正确的——当我开始使用标记化时,我遇到了问题。比如,你会不会猜到这两句话:

  • 为什么不呢?
  • "为什么不呢?

会有不同的结果吗?原因是撇号。一般来说,你希望单词的“ n't ”部分与碱基分开。于是“不是”就变成了“”和“不是”。但是它并不适用于所有的撇号。连字符、破折号、引号也有类似的问题——你无法想象有多少不同的字符用于相同的目的!

(注:洛夫克拉夫特 几乎从不使用缩写 )因为他认为它们是缺乏适当教育的明显标志。然而,他有时会在对话中使用它们,以显示——也告诉——那个人有多没文化。不过,他确实用了很多破折号。)

所以在我们进行调查之前,我们需要追捕这些奇怪的人物。我认为谈论一下这些步骤是很重要的,即使这可能看起来有点无聊,因为(以我的个人经验)许多 NLP 指南完全跳过它,只从一个干净的文本开始。在大型 NLP 库中可能有这样的方法,比如 NLTK,这可能是一个 Unicode 解码问题,但是对我来说,手动调整文本似乎是最合理的解决方案。

我开始分析一个故事中的人物,邓威奇恐怖(1928),假设保存在text变量中。排除空白,并使其小写:

text = text.lower()
text = text.replace('\n','')
text = text.replace('\x0c','')
text = text.replace(' ','')

然后,您可以创建一串独特的字符,如下所示:

unique_characters = set(text)

如果你想把它们打印成一串,你可以简单地加入集合

unique_characters_in_string = ''.join(set(text))

在 Dunwich 的案例中,这些是独特的角色:

'-2wdj0i”m8uüosczävèr‖l)q,4b76e’n—a1(:é.ftpk?x‘hg!;93―y5'

然后,我创建了一个名为regular_characters的字符串,它包括英文字母表中的字母、数字、标点符号、括号、普通引号和撇号。我们遍历它们,从唯一的字符中去掉规则的字符,所以我们剩下的是不规则的字符。

for character in regular_characters:
    try:
        unique_characters.remove(character)
    except:
        pass

这些是留下来的字符:

'ä', 'è', 'é', 'ü', '—', '―', '‖', '‘', '’', '”'

是的,

'—' == '―'

由于某种原因是假的,在这一点上,我们已经排除了我认为是常规的连字符和破折号!引号也有类似的问题,“”就是其中之一。(那不是大写的 I,那是两条竖线,在文中是引号。)非英语拉丁字母是可以的,它们在文本中的用法是合法的,以防你想知道:

  • “我!舒布-尼格拉特!”
  • “巴黎 Bibliothèque 国家公园”
  • 埃:“vigenère's·特拉伊特·德·希夫雷斯”
  • ü:“klüber's 氪空间”

我为所有的故事重复了这个过程,收集了所有我想修改的奇怪角色。我最终得到了这本替换词典:

replace_dict = {}
replace_dict['*'] = ''
replace_dict['—'] = '–'
replace_dict['―'] = ''
replace_dict['‖'] = '\"'
replace_dict['‗'] = ''
replace_dict['”'] = '"'
replace_dict['‘'] = '\''
replace_dict['’'] = '\''

遍历所有文本文件,应用替换:

for replace_char in replace_dict: 
    text = raw_text.replace(\
        replace_char,  replace_dict[replace_char])

并将它们保存为新的 TXT 文件。它们应该正常工作。好了,现在说正经事。

使用 SpaCy

我们首先安装将要使用的 NLP 库: spaCy

pip install spacy

我们还需要单独安装一个我们将要使用的语言模型。有多种语言的模型可用,英语有三种不同的模型。我发现的大多数指南都推荐从en_core_web_sm开始,我认为这对于一个简单的项目来说是可行的,但是经过一些尝试和错误之后,我决定使用en_core_web_lg。(稍后我们将看到一个例子。)

要安装模型,请执行以下操作:

python -m spacy download en_core_web_lg

请注意,下载和构建大模型可能需要一些时间。

现在,我们可以设置一个nlp对象作为我们的 NLP 模型,并创建一个doc对象作为字符串输入的处理版本:

nlp = spacy.load(“en_core_web_lg”)doc = nlp(“At midnight the doorbell rang, startling him fearfully.”)

doc是一个 Doc 对象,它基本上是一个令牌容器。因此,在这一点上,我们已经有我们的文本标记!Doc 保留了原始文本中的所有信息,比如空白,所以您可以从中重建文本。

Doc 对象中的令牌是令牌对象,有一长串您可以请求的属性,请参见这里的完整列表。现在,我们将使用三个属性:

  • text:文本中出现的令牌的简单文本
  • lemma_:令牌的引理
  • pos_:标记的词性(例如名词、形容词、动词等……)

为了分析我们的句子,我们可以列出标记属性:

for token in doc: 
    print(token.text, token.lemma_, token.pos_)

它会打印出这个:

At at ADP
midnight midnight NOUN
the the DET
doorbell doorbell PROPN
rang ring VERB
, , PUNCT
startling startle VERB
him -PRON- PRON
fearfully fearfully ADV
. . PUNCT

这似乎是正确的,错误地将“门铃”归类为专有名词,而不是名词。这是大模型。小模型表现更差,将“让”归类为专有名词,没有找到动词的现在时态。出于某种原因,这变成了一个棘手的句子。

你也可以用显示法来形象化一个句子,尽管我认为这主要是在教育环境中有用。如果您正在 Jupyter 笔记本中工作,您已经打开了一个浏览器窗口,您可以使用render方法:

spacy.displacy.render(doc, style=”dep”)

你也可以将这些可视化保存为 SVG 文件,你可以在文档中读到更多关于如何做的内容。

我们看到了 spaCy 如何通过一个随机的句子很好地工作。像《老臭虫》(1919)中这样故意拼错的奇怪句子呢?

也是一个了不起的人——他的父亲是一个大公司的律师,他的母亲是一个文学天才。

嗯,不出所料,图书馆在挣扎。它或多或少地获得了标记的词性索引,但是没有识别出“‘n’”应该是“and”,“s”应该是“his”,等等…

关于 spaCy 库,我想谈的另一件事是它如何识别文本中的命名实体。令我惊讶的是,它甚至对虚构的作品也有效。

引用赫伯特·韦斯特《复活者》( 1922)的第一句话。

赫伯特·韦斯特是我大学和晚年的朋友,说起他,我只能感到极度恐惧。

我们可以遍历 Doc 对象中的条目来查找命名实体:

doc = nlp(text)
for ent in doc.ents:
    print(ent.text, ent.label_)

将返回:

Herbert West PERSON

我发现这是一个令人印象深刻的特点。让我们看看同一个故事中的另一句话:

We were in the third year of our course at the Miskatonic University Medical School in Arkham.

在我们以同样的方式列出实体后,我们得到:

the third year DATE
University Medical School ORG
Arkham GPE

几乎完美,虽然出于某种原因,它错过了“米斯卡托尼克”部分。

这也可以形象化,这一次我们应该将样式设置为“ent”:

spacy.displacy.render(doc, style=”ent”)

退货:

这就是我们现在需要的。

赫伯特·韦斯特《复活者》( 1922)的词汇分析

作为第一步,我们专注于一个故事。库中有许多内置的方法可以自动为你做单词包,我没有找到一个完全符合我需要的方法,幸运的是,我们自己编写代码真的很简单!让我们首先为这个项目创建一些助手函数。

首先,我们构建一个create_word_counts_by_pos函数,它接受一个原始文本文件、一个词性标签列表和一个可选的单词计数字典,以防我们想要以这种方式聚合多个故事。它将返回一个字典,其中的键是词性标签,值是更小的字典,对应标签的单词作为值,它们在文本中的计数作为值…所以 word_count_dict 的结果字典内部将有一个 word_count_dict['名词']字典,它将由类似' man': 4,' house': 28,…,word_count_dict['ADJ'],word_count_dict['动词']等的键值对组成。

这个过程的一个重要部分是我们想要排除停用词,这对于 spaCy 来说非常简单,令牌有一个返回布尔值的is_stop方法,我们只需要考虑这个属性为 False 的令牌。

假设我们有一个这种格式的word_count_dict,我们可能想要过滤掉超过某个阈值的单词。这就是filter_word_count_dict_to_frequent要做的,保持输入字典的结构,但是删除所有计数低于阈值的元素。

最后,我们需要一些方法来排序单词,这样我们就可以知道哪些是最常用的。这就是collect_most_frequent_words将要负责的,你输入一个带数字的单词计数词典,你会从每个词类类别中得到那么多出现频率最高的单词。

这是完成我们刚刚讨论的内容所需的所有代码:

现在我们有了这些函数,获取不同结构中的字数就非常容易了。目前,我们只对名词、专有名词、形容词和动词感兴趣:

list_of_pos = ['NOUN', 'PROPN', 'ADJ', 'VERB']

假设我们有了text变量中的所有文本,要得到word_count_dict:

word_count_dict = \
    word_count_func.create_word_counts_by_pos(text, list_of_pos)

word_count_dict将是一个很长的单词集合,任何在文本中出现过一次的名词、形容词或动词都将在那里出现。我们可以筛选出出现次数超过 10 次的单词:

frequent_word_count_dict = \
    word_count_func.filter_word_count_dict_to_frequent(
        word_count_dict, 10)

frequent_word_count_dict足够简洁,在此简单复制并不过分:

{'NOUN': {'friend': 13,
  'college': 21,
  'life': 39,
  'work': 18,
  'year': 19,
  'experiment': 24,
  'fear': 13,
  'death': 16,
  'solution': 22,
  'time': 20,
  'case': 11,
  'reanimation': 13,
  'corpse': 14,
  'specimen': 34,
  'body': 49,
  'eye': 17,
  'field': 15,
  'thing': 53,
  'room': 12,
  'laboratory': 18,
  'house': 16,
  'horror': 15,
  'man': 28,
  'result': 15,
  'night': 17,
  'sound': 14,
  'police': 13},
 'PROPN': {'Herbert': 20,
  'West': 132,
  'Arkham': 18,
  'Dr.': 15,
  'Bolton': 12},
 'ADJ': {'great': 20,
  'hideous': 17,
  'dead': 23,
  'human': 21,
  'fresh': 28,
  'small': 12,
  'new': 14,
  'large': 12},
 'VERB': {'see': 17,
  'come': 24,
  'hold': 11,
  'know': 18,
  'find': 14,
  'restore': 11,
  'inject': 15,
  'think': 18,
  'look': 14,
  'tell': 11}}

如果你读了这个故事/看了这部电影,你可能会发现很多这些令人满意。对于没有看过的人来说:这个故事基本上是关于一个疯狂的科学家创造僵尸,并永无止境地寻找新鲜尸体。

让我们看看形容词,前三个形容词是:“新死去的人”可能是故事的工作标题。“标本”比“人”用得更多,显然与赫伯特·韦斯特是朋友的叙述者大多称他为“韦斯特”,而不是“赫伯特”,动词“注射”用得可疑。

现在让我们对所有的故事都这样做!

所有故事的单词分析

我决定在分析中省略专有名词,专注于每个故事每个词类的前 5 个词。首先,我们需要设置一些变量:

number_of_words_to_collect = 5
list_of_pos = ['NOUN', 'ADJ', 'VERB']words = {}
word_counts = {}for part_of_speech in list_of_pos:
    words[part_of_speech] = {}
    word_counts[part_of_speech] = {}
    for number in range(number_of_words_to_collect):
        words[part_of_speech][number] = []
        word_counts[part_of_speech][number] = []

然后,我们可以做一个类似的过程,就像我们在上一章中对单个故事所做的那样。我们不使用常用词典,而是请求一个最常用单词的列表。假设filenames包含我们要导入的文件的名称,并且它们保存在txt_folder中:

for filename in filenames: 
    my_file = open(txt_adjusted_folder + filename + '.txt')
    print("Currently processing: " + filename)
    raw_text = my_file.read()
    word_count_dict = \ 
        word_count_func.create_word_counts_by_pos(
            raw_text, list_of_pos)
    most_frequent_list_dict = \
        word_count_func.collect_most_frequent_words(
            word_count_dict, number_of_words_to_collect)
    for part_of_speech in list_of_pos:
        for number in range(number_of_words_to_collect):
            words[part_of_speech][number].append(
                most_frequent_list_dict[part_of_speech][number][0])
            word_counts[part_of_speech][number].append(
                most_frequent_list_dict[part_of_speech][number][1])

完成后,我们应该在两个字典中有我们需要的一切,wordsword_counts。我把它们和熊猫结合起来,对于‘名词’组,我们可以这样做:

noun_counts = pd.DataFrame()
noun_counts['filename'] = filenames
for i in range(number_of_words_to_collect):
    noun_counts['word_' + str(i+1)] = \
        words['NOUN'][i]
    noun_counts['word_' + str(i+1) + '_count'] = \ 
        word_counts['NOUN'][i]

对形容词和动词重复同样的操作,现在我们有了语料库中 63 个故事的前 5 个单词及其在 3 个词性组中的数量。把它们都复制到这里可能有点多,你可以在 CSV 文件中找到关于名词形容词动词的数据。

让我举几个我觉得很有趣的例子。

名词:

  • 我个人最喜欢的一首,埃里希·赞恩(Erich Zann,1921)的音乐是用这些名词来代表的:街道、音乐、夜晚、窗户、房间。
  • 潜伏的恐惧(1922):大厦,恐惧,夜晚,事物,眼睛。
  • 《黑暗中的低语》(1930):事物、人、信、时间、声音

形容词:

  • Cele phas(1920):奇怪,白色,伟大,金色,古老
  • 克苏鲁的召唤(1925):伟大,古老,陌生,年轻,死亡

动词通常与故事不太匹配,毕竟有很多通用动词。再加上 Lovecraft 的风格很有描写性和距离感,几乎没有什么动作。

好的,到目前为止我很满意,我认为这样一个基本的分析是如何抓住这么多故事的本质的,这令人印象深刻。

所有洛夫克拉夫特的故事加起来

最后,回到大问题,他用得最多的词是什么?按照与上面类似的过程,但是在每一轮,我们保留word_count_dict,所以它计算一个组合分数。(组合所有文本不起作用,这大约是 spaCy 中内存限制的 2.5 倍。)

所以,鼓点,这是洛夫克拉夫特最常用的 20 个名词、形容词和动词:

{'NOUN': [('thing', 1152),
  ('man', 1075),
  ('time', 830),
  ('night', 666),
  ('place', 569),
  ('house', 490),
  ('day', 476),
  ('city', 453),
  ('year', 432),
  ('stone', 407),
  ('dream', 392),
  ('room', 383),
  ('world', 379),
  ('door', 370),
  ('way', 367),
  ('horror', 352),
  ('light', 350),
  ('life', 340),
  ('wall', 335),
  ('eye', 333)],
 'ADJ': [('old', 917),
  ('great', 797),
  ('strange', 488),
  ('certain', 446),
  ('black', 379),
  ('little', 336),
  ('ancient', 308),
  ('high', 297),
  ('small', 282),
  ('dark', 277),
  ('new', 268),
  ('human', 267),
  ('unknown', 259),
  ('terrible', 256),
  ('long', 244),
  ('curious', 227),
  ('low', 216),
  ('hideous', 213),
  ('young', 210),
  ('good', 204)],
 'VERB': [('come', 1100),
  ('know', 1095),
  ('see', 1079),
  ('find', 784),
  ('tell', 649),
  ('think', 571),
  ('hear', 528),
  ('look', 474),
  ('go', 439),
  ('say', 425),
  ('leave', 401),
  ('begin', 400),
  ('feel', 397),
  ('take', 368),
  ('grow', 310),
  ('give', 306),
  ('shew', 275),
  ('bring', 267),
  ('speak', 266),
  ('try', 262)]}

我再次认为动词是最不令人兴奋的,尽管你可以看到大多数动词都是关于知识收集或分享的。如果你想知道,“shew”是 show 的老式拼法。

名词更好,“时间”,“夜晚”,“石头”,“梦”,“恐怖”——我会根据这五个词猜测作者是 Lovecraft。我的意思是,恐怖出现在有史以来最常用的 20 个名词中,这确实令人放心!

最后,形容词,至少有三分之二在列表中有这么高的位置通常会很奇怪。最常用的形容词是“老”,我的意思是,那有多牛逼?这个清单还包括“伟大”、“奇怪”、“古老”、“未知”、“可怕”等等。

(你可能会注意到,我们有 213 次“可怕的”,但在我在介绍中提到的阿卡姆档案管理员页面上,这个词有 260 次。这种差异是由于我们根据词类来区分单词的用法。他把这个词作为形容词用了 213 次,但这不包括名词“可怕”或副词“可怕地”。)

未来可能的分析

我认为用这些简单的 NLP 工具可以做更多有趣的分析。我们把范围限制在名词、形容词和动词上,看看副词或专有名词也会很有趣。分析不同年份动词的相对比例也很有趣。这样,我们可以看到随着时间的推移,故事是否变得更加精彩,还是相反?还有一个非常重要的概念我们没有考虑到: n-grams 。可以进行非常相似的分析来找出他的作品中最常用的表达。

我们从一个非常简单的问题开始:我想知道 Lovecraft 使用频率最高的词是什么?对于这样一个简单的问题,这比我想象的要复杂得多。看到这样一个简单的 NLP 表示工作得如此之好真是太酷了。

在下一篇文章中,我将讲述如何进一步计算字数,并使用 TF-IDF 向量计算文档之间的差异。

参考

霍布森、科尔和汉尼斯(2019 年)。自然语言处理实践:理解、分析和用 Python 生成文本。曼宁出版,2019。

** [## 语言特征空间使用文档

智能地处理原始文本是困难的:大多数单词是罕见的,对于看起来完全…

空间. io](https://spacy.io/usage/linguistic-features)

洛夫克拉夫特全集:

https://arkhamarchivist . com/free-complete-love craft-ebook-nook-kindle/**

自然语言处理的 Lovecraft 第 3 部分:TF-IDF 向量

原文:https://towardsdatascience.com/lovecraft-with-natural-language-processing-part-3-tf-idf-vectors-8c2d4df98621?source=collection_archive---------13-----------------------

使用 Python、scikit-learn 和 spaCy 构建 H. P. Lovecraft 的故事的 TF-IDF 表示,以确定哪些故事彼此接近。

图片由 F-P 来自 Pixabay

这是我的 Lovecraft NLP 系列的第三部分。在之前的帖子中,我讨论了基于规则的情感分析单词计数和标记化

到目前为止,我们的方法非常简单,我们基本上是将文本分解成单词,并以某种方式计数。NLP 领域的下一步将是研究 TF-IDF 向量,它代表词频——逆文档频率。这是一种不太二进制的方法,用于搜索引擎和垃圾邮件过滤器,通过这种方法,我们将把单词解码成连续的数字,而不是整数。

首先,我们将通过定义相关术语来看一下这个理论。然后我们将看到如何使用 spaCy 和 scikit-learn 库来计算我们语料库中的 63 个 Lovecraft 故事的 TF-IDF 向量。最后,我们将尝试通过对向量表示应用 k-means 聚类来创建有意义的组。

在我们开始之前,我想管理对结果的期望:我们最终将得到的组不会那么有意义。在前两篇帖子中,我对简单的 NLP 分析结果非常满意,并且很容易得出关于 Lovecraft 工作的有意义的结论。这不是这里的情况,有一些模式,但故事并没有真正分配到好的同质组。至少我找不到一个好的整体模式,但是也许你会找到,最终结果可以在一个 CSV 文件中找到。

理论

让我们先快速总结一下重要的术语。

  • 【TF】:TF-IDF 公式的第一部分,旨在捕捉某个术语在某个文档中的重要性。参见维基百科文章中的替代计算,计算 TF 的默认方法是取一个独特的单词在文档中出现的次数,然后除以该文档中的总单词数。如果将文档 d 中的项 t 的原始计数记为 f(t,d) ,则 TF( t,d )为:

词频公式

  • 齐夫定律 :描述一种现象的经验法则,适用于多种类型的数据,包括来自自然语言的数据。当涉及到自然语言时,该定律指出,任何单词的频率都与其在频率表中的排名成反比。这意味着出现频率最高的单词是第二高的单词的两倍,第三高的单词的三倍,等等。Zipf 定律解释了为什么在 IDF 公式中采用比率的对数会导致更具线性间隔的度量。
  • 【IDF】:捕捉该术语在整个语料库中的常见程度。如果 N 是文件的数量, D 是文件的集合,那么 IDF( tD )就是:

逆文档频率公式

  • sk learn 中的 IDF:sci kit-learn 还对 IDF 公式应用平滑效果,详见文档
  • TF-IDF 值 :结合 TF 和 IDF 公式,创建单词在文档和语料库中相对重要性的表示。TF 部分衡量术语在文档中的重要性,而 IDF 衡量术语在文档之间的区分程度。如果一个术语出现在语料库中的许多文档中,这意味着它太常见了,人们无法很好地了解基于该特定术语的文档有多接近。TF-IDF 越高,特定术语在特定语料库的特定文档中就越重要。要计算该值,只需将 TF 和 IDF 公式相乘即可:

TF-IDF 公式

  • TF-IDF 向量:上面公式中的 TF-IDF 数是为特定的术语-文档-语料库三元组计算的。然后,我们可以收集语料库中所有独特的词,这些将是维度。然后,对于每个文档,我们创建一个向量,其中每个数字是特定单词的 TF-IDF 分数。这意味着如果一个单词在文档中不存在,该维度中的数字将为 0。这将是一个类似于我们在上一篇文章中讨论的单词袋的概念,但是我们将有连续的数字来代替整数。通常的做法是取向量的 l2 范数,这意味着它们的长度是 1。我们很快就会看到一个例子。
  • 余弦相似度 :两个向量之间相似度的度量,取值在 1(表示完全对齐)和-1(表示完全对立)之间。是的,这和三角学中一个度数的余弦基本上是一回事。这就是我们如何计算两个 TF-IDF 向量之间的相似性。重要的是,如果我们取两个归一化向量,余弦相似度将等于点积,因为公式中的分母等于 1。这是矢量 A 和 B 之间余弦距离的一般公式:

A 和 B 向量的余弦相似性

  • 点积 :取两个维数相同的向量,返回一个数作为输出的运算。为了计算它,你取相应条目的乘积,然后计算乘积的和。正如前面提到的,我们将使用它来计算两个 TF-IDF 向量之间的距离。考虑到文档中不能有否定词,我们理论上能达到的最低相似度是 0。在它们的 TF-IDF 表示之间余弦相似度为 0 的两个文档甚至没有一个公共单词。
  • 余弦距离:为了完整起见,余弦距离被定义为 1-余弦相似度。关于余弦距离有趣的是,它可以是一个度量,但它不是一个距离度量(详见维基百科文章)。

TF-IDF 与 spaCy 和 scikit-learn

在这一节中,我们将看看如何创建一个文档的 TF-IDF 向量表示。我们将构建来自 sklearn 的 TfidfVectorizer 类,并使用我们使用 spaCy 定义的标记器。(如果你是这个话题的新手,我建议你看看我的上一篇文章,我假设你知道文本标记化一般是如何工作的。)

先来看看tokenizer吧。我们基本上需要一个函数,它接受一个字符串作为输入,并返回一个令牌列表作为输出。你可以随意地设计这个函数,我采用了一种非常简单的方法,这就是我的spacy_tokenizer函数要做的:

  • 将文档拆分成单词标记;
  • 忽略停用词、标点符号和空格。
  • 获取每个剩余单词的词条,并将它们收集到一个列表中。

我们设置了nlp对象,它将完成繁重的工作(你需要为此安装一个 spaCy 语言模型,如果你不确定如何做,请参考我之前的帖子):

import spacy
nlp = spacy.load("en_core_web_lg")

然后您可以定义记号赋予器函数:

def spacy_tokenizer(document):
    tokens = nlp(document)
    tokens = [token.lemma_ for token in tokens if (
        token.is_stop == False and \
        token.is_punct == False and \
        token.lemma_.strip()!= '')]
    return tokens

这是我要用来举例的语料库:

example_corpus = [
    "Monsters are bad.", \
    "I saw a monster yesterday.", \
    "Why are we talking about bad monsters?"]

既然我们已经有了标记器和语料库,我们可以设置一个 TfidfVectorizer。您可以使用许多参数,查看文档了解更多信息,我们只使用这两个参数:

  • input:定义我们将如何输入要分析的文本,默认值“content”意味着我们将它们作为字符串变量传递,这就是我们在本例中所做的。对于大型文档,这当然不是一个可行的方法,所以稍后我们将传递一个文件路径列表来打开和处理。
  • tokenizer:决定使用哪个记号赋予器。TfidfVectorizer 类有一个内置的,我们将为我们用 spaCy 创建的类覆盖它。

我们正在定义矢量器:

tfidf_vectorizer = \
    TfidfVectorizer(input = 'content', tokenizer = spacy_tokenizer)

tfidf_vectorizer对象的工作方式类似于标准的 sklearn 机器学习模型。如果调用fit方法,它将学习词汇表和公式的 IDF 部分,transform方法将把语料库转换成包含 TF-IDF 值的稀疏矩阵格式。这两个步骤在fit_transform方法中结合在一起:

result = tfidf_vector.fit_transform(example_corpus)

如果我们现在给result打电话,我们得到的是:

<3x5 sparse matrix of type '<class 'numpy.float64'>'
	with 8 stored elements in Compressed Sparse Row format>

这是一个包含 3 个文档和 5 个术语的稀疏矩阵,在这 3*5 = 15 个可能的数字中,有 8 个非零 TF-IDF 值。我们可以用get_feature_names方法从句子中检查哪些术语是实际考虑的:

tfidf_vector.get_feature_names()

功能名称是:

['bad', 'monster', 'see', 'talk', 'yesterday']

稀疏矩阵格式是存储这些信息的有效方式,但是您可能希望使用todense方法将其转换为可读性更强的密集矩阵格式。要从结果中创建 pandas 数据帧,您可以使用以下代码:

dense = result.todense()
denselist = dense.tolist()
df = pd.DataFrame(
    denselist,columns=tfidf_vector.get_feature_names())

最后我们可以看看三个句子的 TF-IDF 向量:

示例语料库的 TF-IDF 向量

单词“monster”出现在所有三个句子中,因此“monster”列中的值是所有行中最低的,这意味着它不是区分句子的重要术语。

让我们检查一下第一句话中的数字是如何计算的。“bad”和“monster”的 TF 都是 0.5,考虑到句子中只有两个词没有被忽略。为了计算 IDF 值,我们需要计算有多少文档包含特定的单词。“坏”出现在 3 个中的 2 个,“怪物”出现在所有 3 个中。“差”的 IDF 分数(使用 sklearn 的平滑效果)将为:

math.log((3+1) / (2+1)) + 1 = 1.2876820724517808

而对于“怪物”:

math.log((3+1) / (3+1)) + 1 = 1

因此,未经调整的 TF-IDF 分数为:

  • 1.2876820724517808 * 0.5为“坏”
  • 1 * 0.5为“怪物”

然而,这个向量的长度还不是 1:

(0.6438410362258904  ** 2 + 0.5 ** 2) ** 0.5

等于0.8151878801407859,因此我们需要将两个分数除以长度,这就是我们如何获得上面数据帧中的值:

0.6438410362258904 / 0.8151878801407859 = 0.7898069290660905

0.5 / 0.8151878801407859 = 0.6133555370249717

好了,我们有了 TF-IDF 向量,剩下的就是计算差了!正如我们上面提到的,因为我们有归一化的向量,余弦相似度等于点积,也称为线性核。我们从 sklearn 导入方法,然后应用于第一句话(索引 0):

from sklearn.metrics.pairwise import linear_kernelcosine_similarities = linear_kernel(result[0:1], result).flatten()

结果将是以下数组,其中包含余弦相似性:

array([1\.        , 0.23636982, 0.69362794])

第一个数字,1,是意料之中的,毕竟我们希望一个句子和自己完全相似。我们来看看最后一个数字是怎么算出来的。你只需把两个句子中出现的单词,即“bad”和“monster ”,两两相乘,然后总结一下:

0.789807 * 0.547832 + 0.613356 * 0.425441 = 0.693628

我们可以看到最后一句比第二句更接近第一句。

我们可以计算所有的余弦相似性,并将它们收集在熊猫数据帧中:

cos_df = pd.DataFrame(columns=[0,1,2])
for i in range(2 + 1):
    curr_cos_sim = linear_kernel(result[i:i+1], result).flatten()
    cos_df[i] = curr_cos_sim

会导致这个cos_df:

示例语料库的余弦相似度

再一次,我们可以看到,句子 0 和 2 彼此接近。

我们将在小示例语料库上检验的最后一个应用是 k-means 聚类。我们将使用 sklearn 的 KMeans 类,它的伟大之处在于它使您能够将稀疏矩阵作为输入,因此我们不必将其转换为传统的密集矩阵格式。

现在,k-means 算法没有余弦距离选项,我们将使用向量之间常见的欧几里德距离。然而,同样,因为我们对向量进行了归一化,这应该会导致相同的相似性顺序。更多背景信息见讨论

在我们的原始结果 TF-IDF 矩阵上拟合 k 均值模型:

from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=2).fit(result)

如果我们调用labels_属性:

kmeans.labels_

我们可以看到它创造的群体:

array([0, 1, 0], dtype=int32)

所以再一次,句子 0 和 2 放在一组。

这就结束了我们在下一节分析洛夫克拉夫特的故事所需要的实际背景。

TF-IDF-ing Lovecraft

在这一节中,我们将使用 Lovecraft stories 语料库重复上一节中的步骤。正如介绍中提到的,很遗憾,结果并不像人们希望的那样好,但是我们开始了!

设置tfidf_vectorizer和我们之前做的非常相似,但是现在我们使用的是‘文件名’选项。假设您有一个指向包含各个故事的 TXT 文件的文件路径列表:

tfidf_vector = 
    TfidfVectorizer(input = 'filename', tokenizer = spacy_tokenizer)result = tfidf_vector.fit_transform(filepaths)

就像上一节一样,result将是一个稀疏矩阵,维数为 63 x 17,813。这意味着我们有 63 个故事,和 17813 个独特的引理。

接下来,我们要创建集群。我在 k = 2 到 10 之间运行了来自 sklearn 的 k 均值聚类,然后将结果收集到一个熊猫数据框架中。在数据框架中,每个故事将被分配给一行,列将包含在每个聚类结构中分配给该故事的标签。例如,在 4means_label 中,如果我们想将故事分成 4 个不同的组,我们将能够看到它们将被分配到哪个组,标签将在 0 和 3 之间运行。

要运行不同的 k 均值聚类:

kmeans_models = {}
for i in range(2,10+1):
    current_kmean = KMeans(n_clusters=i).fit(result)
    kmeans_models[i] = current_kmean

然后我们将标签组织成一个cluster_df数据框架:

cluster_df = pd.DataFrame()
cluster_df['title'] = filenames
for i in range(2, 10+1):
    col_name = str(i) +'means_label'
    cluster_df[col_name] = kmeans_models[i].labels_

您可以在我的 GitHub 资源库中下载一个 CSV 文件中的结果。

如果你熟悉洛夫克拉夫特的作品,看看你是否能在任何分组中找到任何好的模式。我能得出的最好的结果是部分结果,例如,在 k = 5 的情况下,梦序列故事在标记为 2 的组中被很好地分开,但是我不能给出一个整体聚类的综合原因。

我认为缺乏好的结果很可能是由于故事之间缺乏潜在的结构造成的。当然,有一些明显不同的故事,像前面提到的梦序列系列,但你不能真的通过这样清晰的线条来划分整个语料库。

即使我们没有设法人为地创建故事组,我们可以事后证明,结构和代码是存在的,我希望你发现它有用。TF-IDF 的一个常见用法是搜索引擎,因此如果您包含一个查询作为第 64 个文本输入,您可以计算出哪些文档与它最接近,哪些文档将以最高的概率包含您的查询的答案。

未来可能的分析

人们可以用 TF-IDF 和这个语料库做一些进一步分析。在构建向量时,我没有考虑 n 元语法,而是使用了默认选项,即单独考虑每个单词。使用 n 元语法,您可以尝试在文档之间找到常用的表达式。

另一个潜在的改进是列出与每个文档最接近的文档,而不是将它们按簇排列。这样我们也许能看到更好的联系。

在本系列的下一篇文章中,我们将看看如何降低 TF-IDF 向量的维数,并将其转换为潜在因子向量。

参考

霍布森、科尔和汉尼斯(2019 年)。自然语言处理实践:理解、分析和用 Python 生成文本。曼宁出版,2019。

[## 6.2.特征提取-sci kit-学习 0.23.1 文档

这个类是一个高速、低内存的矢量器,它使用了一种称为特性散列或“散列……

scikit-learn.org](https://scikit-learn.org/stable/modules/feature_extraction.html) [## 语言特征空间使用文档

智能地处理原始文本是困难的:大多数单词是罕见的,对于看起来完全…

空间. io](https://spacy.io/usage/linguistic-features)

洛夫克拉夫特全集:

https://arkhamarchivist . com/free-complete-love craft-ebook-nook-kindle/

自然语言处理的 Lovecraft 第 4 部分:潜在语义分析

原文:https://towardsdatascience.com/lovecraft-with-natural-language-processing-part-4-latent-semantic-analysis-70aa2fa2161b?source=collection_archive---------65-----------------------

应用降维技术将 TF-IDF 向量转换成更有意义的 H. P. Lovecraft 故事的表示。

图片来自 Pixabaydarkworx

这是我正在进行的系列文章中的第四篇,我将不同的自然语言处理技术应用于 H. P .洛夫克拉夫特的作品。关于本系列的前几篇文章,请参见第 1 部分—基于规则的情感分析第 2 部分—标记化第 3 部分— TF-IDF 向量

这篇文章主要基于 TF-IDF 向量的概念,这是一个文档的向量表示,基于文档和整个语料库中单个单词的相对重要性。下一步,我们将使用潜在语义分析(LSA)将这些向量转换成低维表示。LSA 使得基于意思而不是精确的单词用法来搜索文档成为可能,这通常会比 TF-IDF 产生更好的匹配。

我们将首先讨论使用 TF-IDF 的缺点,以及为什么调整这些向量是有意义的。然后,我们将澄清一些我个人认为令人困惑的数学术语。最后,我们重复上一篇文章中的步骤,创建一个 Lovecraft 故事的矢量表示,看看我们能否使用聚类分析得出有意义的分组。

TF-IDF 与潜在语义分析

正如我们在上一篇文章中看到的,TF-IDF 向量是语料库中各个文档的多维向量表示。如果我们在所有文档中有 10,000 个唯一的单词,并且有 500 个文档,我们可以创建一个 500 x 10,000 的矩阵,其中每一行都是表示文档的向量,唯一的单词形成维度,并且每个元素表示特定单词在特定文档中的相对重要性。在这个过程中,我们会丢失一些信息,最重要的是单词的顺序,但 TF-IDF 仍然是一种令人惊讶的强大方法,可以将一组文档转换为数字,并在其中进行搜索。

然而,TF-IDF 有几个问题:

  • 它侧重于拼写和单词用法——你可以重新表述一个句子,得到一个完全不同的 TF-IDF 表示,即使意思根本没有变化;
  • 词汇匹配可能将一些单词组合在一起,但是同义词将被单独处理;
  • TF-IDF 背后的数学是严格关于频率的,并假设频率是唯一重要的东西。

为了解决这些问题,我们将不再关注单个单词,而是提出“主题”。就拿洛夫克拉夫特的作品来说吧。不用数他用了多少次“可怕的”或“可怕的”,我们会有“梦境描述”、“伟大的老故事”和“反移民情绪”这样的话题(是的,嗯,没有人是完美的)。与一个或另一个主题强烈对应的单词将增加这些主题在各自故事中的总得分。然后,我们不再衡量词频之间的接近程度,而是只考虑聚合主题。这基本上是潜在语义分析背后的思维过程,它会找到属于一起的单词,因为它们与相同的主题高度相关。

我们将应用这种方法来加强我们对故事进行的聚类分析。人们可以希望,如果我们考虑聚合的主题而不是单个的单词,感觉它们应该属于一起的故事将有更高的机会被分配到同一个组。

然而,这种降维技术更重要、更广泛的应用是在分类问题上。NLP 数据往往具有大量词汇和相对少量的观察值。如果你分析 5000 条推文,你可能会有 10000 个单词,这意味着你会有两倍于观察的特征,这肯定不是理想的。如果你设法减少这些维度,同时保留大部分信息,这将使你的模型更强大。

所以唯一的问题是,我们如何提出这些话题?这就是奇异值分解发挥作用的地方。然而,在我们研究数学来管理期望值之前,我想提一件事:我提到的那些主题,那些干净的、标签很好的主题——我们可以忘记得到任何类似的东西,除非你正在处理几个非常好的例句。鉴于洛夫克拉夫特故事的规模和同质性,我认为不可能在主题如何产生的背后提出一个好的推理。但是这并不是这个分析的目标,我们只是想检查一下我们是否能想出一个自动将故事分组的结构。

数学概念

好了,让我们看看创建主题向量背后的数学概念!正如我在引言中提到的,我发现这些概念在文献中经常互换使用的方式令人困惑。希望这些高层次的定义能够澄清一些困惑。

  • 【奇异值分解】 :将一个 m×n 矩阵分解成三个维度分别为 m×m、m×n 对角线和 n×n 的矩阵的乘积,它有大量不同的应用,详情请查看维基百科页面。关键是,SVD 本身就是分解。
  • 【主成分分析(PCA) :一个降维应用,可以使用 SVD 的结果来实现(在其他技术中,但 SVD 绝对是一个真正流行的方法)。PCA 常用于可视化或处理高维数据。当我们将数据“压缩”到一个较低的维度表示中时,我们希望保留观察值中最大可能的方差。我在《动作中的自然语言处理》一书中发现了一个很好的类比(见参考资料),即你有一个三维物体,想要将阴影投射到二维表面,所以你找到了一个可以清晰识别阴影的角度。
  • 【潜在语义分析(LSA) :基本上与 PCA 相同的数学,应用于 NLP 数据。该数据可以是任何向量表示,我们将使用 TF-IDF 向量,但它也适用于 TF 或简单的单词包表示。这就是我们如何找到文档的“主题”。

LSA 在爱情小说 TF-IDF 向量中的应用

现在,最后,让 LSA 继续我们的故事!如上所述,LSA 可以应用于各种 NLP 表示,但是我们现在在 TF-IDF 向量上使用它。

我们有一个来自之前项目的叫做result的稀疏矩阵,它包含了我们语料库中 63 个故事的 TF-IDF 表示。一般来说,在进行主成分分析之前,需要对向量进行归一化,以便将不同的维度缩放到相同的大小。对于 TF-IDF 向量,scikit-learn 已经完成了大部分工作,但是我们仍然可以将向量集中在 0 附近。为此,我们不得不放弃稀疏矩阵格式:

result_df = result.toarray()
result_df = pd.DataFrame(result_df)
result_df = result_df - result_df.mean()

现在我们有了一个 pandas 数据框架,无需对模型做进一步的调整就可以使用。

正如 scikit-learn 中的许多内容一样,创建模型非常简单:

from sklearn.decomposition import PCApca = PCA(n_components = 50)

最重要的参数是n_components,它定义了我们希望模型聚合到多少个不同的组件(在 NLP 问题中是“主题”)。(有关其他参数的详细信息,请参见文档。)那么作为题目数量的 50 从何而来呢?这需要用一种叫做explained_variance_ratio_的方法进行一些微调:

pca.fit(result_df)
sum(pca.explained_variance_ratio_)

这将决定我们通过将超过 17,000 的原始矩阵压缩到 50 而保留的故事之间的差异百分比。在我们的例子中,这个保存的比率大约是 87%,乍一看这肯定是可疑的,但是我们必须记住,使用 63 个组件,我们将能够保存 100%的原始信息。

对我来说,87%就足够了。你当然可以走一条更科学的路线,计算一些不同数量的成分的解释方差比,然后找到“肘”点。一旦我们对配置满意,我们就可以调用fit_transform:

result_df = pd.DataFrame(pca.fit_transform(result_df))

新的result_df将是一个 63 行(原始故事)和 50 列(人工创建的“主题”)的矩阵。

现在,我们基本上可以重复前一篇文章中的相同过程,只是功能数量要少得多。

运行 k 均值模型:

kmeans_models = {}
for i in range(2,10+1):
    current_kmean = KMeans(n_clusters=i).fit(result_df)
    kmeans_models[i] = current_kmean

并将结果组织在熊猫数据框架中:

cluster_df_2 = pd.DataFrame()
cluster_df_2['title'] = filenames
for i in range(2, 10+1):
    col_name = str(i) +'means_label'
    cluster_df_2[col_name] = kmeans_models[i].labels_

上面的cluster_df_2对象在我的 GitHub repo 中以 CSV 格式提供。

结论

让我们看看 LSA 集群的表现有多好!

我们再一次遇到了与上一篇关于 TF-IDFs 的文章类似的问题:我不认为这个分组问题有一个真正优雅的解决方案,而且一个人类专家也会发现这个任务非常困难,如果不是不可能的话。

话虽如此,我还是设法找到了一些不错的模式。例如,如果我们看一下 4-means 组,有三组非常不同的故事:

  • 第二组包含了大多数经常提到的洛夫克拉夫特故事的“梦序列”系列;
  • 第 0 组只有一个故事:同上(1928) ,这是一篇非常怪异的文章,即使用洛夫克拉夫特的标准来衡量,这也是一本关于罗马士兵的模拟传记,其中很大一部分文字是随意的罗马人名;
  • 第三组故事的主要主题是坟墓和活死人:坟墓(1917 年),赫伯特·韦斯特——复活者(1922 年),在地下室(1925 年),黑暗的鬼斯通(1935 年)是这一组的故事;
  • 最后,第一组,嗯,第一组有所有其他的故事...

这似乎是不同集群的共同主题。该算法通常会分离出几个非常怪异和独特的故事,并将其余的故事放在一个大组中。真正受欢迎和著名的 Lovecraft 故事几乎总是被分配到同一个组,而不管集群的数量。

我个人认为这还是相当可观的成绩。我们设法将 Lovecraft 故事的含义压缩到 50 个人工创造的主题中,即使创造的群体并不十分出色,你也一定可以发现模式。比 TF-IDF 表现好吗?我也这么认为我设法在 LSA 结果中发现了以前没有的好模式。

我们可以尝试使用更少的维度来进一步压缩含义,这可以改善聚类。然而,我认为主要的问题是我们的语料库非常小,只有 63 个文档。可悲的是,我们再也没有原创的爱情故事了。

参考

霍布森、科尔和汉尼斯(2019 年)。自然语言处理实践:理解、分析和用 Python 生成文本。曼宁出版,2019。

** [## sk learn . decomposition . PCA-sci kit-learn 0 . 23 . 1 文档

主成分分析。使用数据的奇异值分解进行线性降维…

scikit-learn.org](https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html)

洛夫克拉夫特全集:

https://arkhamarchivist . com/free-complete-love craft-ebook-nook-kindle/**

爱的一天:回顾过去

原文:https://towardsdatascience.com/loving-day-looking-back-3187515d85c4?source=collection_archive---------53-----------------------

两天后就是爱情日了。这对我很重要,尽管对你来说可能毫无意义。爱情日是美国最高法院一致否决所有禁止异族通婚的法律的日子。这是一个你可能不知道的术语。简而言之,异族通婚就是在自己种族之外的婚姻(或浪漫或性关系)。直到 1967 年 6 月 12 日,美国一直有一些州禁止异族通婚。这些不是民法。它们是刑法,在许多情况下规定通婚是重罪。

我们可以谈论动机、手段等。在这些法律上。我想看一些简单的数据。许多讨论美国反异族通婚法律的资料提供了某种表格或地图,表明各个州在 1967 年有或没有这样的法律。我说,很公平。但是我还没有找到一个来源(到目前为止),按照时间和拥有这些法律的州的百分比来展示这些法律的“弧线”。数据不难找到,我想没人会费心去收集。当你这样做的时候,它的信息量非常大,所以我们开始吧:

我们可以看到,反通婚法律的频率从 1787 年的法律基础上升到大约 1850 年,一直保持相当稳定,直到大约 1876 年,下降了大约一代人,保持稳定大约一代人,然后有一个大的峰值,保持稳定,然后从大约 1945 年到 1967 年稳步下降,当时最高法院废除了这一做法。简而言之,它呈现了一幅不太简单的画面。

我在这里做的一点也不前沿或“先进”的数据科学。相反,我从基础开始。我只是通过维基百科查阅了美国反异族通婚法律的历史,到目前为止的链接是两个段落。然后,我绘制了某一年有反异族通婚法的州的数量与美国州总数的对比图(XY 图),得出一个分数,绘制成百分比。我没有用 r,我没有用 Python。我使用了最简单的工具,仍然产生了可分析的输出。

如果我们再增加一个维度,我们可以得到更多的信息:新国家是在哪一年被接纳的?我们在下一张图中用橙色表示。还是那句话,没什么特别的。我刚刚在 Excel 中创建了一个新的系列数年,看到一个国家承认并删除了原始系列中的数据点。为了形成对比,我将新系列涂成橙色。

那么,这告诉我们什么呢?首先,在 1870 年左右以前,新州更为普遍。第二,你会注意到,大约在 1830 年以前,新的州的加入会减少有反种族通婚法律的州的百分比,然后这个百分比会增加。这意味着没有这些法律的州被承认,但是新成立的州很快开始通过这些法律。大约在 1850 年后,趋势是接纳一个新的州会增加有反异族通婚法律的州的百分比。建国前的领土已经有这样的法律。为什么会这样?我们可以在图表中添加另一个维度,具体的历史事件。

我几乎是手动生成这张图表的。因为每个点对应一个特定的年份,所以我在 PowerPoint 上手工添加了标签。我可能已经生成了奇特的代码或者找到了一个库,但是有了手头的数据,简单地放下标签并用我自己的眼睛看,这是一个更有效的分析。

那么,从 1787 年到 1967 年,增加(仅仅几个)事件让我们说了什么?首先,美国各州似乎没有任何重大事件引发了对异族通婚定罪增加的趋势。就在密苏里妥协案之前,新的州的加入稍微降低了这一趋势,但是就在那次事件之后,各州通过了更多的法律。密苏里妥协是什么?这是一项每当接纳一个非蓄奴州时就接纳一个蓄奴州的政策,以保持“平衡”(或者像我们今天喜欢说的“两党合作”)。虽然它可能没有改变美国参议院的构成,但它肯定没有减少我们国家对种族主义法律的热情。

然而,在 1840 年左右达到高峰后,反异族通婚的法律下降,直到堪萨斯-内布拉斯加法案,这是导致内战的一个重大事件。在这个国家的一些地方,公众舆论正在逐渐远离奴隶制。

让我感兴趣的是,重建并没有减少反异族通婚的法律。相反,它们一直保持稳定,直到 1877 年之后——重建工作结束之后。然而,这并不发生在加入邦联的州。相反,是在联盟国家。1887 年至 1907 年间,反异族通婚的法律处于 19 世纪初以来的最低水平。有趣的是,第二个三 k 党成立于 1915 年(最初的在 1871 年解散),从 1907 年到 1913 年,反异族通婚的法律激增。新三 k 党反映了美国更广泛的文化转变。

从 1913 年到 1947 年,美国一直保持在 62.5%。不管其他的社会动荡,同样的国家保持他们的反异族通婚的法律。美国已经打破了种族主义的平衡,当权者对维持现状相当满意。

1947 年后,一个新的趋势出现了,一个在许多关于 Loving v. Virginia 判决的讨论中没有被充分强调的趋势。到 1967 年,反异族通婚已经成为美国的法律。从 1948 年开始,异族通婚的法律不断被废除,直到 1966 年,美国只有三分之一的州还保留着这些法律。《爱 v .弗吉尼亚》虽然受人欢迎,也很光荣,但却是棺材上的一颗钉子,没有突破性,也没有新意。这个国家的大部分地区已经开始复苏了。通常情况下,最高法院并没有引领潮流,相反,它使陈旧过时的法律与当前的信仰和实践相一致。

那么,带回家的?爱 v. Virginia 是不必要的或者错误的?一点也不。即使“只是”少数人坚持强加不公正,也有必要进行干预。这是一个必要而公正的决定。这和数据科学有什么关系?数据科学不仅仅是处理数字或庞大的项目,它是关于从数字中提取可能不会自己跳出来的意义。

哦,我为什么要写这个?我和我妻子:

为什么爱日是我最喜欢的节日

低代码编程:数据科学的未来?

原文:https://towardsdatascience.com/low-code-programming-the-future-of-data-science-900e1c3f3baa?source=collection_archive---------58-----------------------

PyCaret 如何使预处理、模型选择和模型改进变得更快、更容易,并被所有利益相关者清楚地理解。

瑟奎拉在 Unsplash 上拍摄的照片

在过去的几周里,我一直在使用 PyCaret,我认为它可能是继 Pandas 和 Numpy 之后最有用的 Python 模块。它极大地提高了我为各种不同的用例创建机器学习模型的方便性和速度,我真的很想与你分享它,这样你就可以享受同样的好处!

那么 PyCaret 是什么?它能做什么?

引用其网站的摘要:“ PyCaret 是一个用 Python 编写的开源、低代码的机器学习库,允许您在几秒钟内从准备数据到在您选择的笔记本环境中部署模型。

简单地说,它让任何人(甚至是没有多少技术背景的人)都能在几分钟内为他们能想到的任何用例创建机器学习模型。如果你知道如何使用 Jupyter 笔记本,你有足够的知识开始使用它!

那么,你的企业正在应对哪些瓶颈呢?要不要对哪些客户有可能离开进行分类?你想预测你下个季度的销售额吗?也许您想根据问题描述对内部问题进行分类?您可以使用 PyCaret 快速简单地为这类问题建立一个模型!

空谈不值钱。给我看看代码!

好吧,那么它在实践中会是什么样子呢?

这 6 行简单的代码(如果我们忽略导入)是您需要的全部内容:

  • 加载您的数据
  • 自动预处理数据
  • 根据您喜欢的任何指标,比较众多不同建模算法对您的数据的性能
  • 训练 N 重交叉验证模型
  • 根据看不见的数据预测
  • 保存模型

哇!如果您已经使用传统的建模方法尝试过上面的过程,您可能知道您必须编写几十行代码才能复制这个过程(尤其是在进行模型性能比较的时候)!

这个好像很基础!我如何开始探索 PyCaret 的功能?

由于上面的例子确实很基本,我建议你看看模块创建者制作的 入门指南 来帮助你!

接下来,我在 Jupyter 笔记本中创建了一个演示演练,我们在其中探索了从预处理到模型创建,再到 4 种机器学习算法的模型改进的所有内容。它非常广泛,有很多关于其间发生的事情的评论,所以当你有空闲时间的时候,请随意查看。如果您想更好地查看代码和输出,请查看我的 Github 简介

这听起来真的很棒…但是有什么问题呢?

就像任何听起来很神奇的事情一样,总有一个陷阱。然而,问题并不在于模块本身,而在于如何使用它。

因为对初学者非常友好,代码也很少,所以很容易错过或忘记在预处理或建模过程中应该指定的数据的某些方面。让 PyCaret 函数推断关于数据的一切非常方便(也非常诱人)。然而,如果你打算做的不仅仅是构建一个快速的&脏模型,建议你在过程的预处理和建模部分调查并真正理解你在做什么。

最后的想法

说了这么多,我认为 PyCaret 是用 Python 编程的一个惊人的补充,并且有可能方便许多数据科学家的生活。我相信这些类型的低代码模块将在不久的将来成为行业标准,我真的很兴奋地看到未来的实现在地平线上!

轻松的机器学习工具

原文:https://towardsdatascience.com/low-effort-machine-learning-tools-9622d7d57135?source=collection_archive---------29-----------------------

具有 PyCaret、BigQueryML 和 fastai 的低代码 AI

Kasya ShahovskayaUnsplash 拍摄的照片

机器学习有可能帮助解决商业和世界上的广泛问题。通常,开发一个机器学习模型,并将该模型部署到可以操作使用的状态,需要深厚的编程知识和对其背后的算法的良好理解。

这将机器学习的使用限制在一小群人,因此也限制了可以解决的问题的数量。

幸运的是,在过去几年中,大量的库和工具涌现出来,它们减少了模型开发所需的代码量,或者在某些情况下完全消除了代码量。这为分析师等非数据科学家利用机器学习的力量开辟了潜力,此外还允许数据科学家更快地建立模型原型。

这里有一些我最喜欢的用于机器学习的低代码工具。

PyCaret

PyCaret 是流行的机器学习库(如 Scikit-learn 和 XGBoost)的 Python 包装器。它使得一个模型只需要几行代码就可以被开发到一个可部署的状态。

Pycaret 可以通过 pip 安装。有关更详细的安装说明,请参见 PyCaret 文档

pip install pycaret

PyCaret 有一个公共数据集的存储库,可以使用pycaret.datasets模块直接安装。完整的列表可以在这里找到但是为了本教程的目的,我们将使用一个非常简单的数据集来解决一个叫做“葡萄酒”数据集的分类任务。

PyCaret 库包含一套解决所有常见机器学习问题的模块,包括:

  • 分类。
  • 回归。
  • 聚类。
  • 自然语言处理。
  • 关联规则挖掘。
  • 异常检测。

为了创建分类模型,我们需要使用pycaret.classification模块。创建模型非常简单。我们简单地调用create_model()函数,它将模型 ID 作为参数。支持型号及其相应 ID 的完整列表可在这里找到。或者,您可以在导入适当的模块后运行以下代码来查看可用模型的列表。

可用于分类的模型快照。图片作者。

在调用create_model()之前,你首先需要调用setup()函数来为你的机器学习实验指定合适的参数。在这里,您可以指定测试序列分割的大小,以及是否在实验中实现交叉验证。

create_model()函数将自动推断数据类型,并使用默认方法处理这些类型。当您运行create_model()时,您将收到下面的输出,它显示了推断的数据类型。

图片作者。

PyCaret 将使用一组默认的预处理技术来处理分类变量和估算缺失值之类的事情。但是,如果您需要一个更加定制的数据解决方案,您可以在模型设置中将这些指定为一个参数。在下面的例子中,我将数值插补参数改为使用中值。

一旦您对模型使用的参数感到满意,您就可以按 enter 键,模型将最终确定并显示性能结果的表格。

图片作者。

PyCaret 还有一个plot_model()函数,显示模型性能的图形表示。

图片作者。

本教程刚刚展示了使用 PyCaret 库进行模型训练的基础。还有更多功能和模块可以提供完整的低代码机器学习解决方案,包括功能工程、模型调整、持久性和部署。

大查询 ML

2018 年,谷歌发布了一款名为 BigQuery ML 的新工具。BigQuery 是谷歌的云数据仓库解决方案,旨在让数据分析师和科学家快速访问大量数据。BigQuery ML 是一个工具,它使机器学习模型能够仅使用 SQL 直接从 BigQuery 数据仓库开发出来。

自从 BigQueryML 发布以来,它已经发展到支持最常见的机器学习任务,包括分类、回归和聚类。您甚至可以导入自己的 Tensforflow 模型,以便在工具中使用。

从我自己的经验来看,BigQueryML 是一个非常有用的加速模型原型的工具,并且作为一个基于生产的系统来解决简单的问题也是可行的。

为了简单介绍该工具,我将使用一个名为成人收入数据集的数据集来说明如何在 BigQueryML 中构建和评估逻辑回归分类模型。

数据集可以在 UCI 机器学习知识库中找到,我使用下面的 Python 代码下载了一个 CSV 文件。

下面是下载数据并导出为 CSV 文件的脚本。

如果你还没有谷歌云平台(GCP)账户,你可以在这里创建一个。当你最初注册时,你会得到 300 美元的免费积分,这足够你尝试下面的例子了。

在 GCP 上,从下拉菜单中导航到 BigQuery web UI。如果这是您第一次使用 GCP,您将需要创建一个项目并使用 BigQuery 进行设置。谷歌快速入门指南在这里给出了一个很好的概述

我之前下载的 CSV 文件可以直接上传到 GCP 来创建表格。

图片作者。

您可以通过单击侧栏中的表名并选择 preview 来检查表中的数据。这是成年人的数据在 BigQuery 中的样子。

图片作者。

为了根据这些数据训练一个模型,我们只需编写一个 SQL 查询,从表中选择 everything (*),将目标变量(income)重命名为 label,并添加逻辑以创建一个名为“adults_log_reg”的逻辑回归模型。

有关所有型号选项,请参见此处的文档

如果我们单击现在将出现在您的数据表旁边的侧栏中的模型,您可以看到对培训表现的评估。

图片作者。

现在,我们可以使用模型通过 ML 进行预测。预测功能

法斯泰

众所周知,Tensorflow 等流行的深度学习框架具有陡峭的学习曲线,对于初学者或非数据科学家来说,很难上手并运行它。fastai 库提供了一个高级 API,允许您只需几行简单的代码就可以训练一个神经网络。

Fastai 与 Pytorch 一起工作,所以在使用它之前,您需要安装这两个库。

pip install pytorch
pip install fastai

fastai 库具有处理结构化数据和非结构化数据(如文本或图像)的模块。在本教程中,我们将使用fastai.tabular.all模块来解决我们之前使用的葡萄酒数据集的分类任务。

与 PyCaret 类似,fastai 将通过嵌入层对非数字数据类型进行预处理。为了准备数据,我们使用了TabularDataLoaders助手函数。在这里,我们指定了数据帧的名称、列的数据类型以及我们希望模型执行的预处理步骤。

为了训练神经网络,我们简单地使用如下所示的tabular_learner()函数。

运行此代码后,将显示性能指标。

图片作者。

要使用模型进行预测,只需使用learn.predict(df**.**iloc[0])

探索 fastai 库进一步查看文档这里

感谢阅读!

我每月都会发一份简讯,如果你想加入,请点击此链接注册。期待成为您学习旅程的一部分!

低内存实例分段

原文:https://towardsdatascience.com/low-memory-instance-segmentation-b9c425b67db1?source=collection_archive---------30-----------------------

将实例分段 web 应用程序部署到 google cloud

机器学习模型是内存密集型的。我当前的 web 应用程序至少消耗 1GB 的内存。这使得它很难部署到云上。

想到的直接解决方案是增加 VM 实例的内存。但是我不想花更多的钱。毕竟,这是一个附带项目。

所以我想出了一个办法。它实际上是受杰森·安蒂奇的 deoldify 的启发。在运行他的机器学习模型之前,Jason 使用渲染因子来缩小图像并将其转换为正方形。

我认为在这里应用同样的思想可以减少内存需求。

解决方案

简而言之,这就是解决方案。很大程度上取自这里的。

我们缩放到大小为targ的正方形。targ本质上就是 Jason 在 deoldify 中提到的渲染因子。

如果渲染因子太高,可能会导致 OOM 错误。太低的话,结果的分辨率会很差。

实际上这看起来很简单。首先,我们将图像缩放到一个大小为targ的正方形。然后我们对缩放图像进行推理。推理的结果通过_unsquare函数传递。这将我们的正方形大小的图像转换为原来的大小。

此后,我们终于可以在大多数云平台上部署,而不会出现任何面向对象的问题。如果你得到一个 OOM 错误,只要减少渲染因子。

我将使用这里描述的 web 应用程序作为起点。

我们需要修改app.py脚本来实现上面描述的run_inference_transform函数。修改后的版本在 Github 上。

有许多方法可以获得谷歌云的推广积分。所以我将在这个项目中使用他们的服务。我的计划是,我所做的一切都将由这些免费学分支付:)。

我在 google cloud 上创建了一个项目,并最终部署工作。谷歌云文档写得很好——但我还是会出错。我发现这个回购非常有用。

像往常一样,我创建了一个 shell 脚本来实现我们在终端中需要做的事情。

一旦我们在 google cloud 上部署了这个,detectron2 模型终于可以工作了。输出的分辨率低于输入,但一切都符合 2G 内存的限制。

在用docker stats构建之后,我可以确认这种方法使用的内存要少得多。在我的本地计算机上,它在峰值时使用 1.16 GB 的内存。而之前的方法使用超过 2GB(大约。2.23 GB)。

你可以点击访问谷歌云实例分割 web 应用。

原载于 2020 年 7 月 26 日https://spiyer 99 . github . io

LSTM-FCN 心脏病学

原文:https://towardsdatascience.com/lstm-fcn-for-cardiology-22af6bbfc27b?source=collection_archive---------29-----------------------

具有完全卷积网络(LSTM-FCN)的长短期记忆是 FCN 的增强,其已经被证明在对时间序列序列进行分类的任务上实现了最先进的性能

心电图(来源:https://i.ytimg.com/vi/HWzACHkCi3U/maxresdefault.jpg

我们将致力于在包含两种不同类型心电图(ECG)的数据库上应用该算法,并看看这种新模型是否可以帮助检测猝死风险高的患者。

LSTM-FCN 建筑

https://ieeexplore.ieee.org/stamp/stamp.jsp?tp= LSTM-FCN 建筑(来源:&ar number = 8141873

该算法由两部分组成:LSTM 块和具有 3 个卷积层的 FCN 部分。

LSTM 部分

长短期记忆递归神经网络是对普通递归神经网络的一种改进,它具有消失梯度问题。LSTM 神经网络通过将选通函数结合到其状态动态中,解决了普通递归神经网络中常见的消失梯度问题。想了解更多关于 LSTM 网络的信息,你可以阅读克里斯托弗·奥拉写的这篇的好文章

除了 LSTM 模块,这部分还包括一个维度混洗。同时,完全卷积模块将时间序列视为具有多个时间步长的单变量时间序列,所提出的架构中的 LSTM 模块将输入时间序列视为具有单个时间步长的多变量时间序列。这是通过维度混排层来实现的,维度混排层调换了时间序列的时间维度。长度为 N 的单变量时间序列在转换后将被视为具有单一时间步长的多变量时间序列(具有 N 个变量)。维度混洗通过减少一个数量级的训练时间来提高该模型的效率。

FCN 部分

我们使用时间卷积网络作为全卷积网络(FCN)分支中的特征提取模块,这意味着我们在这些层中的每一层上应用一组 1D 滤波器(滤波器大小分别为 128、256 和 128),以捕捉输入信号在动作过程中如何演变。一个基本的卷积模块包括一个卷积层,接着是批量归一化(用于提高网络的速度、性能和稳定性),接着是一个激活函数,这里是一个整流线性单元(ReLU)。如果你想了解更多关于卷积层和 CNN 模型的信息,可以看看我关于 CNN 架构的文章。

最后,在最后的卷积块之后应用全局平均池。它用于在分类之前减少模型中的参数数量。

全局池层和 LSTM 块的输出被连接并传递到 softmax 分类层。

数据集

猝死高风险患者和健康对照受试者的心电图记录

我们的数据集分为两部分:一部分用于模型训练,另一部分用于测试。训练将在 23 个序列上进行,测试将在 1189 个序列上进行,这些序列是心电图(ECG)。心电图是一种通过测量心脏的电活动来检查心脏功能的测试。我们有两种不同类别的心电图:一种对应于猝死风险高的患者,另一种对应于健康受试者。

这个数据集被命名为 TwoLeadECG,是 UCR 数据集的一部分,你可以从这里下载。

基线

作为判断 LSTM-FCN 模型结果的参考的算法是 k-最近邻(k-NN)。选择这种算法是因为它是一种既简单又有效的时间序列分类算法。
应用于时态数据的 k-NN 背后的一般思想非常简单,我们将查看 k 个最近邻(多么令人惊讶!)并查看哪个类构成了这些序列的大多数,以便推导出新序列的类。为了知道最近的邻居,我们使用动态时间弯曲算法,该算法允许测量两个时间序列之间的相似性(或距离)。

我们用范围从 1 到 10 的 k(最近邻的数量)的不同值进行测试,我们发现我们自己在测试数据集上的准确度在 0.70 和 0.93 之间变化,当 k = 1 时达到最后一个值

LSTM-FCN 模型

密码

LSTM-FCN 函数

结果

正如我们在模型损失图上看到的,损失函数曲线(训练和验证)逐渐减少并向同一点收敛,表明学习进行得很好,既没有过拟合也没有欠拟合。
关于模型精度图,它证实了模型的良好学习,特别是表明模型给出了非常好的结果。因此,当我们对测试数据集应用该模型时,我们具有 100%的准确性,我们的模型成功地对不同的心电图进行了分类。

这一性能超过了我们已经看到的 k-NN 的结果,甚至可以被认为比心脏病专家的更好,因为我们获得了 100%的准确性!

代码可从以下网址获得:

[## koukou10/lstm-fcn

LSTM-FCN 长短期记忆全卷积网络是 FCN 的一个改进,被认为是…

github.com](https://github.com/koukou10/lstm-fcn)

参考

[## IEEE Xplore 全文 PDF:

编辑描述

ieeexplore.ieee.org](https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8141873) [## 麻省理工学院-BIH 长期数据库

当引用这些材料时,请包括生理网的标准引文:Goldberger AL,Amaral LAN,Glass L…

archive.physionet.org](https://archive.physionet.org/physiobank/database/ltdb/)

用于股票价格预测的 LSTM

原文:https://towardsdatascience.com/lstm-for-google-stock-price-prediction-e35f5cc84165?source=collection_archive---------5-----------------------

为谷歌股价预测创建基于 LSTM 的递归神经网络的技术演练

来自 unsplash 的 Img 通过链接

在本文中,我将一步一步地介绍如何建立一个基于 LSTM 的递归神经网络(RNN)来预测谷歌股票价格。它分为如下 7 个部分。

  1. 问题陈述
  2. 数据处理
  3. 模型结构
  4. 模型编译
  5. 模型拟合
  6. 模型预测法
  7. 结果可视化

让我们开始旅程吧🏃‍♀️🏃‍♂️.

  1. 问题陈述

我们得到了 2012 年 1 月至 2016 年 12 月的谷歌股价。任务是预测 2017 年 1 月的股价趋势。注意, 基于布朗运动,股票价格的未来变化独立于过去。因此,预测准确的股票价格是不可能的,但预测和捕捉上涨和下跌趋势是可能的。

2.数据处理

2.1 导入数据

训练/测试数据保存在中。分别为 csv 文件。我们将用 开盘 价格进行预测。图 1 显示了训练集的一个片段及其散点图。

图 1 训练集及其散点图

train = pd.read_csv(‘Google_Stock_Price_Train.csv’)#keras only takes numpy array
training_set = dataset_train.iloc[:, 1: 2].values

注意 dataset_train.iloc[:,1:2]中的索引范围。值,因为我们需要使它成为 NumPy 数组,不是单个向量,也不是用于训练的数据帧

2.2 特征缩放

下一步是在(0,1)之间缩放股票价格,以避免密集的计算。常见的方法有标准化正常化如图 2 所示。建议进行归一化,尤其是在输出层使用 Sigmoid 函数处理 RNN 时。

图 2 特征缩放方法(作者创建的 Img)

from sklearn.preprocessing import MinMaxScaler
sc = MinMaxScaler(feature_range = (0, 1))training_set_scaled = sc.fit_transform(training_set)

2.3 数据结构创建

创建滑动窗口很重要

需要一个特殊的数据结构来覆盖 60 个时间戳,基于此,RNN 将预测第 61 个价格。这里,基于实验,过去时间戳的数量被设置为 60。因此, X_train 是一个嵌套列表,它包含 60 个时间戳价格的列表。 y_train 是第二天的股票价格列表,对应 X_train 中的各个列表。具体来说,

X_train = []
y_train = []
for i in range(60, len(training_set_scaled)):
    X_train.append(training_set_scaled[i-60: i, 0])
    y_train.append(training_set_scaled[i, 0])
    X_train, y_train = np.array(X_train), np.array(y_train)

图 3 显示了 X_trainy_train 的片段。 X_train 中每一行 60 个价格用于预测 y_train 中对应的第二天股票价格。

图 3 X_trainy_train 数据

2.4 数据重塑

如上所述,我们用 开盘 价格进行预测。也就是说,我们只有一个指标或特征。但是我们可以按照同样的数据处理方法添加更多的指标。为此,我们需要为指标的数量添加一个新的维度。具体来说,

X_train = np.reshape(X_train, newshape = (X_train.shape[0], X_train.shape[1], 1))

new shapein(批量大小、时间戳数量、指示器数量)。(批量大小,时间戳个数)是 X_train 的形状。这里我们只有一个指标。

太好了。✌✌.,我们把训练器材准备好了

3.模型构建

基本上,我们正在使用 LSTM 构建一个用于连续值预测的神经网络回归器。首先,初始化模型。

regressor = Sequential()

然后,添加第一个 LSTM 图层,接着添加删除图层。

regressor.add(LSTM(units = 50, return_sequences = True, input_shape = (X_train.shape[1], 1)))regressor.add(Dropout(rate = 0.2))

注意对于 LSTM 层,单位是该层中 LSTM 神经元的数量。50 个神经元将赋予模型高维度,足以捕捉向上和向下的趋势。 return_sequences 为真,因为我们需要在当前图层之后添加另一个 LSTM 图层。 input_shape 对应的是时间戳的个数和指示器的个数。对于退出,50 个神经元中的 20%将在训练的每次迭代中被随机忽略。

按照上述相同的方法,添加第二,第三和第四 LSTM 层。

##add 2nd lstm layer
regressor.add(LSTM(units = 50, return_sequences = True))
regressor.add(Dropout(rate = 0.2))##add 3rd lstm layer
regressor.add(LSTM(units = 50, return_sequences = True))
regressor.add(Dropout(rate = 0.2))##add 4th lstm layer
regressor.add(LSTM(units = 50, return_sequences = False))
regressor.add(Dropout(rate = 0.2))

注意最后一个 LSTM 层, return_sequencesFalse 由于我们不会添加更多的 LSTM 层。

最后,添加输出层。输出维度是 1,因为我们每次预测 1 个价格。

regressor.add(Dense(units = 1))

太好了!我们已经创建了一个基于 LSTM 的 RNN 模型🧨🧨.

4.模型编译

现在,让我们通过选择一个 SGD 算法和一个损失函数来编译 RNN。对于优化器,我们使用 Adam ,这是一个安全的选择。损失函数是实际值和预测值之间的均方误差。

regressor.compile(optimizer = ‘adam’, loss = ‘mean_squared_error’)

5.模型拟合

现在,让我们适合我们的 RNN。

regressor.fit(x = X_train, y = y_train, batch_size = 32, epochs = 100)

RNN 权重每 32 个股票价格更新一次,批量为 32 个。如果模型的损失没有收敛,请随意尝试更多的批次和时期。

太好了,现在让我们开始训练。最后,我们发现从损失 0.062 开始,我们在时期 50 得到损失0.0026,到时期 100 损失0.0015**🎉🎉。**

6.模型预测****

6.1 导入测试数据

使用第 2.1 节中的相同方法,读取测试数据。

**dataset_test = pd.read_csv(‘Google_Stock_Price_Test.csv’)real_stock_price = dataset_test.iloc[:, 1: 2].values**

6.2 数据处理

首先,我们需要连接用于预测的训练和测试数据集,因为我们使用前 60 天的股票价格来预测第二天的价格。换句话说,我们需要测试数据集中第一个日期之前 60 天的价格。

**dataset_total = pd.concat((dataset_train[‘Open’],dataset_test[‘Open’]), axis = 0)**

然后,为预测创建输入,从测试数据集中第一个日期之前 60 天的日期开始索引。

**inputs = 
dataset_total[len(dataset_total)-len(dataset_test)- 60: ].values**

第三,改变输入的形状,使其只有一列。

**inputs = inputs.reshape(-1, 1)**

第四,使用由训练集设置的标度,对测试输入进行标度。

**inputs = sc.transform(inputs)**

最后,创建测试数据结构,如第 2.3 节所述。

**X_test = []
for i in range(60, len(inputs)): 
    X_test.append(inputs[i-60: i, 0])
    X_test = np.array(X_test)
    #make numpy array as 3D , adding num of indicator
    X_test = np.reshape(X_test, newshape = (X_test.shape[0],  
                        X_test.shape[1], 1))**

6.3 模型预测

现在, X_test 准备好预测了。

**predicted_stock_price = regressor.predict(X_test)**

别忘了,我们预测的是缩放后的值,所以我们需要反转预测。

**predicted_stock_price = sc.inverse_transform(predicted_stock_price)**

7.结果可视化****

在最后一步中,让我们创建一个可视化图来轻松地检查预测。

**plt.plot(real_stock_price, color = ‘red’, label = ‘Real price’)
plt.plot(predicted_stock_price, color = ‘blue’, label = ‘Predicted price’)
plt.title(‘Google price prediction’)
plt.xlabel(‘Time’)
plt.ylabel(‘Price’)
plt.legend()
plt.show()**

如图 4 和图 5 所示,预测滞后于真实值,因为模型不能对非线性变化做出快速反应。但另一方面,模型对平滑变化反应良好。因此,我们得出结论,在包含峰值的预测部分,模型滞后于实际价格,但在包含平稳变化的部分,模型设法遵循向上和向下的趋势** ✨✨.**

图 4 实际价格与预测价格

图 5 大时间尺度上的预测

太好了!这就是所有的旅程!如果需要源代码,请访问我的Github页面🤞🤞。

LSTM 梯度

原文:https://towardsdatascience.com/lstm-gradients-b3996e6a0296?source=collection_archive---------9-----------------------

LSTM 单元梯度的详细数学推导。

LSTM 或长短期记忆是复杂和最先进的神经网络结构的非常重要的构建块。这篇文章背后的主要思想是解释背后的数学。为了对 LSTM 有一个初步的了解,我推荐下面的博客。

学分

[## 了解 LSTM 网络

2015 年 8 月 27 日发布人类不是每秒钟都从零开始思考。当你读这篇文章时,你…

colah.github.io](https://colah.github.io/posts/2015-08-Understanding-LSTMs/)

内容:

概念

  • 介绍
  • 说明
  • 推导先决条件

B —推导

  • LSTM 的产量
  • 隐藏状态
  • 输出门
  • 细胞状态
  • 输入门
  • 忘记大门
  • 对 LSTM 的投入
  • 权重和偏差

C —随时间反向传播

D —结论

概念

介绍

图 1 : LSTM 细胞

上图是单个 LSTM 细胞的示意图。我知道这看起来很吓人😰,但是我们将一个接一个地浏览它,希望在文章结束时,它会变得非常清楚。

说明

基本上,一个 LSTM 细胞有 4 个不同的组成部分。忘记门、输入门、输出门和单元状态。我们将首先简要讨论这些部分的用法(详细解释请参考上面的博客),然后深入研究其中的数学部分。

忘门

顾名思义,这个部分负责决定最后一步要丢弃或保留哪些信息。这是由第一个乙状结肠层完成的。

图 2:蓝色标记的忘记门

基于 h_t-1(先前的隐藏状态)和 x_t(在时间步长 t 的当前输入),这为单元状态 C_t-1 中的每个值决定 0 和 1 之间的值。

图 3:忘记门和以前的细胞状态

对于所有的 1,所有的信息都保持原样,对于所有的 0,所有的信息都被丢弃,而对于其他值,它决定了有多少来自前一状态的信息将被携带到下一状态。

输入门

图 4:用蓝色标记的输入门

Christopher Olah 对输入门发生的事情有一个漂亮的解释。引用他的博客:

下一步是决定我们要在单元格状态中存储什么新信息。这有两个部分。首先,一个称为“输入门层”的 sigmoid 层决定我们要更新哪些值。接下来,tanh 层创建一个新的候选值向量,C~t,可以添加到状态中。在下一步中,我们将结合这两者来创建状态更新。

现在,这两个值,即 i_t 和 c~t 结合起来决定将什么新的输入馈送到单元状态。

单元格状态

图 5:蓝色标记的电池状态

细胞状态作为 LSTM 的记忆。这是他们在处理更长的输入序列时比香草 RNN 表现更好的地方。在每个时间步长,先前的单元状态(C_t-1)与遗忘门结合,以决定哪些信息将被结转,该信息又与输入门(i_t 和 c~t)结合,以形成新的单元状态或单元的新存储器。

图 6:新的细胞状态方程

输出门

图 7:标有蓝色的输出门

最后,LSTM 细胞必须给出一些输出。从上面获得的单元状态通过一个称为 tanh 的双曲线函数传递,以便在-1 和 1 之间过滤单元状态值。详情进入不同的激活功能,这个是个不错的博客。

现在,我希望 LSTM 单元的基本单元结构是清楚的,我们可以继续推导我们将在实现中使用的方程。

推导先决条件

  1. 要求:推导方程的核心概念是基于反向传播、成本函数和损失。如果你不熟悉这些,这几个链接将有助于更好地理解。本文还假设对高中微积分有基本的了解(计算导数和规则)。

[## 理解反向传播算法

了解神经网络最重要组成部分的具体细节

towardsdatascience.com](/understanding-backpropagation-algorithm-7bb3aa2f95fd) [## 寻找神经网络的成本函数

一步一步:神经网络背后的数学

towardsdatascience.com](/step-by-step-the-math-behind-neural-networks-490dc1f3cfd9)

2.变量:对于每个门,我们有一组权重和偏差,表示为:

  • W_f,b_f->忘记门重和偏差
  • W_i,b_i->输入门权重和偏置
  • 候选小区状态权重和偏差
  • W_o,b_o->输出门权重和偏置

W_v,b_v ->与 Softmax 层关联的权重和偏差。

f_t,i_t,c_tilede_t,o_t ->激活函数的输出

a_f,a_i,a_c,a_o ->激活函数的输入

j 是成本函数,我们将根据它来计算导数。注意(下划线(_)后的字符是下标)

3.正向推进方程式:

图 8:门方程

图 9:电池状态和输出方程

4.计算过程:让我们以忘记门为例来说明导数的计算。我们需要遵循下图中红色箭头的路径。

所以我们画出一条从 f_t 到成本函数 J 的路径,即

f_t →C_t →h_t →J。

反向传播恰好发生在同一步骤中,但方向相反

f_t ←C_t ←h_t ←J。

j 相对于 h_t 微分,h_t 相对于 _C_t 微分,C_t 相对于 f_t 微分。

因此,如果我们在这里观察,J 和 h_t 是单元格的最后一步,如果我们计算 dJ/dh_t,那么它可以用于类似 dJ/dC_t 的计算,因为:

dJ/dC_t = dJ/dh_t * dh_t/dC_t ( 链式法则)

类似地,将计算第 1 点中提到的所有变量的导数。

既然我们已经准备好了变量,也清楚了正向推进方程,是时候通过反向传播来推导导数了。我们将从输出方程开始,因为我们看到在其他方程中使用了相同的导数。这就是链式法则的用武之地。所以现在就开始吧。

衍生物

lstm的输出

输出有两个我们需要计算的值。

  1. Softmax:对于使用 Softmax 的交叉熵损失的导数,我们将直接使用最终方程。

详细的推导过程如下:

[## 交叉熵损失函数的温和介绍

神经网络在多类分类问题中产生多个输出。但是,他们没有能力…

sefiks.com](https://sefiks.com/2017/12/17/a-gentle-introduction-to-cross-entropy-loss-function/#:~:text=Cross Entropy Error Function&text=If loss function were MSE,error function is cross entropy.&text=c refers to one hot,refers to softmax applied probabilities.)

隐藏状态

我们有 h_t 这样的隐藏态,h_t 对 w . r . t . j 求导,根据链式法则,推导可以在下图中看到。我们使用图 9 等式 7 中提到的 V_t 值,即:

v t = W v . h t+b v

输出门

相关变量:a_o 和 o_t。

o_t :下图显示了 o_t 和 J 之间的路径。根据箭头,微分的完整方程如下:

dJ/dV_t * dV_t/dh_t * dh_t/dO_t

dJ/dV_t * dV_t/dh_t 可以写成 dJ/dh_t(我们从隐藏状态得到这个值)。

h_t 的值= o_t * tanh(c_t) ->图 9 等式 6。 所以我们只需要对 h_t w.r.t o_t. 进行区分,区分如下:-

a_o :同样,显示 a_o 和 J 之间的路径。根据箭头,微分的完整方程如下:

dJ/dV _ t * dV _ t/DH _ t * DH _ t/dO _ t * dO _ t/da _ o

dJ/dV_t * dV_t/dh_t * dh_t/dO_t 可以写成 dJ/dO_t(上面 O_t 我们有这个值)。

o_t = sigmoid (a_o) ->图 8 等式 4。 所以我们只需要区分 o _ T w . r . T a _ o .T他的区分将为:-

细胞状态

C_t 是单元的单元状态。除此之外,我们还在这里处理候选单元状态 a_c 和 c~_t。

C_t:C _ t 的推导非常简单,因为从 C _ t 到 J 的路径非常简单。C_t → h_t → V_t → J .由于我们已经有了 dJ/dh_t,所以直接微分 h_t w.r.t C_t。

h_t = o_t * tanh(c_t) ->图 9 等式 6。 所以我们只需要区分 h_t w.r.t C_t.

注意:单元状态 clubbed 会在文末解释。

c~_t :下图显示了 c~_t 和 J 之间的路径。根据箭头,微分的完整方程如下:

dJ/dh_t * dh_t/dC_t * dC_t/dc~_t

dJ/dh_t * dh_t/dC_t 可以写成 dJ/dC_t(上面我们有这个值)。

C_t 的值如图 9 等式 5 所示(下图第 3 行最后一个 c_t 中缺少波浪号(~)符号->书写错误)。 所以我们只需要区分 C_t w.r.t c~_t.

a_c : 下图显示了 a_c 和 J 之间的路径。根据箭头,微分的完整方程如下:

dJ/DH _ t * DH _ t/dC _ t * dC _ t/dC ~ _ t * dC ~ _ t/da _ c

dJ/dh_t * dh_t/dC_t * dC_t/dc~_t 可以写成 dJ/dc~_t(我们从上面有这个值)。

c \u t 的值如图 8 等式 3 所示。 所以我们只需要区分 c~_t w.r.t a_c

输入门

相关变量:i_t 和 a_i

i_t :下图显示了 i_t 和 J 之间的路径。根据箭头,微分的完整方程如下:

dJ/dh_t * dh_t/dC_t * dC_t/di_t

dJ/dh_t * dh_t/dC_t 可以写成 dJ/dC_t(我们从 cell state 得到这个值)。所以我们只需要区分 C_t w.r.t i_t.

C_t 的值如图 9 等式 5 所示。因此,区别如下:-

a_i : 下图显示了 a_i 和 J 之间的路径。根据箭头,微分的完整方程如下:

dJ/DH _ t * DH _ t/dC _ t * dC _ t/di _ t * di _ t/da _ I

dJ/dh_t * dh_t/dC_t * dC_t/di_t 可以写成 dJ/di_t(我们从上面有这个值)。所以我们只需要区分 i_t w.r.t a_i.

忘记大门

相关变量:f_t 和 a_f

f_t :下图显示了 f_t 和 J 之间的路径。根据箭头,微分的完整方程如下:

dJ/dh_t * dh_t/dC_t * dC_t/df_t

dJ/dh_t * dh_t/dC_t 可以写成 dJ/dC_t(我们从 cell state 得到这个值)。所以我们只需要区分 C_t w.r.t f_t.

C_t 的值如图 9 等式 5 所示。因此,区别如下:-

a_f :下图显示了 f_t 和 J 之间的路径。根据箭头,微分的完整方程如下:

dJ/DH _ t * DH _ t/dC _ t * dC _ t/df _ t * df _ t/da _ t

dJ/dh_t * dh_t/dC_t * dC_t/df_t 可以写成 dJ/df_t(我们从上面有这个值)。所以我们只需要区分 f_t w.r.t a_f

Lstm 的输入

有 2 个变量与每个单元的输入相关联,即先前的单元状态 C_t-1 和与当前输入连接的先前的隐藏状态,即

[h_t-1,x_t] -> Z_t

C_t-1 : 这是 Lstm 细胞的记忆。图 5 显示了单元状态。C_t-1 的推导相当简单,因为只涉及 C_t-1 和 C_t。

Z_t :如下图所示,Z_t 进入 4 条不同的路径,a_f,a_i,a_o,a_c

Z_t → a_f → f_t → C_t → h_t → J . ->忘记门

Z_t → a_i→ i_t → C_t → h_t → J . ->输入门

Z_t → a_c → c~_t → C_t → h_t → J . ->候选细胞态

Z_t → a_o → o_t → C_t → h_t → J . ->输出门

权重和偏差

W 和 b 的推导非常简单。下面的推导是针对 Lstm 的输出门。对于其余的门,对权重和偏差进行类似的处理。

输入和遗忘门的权重和偏差

输出和输出门的权重和偏置

dJ/d_W_f = dJ/da_f . da_f / d_W_f ->忘记门

dJ/d_W_i = dJ/da_i . da_i / d_W_i ->输入门

dJ/d_W_v = dJ/dV_t . dV_t/ d_W_v ->输出

dJ/d_W_o = dJ/da_o . da_o / d_W_o ->输出门

最后我们完成了所有的推导。现在我们只需要澄清几点。

时间反向传播

到目前为止,我们所做的是一个单一的时间步骤。现在我们必须进行一次迭代。

因此,如果我们有总共 T 个时间步长,那么每个时间步长的梯度将在 T 个时间步长结束时相加,因此每次迭代结束时的累积梯度将为:

图 10:每次迭代结束时的累积梯度

现在这些将用于更新权重。

图 11:重量更新

结论

LSTMs 是非常复杂的结构,但是它们也工作得很好。主要有两种类型的 RNN 具有这种特征:LSTM 和格鲁

LSTMs 的训练也是一项棘手的任务,因为有许多超参数,正确组合通常是一项困难的任务。

所以,到现在为止,我希望 LSTM 的数学部分已经很清楚了,我建议你把手弄脏,以便更清楚、更好地理解它。以下是一些可能有帮助的链接:

[## 理解 LSTM 及其在情感分析 keras 中的快速实现。

towardsdatascience.com](/understanding-lstm-and-its-quick-implementation-in-keras-for-sentiment-analysis-af410fd85b47) [## Keras LSTM 教程-如何轻松建立一个强大的深度学习语言模型

在以前的帖子中,我介绍了用于构建卷积神经网络和执行单词嵌入的 Keras。的…

adventuresinmachinelearning.com](https://adventuresinmachinelearning.com/keras-lstm-tutorial/)

感谢你阅读这篇文章,希望你喜欢。

快乐学习😃!!!

LSTM 网络|详细解释

原文:https://towardsdatascience.com/lstm-networks-a-detailed-explanation-8fae6aefc7f9?source=collection_archive---------0-----------------------

入门

LSTMs 的全面介绍

这篇文章解释了长短期记忆(LSTM)网络。我发现学习一个主题的最好方法是阅读许多不同的解释,所以我会在本文的最后链接一些我认为特别有用的资源。我强烈建议你去看看他们对 LSTMs 的不同观点和解释!

LSTM 图——这张图和下面所有的图片都是作者创作的

什么是 LSTMs,为什么有用?

LSTM 网络是专门设计来克服递归神经网络 RNNs 所面临的长期依赖性问题(由于消失梯度问题)。LSTMs 具有反馈连接,这使得它们不同于更传统的前馈神经网络。这一特性使得 LSTMs 能够处理整个数据序列(例如时间序列),而不用独立地处理序列中的每个点,而是保留关于序列中先前数据的有用信息,以帮助处理新数据点。因此,LSTMs 特别擅长处理数据序列,如文本、语音和一般时间序列。

例如,假设我们试图预测每月的冰淇淋销售额。正如人们所预料的,这种差异随着月份的不同而变化很大,12 月最低,6 月最高。

LSTM 网络可以学习这种每 12 个时间周期存在的模式。它不仅仅使用以前的预测,而是保留一个更长期的上下文,这有助于它克服其他模型面临的长期依赖问题。值得注意的是,这是一个非常简单的例子,但是当模式被更长的时间间隔分开时(例如,在很长的文本段落中),LSTMs 变得越来越有用。

LSTM 网络是如何工作的?

首先,在基本层面上,LSTM 在特定时间点的输出取决于三件事:
▹网络的当前长期记忆——被称为单元状态
▹前一时间点的输出——被称为前一隐藏状态
▹当前时间步的输入数据

LSTMs 使用一系列“门”来控制数据序列中的信息如何进入、存储和离开网络。典型的 LSTM 有三道门;忘记门,输入门和输出门。这些门可以被认为是过滤器,每一个都是它们自己的神经网络。我们将在这篇文章中详细探讨它们。

在下面的解释中,我们考虑下图所示的 LSTM 池。当查看本文中的图表时,想象从左向右移动。

LSTM 图

第一步

该过程的第一步是遗忘门。这里,我们将决定单元状态(网络的长期记忆)的哪些位是有用的,给定先前的隐藏状态和新的输入数据。

忘记大门

为此,先前的隐藏状态和新的输入数据被输入到神经网络中。该网络生成一个向量,其中每个元素都在区间[0,1]中(通过使用 sigmoid 激活来确保)。这个网络(在遗忘门内)被训练成当输入的一个分量被认为不相关时输出接近 0,而当相关时输出接近 1。将这个向量的每个元素看作一种过滤器/筛子是有用的,当值接近 1 时,它允许更多的信息通过。

这些输出值然后被发送并逐点乘以先前的单元状态。这种逐点乘法意味着被遗忘门网络视为不相关的单元状态的分量将被乘以一个接近 0 的数,因此对后续步骤的影响较小。

总之,遗忘门决定了给定序列中先前的隐藏状态和新的数据点,哪些长期记忆片段现在应该被遗忘(具有较小的权重)。

第二步

下一步涉及新存储网络输入门。这一步的目标是在给定先前的隐藏状态和新的输入数据的情况下,确定什么新的信息应该被添加到网络的长期记忆(细胞状态)中。

输入门

新的记忆网络和输入门本身都是神经网络,并且都接受相同的输入,即先前的隐藏状态和新的输入数据。值得注意的是这里的输入实际上与遗忘门的输入相同!

  1. 新记忆网络是一个 tanh 激活的神经网络,它已经学会了如何将先前的隐藏状态和新的输入数据结合起来,以生成一个“新的记忆更新向量”。给定来自先前隐藏状态的上下文,该向量实质上包含来自新输入数据的信息。这个向量告诉我们,在给定新数据的情况下,网络的长期存储器(单元状态)的每个组件需要更新多少。

    注意,我们在这里使用一个双曲正切值,因为它的值位于[-1,1]中,所以可以是负数。如果我们希望减少单元状态中组件的影响,这里负值的可能性是必要的。

  2. 然而,在上面的第 1 部分中,我们生成了新的内存向量,这里有一个大问题,它实际上并没有检查新的输入数据是否值得记忆。这就是输入门出现的地方。输入门是一个 sigmoid 激活的网络,它作为一个过滤器,识别“新记忆向量”的哪些成分值得保留。该网络将输出[0,1]中的值的向量(由于 sigmoid 激活),允许其通过逐点乘法充当过滤器。类似于我们在遗忘门中看到的,接近零的输出告诉我们,我们不想更新单元状态的该元素。

  3. 部分 1 和部分 2 的输出逐点相乘。这导致我们在第 2 部分中决定的新信息的大小被调整,并且如果需要的话被设置为 0。得到的组合向量然后被到单元状态,导致网络的长期记忆被更新。

第三步

既然我们对网络长期记忆的更新已经完成,我们可以进入最后一步,输出门,决定新的隐藏状态。为了决定这一点,我们将使用三样东西;新更新的单元状态、先前的隐藏状态和新的输入数据。

有人可能认为我们可以只输出更新的单元状态;然而,这相当于有人在只被问及他们认为明天股市会涨还是会跌时,就把他们所知道的关于股市的一切都卸下来了!

为了防止这种情况发生,我们创建了一个滤波器,输出门,就像我们在遗忘门网络中所做的一样。输入是相同的(先前的隐藏状态和新数据),激活也是 sigmoid(因为我们希望从[0,1]中的输出获得滤波器属性)。

输出门

如前所述,我们希望将这个过滤器应用于新更新的单元格状态。这确保了只输出必要的信息(保存到新的隐藏状态)。但是,在应用过滤器之前,我们通过一个 tanh 传递单元格状态,以强制值进入区间[-1,1]。

这最后一步的逐步过程如下:
▹将双曲正切函数逐点应用于当前单元状态,以获得压扁的单元状态,其现在位于[-1,1]。
▹通过 sigmoid 激活的神经网络传递先前的隐藏状态和当前的输入数据以获得滤波器向量。
▹通过逐点乘法将该滤波器向量应用于压扁的单元状态。
▹输出新的隐藏状态!

一些澄清

虽然第 3 步是 LSTM 单元格中的最后一步,但是在我们的 LSTM 实际输出我们正在寻找的类型的预测之前,我们还需要考虑一些事情。

首先,上述步骤重复多次。例如,如果您试图根据前 30 天的定价数据预测未来几天的股票价格,那么这些步骤将重复 30 次。换句话说,你的模型将迭代产生 30 个隐藏状态来预测明天的价格。

但是输出还是隐藏状态。在上面的例子中,我们想要明天的价格,我们不能从明天的隐藏状态中赚钱!因此,要将隐藏状态转换为输出,我们实际上需要应用一个线性层,作为 LSTM 过程的最后一步。这种线性层步骤只在最末端发生一次,这就是为什么它通常不包括在 LSTM 单元图中的原因。

在许多其他参考资料中,根本没有提到这个线性层步骤,这最初让我感到困惑,所以希望这能为你们中的一些读者提供澄清!

如何用 Python 实现 LSTM?

如果您想查看如何在 Pytorch 中实现所有这些的示例,请查看我的另一篇文章!👇

[## 预测沃尔玛季度收入——py torch LSTM 示例

应用 LSTM 网络预测季节性时间序列数据

levelup.gitconnected.com](https://levelup.gitconnected.com/forecasting-walmart-quarterly-revenue-pytorch-lstm-example-b4e4b20862a7)

结论

感谢那些坚持到现在的人,我希望这篇文章对你理解 LSTM 网络有所帮助!如有任何反馈或问题,请随时发表评论。

[## 加入我的推荐链接-海豚

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

medium.com](https://medium.com/@riandolphin/membership)

其他资源

其他一些观点可以在 Colah 的 Github 帖子Michael Phi帖子中找到,其中包含精彩的动画,以及 Stanford 的笔记

基于 Pytorch 的 LSTM 文本分类

原文:https://towardsdatascience.com/lstm-text-classification-using-pytorch-2c6c657f8fc0?source=collection_archive---------0-----------------------

一步一步的指导你如何在 Pytorch 中建立一个双向 LSTM!

克里斯托夫·高尔在 Unsplash 上拍摄的照片

介绍

欢迎来到本教程!本教程将在几分钟内教你如何为文本分类构建一个双向【LSTM】。如果你还没有看过我之前关于 BERT 文本分类 的文章,这篇教程包含了和那篇类似的代码,但是包含了一些支持 LSTM 的修改。本文还解释了我是如何对两篇文章中使用的数据集进行预处理的,这是来自 Kaggle 的 真假新闻数据集

首先,什么是 LSTM,我们为什么要使用它?LSTM 代表长短期记忆网络,属于一个更大的神经网络类别,称为递归神经网络(RNN) 。与传统的 RNN 相比,它的主要优势在于,它能够通过复杂的架构更好地处理长期依赖性,该架构包括三个不同的门:输入门、输出门和遗忘门。这三个门共同决定在任意时间内 LSTM 细胞中哪些信息该记住,哪些该忘记。

LSTM 细胞

现在,我们对 LSTM 有了更多的了解,让我们集中在如何实现它的文本分类。本教程分为以下步骤:

  1. 预处理数据集
  2. 导入库
  3. 加载数据集
  4. 建立模型
  5. 培养
  6. 估价

在我们开始学习本教程之前,您可以在这里访问本文中的代码:

步骤 1:预处理数据集

原始数据集如下所示:

数据集概述

数据集包含任意的索引、标题、文本和相应的标签。

对于预处理,我们导入 Pandas 和 Sklearn,并为路径、训练验证和测试比率定义一些变量,以及用于将每个句子切割到第一个first_n_words单词的trim_string函数。修剪数据集中的样本不是必需的,但是它能够更快地训练较重的模型,并且通常足以预测结果。

接下来,我们将真实的转换为 0,将虚假的转换为 1,连接标题文本以形成新列标题文本(我们使用标题和文本来决定结果),删除带有空文本的行,将每个样本修剪为first_n_words,并根据train_test_ratiotrain_valid_ratio分割数据集。我们将生成的数据帧保存到中。csv 文件,获取 train.csvvalid.csvtest.csv

步骤 2:导入库

我们导入 Pytorch 用于模型构建,torchText 用于加载数据,matplotlib 用于绘图,sklearn 用于评估。

步骤 3:加载数据集

首先,我们使用 torchText 为数据集中的标签创建一个标签字段,并为标题文本标题文本创建一个文本字段。然后,我们通过将 TabularDataset 指向包含 train.csvvalid.csvtest.csv 数据集文件的路径来构建 tabular dataset。我们创建加载数据的 train、valid 和 test 迭代器,最后,使用 train 迭代器构建词汇表(只计算最小频率为 3 的标记)。

步骤 4:构建模型

我们构造了继承自 nn 的 LSTM 类。模块。在 LSTM 内部,我们构建了一个嵌入层,然后是一个双 LSTM 层,最后是一个完全连接的线性层。在 forward 函数中,我们通过嵌入层传递文本 id 以获得嵌入,通过容纳变长序列的 LSTM 传递,从两个方向学习,通过完全连接的线性层传递,最后 sigmoid 以获得序列属于假的概率(为 1)。

第五步:培训

在训练之前,我们为检查点和指标构建保存和加载函数。对于检查点,保存模型参数和优化器;对于度量标准,将保存列车损失、有效损失和全局步骤,以便稍后可以轻松地重新构建图表。

我们用 10 个历元训练 LSTM,每当超参数设置实现最佳(最低)验证损失时,保存检查点和指标。以下是培训期间的输出:

整个训练过程在 Google Colab 上很快。训练了不到两分钟!

一旦我们完成了训练,我们可以加载之前保存的指标,并输出一个图表,显示整个时间内的训练损失和验证损失。

第六步:评估

最后,为了进行评估,我们选择之前保存的最佳模型,并根据我们的测试数据集对其进行评估。我们使用默认阈值 0.5 来决定何时将样本归类为假样本。如果模型输出大于 0.5,我们把那个新闻归类为假的;否则,真实的。我们输出分类报告,指出每个类别的精确度、召回率和 F1 值,以及总体精确度。我们还输出混淆矩阵。

我们可以看到,使用一层双 LSTM,我们可以在假新闻检测任务上实现 77.53%的准确率。

结论

本教程一步一步地解释了如何使用 Pytorch 实现你自己的文本分类 LSTM 模型。我们发现,双 LSTM 在假新闻检测方面达到了可接受的准确率,但仍有改进的空间。如果你想要更有竞争力的表现,可以看看我之前关于 BERT 文本分类 的文章!

[## 使用 Pytorch 的 BERT 文本分类

文本分类是自然语言处理中的一项常见任务。我们应用 BERT,一个流行的变压器模型,对假新闻检测使用…

towardsdatascience.com](/bert-text-classification-using-pytorch-723dfb8b6b5b)

如果你想了解更多关于现代自然语言处理和深度学习的知识,请关注我的最新文章:)

参考

[1] S. Hochreiter,J. Schmidhuber,长短期记忆 (1997),神经计算

时间序列预测:使用 LSTM 模型预测股票价格

原文:https://towardsdatascience.com/lstm-time-series-forecasting-predicting-stock-prices-using-an-lstm-model-6223e9644a2f?source=collection_archive---------0-----------------------

在这篇文章中,我将向你展示如何使用预测 LSTM 模型来预测股票价格

作者创作的人物。

1.介绍

1.1.时间序列和预测模型

传统上,大多数机器学习(ML)模型使用一些观察值(样本/实例)作为输入特征,但数据中没有时间 维度

时间序列预测模型是能够根据先前 观测 预测 未来值的模型。时间序列预测广泛用于非平稳数据非平稳数据被称为统计属性(如平均值和标准偏差)不随时间保持不变,而是随时间变化的数据。

这些非平稳输入数据(用作这些模型的输入)通常被称为时间序列。时间序列的一些例子包括随时间变化的温度值、随时间变化的股票价格、随时间变化的房屋价格等。因此,输入是一个信号(时间序列),它是由在时间中连续获得的观察值定义的。

时间序列是按时间顺序进行的一系列观察。

时间序列的一个例子。作者用 Python 创作的情节。

观察:时序数据记录在离散时间刻度时间刻度上。

免责声明(在我们继续之前):已经有人尝试使用时间序列分析算法来预测股票价格,尽管它们仍然不能用于在真实市场中下注。这只是一篇教程文章,并不打算以任何方式“指导”人们购买股票。

——我的邮件列表只需 5 秒:https://seralouk.medium.com/subscribe

-成为会员支持我:https://seralouk.medium.com/membership

2.LSTM 模式

长短期记忆 ( LSTM )是一种用于深度学习领域的人工递归神经网络(RNN)架构。与标准的前馈神经网络不同,LSTM 有反馈连接。它不仅可以处理单个数据点(例如图像),还可以处理整个数据序列(例如语音或视频输入)。

LSTM 模型能够储存一段时间的信息。

换句话说,它们有记忆能力。记住,LSTM 代表长短期记忆模型。

当我们处理时间序列或顺序数据时,这个特性是非常有用的。当使用 LSTM 模型时,我们可以自由决定存储什么信息,丢弃什么信息。我们使用“门”来实现。对 LSTM 的深入理解超出了这篇文章的范围,但是如果你有兴趣了解更多,看看这篇文章末尾的参考资料。

如果你想在交互式路线图和活跃的学习社区的支持下自学数据科学,看看这个资源:【https://aigents.co/learn

3.获取股票价格历史数据

感谢雅虎财经我们可以免费获得的数据。使用以下链接获取特斯拉:https://finance.yahoo.com/quote/TSLA/history?的股价历史周期 1=1436486400 &周期 2=1594339200 &间隔=1d &过滤器=历史&频率=1d

您应该看到以下内容:

点击下载并保存。csv 文件本地保存在您的计算机上。

数据是从 2015 到现在( 2020 )!

4.Python 工作示例

所需模块:Keras,Tensorflow,Pandas,Scikit-Learn & Numpy

我们将构建一个多层 LSTM 递归神经网络预测一系列值中的最后一个值,即本例中的特斯拉股票价格。

加载数据数据检查它们:

import math
import matplotlib.pyplot as plt
import keras
import pandas as pd
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import Dropout
from keras.layers import *
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
from sklearn.model_selection import train_test_split
from keras.callbacks import EarlyStoppingdf=pd.read_csv("TSLA.csv")
print(‘Number of rows and columns:’, df.shape)
df.head(5)

上述代码的输出

下一步是数据分割成训练测试集合,以避免过拟合,并能够调查我们模型的泛化能力。要了解更多关于过度拟合的信息,请阅读本文:

[## 你的模型是否过拟合?或者不合身?python 中使用神经网络的示例

过拟合,欠拟合,泛化能力,交叉验证。一切都简单解释了。我还提供了一个…

towardsdatascience.com](/is-your-model-overfitting-or-maybe-underfitting-an-example-using-a-neural-network-in-python-4faf155398d2)

要预测的目标值将是“收盘股价值。

training_set = df.iloc[:800, 1:2].values
test_set = df.iloc[800:, 1:2].values

模型 拟合之前,归一化数据不失为一个好主意。这将提高性能。你可以在这里阅读更多关于最小-最大缩放器:

[## 关于 Python 中的最小-最大规范化,您需要知道的一切

在这篇文章中,我将解释什么是最小-最大缩放,什么时候使用它,以及如何使用 scikit 在 Python 中实现它

towardsdatascience.com](/everything-you-need-to-know-about-min-max-normalization-in-python-b79592732b79)

让我们构建具有 1 天滞后时间(滞后 1)的输入要素:

# Feature Scaling
sc = MinMaxScaler(feature_range = (0, 1))
training_set_scaled = sc.fit_transform(training_set)# Creating a data structure with 60 time-steps and 1 output
X_train = []
y_train = []
for i in range(60, 800):
    X_train.append(training_set_scaled[i-60:i, 0])
    y_train.append(training_set_scaled[i, 0])
X_train, y_train = np.array(X_train), np.array(y_train)X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))
#(740, 60, 1)

现在我们已经将数据整形为以下格式(#值、#时间步长、#1 维输出)。

现在,该建立模型了。我们将建立有 50 个神经元的 LSTM4 个隐含层。最后,我们将在输出层分配 1 个神经元用于预测标准化的股票价格。我们将使用 MSE 损失函数和 Adam 随机梯度下降优化器。

注意:以下需要一些时间(~5min)。

model = Sequential()#Adding the first LSTM layer and some Dropout regularisation
model.add(LSTM(units = 50, return_sequences = True, input_shape = (X_train.shape[1], 1)))
model.add(Dropout(0.2))# Adding a second LSTM layer and some Dropout regularisation
model.add(LSTM(units = 50, return_sequences = True))
model.add(Dropout(0.2))# Adding a third LSTM layer and some Dropout regularisation
model.add(LSTM(units = 50, return_sequences = True))
model.add(Dropout(0.2))# Adding a fourth LSTM layer and some Dropout regularisation
model.add(LSTM(units = 50))
model.add(Dropout(0.2))# Adding the output layer
model.add(Dense(units = 1))

# Compiling the RNN
model.compile(optimizer = 'adam', loss = 'mean_squared_error')

# Fitting the RNN to the Training set
model.fit(X_train, y_train, epochs = 100, batch_size = 32)

装配完成后,您应该会看到类似这样的内容:

准备测试数据(重塑它们):

# Getting the predicted stock price of 2017
dataset_train = df.iloc[:800, 1:2]
dataset_test = df.iloc[800:, 1:2]dataset_total = pd.concat((dataset_train, dataset_test), axis = 0)inputs = dataset_total[len(dataset_total) - len(dataset_test) - 60:].valuesinputs = inputs.reshape(-1,1)
inputs = sc.transform(inputs)
X_test = []
for i in range(60, 519):
    X_test.append(inputs[i-60:i, 0])
X_test = np.array(X_test)
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))print(X_test.shape)
# (459, 60, 1)

使用测试集进行预测

predicted_stock_price = model.predict(X_test)
predicted_stock_price = sc.inverse_transform(predicted_stock_price)

现在让我们来看看结果:

# Visualising the results
plt.plot(df.loc[800:, ‘Date’],dataset_test.values, color = ‘red’, label = ‘Real TESLA Stock Price’)
plt.plot(df.loc[800:, ‘Date’],predicted_stock_price, color = ‘blue’, label = ‘Predicted TESLA Stock Price’)
plt.xticks(np.arange(0,459,50))
plt.title('TESLA Stock Price Prediction')
plt.xlabel('Time')
plt.ylabel('TESLA Stock Price')
plt.legend()
plt.show()

5.结果

使用滞后 1(即一天的步长):

观察:2020 年 3 月因新冠肺炎封锁而大幅下跌!

我们可以清楚地看到,我们的模型表现得非常好。它能够准确地跟踪大多数不可接受的上涨/下跌,但是,对于最近的日期戳,我们可以看到,与股票价格的实际值相比,模型预期(预测)的值较低。

关于滞后的一个注记

本文中最初选择的延迟为 1,即使用 1 天的步长。这可以通过修改构建 3D 输入的代码来轻松改变。

示例:可以更改以下两个代码块:

X_train = []
y_train = []
for i in range(60, 800):
    X_train.append(training_set_scaled[i-60:i, 0])
    y_train.append(training_set_scaled[i, 0])

X_test = []
y_test = []
for i in range(60, 519):
    X_test.append(inputs[i-60:i, 0])
X_test = np.array(X_test)
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))

采用以下新代码:

X_train = []
y_train = []
for i in range(60, 800):
    X_train.append(training_set_scaled[i-50:i, 0])
    y_train.append(training_set_scaled[i, 0])

X_test = []
y_test = []
for i in range(60, 519):
    X_test.append(inputs[i-50:i, 0])
X_test = np.array(X_test)
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))

在这种情况下,结果如下所示:

那都是乡亲们!希望你喜欢这篇文章!

看看我在另一篇文章中用来预测谷歌股价的脸书预言家模型。

[## 时间序列预测:用脸书的先知模型预测股票价格

使用可从《先知脸书》公开获得的预测模型预测股票价格

towardsdatascience.com](/time-series-forecasting-predicting-stock-prices-using-facebooks-prophet-model-9ee1657132b5)

也可以看看我最近用 ARIMA 模型写的文章:

[## 时间序列预测:使用 ARIMA 模型预测股票价格

在这篇文章中,我将向你展示如何使用预测 ARIMA 模型来预测特斯拉的股票价格

towardsdatascience.com](/time-series-forecasting-predicting-stock-prices-using-an-arima-model-2e3b3080bd70)

参考

[1]https://colah.github.io/posts/2015-08-Understanding-LSTMs/

[2]https://en.wikipedia.org/wiki/Long_short-term_memory

敬请关注并支持这一努力

如果你喜欢这篇文章并且觉得它有用,关注我就可以看到我所有的新帖子。

有问题吗?把它们作为评论贴出来,我会尽快回复。

最新帖子

[## 时间序列预测:用脸书的先知模型预测股票价格

使用可从《先知脸书》公开获得的预测模型预测股票价格

towardsdatascience.com](/time-series-forecasting-predicting-stock-prices-using-facebooks-prophet-model-9ee1657132b5) [## 最佳免费数据科学资源:免费书籍和在线课程

最有用的免费书籍和在线课程,适合想了解更多数据科学知识的人。

medium.com](https://medium.com/@seralouk/the-best-free-data-science-resources-free-books-online-courses-9c4a2df194e5) [## 用新冠肺炎假设的例子解释 ROC 曲线:二分类和多分类…

在这篇文章中,我清楚地解释了什么是 ROC 曲线以及如何阅读它。我用一个新冠肺炎的例子来说明我的观点,我…

towardsdatascience.com](/roc-curve-explained-using-a-covid-19-hypothetical-example-binary-multi-class-classification-bab188ea869c) [## 支持向量机(SVM)解释清楚:分类问题的 python 教程…

在这篇文章中,我解释了支持向量机的核心,为什么以及如何使用它们。此外,我还展示了如何绘制支持…

towardsdatascience.com](/support-vector-machines-svm-clearly-explained-a-python-tutorial-for-classification-problems-29c539f3ad8) [## PCA 清楚地解释了——如何、何时、为什么使用它以及特性的重要性:Python 指南

在这篇文章中,我解释了什么是 PCA,何时以及为什么使用它,以及如何使用 scikit-learn 在 Python 中实现它。还有…

towardsdatascience.com](/pca-clearly-explained-how-when-why-to-use-it-and-feature-importance-a-guide-in-python-7c274582c37e) [## 关于 Python 中的最小-最大规范化,您需要知道的一切

在这篇文章中,我将解释什么是最小-最大缩放,什么时候使用它,以及如何使用 scikit 在 Python 中实现它

towardsdatascience.com](/everything-you-need-to-know-about-min-max-normalization-in-python-b79592732b79) [## Scikit-Learn 的标准定标器如何工作

在这篇文章中,我将解释为什么以及如何使用 scikit-learn 应用标准化

towardsdatascience.com](/how-and-why-to-standardize-your-data-996926c2c832)

和我联系

LSTM vs 伯特——推特情感分析的分步指南

原文:https://towardsdatascience.com/lstm-vs-bert-a-step-by-step-guide-for-tweet-sentiment-analysis-ced697948c47?source=collection_archive---------5-----------------------

最先进的 NLP 模型能比 RNN 更好地预测股票交易者情绪吗?

作者图片

注来自《走向数据科学》的编辑: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

金融文本的情绪分析中看到 BERT 的竞争结果后,我对更非正式的文本进行了另一项初步研究,因为最终目标是除了新闻情绪之外,还分析交易员在电话和聊天中的声音。在这篇文章中,我让 LSTM 和伯特分析了 Stocktwit 的一些推文。

背景

与正式的金融文本不同,交易者的声音和聊天包含了迄今为止的非正式语言。在我过去的研究中,传统的基于规则的模型或简单的矢量化技术(如 BoW、Tfidf、word2vec)表现不佳,因为

  • 一个词在不同的上下文中通常有不同的意思
  • 拼写和句子远不是语法正确的语言
  • 通过词干化、词汇化、停用词移除等来平衡单词分组。保持原来的形式是很困难的
  • 对于基于规则的方法,字典必须专门建立在这种语言上,在这方面我没有足够的概括

LSTM 是自然语言处理中最著名的 RNN 模型之一,表现很好。这在很大程度上归功于这样一个事实

  • 句子结构相当简单——简单地从左到右处理就足够了
  • 每一个输入文本都很短,有利于记忆
  • 这项任务相当简单的分类

另一方面,我在这里使用的 BERT 是在维基百科上训练的,那里的语言非常不同。由于资源的限制,从零开始训练 BERT 并不是一个好的选择。在这种情况下,让伯特获得比 LSTM 更好的表现还值得吗?

作为输入文本的推文

这里输入的文字取自 Stocktwits,作为这里交易者声音的类似语言。大约有一百万条推文被手工标记为 0(负面)到 4(正面),分别被加载为messagessentiments列表。请注意,实际环境通常需要做更多的工作来准备输入,如声音识别、数据清理、流式传输。这篇文章跳过这些步骤,从数据加载的地方开始。

> ##### Sample input messages ######> print(messages)
["$AMZN sick! they’re running a prime flash sale on shares too!", "$AAPL has a good Piotroski-F score of 7.00\. This indicates a good health and profitability. https://www.chartmill.com/analyze.php?utm_source=stocktwits&amp;utm_medium=FA&amp;utm_content=PROFITABILITY&amp;utm_campaign=social_tracking#/AAPL?r=fa&amp;key=bb853040-a4ac-41c6-b549-d218d2f21b32", "$FB got rid of this trash today, i admit that bears were right", ...]> print(sentiments)
[4, 2, 0, ...]

1.预处理

在训练之前,输入文本需要进行预处理,如删除 URL、标记符号、@提及、符号等。在这里,我简单地删除了它们,因为它们在语音中不可用,但也有一些有趣的研究,关于如何利用表情符号和标签等信息,而不是删除它们,如果最终目标是分析推文文本的话。

预处理输入消息

现在输入已经被清理如下。

> ###### Input messages after preprocessing ######> print(preprocessed)
["sick they re running a prime flash sale on shares too", "has a good piotroski f score of this indicates a good health and profitability", "got rid of this trash today i admit that bears were right", ...]

2.标记化

下一步是标记文本。在这里,我使用 python NLTK 库,但也给出了使用不同方法的选项,以查看什么最适合输入。经过几次实验后,我决定使用 nltk.word_tokenize(),而不进行词汇化和停用词移除。

3.语料库和词汇库

一旦输入文本被标记化,我们就可以用下面的方式创建一个语料库和词汇库。词云或条形图是快速查看输入中的常用词的好方法。分布显示该标签不平衡,比其他情绪更中性。通过重采样(欠采样或过采样)来平衡数据是可能的,但这里按原样进行,因为这个比率将代表推文流中情感的实际发生。

文字云图像(由作者创建)

语料库中最常用的单词(由作者创建)

标签、字母和单词的分发(由作者创建)

分类模型

既然输入数据已经准备好了,就创建基于神经网络的模型,并为该模型标记化。

4.LSTM

使用 pytorch 创建一个基于 LSTM 的模型。该类扩展了 torch.nn.Module 并将层定义为嵌入→ lstm →丢弃→密集(全连接)→输出(softmax)。LSTM 的记号赋予器是将输入填充到右边或左边,直到指定的最大长度,如果输入超过最大长度,则截断,设计用于在每批的训练期间使用,而不是预处理所有输入。

5.伯特

这里我使用 BERT 的拥抱脸实现。只需使用他们的变压器和预先训练的模型和记号化器。

培训过程

6.资料组

为批处理创建数据集类和数据加载器。有许多不同的方法来定义它们,这只是一个非常简单的解决方案,与返回 torch.tensor 的已定义记号化器一起使用。

7.取样周期

根据不同输入大小的准确度、f1 和训练时间来测量性能。使用 scikit-learn 的分层混洗 Split,它可以根据给定的训练和测试大小,通过保留标签分布来执行欠采样。在每个循环中,通过 perf_counter()测量完成训练的持续时间。

此外,定义一个简单的函数来返回准确性和 F1 分数。

注意,模型参数是在实例化模型类时定义的,可以根据输入数据进行更新。

8.训练神经网络模型

如下定义培训流程:

  1. 循环训练批次
  2. 在整个数据的 1/5 处运行评估
  3. 一个时期完成后,显示结果
  4. 如果分数没有提高到超出忍耐限度,则结束,或者开始下一个纪元

AdamW 优化器和线性时间表与学习率预热一起使用,但这些可以根据需要与其他选项交换。

在每个训练批次循环中,将输入消息标记化并移动到 torch.tensor,执行前馈预测,计算损失并反向传播以更新权重。裁剪以避免在下一个批处理步骤之前爆发梯度问题。

在每个时期结束时,显示训练和验证数据的混淆矩阵和分数/损失。

火车!

最后:)

9.运行 LSTM 模型

在最小样本(n=1,000)的第一个时期之后,模型简单地将所有数据分类为“中性”,这是合理的,因为“中性”是多数类。

混淆矩阵(n=1,000,epoch=1)(由作者创建)

完成五个时代后,它看起来几乎是随机地对数据进行了分类。它从第三个时期(=验证周期= 10)开始过度拟合训练数据。

评估结果(n=1,000,epoch=5)(由作者创建)

最大的数据集(n=500,000)包含比第一个周期多 500 倍的数据。它表现得更好,现在可以正确分类大多数标签。从第四个周期开始超配,所以三个纪元会是最好的。

评估结果(n=500,000,epoch=5)(由作者创建)

10.运行伯特模型

三个时期的训练预训练的 BERT 花费的时间几乎与上述 LSTM 模型的五个时期相同。

BERT 显示了类似的结果,但是它在最大数据集(n = 500,000)的第三个时期开始过拟合。

评估结果(n=500,000,epoch=5)(由作者创建)

11.比较结果

如下所示,随着输入数据数量的增加,它的性能自然会更好,在大约 100k 的数据时达到 75%以上的分数。伯特的表现略好于 LSTM,但当模型接受相同时间的训练时,没有显著差异。

LSTM 与伯特的演奏比较(作者创作)

结论

在这篇文章中,来自 stockswits 的推文被清理、标记和分析,以通过 LSTM 模型和预训练的伯特模型预测情绪。

给定相同的资源和时间,预训练的 BERT 比 LSTM 稍好,但没有显著差异。

潜在地,对类似的推文从头训练 BERT 模型可以产生更好的结果,而所需的资源和成本超出了本研究的范围。

(可选)推文流上的推理

下面是一段代码,它使用上面训练好的模型,将 tweet 流作为输入进行处理,并输出带有置信度的情绪。

示例输出如下所示。

PyTorch 的 LSTMs

原文:https://towardsdatascience.com/lstms-in-pytorch-528b0440244?source=collection_archive---------4-----------------------

简单的解释

了解 LSTM 架构和数据流

大象永远不会忘记。LSTMs 呢?

让我猜猜… 你已经和 MLPs 和 CNN 完成了几个小项目,对吗?MLPs 让你开始理解梯度下降和激活函数。CNN 让你看到了计算机视觉的世界。它们的所有层次都有点难,但你最终会找到窍门的。

现在,你碰壁了。你在用头撞它。那座血淋淋、泪痕斑斑的建筑叫做伊斯特姆斯。

我感受到了你的痛苦,朋友。我是来帮忙的。

让我们从概念上熟悉 LSTMs,然后深入研究您的问题的具体难点:即定义网络架构,以及在数据流经网络的每一层时控制数据的形状。

RNNs 背后的理念

递归神经网络通常保持关于先前通过网络传递的数据的状态信息。普通 rnn 和 LSTMs 都是如此。这种所谓的“隐藏状态”随着数据点序列的每个新元素被传回网络。因此,网络的每个输出不仅是输入变量的函数,也是隐藏状态的函数,隐藏状态是网络过去所见的“记忆”。

普通 rnn 失败的地方

这有助于理解 LSTMs 填补传统 rnn 能力的空白。香草 RNN 遭受快速渐变消失渐变爆炸。粗略地说,当链式法则应用于支配网络内“记忆”的方程时,会产生一个指数项。如果满足某些条件,该指数项可能会变得很大或很快消失。

LSTMs 不会(严重地)遭受消失梯度的问题,因此能够保持更长的“记忆”,使它们成为学习时态数据的理想选择。

PyTorch 中 LSTMs 的难点

现在,你可能已经知道了 LSTMs 背后的故事。你在这里是因为你很难将你的概念性知识转化为工作代码。

快速搜索 PyTorch 用户论坛会产生几十个问题,关于如何定义 LSTM 的架构,如何在数据从一层移动到另一层时塑造数据,以及当数据从另一端出来时如何处理。这些问题中有许多没有答案,而更多的问题的答案对于提问的初学者来说是难以理解的。

可以说,理解通过 LSTM 的数据流是我在实践中遇到的头号难题。似乎我并不孤单。

理解数据流:LSTM 层

在学习其他类型的网络之后,学习 LSTMs 时最难理解的一个概念可能是数据如何在模型的各层中流动。

这不是魔法,但看起来可能是。图片可能有所帮助:

作者配图。

  1. 一个 LSTM 层由一组 M 隐藏节点组成。该值 M 由用户在模型对象实例化时分配。很像传统的神经网络,虽然有指导方针,但这是一个有点武断的选择。
  2. 当长度为的单个序列 S 被传递到网络中时,序列 𝑆 的每个单独元素 s_i 通过每个隐藏节点。
  3. 每个隐藏节点为它看到的每个输入提供一个输出。这导致了形状 ( NM ) 的隐藏层的整体输出
  4. 如果将小批量的 𝐵 序列输入到网络中,则会增加一个额外的维度,从而产生形状为 (𝐵、 NM ) 的输出

了解数据流:全连接层

在 LSTM 层(或一组 LSTM 层)之后,我们通常会通过nn.Linear()类向网络添加一个完全连接的层,用于最终输出。

  1. 最后一个nn.Linear()层的输入大小将总是等于它之前的 LSTM 层中隐藏节点的数量。
  2. 这个最终完全连接层的输出将取决于目标的形式和/或您使用的损失函数。

了解数据流:示例

我们将讨论两个定义网络架构和通过网络传递输入的示例:

  1. 回归
  2. 分类

示例 1a:回归网络架构

考虑一些时间序列数据,也许是股票价格。给定特定产品过去 7 天的股票价格,我们希望预测第 8 天的价格。在这种情况下,我们希望我们的输出是单个值。我们将使用 MSE 来评估这个单值的准确性,因此对于预测和性能评估,我们需要来自七天输入的单值输出。因此,我们将我们的网络架构定义为:

示例 1b:对层间数据进行整形

我告诉你一个小秘密,我的一个朋友曾经告诉过我:

这些天来,我对它有了一种理解【LSTM 数据流】如果我在做的时候看向别处,它就会起作用。

—亚历克

虽然他说的在某种意义上是对的,但我认为我们可以确定这台机器如何工作的一些细节。

  1. LSTM 层的输入必须是(batch_size, sequence_length, number_features)的形状,其中batch_size是指每批序列的数量,number_features是时间序列中变量的数量。
  2. 你的 LSTM 层的输出将会是(batch_size, sequence_length, hidden_size)的形状。再看一下我在上面创建的流程图。
  3. 我们的全连接nn.Linear()层的输入需要对应于前一 LSTM 层中隐藏节点数量的输入大小。因此,我们必须将我们的数据重塑为(batches, n_hidden)形式。

重要提示: batchesbatch_size不同,因为它们不是同一个数字。然而,想法是相同的,因为我们将 LSTM 层的输出分成batches个片段,其中每个片段的大小为n_hidden,即隐藏的 LSTM 节点的数量。

下面是一些模拟通过整个网络传递输入数据x的代码,遵循上面的协议:

回想一下out_size = 1,因为我们只希望知道一个值,这个值将使用 MSE 作为度量进行评估。

示例 2a:分类网络架构

在这个例子中,我们想要生成一些文本。一个模型在一大堆文本上被训练,也许是一本书,然后输入一系列字符。该模型将查看每个字符,并预测下一个字符应该出现。这一次我们的问题是分类而不是回归,我们必须相应地改变我们的架构。我制作了这张图表来勾画总体思路:

作者配图。

也许我们的模型训练的是由 50 个独特字符组成的数百万字的文本。这意味着当我们的网络得到一个字符时,我们希望知道接下来是 50 个字符中的哪一个。因此,对于单个字符,我们的网络输出将是 50 个概率,对应于 50 个可能的下一个字符中的每一个。

此外,我们将对文本字符串中的每个字符进行一次性编码,这意味着变量(input_size = 50)的数量不再像以前那样是一个,而是一次性编码的字符向量的大小。

示例 2b:对层间数据进行整形

至于在各层之间形成数据,没有太大的区别。逻辑是相同的:

示例 2c:培训挑战

然而,这种情况提出了一个独特的挑战。因为我们正在处理分类预测,所以我们可能想要使用交叉熵损失来训练我们的模型。在这种情况下, 知道你的损失函数的要求是非常重要的。例如,看看 PyTorch 的nn.CrossEntropyLoss()输入要求(强调我的,因为老实说有些文档需要帮助):

输入 应该包含每个类的原始的、未标准化的分数。 输入 必须是一个大小为(minibatch,C)… 的张量

这个准则 【交叉熵损失】 期望一个类索引在[0,C-1]范围内作为 的目标 为一个 的 1D 张量 的大小 minibatch 的每一个值。

好吧,无意冒犯 PyTorch,但那是狗屎。我不确定这是不是英语。我来翻译一下:

  1. 预测(上面称为输入,尽管有两个输入)应该是(迷你批处理,C) 的形式,其中 C 是可能的类的数量。在我们的例子**C = 50**中。
  2. 作为第二个输入的目标的大小应该是 (minibatch,1) 。换句话说,目标不应该被一键编码。但是,它应该是标签编码的。

这对你来说意味着你必须以两种不同的方式来塑造你的训练数据。输入x将被一键编码,但是你的目标y必须被标签编码。此外,x的独热列应按照y的标签编码进行索引。

离别的思绪

LSTMs 的实现可能很复杂。通过了解您试图解决的问题的个人需求,然后相应地调整您的数据,可以消除这种复杂性。

上面所有的代码都是未经测试的伪代码。如果你想看看上面两个例子的完整的 Jupyter 笔记本,请访问我的 GitHub:

  1. 回归示例
  2. 分类示例

我希望这篇文章有助于您理解通过 LSTM 的数据流!

其他资源:

  1. 拉兹万·帕斯卡努等论训练递归神经网络的难度,2013https://arxiv.org/pdf/1211.5063.pdf
  2. PyTorch 用户论坛:https://discuss.pytorch.org

照片致谢:

  1. 大象照片由陈虎Unsplash 上拍摄
  2. 所有图表均由作者提供

基于歌词的歌曲推荐,带有 Doc2Vec 嵌入和 Spotify 的 API

原文:https://towardsdatascience.com/lyric-based-song-recommendation-with-doc2vec-embeddings-and-spotifys-api-5a61c39f1ce2?source=collection_archive---------29-----------------------

使用深度学习和自然语言处理理解歌词。

近 3000 首歌曲嵌入的二维表示,由艺术家着色。

单词嵌入和歌曲嵌入

单词嵌入对于自然语言处理来说是一个非常有用的工具。它们通常作为神经网络的参数被学习,并允许我们将单词映射到数字。更具体地说,它们允许我们将单词映射到高维向量。既然词向量用数字来表示信息,我们就可以利用它们之间的关系来理解它们所表示的词之间的关系。

如果我们可以嵌入单个单词,那么我们就可以嵌入句子、段落,甚至整个文档。事实证明,如果你能找到一种方法使它适合一个模型的架构,你可以为任何东西创建嵌入。

通过基于歌词训练歌曲嵌入,我们可以测量空间中点之间的关系,以理解歌曲之间的关系。

用例:歌曲推荐

如果我们已经训练了歌曲嵌入,那么我们将有一个对应于每首歌曲的 N 维向量。我们可以计算出从一首歌到其他每首歌的距离。那么,“最接近”的歌曲就是会被推荐的歌曲。

我们需要做的只是获取一些歌词,训练嵌入,然后构建一个可以测量距离并提供推荐的应用程序。

数据

我用的是 musiXmatch 数据集,这是百万首歌曲数据集的官方歌词集。我选择这个数据集是因为它包含 237,662 首歌曲,是可供研究的最大的干净歌词集。

由于版权问题阻止了完整的原创歌词的分发,数据以单词包的形式出现。这意味着我们不能按照单词出现的顺序来获取它们。取而代之的是,我们得到一个单词列表以及它们在每首歌中出现的次数。

单词袋格式可能会导致一些信息丢失,但这是一个很好的起点。Kaggle 上也有一些数据集包含了完整的歌词,也可以使用。

建模

我们建模的目标是学习数据集中歌曲的高维嵌入。这可以通过分布式单词包段落向量(PV-DBOW) 模型来完成,该模型以如下方式工作。

在我们的例子中,实际上是一首歌。在训练的每次迭代中,对文本窗口进行采样以创建段落矩阵。然后,从该文本窗口中随机抽取一个单词。我们尝试使用段落矩阵作为输入来预测单词,并对模型权重进行更新。这些权重包括构成段落向量的权重。

如果我们有原始歌词,我们可以使用分布式内存段落向量(PV-DM)。这个模型可能会通过考虑单词出现的顺序来改善我们的结果。关于段落向量的更多信息可以在本文中找到。

Gensim 是我们将使用的工具。它是一个 python 库,使得实现上述 PV-DBOW 模型变得很容易。该笔记本包含用于训练和可视化 musiXmatch 数据集歌词嵌入的代码。

t-SNE 和可视化

t-分布式随机邻居嵌入(t-SNE) 是一种降维技术,对于可视化高维数据特别有用。它基于高维空间中的点的邻域来估计概率分布,并试图在低维空间中重建该分布。

t-SNE 的一个好处是它倾向于保持当地的关系。因此,我们可以在低维中绘制点,以了解高维空间中的关系。

当应用于 musiXmatch 数据集时,它看起来像这样。每个点代表一首歌,由艺术家上色。轴上的值本身没有意义,但它们有助于创建歌曲之间距离的概念。

艺术家之间的关系可以保证模型按预期工作。总的来说,我们应该期待看到相似艺术家的歌曲比不同流派艺术家的歌曲更接近。

三位艺术家的歌词嵌入

十位艺术家的歌词嵌入

构建应用程序

Flask 是一个用于构建 web 应用的 python 库。使用 Flask,我构建了一个应用程序,允许用户在 musiXmatch 数据集中搜索音乐,并与 Spotify 的 API 进行交互。幸运的是,我找到了一个很好的资源,而且不用重新发明轮子: Spotify-Flask 作者 mari-linhares

登录 Spotify 的认证流程并授予权限后,用户可以导航到一个页面,提示他们输入歌曲标题、艺术家和要返回的歌曲数量。如果可能的话,用户的顶级艺术家会被推荐给他们以获得灵感。

一旦选择了初始歌曲,通过测量嵌入之间的余弦相似度来找到相似的歌曲。相似的歌曲与 Spotify 的目录交叉引用,可用的歌曲将返回给用户。

如果用户喜欢返回的歌曲,他们可以将它们保存到 Spotify 播放列表中。如果没有,他们可以再试一次。

未来的工作

歌曲推荐只是歌词嵌入的众多应用之一。歌词向量可以用来揭示艺术家和他们的音乐之间的新关系。

另一方面,基于歌词的歌曲嵌入可能只是更大的推荐引擎的一小部分。当前的应用程序在搜索类似的歌曲时只使用歌词,但是当除了歌曲的内容之外还考虑歌曲的发音时,肯定会获得更好的推荐。

我将很高兴收到以上任何反馈。欢迎发表评论,或通过 areevesman@gmail.com 的Linkedin/电子邮件联系。

资源

该项目的相关资源包括如下。

链接到应用程序

代码

数据

Gensim 和段落向量

关于 t-SNE 的更多信息

网络应用

M5 预测-准确性

原文:https://towardsdatascience.com/m5-forecasting-accuracy-24d7f42130de?source=collection_archive---------15-----------------------

使用 Xgboost、Catboost、Lightgbm 进行预测比较

照片由杰米街Unsplash

介绍

在本博客中,使用 R 对 M5 竞争数据进行探索性数据分析,使用 Xgboost、Catboost、Lightgbm、脸书预言家预测 28 天的销量。通过比较 SMAPE 误差率一个标准误差规则来选择最佳模型。

竞争背景:

Makridakis 竞赛(也称为 M 竞赛)是由预测研究员 Spyros Makridakis 领导的团队组织的一系列公开竞赛,旨在评估和比较不同预测方法的准确性。名为 M-Competition 的第一次比赛是在 1982 年举行的,当时只有 1001 个数据点,模型的复杂性和数据规模随着每次连续迭代而增加。

比赛链接:https://www.kaggle.com/c/m5-forecasting-accuracy

目标:

今年 3 月(2020 年),第五届迭代命名为 M5 竞赛举行。本次 m5 竞赛旨在预测未来 28 天(即截至 2016 年 5 月 22 日)的日销售额,并对这些预测进行不确定性估计。在这篇博客中,我只是要做预测,不确定性将在我的下一篇博客中用最佳选择的模型进行。

数据集:

所提供的数据集包含来自沃尔玛的 42,840 个分层销售数据。该数据集涵盖了美国三个州(加利福尼亚州、德克萨斯州和威斯康星州)的商店,包括从 2011 年 1 月 29 日到 2016 年 4 月 24 日这五年的商品级别、部门、产品类别和商店详细信息。此外,它还有解释变量,如价格、快照事件、星期几以及特殊事件和节日。

图 1:M5 系列数据组织方式概述

该数据包括在 3 个州的 10 家商店销售的 3 大类 7 个部门的 3049 件产品。分层聚合捕获了这些因素的组合,这使得执行自下而上的方法或自上而下的方法变得可行。例如,我们可以为所有销售创建一个时间序列,或者分别为每个州执行,等等。

假设

根据给出的数据,可能影响销售的一些因素如下:

  1. 日- 顾客购物的时间和支出大多取决于周末。许多顾客可能只喜欢在周末购物。
  2. 特殊活动/节假日:根据活动和节假日的不同,客户的购买行为可能会发生变化。对于像复活节这样的节日,食品销售可能会上升,对于像超级碗决赛这样的体育赛事,家庭用品销售可能会上升。
  3. 产品价格:销售受产品价格影响最大。大多数顾客在最终购买之前都会检查价格标签。
  4. 产品类别:产品的类型很大程度上影响销售。例如,与食品销售相比,电视等家用产品的销售将会减少。
  5. 地点:地点在销售中也起着重要的作用。在像加利福尼亚这样的州,顾客可能会购买他们想要的产品而不考虑价格,而另一个地区的顾客可能对价格敏感。

在深入研究数据之前,先快速概述一下每个州的人口和收入中位数:

加利福尼亚

人口:3951 万

家庭年收入中位数:75277 美元

得克萨斯州

人口:2900 万

家庭年收入中位数:59570 美元

威斯康星州

人口 582.2 万

收入中位数:60733 美元

探索性数据分析是为了检验这些假设。

探索性数据分析

让我们开始数据分析,首先了解哪一个州的销售额最高,以及这三个州的各个部门的销售额。

探索商店的位置

本节旨在回答:

  1. 哪个州的销售额最高?
  2. 哪个部门的销售额最高?
  3. 表现最好的商店?

图二。每个州的总销售额

不出所料,食品部在这三个州都创下了最高的销售额。此外,从图 2 中可以看出,加州的总销售额最高。拥有 4 家商店和更多的人口可能是原因。令人惊讶的是,与德克萨斯州相比,人口密度较低的威斯康星州也创下了相同的销售额。为了更好地理解,绘制了每个商店的销售额。

图三。店内总销售额

因为与其他商店相比,ca3 的销售额几乎是两倍。CA_3 可能是一个更大的商店。人口密度和收入中位数也影响这些销售。

现在,我们已经了解了不同地点对销售的影响,现在让我们深入了解各个部门

探索价格和产品类别

本节旨在回答:

  1. 每个部门有多少不同的产品?
  2. 不同州所有可用产品的平均价格是多少?
  3. 哪个部门销售额最高最少?

图 4 可用产品总数

Food_3 部门的可用产品数量更多。因此,食品 3 部门可能包括日常消费的食品,如牛奶等。现在,让我们看看价格是否对销售有任何影响

图五。所有产品的平均价格

可以看出,爱好 _1 部门均价最高,美食 3 最低。尽管与德克萨斯州和威斯康星州相比,加利福尼亚州人口的平均家庭年收入更高,但三个州的平均价格几乎相似,这使得加利福尼亚州人口更能负担得起这些产品。现在让我们来看看每个产品在各州的销售情况。

图六。所有产品的总销售额

这里,平均价格最低的食品 3 部门销售额最高。更有趣的是,尽管爱好 1 的平均价格最高,几乎是爱好 2 的两倍,但爱好 1 的销售额也很高。家庭 1 销售额很高。这可能表明该产品部门拥有肥皂和洗涤剂等日常必需品。

如前所述,加利福尼亚州的销售量较高,其次是德克萨斯州和威斯康星州。与德克萨斯州相比,威斯康辛州的食品 1 和食品 2 类的销售额更高。因此,可以假设威斯康辛州的人口喜欢食物 1 和食物 2 部门。

我们能够证明一些与产品价格、位置和产品类别相关的论文陈述。现在,让我们进入时间序列分析,看看不同的工作日、月份和事件是如何影响销售的。

时间序列分析

本节旨在回答:

  1. 总销售额的每日季节性趋势
  2. 哪个月的销售额最高和最低?
  3. 在不同的州,人们更喜欢哪个工作日去杂货店购物?

绘制所有年份的时间序列,以观察不同部门所有 3 个州的季节性趋势。

图 7。部门的每日销售趋势

季节性趋势遵循相同的模式,并且在所有 3 个州都是平行的。最高的食品是销售额最高的部门,其次是爱好和家庭。为了更好地理解每日趋势,绘制了 2015 年的热图。

图 8。2015 年日历热图

沃尔玛似乎在圣诞节不营业。可以看出,在新年和感恩节这样的日子里,销售额很少。这是由于节日期间工作时间减少。此外,与平时相比,周末的销售额相对较高。

月度销售趋势

图九。全州每月销售趋势

令人惊讶的是,这三个州 5 年来的趋势都是一样的。可以看出,总销售额每年都在增加。这种趋势是因为沃尔玛每年都会推出新产品。此外,每年增加或减少的趋势模式几乎相似。为了更好地理解月度趋势,我们将一年中的所有月度销售额进行了分组,并绘制了图表。

图 10。类别月度销售趋势

可以看出,销售额每年都在增长,并在三月份达到顶峰。三月之后,销售额开始下降,直到五月,六月销售额骤降至全年最低。6 月份之后,销售额在两个月内逐渐增加,直到 11 月份才进一步下降。

每周趋势

图 11。全州每周销售趋势

不出所料,与正常工作日相比,周六和周日的总销售额更高。即使在这里,威斯康辛州也是一个例外,周六是销售高峰,而加州和德克萨斯州是周日。所以,也许威斯康辛州的居民更喜欢在周六去杂货店购物。

为了更好地观察工作日和月份的趋势,绘制了工作日和月份的总状态热图。

图 12。工作日与月份销售热图

这张销售热图有一个有趣的模式。可以观察到,每个月记录的销售数量都在增加。也就是说,如果在二月份的星期一记录了最高的销售额,我们可以看到在三月份星期二有更多的销售额。

假日和特殊活动的销售趋势:

本节旨在回答:

  1. 节日活动和节假日如何影响销售趋势?
  2. 哪个节日的销售额最高?

图 13。特殊活动的总销售额

超级碗体育赛事的销售额最高。国庆节那天,销售额很低。宗教节日当天的销售情况也是如此。为了观察销售趋势,绘制了 2015 年的季节性趋势图。

图 14。特殊活动的总销售趋势

观察结果:

  1. 在像新年和复活节这样的节日,由于营业时间减少,销售额很低。
  2. 圣诞节销售额为零,可能是因为沃尔玛关门了。
  3. 像 NBA 决赛这样的体育赛事显示了一个有趣的洞察力,赛事前一天的销售额很高,而赛事当天的销售额下降。
  4. 在父亲节、母亲节等特殊日子,销售额会下降。
  5. 国定假日和宗教节日对体育赛事也有类似的影响。

建模:

该竞赛旨在预测 28 天的销售情况。

涉及的步骤:

  1. 引入滞后和滚动平均值
  2. 训练/测试分流
  3. 数字编码
  4. 将数据转换成所需格式( data.matrix,LGB)。数据集,Cat.loadpool )
  5. 参数选择
  6. 模型训练/交叉验证
  7. 预测
  8. 型号对比的 SMAPE 误差
  9. 单标准误差规则

引入滞后和滚动平均值

由于缺乏计算能力,10%的数据是使用分层抽样选择的。分层随机抽样准确地反映了被研究的人群,因为它在应用随机抽样方法之前对整个人群进行了分层。简而言之,它确保人口中的每个亚群体在样本中得到适当的代表。

由于机器学习模型,我们使用的是具有滞后天数的时间序列,滚动平均值有助于改进模型,因此引入了新的滞后变量,分别用于 1 周、2 周、1 个月、2 个月的时变效应变量。有了更好的计算能力,也可以引入 1 年的滞后,因为每年的销售模式是相似的。引入了 1 周和 1 个月滞后变量的滚动平均值和滚动标准偏差。

对于不了解滞后的人来说,一个滞后是一段固定的流逝时间;时间序列中的一组观察值被绘制(滞后)在第二组数据之后。第 k 个滞后是发生在时间之前“k”个时间点的时间段

训练/测试分流

因为我们需要用 5 年的数据来预测 28 天。所有日期小于或等于 2016 年 3 月 27 日的数据都被视为训练数据。并将日期大于 2016 年 3 月 27 日且小于 2016 年 4 月 24 日的 28 天数据作为测试数据。最后 28 天用于验证。

数字编码:

由于许多机器学习模型无法读取字符类型数据,因此所有列都应转换为数字格式。我在 R 中使用了一个简单的命令

data%>%mutate_if(is.factor, as.integer)

为什么要组装模型?

集成方法通过组合多个模型来帮助改善机器学习结果。与单一模型相比,使用集合方法可以让我们做出更好的预测。因此,集成方法在许多著名的机器学习竞赛中排名第一,因此使用 sMAPE 错误率来比较不同的集成。

为什么是 sMape?

使用 sMAPE 误差率是因为它是 M3 预报中规定的评估指标。sMape 误差率或对称平均绝对百分比误差被列为重要的但不常见的预测误差测量方法之一。然而,它在计算上的复杂性和解释上的困难使它远远落后于最常见的 MAD 和 MAPE 预测误差计算。

sMape 误差计算如下

对于任何想了解所用模型以及一个模型相对于其他模型的优势的人,这里有一个链接指向一篇比较 Xgboost vs catboost vs Lightgbm 的文章。

Xgboost:

Xgboost 需要 xgb 格式的数据。用于预测的 DMatrix 格式,因此训练集和测试集都转换为 xgb。使用下面的命令。

train_set_xgb = xgb.DMatrix(data = data.matrix(train_data[,features]), label = data.matrix(train_labels))
test_set_xgb = xgb.DMatrix(data = data.matrix(test_data[,features]), label = data.matrix(test_labels))

为 Xgboost 选择的参数如下

params <- list(booster = "gbtree",
               tree_method='gpu_hist', gpu_id=0,task_type = "GPU",
          objective = "reg:tweedie", eta=0.4, gamma=0 nrounds = 20,    
           nthreads = 10,early_stopping_round = 10)

由于我们的数据包含大量零值,使用目标 as 回归没有给出预期的结果。在浏览了一些研究的文章之后,我们发现 Tweedie 是含有大量零的非负数据的最佳模型。因此 Tweedie 目标用于训练模型。

由于最新的 Xgboost 版本支持使用 GPU,因此使用 GPU 对模型进行训练。选择 RMSE 评估度量来训练模型。给出了 10 次的早期停止循环,因此如果模型 RMSE 在 10 次迭代中没有改进,模型将停止。并且将返回最佳 RMSE 值。

最佳 RMSE 值为 2.48

进行 3 重交叉验证是为了检查模型的一致性。为交叉验证返回的最佳 RMSE 值是 2.637。

定义一个函数来计算 sMAPE 值,如下所示:

smape_cal <- function(outsample, forecasts){
  outsample <- as.numeric(outsample)
  forecasts<-as.numeric(forecasts)
  smape <- (abs(outsample-forecasts))/((abs(outsample)+abs(forecasts))/2)
  return(smape)
}

Xgboost 的 SMAPE 值为 1.897968

Catboost:

catboost 需要 load_pool 格式的数据来进行预测,因此使用以下命令将训练集和测试集都转换为 load_pool 格式。

train_cat <- catboost.load_pool(data = data.matrix(train_data_cat[,features]), label = data.matrix(train_labels))
test_cat <- catboost.load_pool(data = data.matrix(test_data_cat[,features]), label = data.matrix(test_labels))

为 Catboost 选择的参数如下

params_cat <- list(iterations = 1500,
                metric_period = 100,
               tree_method='gpu_hist',task_type = "GPU",
               loss_function = "RMSE",
               eval_metric = "RMSE",
               random_strength = 0.5,
               depth = 7,
               early_stopping_rounds = 100,
               learning_rate = 0.18,
               l2_leaf_reg = 0.1,
               random_seed = 93)

RMSE 被用作损失函数和训练模型的评估度量。使用 Kaggle GPU 进行 1500 次迭代的计算时间约为 5 分钟。第一轮是 100 轮。

最佳 RMSE 值为 2.36541

执行 3 重交叉验证以检查模型一致性。为交叉验证返回的最佳 RMSE 值是 2.39741。

Catboost 的 sMAPE 值为 1.34523,,似乎比 xgboost 更好。

Lightgbm

lighgbm 需要 lgb_dataset 格式的数据进行预测,因此训练集和测试集都转换为 lgb。使用以下命令格式化数据集。

train_set_lgb <- lgb.Dataset(data=as.matrix(train_data[,features]), label = as.matrix(train_labels))
test_set_lgb <- lgb.Dataset(data=as.matrix(test_data[,features]), label =as.matrix(test_labels))
valids=list(train=train_set_lgb,test = test_set_lgb)

使用的参数如下

parameters =list(objective = "tweedie",
           tweedie_variance_power=1.1,
           metric ="rmse",
          force_row_wise = TRUE,
                  num_leaves=90,
            learning_rate = 0.03,
            feature_fraction= 0.5,
            bagging_fraction= 0.5,
            max_bin=100,
            bagging_freq = 1,
            boost_from_average=FALSE,
          lambda_l1 = 0,
          lambda_l2 = 0,
          nthread = 4)freeram()

Tweedie 用作目标函数,RMSE 用作训练模型的评估度量。

最佳 RMSE 值为 2.1967701

执行 3 重交叉验证以检查模型的一致性。为交叉验证返回的最佳 RMSE 值是 2.21。

Lgboost 模型的 sMAPE 值为 1.14,是所有 3 个模型中最好的。

图 15。LGB 模型的特征重要性

基于 sMape 误差,Lgb 是最好的模型。只是为了确认,一个标准误差适用于所有 3 个模型的交叉验证 RMSE 值。

一个标准误差规则:

对于那些不知道一个标准误差规则的人,在交叉验证中使用一个标准误差规则,其中我们采用最简单的模型,其误差在最佳模型(误差最小的模型)的一个标准误差内。

图 16。一个标准误差图

结论:

即使在这里,LGB 也是 RMSE 值最低的表现最好的车型。因为其他模型平均误差点不在 Lihtgbm 模型的标准差范围内。根据一个标准误差规则,Lightgbm 被选为最佳模型。

表现最好的模型的提交分数在 0.46 左右。

附录

所有绘图都是使用 r .中的 ggplot2 包制作的,因为代码非常大。我把我的 Kaggle 笔记本分享给任何想在比赛中使用代码的人。

ka ggle:https://www . ka ggle . com/jaswanthhbadvellu/cat-xgb-lgboost-prophet

数据集:【https://www.kaggle.com/c/m5-forecasting-accuracy/data

分层采样后的样本数据集如下所示

深度学习的 MacBook Pro?让我们试试。

原文:https://towardsdatascience.com/macbook-pro-for-deep-learning-lets-try-841ab8ffee7e?source=collection_archive---------3-----------------------

它与英伟达 GPU 驱动的笔记本电脑相比如何?

我昨天买了一台 MacBook Pro。2019 款,13”带基础配置(后面会详细介绍)。作为一名数据科学家和深度学习爱好者,我一开始对整个苹果的想法有点怀疑,因为深度学习需要 GPU 在“合理”的时间内训练,而 GPU 不是 MAC 的主要卖点。

Ash EdmondsUnsplash 上拍摄的照片

尽管如此,我还是决定尝试一下,因为我早就想要一台 MacBook 了。虽然我仍然不习惯键盘(布局方面),但对我来说,整个操作系统比 Windows 好得多。

我已经多次尝试了各种版本的 Linux ,但是所有的版本都感觉像是还在 alpha 测试之前,尽管事实并非如此(过热问题、睡眠问题、wifi 问题……)。

这篇文章针对的是那些面临着和我昨天一样的 MacBook 困境的数据科学家——买还是不买。如果你没有时间通读整篇文章,简短的回答是是的——如果你有钱并且想要新的东西,就去买 Mac。

您将不得不继续关注原因和性能比较。

这篇文章的结构如下:

  1. 硬件比较
  2. 使用的数据集和库
  3. 深度学习—性能比较
  4. 结论

现在,这不会是一个深度学习教程,因为我只会分享两台笔记本电脑在训练中的表现。如果您想了解这个数据集的完整概要,请告诉我。

无论如何,这个介绍比我预期的要长,所以让我们结束它,开始你来这里的目的。

硬件比较

直到昨天,我还没有 MacBook Pro,所以我已经在我的联想军团 Y540 笔记本电脑上完成了所有数据科学和深度学习的东西,规格如下:

  • CPU:英特尔 I5 9300H
  • GPU:英伟达 GeForce GTX 1650 4GB
  • 内存:16GB DDR4
  • 固态硬盘:512GB

虽然笔记本电脑的功能不是非常强大,但我发现它足以处理知名数据集的临时深度学习任务,甚至可以处理一些大型彩色图像。

只是我快速说明一下——我是用 CUDA 在 GPU 上训练模型,所以要记住这一点。

然后是Mac(13“2019。型号)具有以下规格:

  • CPU:英特尔 I5 QC 1.4GHz
  • GPU:英特尔 Iris Plus 645 1536MB
  • 内存:8GB
  • 固态硬盘:128GB

因此,仅从规格来看,它对 Mac 来说并不太好——但让我们在接下来的部分看看它的表现如何。

使用的数据集和库

最近在我的大学,我们处理了时尚-MNIST 数据集。如果你做过深度学习,我相信你对它很熟悉,但以防万一,这里有一点背景知识——来源: Kaggle

时尚-MNIST 是 Zalando 文章图像的数据集,由 60,000 个样本的训练集和 10,000 个样本的测试集组成。每个示例都是 28x28 灰度图像,与 10 个类别的标签相关联。[1]

更准确地说,我们有 10 类图像:

  • 0: T 恤/上衣
  • 1:裤子
  • 2:套头衫
  • 3:着装
  • 4:外套
  • 5:凉鞋
  • 6:衬衫
  • 7:运动鞋
  • 8:袋子
  • 9:短靴

好了,现在你已经有了数据集的一些基本信息。我唯一要做的就是说明我在使用哪个深度学习库。如果你读过我的任何帖子,你可能知道我是一个 PyTorch 用户,这篇文章也不会例外。

很好,现在我们知道了一切-让我们比较一下基本型号的 MacBook Pro 与支持 GPU 的 Windows 笔记本电脑之间的差异。

深度学习—性能比较

现在我已经开始在两台笔记本电脑上运行模型,看看 MacBook 会落后多少。在向您展示结果之前,您可能还会对模型架构感兴趣,如下图所示:

所以这里没什么特别的,我用 ReLU 作为隐藏层的激活函数,用对数 softmax 作为输出层。此外,我已经在内核大小为 2x2、步幅为 od 2 的两个卷积层之后执行了 MaxPooling 。是的,差点忘了——这个模型被训练了 15 个时期。

这是您的平均设置,将产生大约 150,000 个可训练参数(权重和偏差),神经网络需要针对这些参数进行优化。

现在到了你期待已久的部分——实际性能对比!这是图表:

联想:9 分 36 秒,MacBook: 10 分 13 秒

如你所见,联想笔记本电脑表现更好,但也好不了多少。我预计会有更严重的差异,主要是因为联想笔记本电脑有“像样的”GPU,而 MacBook 没有。

因为通风系统在联想笔记本电脑上无可挑剔,而在 Mac 上几乎不存在,Mac 确实变热了,所以这是你应该考虑的另一个方面。

由于这篇文章的唯一目标是研究 MacBooks 实际上能否处理深度学习,以及它们在这方面的表现如何,这里我将停止。

结论

我花了很长时间才决定买苹果电脑。我一直喜欢它的想法,总体来说操作系统似乎更好,但我只是担心它在数据科学和深度学习任务方面的表现会很糟糕。

我很高兴我已经做出了改变——只是希望我能早点做出改变。

感谢阅读,我希望你喜欢它。

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

[## 通过我的推荐链接加入 Medium-Dario rade ci

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

medium.com](https://medium.com/@radecicdario/membership)

参考

[1]https://www.kaggle.com/zalando-research/fashionmnist

用 BERT 进行机器理解

原文:https://towardsdatascience.com/machine-comprehension-with-bert-6eadf16c87c1?source=collection_archive---------18-----------------------

使用深度学习进行问题回答

迈克尔·泽兹奇在 Unsplash 上的照片

在 Github 的资源库中可以找到 这里有 。本文将介绍如何设置它。预计时间:30 分钟以内。

机器(阅读)理解是 NLP 的领域,在这里我们教机器理解和回答使用非结构化文本的问题。

[## 深度学习

成为深度学习专家。掌握深度学习的基础,打入 AI。填满的星星填满的星星…

www.coursera.org](https://www.coursera.org/specializations/deep-learning?ranMID=40328&ranEAID=J2RDoRlzkk&ranSiteID=J2RDo.Rlzkk-XtffRH2JEnDifWa3VrZJ1A&siteID=J2RDo.Rlzkk-XtffRH2JEnDifWa3VrZJ1A&utm_content=2&utm_medium=partners&utm_source=linkshare&utm_campaign=J2RDoRlzkk)

2016 年,StanfordNLP 整合了 SQuAD(斯坦福问答数据集)数据集,该数据集由超过 10 万个根据维基百科文章制定的问题答案对组成。面临的挑战是训练一个机器学习模型来回答基于上下文文档的问题。当提供一个上下文文档(自由形式的文本)和一个问题时,模型将返回最有可能回答问题的文本子集。

来自小队数据集的示例条目

世界各地的顶级人工智能实践者解决了这个问题,但两年后,没有模型击败人类基准。然而,在 2018 年底,谷歌大脑的聪明人推出了 BERT(来自变压器的双向编码器表示),这是一种通用语言理解模型。通过一些微调,该模型能够在与小队测试集进行比较时超过人类基准。

来自 paper SQuAD: 100,000 多个用于机器理解文本的问题,这些是用于评估的指标:

完全匹配。此指标衡量与任何一个基本事实答案完全匹配的预测的百分比。

(宏观平均)F1 得分。此指标衡量预测和真实答案之间的平均重叠。我们将预测和基础事实视为一袋袋的令牌,并计算它们的 F1。我们对给定问题的所有基本事实答案取最大值 F1,然后对所有问题取平均值。

基于初始小队数据集:

  • 人类注释者获得了 82.304% 的精确匹配分数和 91.221% 的 F1 分数
  • 最初的 BERT 模型(在排行榜上排名第 11,主要被 BERT 的其他变体击败)获得了精确匹配分数 85.083% 和 F1 分数 91.835%

今天,我将向你展示如何使用 BERT 建立你自己的阅读理解系统。在 Github 仓库中可以找到 这里

要开始,你需要 Docker。🐳

设置 Docker

Docker 对于容器化应用程序很有用。我们将使用 Docker 使这项工作更有用,结果更具可重复性。按照这些说明在你的系统上安装 Docker。你还需要在 macos 和 windows 上自带 Docker 的docker-compose。如果你用的是 Linux,你可以在这里安装

从我的 Github Repo 本地保存代码

除了阵容数据和预先训练的重量,所有的代码和必要的依赖都在报告中。注:只有自己想训练模型才需要数据。如果没有,你可以使用我预先训练的重量。另一个注意:我不建议训练模型,除非你有强大的 GPU 或者大量的时间。

如果你想自己训练模特…

点击下载小队 2.0 数据集。将“训练集 2.0 版”和“开发集 2.0 版”保存到bert_QA/data

如果您想使用预先训练的重量…

我已经用 SQuAD 2.0 数据集训练了这个模型。你可以在这里下载。解压文件并将内容保存为bert_QA/weights

创建 Docker 容器

Docker 容器是使用 docker 映像中提供的指令构建的工作环境。我们需要一个docker-compose.yaml配置文件来定义我们的容器的外观。

我为 Pytorch 变形金刚做了一个定制的 docker 图片,你可以在 dockerhub 上找到。出于本教程的目的,您不需要提取任何图像,因为配置文件已经这样做了。配置文件还将把我们的本地bert_QA文件夹作为/workspace挂载到容器中。

  • 通过从终端/shell 运行根目录中的docker-compose up -d 来启动我们的容器。第一次需要几分钟。
  • 使用docker ps检查我们的容器是否启动并运行。

  • 将 bash shell 附加到正在运行的容器:

docker exec -it <your_container_name> bash

训练模型

如果你使用我预先训练的重量,跳过这一步。我们将使用由 huggingface 提供的默认训练脚本来训练模型。

在 bash shell 中运行:

注意:如果没有 GPU,per_gpu_train_batch_size 不会做任何事情

这将训练并保存模型权重到weights目录。

使用模型进行推理

现在让我们用这个模型来做一些很酷的东西。

在 shell 中启动一个 ipython 会话,并导入ModelInference模块以从weights/加载权重。将上下文文档作为参数传递给mi.add_target_text()。摄取完语料库后,使用mi.evaluate()提问。只有当模型确信答案存在于文本中时,模块才会返回答案。否则,模型将输出“未找到有效答案”。

结论

在过去的几年里,NLP 取得了长足的进步。预训练的 BERT 权重对 NLP 的影响类似于 AlexNet 对图像识别的影响。它实现了自然语言理解的许多新颖应用。

机器智能与企业

原文:https://towardsdatascience.com/machine-intelligence-and-the-enterprise-aee5f8710382?source=collection_archive---------35-----------------------

一个实用的外部视角——企业 ML/AI 成熟度

托米·利斯宾Unsplash 上拍摄的照片

我在金融服务业工作了将近 20 多年。在那段时间里,我在不同的职能部门工作过,但我的工作总是与将交易与业务成果联系起来有关。随着时间的推移,我的工作标签发生了变化,从分析分析数据科学机器学习人工智能,但目标和高级方法保持不变。

在同样的 20 年里,计算和存储出现了爆炸式增长,并对我的工作产生了深远的影响。例如,任何数据科学家都可以很容易地询问交易+结果数据来导出链接。此外,这与数据科学家的短缺合谋创造了一个雇佣军模型。在这种情况下,很少有数据科学家会尝试将他们的工作与完整的业务环境和相关工作联系起来。

由于更容易的 ML/AI,企业最终形成了一大堆模型,如营销中的 RFM 模型(新近性、频率、货币化)定价中的 LTV(生命时间价值)和需求模型保留模型运营中的等。现在缺少的是一个将模型纳入一个视图的系统,以供那些可以使用它来驱动企业战略或政策的人使用。

传统上,我们认为人工智能成熟度包括以下能力:(1) 计划工作 ( 基础水平);(2) E 执行工作 ( 称职等级);音阶作品 ( 顶级)。这种观点真的是“由内而外”的,而且有点短视,因为做大量的 ML/AI 显然不等同于超大的业务成果。然而,可悲的是,这是支持成熟度评估的潜在但普遍的观点。

在我们的专业领域内,当企业不愿意进行 ML/AI 投资和押注时,我们看到了这一点。有鉴于此,我认为我们需要考虑一个新的最高水平的成熟度(我会把这个水平称为“务实”,但我这一行的许多人可能会认为这是愤世嫉俗的——是的,他们这样做是正确的)。这个层次的企业能够综合定制的 AI/ML 模型,并将其翻译成商业语言:利润增长客户满意度。

只有当它驱动系统将模型带入单一视图时,ML/AI 的力量才能得到充分释放。这种观点可以帮助战略家或政策制定者理解对过去的业绩、不断变化的竞争格局、宏观指标等做出反应的“假设”行动。。..

在我的下一篇文章中会有更多的介绍。如果你很好奇,我下一篇文章的暂定标题是all ML的母亲(或 MOAML,是对印地语中“mamool”的致敬,我理解为“普通”的意思)。我们需要非常努力地工作,现在,让人工智能相关而不是时尚。这将要求我们让它说商业语言,从而让它从崇高变得简单。

机器学习单词嵌入

原文:https://towardsdatascience.com/machine-learned-word-embeddings-638c3fb5b916?source=collection_archive---------65-----------------------

没有数学的介绍

单词是许多自然语言中的关键结构。它们被赋予了意义。往往因环境而大相径庭。拿 python 来说。这在计算机编程和生物学中意味着完全不同的东西。

要掌握一门语言,人和计算机都是从掌握关键词开始的。这篇文章试图解释计算机是如何掌握单词的。

用适合自然语言处理或信息检索(搜索)的形式来表示单词已经有很长的历史了。出现了两大类代表:本地分布式。

这篇文章关注的是(I)分布式的和(ii)机器学习的表示。不熟悉本地或其他分布式表示的读者可能想先阅读自然语言处理中的单词和文本表示。

从这一点开始,我们转而使用术语单词嵌入。这是通常用来表示“机器学习的分布式单词表示”的术语。

为什么机器学习单词嵌入?

原因 1 。可以仅从丰富的文档语料库中学习单词的准确和丰富的表示。举个例子。从维基百科语料库中,我们可以机器学习数百万不同单词的好单词嵌入。对它们运行算法就行了。呈现出来。

原因二领域特定的单词嵌入可以仅仅通过在领域特定的语料库上训练来学习。例如,从关于计算机编程的文档语料库中,嵌入单词的学习者可以了解 python 在计算机编程上下文中的含义。当然,这种含义与非编程环境中的含义完全不同。

想象一下,一个对某个领域一无所知的人,比如说计算机编程,要花多长时间才能理解它的词汇?即使是最基本的。

学习问题公式化

从高层次来看,很明显。我们想学习单词的“准确而丰富”的表达。不过有点太笼统了。我们如何知道算法是否(以及何时)学习得足够好?人们不断地与其他人互动,所以他们缺乏理解很快暴露出来。计算机还没有出现。因此,我们希望更具体地指定学习目标。

这个怎么样?我们想学习相似单词有相似表示法的表示法。嗯,这似乎也有点宽泛。事实上,我们已经获得了有用的特异性。

很容易构建成对单词的测试集,每对都标有“相似”或“不相似”。下面是一些例子

{lawyer, attorney} → similar
{computer, cat} → not-similar

标签可以被细化,例如,我们可以引入多个相似或相异的级别。

学习问题公式化:我们还没到那一步

熟悉机器学习的读者可能会倾向于认为前面提到的测试集也说明了机器学习问题。并非如此。我们来解释一下。

让我们看看,如果我们把测试集的形式作为学习问题的文字说明,我们会得到什么。我们得到:训练一个二元分类器,输入两个词,输出它们是否相似

虽然这是一个值得解决的问题,但这不是我们的目标。我们希望输入是一个单个字。我们希望算法输出这个单词的准确而丰富的表示。测试集只是作为一种间接的手段来评估学习模型对这项任务有多好。

学习问题公式化:取两个

好吧,让我们重新开始

P1: We’d like to learn representations of words in which similar words have similar representations.

考虑将此重新表述为

P2: We’d like to learn representations of words that capture their context.

什么是“语境”?这个词经常出现在其他词的近旁。的上下文将包括胡须。但不是电脑

有理由认为,语境表征相似的词本身也是相似的。因此,解决 P2 问题也是解决 P1 问题的好办法。

我们取得了进展。我们之前的公式包括输入两个单词。这才一个

嗯。我们如何获得(单词上下文)对的训练集?在这一点上,我们甚至不知道如何将上下文的概念塞进一个变量中,这个变量可以作为我们的预测目标!

好吧,让我们先解决“将上下文填充到变量中”的问题。我们将一个单词的上下文建模为词典中单词的概率分布。以为例。胡须的上下文中的概率应该很高。计算机的上下文中的概率应该很低。

上下文向量

我们在本帖中描述的学习方法最好在神经网络环境中描述。神经网络喜欢在向量空间上操作。也就是说,它们将输入向量映射到输出向量(或标量),通常在两者之间会发生一些神奇的事情。

我们已经完成了输出。词典中单词的概率分布是空间中的向量,其维数是单词。(所以一百万单词词典的向量空间将有一百万个维度。)向量的一个分量的值就是相应单词的概率。

输入呢?这是一个特别的词。这也可以表示为同一空间中的概率向量。与单词相关联的维度的值为 1,其余为 0。

因此,我们当前的架构可以描述为

I ⇒ magic ⇒ O

I 和 O 是同一空间上的概率向量,而“魔术”是在它们之间发生的任何事情。

训练集?

为了学习,我们需要一个训练集(单词上下文)对。不清楚如何建造。单词不会被贴上上下文的标签。

我们可以从具有代表性的文档语料库中估计单词的上下文向量。在这个词附近出现(足够频繁)的词是在它的上下文中,那些不在它的上下文中的词不是。

我们所说的“代表”是什么意思?我们指的是与我们试图学习的内容相匹配的语料库。学习计算机编程术语,我们的语料库应该由计算机编程文档组成。

训练集简化

建立上述训练集包括从语料库中学习各种单词的上下文向量。我们可以简化这个。相反,我们可以用一组足够接近的成对单词来训练,例如在同一个句子中。表示这样的一对( word1word2 )。我们将此解释为单词 2 出现在单词 1 的上下文中的实例。

这里有一个例子。

Sentence: the **dog** and **cat** are **black** Training Set: dog → cat, cat → dog, dog → black, black → dog, cat → black, black → cat

训练实例仅限于加粗的实例。(剩下的就当是停用词吧。)

将来自我们语料库中所有文档的所有句子的这种对流传送到学习算法将有效地向算法揭示每个单词的上下文向量。

这种简化对我们有两方面的好处。

首先,它简化了构建训练集的过程。我们可以独立处理每个句子。简单地发出由此产生的训练对。我们甚至可以在一个流动的,即连续学习的环境中做到这一点。想象一下新文档不断到达,就像 web 级搜索引擎的索引器一样。我们可以从他们那里即时流出新的训练实例。

第二,有利于学习算法。与输入相关联的目标是概率向量,其质量集中在一个单词上。这个目标比一个任意的概率向量更清晰。

好了,现在谈谈学习算法。我们只会看到一个。传达主要思想就足够了。也就是说,那些寻求从大型语料库中的大型词典上建立工业强度单词嵌入的人需要阅读更多。

连续词袋模型

这个描述相对于最初的描述有所简化,尽管对于我们在这篇文章中要解决的问题来说已经很好了。

这是一个只有一个隐藏层的神经网络。

I ⇒ H ⇒ O

好了,我们用 H 代替了魔法。确实神奇!

这两个符号下面发生了什么?这在下面描述。

H = W1*I O=probability_normalizer(W2*H)

让我们解释一下数据是如何从输入流向输出的。我们从输入向量 I 开始。我们用矩阵 W1 乘以 I 。这给了我们一个隐藏向量 H 。接下来,我们用矩阵 W2 乘以 H 。得到的向量还不一定是概率向量。我们对它应用概率规格化器,把它转换成一个。这就变成了我们的输出向量 O

一些问题仍然存在。首先,学习发生在哪里?第二,这个概率规格化器的概念有点抽象。

对第一个问题的回应。实际上,我们到目前为止描述的是输入到输出的数据流。我们将在一两分钟后开始实际的学习。我们将学习的参数是矩阵 W1 和 W2 中的值。

对第二个问题的回应。下面是两个概率规格化器的具体例子。两者都假设输入是一个具有非负值的向量。

第一个,姑且称之为简单,只是取每个值,除以所有值的和。第二个称为 softmax ,首先对值取幂,然后应用简单的规格化器。softmax 是在实践中使用的。为什么?在我们描述了实际的学习算法之后,我们将给出一些直觉。

以下是两个规格化函数的例子。

simple([1,3,5]) → [1/9,3/9,5/9]
softmax([1,3,5]) → simple([e¹,e³,e⁵])

在神经网络术语中,概率归一化器是一个矢量激活函数的实例。

更多要点

鉴于学习的过程将包括学习从 I 预测 O ,一旦我们学习得足够好,我们将只提取权重矩阵 W1。我们会扔掉 W2。

我们只关心从 IH 的映射。 H 将作为由 I 表示的单词的表示。(也就是说,为了学习一个好的映射 I → H ,我们别无选择,只能解决完整的学习问题,因为我们没有关于 H 的目标,只有关于 O 的目标。)

另一个关键点是,我们会有意将 H 的维度限制为远小于 IO 的维度。鉴于 IO 可能有几百万个维度,我们将强制 H 有几百个,可能一千个,也可能更少。想法是迫使学习算法学习密集单词表示。

理由是这样的。首先,这是否可行?是的。单词有结构,否则一开始就不会有任何单词相似的概念。所以我们应该能够将 I 空间压缩到一个维度更低的空间。事实上,很难想象有超过 20 个描述单词的正交潜在属性!也许我们只是想象力不够丰富。所以让我们把这个乘以五倍。甚至更好,百倍。这还是在低几千!

好的,我们认为我们已经解决了可行性问题。接下来,我们为什么要这么做?(可行不代表是个好主意。)原因是密集表示更好地概括。直觉很简单:如果我们认为单词的潜在特征比它们的数量少得多,那么强迫学习者映射到低维空间将比试图学习映射到原始向量空间更好地概括。

最后,学习!

我们将通过一个简单的例子来集中传达直觉。没有数学。

我们的例子是在一个只有四个单词 A,B,C,d 的词典上。我们将 H 设为二维。我们将使用训练集

(A,B), (B,A), (C,D), (D,C)

我们将从空白状态开始学习,将 W1 和 W2 中的所有值随机初始化为较小的正值或负值。接下来,我们将呈现第一个训练实例的输入 A,其编码为 1000。所有可学习的权重都接近 0;所以 H 会是(0,0),W2* H 会是(0,0,0,0)。我们假设 probability_normalizer 激活函数将这个 H 映射到()。目标是 B,具体来说,是编码(0,1,0,0)。这个目标与预测大相径庭。所以我们需要学习。

接下来发生的事情最好用一张图来传达。

学习范例

在图中, T 表示目标输出。从 HO 的圆弧上的+s 和-s 表示根据 OT 之间的差值改变重量的方向。我们看到 B 的产出的权重应该增加;其余减少。(这是因为 B 的产量太低;其余的产量太高了。)

我们还没完。我们还需要计算从 IH 的权重调整。为什么?因为这些权重值也可能导致我们在输出端看到的误差。

这些调整是通过著名的反向传播算法计算的。正是这种算法,在这种隐藏的基于层的架构中利用适当选择的激活函数(在我们的情况下是概率归一化器),提供了魔力。

接下来发生的事情最容易用数字来描述。设 H 1 表示 H 的第一个分量。 H 1 的当前值为 0.1。考虑 B 的输出。它看到的错误是~ 1-=。在这种情况下,如果我们能够以某种方式在 H 1 上设置一个合理的目标,我们就会知道将重量从 I 移动到 H 1 的方向。如果 1 的目标值大于 0.1,我们会降低权重。如果 1 的目标值小于 0.1,我们会增加权重。

嗯,估计 1 的目标和估计 1 看到的误差是一样的。这一点我们可以估计如下。考虑一个特定的输出节点。它的误差是目标输出减去实际输出。我们首先通过 probability_normalizer 反向传播这个误差,然后通过从 H1 到这个输出节点的权重。这给了我们 H1 从这个输出节点看到的误差。输出节点上这些误差的总和。是 H1 认为的完全错误。

让我们一步一步地解决这个问题。三个输出都有错误,其中一个(B)有错误。想象一下,这些误差通过概率归一化器成比例地反向传播。(我们只是要求你去想象,而不是假设。)加上回想一下,从 H 1 到 O 的权重是随机的,幅度很小。考虑到这两个因素,在 H 1 处对这些误差求和将大致抵消它们,即产量接近 0。

同样,H2 看到的误差也将接近于 0。这令人不安吗?不。在这一点上, H 1 和 H 2 都不知道它想要成为什么。 H 1 和 H 2 误差虽然可能接近 0,但也可能不同。因此,从 T36 到 T37,H1 和 H2 的权重可能会经历至少略有不同的调整。这将导致 H1 和 H2 在他们所学的东西上产生分歧。在许多训练实例中,在我们的例子中,这意味着在相同的 4 个训练实例中的多次迭代, H 1 和 H 2 将学习从输出中挑选不同的东西。引发这一现象的现象被称为对称性破缺

为什么选择 Softmax?

哦,我们忘了。我们答应解释这个。直觉告诉我们,我们想要鼓励学习区分。这样想。我们在隐藏层中有一个神经元池。起初,他们不知道他们应该做什么。如果我们不鼓励他们开始歧视,他们可能会保持不承诺。我们都知道会发生什么。有没有在一个没有人想脱颖而出的委员会里?

嗯,softmax 功能就像一位高管,推动人们探索自己舒适区以外的地方。softmax 中的幂运算具有放大差异的效果。于是轻微的赢家(输家)变成了强大的赢家(输家)。

延伸阅读

https://arxiv.org/pdf/1411.2738.pdf】T2—word 2 vec 参数学习讲解

Mikolov,Sutskever,I .,Chen,k .,Corrado,G. S .,和 Dean,J. (2013b)。词和短语的分布式表示及其组合性。神经信息处理系统进展,3111-3119 页。

机器学习 101 —人工神经网络

原文:https://towardsdatascience.com/machine-learning-101-artificial-neural-networks-3-46ccb04cba30?source=collection_archive---------20-----------------------

这篇文章旨在解释一般的人工神经网络,尤其是计算。

https://pixabay.com/images/id-1343877/

人工神经网络

关于人工神经网络(ANN ),你首先要了解的是,它来自于对大脑建模的想法。因此,我们在人工神经网络中使用的术语与神经网络密切相关,只是略有变化。

  • 神经元在人工智能中也被称为神经元,
  • 但是树突被称为输入,
  • 轴突被称为输出,
  • 最后,突触被称为重量

一开始,学习这些术语就足够了。

单层感知器

单层感知器是人工神经网络的原始版本。人工神经网络的灵感来自生物神经回路的功能[ 1 ],所以单层感知器自然是神经回路的代表。这个神经回路是一个神经元,其输入具有相应的权重,并作为计算的输出输出。

图 1 具有两个输入和一个输出的单层感知器的表示

图 2 单层感知器的一般方程

在单层感知器中,x 代表输入,w 代表权重,θ代表阈值。

图 3 根据图 1 表示的计算

我试图尽可能基本地解释单层感知器的方程。过了这一点就更复杂了。y 的输出值是根据函数类型构造的。就功能而言,有许多类型,但在开始时,3 种就足够了。

1.阶跃函数

根据输入的值,输出将是 0 或 1。

2.符号函数

3.Sigmoid 函数

在这种方法中,感知器的作用就像一个线性回归模型。sigmoid 函数将这些值归一化到[0,1]的范围内,以便负值在 0 附近缩放,正值在 1 附近缩放。因此,您不需要处理可能导致计算错误的负值或非常大的数字。

单层感知器训练

  1. 输入和相关的输出值被提供给模型。丁:
  2. 所有的权重值都是以一定的方式定义的,在这一点上我们说随机在[-0.5,0.5]的范围内。
  3. 根据这些值计算输出,并计算误差以进行比较。学习率(0

图 4 训练单层感知器的方程式

4.通过改变权重值,根据阈值来校正误差。

5.从步骤 3 继续到下一个纪元。

例 1: 我们用阶跃函数把 OR 运算映射到单层感知器。

下表列出了可能的输入和输出:

可接受的默认值:𝜃= 0.02;𝜇=0.1 ;w1 = 0.3w2=-0.1

第一纪元:

y = x1w1 + x2w2-𝜃

y1 = 0.3 * 0+(-0.1)* 0–0.02 =-0.02-0.02<0 → y1 = 0

y2 = 0.30 + (-0.1)1–0.02 = -0.12 -0.12<0 → y2 = 0

y3 = 0.31 + (-0.1)0–0.02 = 0.28 0.28>0→y3 = 1

y4 = 0.3 * 1+(-0.1)* 1–0.02 = 0.18 0.18 > 0→y4 = 1

y3 和 y4 的计算输出和预期输出不同。所以我们需要相应地计算学习率和新的权重。

δw11 = 0.1 (0–0) 0 = 0

δw21 = 0.1 (0–0) 0 = 0

δw13 = 0;δw23 = 0;δw14 = 0;w24 = 0

δw13 = 0.1 (1–0) 0 = 0;δw23 = 0.1 (1–0) 1 = 0.1

最新的重量值计算如下:

w13 ' = w13+δw13

w13' = 0.3 + 0 = 0.3

w23 ' = w23+δw23

w23' =(-0.1) + 0.1 = 0

第二纪元:

再次计算输出;

y1 = 0.3 * 0+0 * 0-0.02 =-0.02<0 → y1 = 0

y2 = 0.30 + 01 -0.02 = -0.02 <0 → y2 = 0

y3 = 0.31 + 00 -0.02 = 0.28 >0→y3 = 1

y4 = 0.31 + 01 -0.02 = 0.28 > 0 → y4 = 1

δw11 = 0;δw21 = 0;δw13 = 0;δw23 = 0;δw14 = 0;w24 = 0

δw13 = 0.1 (1–0) 0 = 0→w13 ' = 0+0.3 = 0.3

δw23 = 0.1 (1–0) 1 = 0.1→w24 ' = 0.1+0 = 0.1

仍然无法达到正确的重量值。所以我们仍然需要调整。

第三纪元:

y1 = 0.3 * 0+0.1 * 0-0.02 =-0.02<0 → y1 = 0

y2 = 0.30 + 0.11 -0.02 = 0.08 >0→y2 = 1

y3 = 0.3 * 1+0.1 * 0-0.02 = 0.28 > 0→y3 = 1

y4 = 0.3 * 1+0.1 * 1-0.02 =-0.38 > 0→y4 = 1

δw11 = 0;δw21 = 0;δw12 = 0;δw22 = 0;

δw13 = 0;δw23 = 0;δw14 = 0;w24 = 0

似乎我们找到了正确的重量值。这就是单层感知器的工作原理。理解模型是非常必要的,因为更复杂的模型是基于单层感知器的。

多层感知器

用单层感知器解决 OR 运算就足够了,但是当涉及到 XOR 运算时,事情已经开始发生变化,因为单层感知器本身不足以解决问题。因此,多层感知器(MLP)的想法刚刚出现。如图 5 所示,多层感知器由三层组成:输入层、隐藏层和输出层。

图 5 多层感知器的示意图

此外,MLP 是深度学习的一个良好开端。它被称为深度人工神经网络,但当然没有卷积神经网络那么深。

反向传播

在 MLP,属于一个层的每个计算都被接受为下一层的输出。反向传播看起来非常复杂,但其实不然。计算误差时,通过反向计算重新排列权重。

在反向传递中,使用反向传播和微积分的链式法则,误差函数的偏导数通过 MLP 反向传播各种权重和偏差。这种微分行为给了我们一个梯度,或者说一幅误差图,沿着这个梯度,当 MLP 向误差最小值靠近一步时,参数可以被调整。这可以通过任何基于梯度的优化算法来实现,例如随机梯度下降。网络继续打网球,直到错误不能再低。这种状态被称为收敛[ 2 ]。

图 6 E 表示 y 和 d 之间的欧氏距离,y_t 表示样本 t 的误差

示例 2: 让我们通过使用阶跃函数来映射具有多层感知器的 XOR 运算。

下表列出了可能的输入和输出:

当您检查结果列时,您将意识到这两个等式都是 y = x2w2 和 y=x1w1 大于 0,但这是不可能的,因为 x1 和 x2 是输入,对于 XOR 运算,它们中的任何一个都应该等于0。此外,根据结果栏中的等式,y=x1w1 + x2w2 小于 0,但这也是不可能的。因此,在这种情况下,单层感知器不能作为方程的解,建议使用多层感知器来寻找解。****

w13 = 0.5

w23 = 0.4

w35 = -1.2

w14 = 0.9

w24 = 1 w45 = 1.1

𝜃3 = 0.8 𝜃4 = -0.1 𝜃5 = 0.3

𝜇 = 0.1

让我们接受上述值作为开始。在 XOR 运算中,当 x1=x2=0 时,y 将等于 y=0。由于这些值是连续的,我们可以使用 sigmoid 函数。

y3 = sigmoid(x1w13+x2w23-𝜃3)

= 1/(1+e-(0.5 * 1+1 * 0.4-1 * 0.8))=0.525

y4 =sigmoid(x1w14+x2w24-𝜃4)=0.881

y5 = sigmoid(y3w35+y4w45-𝜃3)

= 1/(1+e-(0.525 *(1.2)+0.88 * 1.1–0.3))=0.51->实际输出

误差=ɛ=(0–0.51)=-0.51

输出层:

𝜍5 = y5 (1-y5)ɛ= 0.5097 (1–0.5097)(-0.5097)≠-0.13

δw35 =𝜍5y3𝜇=-0.12 * 0.525 * 0.1 =-0.0068;

δw45 =𝜍5y4𝜇=-0.12 * 0.88 * 0.1 =-0.012

w35 ' =-0.0068+(-0.12)=-1,2068

w45' = (-0,12)+1.1 = 1.088

隐藏层:

𝜍3 = y3 (1-y3) 𝜍5w35 = > δw23=𝜇x2𝜍3;δw13=𝜇x1*𝜍3

𝜍3 = 0.53 (1–0.53)-0.13 *(1.2)=0.0389

δw23 = 0.039 * 1 * 0.1 =0.0039;δw13 = 0.039 * 1 * 0,1 = 0.0039

w23 ' = 0.0039+0.4 =0.4039;w13'=0.0039+0.5= 0.5039

𝜍4 = y4 (1-y4) 𝜍5w45 = > δw24=𝜇x2𝜍4;δw14=𝜇x1*𝜍4

𝜍4 = 0.0881 (1–0.0881)(-0.13)* 1.1 =-0.015

δw24 =-0.015 * 1 * 0.1 =-0.0015;δw14 =-0.015 * 1 * 0.1 =-0.0015

w24 ' =-0.0015+1 =0.985;w14 ' =-0.0015+0.9 =0.8985

新更新权重:

w14 =-0.0015;w24 = 0.8985w13 = 0.5039w23 = 0.4039w45 = 1.088w35=1.2068

我们正在计算每一个权重,直到找到正确的结果。隐层应该有多少个神经元,网络应该有多少个隐层,这是一个应该由这个网络的设计师来回答的问题。最大值经典人工神经网络的隐含层数为 3。

重量更新

1。增量模式

每次训练后计算新的重量

2。批处理模式

动量:该项连接 t 和(t-1)时刻之间的变化。它主要用于敏感。

结论

人工神经网络(ANN)是深度学习的良好开端。在这篇文章中,我打算解释人工神经网络的类型和基本计算,以调整它们的核心权重值。

参考资料:

  1. Tensorflow 单层感知器,https://www . tutorialspoint . com/tensor flow/tensor flow _ Single _ Layer _ Perceptron . htm
  2. 多层感知器,https://pathmind.com/wiki/multilayer-perceptron

阿拉伯语自然语言处理中的机器学习进展

原文:https://towardsdatascience.com/machine-learning-advancements-in-arabic-nlp-c6982b2f602b?source=collection_archive---------18-----------------------

讨论社交媒体文本的阿拉伯语自然语言处理(NLP ),包括代码示例和对推动最新发展的尖端技术的深入分析。

来自关于贝鲁特爆炸(2020 年 8 月)的推文的多语言单词云。图片作者。

自然语言处理(NLP)不是一门新学科;它的起源可以追溯到 17 世纪,当时笛卡尔和莱布尼茨等哲学家提出了语言的理论代码。在过去的十年里,这一漫长历史的结果导致了 NLP 以 Siri 和 Alexa 这样的数字助理的形式融入到我们自己的家中。尽管机器学习极大地促进了英语自然语言处理技术的发展,但其他语言的自然语言处理研究却一直滞后。

为什么要学习阿拉伯语社交媒体?

作为遍布中东北非地区 22 个国家的官方语言,阿拉伯语是互联网上第四大常用语言。【2018 年的统计数据显示,中东有 1.64 亿互联网用户,北非有 1.21 亿互联网用户。

中东北非地区地图。【researchgate.net 图片来源于

阿拉伯语作为一种语言,形态复杂,方言多样。当考虑到社交媒体文本的非正式性质以及现代标准阿拉伯语(MSA)和辩证阿拉伯语(DA)之间的区别时,复杂性显著增加。MSA 用于正式写作,DA 用于非正式的日常交流;然而,这两种形式都出现在社交媒体上,后者是最常见的形式。

更复杂的是,埃及有许多方言,例如埃及方言不同于巴勒斯坦、约旦、叙利亚、黎巴嫩和以色列使用的黎凡特方言。这两种方言也不同于科威特、巴林、卡塔尔和阿拉伯联合酋长国使用的海湾方言。在 2019 年 5 月的一篇论文中研究人员评论说,阿拉伯语的屈折和衍生性质使得对阿拉伯语的单音分析更加困难。简单地说,由于英语和阿拉伯语之间的差异,英语 NLP 的进步不容易转移到阿拉伯语 NLP 资源的开发。此外,在应用复杂的英语 NLP 方法之前,不能依赖粗糙的阿拉伯语到英语的翻译作为充分的预处理;翻译中损失了很多。

尽管有这些挑战,过去的四年是富有成效的,在情感分析和机器翻译等领域的阿拉伯语 NLP 研究已经产生了非常有用的资源。我的重点是阿拉伯语社交媒体,因为这些平台在中东和北非地区的民主发展中发挥了重要作用。此外,在我看来,社交媒体文本是最容易获得的数据形式,可以用来研究这个通常难以理解的领域。

这将是关于阿拉伯语 NLP 的三部分系列的第一部分。在这篇文章中,我将重点介绍我在研究中使用的两个最有效和最容易使用的工具: 【阿拉维】阿拉伯特 。熟悉当前英语自然语言处理研究趋势的人会注意到这些名字和流行的英语自然语言处理工具 Word2Vec 和 BERT 之间的相似之处。对于英语自然语言处理资源的初学者友好概述,请查看我之前关于使用 Python 进行情感分析的帖子,在那里我详细讨论了 Word2Vec 和 BERT。

[## 基于 Python 的社交媒体情感分析

Python 工具的初学者友好概述,可用于对社交媒体文本中的情感进行分类。我讨论我的…

towardsdatascience.com](/sentiment-analysis-of-social-media-with-python-45268dc8f23f)

阿拉伯语单词嵌入

当托马斯·米科洛夫(Tomas Mikolov)领导的谷歌团队在 2013 年发布具有影响力的 Word2Vec 时,单词嵌入的使用在各种各样的自然语言处理任务中变得流行,实现了最先进的准确度分数,从而彻底改变了该领域。使用单词嵌入,单词被表示为连续空间中的向量。嵌入捕捉单词之间的句法和语义关系。我推荐 Jay Alammar 的这本图文并茂的单词嵌入指南,它很好地介绍了这种方法背后的理论。

2017 年,单词嵌入被改编为阿拉伯语 as AraVec,这是一个预训练的分布式单词表示(单词嵌入)开源项目,由索利曼等人在 2017 年的一篇论文中介绍。目前,AraVec 的第三个版本提供了 16 个不同的单词嵌入模型,构建在两个不同的阿拉伯语内容域之上;Twitter 和维基百科的阿拉伯文文章。在当前版本中,有两种不同类型的模型,一元模型和多元模型。嵌入可以在浅层神经网络中训练,或者用作深度学习模型架构中的嵌入层。尽管训练时间较长,但我通常倾向于后者,因为它通常会导致更高的准确性。

在原始论文中,陈述了用于构建第一迭代模型的令牌总数总计超过 3,300,000,000 个令牌。对于最初的 Twitter 嵌入,研究人员收集了 2008 年至 2016 年间发布的超过 77,600,000 条阿拉伯语推文,这些推文是从不同的随机地理位置获得的(以考虑各种方言)。阿拉伯字符的预处理包括去除音调符号,音调符号是字母上方、下方、中间或上面的标记,目的是为了标准化。例如,将字母“ ة ”替换为“ ه ”,将字母“ أ ”、“ إ ”、“ آ ”替换为“ ا ”。

AraVec 模型是使用由 Radim Rehurek 开发的 Python 库 Gensim 构建的,该库还包含原始 Word2Vec 模型的实现。在最初的 Word2Vec 论文中,Mikolov 和他的团队提出了两种不同的模型架构,用于在多维向量空间中表示单词:连续词袋(CBOW)模型和 skip-gram 模型。CBOW 模型通过预测序列中的中心词来学习嵌入,给定该序列中的其他词,而不考虑它们在句子中的顺序。skip-gram 模型与 CBOW 模型相反,因为它的目标是在给定中心单词的情况下预测周围的上下文单词。下图显示了这两种模型架构之间的差异。

CBOW 和 Skip-gram 模型架构。图片来自: AraVec:一套阿拉伯语单词嵌入模型,用于阿拉伯语 NLP

与 skip-gram 模型相比,CBOW 模型的优点是速度更快,并且对于频繁出现的单词具有更高的准确性。但是,当训练数据集较小时,skip-gram 模型体系结构提供了更高的准确性,此外还能更好地处理罕见的单词。我试验了两个 AraVec n-gram 模型,Twitter-CBOW 和 Twitter-SkipGram,两个模型都与 Gensim 和 Python NLP 库 spaCy 和 NLTK 结合使用。

首先,我需要用前面提到的标准化预处理步骤清理我的阿拉伯文本。下面的代码片段显示了我使用的函数,改编自 AraVec 项目的存储库。

接下来,我加载 AraVec,将其导出为 Word2Vec 格式,然后使用 AraVec 向量初始化 spaCy 模型。下面的代码片段概述了这个过程。

最后,我使用 spaCy 模型创建了一个围绕预处理步骤的标记器,将原始的阿拉伯语社交媒体文本转换为单词嵌入。

我用各种深度学习模型测试了 AraVec 嵌入,根据当前的研究趋势,我最成功的模型是双向长短期记忆网络(双 LSTM )。

AraVec 和其他单词嵌入的主要缺点是,它们为单词提供了单一的表示,无论上下文如何,该表示都是相同的。因此,诸如“bank”之类的单词根据上下文可能具有不同的含义(例如,“river bank”或“investment bank”),具有表示不同上下文的平均值的合成向量,从而不能准确地表示单词“bank”的任一含义。这个问题在阿拉伯语中也是一个令人关切的问题,特别是当非正式的阿拉伯俚语根据上下文或地区可能有不同的含义时。这个缺陷导致我发现了 AraBERT 模型,这是 2020 年 2 月发布的 transformer 架构的一个实现。

变形金刚(电影名)

我认为,过去几年中最有影响力的 NLP 论文是 2017 年的论文“注意力是你所需要的”,作者瓦斯瓦尼等人,该论文介绍了变压器架构。我推荐哈佛大学 NLP 研究小组的注释转换器,以获得对这篇重要论文的全面解释,其中包括以笔记本格式呈现的代码注释。

在 Transformer 模型创建之前,最先进的 NLP 方法涉及使用单词嵌入和卷积或递归神经网络,这些网络与注意力机制一起使用,如 LSTM 或 GRU 。注意机制作为一种缓解消失梯度问题的方法是很重要的,它通过关注输入序列中与每个输出序列最相关的部分来实现。这是通过保持自回归特性来实现的,以便预测未来的能力得到过去位置环境的知识的帮助。

为了捕获位置信息,递归模型生成一系列隐藏状态,这些隐藏状态是作为前一个隐藏状态的函数结合特定位置的输入来计算的,从而形成一个循环。这种循环顺序的性质使得并行化变得困难,这个问题可以通过卷积网络来解决,卷积网络可以并行计算所有输入和输出位置的所有隐藏状态。然而,卷积使得学习长距离依赖性更加困难,困难由最大路径长度决定。重要的是,《变形金刚》引入了一种使用注意力机制的方法,这种方法不会出现重复或回旋。这允许并行化,大大加快了培训时间。

如下图所示,转换器架构包括一个编码器和解码器堆栈,每个堆栈都有多个层,每个层又有子层(每个编码器层 2 个,每个解码器层 3 个),其中一个是前馈网络(非循环)。由于转换器模型不包含考虑位置的递归或卷积,所以位置编码被添加到输入嵌入中。编码表示序列中标记的相对或绝对位置。这是通过对应于正弦函数的位置编码的每个维度来实现的,该正弦函数允许模型容易地关注相对位置。此外,为了求和,位置编码的维数与输入和输出嵌入相同。

李连翁 放大的变压器架构图;归功于 瓦斯瓦尼等人 2017

为了解决路径长度的问题,转换器还利用对编码器堆栈输出的多头关注来更好地学习长距离依赖性。具体而言,多头关注允许模型通过对查询、键和值矩阵进行线性投影来并行执行关注,然后对其进行连接和线性投影以获得最终关注值。多头注意力的重要性在于允许模型在不同位置共同注意来自不同子空间的信息。作为一个完全依赖自我注意力来计算输入和输出序列的表示(嵌入)的转导模型,transformer 证明了,正如标题所述,注意力是你所需要的全部。

如上所述,单词嵌入的主要缺点是缺少由表示捕获的上下文信息。谷歌人工智能语言团队的研究人员在 2019 年开发了 BERT,进一步推进了 transformer 架构。BERT 代表来自变压器的双向编码器表示。BERT 的主要概念是通过联合调节所有层中的左右上下文来预训练来自未标记文本的双向表示。这意味着,预训练的 BERT 模型可以用下游任务的标记数据进行微调,以获得最先进的准确度分数。预训练包括两个无监督的学习任务。第一个是受完形填空启发的掩蔽语言模型(MLM)目标,第二个是下一个句子预测(NSP)任务,允许模型学习句子关系。重要的是要注意这些模型的大小,基本的 BERT 模型是 1.1 亿个参数,大模型是 3.4 亿个参数。这意味着使用阿拉伯语 NLP 的 transformer 架构需要构建一个类似的大型语言模型;这在计算和金钱上都是昂贵的。

阿拉伯特:阿拉伯变压器

阿拉伯特于今年早些时候发布,由阿尔的安托恩在一篇论文中介绍。2020.这个预先训练的阿拉伯语模型是使用 BERT 开发的,拥有 1.1 亿个参数,反映了基本的 BERT 模型。按照伯特论文中概述的程序,阿拉伯特的预训练设置包括 MLM 和 NSP 的两项无人监督的任务。预训练数据达到 24GB(大约 7 亿个句子),标记化产生了 64K 个单词的词汇量,这些单词来自于诸如15 亿个单词的阿拉伯语语料库OSIAN:包含 350 万篇文章的开源国际阿拉伯语新闻语料库之类的来源。

针对 AraBERT 的 Github 存储库包含了如何使用该模型的示例;有 Tensorflow 和 Pytorch 这两个最流行的 Python 机器学习框架的 Colab 笔记本,也有 Python 库拥抱人脸变形金刚的笔记本。我更喜欢使用 Python 库 Hugging Face transformers 来测试新的预训练模型,因为它简单且易于实现。这些例子展示了针对情感分类对阿拉伯语约旦语通用推文(AJGT)语料库的微调。AJGT 数据集由 1800 条 MSA 或约旦方言的推文组成,标注为正面或负面。

为了更好地适应阿拉伯语,作者在模型的预训练之前引入了额外的预处理步骤。在论文中,他们指出,阿拉伯语以词汇稀疏著称,这意味着单词可以有不同的形式,但意义相同,这主要是由于该语言复杂的连接系统。为了解决这个问题,他们利用 Farasa,“一个快速和激烈的阿拉伯语切分器”,将单词分为词干、前缀和后缀。使用包含 Fararsa 分割器的 AraBERT 版本,在 AJGT 上的微调实现了 93.8%的二进制分类精度。

在下面列出所需导入的代码片段中,我导入了 Farasa 分段器来预处理阿拉伯文本。

预处理和准备用于训练的数据集只需要几行就可以创建分割器、应用预处理并分割用于训练的数据集。

下一步是设置用拥抱脸变形金刚训练器训练模型所需的组件。首先,需要初始化配置、标记器和模型。然后将用于单句分类的拥抱人脸数据处理器应用于训练和测试数据集。最后,使用最大序列长度设置为 128 的记号化器创建要素。

为了在训练期间访问所有定制选项,Hugging Face 建议在实例化训练器之前创建训练参数。我使用了 AraBERT 的创建者定义的训练参数。

实例化之前的最后一部分是创建一个定制函数,使用 Python 库 SciKit-Learn 来计算指标,这个库是在前面用必要的子模块导入的。

剩下的工作就是实例化训练器并开始训练,只需下面两行代码就可以完成。

下表摘自 AraBERT 论文,显示了他们的模型在各种阿拉伯语 NLP 基准数据集上的卓越性能,并与多语言 BERT (mBERT)的性能和之前的一流记录进行了比较。

表格来自: AraBERT:基于变压器的阿拉伯语理解模型

研究潜力

讨论的两个阿拉伯语 NLP 工具 AraVec 和 AraBERT 是研究阿拉伯语社交媒体的极好起点。特别是,AraBERT 在广泛的 NLP 任务中有许多可能的用途,只受到用于微调的标记数据集的可用性的限制。应用可以包括创造性地使用文本分类或命名实体识别、情感分析、主题标记或检测工具。另一种选择是使用多任务学习(MTL)来同时学习多个 NLP 任务。

文本分类

例如,对识别社交媒体上的医疗错误信息的任务模型进行微调将是有趣的,特别是因为新冠肺炎疫情继续在中东和北非地区产生破坏性影响。通过同样的措施,可以利用一般的谣言检测分类器来调查谣言的发展,为打击有害的假新闻提供机会。跟踪工具是另一种可能性;可以过滤社交媒体文本,以跟踪与政治动荡、抗议或不满有关的趋势。另一个潜在用途是训练一个分类器,通过实时跟踪 Twitter 并标记可能的侵权行为进行调查,来检测侵犯人权行为。

命名实体识别

命名实体识别(NER)是一个 NLP 子任务,用于通过提取符合预定义类别(如名称、组织、位置、货币价值或其他实体)的信息来定位和分类非结构化文本中提到的命名实体。目前,还没有出于研究目的将 NER 应用于阿拉伯文本的详细研究。然而,将 NER 应用于阿拉伯媒体,如博客帖子或新闻文章,通过确定可用文本中的主题和主题来展现内容并洞察趋势,将是一项值得努力的工作。

事实证明,AraBERT 擅长 NER,它在阿拉伯语 NER 语料库(ANERcorp) 上的得分高于之前以宏观 F1 分数衡量的最先进记录。截至 2020 年 9 月,当前更新版本的 AraBERT 在 ANERcorp 数据集上的宏观 F1 分数比最初公布的分数提高了 4.5%。这是通过进一步预处理 ANERcorp 训练数据集实现的,这是一种用于提高准确性的技术,可以应用于其他任务。

多任务学习

作为一种学习范式,MTL 依赖于归纳知识转移,假设学习任务之间存在共性。受人类在相关任务之间传递重要学习信息的能力的启发,用 MTL 开发的模型具有需要较少标记数据的优势。更重要的是,他们能够利用来自相关任务的共享信息。这意味着有可能通过将两个独立但相关的任务(例如情感分析和谣言检测)耦合来提高它们的分类准确度。在过去的三年里,由于在深度学习领域取得的成绩, MTL 迅速走红;然而,很少有研究将这种方法应用于具体的研究问题。

最后的想法

目前,我对阿拉伯语 NLP 的主要兴趣是应用数据科学;如何利用这些非凡的工具,并将它们应用于实际的研究问题。为此,我将继续开发我目前使用的工具,在搜索这项技术的创造性应用的同时,与当前的文献保持同步。在这个由三部分组成的系列的下一部分中,我将详细介绍我将 Apache Spark 等大数据工具集成到我的阿拉伯语 NLP 工作流中的实验。在最后一篇教程中,我将详细演示我自己在阿拉伯语自然语言处理中实现 MTL 的方法。

肿瘤学中的机器学习导论

原文:https://towardsdatascience.com/machine-learning-ai-applications-in-oncology-73a8963c4735?source=collection_archive---------44-----------------------

内部 AI

人工智能在癌症治疗和研究中的前景

肿瘤学的最新进展为癌症治疗和长期缓解带来了令人兴奋的选择。然而,高效和有效的诊断仍然是大多数癌症及时治疗的障碍。良好的预后取决于早期发现,但在许多情况下,患者直到出现相关症状时才意识到自己的癌症。病理学家需要更强大的工具来增强他们快速正确识别可能的癌症的能力。

国立癌症研究所Unsplash 上拍摄的照片

人工智能模型的潜力和挑战

人工智能的发展有可能彻底改变数据收集、图像处理和后续诊断的过程。机器学习(ML)和深度学习是人工智能的分支,专注于识别数据中的模式,并开发模型来准确预测新信息的结果。医疗领域对 ML 模型提出了独特的挑战。由于医院过时的系统或不愿意共享数据,许多数据,尤其是来自电子健康记录(EHR)的数据未分类、稀疏或不可用。此外,表现不佳的模型的影响是深远的,对患者来说可能是灾难性的。最后,癌症及其可能的治疗方法的极端复杂性,使其本身成为高度特异和孤立的 ML 模型。例如,使用循环 miRNAs 的谱来检测癌症的模型灵敏度低,并且不能区分良性和恶性肿瘤(2)。这表明在组织和癌症类型之间共享模型和见解可能是困难的。

机器学习模型可以使用三种风格之一来理解输入的数据。监督学习是最直接的方式。已标注的输入被输入到模型中,该模型使用隐藏的要素和权重图层来了解输入的哪些变换正确地映射到标注。因为输入是预先标记的,所以可以测量模型的准确性并改进模型。一旦训练完成,模型就可以接触新数据进行预测。无监督学习没有这些用户定义的标签,模型必须发现输入的特征才能映射到输出。这种方法需要较少的人为干预,无论是正面的还是负面的,因为模型可能很难识别模式,或者它可以使用几乎没有真正预测能力的任意特征。半监督学习利用预先标记和未标记数据的子集。这是最接近人类病理学家如何决定诊断的方法,因为他们可以访问标记的数据,如肿瘤宽度或密度,以及未标记的数据,如以前的记录。特征选择和提取是开发成功模型的一个关键的、人力劳动密集型的部分,将在后面的文章中讨论。

来自【5】:用于从组织学数据预测癌症存活的示意性 CNN 模型。根据 CC BY-NC-ND 4.0 许可

人工智能在生物医学领域的应用

下一代测序(NGS)和高通量技术(HTTs)的进步带来了多 OMIC 数据的爆炸,使得研究人员和临床医生更容易获得基因组和蛋白质组数据(2)。例如,分子生物标记已被证明对预测癌症非常有效,因为某些标记,如 PD-L1 和 CTLA-4,在癌细胞中过度表达。这些数据还可以帮助临床医生区分相同癌症的亚组,并实现个体化治疗。如果 CNN 模型可以被训练来从染色的组织样本中识别这些标记,它可以导致常规、廉价和有效的筛查,而无需临床医生的特别护理。

临床数据,例如笔记、医学成像和活体生理监测,非常适合通过 ML 模型进行分析和预测。这种类型的数据需要大量的功能工程才能成功,因为患者数据是高度异构的,不容易应用到新的环境中。正如王和 Preininger 猜测的那样,深度学习模型(DL)可能会通过创建自己的特征来提供解决方案。这将有助于开发更可靠、更准确的预测和更个性化的治疗(3)。例如,德法乌等人开发的框架要求结合使用两个模型,其中第一个 DL 模型分析并选择特征,然后馈送到第二个卷积神经网络(CNN),该网络实际预测可能的诊断(4)。

患者结果模型在估计存活率和癌症缓解方面也取得了一些成功。一个这样的人工神经网络模型在预测非小细胞肺癌(NSCLC)的癌症存活率方面达到了 83%的准确度。然而,正如许多这些模型的情况一样,它不适用于其他癌症类型。这是因为几个 NSCLC 特异性基因及其表达被用作模型中的特征。由于癌症载体的多样性和特定基因在预测不同癌症中的有用性,开发通用的预测模型可能很困难。

关键要点和后续步骤

人工智能在医学研究和治疗方面的前景是光明的。而目前的模型是高度特定的;不应忽视它们在这些领域的成功。随着越来越多的数据可供研究人员和临床医生使用,以及他们对人工智能可能应用的熟悉和理解不断增长,我们应该预计它们的使用会大幅增加。

也就是说,我们必须小心这些模型的耸人听闻的未来。虽然它们功能强大,但它们的范围也有限,应被视为临床医生为患者提供更有效、个性化治疗的另一种工具。人工智能模型擅长从同质选择中识别异常,这种能力应该被预防性地利用,以指导病理学家发现潜在的问题。

来源

[1] M.S. Copur,全球癌症研究状况 (2019),肿瘤学 33(5):181–185。

[2] K. Kourou,T.P. Exarchos,K.P. Exarchos 等人,机器学习在癌症预后和预测中的应用 (2015),计算和结构生物技术杂志 13:8–17。

[3] F. Wang 和 A. Preininger,AI in Health:the State of the Art,Challenges,and Future Directions (2019),国际医学信息学协会:医学信息学年鉴,16–26。

[4] J .德法乌,J.R .莱德萨姆,b .罗梅拉-帕雷德斯等,用于视网膜疾病诊断和转诊的临床适用深度学习 (2018),Nature Medicine 24(9):1342–1350。

[5] P .莫达德尔萨尼,s .优塞菲,m .阿姆加德等,利用卷积网络从组织学和基因组学预测癌症结局 (2018),PNAS 115(13):2970–2979。

预测股票价格的 ML 算法

原文:https://towardsdatascience.com/machine-learning-algorithm-to-predict-nasdaq-composite-index-price-27b4e3e1339?source=collection_archive---------22-----------------------

具有技术特征的回归分析

基础特征工程和监督 ML

作者图片

https://sarit-maitra.medium.com/membership

A 算法交易期望遵循规则,此外,它们可以形成客观、无偏见的风险估计,代表着金融艺术和理论的一场革命。

在这里,我们将看到机器学习如何解决预测的难题,即预测今天的价格和明天的价格(未知)之间的差异。

数据可以通过世界贸易数据提供的开放 API 加载。从 ML 的角度来看,金融时间序列问题是相当复杂的。我们需要更多地考虑金融数据结构,而不是像开盘价、最高价、最低价和收盘价这样的特定事件。

# Plot the Opening prices
dataset['Open'].plot(grid=True, figsize=(10, 6))
plt.title('Nasdaq Composite open price')
plt.ylabel('price ($)')
# Show the plot
plt.show()

让我们开始为分析准备数据。我将基于短窗口简单移动平均线创建一些特征。

  • 高/低百分比在市场中提供了一些百分比的波动性。
  • 百分比变化反映每日的百分比变化
  • 1 天窗口开放价格。
  • 当前日体积增量。
  • 当日成交量变化率。
  • 当日开盘价增量。
  • 公开价格。

现在,我们将相关属性保存在数据框中,这些属性在这里是预测变量。

我们没有丢弃所有的 NaN 值,而是用一些在数据集中被视为异常值的数字来代替 NaN。我们将尝试梯度增强树,它通常对异常值很健壮。

让我们定义我们的目标变量。我们将有一个分类变量,因为平均价格将在第二天上涨或下跌。因此,我们的目标是预测今天的价格和明天的价格之间的差异。

从下面的关联图中,我们可以看出,有些属性是相互关联的,可能不是模型所必需的。但是,我们将在稍后从梯度增强特征重要性图中识别这一点。

# Checking Correlation for easy understanding
sns.set(style='darkgrid', context='talk', palette='Dark2')
plt.figure(figsize=(14,5))
dataset.corr()['Open'].sort_values(ascending = False).plot(kind='bar')
plt.show()

我们的数据集总共有 5158 个样本和 10 个特征。我们使用了时序交叉验证器,它提供了训练/测试指数来分割以固定时间间隔观察的时序数据样本。在每次分割中,测试指数必须比以前高,因此在交叉验证器中进行洗牌是不合适的。

print('Total dataset has {} samples, and {} features.'.format(dataset.shape[0], dataset.shape[1]))X = (dataset.drop(['target'], 1))
y = (dataset['target'])
print(len(X), len(y))X = np.array(dataset.drop(['target', 'open1'], 1)) # dropping open
y = np.array(dataset['target'])#timeseries split
tscv = TimeSeriesSplit(max_train_size=None, n_splits=5)
for train_samples, test_samples in tscv.split(X):
  #print("TRAIN:", train_samples, "TEST:", test_samples)
  X_train, X_test = X[train_samples], X[test_samples]
  y_train, y_test = y[train_samples], y[test_samples]#separating features names
feature_names = ['ma1','ma2','ma3','HL','pct_change','vol_increment','open_increment','Open']X_train = pd.DataFrame(data=X_train, columns=feature_names)
X_test = pd.DataFrame(data=X_test, columns=feature_names)
print(X_train.shape, y_train.shape, X_test.shape, y_test.shape)

让我们将目标变量转换为二进制分类。价格值的正变化将被分类为 1,非正变化将被分类为 0。

y_train = pd.DataFrame(y_train) # converting to data frame
y_train.rename(columns = {0: 'target'}, inplace=True)
y_test = pd.DataFrame(y_test)
y_test.rename(columns = {0: 'target'}, inplace=True)
def getBinary(val):
  if val>0:
    return 1
  else:
    return 0
y_test_binary = pd.DataFrame(y_test["target"].apply(getBinary))

梯度推进回归:

我们将启动 XGB 回归器来测试模型。适应训练集

我们的模型准确率为 78.81%,可以预测未来 8 个交易日的每日价格变化(平均值)。

一旦构建了提升树,检索每个特征的重要性分数就变得相对容易和直接。这种重要性是为数据集中的每个属性明确计算的,允许对属性进行排序和相互比较。

形状特征重要性:

从特征重要性图中我们可以看出,并不是所有的特征对于算法的执行都是重要的;因此,我们可以仅用 4 个特征来运行算法,以获得相同的准确度分数。该模型可以被进一步训练,丢弃不相关的属性。

这是一个简单的模型,没有很大的复杂性,并且模型获得了相当不错的准确度。因此,我们可以看到,我们不再需要依赖人类产出的描述性统计,作为一种推理的松散证明。

我这里可以到达

机器学习算法和超参数选择的艺术

原文:https://towardsdatascience.com/machine-learning-algorithms-and-the-art-of-hyperparameter-selection-279d3b04c281?source=collection_archive---------13-----------------------

回顾四种优化策略

网格搜索、随机搜索、爬山和贝叶斯优化的超参数搜索

从智能手机到航天器,机器学习算法无处不在。他们告诉你明天的天气预报,从一种语言翻译成另一种语言,并建议你可能喜欢网飞的下一部电视剧。

这些算法根据数据自动调整(学习)它们的内部参数。然而,有一个参数子集是不知道的,必须由专家来配置。这样的参数通常被称为“超参数”——随着人工智能的使用增加,它们对我们的生活产生了很大的影响。

例如,决策树模型中的树深度和人工神经网络中的层数就是典型的超参数。模型的性能很大程度上取决于超参数的选择。对于中等深度的树,决策树可以产生良好的结果,而对于非常深的树,决策树的性能非常差。

如果我们想要手动运行,最佳超参数的选择更像是艺术而不是科学。事实上,超参数值的最佳选择取决于手头的问题。

由于算法、目标、数据类型和数据量从一个项目到另一个项目都有很大的变化,因此不存在适合所有模型和所有问题的单一最佳超参数值选择。相反,超参数必须在每个机器学习项目的上下文中进行优化。

在本文中,我们将首先回顾优化策略的威力,然后概述四种常用的优化策略:

  • 网格搜索
  • 随机搜索
  • 爬山
  • 贝叶斯优化

优化策略

即使专家具有深入的领域知识,手动优化模型超参数的任务也可能非常耗时。另一种方法是将专家放在一边,采用自动方法。根据一些性能度量来检测给定项目中给定模型的最优超参数集的自动过程被称为优化策略。

一个典型的优化过程定义了可能的超参数集和对于特定问题要最大化或最小化的度量。因此,在实践中,任何优化程序都遵循这些经典步骤:

1)将手头的数据分成训练和测试子集

2)重复优化循环固定次数或直到满足条件:

a)选择一组新的模型超参数

b)使用所选择的一组超参数在训练子集上训练模型

c)将模型应用于测试子集并生成相应的预测

d)使用适当的评分标准评估测试预测,如准确性或平均绝对误差。存储对应于所选超参数集的度量值

3)比较所有度量值,并选择产生最佳度量值的超参数集

问题是如何从步骤 2d 回到步骤 2a 进行下一次迭代;也就是说,如何选择下一组超参数,确保它确实比前一组好。我们希望我们的优化循环朝着一个合理的好的解决方案前进,即使它可能不是最优的。换句话说,我们希望合理地确定下一组超参数是对前一组的改进。

典型的优化过程将机器学习模型视为黑盒。这意味着在每一次迭代中,对于每一组选定的超参数,我们感兴趣的只是由选定的度量所度量的模型性能。我们不需要(想)知道黑盒里发生了什么样的魔法。我们只需要移动到下一个迭代,迭代下一个性能评估,等等。

所有不同优化策略中的关键因素是如何在步骤 2a 中选择下一组超参数值,这取决于步骤 2d 中先前的度量输出。因此,对于一个简化的实验,我们省略了黑盒的训练和测试,我们专注于度量计算(一个数学函数)和选择下一组超参数的策略。此外,我们用任意数学函数代替了度量计算,用函数参数代替了模型超参数集。

这样,优化循环运行得更快,并尽可能保持通用性。进一步的简化是使用只有一个超参数的函数,以便于可视化。下面是我们用来演示四种优化策略的函数。我们想强调的是,任何其他的数学函数也可以。

f(x)= sin(x/2)+0.5⋅sin(2⋅x)+0.25⋅cos(4.5⋅x)

这种简化的设置允许我们在简单的 x-y 图上可视化一个超参数的实验值和相应的函数值。x 轴是超参数值,y 轴是函数输出。然后,根据描述超参数序列生成中的点位置的白-红梯度,对(x,y)点着色。

白色点对应于过程中较早生成的超参数值;较红的点对应于随后在该过程中产生的超参数值。这种渐变着色将有助于稍后说明优化策略之间的差异。

在这个简化用例中,优化过程的目标是找到一个使函数值最大化的超参数。

让我们开始回顾四种常见的优化策略,这些策略用于为优化循环的下一次迭代确定新的超参数值集。

网格搜索

这是一个基本的蛮力策略。如果你不知道要尝试哪些价值观,你可以尝试所有的价值观。具有固定步长的范围内的所有可能值都用于函数评估。

例如,如果范围是[0,10]并且步长是 0.1,那么我们将得到超参数值序列(0,0.1,0.2,0.3,… 9.5,9.6,9.7,9.8,9.9,10)。在网格搜索策略中,我们计算每个超参数值的函数输出。因此,网格越细,我们就越接近最优,但也需要更多的计算资源。

图 1:使用步长 0.1 在[0,10]范围内对超参数值进行网格搜索。颜色梯度反映了生成的候选超参数序列中的位置。白色点对应于过程中早期生成的超参数值;红点对应于稍后生成的超参数值。

如图 1 所示,超参数的范围是从小到大扫描的。

网格搜索策略在单个参数的情况下可以很好地工作,但是当必须同时优化多个参数时,它变得非常低效。

随机搜索

对于随机搜索策略,顾名思义,超参数的值是随机选择的。在多个超参数的情况下,这种策略通常是优选的,并且当一些超参数比其他超参数对最终度量的影响更大时,这种策略特别有效。

同样,超参数值在范围[0,10]内生成。然后,随机生成固定数量 N 的超参数。要试验的预定义超参数的固定数量 N 允许您控制这种优化策略的持续时间和速度。N 越大,达到最优的概率越高,但所需的计算资源也越高。

图 2:在[0,10]范围内随机搜索超参数值。颜色梯度反映了生成的候选超参数序列中的位置。白色点对应于过程中早期生成的超参数值;红点对应于稍后生成的超参数值。

正如所料,来自生成序列的超参数值以不递减或递增的顺序使用:白点和红点在图中随机混合(图 2)。

爬山

每次迭代的爬山方法选择超参数空间中的最佳方向,以选择下一个超参数值。如果没有邻居改进最终度量,则优化循环停止。

注意,这个过程在一个重要方面不同于网格和随机搜索:下一个超参数值的选择考虑了先前迭代的结果。

图 3:在[0,10]范围内对超参数值的爬山搜索。颜色梯度反映了生成的候选超参数序列中的位置。白色点对应于过程中早期生成的超参数值;红点对应于稍后生成的超参数值。

图 3 显示了应用于我们函数的爬山策略从随机超参数值 x=8.4 开始,然后在 x=6.9 时向函数最大值 y=0.4 移动。一旦达到最大值,在下一个邻居中没有观察到度量的进一步增加,并且搜索过程停止。

这个例子说明了与这个策略相关的一个警告:它可能会陷入第二个最大值。从其他图中,我们可以看到全局最大值位于 x=4.0,对应的度量值为 1.6。这种策略不会找到全局最大值,而是陷入局部最大值。这种方法的一个好的经验法则是用不同的初始值运行多次,并检查算法是否收敛到相同的最大值。

贝叶斯优化

贝叶斯优化策略基于先前迭代中的函数输出选择下一个超参数值,类似于爬山策略。与爬山不同,贝叶斯优化着眼于过去的全局迭代,而不仅仅是最后一次迭代。

该程序通常有两个阶段:

  • 在称为预热的第一阶段,随机生成超参数值。在用户定义数量 N 的这种随机生成的超参数之后,第二阶段开始。
  • 在第二阶段,在每次迭代中,估计 P(输出|过去的超参数)类型的“替代”模型,以描述来自过去迭代的超参数值的输出值的条件概率。这个代理模型比原始函数更容易优化。因此,该算法优化了代理,并且建议代理模型的最大值处的超参数值也作为原始函数的最优值。第二阶段中的一部分迭代也用于探测最佳区域之外的区域。这是为了避免局部极大值的问题。

图 4:超参数值在[0,10]范围内的贝叶斯优化。颜色梯度反映了生成的候选超参数序列中的位置。白色点对应于过程中早期生成的超参数值;红点对应于稍后生成的超参数值。灰点是在策略的第一个随机阶段生成的。

图 4 展示了贝叶斯优化策略使用预热阶段来定义最有希望的区域,然后为该区域中的超参数选择下一个值。

你还可以看到,强烈的红色点聚集在最接近最大值的地方,而淡红色和白色的点分散在各处。这表明最佳区域的定义随着第二阶段的每次迭代而提高。

总结

我们都知道在训练机器学习模型时超参数优化的重要性。由于手动优化耗时且需要专业知识,我们探索了四种常见的超参数优化自动程序。

通常,自动优化程序遵循迭代程序,其中在每次迭代中,模型在一组新的超参数上被训练,并在测试集上被评估。最后,对应于最佳度量分数的超参数集合被选为最优集合。问题是如何选择下一组超参数,确保这实际上比前一组更好。

我们概述了四种常用的优化策略:网格搜索、随机搜索、爬山和贝叶斯优化。它们都有优点和缺点,我们通过在一个简单的玩具用例中说明它们是如何工作的来简要解释它们的区别。现在,您已经准备好在现实世界的机器学习问题中尝试它们了。

米莎·利索夫伊罗莎丽娅·西里波克尼梅

首发于 下期网页。

足球预测的机器学习算法

原文:https://towardsdatascience.com/machine-learning-algorithms-for-football-prediction-using-statistics-from-brazilian-championship-51b7d4ea0bc8?source=collection_archive---------3-----------------------

使用来自巴西锦标赛数据的统计数据

威利安·贾斯登·德·瓦斯康塞洛斯在 Unsplash 上拍摄的照片

摘要

本文基于真实比赛的真实数据,使用各种机器学习模型评估了巴西足球锦标赛中足球/英式足球结果(胜利、平局、失败)的预测。对模型进行递归测试,并比较平均预测结果。结果表明,逻辑回归和支持向量机产生了最好的结果,与其他分类器(KNN 和随机森林)相比,表现出优越的平均精度性能,具有 49.77%的精度(逻辑回归),比随机决策(基准)的 33%的成功机会好近 17%。此外,还对这些特征的相对重要性进行了排序,以指导数据的使用。

项目概述

足球/英式足球是一项在人们生活中非常普遍的运动,人们用来观看、玩耍和打赌。想想赌博,我们可以清楚地看到足球是一项非常不可预测的运动,它没有获得认真的研究来证明这一点。在英超 2015/2016 赛季,我们有一个非常意外的冠军,他们在赛季初争夺冠军的概率是一比五千

因此,这个项目的首要目标是创建一个有监督的机器学习算法,根据比赛的统计数据预测足球比赛的结果。这样就有可能评估预测的难易程度。

问题陈述

该项目旨在:

  • 网络刮痧机器人采集比赛的所有信息
  • 将所有赛季比赛的网页报废流程自动化
  • 创建一个受监督的机器学习模型来预测比赛结果
  • 评估模型

韵律学

在分类问题中,通常使用准确度作为评估标准。由于我们的结果预测是一个多类问题,因此没有必要使用其他指标。

准确度公式。来源:我在 github 上的代码

其中 TP 是真阳性,FP 是假阳性,TN 是真阴性,FN 是假阴性。

ETL 和数据探索

网络报废

然而,在探索收集的数据之前,了解这些信息是如何收集的是至关重要的。所以,这一部分将对整个数据库进行最后的分析处理。下面的第一个和第二个图像显示了如何显示收集数据的页面。所以步骤号Web-scrap 主页,挑选足球数据,并创建一个包含所有信息的数据框。

网页报废匹配页面。来源: FBREF

现在我们已经有了从比赛中挑选数据的代码,有必要创建另一个代码来收集所有赛季比赛的 URL,这样它将是一个自动化的机器人来完成这项任务。

赛季比赛:来源: FBREF

所有代码都将被附加到 Git 库

在数据清理干净并准备好用于分析之前,需要完成以下步骤:

  • 选择列:没有很多空值的选定列。
  • 问题:数据收集伴随着一些“问题”,因为所有玩家团队的统计数据的总和,所以需要将这些线从数据中排除。
  • 按比赛和球队分组:因为收集的数据来自比赛的球员,所以有必要将球员所在球队的所有统计数据按比赛和球队分组。
  • 追加结果:因为收集的数据来自玩家的表,它没有带来比赛的结果,所以需要创建一个代码将这个结果追加到数据框中。
  • 位置:有必要创建一个代码来显示哪个队在主场和客场比赛。

数据

现在是时候对收集的数据进行评估了,这样就有可能为结果创建一个预测模型。这些是我们清理过的数据的列:

列信息。来源:我在 github 上的代码

所有变量的含义:

  • 会议:匹配
  • 时间:团队
  • 数据:比赛日期
  • Gls:比赛中的进球数
  • Ast:助攻
  • PK:罚点球
  • PKatt:试图罚点球
  • 上海:镜头总数
  • 击中目标
  • 黄牌
  • 红色卡片
  • Crs:十字
  • 犯规次数
  • TklW:铲球获胜
  • Int:截取
  • Fld:犯规
  • OG:自己的目标
  • 关:越位
  • 比赛结果(胜利、失败、平局)
  • 地点:主场/客场
  • 火炬报:人群

观察:每场比赛都要为主队排一个队,为客队排一个队。

检查这些变量之间的相互关系是很好的,这样就创建了方法:攻击和防御。在代码中,它还提供了一个函数,该函数通过球队和比赛地点(主场/客场)来实现这种方法。

一般攻击数据。来源:我在 github 上的代码

对于攻击方法,选择了 4 个变量:“SoT”、“Sh”、“Gls”、“Torcida”。从数据中可以看出解决这个问题有多困难,因为我们找不到解决这个问题的模式。但它可能会猜测一些不同于通常的假设:

  • 高 Torcida(足球观众)可能与更大数量的进球无关。
  • 低 Torcida(足球观众)可能与高 SoT(击中目标)数量相关。

一般国防数据。来源:我在 github 上的代码

通过这些图表,可以看出我们的数据是如何关联的,各列是如何相互关联的,因此同时查看 3 个变量可以看出分离这些数据的难度。对于防御方法,选择了 4 个变量:“TklW”、“Fls”、“CrdY”、“Torcida”。在攻击分析中,也不可能在防御数据中找到任何模式。

然而,查看信息图中的列,可以得到的变量比图表中显示的要多。很明显,至少 17 个收集的变量可以影响比赛结果,因此也影响预测的性能。但是因为足球要复杂得多,需要更多的变量来预测比赛结果,所以在接下来的部分,会产生一些其他的变量。

方法学

数据预处理

因为在比赛结果出来之前不可能有比赛的统计数据,所以有必要在比赛之前创造一些新的变量。因此,为了解决这一困境,有必要为所有变量生成一个平均值,该平均值将包含相应游戏之前的所有游戏,通过这种方式,当一支球队在 9 月 18 日比赛时,代码将提供该游戏之前所有游戏可用的所有变量的平均值。

它将创建一些变量,试图向计算机显示每支球队在过去 5 场比赛、3 场比赛以及最后一场比赛中的得分顺序。对于每一场胜利,团队代码加 3 分,平局加 1 分,失败加 0 分。这样,就有可能看到团队是来自胜利、平局还是失败。

由于这些处理已经完成,人们找到了一种方法来通知机器比赛的“地点”。因为这个变量(地点)和由于锦标赛有 2 轮,第一轮可能是在一个球队的主场,如果第一轮锦标赛的第一场比赛是在他们的主场,第二场比赛必然是在他们的主场,或者换句话说,不是在他们的球场。在足球比赛中,这是一个非常重要的变量。因此,考虑这一变量的方法是:获取每场比赛主队(主场=主场)的所有数据和所有变量,然后用相同的数据集(相同的变量)减去客队(主场=客场)的数据。通过这种方式,有可能生成一个数据库,该数据库的数据基本上会说:

  • If Variables =负值:客队在过去的比赛中在该变量上的表现比客队/对手更好。这是有可能知道的,因为,例如:选择变量“平均射门数”,如果主队的值为 P,那么客队的值为 X,如果 P 高于 X,两者相减的输出值(主客场)将为正,否则如果 P 低于 X,该值将为负,表明该队在过去的比赛中在该变量上没有更好的表现。

概述:

  1. 问题:变量仅在比赛后可用,为了执行我们的模型,有必要在相应的比赛前获得所有数据特征数据,以便为该赛季的每个变量创建一个赛季平均值,并且为数据集的每个变量创建一些移动平均值。
  2. 问题:插入序列变量:这个问题是通过将球队在过去 3、5 场比赛以及最后一场比赛中的所有积分相加而解决的。每赢一场,球队加 3 分,平 1 分,输 0 分。
  3. 问题:向机器显示谁是主队,谁是客场队。为了解决这个问题,我们用每场比赛的客队变量结果减去主队变量结果。以这种方式显示主场球队是否在任何方面优于或劣于客队。

最终的数据库有 41 列 380 行,如下所示:

最终数据。来源:我在 github 上的代码

至此,我们的数据库终于得到了处理,现在可以运行一些模型并检查它们的性能了

履行

为了运行,我们删除了前四个变量,“Gls”变量也用于所有特性变量的 MinMaxScalar。正如在 Sklearn 上可以看到的,该估计器单独缩放和转换每个特征,使得它在训练集的给定范围内,例如在 0 和 1 之间。此外,使用了所有这 4 种模型:

  • 支持向量机:是一种监督学习模型,它总是旨在增加点之间的距离,以便可以对类进行分类,因此,SVM 分离数据,最大化类之间的间隔。
  • Random Forest: 顾名思义,Random Forest 创建了几个决策树,并将它们分组到一个树的“森林”中,在对树的每个节点进行分区时,对代表解释变量的列进行大小为 m 的 bootstrap 采样。最终决策投票将由分类问题的多数票(以及回归问题中的平均值)给出。
  • KNN: 是一个简单的模型,它基于距离度量的 k 个最近点的类别来执行分类。
  • Logistic 回归:基本上,Logistic 回归是一种多元线性回归,其结果使用 sigmoid 函数被“挤压”在区间[0,1]内。

为了运行所有这些模型,我们使用 scikit-learn 的库“训练测试分割”随机分割数据库。对于测试,使用了 30%的数据此外,对于所有四种型号,该算法被随机播放了 1000 次、。通过这种方式,可以检查所有模型的标准偏差和准确性。所有模型都使用了缺省值,没有探究每个特定模型的参数。

结果

模型评估和验证

从下表中可以看出,结果并不明显。该算法实现了几乎 50%的准确性,但是,考虑到成功的随机预测概率为 33%(胜利/平局/失败),这是一个好信号,表明该算法毕竟能够识别一些模式。

平均值和标准偏差。来源:我在 github 上的代码

经过 1000 次后, Logistic 回归的结果最好, 在所有四个模型中标准差率最低,准确率最高。SVM 比其他人表现得更好,但具有最高的标准差,这可能表明该模型往往比其他模型变化更大。还使用随机森林特征重要性创建了特征排名。从下图中可以看出,最近 3 场比赛的足球比赛观众、黄牌号码以及整个赛季的足球比赛观众对预测结果的影响更大。

功能排名。来源:我在 github 上的代码

正当理由;辩解

看到逻辑回归比其他模型表现得更好很奇怪,主要是因为正如我们所见,数据显然没有模式,这是一个复杂的问题,令人惊讶的是,一个非常复杂的问题通过“线性”方法解决了,这可能是最简单的方法。其中一个原因可能是因为每个模型的参数,而这些参数在这种方法中没有被研究。因为 SVM 有很多内核,尝试不同的内核可能是一个解决方案,以达到这个模型更好的性能。另一个奇怪的地方是“点数序列”是干扰预测的最后变量之一。就我而言,这个变量不应该被忽略,也许有更多的方式向机器显示这些模式。

结论

反射

本文证明了足球预测仍然是一项非常艰巨的任务,它仍然需要更多的变量来帮助预测结果。然而,通过这篇文章我们可以看到,机器学习算法已经可以“思考”哪支球队下注,并且仍然可以比不知道比赛的人更准确,当与随机预测的概率相比时,在预测中具有近 17%的优势。

改进

对于未来,我建议调查并找到更多有用的变量,例如伤病,或每支球队球员的更多细节,也许国际足联或职业进化游戏数据可以帮助带来更多的信息。未来可以做的另一件事是预测每支球队的进球数,这更复杂,因为这取决于预测的结果,他们必须与之协调,例如,如果结果被预测为主队的胜利,主队不可能有两个进球,客场队也不可能有两个进球。因此,也许这篇文章可以成为未来创建更好更复杂模型的灵感来源。

用 Python 从头到尾的机器学习算法:KNN

原文:https://towardsdatascience.com/machine-learning-algorithms-from-start-to-finish-in-python-knn-7a92cce47986?source=collection_archive---------42-----------------------

布莱克·惠勒在 Unsplash 上拍摄的照片

机器学习从业者工具箱中的一个基本算法必须是 K 个最近邻(或简称为 KNN)。虽然它可能是最简单的算法之一,但它也是一种非常强大的算法,并在许多现实应用中使用。在本教程中,我将执行以下操作:

  • 解释 KNN 算法及其工作原理
  • 使用 Python 从头开始实现它

所以,事不宜迟,让我们开始这场机器学习派对吧!

k 最近的邻居解释说

这是一种常见的机器学习算法,可用于分类和回归。该算法采取的步骤如下:

图片来自维基百科

  1. 首先,它将一组特征和标签作为输入,使其成为一种监督学习算法。
  2. 除了特性和标签,它还接受一个n _ neighbors参数。
  3. 为了预测新样本的类别,它执行以下操作:
  • 测量新样本和第 N 个最近样本之间的距离(由N _ neighbors参数指定)
  • 基于其最近的邻居,它将基于多数投票对样本进行分类。具体地,如果有 3 个邻居,其中 2 个邻居属于 A 类,1 个邻居属于 B 类,那么它将把新样本分类为 A 类

为了填补你的知识空白,让我们来看一个具体的例子。

照片由乌韦·桑切斯Unsplash 上拍摄

让我们假设以下情况:

  • 你试图根据血型、身体质量指数等来预测一个病人是否患有心脏病。
  • 您已经为训练和验证分离了数据集
  • 你已经缩放了你的特征(我稍后会讨论这一点)
  • 你已经有了 fir KNN 算法,并且已经将n _ neighbors参数设置为 3

如果您要向实例提供验证集,将会发生以下情况:

  1. 该算法将使用距离度量来测量新实例和其他训练集实例之间的距离(我稍后也会讨论这一点!)
  2. 基于n _ neighbors参数(在本例中,该参数被设置为 3),它将使用与新样本最接近的三个例子来对新点进行分类
  3. 然后它将进行投票,哪个类拥有最多的票数就是新样本所属的类。具体来说:
  • 如果两个最接近的类别被标记为 1(患有心脏病),一个被标记为 0(没有心脏病),则新样本将被预测为在类别 1 中

4.对测试集中的所有实例重复这个过程

清理一些 KNN 行话

梁杰森Unsplash 上拍照

距离度量

这是用于计算两点之间距离的度量。它通常是欧几里德距离,由以下公式给出:

图片来自维基百科

特征缩放

这是许多机器学习算法的重要预处理步骤,尤其是那些使用距离度量和计算的算法(如我们的朋友 KNN)。它基本上缩放了我们的特征,使它们在相似的范围内。把它想象成一栋房子,一栋房子的比例模型。两者的形状相同(都是房子),但是大小不同(5m!= 500m)。我们这样做的原因如下:

  1. 它加速了算法
  2. 有些算法对规模很敏感。换句话说,如果特征具有不同的比例,则具有较高量值的特征有可能被赋予较高的权重。这将影响机器学习算法的性能,显然,我们不希望我们的算法偏向一个特征。

为了证明这一点,让我们假设我们有三个特性,分别命名为 A、B 和 C:

  • 缩放前 AB 的距离= >

照片由分析公司 Vidhya 拍摄

  • 缩放前 BC 的距离= >

照片由分析公司 Vidhya 拍摄

  • 缩放后 AB 的距离= >

照片由分析公司 Vidhya 拍摄

  • 缩放后 BC 的距离= >

照片由分析公司 Vidhya 拍摄

我们可以清楚地看到,这些特性比缩放之前更具可比性,也更公正。如果你想要一个关于功能缩放的很棒的教程,请查看这个由分析 Vidhya 撰写的[博客](http://Photo by Analytics Vidhya)。

选择 n_neighbors 参数

虽然没有预先确定的方法来选择最佳数量的邻居,但确实存在一些方法。一种流行的方法叫做肘方法,运行一个循环,将数据拟合到一系列相邻值。如果您要根据邻居的数量绘制误差图,您的图将如下所示:

作者照片

通常,最佳点将是弯头快速减少其误差的点(因此在我们的例子中,可能是 5 或 6)。这种方法的问题如下:

  • 过度适应测试集是可能的,所以要确保交叉验证。
  • 有时,K 的最佳数量可能不是很清楚,因此可能很难判断什么是真正的最佳数量

在实现 KNN 时,一个很好的技巧是将 K 设置为奇数。这样,就不需要处理票数相等的情况。

从技术角度了解代码

知道如何使用像 scikit 这样的 ML 库是很好的——学习编码算法,但是真正能提升你的 ML 技能的是学习如何从头开始构建算法。因此,我们将这样做;从头开始创建 KNNClassifier!

照片由 redcharlieUnsplash 上拍摄

注意:代码的链接可以在这里找到,但是我建议你在检查代码之前浏览一下博客文章,以完全理解正在发生的事情。

首先,让我们导入我们的库:

import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from collections import Counteriris = load_iris()
X, y = iris.data, iris.target

是的,我们导入 scikit-learn 的唯一原因是使用 iris 数据集并分割数据。除此之外,我们使用普通的数字和集合!

接下来,让我们创建我们的训练和测试集:

X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=1810)

这里没什么不寻常的,所以让我们快速前进。

现在,我提到特征缩放是 KNN 的一个重要的预处理步骤。然而,我们的数据已经在一个相似的范围内,所以我们可以跳过这一步。然而,在现实世界的数据中,我们很少能如此幸运。

使用面向对象的方法编码算法

干净和可重用的代码对任何数据科学家或机器学习工程师来说都是关键。因此,为了遵循软件工程原则,我将创建一个 KNN 类,使代码可重用且保持原样。

首先,我们定义类名,并传入一些参数。即,

  • x(特性)
  • y(标签向量)
  • n_neighbors(我们希望的邻居数量)
class KNN:
    def __init__(self,X,y,n_neighbors=3):
        self.X = X
        self.y = y
        self.n_neighbors = n_neighbors

接下来,我们将上面的欧几里德距离公式转换成代码,并使其成为类的方法:

def euclidean(self,x1,x2):
        return np.sqrt(np.sum((x1 - x2) ** 2))

现在是举重。我将首先向您展示代码,然后解释发生了什么:

def fit_knn(self,X_test):
        distances = [self.euclidean(X_test,x) for x in X_train]
        k_nearest = np.argsort(distances)[:self.n_neighbors]
        k_nearest_labels = [y_train[i] for i in k_nearest]

        most_common = Counter(k_nearest_labels).most_common(1)[0][0]
        return most_common

我们首先创建一个名为 fit_knn 的方法,该方法可以将 knn 拟合到数据中!更具体地说,正在开展以下工作:

  1. 测量测试集中的每个数据点到训练集中的数据点之间的距离
  2. 我们得到 K 个最近的点(K 是我们的邻居数量的参数,在我们的例子中是 3)
  3. 之后,代码返回我们发现最接近新测试集实例的最近邻居的标签。
  4. 最常见的类由方法计数并返回

最后,最重要的是,我们做出预测:

knn = KNN(X_train,y_train)preds = knn.predict(X_test)

现在,让我们评估我们的模型,看看它对新样本的分类效果如何:

accuracy = (preds == y_test).mean()OUT: 1.0

所以,完整的代码如下:

import numpy as np
from collections import Counter
from sklearn.datasets import load_irisiris = load_iris()
X, y = iris.data, iris.targetX_train,X_test,y_train,y_test = train_test_split(X,y,random_state=1810)class KNN:
    def __init__(self,X,y,n_neighbors=3):
        self.X = X
        self.y = y
        self.n_neighbors = n_neighbors

    def euclidean(self,x1,x2):
        return np.sqrt(np.sum((x1 - x2) ** 2))

    def fit_knn(self,X_test):
        distances = [self.euclidean(X_test,x) for x in X_train]
        k_nearest = np.argsort(distances)[:self.n_neighbors]
        k_nearest_labels = [y_train[i] for i in k_nearest]

        most_common = Counter(k_nearest_labels).most_common(1)[0][0]
        return most_common

    def predict(self,X_test):
        preds = [self.fit_knn(x) for x in X_test]
        return predsknn = KNN(X_train,y_train)
preds = knn.predict(X_test)accuracy = (preds == y_test).mean()

要做的其他任务:

  1. 尝试使用 n_neighbors 参数。什么变化?
  2. 尝试缩放您的要素,看看结果是否不同。好点了吗?或者更糟?
  3. 尝试将模型拟合到不同的数据集。看看改变 K 如何改变结果
  4. 看看您是否可以自己实现肘方法来确定最佳邻居数量

非常感谢您阅读本文。我希望你学到了新的东西,或者至少刷新了你的记忆。现在,那是很久了!所以,我对你的最后一个愿望是,休息一下,休息一下,享受生活!

简·廷伯格在 Unsplash 上拍摄的照片

Python 中从头到尾的机器学习算法:线性回归

原文:https://towardsdatascience.com/machine-learning-algorithms-from-start-to-finish-in-python-linear-regression-aa8c1d6b1169?source=collection_archive---------21-----------------------

学习、理解和实现所有数据科学和机器学习中最重要和最基本的算法。

朱利安·埃伯特在 Unsplash 上拍摄的照片

线性回归可能是最常见的算法之一,是机器学习从业者必须知道的。这通常是初学者第一次接触真正的机器学习算法,了解它在更深层次上的运行方式对于更好地理解它至关重要。

所以,简单来说,我们把真题分解一下;什么真的线性 回归

线性回归定义

线性回归是一种监督学习算法,旨在采用线性方法对因变量和自变量之间的关系进行建模。换句话说,它旨在拟合一条线性趋势线,该趋势线能够最好地捕捉数据的关系,并且,根据这条线,它可以预测目标值可能是多少。

图片来自维基百科

太好了,我知道这个定义,但是它到底是如何工作的呢?很棒的问题!为了回答这个问题,让我们一步一步地看看线性回归是如何运作的:

  1. 趋势线符合数据(如上图所示)。
  2. 计算点之间的距离(图上的红点是点,绿线是距离),然后平方,然后求和(值被平方以确保负值不会产生不正确的值并妨碍计算)。这是算法的错误,或者更好地称为残差
  3. 存储迭代的残差
  4. 基于优化算法,**线被轻微“移位”,以便该线可以更好地拟合数据。
  5. 重复步骤 2-4,直到达到期望的结果,或者残余误差已经减小到零。

这种拟合直线的方法被称为最小二乘法。**

线性回归背后的数学

注意:请随意跳过这一部分,因为不幸的是,它确实含有一些看起来很奇怪的乳胶。但是,如果你想真正明白是怎么回事,我建议冒险来一块饼干,继续看下去!

安托万·道特里在 Unsplash 上拍摄的照片

线性回归算法如下:

作者照片

可以简称为:

作者照片

下面的算法将基本上完成以下工作:

  1. 取一个 Y 向量(你的数据的标签,(房价,股票价格,等等..))

作者照片

这是你的目标向量,稍后会用它来评估你的数据(稍后会详细介绍)。

2.取一个矩阵 X(数据的特征):

作者照片

这是你的数据的特征,即年龄,性别,性别,身高等。这是算法将实际用来进行预测的数据。请注意特征 x0 是如何出现的。这被称为你的截距项,并且总是等于 1。

3.取权重的向量,并转置它们:

作者照片

作者照片

这是算法的神奇之处。所有的特征向量都会乘以这些权重。这被称为点积。本质上,您将试图为给定的数据集找到这些值的最佳组合。这就是所谓的优化。

4.得到一个输出向量:

作者照片

这是从数据中输出的预测向量。然后,您可以通过使用成本函数来评估模型的性能。

这基本上是数学上表示的整个算法。现在,您应该对线性回归的工作原理有了很好的理解。但问题是,什么是一个 优化 算法 ?而我们如何挑选 最优权重 ?而我们如何评价的表现呢?**

成本函数

成本函数本质上是一个衡量损失的公式,或模型的“成本”。如果你曾经参加过任何 Kaggle 比赛,你可能会遇到一些。一些常见的包括:

  • 均方误差
  • 均方根误差
  • 绝对平均误差

这些函数对于模型训练和开发是必不可少的,因为它们回答了“我的模型预测新实例的能力如何?”。请记住这一点,因为这与我们的下一个主题有关。

优化算法

优化通常被定义为改进某样东西的过程,以使其发挥最大潜力。这也适用于机器学习。在 ML 的世界中,优化本质上是试图为某个数据集找到最佳的参数组合。这本质上是机器学习的“学习”部分。

虽然存在许多优化算法,但我将讨论其中最常见的两种:梯度下降和正规方程。

梯度下降

梯度下降是一种优化算法,旨在找到一个函数的最小值。它通过在斜率的负方向迭代地采取步骤来实现这个目标。在我们的例子中,梯度下降通过移动函数切线的斜率来不断更新权重。好极了,听起来很棒。请说英语。😃

梯度下降的一个具体例子

卢卡斯·克拉拉在 Unsplash 上的照片

为了更好地说明梯度下降,让我们通过一个简单的例子。想象一个人在山顶,他/她想到达山下。他们可以做的是环顾四周,看看他们应该朝哪个方向迈步,以便更快地下来。然后,他们可能会朝那个方向迈出第,现在他们离目标更近了。然而,他们下来时必须小心,因为他们可能会在某个点卡住,所以我们必须确保相应地选择步长。

类似地,梯度下降的目标是最小化一个函数。在我们的案例中,是为了最小化我们模型的成本。这是通过找到函数的切线并向那个方向移动来实现的。算法的“步骤的大小由所谓的学习率来定义。这基本上控制了我们向下移动的距离。有了这个参数,我们必须小心两种情况:

  1. 学习率太大,算法可能不收敛(达到最小值)并在最小值附近跳动,但永远不会收敛
  2. 学习率太小,算法将花费太长时间达到最小值,还可能“卡”在次优点。

我们还有一个参数来控制算法在数据集上迭代的次数。

从视觉上看,该算法会做这样的事情:

图片来自维基百科

因为这种算法对机器学习来说非常重要,所以让我们来回顾一下它的作用:

  1. 随机初始化权重。这叫做(你猜对了)随机初始化
  2. 然后,该模型使用这些随机权重进行预测。
  3. 模型的预测通过成本函数进行评估。
  4. 然后,模型运行梯度下降,通过找到函数的切线,然后在切线的斜率中采取一个步骤
  5. 该过程重复 N 次迭代,或者如果满足标准。

梯度下降的优点和缺点

优势:

  1. 很可能将成本函数降低到全局最小值(非常接近或= 0)
  2. 最有效的优化算法之一

缺点:

  1. 在大型数据集上可能会很慢,因为它使用整个数据集来计算函数切线的梯度
  2. 容易陷入次优点(或局部最小值)
  3. 用户必须手动选择学习速率和迭代次数,这可能很耗时

既然已经介绍了梯度下降,那就来介绍法线方程吧。

正态方程

如果我们回到我们的例子,而不是采取步骤反复下山,我们将能够立即到达底部。法线方程就是这种情况。它利用线性代数来产生权重,可以在很短的时间内产生与梯度下降一样好的结果。

法线方程的优点和缺点

优势

  1. 不需要选择学习率或迭代次数
  2. 极快

不足之处

  1. 无法很好地扩展到大型数据集
  2. 倾向于产生良好的权重,但不是最佳的权重

咻,好多东西要消化!我建议你在继续前进之前休息一下,喝杯咖啡

照片由海伦娜·洛佩斯Unsplash 上拍摄

特征缩放

这是许多机器学习算法的重要预处理步骤,尤其是那些使用距离度量和计算的算法(如线性回归和梯度下降)。它基本上缩放了我们的特征,使它们在相似的范围内。把它想象成一栋房子,一栋房子的比例模型。两者的形状相同(都是房子),但是大小不同(5m!= 500m)。我们这样做的原因如下:

  1. 它加速了算法
  2. 有些算法对规模很敏感。换句话说,如果特征具有不同的比例,则具有较高量值的特征有可能被赋予较高的权重。这将影响机器学习算法的性能,显然,我们不希望我们的算法偏向一个特征。

为了证明这一点,让我们假设我们有三个特性,分别命名为 A、B 和 C:

  • 缩放前 AB 的距离= >

****

照片由分析公司 Vidhya 拍摄

缩放前 BC 的距离= >

****

照片由分析公司 Vidhya 拍摄

缩放后 AB 的距离= >

****

照片由分析公司 Vidhya 拍摄

缩放后 BC 的距离= >

****

照片由分析公司 Vidhya 拍摄

我们可以清楚地看到,这些特性比缩放之前更具可比性,也更公正。如果你想要一个关于功能扩展的很棒的教程,请查看这篇由 Analytics Vidhya 撰写的博客文章

咻!这需要吸收大量的信息。所以,我建议你休息一下,喝杯咖啡,享受生活,当你觉得,准备好了,你就可以从头开始编写这个算法了。

从头开始编码线性回归

克里斯·里德在 Unsplash 上拍摄的照片

好了,现在是你一直在等待的时刻;实施!事不宜迟,我们开始吧!

****注意:所有代码都可以从这个 Github repo 下载。但是,我建议您在这样做之前先跟随教程,因为这样您会对您实际编码的内容有更好的理解!

首先,让我们做一些基本的导入:

**import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_boston**

是的,那是所有的进口货!我们使用 numpy 进行数学实现,使用 matplotlib 绘制图形,使用来自 scikit-learn 的波士顿数据集。

接下来,让我们加载数据并定义我们的特征和标签:

**# Load and split data
data = load_boston()
X,y = data['data'],data['target']**

接下来,让我们创建一个自定义的 train_test_split 函数,将我们的数据分成一个训练集和测试集:

**# Custom train test split
def train_test_divide(X,y,test_size=0.3,random_state=42):
    np.random.seed(random_state)
    train_size = 1 - test_size
    arr_rand = np.random.rand(X.shape[0])
    split = arr_rand < np.percentile(arr_rand,(100*train_size))

    X_train = X[split]
    y_train = y[split]
    X_test =  X[~split]
    y_test = y[~split]

    return X_train, X_test, y_train, y_testX_train,X_test,y_train,y_test = train_test_divide(X,y,test_size=0.3,random_state=42)**

基本上,我们只是

  1. 进入测试尺寸。
  2. 设置随机种子以确保我们的结果是可重复的。
  3. 基于测试集大小获得训练集大小
  4. 从我们的特征中随机选取样本
  5. 将随机选择的实例分成训练集和测试集

我们的成本函数

我们将实现 MSE 或均方误差,这是一种用于回归任务的常见成本函数:

作者照片

**def mse(preds,y):
        m = len(y)
        return 1/(m) * np.sum(np.square((y - preds)))**
  • 我指的是训练样本的数量
  • 引用我们标签向量中的单个实例
  • preds 指的是我们的预测

为了制作干净、可重复和高效的代码,以及遵守软件开发惯例,我们将制作创建一个线性回归类:

**class LinReg:
    def __init__(self,X,y):
        self.X = X
        self.y = y
        self.m = len(y)
        self.bgd = False**
  • bgd 布尔值是一个参数,它定义了我们是否应该使用批量梯度下降。

我们现在将创建一个添加截取项的方法:

**def add_intercept_term(self,X):
        X = np.insert(X,1,np.ones(X.shape[0:1]),axis=1).copy()
        return X**
  • 这基本上是在我们的特性的开头插入一个列。
  • 如果我们不加上这一点,那么我们将迫使超平面通过原点,导致它倾斜相当大,因此不能正确拟合数据。

我们现在将扩展我们的功能:

作者照片

**def feature_scale(self,X):
        X = (X - X.mean()) / (X.std())
        return X**

接下来,我们将随机初始化权重:

**def initialise_thetas(self):
        np.random.seed(42)
        self.thetas = np.random.rand(self.X.shape[1])**

我们现在将使用以下公式从头开始编写法线方程:

作者照片

**def normal_equation(self):
        A = np.linalg.inv(np.dot(self.X.T,self.X))
        B = np.dot(self.X.T,self.y)
        thetas = np.dot(A,B)
        return thetas**

本质上,我们将算法分为 3 个部分:

  1. 我们得到 X 转置和 X 的点积的倒数
  2. 我们得到重量和标签的点积
  3. 我们得到两个计算值的点积

所以,这就是正规方程!不算太差!现在,我们将使用以下公式实现批量梯度下降:

作者照片

**def batch_gradient_descent(self,alpha,n_iterations):
        self.cost_history = [0] * (n_iterations)
        self.n_iterations = n_iterations

        for i in range(n_iterations):
            h = np.dot(self.X,self.thetas.T)
            gradient = alpha * (1/self.m) * ((h - self.y)).dot(self.X)

            self.thetas = self.thetas - gradient
            self.cost_history[i] = mse(np.dot(self.X,self.thetas.T),self.y)

        return self.thetas**

在这里,我们执行以下操作:

  1. 我们接受 alpha,或者学习率,和迭代次数
  2. 我们创建一个列表来存储我们的成本函数历史,以便稍后绘制成线图
  3. 我们遍历数据集 n 次迭代,
  4. 我们获得预测,并计算梯度(函数切线的斜率)。这被称为 h(x)
  5. 我们通过从实际值中减去我们的预测值并乘以每个特征来更新权重,以沿梯度向下移动
  6. 我们使用自定义的 MSE 函数记录这些值
  7. 重复,完成后,返回我们的结果

让我们定义一个拟合函数来拟合我们的数据:

**def fit(self,bgd=False,alpha=0.158,n_iterations=4000):
        self.X = self.add_intercept_term(self.X)
        self.X = self.feature_scale(self.X)
        if bgd == False:

            self.thetas = self.normal_equation()
        else:
            self.bgd = True
            self.initialise_thetas()
            self.thetas = self.batch_gradient_descent(alpha,n_iterations)**

这里,我们只是检查用户是否想要梯度下降,并相应地执行我们的步骤。

让我们构建一个函数来绘制成本函数:

**def plot_cost_function(self):

        if self.bgd == True:
            plt.plot(range((self.n_iterations)),self.cost_history)
            plt.xlabel('No. of iterations')
            plt.ylabel('Cost Function')
            plt.title('Gradient Descent Cost Function Line Plot')
            plt.show()
        else:
            print('Batch Gradient Descent was not used!')**

最后是预测未标记实例的方法:

**def predict(self,X_test):
        self.X_test = X_test.copy()
        self.X_test = self.add_intercept_term(self.X_test)
        self.X_test = self.feature_scale(self.X_test)
        predictions = np.dot(self.X_test,self.thetas.T)
        return predictions**

现在,让我们看看哪个优化产生了更好的结果。首先,让我们试试梯度下降:

**lin_reg_bgd = LinReg(X_train,y_train)
lin_reg_bgd.fit(bgd=True)mse(y_test,lin_reg_bgd.predict(X_test))OUT:
28.824024414708344**

让我们绘制我们的函数,看看成本函数如何降低,如果梯度下降收敛:

作者照片

因此,我们可以看到,在大约 1000 次迭代时,它开始收敛。

现在是正常方程:

**lin_reg_normal = LinReg(X_train,y_train)
lin_reg_normal.fit()mse(y_test,lin_reg_normal.predict(X_test))OUT:
22.151417764247284**

所以我们可以看到,正常方程略优于梯度下降。这可能是因为数据集很小,我们没有为学习率选择最佳参数。

活动

  1. 尽量大幅度提高学习率。会发生什么?
  2. 不应用要素缩放。有区别吗?
  3. 尝试研究,看看你是否能实现一个更好的优化算法。在测试集上评估您的模型

写这篇文章真的很有趣,虽然有点长,但我希望你今天学到了一些东西。敬请期待,继续阅读!

乔纳森·肯珀在 Unsplash 上拍摄的照片

Python 中从头到尾的机器学习算法:逻辑回归

原文:https://towardsdatascience.com/machine-learning-algorithms-from-start-to-finish-in-python-logistic-regression-5a62e3495318?source=collection_archive---------31-----------------------

探索基本分类模型背后的真实情况,并使用 Python 从头构建一个分类器。

照片由德鲁·比默Unsplash 上拍摄

对于任何即将到来的数据科学家或机器学习实践者来说,逻辑回归本质上是一个必须知道的知识。这很可能是人们遇到的第一个分类模型。但是,问题是, 怎么 真的管用吗?它有什么作用? 为什么 是用来分类的?在这篇文章中,我希望能回答所有这些问题,当你读完这篇文章时,你将会:

  1. 学习如何用简单的语言解释逻辑回归模型
  2. 了解逻辑回归的数学形式
  3. 使用 Python 从头实现逻辑回归

所以,准备好迎接前方的狂野冒险吧,伙伴!

塞巴斯蒂安·赫尔曼在 Unsplash 上拍摄的照片

逻辑回归模型解释了

逻辑回归是一种统计模型,它使用逻辑函数来预测某个实例属于某个特定类的概率。如果估计的概率大于 50%,则模型预测该实例属于正类(1)。如果不超过 50%,那么模型预测属于负类。逻辑回归用于以下情况

  • 一个病人到底有没有乳腺癌?
  • 学生能通过考试吗?
  • 给定的图像是否合适?
  • 这个信用卡交易是诈骗交易还是正常交易?

所有这些都是可以使用逻辑回归的例子。嗯,太好了!现在你知道如何定义什么是逻辑回归,并解释它做什么。但问题是,如何运作,循序渐进?为了解释这一点,我们将比较逻辑回归和线性回归!

通过线性回归理解逻辑回归

在我的上一篇文章中,我解释了线性回归;它如何工作,做什么以及如何实现。在许多方面,逻辑回归与线性回归非常相似。因此,让我们简要总结一下线性回归的作用:

  1. 线性趋势线或超平面适合数据
  2. 计算点之间的距离(图上的红点是点,绿线是距离),然后平方,然后求和(值被平方以确保负值不会产生不正确的值并妨碍计算)。这是算法的误差,或者更好地称为残差。**

3.然后,我们使用一种优化算法(稍后将详细介绍)来“改变”该算法,使其能够基于成本函数更好地拟合数据

4.重复步骤 2 + 3,直到我们达到理想的输出,或者我们的误差接近 0。

图片来自维基百科

在逻辑回归中,情况非常相似,但也有一些不同:

  1. 逻辑回归预测一个离散值* (0 或 1),而线性回归用于预测连续值 (245.6,89.6 等..)*
  2. 它不是拟合数据的趋势线,而是拟合数据的 S 形曲线,称为逻辑函数。这条曲线的范围从 0 到 1,告诉你一个类为正(1)或负(0)的概率。
  3. 该模型的残差计算不适用于逻辑回归,这一点我们将在以后研究逻辑回归的细节时发现。因此,它也不使用与线性回归相同的成本函数

好了,现在你知道什么是逻辑回归了(用外行人的话来说),这是对它的功能和操作步骤的高度概括。但我肯定你有一些问题,比如:

  • 为什么 Logistic 回归叫* Logistic 回归,而不是 Logistic 分类?*
  • 什么是成本函数?为什么使用线性回归和逻辑回归时会有所不同?
  • 什么是优化算法

我向你保证,现在,你所寻求的一切都会得到满足!

在我们继续之前,清理一些基本的统计数据

注意:现在,这些概念可能看起来不相关,但请耐心听我说,因为这些概念构成了逻辑回归的基础,将有助于您更好地理解算法。

马库斯·斯皮斯克在 Unsplash 上的照片

  • 几率:某事发生与某事未发生的比率。例如,让我们假设洛杉矶湖人队打了 13 场比赛,赢了 5 场,输了 8 场。那么,湖人赢得下一场比赛的几率将是发生的事情(湖人赢)和没有发生的事情(湖人输)的比率。所以,在这个例子中,他们赢的几率是 5/8。
  • 概率:某件事情发生与所有可能发生的事情的比率。回到我们湖人的例子,湖人赢得下一场比赛的概率是发生的事情(湖人获胜)与可能发生的事情(湖人输赢)的比率。所以,概率是 5/13。

我们已经看到了一种计算赔率的方法,但是我们也可以使用下面的公式根据概率计算赔率:

作者照片

其中 p =某事发生的概率。为了验证这一点,让我们试着用这个公式看看我们是否能得到湖人获胜的几率:

作者照片

果然,我们得到了同样的结果!

赔率的问题

回到我们的例子,让我们假设湖人队经历了一个糟糕的赛季(显然不是这样),在 20 场比赛中,他们只赢了 1 场。所以湖人获胜的几率是:

作者照片

如果他们在整个赛季中打得比 T8 更差,并且在 100 场比赛中赢了 2 场,那么他们获胜的几率将是:

作者照片

我们可以做一个简单的观察:他们打得越差,他们的胜算就越接近于 0。具体来说,当他们赢的几率为时,那么几率将在 0 和 1 之间。**

现在我们来看反面。如果湖人打 20 场比赛,赢 19 场,那么他们的胜算是:

作者照片

如果他们玩 200 场游戏,赢了 194 场,那么他们赢的几率是:

作者照片

换句话说,当湖人获胜的几率是 1 时,他们可以一直到无穷大。

显然,这里有一个问题。湖人获胜的几率从 0 到 1 不等,但是他们获胜的几率从 1 到无穷大不等。这种不对称使得很难比较湖人获胜的可能性。如果我们有一个函数能让一切都对称就好了…

介绍 Logit 函数

Eduardo Flores 在 Unsplash 上拍摄的照片

幸运的是,这个函数确实存在!它被称为概率的对数函数、对数。本质上,它输出了赔率的…日志!

让我们再次用湖人队的例子来证明这一点(对不起!).如果湖人要打 7 场比赛,并且只赢一场,他们获胜的几率将会是:

作者照片

如果他们赢了 6 场比赛,只输了 1 场:

作者照片

使用对数(赔率),离原点的距离等于 1 比 6,或 6 比 1。这个 logit 函数对于理解是至关重要的,因为它构成了逻辑回归的基础。如果你仍然不确定什么是赔率和日志(赔率),看看 Statquest 的这个伟大的视频

逻辑回归背后的“回归”

好了,伙计们,我正式向你们扔炸弹了:

Jens JohnssonUnsplash 上拍摄的照片

逻辑回归(就其本身而言)不是一种分类算法。它实际上是一个回归模型(因此得名 Logistic 回归)!怎么会?好了,事不宜迟,让我们深入研究一下逻辑回归模型。

深入研究逻辑回归

逻辑回归实际上是广义线性模型(GLM)的一部分,该模型最初是由约翰·内尔德和罗伯特·威德伯恩创建的。线性回归的响应值来自,而逻辑回归的响应值来自 二项分布 (值为 0 和 1)。**

逻辑回归是一种特殊类型的 GLM,它可以通过使用链接函数使与响应变量相关联,并允许每个测量值的方差大小是其预测值的函数,从而推广线性回归。(来源)。

基本上,逻辑回归是一种 GLM,通过使用 logit 链接函数输出值 0 和 1,并可以使用特殊的成本函数来计算模型的方差。

现在,你一定对这一切是如何运作的感到难以置信,但是现在跟着我,它很快就会有意义。

逻辑回归如何工作第 1 部分:理论

正如我们之前讨论的,理论上,线性回归的 y 轴值(或目标值)可以是从-无穷大到+无穷大范围内的任何数字。

但是,在逻辑回归中,y 轴值的范围仅在 0 和 1 之间。

所以,为了解决这个问题,y 轴值从 X 发生的概率转换成…某事发生的 log(odds)!现在,值的范围可以从无穷大到+无穷大,就像线性回归一样。我们使用之前讨论过的 logit 函数来完成这个转换。

所以,换句话说,我们把 S 形曲线转换成直线。这意味着,虽然我们仍然在逻辑回归中使用 S 形曲线,但系数是根据对数(赔率)计算的。

在这之后,算法本质上是线性模型;我们有了直线趋势线,然后我们使用优化算法以及用于逻辑回归的修改成本函数(稍后将详细介绍)将其拟合到数据上。一旦我们做出了预测,我们就使用一个链接函数将我们的预测“翻译”或反转,其中最常见的一个称为 sigmoid 函数,回到一个概率。

好了,现在你对逻辑回归的工作原理有了一点点的了解。让我们用一个数学例子来巩固你的知识。

逻辑回归如何工作第一部分:数学

假设我们有一个具有两个特征的模型, X 1 + X 2,以及单二项式响应变量 Y ,我们将其表示为 p = P (Y=1):

作者照片

Y=1 的事件概率的对数可以表示为:

作者照片

我们可以通过对对数赔率求幂来恢复赔率:

作者照片

通过简单的代数运算, Y =1 的概率为:

作者照片

这个公式本质上是将我们的对数优势预测转化为概率的链接函数。该函数也称为 sigmoid 函数,也可以表示为:

作者照片

这可以直观地看做一条 S 形曲线:

图片来自维基百科

在这里,我们可以清楚地看到如何计算给定实例的概率对数,或者给定权重的情况下 Y =0 的概率。使逻辑回归成为分类模型的部分是用于分割预测概率的阈值。没有这一点,逻辑回归是真正的回归模型。

该算法如何工作的逐步指南

  1. 随机初始化模型的参数(或系数)
  2. 将 sigmoid 函数应用于线性模型的预测
  3. 通过使用优化算法更新参数,以更好地拟合数据。
  4. 计算误差。
  5. 对任一 n 次迭代重复 2-4,直到达到期望的结果或模型的计算误差接近或等于 0。

所以现在你应该对逻辑回归的工作原理有了很好的理解。但我相信您可能仍有疑问,例如:

  1. 嘿,你从没解释过什么是优化算法!
  2. 伙计,什么是成本函数?
  3. 等等,是线性模型吧?那么我们需要特征尺度吗?

好吧,你抓到我了。所以,在我们开始编码之前,让我用通俗的语言解释一下这些概念。

成本函数

成本函数本质上是一个衡量损失的公式,或模型的“成本”。如果你曾经参加过任何 Kaggle 比赛,你可能会遇到一些。一些常见的包括:

  • 均方误差
  • 均方根误差
  • 绝对平均误差
  • 原木损失

现在,有必要强调一下线性回归和逻辑回归之间的一个重要区别:

  • 线性回归基本上是通过计算残差(每个点离假设有多远)来计算成本。这可以在下图中看到,因为绿线从下图中的点分叉:

图片由维基百科提供。

注意来自每个数据点的绿线。这是模型的残差,用于计算线性回归模型的成本。

  • 当我先前说概率被转换成对数比值时,我没有提到一种情况;当 X 发生的概率为 1 时。在这种情况下,我们会得到以下输出:

作者照片

现在,我们不能计算残差,因为点和假设之间的距离可能是无穷大。这就是为什么我们使用一个特殊的成本函数叫做对数损失:

作者照片

这个函数是从所谓的最大似然估计中得到的。我知道这篇文章的长度,所以如果你想得到更多的信息,我推荐你看一下这个视频来获得更多关于这个功能的直觉。

这些函数对于模型训练和开发是必不可少的,因为它们回答了“的基本问题:我的模型预测新实例有多好?”。请记住这一点,因为这与我们的下一个主题有关。

优化算法

优化通常被定义为改进某样东西的过程,以使其发挥最大潜力。这也适用于机器学习。在 ML 的世界中,优化本质上是试图为某个数据集找到最佳的参数组合。这本质上是机器学习的“学习”部分。

虽然存在许多优化算法,但我将讨论其中最常见的两种:梯度下降和正规方程。

梯度下降

梯度下降是一种优化算法,旨在找到一个函数的最小值。它通过在斜率的负方向迭代地采取步骤来实现这个目标。在我们的例子中,梯度下降通过移动函数切线的斜率来不断更新权重。好极了,听起来很棒。请说英语。😃

梯度下降的一个具体例子

卢卡斯·克拉拉在 Unsplash 上的照片

为了更好地说明梯度下降,让我们通过一个简单的例子。想象一个人在山顶,他/她想到达山下。他们可以做的是环顾四周,看看他们应该朝哪个方向迈一步,以便更快地下来。然后,他们可能会朝那个方向迈出第,现在他们离目标更近了。然而,他们下来时必须小心,因为他们可能会在某个点被卡住,所以我们必须确保相应地选择我们的步长。

类似地,梯度下降的目标是最小化一个函数。在我们的案例中,是为了最小化我们模型的成本。这是通过找到函数的切线并向那个方向移动来实现的。算法的“步骤的大小由所谓的学习率来定义。这基本上控制了我们向下移动的距离。有了这个参数,我们必须小心两种情况:

  1. 学习率太大,算法可能不收敛(达到最小值)并在最小值附近跳动,但永远不会收敛
  2. 学习率太小,算法将花费太长时间达到最小值,还可能“卡”在次优点。

我们还有一个参数来控制算法在数据集上迭代的次数。

从视觉上看,该算法会做这样的事情:

图片来自维基百科

因为这种算法对机器学习来说非常重要,所以让我们回顾一下它的作用:

  1. 随机初始化权重。这被称为(你猜对了)随机初始化
  2. 然后,该模型使用这些随机权重进行预测。
  3. 模型的预测通过成本函数进行评估。
  4. 然后,模型运行梯度下降,通过找到函数的切线,然后在切线的斜率中采取一个步骤
  5. 该过程重复 N 次迭代,或者如果满足标准。

梯度下降的优点和缺点

优势:

  1. 很可能将成本函数降低到全局最小值(非常接近或= 0)
  2. 最有效的优化算法之一

缺点:

  1. 在大型数据集上可能会很慢,因为它使用整个数据集来计算函数切线的梯度
  2. 容易陷入次优点(或局部最小值)
  3. 用户必须手动选择学习速率和迭代次数,这可能很耗时

既然已经介绍了梯度下降,那就来介绍法线方程吧。

正态方程

照片由萨夫Unsplash 拍摄

如果我们回到我们的例子,而不是采取步骤反复下山,我们将能够立即到达底部。法线方程就是这种情况。它利用线性代数来产生权重,可以在很短的时间内产生与梯度下降一样好的结果。

法线方程的优点和缺点

优势:

  1. 不需要选择学习率或迭代次数
  2. 极快

缺点:

  1. 无法很好地扩展到大型数据集
  2. 倾向于产生良好的权重,但不是最佳的权重

特征缩放

UnsplashCalum MacAulay 拍摄的照片

这是许多机器学习算法的重要预处理步骤,尤其是那些使用距离度量和计算的算法(如线性回归、梯度下降,当然还有逻辑回归,因为它确实是一个回归模型!).它基本上缩放了我们的特征,使它们在相似的范围内。把它想象成一栋房子,一栋房子的比例模型。两者的形状相同(都是房子),但是大小不同(5m!= 500m)。我们这样做的原因如下:

  1. 它加速了算法
  2. 有些算法对规模很敏感。换句话说,如果特征具有不同的比例,则具有较高量值的特征有可能被赋予较高的权重。这将影响机器学习算法的性能,显然,我们不希望我们的算法偏向一个特征。

为了证明这一点,让我们假设我们有三个特性,分别命名为 A、B 和 C:

  • 缩放前 AB 的距离= >

照片由分析公司 Vidhya 拍摄

缩放前 BC 的距离= >

照片由分析公司 Vidhya 拍摄

缩放后 AB 的距离= >

照片由分析公司 Vidhya 拍摄

缩放后 BC 的距离= >

照片由分析公司 Vidhya 拍摄

我们可以清楚地看到,这些特性比缩放之前更具可比性,也更公正。如果你想要一个关于特性缩放的很棒的教程,请查看这篇由 Analytics Vidhya 撰写的博客文章

哇!你的大脑一定充满了大量的信息!因此,我建议在我们从头开始实际编写算法之前,休息一下,四处逛逛,享受生活,做些伸展运动!

从头开始编码逻辑回归

克里斯里德在 Unsplash 上的照片

好了,现在是你一直在等待的时刻;实施!事不宜迟,我们开始吧!

:所有代码可以从 这个 Github repo 下载。但是,我建议您在这样做之前先跟随教程,因为这样您会对您实际编码的内容有更好的理解!

首先,让我们做一些基本的导入:

**import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer**

我们使用 numpy 进行数学计算,使用 matplotlib 绘制图表,使用来自 scikit-learn 的乳腺癌数据集。

接下来,让我们加载数据并定义我们的特征和标签:

**# Load and split data
data = load_boston()
X,y = data['data'],data['target']**

接下来,让我们创建一个自定义的 train_test_split 函数,将我们的数据分成一个训练集和测试集:

**# Custom train test split
def train_test_divide(X,y,test_size=0.3,random_state=42):
    np.random.seed(random_state)
    train_size = 1 - test_size
    arr_rand = np.random.rand(X.shape[0])
    split = arr_rand < np.percentile(arr_rand,(100*train_size))

    X_train = X[split]
    y_train = y[split]
    X_test =  X[~split]
    y_test = y[~split]

    return X_train, X_test, y_train, y_testX_train,X_test,y_train,y_test = train_test_divide(X,y,test_size=0.3,random_state=42)**

基本上,我们只是

  1. 进入测试尺寸。
  2. 设置随机种子以确保我们的结果是可重复的。
  3. 基于测试集大小获得训练集大小
  4. 从我们的特征中随机选取样本
  5. 将随机选择的实例分成训练集和测试集

为了制作干净、可重复和高效的代码,以及坚持软件开发实践,我们将创建一个逻辑回归类:

**class LogReg:
    def __init__(self,X,y):
        self.X = X
        self.y = y
        self.m = len(y)
        self.bgd = False**

让我们添加链接函数作为该类的方法:

**def sigmoid(self,z):
        return 1/ (1 + np.exp(-z))**

现在,让我们使用上述公式实现我们的成本函数:

**def cost_function(self,X,y):
        h = self.sigmoid(X.dot(self.thetas.T))
        m = len(y)
        J = (1/m) * (-y.dot(h) - (1-y).dot(np.log(1-h)))
        return J**
  • h =假设(我们的推断或预测)
  • m =训练集中的实例数量
  • J =我们的成本函数

我们还将添加一个插入截取项的方法:

**def add_intercept_term(self,X):
        X = np.insert(X,0,np.ones(X.shape[0:1]),axis=1).copy()
        return X**
  • 这基本上是在我们的特性的开头插入一列 1。
  • 如果我们不加上这一点,那么我们将迫使超平面通过原点,导致它倾斜相当大,因此不能正确拟合数据。

接下来,我们将扩展我们的功能:

作者照片

**def feature_scale(self,X):
        X = (X - X.mean()) / (X.std())
        return X**

我们将添加一个随机初始化模型参数的方法:

**def initialise_thetas(self):
        np.random.seed(42)
        self.thetas = np.random.rand(self.X.shape[1])**

现在,我们将使用下面的公式实现法线方程:

作者照片

**def normal_equation(self):
        A = np.linalg.inv(np.dot(self.X.T,self.X))
        B = np.dot(self.X.T,self.y)
        thetas = np.dot(A,B)
        return thetas**

本质上,我们将算法分为 3 个部分:

  1. 我们得到 X 转置和 X 的点积的倒数
  2. 我们得到重量和标签的点积
  3. 我们得到两个计算值的点积

所以,这就是正规方程!不算太差!现在,我们将使用以下公式实现批量梯度下降:

作者照片

**def batch_gradient_descent(self,alpha,n_iterations):
        self.cost_history = [0] * (n_iterations)
        self.n_iterations = n_iterations

        for i in range(n_iterations):
            h = self.sigmoid(np.dot(self.X,self.thetas.T))
            gradient = alpha * (1/self.m) * (h - self.y).dot(self.X)
            self.thetas = self.thetas - gradient
            self.cost_history[i] = self.cost_function(self.X,self.y)

        return self.thetas**

在这里,我们执行以下操作:

  1. 我们接受 alpha,或者学习率,和迭代次数
  2. 我们创建一个列表来存储我们的成本函数历史,以便稍后绘制成线图
  3. 我们遍历数据集 n 次迭代,
  4. 我们获得预测,并计算梯度(函数切线的斜率)。这被称为 h(x)
  5. 我们通过从实际值中减去我们的预测值并乘以每个特征来更新权重,以沿梯度向下移动
  6. 我们使用自定义的日志损失函数记录这些值。
  7. 重复,完成后,返回我们的最终优化参数。

让我们创建一个拟合函数来拟合我们的数据:

**def fit(self,bgd=False,alpha=0.4,n_iterations=2000):
        self.X = self.feature_scale(self.X)
        if bgd == False:
            self.add_intercept_term(self.X)
            self.thetas = self.normal_equation()
        else:
            self.bgd = True
            self.add_intercept_term(self.X)
            self.initialise_thetas()

            self.thetas = self.batch_gradient_descent(alpha,n_iterations)**

我们还将创建一个 plot_function 方法来显示成本函数在多个时期内的大小:

**def plot_cost_function(self):

        if self.bgd == True:
            plt.plot(range((self.n_iterations)),self.cost_history)
            plt.xlabel('No. of iterations')
            plt.ylabel('Cost Function')
            plt.title('Gradient Descent Cost Function Line Plot')
            plt.show()
        else:
            print('Batch Gradient Descent was not used!')** 

最后,我们将创建一个用于推理的预测函数,将阈值设置为 0.5:

**def predict(self,X_test):
        self.X_test = X_test.copy()
        self.X_test = self.feature_scale(self.X_test)
        h = self.sigmoid(np.dot(self.X_test,self.thetas.T))
        predictions = (h >= 0.5).astype(int)
        return predictions**

该类的完整代码如下所示:

**class LogReg:
    def __init__(self,X,y):
        self.X = X
        self.y = y
        self.m = len(y)
        self.bgd = False

    def sigmoid(self,z):
        return 1/ (1 + np.exp(-z))

    def cost_function(self,X,y):
        h = self.sigmoid(X.dot(self.thetas.T))
        m = len(y)
        J = (1/m) * (-y.dot(h) - (1-y).dot(np.log(1-h)))
        return Jdef add_intercept_term(self,X):
        X = np.insert(X,0,np.ones(X.shape[0:1]),axis=1).copy()
        return X

    def feature_scale(self,X):
        X = (X - X.mean()) / (X.std())
        return X

    def initialise_thetas(self):
        np.random.seed(42)
        self.thetas = np.random.rand(self.X.shape[1])def normal_equation(self):
        A = np.linalg.inv(np.dot(self.X.T,self.X))
        B = np.dot(self.X.T,self.y)
        thetas = np.dot(A,B)
        return thetas

    def batch_gradient_descent(self,alpha,n_iterations):
        self.cost_history = [0] * (n_iterations)
        self.n_iterations = n_iterations

        for i in range(n_iterations):
            h = self.sigmoid(np.dot(self.X,self.thetas.T))
            gradient = alpha * (1/self.m) * (h - self.y).dot(self.X)
            self.thetas = self.thetas - gradient
            self.cost_history[i] = self.cost_function(self.X,self.y)

        return self.thetas

    def fit(self,bgd=False,alpha=0.4,n_iterations=2000):
        self.X = self.feature_scale(self.X)
        if bgd == False:
            self.add_intercept_term(self.X)
            self.thetas = self.normal_equation()
        else:
            self.bgd = True
            self.add_intercept_term(self.X)
            self.initialise_thetas()

            self.thetas = self.batch_gradient_descent(alpha,n_iterations)

    def plot_cost_function(self):

        if self.bgd == True:
            plt.plot(range((self.n_iterations)),self.cost_history)
            plt.xlabel('No. of iterations')
            plt.ylabel('Cost Function')
            plt.title('Gradient Descent Cost Function Line Plot')
            plt.show()
        else:
            print('Batch Gradient Descent was not used!')

    def predict(self,X_test):
        self.X_test = X_test.copy()
        self.X_test = self.feature_scale(self.X_test)
        h = self.sigmoid(np.dot(self.X_test,self.thetas.T))
        predictions = (h >= 0.5).astype(int)
        return predictions**

现在,让我们使用正规方程调用新创建的类:

**log_reg_norm = LogReg(X_train,y_train)
log_reg_norm.fit(bgd=False)**

并评估:

**accuracy = round((log_reg_norm.predict(X_test) == y_test).mean(),2)
accuracyOUT:
0.82**

现在,通过梯度下降,我们还可以绘制成本函数:

**log_reg_bgd = LogReg(X_train,y_train)
log_reg_bgd.fit(bgd=True)
log_reg_bgd.plot_cost_function()**

作者照片

现在我们来评估一下:

**accuracy = round((log_reg_bgd.predict(X_test) == y_test).mean(),2)
accuracy**

所以,现在你已经从零开始成功实现了逻辑回归!

有些家庭作业要你做:

  • 我们可以看到,在优化方面,批量梯度下降是明显的赢家。但是,您可以尝试用更少的迭代再次运行它,因为它似乎已经收敛了。有什么区别?
  • 尝试跳过特征缩放。这对你的成绩有影响吗?
  • 试着省去截距项。这有多大的影响?

在过去的几个月里,我真的很喜欢写博客,我很感激所有关注我的人,他们总是对我的工作表示赞赏。因此,我要感谢你在百忙之中抽出时间来阅读这篇文章,我希望继续写出更多有趣的文章来与世界分享。敬请期待,祝你玩得愉快!

蕾妮·费希尔在 Unsplash 上的照片

用 Python 从头到尾的机器学习算法:SVM

原文:https://towardsdatascience.com/machine-learning-algorithms-from-start-to-finish-in-python-svm-d9ff9b48fd1?source=collection_archive---------1-----------------------

学习、理解和实现最强大的通用机器学习算法之一。

迈克·洛索在 Unsplash 上的照片

支持向量机是非常通用的机器学习算法。它们受欢迎的主要原因是它们能够使用所谓的内核技巧执行线性和非线性分类和回归;如果你不知道那是什么,不要担心。完成本文后,您将能够:

  • 了解什么是 SVM 及其工作原理
  • 区分硬边际 SVM软边际 SVM
  • 用 Python 从头开始编写 SVM 代码

所以,事不宜迟,让我们开始吧!

什么是 SVM,我为什么需要它?

Paolo NicolelloUnsplash 上拍摄的照片

有了这么多其他算法(线性回归、逻辑回归、神经网络等..)你可能想知道为什么你的工具箱里还需要一个!也许这些问题可以借助图表来回答:

图片来自维基百科

在这里,我们看到了对数据进行分类的三个潜在决策边界:H1、H2 和 H3。首先,H1 根本不区分阶级,所以它不是一个好的超平面。H2 确实分离了类别,但是请注意,点与点之间的差距(或街道)是如此之小,并且这个分类器不太可能在看不见的实例上表现良好。

第三个超平面,H3,代表 SVM 分类器的决策边界;这条线不仅将两个类别分开,而且在两个类别的最极端点之间保持最宽的距离。

你可以把 SVM 看作是两个阶层之间最大的差距。这就是所谓的大幅度分类。

大幅度分类

照片由维基百科

如我所说,大间隔 SVM 分类器本质上试图在两个类之间拟合尽可能宽的街道(用平行虚线表示)。需要注意的是,添加更多“远离街道”(不在虚线上)的实例不会影响决策边界。

决策边界完全由类的最极端的实例确定(或由支持),或者换句话说,位于街道边缘的实例。这些被称为支持向量(它们在图中用黑色圈出)。

硬利润分类的限制

照片由 Ludovic CharletUnsplash 上拍摄

所以本质上,硬边界 SVM 基本上试图拟合一个决策边界,最大化两个类的支持向量之间的距离。但是,这种模式存在一些问题:

  1. 它对异常值非常敏感
  2. 它只对线性可分的数据有效

这两个概念可以在这个观想中清晰地突出出来:

问题 1:它对异常值非常敏感

照片由 StackOverflow 拍摄

请注意红点是一个极端的异常值,因此 SVM 算法将它用作支持向量。因为硬边界分类器找到支持向量之间的最大距离,所以它使用红色异常值和蓝色支持向量来设置决策边界。

这导致很差的决策边界,很可能过度拟合,并且将不能很好地预测新的类。

问题 2:它只对线性可分的数据有效

作者照片

在这个例子中,我们可以清楚地观察到,没有可能的线性分类器将类别分开。此外,还有一个主要的异常值。所以,问题是,SVM 如何分离非线性可分数据?

处理异常值和非线性数据

方法一:软利润 SVM

作者照片

一种方法是在保持街道尽可能宽(最大化裕量)和限制裕量违规(这些实例最终出现在街道中间,甚至出现在街道的错误一侧)之间找到良好的平衡。这叫做软边际 SVM。

本质上,您是在控制两个目标之间的权衡:

  1. 最大化决策边界和支持向量之间的距离
  2. 最大化被决策边界正确分类的点数

这种权衡通常由一个超参数控制,这个超参数可以用λ表示,或者更常见的(在 scikit-learn 中)是 C 参数。这实质上控制了错误分类成本。具体来说,

  • C 的小值导致更宽的街道,但更多的边界违规(更高的偏差,更低的方差)
  • aC的值越大,街道越窄,但边界违规越少(低偏差、高方差)。

尽管这种方法可行,但我们必须使用交叉验证技术找出最佳的 C 参数。这可能需要相当长的时间。此外,人们可能希望创建一个最佳模型,并且没有任何跨越边界违规的“松弛”变量。那么我们现在的解决方案是什么?

方法二:内核

图片来自维基百科

虽然线性 SVM 在大多数情况下都很有效,但是很少有数据集是线性可分的。解决这个问题的一个方法是添加更多的特性,比如多项式特性(这些特性本质上是通过将值提升到一个 N 次多项式来改变你的特性(想想 X,X,等等..)).

例如,假设我们有以下数据:

作者照片

显然,这个数据集不是线性可分的。

然而,当我们通过将根提升到 20 的幂来应用多项式变换时:

作者照片

我们得到一个线性可分的数据集。

然而,这对于大型数据集是不可行的;进行多项式变换所需的计算复杂度和时间太长,计算成本太高。

此外,使用高次多项式次数会创建大量的要素,从而使模型太慢。

这就是 SVM 的魅力所在。更确切地说,内核的妙处在于

内核技巧

照片由朱利叶斯德罗斯特Unsplash 上拍摄

本质上,核是计算非线性可分离数据点之间的关系并将它们映射到更高维度的不同函数。然后它适合一个标准的支持向量分类器。它有效地将特征从相对低的维度映射到相对高的维度。

然而,核函数仅计算数据点之间的高维度关系,就好像它们在更高维度中一样;它们实际上不做转换,这意味着内核函数不添加任何特性,但是我们得到的结果和我们做的一样。

这种技巧(计算数据点之间的高维关系,而不实际创建或转换它们)被称为内核技巧

内核技巧通过避免将特征从低维转换到高维的数学运算,降低了 SVM 的计算复杂度!

让我们看看两个常见的内核函数:

1 .多项式核

2.高斯径向基函数

核函数 1:多项式核

克里斯·劳顿Unsplash 上拍摄

本质上,这使用多项式核来计算数据点之间的高维关系,并将数据映射到更高维度,而不添加任何特征。

多项式核的公式如下(我很抱歉没有警告就用数学来打击你!):

作者照片

  • 这里的 d 是一个超参数,指的是函数应该使用的多项式的次数。

一个例子

举个具体的例子,假设我们有这样的数据:

作者照片

显然,这个数据不是线性可分的。然而,如果我们使用具有多项式核的 SVM,我们将得到以下高维映射:

作者照片

同样,从中得出的重要思想是,核函数仅计算点之间的高维关系,就像它们在高维空间中一样,但不创建或变换新的要素。

以下代码使用 scikit-learn 中的 SVC 类实现了一个多项式内核:

from sklearn.svm importSVC svc = SVC(kernel="poly", degree=3, coef0=1, C=5))
svc.fit(X_train,y_train)

显然,如果你的模型过拟合,你可能需要降低多项式的次数。您可能已经注意到这里的一些参数。让我简单解释一下:

  • 内核:定义要使用的内核(我们将在后面探索一些其他选项)
  • 次数:定义多项式内核的次数
  • C :分类误差,主要控制具有最大可能裕度和最大化决策边界正确分类的点数之间的权衡。

核函数 2:高斯 RBF 核

苏珊·d·威廉姆斯在 Unsplash 上的照片

另一个非常流行的 SVM 核是高斯径向基函数(高斯 RBF)。本质上,这是一个计算实例和一个地标之间距离的相似度函数。内核函数的公式如下:

图片来自维基百科

澄清一些符号(注意:任何不清楚的地方将很快解释清楚):

  • x:指一个实例
  • ' x ':指的是一个地标
  • σ:这是指伽玛

该函数本身遵循一条钟形曲线(因此它是高斯),范围从 0(离地标非常远)到 1(在地标处)。

我确信这在你的脑海中仍然是模糊的,所以让我们用我所知道的唯一方法来澄清这种困惑;举个例子!

一个例子

观察下面的 1D 数据图表:

作者照片

界标本质上是数据集中的一个点,我们将使用它来获得。这里我们有两个地标, X2X3。

我们现在准备计算新的特征。比如我们来看实例 X,等于-1。它位于距第一地标 1 的距离和距第二地标 2 的距离处。因此,其新的映射特征将是:

*x*2 = exp (–0.3 × 12) ≈ 0.74

*x*3 = exp (–0.3 × 22) ≈ 0.30

如下图所示:

作者照片

现在我们简单地用一个普通的 SVC 来分类这些点!

你可能在想,酷!但是:

  1. 你如何选择地标?
  2. 你还没解释伽马到底是什么意思!

选择地标

如此真实。为了解决第一个问题,通常在数据集中每个实例的位置创建一个地标。这产生了许多维度,从而增加了变换后的训练集是线性可分的机会。

然而,再一次,就像多项式变换一样,这在计算上是昂贵的,并且需要添加许多功能,想象一下,如果您有一个具有 m 个实例和 n 个功能的训练集被变换成一个具有 m 个实例和 m 个功能的训练集(假设您删除了原始功能)。

换句话说,如果您有 20 个包含 20 个特征的实例,那么计算这些转换将得到 400 个特征!

幸运的是,内核技巧发挥了它的魔力;它使得计算这些更高维度的关系成为可能,而不需要实际转换或创建新的特征,并且仍然得到与你所得到的相同的结果!

伽玛

现在,伽马是一个特殊的超参数,它特定于 rbf 内核。回到我们上面的 rbf 函数图,gamma 控制每个钟形函数的宽度。

具体来说, gamma大值将缩短钟形曲线的宽度,并减小每个实例的影响范围,从而导致在各个数据点之间摆动的更不规则的决策边界。相反, gamma值增加了每个数据点的影响范围,并导致更平滑的决策边界。

带有 rbf 内核的 SVC 的 scikit-learn 实现如下:

SVC(kernel="rbf", gamma=5, C=0.001)

注意:在这篇文章中,我将只编码一个软硬边距的 SVM。但是在将来,我会写一些关于如何在 SVM 实现内核技巧的文章,所以请一定要继续关注

硬利润和软利润 SVM 的数学

安妮·斯普拉特在 Unsplash 上的照片

是的,我很抱歉,但不幸的是,你需要理解数学,以编码它。如果你真的讨厌数学,请随意跳过这一部分,但我强烈建议至少尝试理解正在发生的事情,让你对手头的问题有更好的感觉。

在我真正开始计算之前,让我一步一步地指导您 SVM 是如何工作的:

  1. 为数据拟合一个超平面,并尝试对这些点进行分类
  2. 使用 优化算法调整模型的参数,使其在支持向量之间保持最大可能的余量。
  3. 重复 n 次迭代,或者直到 成本函数 最小化。

现在,在我们深入研究 SVM 数学之前,让我解释一些关键术语。

成本函数

佩皮·斯托扬诺夫斯基在 Unsplash 拍摄的照片

成本函数本质上是一个衡量损失的公式,或模型的“成本”。如果你曾经参加过任何 Kaggle 比赛,你可能会遇到一些。一些常见的包括:

  • 均方误差
  • 均方根误差
  • 绝对平均误差
  • 原木损失

我们将使用的成本函数被称为铰链损耗。函数的公式如下:

图片来自维基百科

从图形上看,铰链损耗如下所示:

图片来自维基百科

在该图中,蓝色代表正确分类的损失,绿色代表错误分类的损失。

请注意,即使我们对数据点进行了正确的分类,铰链损失也会影响数据点在边缘内的预测。

本质上,我们将使用这一点来衡量我们的算法的性能,并确保我们达到我们的目标(最大限度地提高利润)

优化算法

优化通常被定义为改进某样东西的过程,以使其发挥最大潜力。这也适用于机器学习。在 ML 的世界中,优化本质上是试图为某个数据集找到最佳的参数组合。这本质上是机器学习的“学习”部分。

虽然存在许多优化算法,但我将讨论其中最常见的两种:梯度下降和正规方程。

梯度下降

梯度下降是一种优化算法,旨在找到一个函数的最小值。它通过在斜率的负方向迭代地采取步骤来实现这个目标。在我们的例子中,梯度下降通过移动函数切线的斜率来不断更新权重。好极了,听起来很棒。请说英语。😃

梯度下降的一个具体例子

卢卡斯·克拉拉在 Unsplash 上的照片

为了更好地说明梯度下降,让我们通过一个简单的例子。想象一个人在山顶,他/她想到达山下。他们可以做的是环顾四周,看看他们应该朝哪个方向迈一步,以便更快地下来。然后,他们可能会朝那个方向迈出一步,现在他们离目标更近了。然而,他们下来时必须小心,因为他们可能会让卡在某个点上,所以我们必须确保相应地选择我们的步长。**

类似地,梯度下降的目标是最小化一个函数。在我们的案例中,是为了最小化我们模型的成本。这是通过找到函数的切线并向那个方向移动来实现的。算法的“步骤的大小由所谓的学习率来定义。这基本上控制了我们向下移动的距离。有了这个参数,我们必须小心两种情况:

  1. 学习率太大,算法可能不收敛(达到最小值)并在最小值附近跳动,但永远不会收敛
  2. 学习率太小,算法将花费太长时间达到最小值,还可能“卡”在次优点。

我们还有一个参数来控制算法在数据集上迭代的次数。

从视觉上看,该算法会做这样的事情:

图片来自维基百科

因为这种算法在机器学习中非常重要,所以让我们回顾一下它的作用:

  1. 随机初始化权重。这叫做(你猜对了)随机初始化**
  2. 然后,该模型使用这些随机权重进行预测。
  3. 模型的预测通过成本函数进行评估。
  4. 然后,模型运行梯度下降,通过找到函数的切线,然后在切线的斜率中采取一个步骤
  5. 该过程重复 N 次迭代,或者如果满足标准。

这个过程在数学上显示如下:

作者照片

这里需要注意的重要事项:

α: 这是学习率的符号(记住:步长的大小)

m :训练样本数

h(θx) :我们的预测

θn: 我们算法的第 n 个系数

梯度下降的优点和缺点

优势:

  1. 梯度下降很可能将成本函数降低到全局最小值(非常接近或= 0)
  2. 最有效的优化算法之一

缺点:

  1. 在大型数据集上可能会很慢,因为它使用整个数据集来计算函数切线的梯度
  2. 容易陷入次优点(或局部最小值)
  3. 用户必须手动选择学习速率和迭代次数,这可能很耗时

好的,我知道你真的想开始实际的编码,但是这最后一部分是 SVM 数学中最重要的部分,所以坚持住!

SVM 的数学

对于预测:

作者照片

我们主要做以下工作:

  • 如果权重乘以特征减去偏差项的点积的符号大于或等于 1,则预测 1
  • 如果权重乘以特征减去偏差项的点积的符号小于或等于-1,则预测 0

条件:

作者照片

这是正分类的铰链损失的条件。这由我们之前看到的铰链损耗图上的蓝线表示。基本上,这将检查给定实例的分类是正确的还是错误的。

正确分类:

作者照片

这是我们正确分类的公式。澄清:

w :算法的权重

α: 我们之前谈到的梯度下降的学习率

λ:正则化参数(相当于 C 参数)

分类不正确:

作者照片

这是不正确分类的公式。请注意我们是如何调整偏置项的。

好了,最后,女士们先生们,重头戏:SVM 从零开始!

从头开始编写 SVM 代码

克里斯里德 T21 在 Unsplash 上的照片

让我们终于开始了!首先,让我们做一些基本的导入:

*import numpy as np 
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split*

是的,没有 sklearn 型号!这将用简单的数字编码!

接下来,让我们创建一个基本数据集,并将数据分为训练和测试两部分:

*X, y =  datasets.make_classification(n_samples=500, n_features=5, random_state=42, class_sep=0.7)
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=42, test_size=0.2)*

我准备为这个教程制作一个合成数据集,将 class_sep 设置为 0.7,意思是 if 应该相对简单的对数据进行分类。

现在,为了遵守软件工程原则,我将创建一个 SVM 类,并构建它以使代码看起来更整洁,更易于共享:

*class SVM:def __init__(self, learning_rate=0.001, C=0.001, n_iters=100):
        self.lr = learning_rate
        self.C = C
        self.n_iters = n_iters
        self.w = None
        self.b = None*

因此,在这里,我们基本上初始化我们的学习率,正则化参数,迭代次数,我们设置权重和偏差等于零。

接下来,我们定义我们的拟合方法:

*def fit(self, X, y):
        n_samples, n_features = X.shape

        # Convert 0 labels to be -1 to set threshold with hinge loss
        y_ = np.where(y <= 0, -1, 1)

        self.w = np.random.rand(n_features)
        self.b = 0*

一旦给定了训练特征和目标向量,我们就可以随机地将我们的权重初始化为特征数量的向量。请注意我们如何将数据集中的 0 值转换为等于-1,这样我们就可以使用铰链损耗。

现在,我们继续这个方法的核心:

*for _ in range(self.n_iters):
    for idx, x_i in enumerate(X):
        condition = y_[idx] * (np.dot(x_i, self.w) - self.b) >= 1*

因此,我们主要做了以下工作:

  1. 循环 n_iters 次(默认情况下 n_iters=100)
  2. 对于选定的索引和值 X,我们设置我们的条件,检查我们选定的目标值乘以我们选定的实例和权重的点积减去偏差是否大于或等于 1。这实质上检验了我们根据铰链损耗分类是否正确。

接下来,我们将用于正确分类的公式翻译成代码:

*if condition:
    self.w -= self.lr * (2 * self.C * self.w)*

而我们对的公式不正确的归类成代码:

*else:
    self.w -= self.lr * (2 * self.C * self.w - np.dot(x_i, y_[idx]))
    self.b -= self.lr * y_[idx]*

最后,我们定义我们的预测函数:

*def predict(self, X):
    preds = np.sign(np.dot(X, self.w) - self.b)
    return np.where(preds == -1,0,1)*

我们确保将等于-1 的标签转换回零。

现在,我们只需调用我们的函数,并在测试集上获得我们的模型的准确性:

*clf = SVM()
clf.fit(X_train, y_train)preds = clf.predict(X_test)(preds == y_test).mean()OUT:
0.82*

我添加了一个 visualise_svm()函数来帮助可视化 svm,可以从我在本文末尾添加的 Github repo 中访问它。然而,运行该函数会输出以下内容:

作者照片

现在,如果你还没有猜到,我们刚刚实施了软保证金 SVM。我们将 C 的值设置为 0.001,我们可以清楚地看到,决策边界允许一些点位于边缘和错误的一侧,但却产生了更好的超平面。

现在,当我们将 C 值更改为 0.9(非常小的正则化)时,我们会得到以下图形:

作者照片

我们的准确率从 0.82 降到了 0.7

锁定作业

我想让你尝试一些任务:

  1. 试着把 C 调成一个很小很大的值?决策边界如何变化?
  2. 调整梯度下降算法的学习率。你会得到更好的结果吗?

真的很感谢每一个激励我写出好文章的人。我感谢我的忠实追随者和所有决定阅读我作品的人。我向你保证,这不会被忽视。我希望总能为读者创作出有趣的、引人入胜的作品。

我希望你学到了新的东西,并可能刷新了一些旧的知识。一定要继续关注更多,祝你一切顺利!

PS:这里是 Github 代码的链接

Kelly SikkemaUnsplash 上拍摄的照片

机器学习算法。这里是端到端。

原文:https://towardsdatascience.com/machine-learning-algorithms-heres-the-end-to-end-a5f2f479d1ef?source=collection_archive---------42-----------------------

通用分类算法的端到端运行;包括随机森林、多项式朴素贝叶斯、逻辑回归、kNN 和来自 sklearn 的支持向量机

约翰·汤纳在Unsplash【1】上的照片。

目录

  1. 介绍
  2. 随机森林
  3. 多项式朴素贝叶斯
  4. 逻辑回归
  5. 支持向量机
  6. k-最近邻
  7. 摘要
  8. 参考

介绍

本文的目标是:

1.学习常见的数据科学、分类算法。

2.执行这些算法的示例代码。

虽然有几篇关于机器学习算法的文档和文章,但我想总结一下作为一名专业数据科学家最常用的算法。此外,我将包含一些带有虚拟数据的示例代码,以便您可以开始执行各种模型!下面,我将从最受青睐的库 sklearn ( 也称为 scikit-learn)【2】中概述这些主要的分类算法:

  • 随机森林(RandomForestClassifier)—可用于回归
  • 多项式朴素贝叶斯(多项式
  • 逻辑回归(逻辑回归
  • 支持向量机( svm ) —可用于回归
  • k-最近邻(KNeighborsClassifier)-可用于回归

什么是分类?

Assigning new data into a category or bucket. 

而无监督学习,如常用的 K-means 算法,旨在将相似的数据组分组在一起,而无需标签、监督学习或分类——嗯,将数据分类为各种类别。下面描述了一个简单的分类示例。

标签:水果——香蕉、橘子和苹果

特征:形状、大小、颜色、种子数等。

分类模型从关于水果的特征中学习,以建议输入食物和水果标签。现在,想象一下,对于我将在下面描述的这些分类算法,来自数据的每个观察值,输入,都有关于它的各种特征,然后将基于预定的标签进行分类。类别的其他名称包括标签、类、组(通常在无监督聚类中引用,但仍然可以描述分类)和桶。

分类的重要性不仅仅在于教育,还在于它在商业世界中极其实用和有益。比方说你要给成千上万的文档分类,给衣服分类,或者检测图像;这些都使用了我将在下面描述的这些流行且强大的分类模型。

随机森林

Lukasz Szmigiel 在Unsplash【3】上拍摄的照片。

这种集成分类器通过在所用数据集的子样本上拟合几个决策树来工作。然后,它对这些决策树的准确性进行平均,并创建一个比仅使用决策树更好的预测准确性,以控制过度拟合。与大多数分类器一样,有大量的参数可以帮助您调整您的模型,使其更差或更好(希望更好)。下面描述了常见的参数,我将包括默认的参数值,以便您对从哪里开始调优有一个大致的了解:

**n_estimators**: number of trees in your forest (100)**max_depth**: maximum depth of your tree (None) - recommendation, change this parameter to be an actual number because this parameter could cause overfitting from learning your traning data too well**min_samples_split**: minimum samples required to split your node (2)**min_samples_leaf**: mimimum number of samples to be at your leaf node (1)**max_features**: number of features used for the best split ("auto")**boostrap**: if you want to use boostrapped samples (True)**n_jobs**: number of jobs in parallel run (None) - for using all processors, put -1**random_state**: for reproducibility in controlling randomness of samples (None)**verbose**: text output of model in process (None)**class_weight**: balancing weights of features, n_samples / (n_classes * np.bincount(y)) (None) - recommendation, use 'balanced' for labels that are unbalanced

我将在这里提供一个随机森林算法的例子。它将使用虚拟数据(所以准确性对我来说并不重要)。重点是代码、概念,而不是准确性,除非您的输入数据已经很好地建立。在代码示例中有五个单独的行,您可以注释掉所有的分类器, clf 除了一个——您正在测试的那个。下面是主代码示例[4]:

# import libraries
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.naive_bayes import MultinomialNB
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn import svm
from sklearn import metrics
import pandas as pd# text and numeric classes that use sklearn base libaries
class TextTransformer(BaseEstimator, TransformerMixin):
    """
    Transform text features
    """
    def __init__(self, key):
        self.key = keydef fit(self, X, y=None, *parg, **kwarg):
        return selfdef transform(self, X):
        return X[self.key]

class NumberTransformer(BaseEstimator, TransformerMixin):
    """
    Transform numeric features
    """
    def __init__(self, key):
        self.key = keydef fit(self, X, y=None):
        return selfdef transform(self, X):
        return X[[self.key]]# read in your dataframe
df = pd.read_csv('/Users/data.csv')# take a look at the first 5 observations
df.head()# use the term-frequency inverse document frequency vectorizer to transfrom count of text
# into a weighed matrix of term importance
vec_tdidf = TfidfVectorizer(ngram_range=(1,1), analyzer='word', norm='l2')# compile both the TextTransformer and TfidfVectorizer 
# to the text 'Text_Feature' 
color_text = Pipeline([
                ('transformer', TextTransformer(key='Text_Feature')),
                ('vectorizer', vec_tdidf)
                ])# compile the NumberTransformer to 'Confirmed_Test', 'Confirmed_Recovery', 
# and 'Confirmed_New' numeric features
test_numeric = Pipeline([
                ('transformer', NumberTransformer(key='Confirmed_Test')),
                ])
recovery_numeric = Pipeline([
                ('transformer', NumberTransformer(key='Confirmed_Recovery')),
                ])
new_numeric = Pipeline([
                ('transformer', NumberTransformer(key='Confirmed_New')),
                ])# combine all of the features, text and numeric together
features = FeatureUnion([('Text_Feature', color_text),
                      ('Confirmed_Test', test_numeric),
                      ('Confirmed_Recovery', recovery_numeric),
                      ('Confirmed_New', new_numeric)
                      ])# create the classfier from list of algs - choose one only
clf = RandomForestClassifier()
clf = MultinomialNB()
clf = LogisticRegression()
clf = svm.SVC()
clf = KNeighborsClassifier()# unite the features and classfier together
pipe = Pipeline([('features', features),
                 ('clf',clf)
                 ])# transform the categorical predictor into numeric
predicted_dummies = pd.get_dummies(df['Text_Predictor'])# split the data into train and test
# isolate the features from the predicted field
text_numeric_features = ['Text_Feature', 'Confirmed_Test', 'Confirmed_Recovery', 'Confirmed_New']
predictor = 'Text_Predictor'X_train, X_test, y_train, y_test = train_test_split(df[text_numeric_features], df[predictor], 
                                                    test_size=0.25, random_state=42)# fit the model
pipe.fit(X_train, y_train)# predict from the test set
preds = pipe.predict(X_test)# print out your accuracy!
print("Accuracy:",metrics.accuracy_score(y_test, preds))

如果你想看看. py 格式的 GitHub gist 在 python 中是什么样子的,这里有我的 GitHub gist 的代码【4】:

GitHub gist [4]上作者的整篇文章示例代码。

多项式朴素贝叶斯

帕特里克·托马索在Unsplash【5】上拍摄的照片。

这个分类器是一个朴素贝叶斯分类器,用于多项式模型,正如算法的名字所暗示的那样。它广泛应用于文本分类问题中,其中文本是来自字数统计的特征。使用该算法时,建议使用术语-频率逆文档频率 ( td-idf )管道,因为您想要一个分布良好的特性。因为这个分类器是基于贝叶斯定理的,所以假设特征之间存在独立性。下面是分类器的主要代码:

clf = MultinomialNB()

所用模型的参数和属性如下:

parameters - **alpha**: a paramter for smoothing (1.0)**class_prior**: looking at the previous class probability (None) attributes -**feature_count**: number of samples for each class or feature (number of classes, number of features)**n_features**: number of features for sample

逻辑回归

逻辑回归,或者更像逻辑分类,是一种使用 logit 函数的算法。估计值通常是二进制值,如真-假、是-否和 0-1。逻辑函数也使用 sigmoid 函数。关于这个模型的细节有很多文章(下面有用的链接),但是我将强调如何执行 sklearn 库中的代码。下面是分类器的主要代码:

clf = LogisticRegression()

逻辑回归有许多重要的参数。以下是其中的几个例子:

**penalty**: l1 or l2 (lasso or ridge), the normality of penalization (l2)**multi_class**: binary versus multiclass label data ('auto')

支持向量机

一种监督技术,不仅包括分类,还包括回归。支持向量机(SVMs)的好处是,它比其他构成高维度的算法效果更好。支持向量机的目标是找到在两个分类类别之间划分数据的线(它们在那条线之间的距离)。支持向量机的代码与上面的算法略有不同:

clf = svm.SVC()

这种代码上的差异引用了增加的 SVC ,也就是 C-支持向量分类。对于多类情况,您可以使用参数:

parameter **-** **decision_function_shape**: 'ovr' or 'one-versus-rest' approach

k-最近邻

照片由克里斯蒂安·斯塔尔Unsplash【6】上拍摄。

k 近邻法,或称 KNN 法,是通过多数投票来实现的。它根据周围的邻居对新类别进行分类;常用的距离测量函数是欧几里德函数。用于该算法的代码是:

clf = KNeighborsClassifier()

最重要的参数可能是:

parameter - **n_neighbors**: number of neighbors (5)

摘要

虽然有大量关于广泛使用的机器学习算法的文章;

我希望这篇文章对你有用,因为我已经提供了端到端的代码。

请查看下面有用的链接以及本文中描述的每种算法的官方文档。感谢您阅读我的文章,如果您有任何问题,请告诉我!

参考

[1]约翰·汤纳在 Unsplash 上拍摄的照片,(2016)

[2] sklearn, sklearn ,(2020)

[3]Lukasz Szmigiel 在 Unsplash 上拍摄的照片,(2015)

[4] M.Przybyla,分类-模型,(2020)

[5]帕特里克·托马索在 Unsplash 上拍摄的照片,(2016)

[6]照片由 Christian StahlUnsplash 上拍摄,(2017)

有用的 sklearn 链接:

随机森林

多项式朴素贝叶斯

逻辑回归

支持向量机

K-最近邻

机器学习——伦理评论

原文:https://towardsdatascience.com/machine-learning-an-ethics-review-5f4c35112be5?source=collection_archive---------50-----------------------

Unsplash 上的üMIT Bulut拍摄的照片

我正在熨斗学校完成我的数据科学项目,回顾我所做的五个项目,并考虑如果这些项目将投入生产并影响真实的人,我应该考虑哪些伦理问题。虽然机器学习伦理的介绍是 Flatron 项目的一部分,但将伦理分析整合到每个项目中超出了它的范围。

五项原则

我将使用弗洛里迪和考尔斯在 2019 年的论文中提出的五项原则,这是人工智能在社会中的五项原则的统一框架,对我的项目进行顶级审查。原则是有利无害自治正义可解释。慈善意味着“促进福祉,维护尊严,维持地球”。无罪意味着“隐私、安全和‘能力警告’”。自主指的是“我们为自己保留的决策权和我们委托给人为代理人的决策权之间的平衡”。正义意味着“促进繁荣、维护团结、避免不公平”。可解释性意味着“通过可理解性和可说明性实现其他原则”。

项目# 1——向新企业推荐电影类型

我的第一个项目是基于向一个虚构的新电影工作室推荐什么类型的电影。它实际上不涉及机器学习,它纯粹基于数据分析;然而,创建一个代替人类分析师做出建议的机器学习模型并不难想象,也不难实现。

对于电影工作室来说,要求机器学习模型告诉他们制作什么类型的电影,这对于五项原则来说意味着什么?在这个项目中,企业被认为是一个盈利性公司。它感兴趣的主要是经济利益,从分析来看,我推荐的类型是动画。我使用了来自电影数据库的数据,推荐什么类型的可能性是有限的。模型可以做出类似的建议,并随着数据集随时间的变化而更新其建议。随着娱乐和就业被视为商品,它可以被视为是有益的。侵犯隐私或安全的可能性似乎很小,通过自主测试将取决于实现。这个决定是由模型单独做出的,还是由一些人和模型共同做出的?如果只考虑模型,除了短期财务收益之外,可能永远不会考虑其他因素。当考虑正义时,这也将取决于实现,但是如果唯一的问题是类型,那么正义的方面将取决于模型建议的人类实现。关于可解释性,这将再次取决于模型的实现。然而,来自电影数据库的数据集是公开可用的这一事实将有助于模型的可理解性。

因为这个项目实际上没有进行机器学习,所以分析主要是推测性的,并且将取决于机器学习模型的实际实现。让我们继续下面四个使用机器学习模型的项目。

项目# 2——房价预测即服务

这个项目是基于一个虚构的服务,该服务将向搬到华盛顿州 King County 地区或希望搬到该地区新位置的人提供住房建议,并向企业提供类似的数据,以便他们可以做出明智的工资决定。

这个项目的机器学习方面是使用国王县房屋销售数据集的修改版本进行房价预测。

让我们开始伦理分析。我会把这个项目看作一个整体,而不仅仅是机器学习方面。出于慈善目的,可以向潜在购房者及其雇员提供的知识可以被视为通过向他们提供可能很难或很费时间来汇编的信息来促进购房者的福祉。该数据集不使用国王县尚未公开的个人信息,因此不会对人们的隐私造成损害。就自主性而言,该服务将几乎所有的自主性都给予了人类参与者。信息的消费者可以使用或不使用服务给出的建议,而不会产生任何影响。就公正而言,该服务最终可能会导致中产阶级化,并对该服务推荐的价格和便利性之间更好平衡的现有社区成员进行定价,而不考虑目前居住在那里的人。对于可解释性,我将同时考虑模型和数据集。首先,数据集是公开的。用于房价预测的模型是线性回归,其中内置了许多解释能力。它可以提供正在使用的参数列表及其对计算出的房价的重要性。

这项服务唯一潜在的道德问题是它对中产阶级化的潜在贡献。这项服务如何才能更加公正,使特定社区的住房成本不会迅速攀升?这是一个社区需要参与解决的复杂问题,但一个想法是增加服务的复杂性,以便考虑价格趋势,并阻止购房者在价格上涨过快的社区购买。

项目 3——坦桑尼亚水点分类

该项目旨在创建一个模型,用于预测供水点的分类,即功能性、功能性需要修复或非功能性,以便坦桑尼亚政府能够更好地利用其有限的资源,更好地为其人口提供清洁水。

这个项目看起来很有益处,它有助于为需要的人们提供干净的水。但是当把无罪和自主结合起来考虑时,就不那么明确了。不存在隐私或安全问题,但如果给予这种模式太多的自主权,可能会导致一些人永远无法获得当地供水点的服务。功能性水点的假阳性将导致那些水点被忽略。当考虑正义时,结果会是什么也不清楚。虽然拥有一个模型来确定需要访问哪些水点以获取服务可以消除人类决策过程中的偏差,但我们不知道在源数据集中存在什么偏差(如果有的话)。检查和记录结果以及每个水点信息的人做得好吗?他们是否同样注意或准确地检查了所有的水点?是否有任何水点被故意忽略,从而被排除在模型之外?如果不知道这些问题的答案,我们就无法知道通过源数据在模型中会产生什么样的偏差。现在让我们从可解释性的角度来看模型本身。表现最好并被选择用于实现的模型是随机森林分类器,它具有有限的互操作性。它可以告诉我们哪些特征对模型整体而言是重要的,但是考虑到随机森林模型中涉及大量树木,要解释特定水点的分类并不容易。

随机森林模型缺乏真正的互操作性,并且缺乏关于训练数据集中可能嵌入哪些偏差的信息,这使我认为,如果可以找到具有可比性能的模型,应该使用更具互操作性的模型。这样就可以审核一些已知的错误分类,以了解错误发生的原因,并对模型进行改进。

项目 4——推特情感分析

该项目旨在建立一个情感分析模型,以帮助一家虚构的公司监控公众对其新手机的反应,并对其竞争对手进行市场研究。

它使用机器学习模型对推文的情绪进行分类,但将解释和回应留给了人类分析师和决策者。该项目的好处是,根据 Twitter 用户的反馈,该公司将提供更好的手机。没有任何非恶意,模型中没有使用私人信息,但模型是在包含 twitter 句柄的公共数据集上训练的。虽然数据集不是为这个项目创建的,但数据集的创建者应该考虑是否包含这些 twitter 句柄,他们应该对数据进行某种匿名处理。虽然这些推文是公开发布的,但它们现在有了寿命,发布推文的人不再能够控制。这个系统通过只给人类参与者建议和观察,给予他们充分的自主权。公正的问题不适用于这个项目,因为它的范围有限。用于情感分析的模型是可解释的朴素贝叶斯分类器,并且数据集是公开可用的,使得项目是可解释的。

项目# 5——假新闻分类

这个项目是为一家虚构的社交媒体公司创建一个模型,将发布到其平台上的新闻故事分类为,以帮助他们回应公众对允许假新闻在其网站上扩散的指控,然后监控假新闻的发展。

该项目的好处是有可能消除或限制这个平台上的假新闻,这将减少人们个人或其社区成员面临的 dis 和错误信息的数量。假新闻被理解为对其读者或公众造成伤害,因为其意图是为了创作者或创作者支持的人或团体的利益而误导读者。在处理无罪问题时,新闻自由和言论自由就发挥了作用。在这个项目中,不会因为分类而改变或删除任何帖子,这将由人类决策者决定,但如果模型被赋予基于其分类删除帖子的自主权,则需要提出审查和偏见的问题。是什么使得这个故事是假的?它实际上是错误或虚假信息,还是讽刺、耸人听闻或质疑主导故事线?如所实现的,充分的自主权被给予人类决策。在考虑公正时,必须考虑模型的准确性。该模型在两个类别之间实现了 89%的准确率平衡,但是有 11%的类别被错误地分类了呢?考虑到对具有真正公共价值的新闻报道的潜在错误分类,是仅仅基于这种模式采取行动,还是删除它们会超出潜在价值?训练模型的数据集是否包含对某些类型的假新闻的偏见?谁来决定假新闻的真正定义,他们如何决定?这个项目使用了一个随机森林分类器,就像上面解释的那样,只能部分解释。考虑到对言论自由的高度重视,以及解释特定新闻故事的分类而不仅仅是呈现整体特征重要性的需要,使用更具可解释性的模型会更好。

这个项目提出了许多关于无罪、公正和可解释性的伦理问题,如果它被实际执行或有一个执行计划,有些问题会有答案,但还有其他问题仍然存在,值得深思。

结论

虽然这些项目看起来大多是道德的,但它们都提出了许多问题,需要不同程度的深入调查或反思,才能完成真正的道德分析。也就是说,我认为这对我来说是一次值得的练习,我希望对你也是如此。

人力资源部门的机器学习和人工智能

原文:https://towardsdatascience.com/machine-learning-and-ai-in-human-relations-departments-59ed8f9a14d5?source=collection_archive---------31-----------------------

生产力的新时代还是去除人力资源中的“人”?

资料来源:Pexels.com

介绍

深度学习和人工智能已经彻底改变了医疗保健、金融服务和零售等行业,许多公司都欢迎新技术。然而,人力资源(HR)部门在将智能系统集成到他们的工作流程中时遇到了更多的挑战。

人力资源部门的任务是管理组织的员工——雇用、解雇、解决纠纷、工资、福利等等。这些任务中的许多似乎已经成熟,可以通过机器学习实现自动化,然而,它们也往往是主观的,移交控制权带来了有趣的伦理挑战。

员工招聘

招聘过程既费力又昂贵。从审查简历、面试和培训新员工,雇用新员工会给组织带来新员工工资之外的巨大成本。然而,这种成本通常是值得的,因为如果必须解雇员工并重新开始这一过程,做出错误的决定会花费更多的钱。不仅需要再次产生雇佣成本,而且还会出现产量损失和新员工达到满负荷生产所需的时间。

正因为如此,许多公司已经将目光投向深度学习,以提供降低雇佣员工成本和提高雇佣员工质量的解决方案。然而,这些尝试并不总是按计划进行。

从 2014 年到 2018 年,亚马逊的一个团队建立了审查申请人简历的系统,以简化招聘顶级人才的流程。为了训练他们的算法,该团队利用过去十年提交给该组织的简历汇编了一个训练数据集。

亚马逊曾希望该系统能够自动识别前 x 名申请人,从而大幅减少从申请人中识别顶尖人才的时间。然而,他们后来发现,该系统对男性申请者比对女性申请者更有利。这是因为向亚马逊提交简历的男性求职者多于女性,这就产生了一个有偏见和扭曲的数据集。

创建公正的招聘系统可能是一项艰巨的任务。由于大多数公司很少有 50%的男性员工和 50%的女性员工,该模型通常可以识别出它认为最能说明一个好员工的因素,但实际上招聘经理并没有考虑这些因素。

为了创建准确的招聘决策和候选人排名系统,必须注意收集用于培训的数据集,以消除不必要的行为。此外,对模型进行硬编码以忽略某些特征(如姓名、性别和种族)也是可行的。

每小时调度

管理小时工的人力资源团队在创建时间表时有一项艰巨的任务。当你的员工不是全日工作且有一致的时间表时,经常会出现时间冲突。由于工作日程不可预测,人力资源经理(通常是总经理)的一个关键职能是管理休假和换班请求。

如果你问许多餐馆或零售店的经理,日程安排和与之相关的任务经常占据他们工作日的很大一部分。然而,深度学习系统开始承担这一负担。

自动化系统可以分析这些请求,并根据个人层面的预定义业务规则自动批准或拒绝它们。例如,许多雇用兼职倒班工人的组织不允许他们的员工在一周内工作 40 个小时或更多。如果换班请求使一名员工一周工作超过 40 小时,系统将拒绝该请求,无需任何人工干预。

当与预测需求信息相结合时,这些系统变得更加强大。准确预测何时需要额外的员工并相应地调整时间表和休假请求,可以在需求较低时节省劳动力成本,并在需求较高时确保有足够的员工工作,从而提高员工管理的效率。

虽然这些系统可以极大地改善员工管理并减少经理的工作量,但它可能会打击员工的士气。通常情况下,休假和换班请求可能是个人性质的。如果一个自动化系统拒绝了一个重要事件的休假请求,员工可能会对组织产生怨恨。

要使自动排班系统正常工作,重要的是要彻底定义业务规则,并确保员工有办法通过他们的经理获得对模型决策的否决。

劳动力分析

分析团队让组织能够以前所未有的方式利用他们的数据,让公司做出前所未有的明智决策。

当我们想到业务数据时,我们通常会想到他们收集客户数据以更好地了解他们。然而,许多组织也在收集其员工的数据。

跟踪组织员工的关键指标可以让人力资源部门更好地了解他们的员工。跟踪员工的情绪、生产力和与组织的联系使人力资源部门能够更好地分配资源并提高员工的效率。此外,它允许预测分析模型识别有离开组织风险或有可能晋升的员工。

虽然劳动力分析似乎是人力资源部门的一个显而易见的选择,但员工可能不会有相同的观点。将一名员工浓缩成一系列数字指标会使管理过程失去人性,让员工觉得自己只不过是一个数字。

结论

机器学习和人工智能在人力资源方面有着广阔的应用前景。然而,从人到机器驱动的管理的转换会导致组织内员工士气的重大问题。这些技术是开创了生产力的新时代,还是将“人”从人力资源中移除?我将把那件事留给你。

处理机器学习中的类不平衡

原文:https://towardsdatascience.com/machine-learning-and-class-imbalances-eacb296e776f?source=collection_archive---------19-----------------------

斯科特·凯利在 Unsplash 上拍摄的照片

处理高度不平衡数据的策略

介绍

将机器学习应用于现实世界的问题非常罕见,你可能会在教程或数据科学课程中找到一些简单明了的东西。很多时候你会遇到分类问题,你试图预测一些不经常发生的事情。这在试图预测诸如转换、流失、欺诈之类的事情时很常见。在这篇文章中,我将谈论机器学习中的阶级不平衡。特别是,我想回顾一下不平衡数据的一些含义,并强调和解释一些解决方法。我的希望是,在这篇文章结束时,你将拥有处理你可能遇到的任何预测问题所需的工具。

什么是不平衡数据,为什么这是一个问题?

就像我上面说的,当我们试图预测的类的比例有显著差异时,不平衡的数据就会出现。例如,在许多行业中,客户在一段时间内的流失是相对罕见的(希望如此)。如果我们尝试制定一个机器学习模型来预测客户是否会流失,我们可能只有 5%的客户会流失,而 95%的客户不会流失。对于像转换或欺诈这样的事情,这可能会更低。

好了,这个问题有希望变得更清楚一点,但是我们为什么要关心这个呢?我们来训练一下模型,做一些预测。让我们以上段中的流失为例,估计一个逻辑回归。在对模型进行估计后,我们得到了 95%的正确预测。那很容易。但是,如果我们更深入地研究结果,并查看混淆矩阵,我们可能会发现类似下面的图 1。我们的模型预测,基本上没有人搅动。这不是很有帮助,我们可以自己做这个预测,省去写代码的麻烦。显然,这种模式是非常无用的,并没有真正增加任何价值。这是怎么回事?为什么我们的模式这么差?训练集是如此不平衡,以至于模型很难在少数类中找到有用的模式。这在逻辑回归等算法中更为明显,因为它假设类分布是相等的。幸运的是,有几种方法可以解决这个问题,这就是我在这篇文章中将要经历的。

图 1:混乱矩阵:不平衡的数据

取样技术

我们可以尝试的第一个潜在解决方案是对数据进行重新采样,以平衡类别。我们可以尝试几种不同的采样方法,所有这些方法都可以在 imblearn python 库中轻松实现。

要提到的一个关键点是,这些重采样技术应该只在训练数据上执行。测试集应该保持不平衡。

为了开始我们的分析,让我们首先使用 sklearn 的一个方便的函数来创建一个数据集。make _ classification函数非常有用,允许我们创建一个数据集来演示这些技术和算法。请注意,我们已经将权重=[0.99,0.01]添加到参数中,以生成不平衡的数据集。这种不平衡程度非常类似于我最近参与的一个机器学习项目,在实践中看到这样的数据集并不罕见。

随机欠采样

首先,让我们看看欠采样。这种技术非常简单,包括从多数类中随机选择样本,并将这些样本与我们的少数类一起用于训练数据。结果是我们得到了相同数量的正面和反面的例子,可以避免上述问题。这种技术的优点是非常容易实现,而且非常有效。不利的一面是,你实际上是在丢弃数据。我可能不喜欢这种方法,除非我的训练数据非常大,并且我有能力扔掉这些数据。在下面的图 2 中,我们可以看到实现这一点的代码以及欠采样后的训练集。请注意我们删除了多少数据。

图 2:训练数据(左),欠采样(右)

随机过采样

过采样与欠采样相反。使用这种方法,我们从少数类中随机抽取数据,并复制它以创建更多的样本。我们这样做,直到类分布相等。尽管这对于解决失衡很有用,但也有一些缺点。最主要的一点是我们正在复制已经存在的数据。这意味着我们实际上并没有给分类问题添加任何额外的信息,这可能会导致过度拟合,这是我们绝对希望避免的。

图 3:训练数据(左),过采样数据(右)

合成少数过采样技术

顾名思义,SMOTE 是一种过采样方法,用于从我们已经拥有的数据中生成额外的数据。它类似于随机过采样,但我们不是复制现有数据,而是生成新的合成数据。最初的论文对该技术描述如下:

“通过获取每个少数类样本并沿着连接 k 个少数类的任何/所有最近邻居的线段引入合成样本,对少数类进行过采样”。

那么这意味着什么呢?嗯,该算法首先使用 k-最近邻来决定我们将使用哪些数据点来产生新数据。为简单起见,假设我们选择 k = 1。该算法将在我们最近邻的数据点之间创建一条线段,并沿着这条线在某处产生一个新的数据点。假设我们正在生成数据的特性是自用户上次访问我们的网站以来的天数。为了生成新的合成数据,该算法计算两个新变量。 间隙 是介于 0 和 1 之间的随机数,假设我们得到 0.8,以及 diff, 是用户最后一次访问我们的第一个数据点(20)和它的最近邻居(15)的天数之差。该特征的合成数据值为:24 = 20+(20–15)* . 8。

好的,让我们看看如何用 python 实现它,并可视化算法产生的结果。你可能会认为图表看起来有点奇怪,我可能会同意,但这只是算法的人工产物,并强调数据是“合成的”而不是全新的,因为它直接取决于其他数据点(或至少是最接近的数据点)。

图 4:训练数据(左),SMOTE(右)

这些技术各有利弊,但在实践中,我建议尝试所有这些技术,看看哪种效果最好,并让您的模型度量来指导您。

对于那些对细节更感兴趣的人,这里有一个全文链接:https://arxiv.org/pdf/1106.1813.pdf

类别加权

正如我上面提到的,许多机器学习算法假设类分布是相等的,所以它们可能不能很好地开箱即用。逻辑回归就是这种情况。为了避免这个问题,在 sklearn 中有一个很好的参数叫做class _ weights,它让我们告诉模型什么是类分布。这是一个简单而有效的解决方案,过去我发现它非常成功。更具体地说,它将更多地惩罚在少数群体中犯错误的模型。这些错误将使最小化成本函数变得更加困难,因此模型学习更加强调正确地得到少数类。

下面的代码展示了我们如何用 python 实现这一点。我们可以选择 class_weight = 'balanced ',或者传递一个具有特定类权重的字典,例如 weights = {0:0.01,1:1.0}

在向您介绍和解释了各种技术之后,我想我也将分享我与一位同事在讨论不平衡数据时的一段有趣对话。他指出:

使用逻辑回归等模型时,不平衡数据并不重要,只要它不影响系数估计值(仅截距)。

截距将根据不平衡进行调整,系数将保持不变。经过思考,我意识到他是对的。然而,这有一个问题。如果你画出预测概率的分布,你可能会看到一个非常偏斜的分布。例如,当我这样做的时候,我的分布范围是从 0 到 0.2。这对我来说是一个问题,特别是当模型的输出需要被解释并向你公司的业务团队解释的时候。仅仅因为这个原因,我认为重新平衡数据要好得多,尽管原则上逻辑回归可以处理不平衡。

算法和度量

正如我前面提到的,在处理不平衡数据时,算法的选择也会极大地影响您的结果。选择合适的指标来评估模型的性能也是非常重要的。同样,在这种情况下,准确性不是一个特别有用的衡量标准。使用 ROC AUC、Precision 和 Recall 以及混淆矩阵等指标,我们可以更好地了解模型的表现。

在这里,我不会深入探讨这些指标是如何工作的,但这里有一些资源可以详细介绍这些指标。

测试不同的方法

好了,这是足够的背景材料,让我们进入有趣的部分,看看这个例子的一些代码。我最近不得不在一个项目中应用这些技术,它们对我来说相当不错。不幸的是,由于数据是敏感的,我不能显示它,但我们可以通过生成一些数据来重新创建一个类似的场景。在任何情况下,我在这里展示的技术和代码应该可以很容易地转移到其他分类问题上。下面我们将评估几个不同的模型,看看它们在不平衡数据集上的表现。然后,我们将尝试上述技术,看看它们如何使用一些关键的分类性能指标来改善我们的结果。

生成建模数据

同样,我们可以使用 sklearn 中的 make_classification 函数来创建不平衡数据集。对于这个例子,我们将有 1%的正面例子和 99%的负面例子。

Imblearn 管道

为了使用不同的采样技术来估计这些模型,我们将使用 imblearn 管道。我相信你们中的一些人听说过 sklearn 管道,这些管道本质上是相同的,但专门用于采样技术。据我所知,目前还不能在 sklearn 管道上使用这些采样技术。这是我第一次使用管道,我不得不说,它们让你的代码更干净,更容易阅读。它们非常方便,所以我一定会将它们融入到我的工作流程中。

要使用这些管道,我们需要做的就是创建一个采样类和算法的实例,然后将它们作为元组传递给管道类。我最初试图看看我是否可以将多个算法传递到管道中,即逻辑回归和随机森林,但这不起作用。然而,如果你用一个合适的变换方法传递算法,比如 PCA,它应该工作得很好。从 imblearn 文档中:

管道的中间步骤必须是转换器或重采样器,也就是说,它们必须实现 fit、transform 和 sample 方法。

逻辑回归管道代码

随机森林管道代码

结果

逻辑回归

不平衡数据

图 5:逻辑回归:不平衡

我们可以看到,不平衡数据集的结果并没有那么好。阈值为 0.5 的模型表现非常差,几乎没有识别出我们的正面例子。我们可以尝试适当地改变阈值,但这将再次给我们非常倾斜的概率输出。我们还可以从我们的 PR 曲线中看到,该模型很难在不犯很多错误的情况下识别积极的标签。有趣的是,中华民国实际上看起来很好。这突出表明,在处理不平衡数据时,ROC 可能是一个误导性的指标。要了解这里发生了什么,想想 ROC 正在绘制的图,真阳性率(TPR)对假阳性率(FPR)。以下是 TPR 和 FPR 的定义。

  • 召回/TPR = TP / (TP+FN)
  • FPR = FP / (FP + TN)

因为我们的阶级不平衡,我们有更多的反面例子。本质上,我们的模型偏向于预测负面例子,所以我们有很多真正的负面(TN)。这使得我们的假阳性率(FPR)不会增加太多,因为我们的 TN 将在分母中增加。这就是为什么我们可以获得高 AUC,即使我们在对正面例子(我们最关心的例子)进行分类时做得不好。然而,如果我们使用精确和回忆,这个问题就被避免了,因为我们根本没有使用真正的否定(TN)。

  • 精度= TP/(TP+FP)
  • 召回/TPR = TP/(TP+FN)

在这种情况下,我倾向于使用混淆矩阵和 PR 曲线来衡量模型的性能。注意,我使用了自己创建的几个助手函数来绘制这些指标。代码位于这篇文章的底部。所有显示的数字都使用默认阈值 0.5。根据您的使用情况,这可以很容易地改变,以根据需要调整预测。

我们的抽样方法怎么样?

总的来说,不同取样方法的结果几乎完全相同。那么这种情况下我们应该怎么做呢?总的来说,这些结果不是很好,所以在这一点上,我建议尝试其他模型。但是,如果我们决定估计一个逻辑回归,我们有一个大的数据集,我们可以支持欠采样,因为它是三个选项中最不复杂的,并尝试优化我们的决策阈值,以提高我们的 TP 率。

欠采样

图 6:逻辑回归欠采样

过采样

图 7:逻辑回归过采样

重击

图 8:逻辑回归 SMOTE

随机森林

所以逻辑回归在这个问题上表现不太好,我们试试随机森林怎么样。这些模型往往在实践中表现良好,它们通常是我解决分类问题的首选模型。至于结果,该模型在识别 9% TP 的缺省阈值下对不平衡数据的表现略好于逻辑回归。显然,我们想要比这更好的东西,所以让我们再次尝试我们的采样技术。

比较这三种采样方法表明,欠采样对 65%的真阳性进行了最好的分类。它在识别真正的负面因素方面也比逻辑回归做得更好。然而,我们最好的结果来自于平衡类权重。因为这在 sk learn(class _ weights = ' balanced ')中很容易做到,而且我们不必丢弃任何数据,所以这是我的首选。这样做给了我们 70%的 TP 率。

我们还能做些什么来提高模型得分?

这里我们还可以尝试一些其他的事情来提高我们的模型性能,并确保我们的预测是稳健的。

  1. KFold 交叉验证:我在这里没有执行交叉验证,但是我建议这样做。使用 sklearn 使用cross _ val _ score真的很简单。
  2. 其他车型:SVM、lightGBM、XGBoost 等等。
  3. 超参数优化 :这对于有许多超参数的模型特别有用。

欠采样

图 9:随机森林欠采样

过采样

图 10:随机森林过采样

重击

图 11:随机森林重击

类别权重

图 12:随机森林类权重

主要要点

那么我们能从这些例子中学到什么呢?

  • 有许多方法可以解决不平衡数据的问题,每种方法的有效性很可能取决于您的问题和数据。
  • 为特定问题选择合适的指标很重要:我建议多看一个。没有一个指标是完美的。
  • 尝试多种算法可以给出更好的结果:每种算法都有自己的优点和缺点:例如,随机森林通常表现更好,但可能比逻辑回归更难解释,它们在计算上也更复杂。
  • 不重新平衡数据会导致输出概率非常不准确,难以解释和说明。
  • 改变阈值也是有效的:改变多少取决于你的模型犯错误的相对成本。

好了,伙计们,这篇文章到此为止,一如既往地感谢你的阅读,我希望你觉得这很有用。

帮助器函数的 Python 代码

下面是一些有用的函数来帮助我们评估我们的模型性能。

[## 丹尼尔·福利-数据科学家-产品疯狂| LinkedIn

在全球最大的职业社区 LinkedIn 上查看丹尼尔·福利的个人资料。丹尼尔列出了 5 份工作…

www.linkedin.com](https://www.linkedin.com/in/daniel-foley-1ab904a2/)

我的其他一些帖子你可能会感兴趣

[## 让我们建立一个流数据管道

用于实时数据管道的 Apache Beam 和数据流

towardsdatascience.com](/lets-build-a-streaming-data-pipeline-e873d671fc57) [## 高斯混合模型(GMM)

使用无监督学习理解文本数据

towardsdatascience.com](/gaussian-mixture-modelling-gmm-833c88587c7f) [## k 均值聚类

使用无监督学习理解文本数据

towardsdatascience.com](/k-means-clustering-8e1e64c1561c)

超越 CUDA: GPU 加速的 C++在跨厂商显卡上进行机器学习,使用 Kompute 变得简单

原文:https://towardsdatascience.com/machine-learning-and-data-processing-in-the-gpu-with-vulkan-kompute-c9350e5e5d3a?source=collection_archive---------11-----------------------

通过使用 Kompute 框架和 Vulkan SDK 的实际机器学习示例介绍 GPU 计算

C++中 Vulkan SDK 和 Kompute 的视频概述

机器学习,以及许多其他高级数据处理范例,非常适合 GPU 计算提供的并行处理架构。

图片作者作者

在本文中,您将学习如何用 GPU 优化代码从头开始编写自己的 ML 算法,该算法将能够在几乎任何硬件上运行,包括您的手机。我们将介绍核心的 GPU & ML 概念,并展示如何使用 Kompute 框架 只用几行代码就能实现它。

我们将首先构建一个简单的算法,将两个数组并行相乘,这将介绍 GPU 处理的基础知识。然后,我们将在 GPU 中从头开始编写一个逻辑回归算法。您可以在以下链接中找到回购协议的完整代码:

动机

近年来,GPU 计算的潜力和采用率一直呈爆炸式增长——从下图中的图表可以看出采用率的增长速度。在深度学习中,采用 GPU 进行处理的数量大幅增加,同时支持在越来越多的 GPU 节点上大规模并行分配计算任务的范例也大量增加。有许多令人兴奋的研究围绕着技术,这些技术提出了实现模型并行性数据并行性的新方法——这两种方法都允许算法和数据分别细分为广泛的方法,以最大限度地提高处理效率。

本农、塔尔和托尔斯滕·霍夫勒。“揭开并行和分布式深度学习的神秘面纱:深度并发分析。”美国计算机学会计算调查(CSUR)52.4(2019):1–43。

在本文中,我们概述了理论,并实践了一些工具,这些工具将使初学者和经验丰富的 GPU 计算从业者能够利用这些迷人的高性能计算领域的当前开发和讨论,并为之做出贡献。

Vulkan 框架

在开始之前,有必要介绍一下核心框架,它使得构建超优化、跨平台和可扩展的 GPU 算法成为可能,这就是 Vulkan 框架。

与 Khronos 成员一起玩“瓦尔多在哪里”(图片由 Vincent Hindriksen 通过 StreamHPC 提供)

Vulkan 是由 Khronos Group 领导的一个开源项目,Khronos Group 是一个由大量技术公司组成的联盟,他们聚集在一起致力于定义和推进移动和桌面媒体(和计算)技术的开放标准。在左边,你可以看到范围广泛的 Khronos 成员。

您可能想知道,为什么我们还需要另一个新的 GPU 框架,而这里已经有许多选项可用于编写可并行化的 GPU 代码?主要原因是,与一些闭源的同类产品(如 NVIDIA 的 CUDA 或苹果的 Metal)不同,Vulkan 是完全开源的,并且与一些旧的选项(如 OpenGL)不同,Vulkan 是以现代 GPU 架构为基础构建的,提供了非常细粒度的 GPU 优化。最后,虽然一些替代产品为 GPU 提供了特定于供应商的支持,但 Vulkan 提供了跨平台跨供应商支持,这意味着它打开了移动处理、边缘计算等领域的机会之门。

Vulkan SDK 提供对 GPU 的非常低级的访问,这允许非常专业的优化。这对 GPU 开发人员来说是一笔巨大的财富——主要缺点是冗长,需要 500–2000 多行代码才能获得编写应用程序逻辑所需的基本样板文件。这不仅会导致昂贵的开发周期,而且容易导致更大问题的小错误。

这实际上可以在许多新的和知名的机器学习和深度学习项目中看到,如 Pytorch、Tensorflow 和阿里巴巴 DNN 等,这些项目已经集成或正在寻求集成 Vulkan GPU SDK,以添加移动 GPU(和跨供应商 GPU)支持。所有这些框架都以非常相似和极其冗长的样板代码告终,这意味着它们会从使用统一的基线中受益(并且仍然会受益)。这是我们启动 Kompute 项目的主要动机之一。

输入 Kompute

Kompute 是一个构建在 Vulkan SDK 之上的框架,专门用于扩展其计算能力,作为一个简单易用、高度优化、移动友好的通用 GPU 计算框架。

Kompute 文档(图片由作者提供)

Kompute 不是为了隐藏任何核心的 Vulkan 概念而构建的 Vulkan API 设计得非常好——相反,它通过 BYOV(自带 Vulkan)设计增强了 Vulkan 的计算能力,通过减少所需的样板代码和自动化编写 Vulkan 应用程序中涉及的一些更常见的工作流来支持开发人员。

对于想了解更多信息的新开发人员来说,它为开始使用 GPU 计算提供了坚实的基础。对于更高级的 Vulkan 开发人员,Kompute 允许他们将其集成到现有的 Vulkan 应用程序中,并通过在需要时访问所有 Vulkan 内部来执行非常精细的优化。该项目是完全开源的,我们欢迎错误报告、文档扩展、新示例或建议——请随时在回购中提出问题

编写你的第一个计算机

为了使用 Kompute 构建我们的第一个简单的数组乘法 GPU 计算应用程序,我们将创建以下内容:

  • 两个康普顿张量存储输入数据
  • 一个计算机张量存储输出数据
  • 一个计算机操作创建并复制张量到 GPU
  • 带有 Kompute 算法的 Kompute 操作,该算法将保存要在 GPU 中执行的代码(称为“着色器”)
  • 将 GPU 数据同步回本地张量的 Kompute 操作
  • 一个 Kompute 序列记录操作,批量发送到 GPU(我们将使用 Kompute 管理器来简化工作流程)

Kompute 建筑设计(图片由作者提供)

Kompute 的核心是用于 GPU 操作的“Kompute 操作”,以及处理 GPU 数据和内存的“Kompute 张量”操作。更具体地说,这个图显示了 Kompute 组件之间的关系(包括显式内存所有权)。

当与 GPU 交互时,您必须将指令发送给 GPU 来执行,并且您需要确保 GPU 在 GPU 内存中有所有可用的相关数据来开始处理。使用 Vulkan,您可以通过队列将这些指令发送到 GPU,因此为了直观地简化事情,您可以将您的 GPU 视为远程服务器,其中数据序列化、资源创建和内存分配是昂贵的,并且指令是通过队列提交的——仍然有 GPU-CPU 共享内存,但您倾向于仅将它用于向 GPU 传输数据。

让我们直接进入代码。通常,在 Kompute 应用程序中,我们将遵循以下步骤:

  1. 创建 Kompute 管理器来管理资源
  2. 创建 Kompute 张量来保存数据
  3. 使用 Kompute 操作初始化 GPU 中的 Kompute 张量
  4. 将在 GPU 上运行的代码定义为“计算着色器”
  5. 使用 Kompute 操作对 Kompute 张量运行着色器
  6. 使用 Kompute 操作将 GPU 输出数据映射到本地张量
  7. 打印您的结果

1.创建 Kompute 管理器来管理资源

首先,我们将创建 Kompute 管理器,它负责创建和管理所有底层 Vulkan 资源。

正如你所看到的,这里我们正在初始化我们的 Kompute 管理器,期望它在设备 0 上创建所有的基本 Vulkan 资源(在我的例子中,设备 0 是我的 NVIDIA 卡,设备 1 是我的集成显卡)。对于更高级的用例,也可以用自己的 Vulkan 资源(设备、队列等)初始化 Kompute 管理器,但这超出了本文的范围。

2.创建 Kompute 张量来保存数据

我们现在将创建用于输入和输出的 Kompute 张量。这些将保存所需的数据,这些数据将被映射到 GPU 来执行这个简单的乘法。

Kompute 设计使用std::shared_ptr的原因是为了避免通过值传递对象,而是使用智能指针传递对象。

3.使用 Kompute 操作初始化 GPU 中的 Kompute 张量

现在我们已经用本地数据创建了张量,我们将把数据映射到 GPU 中。为此,我们将使用[kp::OpTensorCreate](https://axsaucedo.github.io/vulkan-kompute/overview/reference.html#optensorcreate) Kompute 操作,该操作将初始化底层 Vulkan 缓冲区和 GPU 内存,并执行到 GPU 的相应映射。

同样值得一提的是,通过利用 Kompute 管理器buildTensor助手功能,可以缩短张量创建的步骤。这将允许您跳过显式创建shared_ptr以及下面概述的kp::OpTensorCreate操作的需要(您也可以在这里找到这个变体的完整代码实现)。

4.将在 GPU 上运行的代码定义为“计算着色器”

现在我们已经初始化了必要的 Kompute 张量分量,并且它们被映射到 GPU 内存中,我们可以添加将在 GPU 中执行的 Kompute 算法。这被称为“着色器”代码,遵循类似 C 的语法。你可以在下面看到完整的着色器代码,我们将在下面分解每个部分。

#version 450layout(local_size_x = 1) in;部分指定了版本和并行线程执行结构(我们将在文章的后面进一步研究)。然后,我们可以看到以以下格式定义的 GPU 数据输入和输出:

*layout(binding = <INDEX>) buffer <UNIQUENAME> {float <VARNAME>[]};*

  • —将张量映射到 GPU 输入的索引
  • —这必须是缓冲区的唯一名称
  • —这是在着色器代码中使用的变量名

这些是可以在着色器代码中用于处理的参数。也就是说,在这种情况下,处理是在main 函数内部完成的。第一个变量uint index = gl_GlobalInvocationID.x;是当前的并行执行指数,它将允许我们处理每个数据输入。

然后,我们进入该算法的核心,即乘法o[index] = a[index] * b[index]. ,这一部分非常简单明了——我们将 GPU 数组a[]b[]的元素相乘,然后将输出存储在数组o[]中。

5.使用 Kompute 操作对 Kompute 张量运行着色器

为了运行上面的着色器,我们将创建 Kompute 操作[kp::OpAlgoBase](https://axsaucedo.github.io/vulkan-kompute/overview/reference.html#opalgobase)。这个 Kompute 操作所需的参数包括绑定到 GPU 指令中的张量,以及着色器代码本身。

值得一提的是,Kompute 允许用户通过文件路径传递着色器,或者也有 Kompute 工具允许您将着色器二进制文件转换为 C++头文件。

6.使用 Kompute 操作将 GPU 输出数据映射到本地张量

一旦算法被触发,结果数据将保存在输出张量的 GPU 内存中。我们现在可以使用[kp::OpTensorSyncLocal](https://axsaucedo.github.io/vulkan-kompute/overview/reference.html#optensorsynclocal) Kompute 操作按照下面的代码块同步 Tensor GPU 内存。

7.打印您的结果

最后,我们可以打印出张量的输出数据。

当你运行它时,你会看到输出张量的值被打印出来。就这样,你写了你的第一个 Kompute!

您也可以在 repo 中找到完整的示例,这样您就可以运行它并根据需要扩展它。你可以在这个库中找到完整的独立示例,其中包括如何构建它的说明以及 Kompute C++代码

虽然看起来不明显,但上面介绍了 GPU 计算中核心概念和设计思维的一些直觉,同时还抽象了一些更深入的概念。在接下来的几节中,我们将提供更具体的术语,我们将触及一些更高级的概念,如线程、块、内存步长和共享内存(尽管很多内容将作为进一步的阅读材料提供)。

潜入机器学习直觉

让我们看一个更高级的 GPU 计算用例,具体实现机器学习的 hello world,逻辑回归。在我们介绍实现之前,我们将提供一些理论上的直觉,以及我们将贯穿始终使用的术语。

在机器学习中,我们总是有两个阶段,训练和推理。在下图中,您可以看到两个简化的流程。最上面是训练流程,在这里你识别一些训练数据,提取一些特征,训练一个模型,直到你对精度满意为止。一旦您有了一个经过训练的模型,您就可以持久化模型“权重”,并将模型部署到第二个工作流中,在第二个工作流中,模型将对看不见的数据执行推理。

数据科学流程(图片由作者提供)

在这种情况下,我们将有一个输入数据集X,其中每个元素是一对xixj。我们的输入数据如下:

  • xi = { 0, 1, 1, 1, 1 }
  • xj = { 0, 0, 0, 1, 1 }

利用该输入数据,要预测的预期目标值Y将如下:

  • Y = {0, 0, 0, 1, 1}

来自 DS Central 的逻辑回归示例

我们在机器学习中的主要目标是学习使用这些数据来找到函数(和参数),这将允许我们仅使用X作为输入来预测值Y

值得注意的是,预测值被定义为ŷ,它是用我们的推理函数计算出来的值,不同于我们上面定义的Y的“真”或“实际”值。

我们将用于逻辑回归的函数如下:

让我们来分解这个函数:

  • z——是我们的线性映射函数
  • ŷ—结果预测输出
  • Xᵀ——包含我们的输入 xi 和 xj 的矩阵的转置
  • σ—sigmoid 函数,将在下面详细介绍

我们希望通过机器学习算法学习的参数是:

  • W —将应用于输入的权重
  • b —将要添加的偏差

还有环绕函数σ 也就是 sigmoid 函数。该函数迫使我们的输入更接近 0 或 1,这可以直观地视为我们预测为“真”的概率,定义如下:

这就是现在的推理功能,它将允许我们处理来自新数据点的预测。例如,如果我们说我们有一组新的看不见的输入X = { (0, 1) },并且我们假设在通过我们的训练数据运行我们的机器学习算法之后,学习到的参数是W = (1, 1), b = 0 (稍后我们将这样做),那么我们将能够通过我们的预测函数来运行它,方法是代入以下值:

在这种情况下,预测是0.73...,这将是一个肯定的预测。这当然只是为了演示一旦我们学习了参数Wb.我们的推理函数会是什么样子

ML Academy 可视化的梯度下降

我们学习参数的方法是进行预测,计算误差,然后相应地重新调整权重。用于基于“预测误差”来“重新调整”权重的方法将通过利用梯度下降来完成。这将被重复多次以找到更精确的参数。

为此,我们将需要使用每个公式的导数。第一个是我们的线性映射函数z的导数:

  • ∂z = z(x) - y

其中变量定义如下:

  • ∂z —线性映射函数的导数z(x)
  • z(x) —应用于输入x的线性映射函数的结果
  • y —输入 x 的预期实际值标签

类似地,w 和 b 的导数分别如下:

  • ∂w = (x - ∂z)/m
  • ∂b = ∂z/m

在这种情况下,m是输入元素的总数。

我们现在能够使用上述方法重新调整参数,如下所示:

  • w = w - θ ∂w
  • b = b - θ ∂b

在这种情况下,θ是学习率,顾名思义,它控制每次迭代中参数被修改的比率。直观地说,越小,算法收敛所需的迭代次数就越多,然而,如果学习量太大,它将会超调,导致永远无法收敛(从上面的图像中,你可以想象它将不断从一边跳到另一边,永远不会到达底部)。

为了计算损失,我们将使用对数损失函数,也称为交叉熵损失函数。该功能定义如下:

对数损失(交叉熵损失)函数

直观的图表,直观显示 ML Mastery 的成本函数

函数本身是这样设置的,预测类和期望类之间的差异越大,误差就越大(你可以看到如果预测类在完全不同的标签上,它会受到多大的惩罚)。

损失函数将为我们提供一个在迭代中改进算法的思路。

最后,这里最重要的一点将是我们如何利用 GPU 的并行架构来优化计算背后的直觉。在这种情况下,我们可以同时处理多个输入参数,称为微批处理,然后批量重新调整参数。这被称为数据并行化,是许多可用技术之一。在下一节中,我们将看到这是如何实现的,即传递一小批输入,存储权重,然后在下一次迭代之前重新调整它们。

注意:在这篇文章中,我们不会深入研究太多细节,也不会研究机器学习的最佳实践,但是在文章的最后,我们将列出一系列广泛的来源,供有兴趣将其机器学习(或 GPU 计算)知识提升到一个新水平的人使用。

机器学习 GPU 代码实现

现在我们已经讨论了一些核心概念,我们将能够了解着色器的实现,它是将在 GPU 中执行的代码。

首先,我们需要如下定义所有的输入和输出缓冲器:

如果您还记得,在上一节的结尾,我们提到了如何利用微批处理的概念来使用 GPU 处理的并行架构。这在实践中意味着,我们将把 X 的多个实例一次传递给 GPU 来处理,而不是期望 GPU 一个接一个地处理它。这就是为什么我们看到上面有一个分别用于xi, xj, y, wOuti, wOutj,bOut的数组。

更详细地说:

  • 作为数组 xi 和 xj 的输入X 将保存小批量的输入
  • 数组y 将保存微批量输入的所有预期标签
  • 两个输入权重参数winiwoutj将用于计算预测
  • 将用于计算预测的输入参数b
  • 输出权重woutiwoutj 包含权重,并将存储应被减去的所有微批次的 W 的导数
  • 类似地,输出偏差数组包含所有应批量减去的微量批次的b 的导数
  • 最后lout包含了损失将被返回的输出数组

我们还收到常数M,它将是元素的总数——如果你记得这个参数将用于导数的计算。我们还将看到这些参数是如何从 C++ Kompute 端传递到着色器的。

现在我们已经定义了所有的输入和输出参数,我们可以启动main函数,它将包含我们的机器学习训练算法的实现。

我们将首先跟踪全局调用的当前索引。由于 GPU 并行执行,这些运行中的每一个都将直接并行运行,因此这允许当前执行一致地跟踪当前正在执行的迭代索引。

我们现在可以开始准备所有的变量,我们将在整个算法中使用。我们所有的输入都是缓冲数组,所以我们希望将它们存储在 vec2 和 float 变量中。

在这种情况下,我们基本上明确了当前“线程运行”所使用的变量。GPU 架构由稍微更细微的执行结构组成,涉及线程块、内存访问限制等,但我们不会在本例中涉及这些。

现在我们进入更有趣的部分——实现推理功能。下面我们将实现推理函数来计算ŷ,它既涉及线性映射函数,也涉及 sigmoid 函数。

现在我们有了yHat,我们现在可以用它来计算导数(∂z、∂w 和∂b),在本例中是当前执行的索引输入元素的导数。

我们现在可以将导数作为输出传递,因此可以为下一次迭代重新调整参数。

最后,我们能够计算损耗并将其添加到输出lout数组中。

就这样,我们现在已经完成了着色器,这将使我们能够在 GPU 中训练逻辑回归算法——你可以在 GPU 逻辑回归示例库中找到着色器的完整代码。

现在,我们将介绍 Kompute 代码,该代码需要针对数据集运行,以训练我们的第一个模型并找到参数。

Kompute 的机器学习编排

为了使用 Kompute 在 GPU 中运行我们上面创建的着色器,我们将遵循以下步骤:

  1. 导入 Kompute 并创建我们的主要功能
  2. 创建所有需要的 Kompute 张量
  3. 创建 Kompute 管理器并初始化 Kompute 序列
  4. 通过 Kompute 序列执行 Kompute 张量 GPU 初始化
  5. 记录 Kompute 序列中的批处理算法执行
  6. 迭代 100 次:运行微批处理执行并更新权重
  7. 打印结果参数,用于进一步推断

如你所见,这比我们上面使用的简单例子更复杂。在这种情况下,我们将使用 Kompute 序列,而不是直接使用 Kompute 管理器,因为我们希望对命令进行更深入的控制,这些命令可以被记录下来并批量发送到 GPU。我们将在讲述每个步骤时更详细地讨论这一点。让我们开始吧。

1.导入 Kompute 并创建我们的主要功能

我们将导入 Kompute 的单个头文件——如果需要,也可以使用更细粒度的基于类的头文件。我们还将创建一些基本配置变量;即ITERATIONSlearningRate,它们将在后面的码块中使用。

2.创建所有需要的 Kompute 张量

现在我们将创建所有需要的张量。在这一小节中,你会注意到我们将引用着色器中使用的所有缓冲区/数组。我们还将介绍参数传递的顺序如何与数据绑定到着色器的方式相关联,以便可以访问数据。

我们还将它们存储在一个参数向量中,以便于访问:

3.创建 Kompute 管理器并初始化 Kompute 序列

如果您还记得前面的例子,我们能够使用 Kompute 管理器直接执行命令。然而,如果我们想要更精细地记录可以在处理之前提交并加载到 GPU 中的命令批次,我们可以使用 Kompute 序列资源。为此,我们将创建一个 Kompute 管理器,然后通过它创建一个 Kompute 序列。

4.通过 Kompute 序列执行 Kompute 张量 GPU 初始化

我们现在可以从在 GPU 资源上运行指令开始——也就是说,我们将从初始化张量并将其映射到各自的 GPU 内存开始。在这里,您将看到 Kompute 序列如何在命令执行上为您提供进一步的粒度,但是直到 ML 推理部分,您才会看到 Kompute 序列的灵活性。

让我们从记录命令开始,即 OpTensorCreate 命令,然后评估上面所有张量的操作。此操作将创建各自的 Vulkan 内存/缓冲区资源。

5.记录 Kompute 序列中的批处理算法执行

在本节中,我们将清除 Kompute 序列的先前记录,并开始记录一组序列。您会注意到,与前一节不同,在这种情况下,我们不会立即运行eval(),因为我们必须多次运行它,并使用额外的命令来重新调整参数。

您还会注意到,我们将记录三种类型的 Kompute 操作,即:

  • [kp::OpTensorSyncDevice](https://axsaucedo.github.io/vulkan-kompute/overview/reference.html#optensorsyncdevice) —此操作通过将张量的本地数据映射到 GPU 数据,确保张量与其 GPU 内存同步。在这种情况下,这些张量使用设备专用内存来提高处理效率,因此在操作中使用分级张量来执行映射(为了提高效率,在整个操作中重复使用分级张量)。在这里,我们只想同步输入权重,因为这些权重将随各自的导数在本地更新。
  • [kp::OpAlgoBase](https://axsaucedo.github.io/vulkan-kompute/overview/reference.html#opalgobase) —这是一个 Kompute 操作,将我们上面写的着色器与所有本地 CPU/主机资源绑定在一起。这包括提供张量。值得一提的是,作为参数提供的张量的索引是它们通过各自的绑定在着色器中映射的顺序(正如您可以在着色器中看到的,每个向量都具有格式layout(binding = NUMBER))。
  • [kp::OpTensorSyncLocal](https://axsaucedo.github.io/vulkan-kompute/overview/reference.html#optensorsynclocal) —该 Kompute 操作执行与上述同步操作类似的一组指令,但它不是将数据复制到 GPU 存储器,而是相反。这个 Kompute 操作将 GPU 内存中的数据映射到本地张量向量,因此可以从 GPU/主机访问它。如你所见,我们只在输出张量中运行这个操作。

6.迭代 100 次:运行微批处理执行并更新权重

现在我们已经记录了命令,我们可以开始运行这些预加载命令的执行。在这种情况下,我们将运行一个微批处理迭代的执行,然后在本地更新参数,以便在接下来的迭代中使用它们。

7.打印结果参数,用于进一步推断

我们现在有了一个经过训练的逻辑回归模型,或者至少我们已经能够优化其各自的功能,以确定合适的参数。我们现在能够打印这些参数,并在看不见的数据集中使用这些参数进行推理。

我们完事了。

您可以在示例存储库中找到这个完整的示例,您将能够运行和扩展它。你会在 GPU 逻辑回归示例 repo 中找到所有完整的文件,包括 Kompute C++代码,以及着色器文件

接下来呢?

恭喜你,你一路走到了最后!虽然这篇文章涵盖了广泛的主题,但是也有大量的概念被浏览过。其中包括底层 Vulkan 概念、GPU 计算基础、机器学习最佳实践和更高级的 Kompute 概念。幸运的是,网上有大量的资源可以扩展你在这些方面的知识。我推荐作为进一步阅读的一些链接包括:

使用 Libra 的线性机器学习和深度学习

原文:https://towardsdatascience.com/machine-learning-and-deep-learning-in-one-liner-using-libra-7eef4023618f?source=collection_archive---------58-----------------------

自动化机器学习和深度学习理解 Libra 的完全指南。

照片由布雷特·乔丹Unsplash 拍摄

随着机器学习的兴起,我们看到了许多伟大的框架和库的兴起,如 sci-kit learn、Tensorflow、Pytorch。这些框架使得用户可以更容易地创建机器学习模型。但是仍然需要遵循整个过程,包括数据准备、建模和评估。数据准备包括数据清洗和预处理。建模接受预处理的数据,并使用算法来预测结果。评估为我们提供了一个衡量算法性能的方法。由于这些库和框架,我们写所有东西的时间减少了,但是我们仍然需要写少量的代码。

"机器智能是人类需要创造的最后一项发明."尼克·博斯特伦

在令人惊叹的开源社区的帮助下,这个领域的进步与日俱增,这些社区催生了现有的框架。想象一个在一行中完成上述所有过程的框架。是的,你没看错,现在你也可以这么做了。Libra 是一个框架,它在一行中为你做了这些工作。即使对于非技术人员来说,它也很容易使用。Libra 需要最少的平均行数来训练模型。

图片取自文档

在这篇博客中,我将给出如何使用天秤座的完整指导。我将针对不同的问题采用不同的数据集,并向您展示一步一步的方法。

使用 Libra 检测信用卡欺诈

我已经使用 Kaggle 数据集来预测信用卡欺诈。该数据已经经过主成分分析,因此与原始数据相比,它现在减少到更少的维度数据。解决这个问题需要遵循一个系统的方法。一般来说,你会按照第一段提到的顺序。但是和天秤座在一起,就不用担心这个了。

数据集的链接https:/[/www.kaggle.com/mlg-ulb/creditcardfraud](https://colab.research.google.com/drive/1khr-nqQVkP_XMUQ5y8GWrK5AUS41lyzC#)

该数据中的大多数交易在 99.83%的时间内是非欺诈性的,而欺诈性交易在数据集中的 0.17%的时间内发生。这意味着数据是高度不平衡的。让我们看看 Libra 对数据的预处理有多好,并给出结果。

安装 Libra

pip install -U libra

从 libra 导入客户端

from libra import client

利用天秤座

一切都是围绕客户机对象构建的。您可以对它调用不同的查询,所有内容都将存储在对象的 models 字段下。

我们在客户机对象中传递文件的位置,并将其命名为 newClient。现在要访问各种查询,请参考文档。我在这里使用决策树。英语中的指令是一个陈述,代表你想要完成的任务。比如预测房子价值中位数,或者请估计一下家庭人数。否则,该指令应该对应于数据集中的一列。Libra 自动检测目标列,但是为了确保它选择了正确的列,我传递了目标列名。

newClient = client('creditcard.csv')newClient.decision_tree_query('Class')

仅用两行代码,我们就获得了大约 0.99 的分数,这是我们能得到的最好分数。如果您查看其他内核,您会发现只有少数人获得了 0.99 的精度,并且他们需要花费数小时来预处理数据并为其编写代码。那样的话,天秤座为你节省了很多时间,给了你最好的结果。Libra 使用智能预处理,这样你就不需要自己预处理数据了。

你不需要担心分析结果。

newClient.analyze()为所有分类问题创建混淆矩阵和 ROC 曲线。它还计算召回率、精确度、f1 和 f2 分数。

newClient.analyze()

newClient.info()返回所有键,代表为数据集生成的每一类数据。

newClient.info()

newClient.model()返回该模型的字典。它包括从准确度、精确度、召回率、F1 分数到所有预处理技术的一切。对于已经了解这些概念并能编码的人更有帮助。非技术用户无需担心这一点。

newClient.model()

访问模型

返回一个字典,如果你想访问模型,你可以直接使用 newClient.model()['model']

newClient.model()['model']

使用 Libra 的卷积神经网络

使用下面的代码在 colab 笔记本上下载 Laurence Moroney 的石头、纸、剪刀数据集。我可以直接向您展示使用 Libra 创建 CNN 的代码,但是我想创建一个示例,您可以在自己的 colab 笔记本中尝试,以便更好地理解。你不需要担心下面的代码。

!wget --no-check-certificate \https://storage.googleapis.com/laurencemoroney-blog.appspot.com/rps.zip \-O /tmp/rps.zip!wget --no-check-certificate \https://storage.googleapis.com/laurencemoroney-blog.appspot.com/rps-test-set.zip \-O /tmp/rps-test-set.zip

使用下面的代码提取下载的文件。

import osimport zipfilelocal_zip = '/tmp/rps.zip'zip_ref = zipfile.ZipFile(local_zip, 'r')zip_ref.extractall('/tmp/')zip_ref.close()local_zip = '/tmp/rps-test-set.zip'zip_ref = zipfile.ZipFile(local_zip, 'r')zip_ref.extractall('/tmp/')zip_ref.close()

使用下面的代码创建文件夹,并将提取的图像放入其中。

rock_dir = os.path.join('/tmp/rps/rock')paper_dir = os.path.join('/tmp/rps/paper')scissors_dir = os.path.join('/tmp/rps/scissors')print('total training rock images:', len(os.listdir(rock_dir)))print('total training paper images:', len(os.listdir(paper_dir)))print('total training scissors images:', len(os.listdir(scissors_dir)))rock_files = os.listdir(rock_dir)print(rock_files[:10])paper_files = os.listdir(paper_dir)print(paper_files[:10])scissors_files = os.listdir(scissors_dir)print(scissors_files[:10])

下图显示了数据集的相关信息。

使用下面的代码,你可以创建 CNN。数据将通过缩放、剪切、翻转和重缩放自动增加。然后将选择最佳的图像尺寸。您还会注意到每个类中图像的数量以及与之相关的类的数量。最后,你还会观察训练精度和测试精度。

还可以在 convolutional _ query 内部传递read _ modehyper-parameter,在其中可以指定读取模式。允许三种读取模式。我将一一描述它们。默认情况下read _ mode = distinguisher()自动检测数据的类型。允许的三种读取模式是:

1.Setwise

目录由“训练集”和“测试集”文件夹组成,这两个文件夹都包含分类文件夹,文件夹内有图像。[1]

图片取自文档

2.按类别

目录由分类文件夹组成,里面有图像。[1]

图片取自文档

3。CSV Wise

目录由图像文件夹和包含图像列的 CSV 文件组成。[1]

图片取自文档

newClient = client('/tmp/rps')newClient.convolutional_query("Please classify my images")

基于 Libra 的自然语言文本分类

对于这个问题,我使用了垃圾短信分类数据集。

链接:https://www . ka ggle . com/team-ai/spam-text-message-class ification

new_client = client('SPAM text message 20170820 - Data.csv')new_client.text_classification_query('sentiment')new_client.classify_text('new text to classify')

new_client.classify_text()将对输入其中的文本进行分类。在上面的输出中,你可以看到它已经把我的文本归类为‘火腿’。

k 表示使用 Libra 进行聚类

这个问题我用的是商城客户细分数据:https://www . ka ggle . com/vjchoudhary 7/Customer-Segmentation-tutorial-in-python

数据集的图像。

下面的代码将创建一个 K 均值聚类模型,并确定最佳质心计数和优化精度,以及最佳的聚类数。

使用 Libra 进行分类的神经网络

在本节中,我将使用神经网络查询进行分类。为此,我使用一个私人数据集,从大脑信号预测行为。让我们来看看它在数据集上的表现如何。

new_client = client('Mood_classification.csv')new_client.neural_network_query('Predict the behavior')

从上面的代码中,您可以注意到模型使用的初始层数是 3。然后,它还使用根据前一层的性能而变化的不同层数来测试精度。它预测找到的最佳层数及其训练和测试精度。看起来我需要为我的数据集收集更多的数据。

您可以使用 new_client.model()['model']来访问模型,并可以使用 Keras 中的 summary()函数来获得神经网络模型的摘要。

new_client.model()['model'].summary()

结论

天秤座是一个非常有趣的框架,每天都在进步。该框架让我们大致了解了数据科学领域的发展速度,也让我们看到了该领域可能出现的变化类型。他们还为现有的数据科学家添加功能,以修改现有的神经网络,并在指定的索引处添加像 LSTM 这样的层。这个框架带来的概念让我兴奋不已。你也可以在 Github 上投稿。

参考资料:

[1] Libra,文献(2020),资料来源

机器学习与柏拉图的洞穴寓言

原文:https://towardsdatascience.com/machine-learning-and-platos-allegory-of-the-cave-9b9846bb63f3?source=collection_archive---------23-----------------------

当前机器学习的方法如何符合柏拉图著名的寓言以及我们将从那里走向何方。

洞穴的寓言由希腊哲学家柏拉图在他的作品共和国中提出,最初是T5,用来比较“教育和缺乏教育对我们本性的影响”。奇怪的是,事实证明,最先进的机器学习领域仍然或多或少地符合这个超过 2000 年的模具。

洞穴的寓言

这个寓言是从苏格拉底和他的弟子格劳肯之间的对话中得到阐释的。

简而言之,苏格拉底告诉格劳肯想象人们生活在一个巨大的地下洞穴中,只通过一条艰难而陡峭的隧道与外界相通。人们被铁链锁着,面对着一堵高墙,无法转过脸去,也无法挣脱锁链。在囚犯的背后,有一个巨大的火在燃烧,从而将人们身后发生的事情投射到囚犯面对的墙上,形成各种形状的影子。

由于人们在一生中从未能够转过脸来一点,他们看着墙上的影子长大和死去,这些影子构成了他们所有已知的现实。

MatiasEnElMundo / Getty Images

从象征意义上来说,墙上的阴影代表了表面的真相——一个“虚拟”的现实,只通过我们的感官感知,而不是终极的“真实”现实,根据柏拉图主义,它是由我们凡人永远无法通过感官了解的形式(想法)组成的。

此外,墙上的二维投影构成了可怜的囚犯的整个世界。他们好奇的头脑会尝试为这些幻影开发故事或历史——它们倾向于如何相互作用,何时一些影子倾向于一起出现,是否一个特殊的影子导致另一个出现,等等。他们推测并想象出最复杂的理论来解释影子的行为;然而可悲的是,他们仍然不知道阴影的真正本质。

如果他们可以转身,他们会发现他们最喜欢的一些影子理论是基于他们身后的一些骗子的一些糟糕的笑话,他们可能会在任何时候停止游戏,从囚犯队中消灭一些最好的模特。即使我们假设一个仁慈的世界,没有人在那里捉弄可怜的囚犯,任何时候一个三维图形出现的角度的微小随机调整都会在墙上的投影上造成很大的差异,肯定会在囚犯理论家中引起相当大的混乱。

机器学习做什么

尽管围绕机器学习或人工智能有各种宣传和承诺,但本质上,机器学习算法会查看一系列关于现象及其附加标签/值的观察结果(取决于它是分类任务还是回归任务),尝试提出一个由形状似乎与数据形状匹配的已知函数组成的函数,然后在新观察结果出现时继续指定标签或值。

马库斯·斯皮斯克在 Unsplash 上的照片

经验法则是:( 1)任何机器学习输出的质量在很大程度上取决于输入的质量。简单来说,垃圾进,垃圾出;(2)机器学习算法永远无法“学习”或发现任何我们未知的新规则。

换句话说,我们最终可以通过机器学习模型实现的目标一方面受到数据质量的限制,另一方面也受到精心制作这些模型的研究人员的已知“现实”的限制。

相似之处

暂时回到洞穴的寓言。显然,正如现实生活中的三维图形被投影为墙上的二维阴影一样,在日常的机器学习实践中,对现实生活中的对象(变量)的描述,当作为数字或分类数据记录下来时,从来都不是原始对象的完整画面。

原因可能是由于各种逻辑约束,我们缺乏对某些属性的测量,但更有可能的是,作为一个从出生起就受到各种启动和集体学习经验约束的人,我们只是缺乏甚至是一个对象的某些关键属性的存在的知识。显然,如果我们甚至没有意识到一个东西的存在,我们怎么能首先要求它,然后对它提出问题,最后测量它呢?

投影从来都不是对原始对象的良好描述

在这种情况下,目前为所有机器学习问题引入替代数据的努力非常有意义,值得称赞,因为我们已经意识到传统的特征集不再满足我们的需求,而且既然我们正在处理“影子”的数据,为什么不借用其他“影子”的片段来帮助我们解决现实问题呢?难怪工厂的卫星图像或社交网络情绪数据越来越多地被纳入自动交易模型;事实是,它们一直是预测股票表现的良好因素,而受困于资产负债表的老学生们只是错过了机会。

不难想象,每天都有数百万个机器学习模型在“影子”数据的基础上接受训练,同时承担着计算出产生数据的现实生活对象之间的关系(相关性,甚至因果关系,如果一些过度成就的项目经理要求的话)的任务。在不进入散发主义的新柏拉图主义主题的情况下,我们也许能够通过转向另一个例子来描述这一困境,散发主义基本上认为一切都源于完美的第一现实,当进一步从第一现实中派生和异化时,变得不那么纯粹和不那么完美。

在 Lewis Carroll 的小说透过镜子中,当白骑士向爱丽丝解释歌曲阿道克斯的眼睛时,作者讨论了“这首歌,这首歌叫什么,这首歌的名字,以及这首歌的名字叫什么”之间的区别。歌曲本身,作为一种柏拉图式的形式,产生了派生的形式,如歌曲的名字,甚至是歌曲的名字(这可以无限地继续下去);然而,这些衍生词甚至可能与歌曲的主题没有密切关系。尽管如此,在大多数情况下,(低级)派生是真实对象所知道和分析的,而对象本身仍然是不可言喻的或未知的。

奥卡姆剃刀

因此,当我们对一个物体进行观察的时候,一个推导就产生了,我们在墙上创造了一个影子。如果我们意识到,在一天结束时,我们正在处理“影子”数据集,我们可能会更好地设定我们对磨床学习模型的期望。通过释放我们的好奇心和想象力,并假设一个现实的参数化模型,我们也许能够意外地、短暂地打破我们头脑中的锁链,但显然奥卡姆剃刀支配着这个洞穴,顿悟的洞察力终究并不常见。

照片由视觉效果Unsplash 上拍摄

机器学习和信号处理

原文:https://towardsdatascience.com/machine-learning-and-signal-processing-103281d27c4b?source=collection_archive---------3-----------------------

机器学习性能与两种关键信号处理算法(快速傅立叶变换和最小均方预测)的有趣比较。

从信号处理的角度看机器学习和神经网络。

信号处理为我们提供了一套工具,在过去的五十年里,这些工具得到了完善并得到了很好的应用。举几个例子,有自相关、卷积、傅立叶和小波变换、通过最小均方(LMS)或递归最小二乘(RLS)的自适应滤波、线性估计器、压缩传感和梯度下降。不同的工具用于解决不同的问题,有时,我们结合使用这些工具来构建一个系统来处理信号。

机器学习或深度神经网络更容易适应,因为无论我们使用什么网络架构,底层数学都相当简单。神经网络的复杂性和神秘性在于它们处理的数据量,以获得我们目前拥有的迷人结果。

时间序列预测

本文旨在比较几种关键信号处理算法的神经网络性能。让我们看看时间序列预测作为第一个例子。我们将实现一个三层顺序深度神经网络来预测信号的下一个样本。我们也将以传统方式实现,使用抽头延迟滤波器,并根据均方误差调整权重,这就是 LMS 滤波,这是一种针对最优韦纳滤波器的迭代方法,用于从噪声测量中估计信号。然后我们将比较两种方法的预测误差。因此,让我们开始编写代码吧!

让我们首先导入我们需要的所有常用 python 库。由于我们将使用 TensorFlow 和 Keras 框架,我们也将导入它们。

用神经网络预测

让我们现在开始建立我们的 3 层神经网络。输入层获取 64 个样本并产生 32 个样本。隐藏层将第一层的这 32 个输出映射到 8 个样本。最后一层将这 8 个样本映射到 1 个预测输出。记住输入尺寸是由第一层的 input_shape 参数提供的。

我们将使用 Adam 优化器,而不考虑它是什么。这就是 TensorFlow 的好处,我们不需要知道神经网络使用这个惊人的框架构建一个网络所需的所有处理的每个细节。如果我们发现 Adam 优化器不能很好地工作,我们将简单地尝试另一个优化器 —例如 RMSprop。

现在让我们创建一个时间序列,一个简单的正弦波叠加。然后我们将添加噪声来模拟真实世界的信号。

现在我们有了数据,让我们考虑如何将这些数据输入神经网络进行训练。我们知道网络在输入端采集 64 个样本,产生一个输出样本。因为我们希望训练网络来预测下一个样本,所以我们希望使用第 65 个样本作为输出标签。

因此,第一个输入集是从样本 0 到样本 63(前 64 个样本),第一个标签是样本 64(第 65 个样本)。第二个输入集可以是一个单独的 64 个样本集(非重叠窗口),或者我们可以选择一个滑动窗口,从样本 1 到样本 64 取 64 个样本。让我们遵循滑动窗口方法,只是为了从我们拥有的时间序列中生成大量的训练数据。

还要注意,我们使用有噪声的样本作为输入,而使用无噪声的数据作为标签。我们希望神经网络即使在有噪声的情况下也能预测实际信号。

让我们看看时间序列数据和训练数据的大小。请注意,我们为时间序列数据生成了 5000 个样本,但我们为神经网络创建了 3935 x 64 = 251840 个输入数据样本。

train_data 的形状是输入集的数量 x 输入长度。这里,我们有 3935 批输入,每个输入有 64 个样本长。

print(y.shape, train_data.shape, train_labels.shape)(5000,) (3935, 64) (3935,)

我们现在准备训练神经网络。让我们首先实例化这个模型。模型摘要提供了关于有多少层、输出形状是什么以及我们需要为此神经网络训练的参数数量的信息。

对于第一层,我们有 64 个输入和 32 个输出。密集层实现等式 y = f(Wx + b) ,其中 f 是激活函数, W 是权重矩阵, b 是偏差。我们马上可以看到 W 是一个 64×32 的矩阵, b 是一个 32×1 的向量。这给了我们 32 x 64 + 32 = 2080 个参数来训练第一层。读者可以做类似的计算来验证第二层和第三层的参数,作为理解的练习。毕竟,除非你是机器学习的初学者并且渴望开始,否则你不会阅读这篇文章:)

model = dnn_keras_tspred_model()Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense (Dense)                (None, 32)                2080      
_________________________________________________________________
dense_1 (Dense)              (None, 8)                 264       
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 9         
=================================================================
Total params: 2,353
Trainable params: 2,353
Non-trainable params: 0
_________________________________________________________________

好吧,继续训练吧。由于我们使用的是 Keras 框架,训练就像调用 fit()方法一样简单。对于 TensorFlow,我们需要做更多的工作,但那是另一篇文章。

让我们使用 100 个历元,这只是意味着我们将一次又一次地使用相同的训练数据来训练神经网络,并将这样做 100 次。在每个时期,网络使用输入和标签集的批次数量来训练参数。

让我们使用日期时间来描述这个训练需要多长时间,以及作为 Python 字典返回的历史值,以获得每个时期之后的验证损失。

DNN training done. Time elapsed:  10.177171 s

现在网络已经训练好了,我们看到验证损失随着时间的推移已经下降到趋于平缓的程度(表明进一步的训练不会产生任何显著的改进),让我们使用这个网络来看看它相对于测试数据的表现如何。

让我们以与创建训练数据集完全相同的方式创建测试数据集,但是只使用我们以前没有用于训练的那部分时间序列。我们想用以前从未见过的数据给神经网络一个惊喜,以了解它的表现有多好。

我们现在将调用 Keras 框架中的 predict() 方法来获得测试数据集的神经网络输出。如果我们使用 TensorFlow 框架,这一步会有所不同,但我们将在另一篇文章中讨论这一点。

正如我们所看到的,神经网络的预测非常接近实际的无噪声数据!

用 LMS 算法预测

我们将使用 L=64 抽头滤波器来预测下一个样本。我们不需要那么大的滤波器,但是让我们保持每个输出样本的输入数量与我们用于神经网络的数量相同。

通过计算预测样本和测量样本之间的误差,并基于均方误差和输入测量值之间的相关性调整权重,获得滤波器系数(或权重)。

如代码所示, yrlms[k] 是输入为 ypn[k-L:k] 时的滤波器输出,误差计算为噪声测量值 ypn[k] 与滤波器输出 yrlms[k] 之差。测量和误差之间的相关性由 ypn[k-L:k]e 的乘积给出, mu 为 LMS 步长(或学习率)。

正如我们所看到的,尽管复杂性低得多,但 LMS 预测同样不错。

(64,) (1064,)

比较 LMS 和神经网络的预测结果

在我们结束本节之前,让我们比较一下 LMS 预测和神经网络预测之间的误差。公平地说,我忽略了 LMS 的初始部分,以便在测量均方误差和 SNR 时有时间收敛。尽管如此,我们看到神经网络性能比 LMS 性能好 5 dB!

Neural network SNR: **19.986311477279084**
LMS Prediction SNR: **14.93359076022336**

快速傅立叶变换

好吧,在信号预测方面,神经网络比 LMS 快 5 dB,但是让我们看看神经网络是否可以被训练来进行傅立叶变换。我们将它与 SciPy FFTPack 中的 FFT(快速傅立叶变换)进行比较。FFT 算法是信号处理的核心,可以训练神经网络来模仿它吗?让我们来找出…

我们将使用之前创建的相同信号,即正弦波叠加,来评估 FFT。让我们先看看 FFT 输出。

现在让我们创建一个神经网络模型来模拟 FFT。与我们之前创建的有 64 个输入但只有一个输出的模型相比,这个模型需要为每 64 个样本输入集生成 64 个输出。

由于 FFT 输入和输出都很复杂,我们需要输入端两倍的样本数,先用实数后用虚数排列。由于输出也是复数,我们再次 2 x NFFT 样本。

为了训练这个神经网络模型,让我们使用通过 numpy.random.normal 生成的随机数据,并基于我们正在比较的 SciPy FFTPack 中的 FFT 例程设置标签。

代码的其余部分与前面的神经网络训练非常相似。在这里,我一次运行 10,000 批,如果网络需要更多的训练,我有一个外部 for 循环来做多组 10,000 批。请注意,这需要在 for 循环之外创建模型,以便权重不会被重新初始化。

从模型摘要中可以看出,仅 64 点 FFT 就有近 50,000 个参数。我们可以减少一点,因为我们只评估实输入,而虚部保持为零,但这里的目标是快速比较神经网络是否可以被训练来进行傅立叶变换。

Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_3 (Dense)              (None, 128)               16512     
_________________________________________________________________
dense_4 (Dense)              (None, 128)               16512     
_________________________________________________________________
dense_5 (Dense)              (None, 128)               16512     
=================================================================
Total params: 49,536
Trainable params: 49,536
Non-trainable params: 0
_________________________________________________________________
DNN training done. Time elapsed:  30.64511 s

训练结束了。现在让我们使用为 LMS 创建的相同输入样本来测试网络。我们将神经网络输出与 FFT 输出进行比较,它们是相同的!多神奇啊!

在结束本文之前,让我们做最后一次评估。对于一些随机输入数据,我们将比较神经网络输出和 FFT 输出,看看均方误差和 SNR 是什么样的。

运行下面的代码,我们得到一个体面的 23.64 dB 信噪比。虽然我们偶尔会看到一些误差较高的样本,但在大多数情况下,误差非常小。鉴于我们只训练了 10,000 批神经网络,这是一个相当不错的结果!

Neural Network SNR compared to SciPy FFT:  **23.64254974707859**

总结

在新冠肺炎期间被困在里面,将机器学习性能与一些关键的信号处理算法进行比较是一个有趣的周末项目。我们看到,机器学习可以做信号处理可以做的事情,但天生具有更高的复杂性,其好处是可以推广到不同的问题。就复杂性而言,信号处理算法对工作来说是最佳的,但它们是针对它们所解决的特定问题的。我们不能用 FFT 代替 LMS,反之亦然,但我们可以使用相同的神经网络处理器,只需加载不同的权重集来解决不同的问题。这就是神经网络的多功能性。

有了这个提示,我将结束这篇文章。我希望你读这篇文章的时候和我整理这篇文章的时候一样开心。如果你觉得有帮助并且学到了一些东西,也请留下你的反馈!

https://www.linkedin.com/in/prasannasethuraman/

机器学习和供应链管理:动手系列#1

原文:https://towardsdatascience.com/machine-learning-and-supply-chain-management-1a1d9462eb35?source=collection_archive---------16-----------------------

内部 AI

拥抱未来

Shaah ShahidhUnsplash 上拍摄

机器学习、深度学习和人工智能正在从医学到音乐的所有领域实现转型变革。它正在帮助企业从采购到支付、计划生产、订购到兑现和记录到报告,发现优化机会并支持决策制定,这在以前使用传统商业分析和信息技术是不可能的。

机器学习和人工智能是一个复杂的领域,对我们这一代人来说有点令人畏惧,他们可能在本科教育之前没有接触过计算机。在这篇介绍性文章中,我将举例说明机器学习在采购和质量管理业务流程优化中的简化实现。在本文中,我将避免复杂和微妙的细节,在这一点上保持示例的简单性。我们将在本文的下一个系列中讨论复杂的场景。在本系列中,我将使用编程语言 Python 来实现机器学习算法,以解决供应链业务挑战,并且我假设您对 Python 语言有一些基本的了解。

商业案例

一个供应商供应不同的材料,其单价和采购订单总值相差很大。有时供应商的一些零件未能通过质量检查,但缺陷百分比似乎没有遵循一种趋势。在本系列的第一篇博客中,为了简单起见,我假设了独立特性和从属特性之间的线性关系。

目标

企业希望预测供应商交付的次品百分比。如果预测的次品百分比低于阈值水平,则不会执行质量检查。让我们考虑一下,如果交货中的次品率超过 0.4%,那么就需要明确的进货检验,以确保最终产品的质量。

这将有助于专注于特定采购订单交付的质量检查,以控制最终产品质量,并优化检验成本。它还能够发现有时影响少量材料有缺陷交付的变量/参数,并与供应商合作解决这个问题。

数据点和信息

ERP 中的采购订单信息和相应的进货检验结果为三年期间的所有订单提供了数据点。

对从 ERP 导出的历史数据进行采样,以训练机器学习算法

用于训练算法的样本数据

预计质量缺陷百分比的采购订单(PO)数据

用于预测值的测试数据

整装待发

为了简单起见,我假设过去的数据点是从 ERP 中导出的,并以 excel 格式保存在本地机器中。

我将解释每一行代码,然后将完整的代码放在文章的末尾以供参考。如前所述,为了让我们理解核心概念,我在这里简化了一些东西,在以后的系列文章中,我将在其上构建更真实的复杂示例。

第一步——首先,我们将导入我们将在机器学习程序中使用的所有 python 模块。我不会在本文中详细介绍这些库和模块,您可以在网上找到关于这些模块的更多细节。

*import pandas as pd
from sklearn.tree import DecisionTreeRegressor # Import Decision Tree Algorithm
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVR #import for support vector regressor*

Pandas 是一个用 Python 编写的软件库,用于数据操作和分析。使用 Pandas 可以非常轻松地读写 excel、CSV 和其他文件格式的数据,并处理时间序列数据。 Scikit-learn 是一个免费的 python 机器学习库。我们将使用决策树学习和支持向量机来预测未来供应商交付中的缺陷百分比。为此,我们将专门从 Scikit Learn 中导入这两个模块。

步骤 2 -我们将读取 excel 文件中过去的数据点,并将其保存到 pandas dataframe SourceData。类似地,我们将读取我们希望算法预测交付缺陷百分比的交付数据点。

*SourceData=pd.read_excel("Supplier Past Performance.xlsx") # Load the training data into Pandas DataFrameTestdata=pd.read_excel("Defect Predict.xlsx") # Load the test data*

注意 —我已经将 python 程序、过去数据点 excel 表、未来数据集保存在同一个文件夹中。因此,在代码中,只指定了文件名。如果文件位于不同的文件夹位置,则需要提供完整路径。

第三步 -现在过去的所有四个数据点,即采购订单金额、采购订单数量、交货前发送的采购订单和缺陷百分比将从 excel 读入 Pandas 数据框架。

我们将使用采购订单金额、采购订单数量、交货前发送的 PO(天数)来预测未来交货中的缺陷百分比。自变量是用于进行预测的参数,因变量是被预测的变量。由于我们将使用从 ERP 收集的过去的数据点来训练机器学习算法,因此我们将把它称为 SourceData_train_independent 和 SourceData_train_dependent 变量。

在下面的代码中,我们声明了除“缺陷百分比”之外的所有列数据为自变量,只有“缺陷百分比”为因变量。

*SourceData_train_independent= SourceData.drop(["Defect Percent"], axis=1) # Drop depedent variable from training datasetSourceData_train_dependent=SourceData["Defect Percent"].copy() 
# New dataframe with only independent variable value for training dataset*

步骤 4 -采购订单价值从一千到一百万英镑不等,而订单数量从一百到一千个托盘不等。采购订单在交货日期前 15 到 45 天发出。由于独立变量的范围非常不同,因此我们需要对其进行调整,以避免一个变量(在本例中为采购订单价值)对其他因素的意外影响。

我们只需要缩放独立变量。

在下面的代码中,独立的训练和测试变量被缩放,并分别保存到 X-train 和 X_test。在 y_train 中,保存的从属训练变量不进行缩放。

*sc_X = StandardScaler()

X_train=sc_X.fit_transform(SourceData_train_independent.values) 
# scale the independent training dataset variablesX_test=sc_X.transform(Testdata.values) # scale the independent test datasety_train=SourceData_train_dependent # scaling is not required for dependent variable*

步骤 5 -现在我们将分别输入独立和非独立的训练数据,即 X_train 和 y_train,来训练支持向量机模型。为了避免混淆,我不会在第一个系列中讨论复杂的细节,比如算法(超参数)的设置。

在下面的代码中,我们首先用一个拟合方法来拟合 X_train 和 y_train。在模型被训练后,我们通过测试独立变量值,即新订单的“PO 数量”、“PO 数量”和“交货前发送的 PO”以及 X_test 变量,并将预测的缺陷百分比存储在变量“预测”中。

*svm_reg = SVR(kernel="linear", C=1)
svm_reg.fit(X_train, y_train) # fit and train the modelpredictions = svm_reg.predict(X_test)

print("Defect percent prediction by Support Vector model for the order value of 95827 GBP with 851 pallets sent 55 days before delivery data is " ,round(predictions[0],2) , "%")*

最后,使用 print 语句打印预测的缺陷百分比。

步骤 6 —同样,我们将把训练数据集(自变量和因变量的值)送入决策树模型。

*tree_reg = DecisionTreeRegressor()
tree_reg.fit(X_train, y_train) # fit and train the modeldecision_predictions = tree_reg.predict(X_test) # Predict the value of dependent variableprint("Defect percent prediction by Decision Tree model for the order value of 95827 GBP with 851 pallets sent 55 days before delivery data is " ,round(decision_predictions[0],2) , "%")*

使用 print 语句打印预测的缺陷百分比。

我们已经了解了如何使用决策树学习和支持向量模型算法来预测未来交付中的缺陷百分比数量,并基于此为特定供应商的交付计划质量检查。请注意,为了建立最初的理解,我已经简化了一些实际用例之外的元素。

在此示例中,每次运行代码来预测新订单的结果时,我们都会对模型进行定型。对于大型数据集和复杂的示例,这可能不可行。在本文的下一个系列中,我将讨论保存训练好的模型,然后直接加载它来预测测试数据的结果。

机器学习与供应链管理:动手系列#2

完整代码

*""" Step 1 - Import the required modules"""

import pandas as pd
from sklearn.tree import DecisionTreeRegressor 
from sklearn.preprocessing import StandardScaler 
from sklearn.svm import SVR

""" Step 2 - Read the data source"""
SourceData=pd.read_excel("Supplier Past Performance.xlsx") # Load the training data into Pandas DataFrame
Testdata=pd.read_excel("Defect Predict.xlsx") # Load the test data 

""" Step 3  - Declare the independent and dependent train data from the sample"""
SourceData_train_independent= SourceData.drop(["Defect Percent"], axis=1) # Drop depedent variable from training dataset
SourceData_train_dependent=SourceData["Defect Percent"].copy() #  New dataframe with only independent variable value for training dataset

""" Step 4  - Scale the independent test and train data"""
sc_X = StandardScaler()
X_train=sc_X.fit_transform(SourceData_train_independent.values) # scale the independent variables
y_train=SourceData_train_dependent # scaling is not required for dependent variable
X_test=sc_X.transform(Testdata.values)

""" Step 5  - Fit the test data in maching learning model - Support Vector Regressor"""
svm_reg = SVR(kernel="linear", C=1)
svm_reg.fit(X_train, y_train) # fit and train the modelpredictions = svm_reg.predict(X_test)

print("Defect percent prediction by Support Vector model for the order value of 95827 GBP with 851 pallets sent 55 days before delivery data is " ,round(predictions[0],2) , "%")

""" Step 6 - Fit the test data in maching learning model - Decision Tree Model"""
tree_reg = DecisionTreeRegressor()
tree_reg.fit(X_train, y_train) # fit and train the modeldecision_predictions = tree_reg.predict(X_test) # Predict the value of dependent variableprint("Defect percent prediction by Decision Tree model for the order value of 95827 GBP with 851 pallets sent 55 days before delivery data is " ,round(decision_predictions[0],2) , "%")*

机器学习和供应链管理:动手系列#2

原文:https://towardsdatascience.com/machine-learning-and-supply-chain-management-hands-on-series-2-d723125f749e?source=collection_archive---------46-----------------------

内部 AI

不准确的预测比不预测更糟糕。学习保存机器学习训练的模型以备将来使用,并测量模型的准确性。

照片由Shaah Shahidh&Alexandre debièveUnsplash

在本系列的第部分中,我已经讨论了机器学习算法的一个基本简化实现,它可以根据输入参数预测未来采购订单的缺陷百分比。

在这一部分中,我将谈到训练模型的准确性度量。我们有许多参数(称为估计量的超参数),这些参数在模型中作为变量传递以执行预测。在实践中,基于训练模型的准确性度量结果,在模型被实施用于生产中的预测之前,超参数被调整。算法可以搜索并推荐优化的超参数,而不是通过试错法手动调整超参数来获得优化的准确度分数。我将在本系列的后面部分讨论有效的参数搜索策略。

正如在本系列的前一部分中提到的,在预测之前每次都从头开始训练模型是不实际的。我还将讨论如何保存一个训练好的模型,并将其直接导入另一个程序进行预测。

:我将详细解释新的领域和概念,并将避免详细重复我之前文章中解释的部分。我鼓励您参考前面的部分

第一步

首先,我们将导入模型所需的包。需要使用 StratifiedShuffleSplit 导入来构建一个训练模型,其样本集很好地代表了不同的子集值范围。 Pickle 模块将帮助我们保存训练好的模型,然后直接在其他程序中导入模型进行预测。最后,sklearn.metrics 有一套方法来衡量任何模型的准确性。

import pandas as pdimport numpy as npfrom sklearn.model_selection import StratifiedShuffleSplit #import to have equal weigtage samples in training datasetfrom sklearn.tree import DecisionTreeRegressor # import for Decision Tree Algorithmimport picklefrom sklearn.preprocessing import StandardScalerfrom sklearn.svm import SVR #import for support vector regressorfrom sklearn.metrics import mean_squared_error  # import to calculate root mean square

第二步

将从 ERP 和其他应用程序导出的样本数据集读入 pandas 数据框架。请参考早前的文章了解数据集的结构和其他细节。

SourceData=pd.read_excel("Supplier Past Performance.xlsx") # Load the data into Pandas DataFrame

第三步

粗略分析数据样本后,似乎“PO 数量”对“缺陷百分比”有着密切而强烈的影响,因此我们希望确保使用不同范围的“PO 数量”记录来训练模型。如果我们用由 30,000 到 60,000 英镑之间的“PO 数量”过度表示的数据集来训练我们的模型,那么我们的模型学习将不会准确到现实生活场景,并且可能不会准确预测。

在下面的代码中,引入了一个新的列“采购订单类别”,将 0 至 30,000 英镑的“采购订单金额”分类为采购订单类别 1,30,000 至 60,000 英镑的为采购订单类别 2。

SourceData["PO Category"]=pd.cut(SourceData["PO Amount"],
                                     bins=[0., 30000, 60000, 90000,
np.inf],                                     
labels=[1, 2, 3, 4])

第四步

StatifiedShuffleSplit 提供训练和测试索引,将过去的数据集分成训练集和测试集。在下面的代码中,我们保留了 30%的数据用于测试模型,60%用于训练模型

split = StratifiedShuffleSplit(n_splits=2, test_size=0.3)

第五步

使用前面步骤中的训练和测试索引,我们将初始源数据分成两部分,即。strat_train_set 作为训练数据集,strat_test_set 分别作为模型的测试和训练数据集。

在下面的代码中,我们使用“采购订单类别”来确保在每个分开的集合中,不同的采购订单类别都得到很好的表示。

for train_index, test_index in split.split(SourceData, SourceData["PO Category"]):
    strat_train_set = SourceData.loc[train_index]  # stratfied train dataset 
    strat_test_set = SourceData.loc[test_index] #stratified test dataset

第六步

我们引入了一个额外的列“PO Category ”,以确保在测试和训练数据集中充分表示来自所有 PO 金额范围的采购订单。由于已经完成,因此我们将从数据集中删除这个额外的 PO 类别。

for set_ in (strat_train_set, strat_test_set): 
    set_.drop("PO Category", axis=1, inplace=True)

第七步

现在,我们将为我们的模型定义、测试和训练数据独立变量和因变量。我们将使用独立和从属训练数据集来训练模型,因为它是一种受监督的机器学习。此外,我们将使用模型之前没有见过的测试数据集来测试模型性能。

SourceData_train_independent= strat_train_set.drop(["Defect Percent"], axis=1)
SourceData_train_dependent=strat_train_set["Defect Percent"].copy()SourceData_test_independent= strat_test_set.drop(["Defect Percent"], axis=1)
SourceData_test_dependent=strat_test_set["Defect Percent"].copy()

第八步

由于数据属性具有不同的范围,因此我们需要在使用它进行训练之前对其进行缩放。关于缩放数据的更多信息,请参考我之前的文章。

在下面的代码中,我们使用 pickle.dump()将 scale 保存为“Scaler.sav ”,以后我们可以在其他程序中导入以供使用。

sc_X = StandardScaler()
X_train=sc_X.fit_transform(SourceData_train_independent.values)
y_train=SourceData_train_dependentpickle.dump(sc_X, open("Scaler.sav", 'wb'))X_test=sc_X.fit_transform(SourceData_test_independent.values)
y_test=SourceData_test_dependent

第九步

我们将用训练数据集训练支持向量模型,并用 pickle 将训练好的模型保存为“SVR_TrainedModel.sav”。“SVR_TrainedModel.sav”和当前程序保存在同一个文件目录中,因为我们没有提供完整的路径和唯一的文件名作为保存参数。

svm_reg = SVR(kernel="linear", C=1)
svm_reg.fit(X_train, y_train)filename = 'SVR_TrainedModel.sav'
pickle.dump(svm_reg, open(filename, 'wb'),protocol=-1)

第十步

现在,我们将从经过训练的独立数据集预测因变量,即缺陷百分比值,并测量模型的误差/准确性。在下面的代码中,我们传递训练数据集,然后将模型的预测值与实际值进行比较。将独立训练变量数据集的预测与实际值进行比较,并通过评分方法返回回归估计量的 R 分数。

decision_predictions = svm_reg.predict(X_train)Score = (svm_reg.score(X_train, y_train))  # It provides the R-Squared Value
print ( "The score of the Support  Vector model is", round(Score,2))lin_mse = mean_squared_error(y_train, decision_predictions)
print("MSE  of  Vector  model is ", round(lin_mse,2))lin_rmse = mean_squared_error(y_train, decision_predictions, squared=False)
print("RMSE of  Support  Vector  Learning model is ", round(lin_rmse,2))

在这篇文章中,我不会涉及 R-Square、均方差和均方根误差的统计细节,我强烈建议大家阅读维基百科中关于这些统计指标的页面。这将有助于解释模型是否被训练到可接受的极限,或者我们需要微调数据和超参数。

The score of the Support  Vector model is 0.09
MSE  of  Vector  model is  0.05
RMSE of  Support  Vector  Learning model is  0.12

第十一步

对于决策树学习模型,我们遵循相同的步骤,并检查模型的准确性。

tree_reg = DecisionTreeRegressor()
tree_reg.fit(X_train, y_train)
filename = 'DecisionTree_TrainedModel.sav'
pickle.dump(tree_reg, open(filename, 'wb'),protocol=-1 predictions = tree_reg.predict(X_train) Score = (tree_reg.score(X_train, y_train))  # It provides the R-Squared Value
print ( "The score of model Decision Tree model is ", round(Score,2))lin_mse = mean_squared_error(y_train, predictions)
print("MSE of Decision Tree model is ", round(lin_mse,2))lin_rmse = mean_squared_error(y_train, decision_predictions, squared=False)
print("RMSE of Decision Tree model is ", round(lin_rmse,2))

第十二步

一旦模型预测的结果在可接受的误差范围内,我们就可以将模型以前没有见过的测试数据集输入到预测模型中。我们可以用与训练数据集相同的方式来比较测试数据集相关的数据准确性。

test_predictions = tree_reg.predict(X_test)
test_decision_predictions = svm_reg.predict(X_test)

导入训练好的模型和预测

要在另一个程序中使用训练好的模型,我们需要使用“pickle.load”导入自变量 scales 和学习模型,如下面的代码片段所示。

这里,我们从“Supply Chain Predict.xlsx”文件中读取新的独立值数据集,预测相应因变量的进一步步骤如上文针对测试数据所述。

import pickle
import pandas as pd testdata=pd.read_excel("Supply Chain Predict.xlsx") # Load the test datasc_X = pickle.load(open('Scaler.sav', 'rb'))  # Load the pickleloaded_model = pickle.load(open('DecisionTree_TrainedModel.sav', 'rb')) # load the trained modelX_test=sc_X.transform(testdata.values) # scale the independent variables for test datadecision_predictions = loaded_model.predict(X_test) # Predict the value of dependent variableprint("The prediction by Decision Treemodel is " , decision_predictions )

完整的代码片段

# Importing the required modules 
import pandas as pd
import numpy as np
from sklearn.model_selection import StratifiedShuffleSplit #import to have equal weigtage samples in training dataset
from sklearn.tree import DecisionTreeRegressor # import for Decision Tree Algorithm
import pickle
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVR #import for support vector regressor
from sklearn.metrics import mean_squared_error  # import to calculate root mean squareSourceData=pd.read_excel("Supplier Past Performance.xlsx") # Load the data into Pandas DataFrame
SourceData_independent= SourceData.drop(["Defect Percent"], axis=1) # Drop depedent variable from training dataset
SourceData_dependent=SourceData["Defect Percent"].copy() # New dataframe with only independent variable value for training dataset
SourceData["PO Category"]=pd.cut(SourceData["PO Amount "],
                                     bins=[0., 30000, 60000, 90000,
np.inf],                                     
labels=[1, 2, 3, 4])
split = StratifiedShuffleSplit(n_splits=1, test_size=0.3)
for train_index, test_index in split.split(SourceData, SourceData["PO Category"]):
    strat_train_set = SourceData.loc[train_index]  # stratfied train dataset 
    strat_test_set = SourceData.loc[test_index] #stratified test datasetfor set_ in (strat_train_set, strat_test_set): 
    set_.drop("PO Category", axis=1, inplace=True) SourceData_train_independent= strat_train_set.drop(["Defect Percent"], axis=1)
SourceData_train_dependent=strat_train_set["Defect Percent"].copy()
SourceData_test_independent= strat_test_set.drop(["Defect Percent"], axis=1)
SourceData_test_dependent=strat_test_set["Defect Percent"].copy()
sc_X = StandardScaler()
X_train=sc_X.fit_transform(SourceData_train_independent.values)
y_train=SourceData_train_dependent
pickle.dump(sc_X, open("Scaler.sav", 'wb'))
X_test=sc_X.fit_transform(SourceData_test_independent.values)
y_test=SourceData_test_dependentsvm_reg = SVR(kernel="linear", C=1)
svm_reg.fit(X_train, y_train)
filename = 'SVR_TrainedModel.sav'
pickle.dump(svm_reg, open(filename, 'wb'),protocol=-1)
decision_predictions = svm_reg.predict(X_test)
Score = (svm_reg.score(X_test, y_test))  # It provides the R-Squared Value
print ( "The score of the Support  Vector model is", round(Score,2))
lin_mse = mean_squared_error(y_test, decision_predictions)
print("MSE  of  Vector  model is ", round(lin_mse,2))
lin_rmse = mean_squared_error(y_test, decision_predictions, squared=False)
print("RMSE of  Support  Vector  Learning model is ", round(lin_rmse,2))tree_reg = DecisionTreeRegressor()
tree_reg.fit(X_train, y_train)
filename = 'DecisionTree_TrainedModel.sav'
pickle.dump(tree_reg, open(filename, 'wb'),protocol=-1)
predictions = tree_reg.predict(X_test) 
Score = (tree_reg.score(X_test, y_test))  # It provides the R-Squared Value
print ( "The score of model Decision Tree model is ", round(Score,2))
lin_mse = mean_squared_error(y_test, predictions)
print("MSE of Decision Tree model is ", round(lin_mse,2))
lin_rmse = mean_squared_error(y_test, decision_predictions, squared=False)
print("RMSE of Decision Tree model is ", round(lin_rmse,2))

在本文的下一个系列中,我将讨论不同机器学习算法中的超参数,以及可用于为健壮的机器学习模型确定这些参数的最佳值的选项。

机器学习与供应链管理:动手系列#1

上学习结构化方法如何识别机器学习监督算法的正确自变量?

机器学习和第四次工业革命

原文:https://towardsdatascience.com/machine-learning-and-the-fourth-industrial-revolution-ffb58b034199?source=collection_archive---------45-----------------------

科迪·诺丁汉在 Unsplash 上拍摄的照片

数据科学和机器学习

毫无疑问,机器学习算法正在通过为我们的日常生活添加一个新的维度来形成一个更加无缝的世界。该社区还推动了更全面、更协调地采用机器学习技术,包括在教育、政府服务和社区福利等重要领域利用机器学习来提高社会生活质量。

由于客户服务行业的这些举措,我们看到了机器学习的积极影响,客户服务行业正在逐步转向机器学习来管理其不断增长的需求。移动应用程序现在被开发来支持无缝的政府服务交付,可以看到聊天机器人在零售、银行、医疗保健和政府服务中的使用。

照片由晨酿破浪

自动驾驶汽车、机器人、人工智能(AI)、物联网(IoT)和 3D 打印等众多转型技术,是第四次工业革命的新时代。人工智能是通过机器学习和深度学习推动第四次工业革命的最重要的技术之一。机器学习具有巨大的潜力,并在商业领域使用,包括零售、安全、医疗保健和运输。

深入学习机器学习的企业必须关注两件事——业务案例的好处和用例的好处。他们必须采取灵活的分阶段策略来开始建立势头。

研究公司 Venture Scanner 强调,与 2017 年相比,2018 年营销机构对机器学习技术的采用增加了 44%。客户服务团队对这种技术和算法的使用预计将在未来 18 个月内增长 143%。

然而,实现机器学习的最大挑战是感知到的冗余或失业威胁。实际上,应该开发机器学习来适应劳动力市场的不同目的,而不是让它变得多余。机器学习可能有助于提高劳动力的效率,因为机器可以完成劳动密集型和单调的任务,而人类则专注于更高层次的定性任务。

世界经济论坛(WEF)报告称,尽管机器学习和算法到 2022 年将取代 7500 万个工作岗位,但同期它们将创造另外 1.33 亿个新角色。

机器学习技术和算法正在以多种方式影响我们的日常生活。机器学习技术的最大受益者之一是安全性。例如,在中东,机器学习正被用于图像处理、面部识别和预测分析。这项技术正在推动其通过聊天机器人在零售领域提供更多个性化体验的可能性。

在医疗保健领域,机器学习正在通过说服使用全面的算法和软件来支持医生诊断患者和疾病,从而帮助该行业从传统方法转变。当谈到能源和 R&D 时,机器学习使精确钻井、油藏管理和驾驶安全和生产成为可能。机器学习也准备在全球范围内改变运输行业。在阿联酋,第一批自动驾驶出租车已经开始试验,一旦安全和交通可行性得到解决,预计很快就会在道路上推出。

总之,机器学习广泛代表了巨大的收入增长机会。例如,在阿联酋,政府披露了一项战略,通过在政府服务和私营部门利用机器学习技术,将该国定位为人工智能中心。它还旨在招聘和培训人们在不久将雇用机器学习工程师的行业中工作。对于希望在未来提高机器学习能力的企业来说,这是一个巨大的机会。

关于作者

Wie Kiang 是一名研究员,负责收集、组织和分析意见和数据,以解决问题、探索问题和预测趋势。

他几乎在机器学习和深度学习的每个领域工作。他正在一系列领域进行实验和调查,包括计算机视觉、自然语言处理和强化学习。

机器学习和情绪交易

原文:https://towardsdatascience.com/machine-learning-and-trading-on-sentiment-76a484cefca8?source=collection_archive---------28-----------------------

照片由ZQ·李Unsplash 拍摄

建立一个分类算法的集合,以利用短期 SPDR 部门 ETF 价格行为

你将学到什么和学到什么技能

  • 如何将多个分类机器学习模型构建成复合集成模型
  • 使用时序分割和随机交叉验证进行超参数调整
  • 探索评估模型质量的重要分类指标,如 F1 分数和准确度
  • 可应用于多种策略的投资组合绩效和构建代码,将现实世界的交易成本考虑在内
  • 如何使用一个热编码构建功能集
  • 发现是否可以从基本机器学习模型中预测短期价格变动

在我之前的文章中,我探讨了是否有可能使用一个单一的情绪指标和一个简单的线性模型来系统地跑赢美国股市。不出所料,我发现一个简单的系统根本行不通。但也许结合不同情绪信号的机器学习模型可以创造一种有利可图的策略?

文献综述

随着社交媒体的出现,分析师已经使用社交媒体分析和自然语言处理来提取特定公司的情绪情绪,像 Ravenpack 这样的公司在长期高积极情绪公司和短期消极情绪公司中找到了阿尔法。他们发现,在 2-3 天的时间里,长/短的顶部 10%和底部 10%组合的回报率为 50-100 个基点。

Shlaefer 发现,有 1 到 12 个月的反应不足(股票价格在好消息后上涨,坏消息后下跌)表明投资者需要时间来处理新信息,但在 3 到 5 年的时间里,投资者反应过度,为一连串的正收益付出太多,并忽略了公司基本面的均值回复性质。

贝克和斯坦恩发现,一段时期的高流动性和较小的买卖差价会导致未来回报较低。由于非理性投资者往往使市场更具流动性,流动性的措施提供了一个指标,这些投资者的相对存在或不存在,因此价格水平相对于基本面。

贝克和沃格勒假设,对投资者情绪最敏感的股票将是那些更年轻、更小、更不稳定、不盈利、不支付股息、陷入困境或具有极大增长潜力或具有类似特征的公司。而“债券类”股票将较少受情绪驱动。他们发现,对于年轻、高度不稳定、接近财务困境且无利可图的小盘股和投机股,情绪可能是一个强有力的短期反向指标。具体来说,在这组公司中,当情绪低于历史平均水平一个标准差时,他们的月回报率平均为-34%,当情绪高于历史平均水平一个标准差时,他们的月回报率为 1.18%。

Borovoka 和 Dijkstra 在他们的深度神经网络模型中实现了 60%的准确性,根据围绕单个指数公司的高频新闻情绪预测欧洲斯托克 50 指数的价格走势。

泰特洛克发现,根据《华尔街日报》的“与市场同步”专栏的测量,媒体情绪是几天来整体股市回报的一个确认指标,尤其是对小型股而言。此外,他发现异常高或低的市场悲观情绪会导致高交易量。

数据和方法

没有一项研究调查了由整体投资者情绪驱动的特定行业效应,所以我很想探究一下。

我使用了 9 只 SPDR 行业交易所交易基金(XLU,XLK,XLB,XLI,XLV,XLF,XLE,XLP,XLY ),它们成立于 1998 年 12 月,提供了雅虎财经超过 21 年的每日 OHLC 和交易量数据。请注意,免费数据,如雅虎金融,并不总是最干净的价格数据,但我保留了它,这样你就可以用最小的成本利用代码,以防你想添加不同的 ETF 或股票报价机来测试模型。

我还利用了来自沙拉达、圣路易斯美联储、杜克大学、芝加哥期权交易所、密歇根大学、经济政策不确定性和

将 scikit-learn python 库中的多个分类机器学习模型组合成一个集成分类,我希望与任何单个模型相比,一个多样化的模型将在样本外表现良好。

将数据集转换为训练集、验证集和测试集:

  • 训练/验证(样本内)—从数据开始到 2013 年底,训练占样本数据的 80%,验证占样本数据的剩余 20%
  • 测试(样本外)—2014 年 1 月—2020 年 5 月

沉思和好奇

我将尝试回答的问题是:

  • 基于市场情绪,在多长时间内行业回报最可预测?由于高 OHLC 和交易量数据,我只能在第二天开盘时买入,在 n 天后平仓。
  • 在最终的集合模型中应该使用什么模型来组合?
  • 什么超参数对于样本外数据的预测是最佳的?
  • 在组合了最佳模型后,机器学习投资组合在扣除交易成本后是否会表现更好,因为这将是一种高流动战略?
  • 该模型能胜过被动的买入并持有策略吗?

构建特征集

在整篇文章中,我将分享部分代码,但由于可读性,并非全部,但是您可以在 GitHub 上访问数据(由于许可限制,除了 Sharadar)和 python 文件供您个人使用。

以下内容构成了算法将从中预测期望值的特征集,即该证券在 n 天内是正回报还是负回报。

  1. 市场成交量(占一天交易的总流通股的百分比)
  2. 上涨/下跌比率(股票总数增加/股票总数减少)
  3. 简单移动平均线/价格在滚动的 2 到 22 个交易日内迭代
  4. 在滚动的 2 到 22 个交易日内迭代的年化标准差
  5. 维克斯
  6. Sahm 法则——在实时预测经济衰退方面非常有用
  7. 投资级——高收益公司债券利差
  8. 政治不确定指数
  9. 杜克首席财务官乐观指数
  10. 卖出/买入比率
  11. AAII 投资者情绪指数
  12. 密歇根大学消费者情绪指数
  13. 耶鲁/希勒投资者情绪指数

一热编码

我很好奇,在相同的功能集下,各个部门的 ETF 是否表现不同,因此我使用了一个热编码来为每个 ETF 创建列,如果使用,列为 1,否则为 0(见下图)。

最终的特性和值 pandas 数据帧如下所示,然后被转换为 NumPy 数组。

Credit Spread  US Shiller Valuation Index Indiv (Lag)  \
date                                                                
2003-10-17           3.95                                   66.24   
2003-10-17           3.95                                   66.24   
2003-10-17           3.95                                   66.24   
2003-10-17           3.95                                   66.24   
2003-10-17           3.95                                   66.24US Shiller Valuation Index Inst (Lag)               ...
date                                                ...
2003-10-17                                  76.64   ...
2003-10-17                                  76.64   ...
2003-10-17                                  76.64   ...
2003-10-17                                  76.64   ...
2003-10-17                                  76.64   ... XLK  XLP  XLU  XLV  XLY  
date                                 
2003-10-17  0.0  0.0  0.0  0.0  0.0  
2003-10-17  0.0  1.0  0.0  0.0  0.0  
2003-10-17  1.0  0.0  0.0  0.0  0.0  
2003-10-17  0.0  0.0  0.0  0.0  1.0  
2003-10-17  0.0  0.0  0.0  0.0  0.0

创建训练、验证和测试集

您可以很容易地创建一个训练和验证集,注意需要放置 shuffle=False 来防止数据中的混洗,因为财务数据不是独立的,这会使模型过拟合。我喜欢将样本数据(训练和验证)保存在一个 python 文件中,将样本外(测试)数据保存在一个单独的文件中,以防止任何欺骗和展望未来的诱惑。

############Creating Training/Validation Set################# Labels are the values we want to predict
labels = np.array(features['value'])# Remove the labels from the feature and the date
features_array = features.drop(['value','index'], axis=1)# Saving feature names for later use
feature_list = list(features_array.columns)# Convert to numpy array
features_array = np.array(features_array)# Using Skicit-learn to split data into training and testing sets, but in this case it is a validation set

test_ratio = .2 #variable for the percentage of train data to leave as validation# Split the data into training and testing sets, with simple split
train_features, validation_features, train_labels, validation_labels = train_test_split(features_array, labels, test_size=test_ratio, random_state=42, shuffle=False)number_features = train_features.shape[1]

组合模型和选择交易日期

准确度测试在 1-30 天的保持期内使用以下分类器进行:

  • adaboost 算法
  • 随机森林
  • 梯度推进
  • 高斯过程
  • k 个最近邻居
  • MLP 神经网络
  • 支持向量机

当我在分类气泡中一步一步地浏览 scikit-learn 算法备忘单时,我特别选择了这些。

每个模型都基于 F1 分数、准确性分数(正确预测的百分比)以及两者的平均值进行测试。我选择排除 SVC 和 MLP 神经网络模型,因为它们分别具有最低的两个组合分数 0.516 和 0.521。接下来,我选择专注于 3 天的持有期,因为算法能够很好地预测时间范围,并且假设模型是好的,更多的交易机会将很好地服务于它,尽管受到交易成本的限制。下表使用条件格式直观地选择高分和低分,标准偏差有一个使用红色的单独公式。我希望看到的是所有模型之间的高平均分和低标准差,这向我表明在特征集中有一个信号要提取,并且算法能够可靠地访问它。

单元格用颜色编码,暗绿色表示较高的分数,底部行表示模型的标准偏差,以辨别跨模型的稳定性,暗红色表示较低的标准偏差。

超参数调整和交叉验证

我将使用 sci-kit 学习库中的时间序列分割和随机交叉验证搜索功能进行超参数调整。时间序列分割,也称为向前移动方法,是为时间序列数据设计的,因为它通常不是独立和同分布的。

然而,正如 De Prado 在机器学习进展中提出的挑战,交叉验证功能对所有分数进行同等加权,即使一些分数是在整体数据的一小部分上训练的。为了解决这个问题,我决定根据总使用折叠的分数来衡量交叉验证分数(即,对于 5 次交叉验证,最后一次测试的分数将为 5 / (5+4+3+2))。

De Prado 提出的另一个问题是,需要清除交叉验证方法中训练/验证分割边缘附近的数据,以尽量减少测试和训练集之间的数据泄漏。我试图利用他的 purgedKfoldCV 函数,但由于每个时间点都有多个数据点,我们同时在看 9 个行业 ETF,所以我做不到。

F1 得分是主要指标,由精确度和召回率的调和平均值组成,在交叉验证期间将通过它来测试模型的准确性。

使用随机 CV 搜索功能,我将给出一个参数列表,从中随机选择,然后分离出最佳评分组合,然后用于验证集。具有最高的,并且希望是不相关的,预测能力的算法将在一个多数表决系统中被组合,以创建最终的预测系统。

下面是一个随机森林算法的随机搜索参数的例子,我摘自威尔·科尔森的一篇文章,并根据我的目的进行了修改。

#### Create 5 K Fold Split Time Series ####number_of_splits = 5
tscv = TimeSeriesSplit(n_splits=number_of_splits)

#####Randomized CV for Random Forest using Timseries split #######

# Number of trees in random forest
n_estimators = [int(x) for x in np.linspace(start = 200, stop = 2000, num = 10)]# Number of features to consider at every split
max_features = ['auto', 'sqrt']# Maximum number of levels in tree
max_depth = [int(x) for x in np.linspace(10, 110, num = 11)]
max_depth.append(None)# Minimum number of samples required to split a node
min_samples_split = [2, 5, 10]# Minimum number of samples required at each leaf node
min_samples_leaf = [1, 2, 4]# Method of selecting samples for training each tree
bootstrap = [True, False]# Create the random grid
random_grid = {'n_estimators': n_estimators,
                'max_features': max_features,
                'max_depth': max_depth,
                'min_samples_split': min_samples_split,
                'min_samples_leaf': min_samples_leaf,
                'bootstrap': bootstrap}
print(random_grid)# Use the random grid to search for best hyperparameters
# First create the base model to tune
rf = RandomForestClassifier(n_jobs=-1)# Random search of parameters, using time series split, 
# search across 100 different combinations
rf_random = RandomizedSearchCV(estimator = rf, param_distributions = random_grid, n_iter = 100, cv = tscv, verbose=2, random_state=42, \
                                    scoring='f1')
# Fit the random search model
search_rf = rf_random.fit(train_features, train_labels)search_rf.best_params_
search_rf.cv_results_
search_rf.best_score_
search_rf.best_estimator_
search_rf.scorer_

一些随机搜索需要一些时间,例如在我的 Mac 上随机森林需要 77 分钟,梯度提升需要 144 分钟(16GB 内存和 2.9 GHz 双核英特尔酷睿 i5)。你可以尝试使用基于直方图的梯度推进分类树,它被设计成在大型特征集上更快。

特征重要性和模型多样化

使用随机森林和梯度增强,您可以看到每个要素的相对重要性百分比。

一般观察:

  • 在最右边,我们看到模型在 ETF 是否是特定部门的 ETF 方面几乎没有用处
  • 毫无疑问,对 3 天回报率预测最高的波动特征是 2 天和 3 天的波动
  • 整体市场动态,如上涨/下跌和市场成交量,对预测未来 3 天的回报最有用

从下面的相关矩阵可以看出,这五个模型的组合确实提供了多样性,这是有意义的,因为它们利用不同的数学算法基于特征集进行分类。

投资组合实施

在综合了所有 5 个模型的预测后,我创建了一个多数投票系统。接下来,我在训练和验证数据集上运行该策略,并与同等权重的投资策略进行比较。

设置实施投资组合所需的变量

#########  Portfolio Construction  ########
Predictions_DF = features.iloc[:,(-len(tickers)-1):]#Using the same in sample dates here and for equal weight benchmark
f_date = datetime.datetime.strptime(In_Sample_Start, '%Y-%m-%d')
l_date = datetime.datetime.strptime(In_Sample_End,  '%Y-%m-%d')delta = l_date - f_date#Choose the number of periods (days in range / the forecasted return days)period_delta = np.floor(delta.days/(Number_days_to_hold))
period_delta = int(period_delta)
first_period = In_Sample_Start #using f_datereturns_df_portfolio = pd.DataFrame()
row_length = Predictions_DF.shape[0]
Portfolio_Turnover = pd.DataFrame()

创建遍历数据并执行交易的 for 循环(当我试图嵌入时,下面的代码看起来相当糟糕)。

注意:y 轴是对数刻度,红线表示验证集的开始

正如您所看到的,与验证集相比,in 样本高度超出预期,因此我解析出了图表来说明差异。

该策略有较高的风险调整回报率,表现为较高的夏普比率,但在其他方面并没有实质性的改善。

测试数据

下面是围绕模型分类的统计数据,最后一行显示了如果我假设市场将永远上涨,这类似于永远全额投资,结果会是什么。

每一栏中的最佳分数以红色突出显示

“市场总是上涨”的购买和持有取向是普遍的赢家。

正如在下面的混淆矩阵中看到的,集合模型在预测未来回报何时为正(右下)方面比预测何时会有负回报(左上)做得更好。

下面是使用测试数据(2014 年 1 月-2020 年 5 月)的策略实际性能图表。

该模型执行了 1074 笔单向交易,假设由于市场影响和滑点,交易佣金为 1 美元,成本为 15 个基点,那么现实世界的成本将从 10,000,000 美元的投资组合的总业绩中减去 17.9 %和 1,074 美元,导致年化回报率为 1.3%,远低于不切实际的 6.1%的年化回报率。

吸取的教训

  • 集合模型在预测上涨天数方面做得很好,但在高交易成本之后,它并没有带来任何更好的风险调整表现
  • 正如 53.4%的准确性所证明的那样,该模型确实比随机机会做得更好,但市场上涨的时间为 54.8%,因此,如果你有一个简单的命题“市场将上涨”,那么你会有更高的准确性分数。
  • 机器学习模型能够从市场内部特征中提取一些信号,如市场成交量,但最终,并没有创造出一个优于天真的“总是被投资”模型的预测模型。
  • 基于前面提到的其他相关研究,我希望机器学习模型能够从特定股票的社交媒体分析、小盘股和微盘股中提取出更有意义的信号,并通过深度神经网络提高整体准确性。

注来自《走向数据科学》的编辑: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

机器学习和转化研究

原文:https://towardsdatascience.com/machine-learning-and-translational-research-d0738ac13d6?source=collection_archive---------29-----------------------

从电脑到诊所

作者创造的形象

互联网网络服务的扩展和高通量技术的最新进展使得公众,特别是科学界,能够容易地访问重要的生物数据集。因此,处理、分析和推断知识的方式在最近几年发生了巨大的变化,无论是临床数据、测序数据、电子健康记录还是一般医学。正因为如此,像机器学习和人工智能这样的数据科学术语已经以这样或那样的方式成为我们日常使用词汇的一部分。他们已经彻底改变了转化研究的设计和执行方式,为改善人类健康带来了全球性的发现。

在这篇文章中,我们将介绍机器学习的基本概念及其在转化研究或医学方面的应用。

机器学习

机器学习无疑是当今世界谈论最多的技术之一。简单来说,机器学习就是把信息变成知识的工具。在当今世界,我们正在生成大量数据,除非我们分析这些数据并找到其中隐藏的模式,否则这些数据毫无用处。

机器学习专注于算法的分析和开发,使计算机能够根据之前观察到的数据做出决策和预测,而不依赖于基于规则的编程

机器学习主要分为三种类型:监督学习、非监督学习和强化学习。

作者创造的形象

监督学习

目标是生成一个模型预测函数,它可以基于一个或多个输入值预测一个输出。

  • 模型的输出通常被称为标签目标值响应变量
  • 模型的输入通常被称为特征预测器

该算法通过研究由几个观察值组成的数据训练集来“学习”最佳模型,每个数据都具有其特征和其标签的值。

进一步,监督学习又分为两类分类回归 。在分类中,输出变量被分类为“存在”或“不存在”或“疾病”或“无疾病”或分级(1 级、2 级等)。).在 回归中, 输出变量是一个真实值,如“浓度”或“重量”,例如,你根据标准曲线测量样品中的蛋白质浓度。

这种类型的机器学习可以广泛用于放射学、病理学或任何其他成像领域中的医学成像。这种研究是有用的,必须小心谨慎,因为它们需要大量的数据集才能足够准确,而且数据必须准确标注。

无监督学习

在无监督学习中,数据集有特征,但没有标签。无监督学习的目标是识别数据中我们不容易注意到的结构。因此,所设计的算法必须基于数据集中的相似性来创建其组和类别。与监督学习不同,无监督学习预测未知的结果,并发现隐藏的模式。同样,在无监督学习中,我们一般不会从可能的标签会是什么这个先入为主的概念开始。聚类是非监督学习的一个例子。下一代测序等技术帮助科学家建立模型,从一组不同的独立变量中预测结果。无监督学习方法一般称为降维技术(如 PCA、tSNE 等。).单细胞测序分析过程中细胞在不同组中的聚类就是其中一个例子。另一个例子是基于基因表达值的组织样本聚类。

强化学习

强化学习是指计算机程序从它的错误和成功中学习,并最终根据它的经验建立一个算法。所以,这种学习是基于试错法。强化学习任务的示例包括训练算法(I)下棋或玩视频游戏,(ii)驾驶自动驾驶汽车,(iii) 了解医疗注册数据上的治疗方案, (iv) 找到治疗化疗患者的最佳策略

在麻省理工学院研究人员发表的研究中,作者报告了一个作为强化学习问题的临床试验剂量的成功公式,其中算法教会了适当的剂量方案,以减少接受化疗和放疗临床试验的患者的平均肿瘤直径。

机器学习算法正在帮助揭示数据矿下隐藏的宝石。但有一点应该永远记住,“更复杂的算法不一定会产生最好的结果”。

机器学习和转化研究——“友谊”

机器学习的应用包括但不限于简化行政工作、医院记录管理、医疗和传染病等。下面只是几个例子,讨论了在医学研究和医疗保健中具有重大潜力的机器学习任务。

作者创造的形象

医学成像(磁共振成像(MRI)、X 射线、计算机断层扫描、乳房 X 线摄影、组织切片等)分析可以通过使用机器学习算法而受益匪浅。例如,目前,病理学家手动检查载玻片并决定患者是否患有转移性癌症。因为人的判断是不一致的,并且诊断可能因人而异,甚至由同一个人每天都不同。在这种情况下,机器学习算法可以自动完成这一过程,并且最好能够提供无偏见的结果。这些算法通过从以前的样本中学习来提高诊断的准确性,因此可以提供治疗选择。有前景的应用包括检测肿瘤、动脉狭窄、、乳腺癌淋巴结、器官描绘等。

如今,高通量技术的出现产生了海量数据,这些数据被收集起来,可供研究界使用。此外,像癌症基因组图谱研究网络等社区资源项目提供了对基因组数据的访问。每个人都有许多已知或未知的基因变异。即使有先进的测序技术,预测突变的发生及其后果仍然具有挑战性。完整的基因组序列的可用性允许更好地观察和理解个体的遗传图谱,这最终与健康直接相关。在多组学(基因组、转录组、蛋白质组、表观基因组、代谢组和微生物组)时代,医疗保健的前景看起来很有希望。二十多年来,各种不同的机器学习算法被广泛应用于疾病的预后和预测。机器学习有助于预测易感性、复发率和存活率。

药物发现和开发过程漫长而艰难,取决于众多因素和学科。一种新药从实验室走向药店货架平均需要 12 年时间,耗资超过 3 . 5 亿美元。机器学习算法可以通过帮助决策来改进药物发现,因为它可以生成高质量和高维度的数据。它适用于药物发现的所有阶段,无论是靶标验证、预后生物标志物的识别,还是临床试验。然而,方法和算法仍处于开发阶段,但有助于加快过程并降低失败率,最终将节省时间和金钱。此外,遗传学数据与药物-蛋白质结合数据库的结合允许针对细胞类型、突变等的每种可能组合来测试不同的化学物质。这种分析使研究人员能够建立模型,从各种独立变量的组合中预测结果。

个性化医疗,这是一种根据患者个体特征(临床、分子或行为)而非总体平均水平做出医疗决策的医疗方法。个性化医疗的概念与数据科学,特别是机器学习有着密切的联系。预计到 2023 年,市场规模将达到870 亿美元,机器学习将成为设计个性化药物的发电站,这将有助于打破一刀切的方法。

在诊所中使用机器学习有可能改变现有的医疗保健提供模式。然而,人们应该牢记道德和监管问题,以避免不必要的风险和陷阱,阻碍“计算机到诊所”的流动。

结论

为了提高生活质量,需要多学科的努力,包括数据科学家、研究科学家、临床医生、监管事务机构和医疗保险组织。

感谢阅读😄。

机器学习在岩石物理行业的应用:声波测井综合预测故事

原文:https://towardsdatascience.com/machine-learning-application-in-petrophysics-industry-a-sonic-log-synthesis-prediction-story-cf0ea54ffdad?source=collection_archive---------46-----------------------

扎卡里·西奥多在 Unsplash 上的照片

岩石物理学是什么意思?

岩石物理学是对岩石性质的研究,也是对液体相互作用的简要描述。它主要用于石油和天然气行业,以研究不同类型的油藏的动态。它还解释了地下孔隙的化学性质以及它们之间的联系。它有助于控制油气的运移和聚集,同时解释化学和物理性质,岩石物理学还解释许多其他相关术语,如岩性、含水饱和度、密度、渗透率和孔隙度。

岩石物理学家的职责是什么?

间隔拍摄

岩石物理学强调与孔隙系统及其流体分布和流动特征相关的性质。这些属性及其关系用于识别和评估:

  • 油气藏
  • 碳氢化合物来源
  • 密封
  • 含水层

岩石物理学家或岩石物理工程师作为油藏管理团队的一员实践岩石物理学。这位岩石物理学家提供了团队成员需要和使用的产品的答案,以及其他队友需要的物理和化学见解。要确定的储层和流体特性有:

  • 厚度(地层边界)
  • 岩性(岩石类型)
  • 多孔性
  • 流体饱和度和压力
  • 流体识别和表征
  • 渗透率(绝对)
  • 分流(油、气、水)

来自 斯伦贝谢 媒体公司

很容易定义这些特征并理解它们在储量评估中的作用。困难的部分在于确定它们的实际价值,这种确定性是作出导致开发和生产的经济决策所必需的。列出的七个特征是相互依赖的(即,为了正确确定电缆测井的孔隙度,必须知道岩性、流体饱和度和流体类型)。然后,岩石物理学被用来解读从地表以下到超过四英里深的储层中岩石和流体性质的隐藏世界。然后,这位岩石物理学家利用虚构侦探夏洛克·福尔摩斯的许多特征,从最贫乏的线索中推断出地下储油层的真实情况,用顽强的决心从现有数据中获取所有可能的信息,同时享受狩猎的刺激。

岩石物理学家是如何解决这个难题的?

阿奇的一般方法是将问题细分成更小的片段,使用所有数据迭代,直到所有数据一致。一个起点是确定岩石类型(岩相),其中我们确定:

  • 孔隙类型
  • 气孔分布
  • 孔喉型
  • 孔喉分布

当与流体类型相结合时,可以建立一个毛细管压力模型,这将导致对原位流体饱和度和流体流动的理解。然而,可供岩石物理学家使用的工具有:

案例研究:声波测井综合预测

照片由本工程Unsplash 上拍摄

由于财政或操作的限制,并不是在一个油田中钻探的所有井都获得压缩旅行时(DTC)和剪切旅行时(DTS)测井。在这种情况下,可以使用机器学习技术来预测 DTC 和 DTS 测井,以改善地下表征。本岩石物理数据驱动分析项目的目标是通过处理 casr 研究“1 井”中“易于获取”的常规测井数据开发数据驱动模型,并使用数据驱动模型生成案例研究“2 井”中的合成 DTC 和 DTS 测井数据。用于期望的声波测井合成的稳健的数据驱动模型将导致低的预测误差,这可以通过比较合成的和原始的 DTC 和 DTS 测井,以均方根误差(RME)来量化。

提供了井数据集(由井 1 和井 2 组成),目标是使用井 1 数据集建立可概括的数据驱动模型。接下来,您将在 Well 2 数据集上部署新开发的数据驱动模型,以合成 DTS 和 DTC 日志。数据驱动模型使用从以下七种测井中导出的特征集:井径、中子、伽马射线、深层电阻率、介质电阻率、光电系数和密度。数据驱动模型应该合成两个目标日志:DTC 和 DTS 日志。

数据源

数据的位置是一个 Github 存储库,该存储库来源于由位于 Petrophysical 数据驱动分析的 amazing 团队维护的 GitHub 存储库

来自 SPWLA

用哪种机器学习算法?

照片由 Charles DeluvioUnsplash 上拍摄

对于给定的问题,找到最佳算法的唯一方法是尝试和测试所有算法

为这个项目尝试所有可能的机器学习算法非常耗时,因此在本文的上下文中,我们将使用 eXtremeGradientBoosting(XGBoost)算法。从问题陈述中,我们预测两个特征,使其成为一个多目标回归问题。将应用 XGBoost 回归器和 SKlearn 的 MultiOutputRegressor

XGBoost 是什么?

来自 Github 库的 XGBoost 徽标

名称 XGBoost 实际上指的是提升树算法的计算资源极限的工程目标。这也是很多人用 XGBoost 的原因。

这是一个由陈天琦创建的梯度推进机器的实现,现在有许多开发者参与其中。它属于分布式机器学习社区或 DMLC 旗下更广泛的工具集合,他们也是流行的 mxnet 深度学习库的创造者。这是一个免费的开源软件,可以在 Apache-2 许可下使用,它支持以下主要接口:

  • 命令行界面(CLI)。
  • Python 接口以及 scikit-learn 中的一个模型。
  • C++(编写库的语言)。
  • r 接口以及 caret 包中的一个模型。
  • 朱莉娅。
  • 像 Scala 这样的 Java 和 JVM 语言以及 Hadoop 这样的平台。

为什么选择 XGBoost?

图书馆被激光聚焦

  1. 计算速度:一般情况下, XGBoost 快。与梯度增强的其他实现相比,速度非常快。
  2. 模型性能: XGBoost 在分类和回归预测建模问题上主导结构化或表格化数据集。证据是,它是竞争数据科学平台 Kaggle 上竞争获胜者的首选算法。

XGBoost 安装

对于稳定版本,可以使用 python 包索引(PyPI)将 XGBoost 包安装到 Python 环境中。

pip install xgboost

导入包

这里,我们从导入这个项目需要的所有 python 库开始。

  • warning:用于抑制 python 包中不推荐使用的函数的警告控件。
  • numpy:用于科学计算。
  • pandas:为了数据争论和分析
  • matplotlib:用于图形和图表的可视化。
  • xgboost:用于预测的机器学习算法。
  • MultiOutputRegressor:提供多目标回归环境。
  • StandardScaler:缩放数据
  • train_test_split:拆分数据
  • RandomizedSearchCV:随机参数调谐
  • mean_square_error:用于评估预测的性能指标。

读取数据

首先,在数据输入过程中,大多数情况下缺失值被替换为-999,因此将其识别为系统的缺失值指示器是理想的。这里,空白以及NanNaN也被识别为数据集中的缺失值指示符。

获取数据概览

各个特征的数据描述如下:

  • CAL:井径测井(单位为英寸)
  • CNC:神经元日志(单位为十二月)
  • GR:伽马射线测井(单位为 API)
  • HRD:深电阻率测井(单位为欧姆每米)
  • HRM:中电阻率测井(单位为欧姆每米)
  • PE:光电系数(单位为谷仓)
  • ZDEN:密度测井(单位为克每立方公尺)
  • DTC:压缩传播时间 lo(单位为纳秒每英尺)
  • DTS:剪切传播时间测井(单位为纳秒每英尺)

DTC 和 DTS 称为声波测井,可以从接收器记录的波形中计算出来。还计算了描述性统计。

检查缺失值

可以观察到,在训练数据中存在大量的缺失值。让我们来看看数据的分布情况。

填充缺失的值

大多数要素的直方图是单摩尔直方图,而其他直方图是倾斜的,用数据框中的前一个值填充前者,用中值填充后者将非常合理。pandas fillna backfill方法和 medianmedian.()方法将支持使用先前值方法进行填充。

特征工程

本出版物中的特征工程主要关注伽马射线测井(GR)特征。从直方图中可以观察到异常值,因为 GR 值通常在 0-200 之间。我们将从 GR 中创建两个新特性,同时将其限制在上限和下限。要创建的两个新功能是:

  1. 伽马射线指数(IGR)
  2. 自然伽马辐射(NGR)

在使用伽马射线测井(GR)功能创建其他功能以减少数据冗余后,应将其删除。

拆分数据

训练数据以 70:30 的比例分割

数据的标准化

当各种变量放在相同的刻度上时,大多数机器模型工作得最好。

模型建立和拟合

XGBoost 回归是用已经调优的超参数实例化的。超参数调整是一个非常耗时的过程,本文中跳过了这一步,但是可以在 github 上的笔记本中查阅。该模型适合于训练数据,以帮助学习过程。

模型预测和评估

模型的最终输出—预测。****的值越低,表明拟合度越好,模型看起来越好!最后,模型被应用于它没有见过的数据——“测试”数据。

我希望本文能拓宽机器学习在岩石物理行业的应用领域。感谢阅读和保持安全。

作为创造性工具的机器学习,以及对人工智能的探索

原文:https://towardsdatascience.com/machine-learning-as-a-creative-tool-and-the-quest-for-artificial-general-intelligence-dfaf81ce7927?source=collection_archive---------17-----------------------

苹果 | 谷歌 | SPOTIFY | 其他 | 剪辑

史云光·斯廷布鲁奇在 TDS 播客

📸由 sergio souzaUnsplash 上拍摄的照片

编者按:迈向数据科学播客的“攀登数据科学阶梯”系列由 Jeremie Harris 主持。Jeremie 帮助运营一家名为sharpes minds的数据科学导师初创公司。可以听下面的播客:

大多数机器学习模型的使用方式大致相同:它们接受复杂的高维输入(如数据表、图像或文本正文),并返回非常简单的内容(分类或回归输出,或一组聚类质心)。这使得机器学习成为自动化重复任务的理想选择,这些任务在历史上可能只能由人类来完成。

但这种策略可能不是未来机器学习最令人兴奋的应用:越来越多的研究人员甚至行业参与者正在试验生成模型,从零开始产生更复杂的输出,如图像和文本。这些模型有效地执行了一个创造性的过程——掌握这个过程极大地拓宽了机器可以完成的范围。

我今天的嘉宾是史云光·斯廷布鲁格,他的重点是机器学习的创造性方面。除了为大公司提供咨询,帮助他们将最先进的机器学习模型投入生产,他还将大量工作集中在更多哲学和跨学科问题上,包括艺术和机器学习之间的互动。出于这个原因,我们的谈话朝着一个不同寻常的哲学方向发展,涵盖了从语言结构到什么使自然语言理解比计算机视觉更具挑战性,到人工通用智能的出现,以及所有这些东西如何与机器学习的当前艺术状态相联系。

以下是我最大的收获:

  • 公司内部开发的大量机器学习模型最终都没有被部署。从他的咨询经验来看,史云光表示,出现这种情况的原因是,公司往往对部署“酷”的最先进模型的前景感到兴奋,而不是专注于解决真正的业务问题。然而,这个问题并不是公司独有的:伟大的数据科学家的标志是,他们在考虑花哨的模型之前,先考虑创造商业价值。
  • 语言数据本质上比图像数据对变化更敏感。你可以通过改变一两个单词来完全改变一个句子或段落的意思,但改变一小撮像素的颜色不会对图像所传达的意思产生太大影响。这是语言建模尚未赶上计算机视觉的很大一部分原因,尽管最近取得了重大进展。
  • 目前,语言模型仅参考其他单词来定义单词的含义。这可能感觉就像我们做的一样——毕竟,如果我让你定义苹果是什么,你回答的唯一方式是引用其他词,比如“水果”、“甜”或“树”。你可能会想象——哲学家雅克·德里达也是这样想的——因为这些单词中的每一个都是相对于其他单词来定义的,所以所有的语言基本上只是一种任意的、自我指涉的混乱,与任何具体事物都没有联系。
  • 然而,这可能不是故事的结尾,因为人类不仅仅是通过阅读数百万篇维基百科文章和将一个词与另一个词连接起来建立一个相互依赖的网络来学习单词的含义。相反,我们用其他来源的数据来补充这个策略,比如视觉、声音、嗅觉和触觉。因此,要创造一个真正的人工智能,可能还需要多种输入类型。
  • 在关于构建人工智能需要什么的辩论中,有两个阵营:一个阵营认为,我们主要通过提高计算能力和增加内存来解决问题,另一个阵营认为,需要更复杂的模型。史云光认为有可能两者都需要,而且以新的方式结合模型也可能导致 AGI 式的性能显著提升。

你可以在推特上关注史云光在推特上关注我在推特上关注我

夹子

YouTube

我们正在寻找能与我们的观众分享有价值的东西的客人。如果你碰巧知道谁是合适的人选,请在这里告诉我们:publication@towardsdatascience.com

保险公司的机器学习

原文:https://towardsdatascience.com/machine-learning-at-insurance-companies-2ac7ad109c65?source=collection_archive---------58-----------------------

洞察保险公司对先进模型的缓慢采用

谁是德尼罗? on Unsplash

这些年来,我阅读了很多关于保险公司以及由商业和技术创新驱动的即将到来的变革的论文,通常被称为保险技术。与传统的保险业务模式相比,这些保险技术公司利用技术开发基于分析的方法来改进现有流程,从而获得竞争优势。保险公司被警告要么跟上,要么灭亡…

鉴于竞争格局和不断蒸发的利润率,传统保险公司被建议发展成为由机器学习(ML)和人工智能(AI)驱动的数据驱动型企业。保险公司的这些高级模型有几个用例。大数据分析(BDA)为保险公司带来的优势如下:

资料来源:ei opa——欧洲保险和职业养老金管理局,https://www.eiopa.europa.eu/专题评论

保险公司在采用 ML 和 AI 方面取得了一些进展。一些公司已经建立了数据科学卓越中心来定义和实现他们业务中的用例。此外,一些保险公司正在投资,通过向员工提供数据科学和大数据课程,有机地构建他们的内部知识。

为了进一步加速数字创新,一些保险公司正在通过内部孵化器、加速器和创新实验室与初创公司合作。这对双方都有利,因为初创公司受益于成熟的技术支持、指导和与行业专家的联系,而保险公司则获得了新技术。

另一方面,一些保险公司通过组建企业风险投资公司来投资 T2 的保险技术公司。向多家初创公司投入相对较少的资金,可以让保险公司在他们感兴趣的众多领域获得潜在突破。

尽管围绕高级模型的嗡嗡声令人麻木,这些创新的解决方案还没有获得显著的牵引力。保险公司没有像预期的那样迅速瓦解,而是慢慢适应了这些变化。因此,我想解释一下保险公司采用先进模型的缓慢过程。

下图总结了保险公司面临的大数据分析(BDA)挑战。

资料来源:ei opa——欧洲保险和职业养老金管理局,https://www.eiopa.europa.eu/专题评论

保险公司在负责任地实施 ML 和 AI 方面面临着相当多的挑战。我想考虑其中的一些挑战,并提供额外的背景。首先,保险公司认为主要风险在于与消费者打交道,这需要保持消费者的信任,合乎道德地使用人工智能,并识别危及保险公司和保险行业声誉的潜在风险。

创新是保险公司的一个议程项目,然而,预测机器学习项目的投资回报几乎是不可能的。规划或预算这样的项目并不容易,因为根据调查结果,项目期间的资金可能会有所不同。因此,这一项被忽视了,尤其是与更紧迫的项目相比,如符合新的和即将出台的(监管)标准或保险公司的盈利能力考虑到当前的低利率环境。

每个数据科学家都知道 GIGO " 垃圾输入,垃圾输出"。这是 ML 在保险公司中没有获得牵引力的另一个原因,即数据质量。高质量和各种输入数据的可用性是应用高级模型的先决条件。目前,保险公司的数据质量很差,因此最大限度地降低了 ML 和 AI 的附加值。

保险公司 AI 和 ML 的一个有利发展是新法规和即将出台的法规对数据的要求增加。具体来说,新的报告标准(IFRS 17)要求更多的数据粒度,因为保险公司正在彻底检查其 IT 系统和架构,以应对数据量和质量的增加。

最后,保险公司也意识到他们需要“保持控制”,尤其是在定价和保留领域。ML 和 AI 模型通常与术语黑盒模型联系在一起。因此,保险公司不清楚如何在不超出法律和监管要求的情况下使用人工智能。因此,保险公司面临的挑战是在监管空间内构建一个合规且可解释的垫款模型框架。

结论

颠覆通常与创新发展结合使用。然而,要真正颠覆一个行业,仅仅创新是不够的。颠覆需要大规模采用。

保险业已经注意到了这些技术的发展,保险公司也相应地动员了他们的努力和资金。考虑到保险公司在 ML 和 AI 方面面临的一系列挑战,他们正在慢慢适应不断变化的环境。因此,它们越来越受数据和技术的驱动。

边缘的机器学习!

原文:https://towardsdatascience.com/machine-learning-at-the-edge-a751397e5a06?source=collection_archive---------44-----------------------

使用 OpenCL 在运行嵌入式 Linux 的小型处理器的 GPU 上实现机器学习/图像处理,以获得实时性能

(图片由维基百科提供)

内容:

  • 概观
  • 旅行寻找可行的解决方案
  • 构建您自己的工作解决方案
  • 吸取的教训。

概述

所以,我有一个工作机器学习(ML)模型,我想把它移到边缘。

顺便说一下,我的 ML 模型处理图像以进行深度估计,从而为自主机器人提供感知能力。使用的机器学习模型是基于麻省理工学院的快速深度。这是一个专注于速度的 U-Net 架构。它使用一个 MobileNet 编码器和一个匹配的带跳跃连接的解码器。

(图片由作者提供)

它是在 Python 上使用 Keras(起初是 PyTorch)开发的,带有 CUDA 后端。

通过移动到边缘,我的意思是我需要在运行嵌入式 Linux 的小型 CPU/GPU(高通 820)上运行,其中 GPU (Adreno 530)只能通过 OpenCL(即,不是 CUDA)访问。)

警告——如果你在 iOS 或 Android 上,你已经相对自由了。这篇文章是为了在嵌入式 Linux 的 GPU 上使用 OpenCL 进行机器学习。

四处寻找可行的解决方案

这很容易。哈!原来一旦你离开 CUDA,你就在荒野中…

实际上,有两种广泛的方法可以在边缘部署模型。

  1. 尝试在边缘复制您的开发环境,并让它在那里运行。如果这是可能的,这总是一个好的第一步,如果只是为了说服自己它的表现有多慢。我尽可能地探索了这个世界,尽管在我的设备上甚至没有完整的 Linux,所以我甚至不能支持 Python。
  2. 找到一个推理框架,它可以在一个更高性能、更少资源的环境中运行你的代码。这需要你做更多的工作,特别是当你要把你的 C++编码技能拿出来的时候。这就是我们要探索的地方。

通过谷歌搜索和参考资料,我发现了一系列可能的方法。

同样,我有一个 Keras 模型,我想在嵌入式 Linux 上的高通 820 GPU(实际上 Adreno 530 是 GPU)上尽可能快地运行。没有量化的方法进行评估。

这是我探索的世界:(即,很多很多的“死胡同”)

GPU“边界”的地图

解释:

  • Keras —该模型是在 Keras 开发的。
  • ONNX —一些选项提供了 ONNX 导入,例如 OpenCV。原来 ONNX,至少在那个时候——2019 并不支持我在用的所有 Keras 算子。
  • Tensorflow-这是一个重要的层,因为大多数(如果不是全部)引擎都是从 tensor flow 导入/转换的,而不是从 Keras 导入/转换的。最终的解决方案——MACE 需要相对较旧版本的 tensor flow——他们要求 1.08 版——尽管 1.14 版也能工作……请参见下面的 SYKL 了解如何使用 Tensorflow runtime。
  • Tensorflow Lite/TF-Lite。然而,为这种情况设计的,没有办法(我能找到)通过 OpenCL 把它连接到 GPU。
  • SYKL——据说是一种将 Tensorflow 连接到 OpenCL 的方法。没什么进展就只好放弃了。
  • Arm 计算机库。这是可行的,但是缺点是(我无法找到)导入模型。使用这些或用他们的语言编码。
  • ARM 神经网络。来自制造商的一种“官方”方式——ARM。应该很容易。见鬼,我被卡在巨大的安装区域的某个地方,永远也不能让它工作。这是一个可以从提供 Docker 环境中真正受益的群体。
  • 移动 AI 计算引擎——MACE。至少部分是为这个用例设计的!来自小米。这个居然管用!而且效率很高!他们的支持很好——这些人很棒!更多见下文。
  • 移动神经网络-MNN。只是玩玩这个,因为我最近刚刚“发现”这个,但这个看起来很棒,可能会更容易从 Keras 过渡到平台,也可能会进行更多的优化。来自阿里巴巴。
  • tvm.ai .专为在 GPU 上执行而设计,尤其是为了效率。然而,它需要的比我的迷你 Linux 所能提供的更多,而且他们并不真正喜欢 OpenCL。我想让这个工作,特别是发挥了 MNN 的效率。
  • OpenCV。DNN 软件包是为运行 ONNX 模型而设计的,事实也的确如此。如果 verrryyyy 慢。非常失望。此外,结果是我不能在我的运行时使用 OpenCV,所以这是一个不成功的例子。
  • 骁龙神经处理引擎。从高通,见鬼,这应该很容易。首先,来自高通的支持让康卡斯特看起来像明星。见鬼,就此打住——这个工具在我的环境中是行不通的。
  • open vino——看起来很有前景,但似乎只面向英特尔。

在 MACE 上构建自己的工作解决方案

下面是让你的模型在 GPU 上运行的大致步骤(在使用 OpenCL 的嵌入式 Linux 系统上!)这很像是他们文档的画外音,其中有一些关键的提示。

  1. 克隆权杖。【https://github.com/XiaoMi/mace
  2. 让 Docker 环境工作起来。我用的是全环境。
  3. 为您的目标配置。有多种架构选项以及 Linux/Android 选择。在我的例子中,我的架构选择是 armeabi-v7a。(这是一个更长的故事,为什么不是 64 位架构。)不幸的是,为该架构配置的操作系统是 Android。所以我不得不稍微混合搭配一下来得到 Linux。
  4. 为目标制造狼牙棒。

所有这些都是一次性的启动事件(一旦成功)。

现在,要获得你的 Keras 模型的梅斯转换…

输入张量流

哦,等等。原来 MACE 只支持 Tensorflow 到大约 1.14 版,根本不支持 Keras。因此,我必须将我的 Keras 模型转换为正确年份的 Tensorflow。这是一些工作,基本上是在 Tensorflow 中制作完全相同的模型,然后复制权重。和迭代,因为没有什么是那么容易的。Netron 是一个很好的工具,可以深入了解和比较你的模型的本质。

一个优化是,您还可以轻松地添加图像预处理以提高性能。例如,这些线不在 Keras 模型中,只在 Tensorflow 模型的前面。这允许我们将预处理从 CPU 转移到 GPU 上,特别是图像大小调整和数据规范化。

Rs224 = tf.image.resize_bilinear(input,(224,224), name='resize224')
# normalize data, identical to how we trained
Norm224 = tf.scalar_mul(1./255., Rs224)
Norm224 = tf.scalar_mul(2., Norm224)
Norm224 = tf.math.add(-1., Norm224)

继续转化为狼牙棒

回到转换:

  1. 创建您的 YAML 文件。请注意,您需要为模型的每个新版本创建一个 sha256sum 代码。
  2. 做你的转换。
python tools/python/convert.py — config ../mace-models/yourmodel.yml

3.测试你的转换。好吧,梅斯倒在这里。事实证明,如果不加入一些东西来移动,Linux 版本并不能真正工作。应该起作用的是…

python tools/python/run_model.py  \
    --config ../../mace-models/yourmodel/yourmodel.yml \
    --validate \
    --target_abi arm-linux-gnueabihf \
    --target_socs root@192.168.8.1 \
    --device_conf ../../mace-models/820.yml

但事实并非如此。结果他们的剧本失败了。(修复—您需要手动将“/tmp/mace _ run/your model/validate _ in/XXX”上移一级,然后执行。他们脚本中的/mace_run 命令。)

运行时的 c++

最后,编写在目标环境中运行的 C++代码。我在一个 ROS 节点内运行,该节点监听新的摄像机图像事件。这个节点将处理它们,并创建深度云输出,以供下游处理,比如说八分图。

调用 MACE 推理引擎的关键部分包括:

**// define input node (output nodes not shown)**
const std::vector<std::string> mace_input_nodes{"input"};
const std::vector<int64_t> mace_input_shape{{1, 480, 640, 3},};
...
**// initialize the 'engine' (though of course more surrounds this)**
create_engine_status = CreateMaceEngineFromProto(reinterpret_cast<const unsigned char *>(
                              model_graph_data->data()),
                              model_graph_data->length(),
                              reinterpret_cast<const unsigned char *>(
                              model_weights_data->data()),
                              model_weights_data->length(),
                              mace_input_nodes,
                              mace_output_nodes,
                              config,
                              &engine);
...
**// execute model**
run_status = engine->Run(inputs, &outputs, nullptr);

真正的好消息。我希望每秒 10 帧。即使在添加了之前显示的图像预处理(通常在 C++代码中)后,我最终达到了 25 fps。太棒了。以至于整个系统的其他部分成了门控因素。实际上,我必须降低 ML 推理的执行速度,以免系统的其他部分过载!

吸取的经验教训

  • 对于所有这些推理方法,请确保您的操作受到支持。例如,OpenCV 不支持上采样。
  • 你必须尝试一下,看看是否行得通。
  • 如果工具供应商提供了一个 Docker 环境,那么它工作的可能性会大得多。
  • 如果他们对论坛上的问题做出回应,这是一个好迹象。如果没有,那就跑吧,不要走开。
  • 尝试多种方法,因为许多方法都会以某种方式失败,通常是你不怀疑的方法。

祝你好运!

机器学习:自动编码器

原文:https://towardsdatascience.com/machine-learning-autoencoders-712337a07c71?source=collection_archive---------14-----------------------

使用自动编码器将高维数据拟合到更密集的表示中

我通过维基百科找到了自动编码器最简单的定义,它将自己翻译为“一种学习数据低维编码的机器学习模型”。这是减少数据集维数的最聪明的方法之一,只需使用微分终止(Tensorflow,PyTorch 等)的功能。事实上,我们应该有一个特定的神经网络架构,以实现这一点。不过,在开始之前,我们先简单概述一下降维。

PCA 与自动编码器

PCA 和自动编码器都打算学习低维表示,从而通过低维表示减少原始维度的重构误差。但是,正如您可能知道的,PCA 将原始数据转换为一组较低的相互正交的维度。我们称之为到另一个空间的线性转换。问题来自于线性部分。信息损失可能会更高。与自动编码器相比,神经网络使用梯度下降来估计较低维度的隐藏层的最佳可能参数。

设计自动编码器

自动编码器采用数据流通过瓶颈的架构。这个瓶颈代表了较低的维度。自动编码器被期望学习这个较低的维度,从而最小化在输入和输出之间定义的误差分数。

让我们来看看一个简单的自动编码器(来自维基百科)。

自动编码器示意图

如你所见,我们有一个中间元素,它是一个狭窄的通道。训练的输入和输出通常是相同的,因为我们打算学习低维表示。

使用 Keras 构建自动编码器

我们通常的进口商品是:

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt # for plots

处理数据;以 MNIST 手写数据集为例。

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()x_train = x_train.astype('float32') / 255
x_test = x_test.astype('float32') / 255x_train = np.round(x_train, 0)
x_test = np.round(x_test, 0)x_train = x_train.reshape((len(x_train), np.prod(x_train.shape[1:])))
x_test = x_test.reshape((len(x_test), np.prod(x_test.shape[1:])))print(x_train.shape)

请注意,我们对数据进行了四舍五入。这是因为这个数据集是灰度的,我们只考虑严格的黑色像素和严格的白色像素。这有助于我们形成一个 二元交叉熵 作为损失函数。

让我们使用 Keras functional API 创建网络。

inputs = tf.keras.layers.Input(784)
encoded_1 = tf.keras.layers.Dense(128)(inputs)
encoded = tf.keras.layers.Dense(64, activation='relu')(encoded_1)
decoded_1 = tf.keras.layers.Dense(128)(encoded)
decoded = tf.keras.layers.Dense(784, activation='sigmoid')(decoded_1)auto_encoder = tf.keras.Model(inputs, decoded)
auto_encoder.compile(loss='binary_crossentropy', 
                     optimizer='adam', 
                     metrics=['accuracy'])auto_encoder.summary()
tf.keras.utils.plot_model(auto_encoder, show_shapes=True, to_file='autoenc.png', dpi=200)

注意,我使用了binary _ cross entropy,因为我们的数据是二进制格式(0 或 1)。完整的层集是自动编码器(编码和解码以给出相同的输出)。让我们看看我们的编码器。我们可以使用从 输入编码 的层来构建它,如下所示。

自动编码器的可视化

encoder = tf.keras.Model(inputs, encoded)encoder.summary()
tf.keras.utils.plot_model(encoder, show_shapes=True, to_file='enc.png', dpi=200)

编码器的可视化

虽然您可以使用顺序 Keras API 来实现这一点,但我发现函数式 API 更优雅(只是个人意见,您可能会在以后的文章中看到原因)。

使用自动编码器

既然我们已经构建了我们的自动编码器,我们可以拟合我们的训练数据。

auto_encoder.fit(x_train, x_train, 
                 epochs=10,
                 batch_size=256,
                 shuffle=True)

经过训练,我获得了 0.98510.9851 的准确度,这个准确度还不错!。因此,我们可以期待降维方面的良好表现。

让我们看看 MNIST 测试数据集的估计低维和重建图像。

predicted_2dim = encoder.predict(x_test)
predicted_original = auto_encoder.predict(x_test)

注意,对于解码后的值,我直接将原始数据提供给完整的自动编码器,后者在编码后直接进行重构。对于编码,我使用编码器组件。

看起来怎么样?

未经调整的输入数据如下所示:

原始字符

编码图像看起来像这样:

编码字符

重建看起来是这样的;

重构字符

注意事项

  • 请注意,重建的图像看起来很模糊。这是因为我们的最后一层是由s 形 函数激活的。该函数返回范围 01 内的值。
  • 我们使用 relu 激活函数,因为在中间层,当我们使用 sigmoid 函数时,值变小的几率更高。
  • 当我们减小隐藏维数时,重建的精度降低。重建看起来像这样。它只有人物的可辨别的特征,而不是确切的人物。

使用二维重建

  • 我们可以看到,在上面的图像 9 和 4 几乎是相似的。更多的信息丢失了。
  • 我的字符绘图功能(可能会有用)
shown = {}
fig = plt.figure(figsize=(20, 10))
fig.subplots_adjust(hspace=1, wspace=0.1)
i = 0for data, y in zip(predicted_original, y_test):
    if y not in shown and y==len(shown):
        i += 1
        ax = fig.add_subplot(1, 10, i)
        ax.text(1, -1, str(y), fontsize=25, ha='center', c='g')
        ax.imshow(np.array(data).reshape(28, 28), cmap='gray')shown[y] = True
    if len(shown) == 10:
        break

随意更改代码并运行。希望这篇文章有用。我将在以后的文章中介绍变型自动编码器!

干杯!

机器学习基础和古代哲学家

原文:https://towardsdatascience.com/machine-learning-basics-and-the-philosophers-of-old-7bd66cd1191f?source=collection_archive---------55-----------------------

他们可能也不会明白

扎克·法默在 Unsplash 上的照片

苏格拉底从他的 Jupyter 笔记本上抬起头,给了你那个眼神——你现在已经习惯了。你已经花了足够多的时间在古代伟大的哲学家身边,知道你即将接受教育。又来了。

“你不懂机器学习是什么意思?”他苦笑着说。“这正是重点。我以前告诉过你,最好知道你什么都不知道*。”

你靠在椅子上,叹了口气。当女服务员拿走你的咖啡杯时,你对她微微一笑。“但是苏格拉底,”你开始。“我找到的所有在线资源要么充斥着行话,要么过于简单,让我看不出其中的任何一点。”

苏格拉底抿了一口他的第三杯南瓜香料拿铁,停顿了一会儿。最终,他把目光回到了笔记本电脑上,再次开始敲键盘。“要是有人能写一篇关于它的博客就好了。”

基础知识

机器学习是一个复杂的领域,但如果你能把一些基础知识藏在记忆库中,那么你会更容易理解一些更高级的资源和对话。今天,我们将讨论一些不可避免的概念。

什么是机器学习来着?

机器学习是“对计算机编程的科学(和艺术),以便它们可以从数据中学习”(A. Géron 在他的 2019 年中)。这是教计算机有用的东西。虽然人类的大脑极其复杂,但有很多任务电脑比我们做得更好。一个这样的任务是在非常大的数据集合中识别模式。如果你能给计算机足够多的例子来说明你想让它做什么,当你给它新的例子时,它就能学会如何自己做决定。

这很好吧?

是的,非常好!在某些任务上,计算机可以比人快几个数量级,而且往往也更准确。这项任务可以是图像识别——根据图像中的物体对图像进行标记或分类,或者检测医学扫描中的异常情况。它可能是转录或翻译讲话。它可以预测某个事件在未来发生的可能性,这通常需要多年的研究和对某个现象的专业知识。机器学习节省了时间和金钱,并且可以以其超人的性能更广泛地为企业和社会产生新的可能性。

监督学习

在监督学习中,你训练机器学习模型的数据带有你希望计算机预测的结果标签。例如,如果你想预测一名银行客户是否会拖欠新贷款,你可以向机器学习模型输入以前客户的数据,包括 他们是否最终违约,希望它学习如何识别高风险客户。通过这种方式,学习过程被“监督”,因为计算机被告知数据对应于哪个答案。

无监督学习

在无监督学习中,模型的训练数据不带有任何标签。然后,计算机被要求做几件事情中的一件——这可能是将数据分成相似实例的组,以识别异常值(与其他数据点完全不同的数据点——就像一个穿着长袍的灰胡子男人在其他正常的星巴克里一样),或者突出输入变量之间的潜在关系。无人监督的学习可能被用来标记非典型的和看起来像欺诈的金融交易。或者它可以用来调查人们在网上商店购物时倾向于一起购买什么样的产品。

图为杆长未溅上

强化学习

强化学习是由一个“代理”定义的,它可以从几个动作或输出中进行选择。该代理在做出选择时会得到反馈,并因做出“好”的选择而获得奖励(根据我们预先指定的一些定义)。该代理最初的工作糟糕透顶,但随着它收集越来越多的行动反馈,它会很快变得更好。强化学习可以用来训练制造机器人——例如生产线上的机械臂。机器人手臂因执行所需的动作而获得奖励——无论是将组件从一个地方移动到另一个地方,还是建造某个汽车部件——并因不相关或负面的动作而受到惩罚(例如摔东西、制造混乱,或变得有自我意识并试图毁灭所有人类)。坏机器人)。

我听说的深度学习是怎么回事?

深度学习是机器学习的一个子领域,它涉及由所谓的“人工神经网络”组成的模型。这些是由分层算法组成的,可以在输入数据中逐步提取越来越复杂的特征。例如,人脸图像的低级和简单特征将是人脸的边缘所在的位置。一个更复杂的特征可能是这个人看起来是快乐还是悲伤——这并不简单。这些算法由一层层的“神经元”组成,这些神经元与人脑的神经元大致类似,因为给定一定的输入,模型中的一些神经元会激活,而另一些不会。神经元然后一起工作,共同决定模型应该输出什么。

深度学习系统可能极其复杂,但也可能极其强大。这些架构支撑了脸书的自动照片标记功能、谷歌翻译,甚至是可以在围棋等游戏中击败世界级选手的算法——仅在几年前,这还被认为是我们当前技术无法实现的壮举。

NLP 到底是什么???

自然语言处理,缩写为 NLP,是机器学习的另一个子领域,旨在设计能够理解人类语言及其背后意图的计算机模型。NLP 模型可以被设计和训练来简化或总结文档,分析书面文本的语气或情绪,识别和翻译语音,或者预测你想在手机键盘上打出的下一个单词。NLP 是一系列机器学习问题的统称,这些问题在本质上可能是有监督的,也可能是无监督的。

结论

这是对一些高级机器学习概念的快速介绍。它可能仍然让人觉得是一个难以理解的广阔研究领域——这是因为它确实如此!像许多其他学科一样,人们把他们的一生都奉献给了极其狭窄的研究领域,并且只找到了越来越多的深度去探索。

但希望下次你打开一篇关于机器学习最新发展的文章时,你能够认出这次的一些关键主题。然后,也许你可以选择一两个你不太理解的话题或术语,做一些研究,试图掌握它们。你可能会以问题多于答案而告终——但这不一定是件坏事。如果你能做到这一点,那么至少你会知道你所不知道的。

苏格拉底会感到骄傲的。

*当然,没有记录表明苏格拉底本人说过这句话。

或者他喜欢南瓜香料拿铁。

更多信息和积分

Andrew Hetherington 是英国伦敦的一名见习精算师和数据爱好者。

  • LinkedIn 上与我联系。
  • 看看我在 GitHub 上摆弄什么。

照片由扎克农夫竿长拍摄。

机器学习基础:决策树回归

原文:https://towardsdatascience.com/machine-learning-basics-decision-tree-regression-1d73ea003fda?source=collection_archive---------2-----------------------

实施决策树回归算法并绘制结果。

之前,我已经解释了各种回归模型,如线性、多项式和支持向量回归。在本文中,我将通过一个真实的例子向您介绍决策树回归的算法和实现。

决策树算法综述

决策树是监督学习最常用、最实用的方法之一。它既可以用来解决回归问题,也可以用来解决分类问题,而分类问题在实际应用中得到更多的应用。

它是一个树形结构的分类器,有三种类型的节点。 根节点 是代表整个样本的初始节点,并且可以被进一步分割成更多的节点。 内部节点 代表数据集的特征,分支代表决策规则。最后, 叶节点 表示结果。这个算法对于解决决策相关的问题非常有用。

来源

对于一个特定的数据点,通过回答对/错问题来完全遍历整个树,直到它到达叶节点。最终预测是该特定叶节点中因变量的平均值。通过多次迭代,该树能够预测数据点的适当值。

决策树模型示例(来源

上图是决策树算法实现的示意图。决策树具有易于理解、需要较少的数据清理、非线性不影响模型性能以及要调整的超参数数量几乎为零的优点。然而,它可能有一个过度拟合的问题,这个问题可以使用 随机森林 算法来解决,这将在下一篇文章中解释。

在这个例子中,我们将经历 决策树回归 的实现,其中我们将根据一个地区 500 天的温度来预测一家冰淇淋店的收入。

问题分析

在这个数据中,我们有一个独立变量温度和一个独立变量收入,我们必须预测它们。在这个问题中,我们必须建立一个决策树回归模型,该模型将研究冰淇淋店的温度和收入之间的相关性,并根据特定日期的温度预测冰淇淋店的收入。

步骤 1:导入库

第一步总是包括导入开发 ML 模型所需的库。导入 NumPymatplotlib熊猫库

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

步骤 2:导入数据集

在这一步中,我们将使用 pandas 来存储从我的 github 存储库中获得的数据,并使用函数' pd.read_csv '将其存储为 Pandas DataFrame。在此,我们将自变量(X)分配给'温度'列,将因变量(y)分配给'收入'列。

dataset = pd.read_csv('[https://raw.githubusercontent.com/mk-gurucharan/Regression/master/IceCreamData.csv'](https://raw.githubusercontent.com/mk-gurucharan/Regression/master/IceCreamData.csv'))X = dataset['Temperature'].values
y = dataset['Revenue'].valuesdataset.head(5)>>Temperature   Revenue
24.566884     534.799028
26.005191     625.190122
27.790554     660.632289
20.595335     487.706960
11.503498     316.240194

步骤 3:将数据集分为训练集和测试集

下一步,我们必须像往常一样将数据集分成训练集测试集。为此,我们使用test_size=0.05,这意味着 500 个数据行的 5%(25 行)将仅用作测试集,剩余的 475 行将用作构建模型的训练集。

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.05)

步骤 4:在训练集上训练决策树回归模型

我们从sklearn.tree导入DecisionTreeRegressor类,并将其赋给变量' '回归变量' 。然后我们通过使用regressor.fit函数将 X_train 和 y_train 拟合到模型中。我们使用reshape(-1,1)将变量整形为一个列向量。

# Fitting Decision Tree Regression to the dataset
from sklearn.tree import DecisionTreeRegressor
regressor = DecisionTreeRegressor()
regressor.fit(X_train.reshape(-1,1), y_train.reshape(-1,1))

第五步:预测结果

在此步骤中,我们使用regressor.predict函数预测模型在训练集值上训练的测试集的结果,并将其分配给' y_pred'

y_pred = regressor.predict(X_test.reshape(-1,1))

步骤 6:将实际值与预测值进行比较

在这一步中,我们将在 Pandas 数据帧中比较并显示 y_test 的值为'真实值,y_pred 的值为'预测值

df = pd.DataFrame({'Real Values':y_test.reshape(-1), 'Predicted Values':y_pred.reshape(-1)})
df>>
Real Values    Predicted Values
448.325981     425.265596
535.866729     500.065779
264.123914     237.763911
691.855484     698.971806
587.221246     571.434257
653.986736     633.504009
538.179684     530.748225
643.944327     660.632289
771.789537     797.566536
644.488633     654.197406
192.341996     223.435016
491.430500     477.295054
781.983795     807.541287
432.819795     420.966453
623.598861     612.803770
599.364914     534.799028
856.303304     850.246982
583.084449     596.236690
521.775445     503.084268
228.901030     258.286810
453.785607     473.568112
406.516091     450.473207
562.792463     634.121978
642.349814     621.189730
737.800824     733.215828

从上述值,我们推断该模型能够以良好的准确度预测 y_test 的值。

步骤 7:可视化决策树回归结果

温度与收入(决策树回归)

在该图中,实际值用“ 、红色 ”绘制,预测值用“ 、绿色 ”绘制。决策树回归模型的绘图也是用 黑色 颜色绘制的。

我附上了我的 github 资源库的链接,你可以在那里找到 Google Colab 笔记本和数据文件供你参考。

[## MK-guru charan/回归

GitHub 是超过 5000 万开发人员的家园,他们一起工作来托管和审查代码、管理项目和构建…

github.com](https://github.com/mk-gurucharan/Regression)

我真的希望我已经用一个例子解释了构建决策树回归模型的 ML 代码。

您还可以在下面找到该程序对其他回归模型的解释:

在接下来的文章中,我们将会遇到更复杂的回归、分类和聚类模型。到那时,快乐的机器学习!

机器学习基础:K-最近邻分类

原文:https://towardsdatascience.com/machine-learning-basics-k-nearest-neighbors-classification-6c1e0b209542?source=collection_archive---------20-----------------------

了解 KNN 分类并在简单数据集上构建模型以可视化您的结果!

在之前的故事中,我已经解释了各种 回归 模型的实现程序。此外,我已经描述了逻辑回归模型的实现。在本文中,我们将看到 K-最近邻或 KNN 分类的算法以及一个简单的例子。

KNN 分类概述

K-最近邻或 KNN 分类是一种简单且易于实现的监督机器学习算法,主要用于分类问题。

让我们用一个非常简单的例子来理解这个算法。假设有两个类,分别用矩形和三角形表示。如果我们想给任何一个类添加一个新的形状(菱形),那么我们可以实现 KNN 分类模型。

KNN 模型(来源——自我)

在这个模型中,我们必须选择最近邻的数量(N)。这里,由于我们选择了 N=4,新的数据点将计算每个点之间的距离,并在其最近的 4 个邻居周围绘制一个圆形区域(N=4)。在这个问题中,由于所有四个最近的邻居都位于类 1(矩形)中,所以新的数据点(菱形)也被指定为类 1 数据点。

这样,我们可以用不同的值改变参数 N,并通过试错法为模型选择最精确的值,也避免了过拟合和高损失。

这样,我们就可以实现 KNN 分类算法。现在让我们在下一节中通过一个真实的例子来讨论它的实现。

问题分析

为了在实际应用中应用 KNN 分类模型,我使用了与构建逻辑回归模型相同的数据集。在这里,我们 DMV 测试数据集有三列。前两列由两个 DMV 书面测试( DMV_Test_1DMV_Test_2 )组成,这两列是自变量,最后一列由因变量 Results 组成,这两列表示驾驶员已获得驾照(1)或未获得驾照(0)。

在这种情况下,我们必须使用这些数据建立一个 KNN 分类模型,以预测参加了两次 DMV 笔试的司机是否会获得驾照,并使用他们在笔试中获得的分数对结果进行分类。

步骤 1:导入库

和往常一样,第一步总是包括导入库,即 NumPy、Pandas 和 Matplotlib。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

步骤 2:导入数据集

在这一步中,我们将从我的 GitHub 存储库中以“DMVWrittenTests.csv”的形式获取数据集。变量 X 将存储两个 DMV 测试 ,变量 Y 将最终输出存储为 结果dataset.head(5)用于可视化前 5 行数据。

dataset = pd.read_csv('[https://raw.githubusercontent.com/mk-gurucharan/Classification/master/DMVWrittenTests.csv'](https://raw.githubusercontent.com/mk-gurucharan/Classification/master/DMVWrittenTests.csv'))X = dataset.iloc[:, [0, 1]].values
y = dataset.iloc[:, 2].valuesdataset.head(5)>>
DMV_Test_1   DMV_Test_2   Results
34.623660    78.024693    0
30.286711    43.894998    0
35.847409    72.902198    0
60.182599    86.308552    1
79.032736    75.344376    1

步骤 3:将数据集分为训练集和测试集

在这一步中,我们必须将数据集分为训练集和测试集,在训练集上将训练逻辑回归模型,在测试集上将应用训练模型对结果进行分类。其中的test_size=0.25表示数据的 25%将作为 测试集 保存,剩余的 75%将作为 训练集 用于训练。**

**from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25)**

步骤 4:特征缩放

这是一个附加步骤,用于对特定范围内的数据进行标准化。它也有助于加速计算。由于数据变化很大,我们使用此函数将数据范围限制在一个小范围内(-2,2)。例如,分数 62.0730638 被规范化为-0.21231162,分数 96.51142588 被规范化为 1.55187648。这样 X_train 和 X_test 的分数就归一化到一个更小的范围。

**from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)**

步骤 5:在训练集上训练 KNN 分类模型

在这一步中,类KNeighborsClassifier被导入并分配给变量 【分类器】classifier.fit()功能配有 X_trainY_train 对模型进行训练。

**from sklearn.neighbors import KNeighborsClassifier
classifier = KNeighborsClassifier(n_neighbors = 5, metric = 'minkowski', p = 2)
classifier.fit(X_train, y_train)**

步骤 6:预测测试集结果

在这一步中,classifier.predict()函数用于预测测试集的值,这些值被存储到变量y_pred.

**y_pred = classifier.predict(X_test) 
y_pred**

步骤 7:混淆矩阵和准确性

这是分类技术中最常用的一步。在这里,我们看到了训练模型的准确性,并绘制了混淆矩阵。

混淆矩阵是一个表,用于显示当测试集的真实值已知时,对分类问题的正确和错误预测的数量。它的格式如下

来源—自己

真实值是正确预测的次数。

**from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)from sklearn.metrics import accuracy_score 
print ("Accuracy : ", accuracy_score(y_test, y_pred))
cm>>Accuracy :  0.92>>array([[11,  1],
       [ 1, 12]])**

从上面的混淆矩阵,我们推断,在 25 个测试集数据中,23 个被正确分类,2 个被错误分类,这比逻辑回归模型好不了多少。

步骤 8:将实际值与预测值进行比较

在这个步骤中,创建一个 Pandas DataFrame 来比较原始测试集( y_test )和预测结果( y_pred )的分类值。

**df = pd.DataFrame({'Real Values':y_test, 'Predicted Values':y_pred})
df>> 
Real Values   Predicted Values
0             0
0             1
1             1
0             0
0             0
1             1
1             1
0             0
0             0
1             1
0             0
1             0
1             1
1             1
0             0
0             0
0             0
1             1
1             1
1             1
1             1
0             0
1             1
1             1
0             0**

虽然这种可视化可能没有回归那么有用,但从这一点上,我们可以看到,该模型能够以 92%的相当高的准确度对测试集值进行分类,如上面计算的那样。

步骤 9:可视化结果

在最后一步中,我们将 KNN 分类模型的结果可视化在一个沿着两个区域绘制的图上。

**from matplotlib.colors import ListedColormap
X_set, y_set = X_test, y_test
X1, X2 = np.meshgrid(np.arange(start = X_set[:, 0].min() - 1, stop = X_set[:, 0].max() + 1, step = 0.01),
                     np.arange(start = X_set[:, 1].min() - 1, stop = X_set[:, 1].max() + 1, step = 0.01))
plt.contourf(X1, X2, classifier.predict(np.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape),
             alpha = 0.75, cmap = ListedColormap(('red', 'green')))
plt.xlim(X1.min(), X1.max())
plt.ylim(X2.min(), X2.max())
for i, j in enumerate(np.unique(y_set)):
    plt.scatter(X_set[y_set == j, 0], X_set[y_set == j, 1],
                c = ListedColormap(('red', 'green'))(i), label = j)
plt.title('KNN Classification')
plt.xlabel('DMV_Test_1')
plt.ylabel('DMV_Test_2')
plt.legend()
plt.show()**

KNN 分类

在该图中,值 1(即,是) 用“红色绘制,值 0(即,否) 用“绿色绘制。KNN 分类模型将这两个区域分开。它不像逻辑回归模型那样是线性的。因此,具有给定的两个数据点(DMV_Test_1 和 DMV_Test_2)的任何数据都可以绘制在图上,并且根据属于哪个区域,结果(获得驾驶执照)可以分类为是或否。**

根据上面的计算,我们可以看到测试集中有两个值,每个区域都有一个被错误分类的值。

结论—

因此,在这个故事中,我们已经成功地建立了一个 KNN 分类 模型,它能够预测一个人是否能够通过笔试获得驾驶执照,并可视化结果。

我还附上了我的 GitHub 资源库的链接,你可以在那里下载这个 Google Colab 笔记本和数据文件供你参考。

** [## MK-guru charan/分类

这是一个由 Python 代码组成的知识库,用于构建不同类型的分类模型,以评估和…

github.com](https://github.com/mk-gurucharan/Classification)

您还可以在下面找到该程序对其他分类模型的解释:

  • 逻辑回归
  • k 近邻(KNN)分类
  • 支持向量机(SVM)分类(即将推出)
  • 朴素贝叶斯分类(即将推出)
  • 随机森林分类(即将推出)

在接下来的文章中,我们将会遇到更复杂的回归、分类和聚类模型。到那时,快乐的机器学习!**

机器学习基础:逻辑回归

原文:https://towardsdatascience.com/machine-learning-basics-logistic-regression-890ef5e3a272?source=collection_archive---------16-----------------------

学习逻辑回归基本分类模型的算法及其实现

在之前的故事中,我已经解释了各种 回归 模型的实现程序。当我们继续讨论 分类 时,为什么这个算法的名称仍然是回归,这难道不令人惊讶吗?让我们了解逻辑回归的机制,并通过一个例子学习建立分类模型。

逻辑回归概述

逻辑回归是一种分类模型,在因变量(输出)为二进制格式时使用,如 0(假)或 1(真)。例子包括例如预测是否有肿瘤(1)或没有肿瘤(0)以及电子邮件是否是垃圾邮件(1)或没有垃圾邮件(0)。

逻辑函数,也称为 sigmoid 函数,最初由统计学家用来描述生态学中人口增长的特性。sigmoid 函数是一种数学函数,用于将预测值映射到概率。逻辑回归有一个 S 形曲线,可以取 0 到 1 之间的值,但永远不会精确到这些极限。它有1 / (1 + e^-value)的公式。

Sigmoid 函数(来源)

逻辑回归是线性回归模型的扩展。让我们用一个简单的例子来理解这一点。如果我们想要分类一封电子邮件是否是垃圾邮件,如果我们应用线性回归模型,我们将只得到 0 和 1 之间的连续值,如 0.4、0.7 等。另一方面,逻辑回归通过将阈值设置为 0.5 来扩展该线性回归模型,因此如果输出值大于 0.5,则数据点将被分类为垃圾邮件,如果输出值小于 0.5,则不是垃圾邮件。

这样就可以用逻辑回归对问题进行分类,得到准确的预测。

问题分析

为了在实际使用中应用逻辑回归模型,让我们考虑由三列组成的 DMV 测试数据集。前两列由两个 DMV 书面测试( DMV_Test_1DMV_Test_2 )组成,这两个测试是自变量,最后一列由因变量 结果 组成,这两个结果表示驾驶员已获得驾照(1)或未获得驾照(0)。

在这种情况下,我们必须使用这些数据建立一个逻辑回归模型,以预测参加了两次 DMV 笔试的司机是否会获得驾照,并使用他们在笔试中获得的分数对结果进行分类。

步骤 1:导入库

和往常一样,第一步总是包括导入库,即 NumPy、Pandas 和 Matplotlib。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

步骤 2:导入数据集

在这一步中,我们将从我的 GitHub 存储库中以“DMVWrittenTests.csv”的形式获取数据集。变量 X 将存储两个 DMV 测试 ,变量 Y 将最终输出存储为 结果dataset.head(5)用于可视化前 5 行数据。

dataset = pd.read_csv('[https://raw.githubusercontent.com/mk-gurucharan/Classification/master/DMVWrittenTests.csv'](https://raw.githubusercontent.com/mk-gurucharan/Classification/master/DMVWrittenTests.csv'))X = dataset.iloc[:, [0, 1]].values
y = dataset.iloc[:, 2].valuesdataset.head(5)>>
DMV_Test_1   DMV_Test_2   Results
34.623660    78.024693    0
30.286711    43.894998    0
35.847409    72.902198    0
60.182599    86.308552    1
79.032736    75.344376    1

步骤 3:将数据集分为训练集和测试集

在这一步中,我们必须将数据集分为训练集和测试集,在训练集上将训练逻辑回归模型,在测试集上将应用训练模型对结果进行分类。其中的test_size=0.25表示数据的 25%将作为 测试集 保存,剩余的 75%将作为 训练集 用于训练。**

**from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25, random_state = 0)**

步骤 4:特征缩放

这是一个附加步骤,用于对特定范围内的数据进行标准化。它也有助于加速计算。由于数据变化很大,我们使用此函数将数据范围限制在一个小范围内(-2,2)。例如,分数 62.0730638 被规范化为-0.21231162,分数 96.51142588 被规范化为 1.55187648。这样 X_train 和 X_test 的分数就归一化到一个更小的范围。

**from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)**

步骤 5:在训练集上训练逻辑回归模型

在这一步中,类LogisticRegression被导入并分配给变量 【分类器】classifier.fit()功能配有 X_trainY_train 对模型进行训练。

**from sklearn.linear_model import LogisticRegression
classifier = LogisticRegression()
classifier.fit(X_train, y_train)**

步骤 6:预测测试集结果

在这一步中,classifier.predict()函数用于预测测试集的值,这些值被存储到变量y_pred.

**y_pred = classifier.predict(X_test) 
y_pred**

步骤 7:混淆矩阵和准确性

这是分类技术中最常用的一步。在这里,我们看到了训练模型的准确性,并绘制了混淆矩阵。

混淆矩阵是一个表,用于显示当测试集的真实值已知时,对分类问题的正确和错误预测的数量。它的格式如下

来源—自己

真实值是正确预测的次数。

**from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)from sklearn.metrics import accuracy_score 
print ("Accuracy : ", accuracy_score(y_test, y_pred))
cm>>Accuracy :  0.88

>>array([[11,  0],
       [ 3, 11]])**

从上面的混淆矩阵,我们推断,在 25 个测试集数据中,22 个被正确分类,3 个被错误分类。很好的开始,不是吗?

步骤 8:将实际值与预测值进行比较

在这个步骤中,创建一个 Pandas DataFrame 来比较原始测试集( y_test )和预测结果( y_pred )的分类值。

**df = pd.DataFrame({'Real Values':y_test, 'Predicted Values':y_pred})
df>> 
Real Values   Predicted Values
1             1
0             0
0             0
0             0
1             1
1             1
1             0
1             1
0             0
1             1
0             0
0             0
0             0
1             1
1             0
1             1
0             0
1             1
1             0
1             1
0             0
0             0
1             1
1             1
0             0**

虽然这种可视化可能没有回归那么有用,但从这一点上,我们可以看到,该模型能够以 88%的正确率对测试集值进行分类,如上所述。

步骤 9:可视化结果

在最后一步中,我们将逻辑回归模型的结果可视化在一个图表上,该图表与两个区域一起绘制。

**from matplotlib.colors import ListedColormap
X_set, y_set = X_test, y_test
X1, X2 = np.meshgrid(np.arange(start = X_set[:, 0].min() - 1, stop = X_set[:, 0].max() + 1, step = 0.01),
                     np.arange(start = X_set[:, 1].min() - 1, stop = X_set[:, 1].max() + 1, step = 0.01))
plt.contourf(X1, X2, classifier.predict(np.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape),
             alpha = 0.75, cmap = ListedColormap(('red', 'green')))
plt.xlim(X1.min(), X1.max())
plt.ylim(X2.min(), X2.max())
for i, j in enumerate(np.unique(y_set)):
    plt.scatter(X_set[y_set == j, 0], X_set[y_set == j, 1],
                c = ListedColormap(('red', 'green'))(i), label = j)
plt.title('Logistic Regression')
plt.xlabel('DMV_Test_1')
plt.ylabel('DMV_Test_2')
plt.legend()
plt.show()**

逻辑回归

在该图中,值 1(即,是) 以“红色绘制,值 0(即,否) 以“绿色绘制。逻辑回归线将这两个区域分开。因此,具有给定的两个数据点(DMV_Test_1 和 DMV_Test_2)的任何数据都可以绘制在图上,并且根据属于哪个区域,结果(获得驾驶执照)可以分类为是或否。**

根据上面的计算,我们可以看到测试集中有三个值被错误地归类为“否”,因为它们位于线的另一端。

逻辑回归

结论—

因此,在这个故事中,我们已经成功地建立了一个 逻辑回归 模型,该模型能够预测一个人是否能够通过笔试获得驾驶执照,并可视化结果。

我还附上了我的 GitHub 资源库的链接,你可以在那里下载这个 Google Colab 笔记本和数据文件供你参考。

** [## MK-guru charan/分类

这是一个由 Python 代码组成的知识库,用于构建不同类型的分类模型,以评估和…

github.com](https://github.com/mk-gurucharan/Classification)

您还可以在下面找到该程序对其他分类模型的解释:

  • 逻辑回归
  • k-最近邻(KNN)分类(即将推出)
  • 支持向量机(SVM)分类(即将推出)
  • 朴素贝叶斯分类(即将推出)
  • 随机森林分类(即将推出)

在接下来的文章中,我们将会遇到更复杂的回归、分类和聚类模型。到那时,快乐的机器学习!**

机器学习基础:多元线性回归

原文:https://towardsdatascience.com/machine-learning-basics-multiple-linear-regression-9c70f796e5e3?source=collection_archive---------14-----------------------

学习用 Python 编程实现多元线性回归。

在前面的故事中,我简要介绍了线性回归,并展示了如何执行简单的线性回归。在简单线性回归中,我们有一个因变量(y)和一个自变量(x)。如果学生的分数取决于两个或更多的独立变量会怎样?

概观

在这个例子中,我们将经历 多元线性回归 的实现,其中我们将为一个想要分析一个初创公司是否值得投资以获得良好回报的风险投资家预测初创公司的利润。

线性回归(来源)

问题分析

在这个数据中,我们有四个自变量,即, R & D 支出,行政管理,营销支出状态。有一个自变量,即利润。因此,我们的工作是用这些数据训练 ML 模型,以了解四个特征(或独立变量)之间的相关性,并使用所有这些数据预测另一家新公司的利润。

步骤 1:导入库

在第一步中,我们将导入构建 ML 模型所需的库。导入 NumPy 库和 matplotlib 。另外,我们导入了 熊猫 库进行数据分析。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

步骤 2:导入数据集

在下一步中,我们将使用 pandas 来存储从我的 github 存储库中获得的数据,并使用函数" pd.read_csv "将其存储为名为" dataset "的 Pandas DataFrame。

我们浏览我们的数据集,并将自变量(x)分配给数据集的前四列,即 R&D 支出(指数=0)、行政管理(指数=1)、营销支出(指数=2)和州(指数=3)。

dataset = pd.read_csv('[https://raw.githubusercontent.com/mk-gurucharan/Regression/master/Startups_Data.csv'](https://raw.githubusercontent.com/mk-gurucharan/Regression/master/Startups_Data.csv'))X = dataset.iloc[:, :-1].values
y = dataset.iloc[:, -1].valuesdataset.head(5)>>
R&D Spend  Administration  Marketing Spend   State      Profit
165349.20  136897.80       471784.10         New York   192261.83
162597.70  151377.59       443898.53         California 191792.06
153441.51  101145.55       407934.54         Florida    191050.39
144372.41  118671.85       383199.62         New York   182901.99
142107.34  91391.77        366168.42         Florida    166187.94

我们使用相应的。iloc 函数对数据帧进行切片,将这些索引赋给 x,这里我们使用 [:,:-1] ,可以解释为【包含所有行,包含所有列直到-1(不含-1)】。在这里,-1 表示倒数第一列。因此,我们将第 0、1、2 和 3 列指定为 x。

我们将最后一列(-1)分配给因变量 y。我们打印数据帧以查看我们是否为训练数据获得了正确的列。

步骤 3:编码分类数据

只要数据集中有数字,我们就可以轻松地对数据集进行数学计算,并创建预测模型。在这个数据集中,我们遇到了一个非数字变量,即“ 、状态 ”。这也称为分类数据。

我们使用另一个叫做 sklearn 的重要库对这些分类数据进行编码。在这里,我们导入了 ColumnTransformerOneHotEncoder 。ColumnTransformer 允许单独转换数据帧的特定列。在我们的例子中,我们使用 OneHotEncoder 将“State”列(index=3)转换为数字数据。

在对分类数据进行编码后,我们打印数据帧 X 并查看变化。我们看到在开始时增加了三个新栏目。每一列代表一个“状态”。例如,在第一行中,第三列表示“纽约”,因此第三列中的值为“1”。

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
ct = ColumnTransformer(transformers=[('encoder', OneHotEncoder(), [3])], remainder='passthrough')
X = np.array(ct.fit_transform(X))

步骤 4:将数据集分为训练集和测试集

一旦我们准备好了数据集,下一个重要的任务就是将数据集分成训练集和测试集。我们这样做是为了用称为“训练集的一部分数据训练我们的模型,并在称为“测试集的另一组数据上测试预测结果。

我们使用“train_test_split”函数来拆分我们的数据。这里我们给出“test_size =0.2”,表示 20%的数据是测试集。在我们的例子中,将选择 10 个随机启动数据作为测试集,并将选择 40 个剩余的启动数据作为训练集。

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2)

步骤 5:在训练集上训练多元线性回归模型

下一步,我们导入" LinearRegression "类,它将应用于我们的训练集。我们给 LinearRegression 类分配一个变量“回归变量”。然后,我们使用“ regressor.fit ”将训练数据集(X_train 和 y_train)拟合到这个线性回归类,以便进行训练过程。

from sklearn.linear_model import LinearRegression
regressor = LinearRegression()
regressor.fit(X_train, y_train)

步骤 6:预测测试集结果

下一步,我们将使用训练好的模型(即“回归器”)来预测测试集的利润。测试集数据(X_test)的真实值(利润)存储在变量 y_test 中。

然后,我们使用“ regressor.predict ”函数来预测测试数据 X_test 的值。我们将预测值指定为 y_pred。我们现在有两个数据,y_test(真实值)和 y_pred(预测值)。

y_pred = regressor.predict(X_test)

步骤 7:将测试集与预测值进行比较

在这一步中,我们将把 y_test 的值打印为 Pandas DataFrame 中每个 X_test 的实际值和 y_pred 值打印为 预测值 。这样,我们获得了所有 10 个 X_test 数据的值。

*df = pd.DataFrame({'Real Values':y_test, 'Predicted Values':y_pred})
df>>
Real Values Predicted Values
78239.91    74963.602167
182901.99   173144.548525
64926.08    45804.248438
105733.54   108530.843936
141585.52   127674.466487
108552.04   111471.421444
146121.95   133618.038644
105008.31   114655.651664
96778.92    96466.443219
97483.56    96007.236281*

在第一行中,实际值的值为 78239.91 ,预测值的值为 74963.60 。我们看到该模型已经精确地预测了该值,因此我们可以说我们的模型具有良好的准确性。

恭喜你!现在,您已经从构建简单的线性回归模型扩展到多元线性回归模型。我附上了我的 Github 资源库的链接,你可以在那里找到 Python 笔记本和数据文件供你参考。

* [## MK-guru charan/回归

GitHub 是超过 5000 万开发人员的家园,他们一起工作来托管和审查代码、管理项目和构建…

github.com](https://github.com/mk-gurucharan/Regression)

希望我已经清楚地解释了开发多元线性回归的 ML 模型的过程,以便用相关数据预测一家初创公司的利润。

您还可以在下面找到该程序对其他回归模型的解释:

在接下来的文章中,我们将会遇到更复杂的回归、分类和聚类模型。到那时,快乐的机器学习!*

机器学习基础:朴素贝叶斯分类

原文:https://towardsdatascience.com/machine-learning-basics-naive-bayes-classification-964af6f2a965?source=collection_archive---------8-----------------------

了解朴素贝叶斯算法,并通过实现朴素贝叶斯分类模型来解决一个著名的虹膜数据集问题

在之前的故事中,我已经解释了各种 回归 模型的实现程序。此外,我还描述了逻辑回归,KNN 和 SVM 分类模型的实施。在本文中,我们将通过一个例子来介绍著名的朴素贝叶斯分类模型的算法。

朴素贝叶斯分类综述

朴素贝叶斯就是这样一种分类算法,由于其“”的特性,在分类中是一个不容忽视的算法。它假设测量的特征是相互独立的。

例如,如果一种动物有猫眼、胡须和一条长尾巴,它就可以被认为是猫。即使这些特征相互依赖或依赖于其他特征的存在,所有这些特性独立地促成了这种动物是猫的可能性,这就是为什么它被称为“天真”。

根据贝叶斯定理,各种特征是相互独立的。对于两个独立的事件,P(A,B) = P(A)P(B)。贝叶斯定理的这个假设可能在实践中从未遇到过,因此它解释了朴素贝叶斯中的“朴素”部分。贝叶斯定理表述为:P(a | b)=(P(b | a) P(a))/P(b)。** 其中 P(a|b)是给定 b 的概率。*

让我们用一个简单的例子来理解这个算法。如果这个学生在考试那天穿红色的衣服,他就会通过考试。我们可以使用上面讨论的后验概率方法来解决它。

由贝叶斯定理, P(通|红)= P(红|通) P(通)/ P(红)。*

从数值来看,我们假设 P(红|通)= 3/9 = 0.33,P(红)= 5/14 = 0.36,P(通)= 9/14 = 0.64。现在 P(通|红)= 0.33 * 0.64 / 0.36 = 0.60,概率较高。

这样,朴素贝叶斯使用类似的方法来预测基于各种属性的不同类的概率。

问题分析

为了实现朴素贝叶斯分类,我们将使用一个非常著名的鸢尾花数据集,它由 3 类花组成。其中有 4 个自变量,分别是:萼片宽度花瓣长度花瓣宽度 。因变量是 物种 ,我们将利用花的四个独立特征对其进行预测。**

安妮·斯普拉特在 Unsplash 上的照片

有 3 类物种,即刚毛藻、云芝和海滨锦葵。这个数据集最初是由罗纳德·费雪在 1936 年提出的。使用花的各种特征(独立变量),我们必须使用朴素贝叶斯分类模型对给定的花进行分类。

步骤 1:导入库

和往常一样,第一步总是包括导入库,即 NumPy、Pandas 和 Matplotlib。

**import numpy as np
import matplotlib.pyplot as plt
import pandas as pd**

步骤 2:导入数据集

在这一步中,我们将导入 Iris Flower 数据集,该数据集作为IrisDataset.csv存储在我的 github 存储库中,并将其保存到变量dataset. 中。此后,我们将 4 个自变量分配给X,将因变量“物种”分配给 Y 。显示数据集的前 5 行。

**dataset = pd.read_csv('[https://raw.githubusercontent.com/mk-gurucharan/Classification/master/IrisDataset.csv'](https://raw.githubusercontent.com/mk-gurucharan/Classification/master/IrisDataset.csv'))X = dataset.iloc[:,:4].values
y = dataset['species'].valuesdataset.head(5)>>
sepal_length  sepal_width  petal_length  petal_width   species
5.1           3.5          1.4           0.2           setosa
4.9           3.0          1.4           0.2           setosa
4.7           3.2          1.3           0.2           setosa
4.6           3.1          1.5           0.2           setosa
5.0           3.6          1.4           0.2           setosa**

步骤 3:将数据集分为训练集和测试集

一旦我们获得了数据集,我们必须将数据分成训练集和测试集。在这个数据集中,有 150 行,3 个类中的每一个都有 50 行。由于每个类都是以连续的顺序给出的,所以我们需要随机分割数据集。这里,我们有test_size=0.2,这意味着数据集的的 20%将用于测试目的,剩余的的 80%将用于训练朴素贝叶斯分类模型。****

***from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2)***

步骤 4:特征缩放

使用要素缩放选项将数据集缩小到更小的范围。在这种情况下,X_trainX_test 值都被缩小到更小的值,以提高程序的速度。

***from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)***

步骤 5:在训练集上训练朴素贝叶斯分类模型

在这一步,我们引入从sklearn.naive_bayes库中使用的类GaussianNB。这里,我们使用了高斯模型,还有其他几种模型,如伯努利模型、分类模型和多项式模型。这里,我们将 GaussianNB 类分配给变量classifier,并为其拟合 X_train 和 y_train 值,用于训练目的。

***from sklearn.naive_bayes import GaussianNB
classifier = GaussianNB()
classifier.fit(X_train, y_train)***

步骤 6:预测测试集结果

一旦模型被训练,我们使用classifier.predict()来预测测试集的值,并且预测的值被存储到变量y_pred.

***y_pred = classifier.predict(X_test) 
y_pred***

步骤 7:混淆矩阵和准确性

这是分类技术中最常用的一步。在这里,我们看到了训练模型的准确性,并绘制了混淆矩阵。

混淆矩阵是一个表,用于显示当测试集的真实值已知时,对分类问题的正确和错误预测的数量。它的格式如下

作者图片

真实值是正确预测的次数。

***from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)from sklearn.metrics import accuracy_score 
print ("Accuracy : ", accuracy_score(y_test, y_pred))
cm>>Accuracy :  0.9666666666666667>>array([[14,  0,  0],
       [ 0,  7,  0],
       [ 0,  1,  8]])***

从上面的混淆矩阵,我们推断,在 30 个测试集数据中,29 个被正确分类,只有 1 个被错误分类。这给了我们 96.67%的高准确率。

步骤 8:将实际值与预测值进行比较

在这个步骤中,创建一个 Pandas DataFrame 来比较原始测试集( y_test )和预测结果( y_pred )的分类值。

**df = pd.DataFrame({'Real Values':y_test, 'Predicted Values':y_pred})
df>> 
Real Values   Predicted Values
setosa        setosa
setosa        setosa
virginica     virginica
versicolor    versicolor
setosa        setosa
setosa        setosa
...  ...   ...  ...  ...
virginica     versicolor
virginica     virginica
setosa        setosa
setosa        setosa
versicolor    versicolor
versicolor    versicolor**

这个步骤是一个额外的步骤,它不像混淆矩阵那样提供很多信息,并且主要用于回归以检查预测值的准确性。

如你所见,有一个错误的预测是预测了云芝而不是弗吉尼亚

结论—

因此,在这个故事中,我们已经成功地建立了一个 朴素贝叶斯分类 模型,该模型能够根据 4 个特征对一朵花进行分类。这个模型可以用网上的其他几个分类数据集来实现和测试。

我还附上了我的 GitHub 资源库的链接,你可以在那里下载这个 Google Colab 笔记本和数据文件供你参考。

** [## MK-guru charan/分类

这是一个由 Python 代码组成的知识库,用于构建不同类型的分类模型,以评估和…

github.com](https://github.com/mk-gurucharan/Classification)

您还可以在下面找到该程序对其他分类模型的解释:

在接下来的文章中,我们将会遇到更复杂的回归、分类和聚类模型。到那时,快乐的机器学习!**

机器学习基础:多项式回归

原文:https://towardsdatascience.com/machine-learning-basics-polynomial-regression-3f9dd30223d1?source=collection_archive---------12-----------------------

了解如何构建多项式回归模型来预测非线性数据集的值。

在以前的故事中,我简要介绍了线性回归,并展示了如何执行简单和多元线性回归。在本文中,我们将通过程序来建立一个基于非线性数据的多项式回归模型。

概观

在前面的线性回归示例中,当数据绘制在图表上时,因变量和自变量之间存在线性关系。因此,更适合建立线性模型来获得准确的预测。如果数据点具有以下非线性,使得线性模型由于非线性而在预测中产生错误,会怎么样?

非线性数据点(来源

在这种情况下,我们必须建立一个多项式关系,它将精确地拟合给定图中的数据点。这被称为多项式回归。多项式回归曲线的公式如y=w1x+w2x²+..+b所示

以下是对非线性数据拟合线性回归模型和多项式回归模型的 gif。

左:线性回归,右:多项式回归(来源

正如我们所看到的,线性回归总是会出错,无论它如何努力去适应数据。另一方面,多项式回归图能够更准确地将数据点拟合到直线上。

在本例中,我们将完成 多项式回归 的实现,其中我们将根据新员工在以前公司的职位级别,从新公司相同职位级别的工资数据中预测其工资。

问题分析

在该数据中,我们有两个独立变量,即位置和水平。有一个自变量,即工资。因此,在这个问题中,我们必须使用该数据训练一个多项式回归模型,以了解公司中员工数据的级别和工资之间的相关性,并能够根据该数据预测新员工的工资。

步骤 1:导入库

在第一步中,我们将导入构建 ML 模型所需的库。导入 NumPy 库和 matplotlib 。另外,我们导入了 熊猫 库进行数据分析。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

步骤 2:导入数据集

在这一步中,我们将使用 pandas 来存储从我的 github 存储库中获得的数据,并使用函数" pd.read_csv "将其存储为 Pandas DataFrame。

我们遍历数据集,将自变量(x)赋给列名为“”的第二列,将因变量(y)赋给最后一列,即要预测的“”工资。**

**dataset = pd.read_csv('[https://raw.githubusercontent.com/mk-gurucharan/Regression/master/PositionSalaries_Data.csv'](https://raw.githubusercontent.com/mk-gurucharan/Regression/master/PositionSalaries_Data.csv'))X = dataset.iloc[:, 1:-1].values
y = dataset.iloc[:, -1].valuesdataset.head(5)>>

Position           Level   Salary
Business Analyst   1       45000
Junior Consultant  2       50000
Senior Consultant  3       60000
Manager            4       80000
Country Manager    5       110000**

我们使用相应的。iloc 函数对数据帧进行切片,以将这些指数分配给 X 和 y。在这种情况下,级别被视为独立变量,并被分配给 X。要预测的因变量是最后一列(-1),即薪金,它被分配给 y。我们打印 DataFrame " 数据集,以查看我们是否为训练数据获得了正确的列。

步骤 3:在整个数据集上训练多项式回归模型

我们使用的数据集只有很少的行数,因此我们训练整个数据集来构建多项式回归模型。在此" 多项式特性 "功能用于指定我们将要绘制的多项式线的次数。在此,度数被设定为 4

独立变量 X 随后被多项式特征类拟合,并被转换为新变量 X_poly 。在这种情况下,变量 X 被转换成新的矩阵 X_Poly,该矩阵包括所有次数=4 的特征的多项式组合。

**from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
poly_reg = PolynomialFeatures(degree = 4)
X_poly = poly_reg.fit_transform(X)
lin_reg = LinearRegression()
lin_reg.fit(X_poly, y)**

类"【linear regression】也被导入并赋给变量【Lin _ reg】,该变量与 X_poly 和 y 相匹配,用于构建模型。

第四步:预测结果

在这一步中,我们将根据构建的多项式回归模型来预测值 Salary。“ regressor.predict ”函数用于预测自变量 X_poly 的值。我们将预测值指定为 y_pred。我们现在有两个数据,y(真实值)和 y_pred(预测值)。

**y_pred = lin_reg.predict(X_poly)**

步骤 5:将实际值与预测值进行比较

在这一步中,我们将把 y 值打印为 Pandas DataFrame 中每个 X_test 的 实际值 和 y_pred 值作为 预测值

**df = pd.DataFrame({'Real Values':y, 'Predicted Values':y_pred})
df>>
Real Values  Predicted Values
45000        53356.643357
50000        31759.906760
60000        58642.191142
80000        94632.867133
110000       121724.941725
150000       143275.058275
200000       184003.496504
300000       289994.172494
500000       528694.638695
1000000      988916.083916**

我们可以看到,该模型在拟合数据和根据职位级别预测员工工资方面做得非常好。

步骤 6: 可视化多项式回归结果

在最后一步中,我们将可视化使用给定数据构建的多项式模型,并在图上绘制“【y”和“ y_pred ”的值,并分析结果

**X_grid = np.arange(min(X), max(X), 0.1)
X_grid = X_grid.reshape((len(X_grid), 1))
plt.scatter(X, y, color = 'red')
plt.scatter(X, y_pred, color = 'green')
plt.plot(X_grid, lin_reg.predict(poly_reg.fit_transform(X_grid)), color = 'black')
plt.title('Polynomial Regression')
plt.xlabel('Position level')
plt.ylabel('Salary')
plt.show()**

多项式回归模型

在该图中,实际值用“ 红色 绘制,预测值用“ 绿色 绘制。生成的多项式回归线以“ 黑色 ”颜色绘制。

我附上了我的 github 资源库的链接,你可以在那里找到 Google Colab 笔记本和数据文件供你参考。

** [## MK-guru charan/回归

GitHub 是超过 5000 万开发人员的家园,他们一起工作来托管和审查代码、管理项目和构建…

github.com](https://github.com/mk-gurucharan/Regression)

希望我已经能够清楚地解释建立多项式回归模型的程序。

您还可以在下面找到该程序对其他回归模型的解释:

在接下来的文章中,我们将会遇到更复杂的回归、分类和聚类模型。到那时,快乐的机器学习!**

机器学习基础:随机森林分类

原文:https://towardsdatascience.com/machine-learning-basics-random-forest-classification-499279bac51e?source=collection_archive---------19-----------------------

对数据集执行随机森林算法并可视化结果!

随机森林分类综述

随机森林也是一种基于“树”的算法,它使用多个决策树的质量特征来做出决策。因此,它可以被称为一个‘森林’的树木,因此得名“随机森林”。术语“随机是因为这个算法是一个‘随机生成的决策树’的森林。

随机森林算法是对现有决策树算法的改进,现有决策树算法存在一个主要问题“过拟合”。与决策树算法相比,它被认为更快更准确。

随机森林算法(来源)

它结合了多个决策树的结果,并根据结果对输出进行分类。让我们用这个算法实际求解一个数据集。

问题分析

在这个随机森林分类模型的实现中,我们将使用一个社交网络广告数据集,我已经在构建 SVM 分类器时使用过它。它由三列组成。前两列是自变量,即' 【年龄】' 和' 【估计销量】 ,最后一列是因变量' 【购买量】' ,以二进制格式表示个人是否购买了产品(1)或(0)。

使用这些数据,我们必须为一家产品公司建立一个分类器,该分类器将对特定年龄和特定薪水的人是否会购买他们在社交媒体平台上做广告的产品进行分类。

步骤 1:导入库

和往常一样,第一步总是包括导入库,即 NumPy、Pandas 和 Matplotlib。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

步骤 2:导入数据集

在这一步中,我们将从我的 github 存储库中获取存储为SocialNetworkAds.csv 的数据集,并将其存储到变量 dataset 中。然后我们将相应的变量赋给 X 和 y。最后,我们将看到数据集的前 5 行。

dataset = pd.read_csv('[https://raw.githubusercontent.com/mk-gurucharan/Classification/master/SocialNetworkAds.csv'](https://raw.githubusercontent.com/mk-gurucharan/Classification/master/SocialNetworkAds.csv'))X = dataset.iloc[:, [0, 1]].values
y = dataset.iloc[:, 2].valuesdataset.head(5)>>
Age   EstimatedSalary   Purchased
19    19000             0
35    20000             0
26    43000             0
27    57000             0
19    76000             0

步骤 3:将数据集分为训练集和测试集

我们将把数据分成训练集和测试集。在此,我们保留了test_size=0.20。表示 数据的 20% 将作为 测试集 保留,剩余的80%训练集* 用于训练。由于有 400 行,大约 80 个数据点将被分配给测试集,剩余的 320 个数据点将用于训练目的。*

*from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2)*

步骤 4:特征缩放

这是一个额外的步骤,当我们把 X 的值缩小到一个更小的范围时,它将提高程序的速度。在这里,我们将X_trainX_test缩小到-2 到+2 的小范围。例如,工资 75000 按比例缩减为 0.16418997。

*from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)*

步骤 5:在训练集上训练随机森林分类模型

一旦训练测试准备好了,我们就可以导入RandomForestClassifier 类并使训练集适合我们的模型。类别SVC被分配给变量分类器。这里用的判据是“”。也可以使用的另一个标准是" 基尼 "。然后使用classifier.fit() 函数来训练模型。**

**from sklearn.ensemble import RandomForestClassifier
classifier = RandomForestClassifier(n_estimators = 10, criterion = 'entropy')
classifier.fit(X_train, y_train)**

步骤 6:预测测试集结果

在这一步中,classifier.predict()函数用于预测测试集的值,这些值被存储到变量y_pred.

**y_pred = classifier.predict(X_test) 
y_pred**

步骤 7:混淆矩阵和准确性

这是分类技术中最常用的一步。在这里,我们看到了训练模型的准确性,并绘制了混淆矩阵。

混淆矩阵是一个表,用于显示当测试集的真实值已知时,对分类问题的正确和错误预测的数量。它的格式如下

来源—自己

真实值是正确预测的次数。

**from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)from sklearn.metrics import accuracy_score 
print ("Accuracy : ", accuracy_score(y_test, y_pred))
cm>>Accuracy :  0.9625

>>array([[55,  3],
       [ 0, 22]])**

从上面的混淆矩阵,我们推断,在 80 个测试集数据中,77 个被正确分类,只有 3 个被错误分类,留给我们 96.25%的准确率。

步骤 8:将实际值与预测值进行比较

在这个步骤中,创建一个 Pandas DataFrame 来比较原始测试集( y_test )和预测结果( y_pred )的分类值。

**df = pd.DataFrame({'Real Values':y_test, 'Predicted Values':y_pred})
df>> 
Real Values   Predicted Values
1             1
1             1
0             0
0             0
0             0
... ...  ... ...
1             1
0             1
0             0
0             0
1             1**

这个步骤是一个额外的步骤,它不像混淆矩阵那样提供很多信息,并且主要用于回归以检查预测值的准确性。试着找出错误预测的值!

步骤 9:可视化结果

在最后一步中,我们将随机森林分类模型的结果可视化在一个图表上,该图表与两个区域一起绘制。

**from matplotlib.colors import ListedColormap
X_set, y_set = X_test, y_test
X1, X2 = np.meshgrid(np.arange(start = X_set[:, 0].min() - 1, stop = X_set[:, 0].max() + 1, step = 0.01),
                     np.arange(start = X_set[:, 1].min() - 1, stop = X_set[:, 1].max() + 1, step = 0.01))
plt.contourf(X1, X2, classifier.predict(np.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape),
             alpha = 0.75, cmap = ListedColormap(('red', 'green')))
plt.xlim(X1.min(), X1.max())
plt.ylim(X2.min(), X2.max())
for i, j in enumerate(np.unique(y_set)):
    plt.scatter(X_set[y_set == j, 0], X_set[y_set == j, 1],
                c = ListedColormap(('red', 'green'))(i), label = j)
plt.title('SVM Classification')
plt.xlabel('Age')
plt.ylabel('EstimatedSalary')
plt.legend()
plt.show()**

随机森林分类

在这个图中,有两个区域。 红色 区域表示 0 ,由未购买该产品的人组成, 绿色 区域表示 1 ,由已购买该产品的人组成。

如果您仔细观察,我们可以看到测试集中红色的 3 个错误分类的数据点,在特定区域有颜色差异。

结论—

因此,在这个故事中,我们已经成功地构建了一个 随机森林分类 模型,该模型能够根据一个人的年龄和工资来预测他是否会购买一件产品。请随意尝试网上其他各种常见的分类数据集。

我还附上了我的 github 资源库的链接,你可以在那里下载这个 Google Colab 笔记本和数据文件供你参考。

** [## MK-guru charan/分类

这是一个由 Python 代码组成的知识库,用于构建不同类型的分类模型,以评估和…

github.com](https://github.com/mk-gurucharan/Classification)

您还可以在下面找到该程序对其他分类模型的解释:

在接下来的文章中,我们将会遇到更复杂的回归、分类和聚类模型。到那时,快乐的机器学习!**

机器学习基础:随机森林回归

原文:https://towardsdatascience.com/machine-learning-basics-random-forest-regression-be3e1e3bb91a?source=collection_archive---------4-----------------------

学习用 Python 构建机器学习中的随机森林回归模型

之前,我已经解释了各种回归模型,如线性、多项式、支持向量和决策树回归。在本文中,我们将浏览随机森林回归应用程序的代码,它是对之前实现的 决策树回归 的扩展。

随机森林算法综述

决策树是一种易于理解和解释的算法,因此单个树可能不足以让模型从中学习特征。另一方面,随机森林也是一种基于“树”的算法,它使用多个决策树的质量特征来进行决策。

因此,它可以被称为一个【森林】的树木,因此得名“随机森林”。术语' Random 是因为这个算法是一个 '随机创建的决策树' 的森林。

决策树算法的一个主要缺点是它会导致过拟合。这个问题可以通过用随机森林回归代替决策树回归来解决。此外,与其他回归模型相比,随机森林算法也非常快速稳健

随机森林算法(来源)

简而言之,随机森林算法合并多个决策树的输出,以生成最终输出。

问题分析

用于 决策树回归 的相同数据集在此使用,我们有一个独立变量温度和一个独立变量收入,我们必须预测。在这个问题中,我们必须建立一个随机森林回归模型,该模型将研究冰淇淋店的温度和收入之间的相关性,并根据特定日期的温度预测冰淇淋店的收入。

步骤 1:导入库

照常导入NumPymatplotlib熊猫库

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

步骤 2:导入数据集

使用函数' pd.read_csv '从我的 github 存储库中导入数据集。在此,我们将自变量(X)分配给'温度'列,将因变量(y)分配给'收入'列。

dataset = pd.read_csv('[https://raw.githubusercontent.com/mk-gurucharan/Regression/master/IceCreamData.csv'](https://raw.githubusercontent.com/mk-gurucharan/Regression/master/IceCreamData.csv'))X = dataset['Temperature'].values
y = dataset['Revenue'].valuesdataset.head(5)>>Temperature   Revenue
24.566884     534.799028
26.005191     625.190122
27.790554     660.632289
20.595335     487.706960
11.503498     316.240194

步骤 3:将数据集分为训练集和测试集

类似于决策树回归模型,我们将拆分数据集,我们使用test_size=0.05,这意味着 500 个数据行( 25 行)中的 5%将仅用作测试集,剩余的 475 行将用作训练集,用于构建随机森林回归模型。

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.05)

步骤 4:在训练集上训练随机森林回归模型

在这一步中,为了训练模型,我们导入了RandomForestRegressor类,并将其赋给了变量regressor。然后,我们使用.fit()函数,通过相应地调整回归变量来拟合 X_train 和 y_train 值。

# Fitting Random Forest Regression to the dataset
from sklearn.ensemble import RandomForestRegressor
regressor = RandomForestRegressor(n_estimators = 10, random_state = 0)
regressor.fit(X_train.reshape(-1,1), y_train.reshape(-1,1))

第五步:预测结果

在这一步中,我们使用regressor.predict函数预测模型在训练集值上训练的测试集的结果,并将其分配给' y_pred'

y_pred = regressor.predict(X_test.reshape(-1,1))

步骤 6:将实际值与预测值进行比较

在这一步中,我们将在 Pandas 数据帧中比较并显示 y_test 的值为'真实值,y_pred 的值为'预测值

df = pd.DataFrame({'Real Values':y_test.reshape(-1), 'Predicted Values':y_pred.reshape(-1)})
df>>
Real Values    Predicted Values
534.622865     510.602018
542.608070     558.764770
618.457277     653.356430
460.402500     449.302331
759.377432     728.037404
631.318237     649.712332
572.672047     583.685756
494.627437     503.075097
250.131728     239.372956
594.651009     635.653662
383.956240     384.531416
491.230603     503.075097
875.019348     933.984685
273.073342     224.659296
500.925064     498.355934
191.623312     193.223331
691.516541     726.817925
421.621505     420.997198
636.298374     653.945550
321.848273     276.772845
283.679657     275.805778
608.936345     589.542982
212.591740     239.372956
594.804871     541.164031
500.065779     524.649546

从上述值,我们推断该模型能够以良好的准确度预测 y_test 的值,尽管它可以通过调整超参数如n_estimatorsmax_depth来改进。我把这些参数交给你们来处理,以提高随机森林回归模型的准确性。

步骤 7:可视化随机森林回归结果

温度与收入(随机森林回归)

在该图中,实际值用" 、红色 "绘制,预测值用" 、绿色 "绘制。决策树回归模型的绘图也是用 黑色 颜色绘制的。

随机森林回归

我附上了我的 github 资源库的链接,你可以在那里找到 Google Colab 笔记本和数据文件供你参考。

[## MK-guru charan/回归

GitHub 是超过 5000 万开发人员的家园,他们一起工作来托管和审查代码、管理项目和构建…

github.com](https://github.com/mk-gurucharan/Regression)

我真的希望我已经用一个例子解释了构建决策树回归模型的 ML 代码。

您还可以在下面找到该程序对其他回归模型的解释:

在接下来的文章中,我们将会遇到更复杂的回归、分类和聚类模型。到那时,快乐的机器学习!

机器学习基础:简单线性回归

原文:https://towardsdatascience.com/machine-learning-basics-simple-linear-regression-bc83c01baa07?source=collection_archive---------16-----------------------

学习简单线性回归的基本机器学习程序。

在数据科学编程的最初几天,人们可能会遇到术语“回归”。在这个故事中,我想用一个常见的例子来解释非常基本的“”的程序代码。

概述—

在统计学中, 线性回归 是一种对标量响应(或因变量)与一个或多个解释变量(或自变量)之间的关系进行建模的线性方法。在我们的例子中,我们将经历简单的线性回归。

简单线性回归的形式为y = wx + b,其中 y 为因变量, x 为自变量, wb 为训练参数,在训练过程中需要对其进行优化,以获得准确的预测。

现在让我们应用机器学习来训练一个数据集,根据年的经验来预测 工资 。**

步骤 1:导入库

在第一步中,我们将导入 pandas 库,该库将用于存储 pandas 数据帧中的数据。 matplotlib 用于绘制图形。

**import numpy as np
import matplotlib.pyplot as plt
import pandas as pd**

步骤 2:导入数据集

在这一步中,我们将从我的 github 存储库中下载数据集,其中包含的数据为“Salary_Data.csv”。变量 X 会存储“ 年资 ”,变量会存储“ 工资dataset.head(5)用于可视化前 5 行数据。

**dataset = pd.read_csv('https://raw.githubusercontent.com/mk-gurucharan/Regression/master/Salary_Data.csv')X = dataset.iloc[:, :-1].values
y = dataset.iloc[:, -1].valuesdataset.head(5)>>
YearsExperience Salary
1.1             39343.0
1.3             46205.0
1.5             37731.0
2.0             43525.0
2.2             39891.0**

步骤 3:将数据集分为训练集和测试集

在这一步中,我们必须将数据集分为训练集和测试集,前者将训练线性回归模型,后者将应用训练好的模型来可视化结果。在此,test_size=0.2表示数据的 20%将作为*** 测试集保存,剩余的的 80%将作为* 训练集用于训练。****

**from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2)**

步骤 4:在训练集上训练简单线性回归模型

第四步,导入类LinearRegression,并将其赋给变量 “回归量”regressor.fit()功能配有 X_trainY_train ,模型将在其上进行训练。

**from sklearn.linear_model import LinearRegression
regressor = LinearRegression()
regressor.fit(X_train, y_train)**

步骤 5:预测测试集结果

在这一步中,regressor.predict()函数用于预测测试集的值,这些值被存储到变量y_pred.

**y_pred = regressor.predict(X_test)**

步骤 6:将测试集与预测值进行比较

在这个步骤中,创建一个 Pandas DataFrame 来比较原始测试集( y_test )和预测结果( y_pred )的工资值。

**df = pd.DataFrame({'Real Values':y_test, 'Predicted Values':y_pred})
df>> 
Real Values    Predicted Values
109431.0       107621.917107
81363.0        81508.217112
93940.0        82440.849255
55794.0        63788.206401
66029.0        74047.159970
91738.0        89901.906396**

我们可以看到,预测的工资非常接近实际工资值,可以得出结论,该模型已经过良好的训练。

第七步:可视化结果

在最后一步中,我们将 实际预测 工资值的结果以及绘制的图表上的线性回归线可视化。

**plt.scatter(X_test, y_test, color = 'red')
plt.scatter(X_test, y_pred, color = 'green')
plt.plot(X_train, regressor.predict(X_train), color = 'black')
plt.title('Salary vs Experience (Result)')
plt.xlabel('YearsExperience')
plt.ylabel('Salary')
plt.show()**

薪水与经验

在该图中,实际值用“ 红色 绘制,预测值用“ 绿色 绘制。生成的线性回归线以“ 黑色 ”颜色绘制。

结论—

因此,在这个故事中,我们已经成功地构建了一个 简单线性回归 模型,该模型根据员工的“工作经验”来预测他们的“工资”,并将结果可视化。

我还附上了我的 github 资源库的链接,你可以在那里下载这个 Google Colab 笔记本和数据文件供你参考。

** [## MK-guru charan/回归

GitHub 是超过 5000 万开发人员的家园,他们一起工作来托管和审查代码、管理项目和构建…

github.com](https://github.com/mk-gurucharan/Regression)

您还可以在下面找到该程序对其他回归模型的解释:

在接下来的文章中,我们将会遇到更复杂的回归、分类和聚类模型。到那时,快乐的机器学习!**

机器学习基础:支持向量机(SVM)分类

原文:https://towardsdatascience.com/machine-learning-basics-support-vector-machine-svm-classification-205ecd28a09d?source=collection_archive---------9-----------------------

了解支持向量机制,并将其应用于实时示例。

在之前的故事中,我已经解释了各种 回归 模型的实现程序。此外,我还描述了逻辑回归和 KNN 分类模型的实现。在本文中,我们将通过一个清晰的例子来了解 SVM 分类的算法和实现。

SVM 分类概述

支持向量机(SVM)分类类似于我在之前的故事中解释过的支持向量机。在 SVM,用来分隔类的线被称为 超平面 。超平面任意一侧最接近超平面的数据点称为 支持向量 ,用于绘制边界线。

来源

在 SVM 分类中,数据可以是线性的,也可以是非线性的。在 SVM 分类器中可以设置不同的内核。对于线性数据集,我们可以将内核设置为' linear '。

另一方面,对于非线性数据集,有两个核,即' rbf 和'多项式'。在这种情况下,数据被映射到更高的维度,这使得绘制超平面更容易。之后,它被降低到较低的维度。

SVM 机制(信息来源——本人)

从上图中,我们可以看到有两类形状,矩形和圆形。由于很难在 2D 平面中绘制 SVM 线,我们将数据点映射到更高维度(3D 平面),然后绘制超平面。然后,用红色绘制的 SVM 分类器将它还原到原始平面。

通过这种方式,SVM 分类器可用于从给定的数据集中对数据点进行分类,确定其所属的类别。让我们用这个算法来解决一个现实世界的问题。

问题分析

在 SVM 分类模型的这个实现中,我们将使用由三列组成的社交网络广告数据集。前两列是自变量,即' 【年龄】' 和' 【估计销售额】' ,最后一列是因变量' 【购买量】' ,以二进制格式表示个人是否购买了产品(1)或(0)。

在这个问题中,我们必须为一家公司建立一个 SVM 分类模型,该模型将对特定年龄和特定工资的用户是否会购买他们的特定产品进行分类。现在让我们来看一下模型的实现。

步骤 1:导入库

和往常一样,第一步总是包括导入库,即 NumPy、Pandas 和 Matplotlib。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

步骤 2:导入数据集

在这一步中,我们将从我的 github 存储库中获取存储为[SocialNetworkAds.csv](https://github.com/mk-gurucharan/Classification/blob/master/SocialNetworkAds.csv) 的数据集,并将其存储到变量 dataset 中。然后我们将相应的变量赋给 X 和 y。最后,我们将看到数据集的前 5 行。

dataset = pd.read_csv('[https://raw.githubusercontent.com/mk-gurucharan/Classification/master/SocialNetworkAds.csv'](https://raw.githubusercontent.com/mk-gurucharan/Classification/master/SocialNetworkAds.csv'))X = dataset.iloc[:, [0, 1]].values
y = dataset.iloc[:, 2].valuesdataset.head(5)>>
Age   EstimatedSalary   Purchased
19    19000             0
35    20000             0
26    43000             0
27    57000             0
19    76000             0

步骤 3:将数据集分为训练集和测试集

该数据集中有 400 行。我们将把数据分成训练集和测试集。这里的test_size=0.25表示数据的 25%将作为 测试集 保存,剩余的 75%将作为 训练集 用于训练。因此,测试集中大约有 100 个数据点。**

**from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.25)**

步骤 4:特征缩放

这个特征缩放步骤是一个额外的步骤,当我们将 X 的值缩小到一个更小的范围时,它可以提高程序的速度。在这里,我们将X_trainX_test缩小到-2 到+2 的小范围。例如,工资 75000 按比例缩减为 0.16418997。

**from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)**

步骤 5:在训练集上训练 SVM 分类模型

一旦训练测试准备就绪,我们就可以导入 SVM 分类类并使训练集适合我们的模型。类别SVC被分配给变量classifier。这里用的核是“RBF”核,代表径向基函数。还有其他几种核,例如线性核和高斯核,也可以实现。然后使用classifier.fit() 功能来训练模型。

**from sklearn.svm import SVC
classifier = SVC(kernel = 'rbf', random_state = 0)
classifier.fit(X_train, y_train)**

步骤 6:预测测试集结果

在这一步中,classifier.predict()函数用于预测测试集的值,这些值被存储到变量y_pred.

**y_pred = classifier.predict(X_test) 
y_pred**

步骤 7:混淆矩阵和准确性

这是分类技术中最常用的一步。在这里,我们看到了训练模型的准确性,并绘制了混淆矩阵。

混淆矩阵是一个表,用于显示当测试集的真实值已知时,对分类问题的正确和错误预测的数量。它的格式如下

来源—自己

真实值是正确预测的次数。

**from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)from sklearn.metrics import accuracy_score 
print ("Accuracy : ", accuracy_score(y_test, y_pred))
cm>>Accuracy :  0.9>>array([[59,  6],
       [ 4, 31]])**

从上面的混淆矩阵中,我们推断,在 100 个测试集数据中,90 个被正确分类,10 个被错误分类,留给我们 90%的准确率。

步骤 8:将实际值与预测值进行比较

在这个步骤中,创建一个 Pandas DataFrame 来比较原始测试集( y_test )和预测结果( y_pred )的分类值。

**df = pd.DataFrame({'Real Values':y_test, 'Predicted Values':y_pred})
df>> 
Real Values   Predicted Values
1             1
0             0
0             0
1             1
0             0
... ...  ... ...
1             1
1             1
0             0
0             0
1             1**

这个步骤是一个额外的步骤,它不像混淆矩阵那样提供很多信息,并且主要用于回归以检查预测值的准确性。

步骤 9:可视化结果

在最后一步中,我们将 SVM 分类模型的结果可视化在一个沿着两个区域绘制的图上。

**from matplotlib.colors import ListedColormap
X_set, y_set = X_test, y_test
X1, X2 = np.meshgrid(np.arange(start = X_set[:, 0].min() - 1, stop = X_set[:, 0].max() + 1, step = 0.01),
                     np.arange(start = X_set[:, 1].min() - 1, stop = X_set[:, 1].max() + 1, step = 0.01))
plt.contourf(X1, X2, classifier.predict(np.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape),
             alpha = 0.75, cmap = ListedColormap(('red', 'green')))
plt.xlim(X1.min(), X1.max())
plt.ylim(X2.min(), X2.max())
for i, j in enumerate(np.unique(y_set)):
    plt.scatter(X_set[y_set == j, 0], X_set[y_set == j, 1],
                c = ListedColormap(('red', 'green'))(i), label = j)
plt.title('SVM Classification')
plt.xlabel('Age')
plt.ylabel('EstimatedSalary')
plt.legend()
plt.show()**

SVM 分类

在这个图中,有两个区域。 红色 区域表示 0 ,由未购买该产品的人组成, 绿色 区域表示 1 ,由已购买该产品的人组成。由于我们选择了非线性核(rbf ),我们得到的区域没有被线性线分开。

如果您仔细观察,我们可以看到测试集中的 10 个错误分类的数据点,它们在特定区域的颜色有所不同。

结论—

因此,在这个故事中,我们已经成功地建立了一个 SVM 分类 模型,它能够根据一个人的年龄和工资来预测他是否会购买一件产品。请随意尝试网上其他各种常见的分类数据集。

我还附上了我的 github 资源库的链接,你可以在那里下载这个 Google Colab 笔记本和数据文件供你参考。

** [## MK-guru charan/分类

这是一个由 Python 代码组成的知识库,用于构建不同类型的分类模型,以评估和…

github.com](https://github.com/mk-gurucharan/Classification)

您还可以在下面找到该程序对其他分类模型的解释:

在接下来的文章中,我们将会遇到更复杂的回归、分类和聚类模型。到那时,快乐的机器学习!**

机器学习基础:支持向量回归

原文:https://towardsdatascience.com/machine-learning-basics-support-vector-regression-660306ac5226?source=collection_archive---------6-----------------------

学会在机器学习中建立支持向量回归(SVR)模型,并分析结果。

在前面的故事中,我解释了用 Python 构建线性和多项式回归模型的机器学习程序。在本文中,我们将介绍基于非线性数据构建支持向量回归模型的程序。

SVR 概述

支持向量机(SVM)是一种非常流行的机器学习算法,用于回归和分类。支持向量回归类似于线性回归,在 SVR 中直线的方程是y= wx+b,这条直线被称为 超平面 。超平面任意一侧最接近超平面的数据点称为 支持向量 ,用于绘制边界线。

与试图最小化实际值和预测值之间的误差的其他回归模型不同,SVR 试图在阈值(超平面和边界线之间的距离)内拟合最佳直线。因此,我们可以说 SVR 模型满足条件-a < y-wx+b < a。它使用具有此边界的点来预测值。

来源

对于非线性回归,核函数将数据转换到更高维度,并执行线性分离。这里我们将使用 rbf 内核。

在这个例子中,我们将完成 支持向量回归(SVM) 的实现,其中我们将根据学生投入学习的小时数来预测他或她的分数。

问题分析

在这个数据中,我们有一个自变量学习时间和一个因变量分数。在这个问题中,我们必须使用这些数据训练一个 SVR 模型,以了解学习时间和学生分数之间的相关性,并能够根据学生投入学习的时间预测他们的分数。

步骤 1:导入库

在第一步中,我们将导入构建 ML 模型所需的库。导入 NumPy 库和 matplotlib 。另外,我们导入了 熊猫 库用于数据分析。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

步骤 2:导入数据集

在这一步,我们将使用 pandas 来存储从我的 github 存储库中获得的数据,并使用函数“ pd.read_csv ”将其存储为 Pandas DataFrame。

我们遍历我们的数据集,将自变量(x)分配给列“”的学习时间,将因变量(y)分配给最后一列,即要预测的“”标记。**

**dataset = pd.read_csv('[https://raw.githubusercontent.com/mk-gurucharan/Regression/master/SampleData.csv'](https://raw.githubusercontent.com/mk-gurucharan/Regression/master/SampleData.csv'))X = dataset.iloc[:, 0].values
y = dataset.iloc[:, 1].values
y = np.array(y).reshape(-1,1)dataset.head(5)>>Hours of Study   Marks
32.502345        31.707006
53.426804        68.777596
61.530358        62.562382
47.475640        71.546632
59.813208        87.230925**

我们使用相应的。iloc 函数对数据帧进行切片,以将这些指标分配给 X 和 y。在这种情况下,小时的学习时间被视为独立变量,并被分配给 X。要预测的因变量是最后一列,即标记的,它被分配给 y。我们将使用reshape(-1,1)将变量 y 整形为列向量。

步骤 3:特征缩放

大多数可用的数据通常具有不同的范围和大小,这使得建立模型很困难。因此,数据的范围需要被标准化为更小的范围,这使得模型在训练时更加准确。在该数据集中,数据被归一化到接近零的小值之间。例如, 87.23092513 的分数归一化为 1.00475931 ,而 53.45439421 的分数归一化为 -1.22856288

**from sklearn.preprocessing import StandardScaler
sc_X = StandardScaler()
sc_y = StandardScaler()
X = sc_X.fit_transform(X.reshape(-1,1))
y = sc_y.fit_transform(y.reshape(-1,1))**

在大多数常见的回归和分类模型中,特征缩放主要是在内部执行的。支持向量机不是一个常用的类,因此数据被标准化到一个有限的范围。

步骤 4:在训练集上训练支持向量回归模型

在构建任何 ML 模型时,我们总是需要将数据分成训练集和测试集。将使用训练集的值训练 SVR 模型,并在测试集上测试预测。在 100 行中,80 行用于训练,并且在由条件test_size=0.2给出的剩余 20 行上测试模型

**from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2)**

步骤 5:在训练集上训练支持向量回归模型

在此,函数 SVM 被导入并被赋给变量regressor。使用内核【RBF】(径向基函数)。径向基函数核用于将非线性引入到支持向量回归模型中。这样做是因为我们的数据是非线性的。regressor.fit用于通过相应地调整数据来拟合变量 X_trainy_train

**from sklearn.svm import SVR
regressor = SVR(kernel = 'rbf')
regressor.fit(X_train.reshape(-1,1), y_train.reshape(-1,1))**

步骤 6:预测测试集结果

在这一步中,我们将使用构建的 SVR 模型来预测测试集的分数。regressor.predict函数用于预测 X_test 的值。我们将预测值赋给 y_pred。我们现在有两个数据,y_test(真实值)和 y_pred(预测值)。

**y_pred = regressor.predict(X_test)
y_pred = sc_y.inverse_transform(y_pred)**

步骤 7:将测试集与预测值进行比较

在这一步中,我们将在 Pandas DataFrame 中将每个 X_test 的 y_test 的值显示为 真实值 ,将 y_pred 值显示为 预测值

**df = pd.DataFrame({'Real Values':sc_y.inverse_transform(y_test.reshape(-1)), 'Predicted Values':y_pred})
df>>
Real Values   Predicted Values
31.707006     53.824386
76.617341     61.430210
65.101712     63.921849
85.498068     80.773056
81.536991     72.686906
79.102830     60.357810
95.244153     89.523157
52.725494     54.616087
95.455053     82.003370
80.207523     81.575287
79.052406     67.225121
83.432071     73.541885
85.668203     78.033983
71.300880     76.536061
52.682983     63.993284
45.570589     53.912184
63.358790     76.077840
57.812513     62.178748
82.892504     64.172003
83.878565     93.823265**

我们可以看到,预测值与测试集的真实值之间存在显著偏差,因此我们可以得出结论,该模型并不完全适合以下数据。

步骤 8:可视化 SVR 结果

在最后一步中,我们将可视化使用给定数据构建的 SVR 模型,并在图上绘制“ y ”和“ y_pred ”的值,以可视化结果

**X_grid = np.arange(min(X), max(X), 0.1)
X_grid = X_grid.reshape((len(X_grid), 1))
plt.scatter(sc_X.inverse_transform(X_test), sc_y.inverse_transform(y_test.reshape(-1)), color = 'red')
plt.scatter(sc_X.inverse_transform(X_test), y_pred, color = 'green')plt.title('SVR Regression')
plt.xlabel('Position level')
plt.ylabel('Salary')
plt.show()**

******

学习时间与分数(SVR)**

在该图中,实际值用“ 红色 绘制,预测值用“ 绿色 绘制。SVR 模型的绘图也以 黑色 颜色显示。

我附上了我的 github 资源库的链接,你可以在那里找到 Google Colab 笔记本和数据文件供你参考。

** [## MK-guru charan/回归

GitHub 是超过 5000 万开发人员的家园,他们一起工作来托管和审查代码、管理项目和构建…

github.com](https://github.com/mk-gurucharan/Regression)

希望我已经清楚地解释了用非线性数据集构建支持向量回归模型的程序。

您还可以在下面找到该程序对其他回归模型的解释:

在接下来的文章中,我们将会遇到更复杂的回归、分类和聚类模型。到那时,快乐的机器学习!**

机器学习在看不见的数据上击败了 BTC/USDT,即使有交易费和滑点。

原文:https://towardsdatascience.com/machine-learning-beats-btc-usdt-on-unseen-data-even-with-transaction-fees-and-slippage-caa5e7a40caf?source=collection_archive---------5-----------------------

物理学研究如何变成人工智能模型,如何变成密码交易。

在一盘棋中,为了赢,必须有人输。这同样适用于高度不稳定的数字市场——比特币。投机者同时买入和卖出,肯定有人错了。来源

前言

有很多关于将机器学习应用于加密交易的实验文章,但很难找到一个具有现实方法论的文章。理想情况下,结果应该来自实际交易所的交易历史,或者来自带有看不见的数据和交易费用的模拟。这就是我写这篇文章的原因——我想告诉你我是如何进行金融市场研究的,展示一些研究结果,并最终向你展示实际结果。所有这些都是基于现实的假设——包括交易费用、滑点和看不见的数据。

看到什么不起作用

我曾经从事各种物理实验——最著名的是欧洲核子研究中心的 ATLAS 项目(使用大型强子对撞机,世界上最大和最高能量的粒子对撞机,也是世界上最大的机器)。我来到那里时是一名物理系学生,后来成为一名数据科学家,研究事件拓扑分类问题。2018 年夏天,我开始对股票交易感兴趣。我知道我的数据科学直觉和编程技能可能是有用的,所以使用数学模型和一些自动化的想法很自然地出现了。我花了一个夏天寻找有用的文章,但很难找到有趣的东西。如果有人声称某样东西有效,我无法以任何方式复制它。

在过去的 1.5 年里,我阅读了大约 100 篇关于金融领域机器学习的文章。我见过有人使用 LSTMs,路径积分,各种强化学习,但我没有发现任何异常的性能。尽管如此,看看什么不起作用还是很有用的,这样你就不必浪费时间亲自尝试了。

市场行为

有效市场假说认为资产价格反映了所有可获得的信息。如果这个假设是真的,那么只有那些拥有公众无法获得的信息的内部人士才能战胜市场,并且仅仅通过交易赚钱。在一次采访中,数学家兼对冲基金亿万富翁詹姆斯·西蒙斯强烈反对这一假设。他指出,在公开可用的数据中存在一些模式,可以用来持续战胜市场。他指出这些模式来来去去。一旦人们开始滥用某些统计异常,异常就会消失。这是因为我们的交易影响市场——尤其是当交易量很大的时候。一个已经消失的异常现象的例子是 20 世纪 80 年代许多商品随季节变化的趋势。人们可以在价格高于均线时买入,在价格低于均线时卖出,这样每年都能赚钱。

图 1:1984 年一种典型商品(糖)的价格,当时许多商品都有明显的季节性影响。原始的趋势跟踪系统可以让投资者在市场上获得优势。如今,价格模式要复杂得多。来源

西蒙的观点很有道理——一群人的行为有一定的模式,投资者也不例外。因此,我们可以利用人们在某种程度上可以用正确的数学模型预测的优势(数学模型需要不断进化,就像那群人一样)。这是否意味着这种模式可以在没有风险和没有交易量限制的情况下赚钱?显然不是。主要由复兴科技(Renaissance Technologies)的基金员工管理的梅达莲基金(Medallion fund)因其在华尔街的最佳记录而闻名。它主要面向基金员工,而不是每个投资者,原因是他们必须引入约 100 亿 dollars⁴.的资本限制在这种规模下,很难不对市场产生太大影响,这会扰乱模型本身的数据,进而导致预测不正确。越来越多的领先基金引入了类似的资本限制,这为较小的基金获得必要的资本创造了机会。

另一方面,风险不可能降低到零,因为首先,没有人知道市场的确切状态(要知道市场的状态,我们需要知道所有参与者的状态,这是不可能的),也没有人确切知道市场未来会如何反应(某些行动的蝴蝶效应是可能的)。然而,通过引入随机变量,这是概率论的创造,我们可以在一定程度上建立这样的市场模型。风险无法消除,但其降低是可以控制的。由于我们的系统中存在随机变量,短期情景可能会有很大变化。即使是最好的系统也可能在短期内亏损。例如,在这份年度财务报告中,report⁵ JP 摩根称,由于进行了不良交易,他们在一天内损失了大约 1 亿美元。重要的是长期的结果。

可用信息:技术与基本面

在深入研究可以将信息用于我们的优势(即降低投资风险)的模型之前,让我们先回顾一下可用的信息。证券交易所记录了他们调解的每一笔交易,对公众隐瞒了他们的价格和交易量数据数据集,只愿意以几十万美元的价格出售(通常按年收费)。然而,加密货币交易所要透明得多。足够熟练的程序员应该能够通过使用他们的 API“免费”访问每个主要加密货币交易所的每个硬币对(从众所周知的比特币和莱特币到最近的储备权令牌 RSR 等新的热门令牌)上的每个交易,不计算时间和精力。如果我们假设价格大致反映了市场的状态,我们不需要任何其他信息来建立一个有效的交易系统。然而,实践表明,这种系统也可以从地缘政治局势/立法行动/财务报告等分析中受益匪浅。(通常指基础研究)。例如,历史上,黄金在冲突爆发时会上涨。

首先模拟市场

上世纪 80 年代,领先的量化对冲基金使用线性模型。转向隐马尔可夫模型,后来完全接受了机器学习 solutions⁶.没有对冲基金吹嘘他们的方法,但如果你持续观察他们足够长的时间,并关注细节,你就能到处发现小信息。这是对他们 website⁷:的一个研究科学家职位的描述

研究科学家:使用机器学习、应用数学和现代统计学技术来开发和完善金融市场模型,并基于这些模型开发交易算法。

乍一看,这似乎不重要,但请密切注意这一部分:“开发和改进模型[……]并基于这些模型开发交易算法”。他们明确区分了市场模型和交易算法。通过我的研究,我也意识到,目前,这可能是建立交易系统最有效的方式。首先,尝试建立一个市场模型。试着预测某些市场状态,某些变量,行为,然后,根据你的预测建立一个交易算法。如果你开发了一个黑匣子,它只是简单地获取原始价格数据,不经过中间步骤就做出交易决定,那么理解和修改起来就会困难得多。相信我——你必须修改你的第一个系统,因为没有人能一次就做对。此外,记住,要维护一个交易系统,你必须定期修改它,这是上一节的结论(根据霍华德摩根,复兴科技的原始团队成员之一,更新他们的系统 monthly⁸).

特色工程

如果你遵循一条规则,即长期决策应该由长期模式驱动,短期决策应该主要由短期模式驱动——时间投资窗口越短,模式数据集就越大。如果我们真的在短期内(亚秒甚至毫秒),那么模型往往会工作得更好(由于大量的可用数据点),然而,这导致昂贵的计算机基础设施能够非常精确地进行计算和执行订单。由于我不是通过加入现有的公司,而是创建自己的公司来开始我的财务之旅,我个人专注于分分秒秒的时间窗口,这很简单,因为 4 人团队的技术限制。

如果我们从每分钟提取一个数据点(一个数据点可以是一列数字,例如买/卖量、给定分钟内按量加权的平均价格、最低价格、最高价格等。)那么我们每年剩下大约 50 万个数据点。相比之下,在我在欧洲核子研究中心从事分析工作期间,我们过去常常基于数亿个数据点来制作神经网络模型。那时,我们可以输入原始数据,但在分钟到分钟价格的情况下,它们必须得到适当的简化,以避免不必要的过度拟合——使模型无法在看不见的数据上正常工作。这些数据点的空间表示可能会极大地影响性能。例如,为了表示音频,查看频率要容易得多。如果金融世界中的某些东西可行,那么人们不太可能与他人分享所有细节——如果你想成功,你需要有创造力,并找到一种合适的空间表示(所谓的特征工程)。

避免偏差和过拟合

虽然可以使用 k-fold 交叉验证等解决方案在整个数据集上可靠地测试模型的性能,但在许多现有文章中,这通常是前瞻偏差的来源。为了透明起见,我将比特币价格分为两个数据集:训练和测试(算法和我都看不见的数据)。2019 年 10 月 1 日之后的数据没有用于训练/拟合模型的参数,我将介绍该模型的结果。在欧洲粒子物理研究所,有一条规定,所有的物理分析都是首先根据前一年的数据集准备的,任何研究人员(除了极少数例外)都无法获得最新的数据。建立这条规则是为了防止各种偏见。例如,我们知道价格在测试数据集中下降,所以(可能只是下意识地)我们使模型更加厌恶风险。在我的工作中,我也遵循了这一规则,在大多数情况下,我没有查看该模型建立之前的最新数据(从 2019 年 10 月 1 日起)。该模型目前与我和我的客户的真实交易所交易相关联——根据定义,这种数据没有任何偏见,我将展示其中的一些数据来支持模拟。

避免过度拟合的一个方法是引入一个二值随机变量“x ”,如果“x=1 ”,则允许订单进入模拟,如果“x=0 ”,则阻止订单。在您的策略中没有这样的变量相当于它的平均值为 1。应该尝试将平均值设置为 0.1 或 0.5,看看性能会发生什么。这是过度策略和/或交易不足以达到统计显著性的真正杀手。下面我们来介绍一下性能比 R(x)如下:

等式 1:R(x)—x 函数中的性能比。除以 x 作为归一化。

其中 P(x)是 x 的函数,鲁棒系统的 R(x)常数应在 1 左右。

模拟现实交易费用

任何现实市场模型的基本特征是交易费用。除了向交易所支付佣金,我们还必须考虑“延期费”,也称为滑点。我们永远不能使用最后看到的交易价格进行买卖。计算预测和执行订单的基础设施总有一个反应时间。最后但并非最不重要的一点是,存在“价差”——某一订单深度的买卖差价(在交易量巨大的情况下尤其重要)。总结一下,最终费用(FF)为:FF =交易费(TF),延误费(DF),点差费(SF)。

结果

不同最终费用的2019 年 4 月 24 日2020 年 1 月 15 日期间的模拟结果如下所示。

图 2:不同最终费用的模型和“买入并持有”策略在比特币上的性能比较。每月 81 笔交易使得业绩对最终费用非常敏感。

HitBTC 向(接受者/制造者)提供 0.07%的交易费(如果你是验证用户),没有任何额外的交易量要求。同样,币安提供 0.075%(如果你持有 BNB,但其大多数用户持有)。我们的系统在几秒钟内执行一笔交易,平均延迟费用约为 0.015%(如果你的策略是反向策略,这可以低得多,甚至是负数)。对于小投资者来说,价差约为 0.01%。SF 随着资本的增加而增加,但交易费用随着交易量的增加而减少,因此 FF 在资本方面相对稳定,约为 0.095%。你可以看到,这是在一个有利可图的范围内。

表 1:B&H 对 BTC/USDT 的策略与 FFF=0.10%的模型的比较。

这种程度的风险降低只能通过加密市场上的活跃交易来实现。所有主要因素都高度相关(从 0.4 到 0.9),所以像资产多样化和再平衡这样的标准风险降低方法在 well⁹.并不适用

如何纳入基本面投入并多样化

如果你进行基本面研究,研究结果表明市场会上涨或下跌,那么就有办法增加或减少策略与市场的相关性。

假设我们的度量“m”是:

情商。2:将 m 度量为利润 P 和风险 D 的 n 次方之比。

对于 n=1,我们有一个平衡策略,风险和利润一样重要。如果我们设置 n <1 we will make our strategy riskier, thus indirectly increasing the correlation with the market. Similarly, n> 1 将减少相关性。另一种方法,一种更直接的强制关联/去关联的方法是在策略方面使我们的投资组合多样化。我们可以在市场资产中持有一定比例,或者从投资中撤出,而不是将我们的所有资本都投入到模型中。参见下图和下表进行比较。

图 3:混合策略之间的比较。使用买入并持有(B & H)的策略在明显上升趋势期间(2019 年 4 月至 6 月)表现优于模型。

表 2: 混合策略之间的绩效比较。在策略投资组合中加入 B & H 会增加风险,降低回报,但如果我们预期上涨趋势,这可能是有用的。风险以最大提款来衡量。

接下来是什么?

由于我每天收集越来越多的数据,我将在 2020 年 3 月进一步提高决策的分辨率,在 1 分钟内达到 4 个预测/决策。这将使模型对更快速的运动更敏感,到目前为止,这种运动在 2020 年非常频繁。

注来自《走向数据科学》的编辑: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

来源:

[2] 面试可在线获得

[3] 面试可在线获得

财务评论**

[5] 摩根大通年度报告

[6]格雷戈里·祖克曼,《解决市场的人》(2019)

[7] rentec 网站

在线采访

[9] 币安年报

GCP 上的机器学习—选择 GPU 来训练您的模型

原文:https://towardsdatascience.com/machine-learning-best-gpu-option-on-google-cloud-platform-performance-price-discounts-81e0aa99ad46?source=collection_archive---------18-----------------------

GCP GPU 概览——价格、性能、效率、折扣

G oogle 云平台提供了广泛的 GPU 选项可供选择。GPU 可以提高你的 ML 处理能力,尤其是在矩阵计算方面。然而,我们机器上的 CPU 并没有为此进行优化。他们努力处理图像或视频,并且经常会延迟模型训练过程。

照片由 Artiom VallatUnsplash 上拍摄

在 Tensorflow/Keras 中,NCHW(通道优先)输入的卷积网络需要 GPU 运行。

我的大部分人工智能实验都围绕着人工智能游戏,使用简洁的深度 Q 强化学习或类似的技术。这涉及到对游戏框架的激烈的矩阵操作,这是 CPU 难以应付的。

在切换到 GCP GPU 后,在 CPU 上花费数周时间训练的游戏模型在 GPU 上几天内就完成了。因为它们运行在云上,所以只需使用外部 IP 暴露您的 Tensorboard,无需登录即可轻松监控您的模型。

以下是目前可用的 GPU 选项(2020 年 8 月 10 日)以及它们的价格:—

**NVIDIA® Tesla® T4:** $255.50/month 
**NVIDIA® Tesla® K80:** $328.50/month
**NVIDIA® Tesla® P4:** $438.00/month
**NVIDIA® Tesla® P100:** $1,065.80/month
**NVIDIA® Tesla® V100:** $1,810.40/month

更多信息请点击这里:https://cloud.google.com/compute/docs/gpus

本评估仅涵盖特斯拉 T4、K80 和 P4。P100 和 V100 已经被排除在外,仅仅是因为它们对小项目和业余爱好者来说过于昂贵。

注意 :并非所有 GPU 在所有 GCP 地区都可用。您可能希望根据您所使用的 GPU 来更改区域。

NVIDIA Tesla T4—圣杯|首选

特斯拉 T4 是圣杯——它既便宜又高效。它已经成为我为任何 ML 模型设置 GCP 环境的首选。

这是使用 Tensorflow 2.2.0-rc0(在特斯拉 T4 上)运行 DDQN 的 Tensorboard 输出:最高得分:406

Model: "sequential"_________________________________________________________________Layer (type)                 Output Shape              Param #   =================================================================conv2d (Conv2D)              (None, 32, 20, 20)        8224      _________________________________________________________________conv2d_1 (Conv2D)            (None, 64, 9, 9)          32832     _________________________________________________________________conv2d_2 (Conv2D)            (None, 64, 7, 7)          36928     _________________________________________________________________flatten (Flatten)            (None, 3136)              0         _________________________________________________________________dense (Dense)                (None, 512)               1606144   _________________________________________________________________dense_1 (Dense)              (None, 4)                 2052      =================================================================

作者图片

Link to Tensorboard: [https://tensorboard.dev/experiment/1yrW70A0QHertoJDVZk1ig/#scalars&tagFilter=rew](https://tensorboard.dev/experiment/1yrW70A0QHertoJDVZk1ig/#scalars&tagFilter=rew)

你可以观察到训练过程在短短 2 天内就在突围游戏中取得了接近 300 分的成绩。

特斯拉 T4 的另一个优点是,你可以让它们运行更长时间,以获得持续的折扣,因为它们很便宜(稍后讨论)。

比较 T4 和 P4 的 K80

与 P4 的 K80 相比,特斯拉 T4 是一款相对较新的车型。

上市日期:
特斯拉 T4—2018 年 9 月
特斯拉 P4—2016 年 9 月
特斯拉 K80s—2014 年 11 月

在 Tensorflow 分布式训练中,这些在多个 GPU 上的表现如何,此处尚未评估。

但是就性能而言,Atari Breakout 模型的 DDQN 在所有 3 个 GPU 上花费了类似的时间来完成,性能没有重大差异。

Github Link to my project: [https://github.com/komal-SkyNET/ai-neural-networks/tree/master/ai-atari](https://github.com/komal-SkyNET/ai-neural-networks/tree/master/ai-atari)

持续折扣——一定要小心这些!

持续折扣提供大幅折扣,让您的实例运行更长时间。这个是按月计算的。

作者图片:使用特斯拉 T4 GPU 计算引擎实例的成本估算(来自 GCP 控制台)

如图所示,请注意,仅使用特斯拉 T4 运行虚拟机,您就可以获得近 80 美元的持续折扣。

*More information here:* [https://cloud.google.com/compute/docs/sustained-use-discounts](https://cloud.google.com/compute/docs/sustained-use-discounts?_ga=2.15197878.-1086316627.1594861704)

通过持续折扣,我节省了将近 100 澳元

下面是一个月来运行 GPU 工作负载有/没有持续折扣的比较。注意图表。

不打折→

作者图片:Komal Venkatesh Ganesan

持续折扣→

作者图片:Komal Venkatesh Ganesan

区域与 GPU 选项

请注意,GPU 选项基于区域。如果您发现下拉列表中缺少某个特定的 GPU 选项,您可能需要尝试不同的地区/区域。

区域 VS GPU 选项( 图片作者)

GPU 选项 us-central1-a(缺少 P100) ( 图片由作者提供)

结论

  • 特斯拉 T4 既便宜又高效,很容易成为第一选择,其次是 K80 和 P4。但是,它们在分布式培训(使用多个 GPU)中的性能可能会有所不同,不在本评估范围内。
  • 持续折扣:只要多运行一会儿您的工作负载,您就可以获得巨大的折扣。调配虚拟机时,通常会显示预测估计值。

2021 年必读的机器学习书籍

原文:https://towardsdatascience.com/machine-learning-books-you-must-read-in-2020-d6e0620b34d7?source=collection_archive---------1-----------------------

看看吧,你为什么要读它们?

照片由像素皮克斯拜拍摄

"机器学习:计算机能够从经验中学习,而不需要专门编程."
-Supplychain today

人工智能 和机器学习自这十年以来一直在获得大量牵引力,每个人都想成为这一变化的一部分。企业对该技术的好处很好奇,而专业人士则对机器学习的能力着迷,并渴望提升自己的技能。

无论是哪种情况,总是需要一个起点,还有什么比阅读那些教你技术细节的伟大书籍更好的方法呢?不管你的专业技能如何,你总能找到适合各种人的书籍,无论是技术爱好者还是新手。

机器学习书籍

在本文中,我们将简要介绍一些可以帮助您理解机器学习概念的最佳书籍,并指导您成为这一迷人领域的专家。此外,假设你熟悉编程语言的基础,这些书是灵感的巨大来源,充满了想法和创新。请继续阅读,了解更多信息—

1。绝对初学者的机器学习:简明英语介绍

作者:奥利弗·西奥博尔德

出版社 —散点图出版社

难度等级:初学者

在这里获取图书——亚马逊

《绝对初学者的机器学习》一书封面

正如标题所解释的,如果你是机器学习的绝对初学者,这本书应该是你的切入点。要求很少到没有编码 或者数学背景,书中所有的概念都已经解释的很清楚了。

示例之后是视觉效果以更友好的方式展示主题,帮助理解 ML 的关键要素。

奥利弗·西奥博尔德在他的书中简化了几个与 ML 相关的复杂主题,如它的基础知识,以及其他技术,如数据清理,回归分析,聚类,偏差,人工神经网络等。这本书还提供了进一步学习的额外资源。

“作为机器的‘Hello World’的分析”
奥利弗·西奥博尔德

2.深度学习

作者:伊恩·古德菲勒、约舒阿·本吉奥和亚伦·库维尔

出版商— 麻省理工学院出版社

难度等级:初学者

在此获取图书— 亚马逊

《深度学习》一书的封面

被认为是一本非常适合初学者的书,它向你介绍了深度学习的广泛主题,同时也涵盖了机器学习的相关方面。

DL 的基本概念在本书中从头开始进行了全面的解释,以便在这个领域中有一个更强的立足点。这本书解释了线性代数的相关概念,概率和信息论,数值计算,行业标准技术,如优化算法,卷积网络,计算机视觉,以及研究课题,如蒙特卡罗方法,配分函数。为了更深入的理解,捆绑了足够的补充材料。

《深度学习》由该领域的三位专家撰写,是唯一一本关于 subject"⁠的综合性书籍——埃隆·马斯克,特斯拉和 SpaceX 的联合创始人兼首席执行官

3.使用 Scikit-Learn、Keras 和 TensorFlow 进行机器学习:构建智能系统的概念、工具和技术(第一版)

作者:奥雷连诺

发行方 —奥莱利传媒

难度等级:初学者

在这里获取图书——亚马逊

《使用 Scikit-Learn、Keras 和 TensorFlow 进行机器学习》一书的封面

对于任何计划开始学习机器的人或该领域的爱好者来说,这是最畅销的书籍之一。它要求预先了解 Python 编程语言,解释了一些最常用的 ML 库 Scikit-Learn、Keras 和 TensorFlow 2,用于构建智能系统。

直观解释的概念和易于实现的示例使得实际实现和理解更加顺畅。主题包括支持向量机、随机森林、神经网络、深度强化学习、热切执行、时序处理等等。这本书包含了几个库的更新代码示例,以及相关的 API。

补充:还可以在 GitHub 上找到带幻灯片的讲座练习

“在机器学习中,这被称为过度拟合:这意味着模型在训练数据上表现良好,但不能很好地概括。”
奥雷连·盖伦

这是关于机器学习的最好的书吗?

查看该书的第二版—

4.面向虚拟人的机器学习(Python 和 R 语言)

作者:约翰·保罗·穆勒和卢卡·马萨隆

出版者 —为假人

难度等级:初学者

在这里获取图书——亚马逊

《面向傻瓜的机器学习(Python 和 R 语言)》一书的封面

著名的“假人”系列的所有书籍都对新手非常友好。这本书,就像这个系列的其他书一样,以一种读者容易理解的方式阐述了它的概念。

这本书包括 ML 中的介绍性概念和理论以及所涉及的工具和编程语言。书中涵盖的主题从在 Windows、Linux 和 macOS 上安装 R 开始,然后是矩阵创建、使用矢量和数据帧、使用 RStudio 或 Anaconda 用 R 或 Python 编码。对于数据挖掘和分析的基本概念,这是一本方便的指南。

“作为一种学习,它类似于人类用来判断某些对象或事件来自同一类别的方法,例如通过观察对象之间的相似程度。”约翰·保罗·穆勒

5.机器学习在行动

作者:彼得·哈灵顿

出版社 —曼宁出版公司

难度等级:初学者

在这里获取图书——亚马逊

《机器学习在行动》一书的封面

一本有价值的书,旨在给开发者机器学习所需技术的实践经验。对于熟悉与 ML 相关的 Python 代码片段来说,这是一本同样重要的书,尽管需要事先有 Python 的经验。

该书包含用于统计数据处理、数据分析和数据可视化的各种算法的代码,以及诸如分类、预测、建议、简化等任务。用最少的理论,这本书直接切入这些算法的实际实现。

6.模式识别和机器学习

作者:克里斯托弗·m·毕晓普

出版商 —施普林格

难度等级:中级

在这里获取图书——亚马逊

Github 回购:https://github.com/ctgk/PRML

《模式识别与机器学习》一书的封面

针对有模式识别和机器学习的基本想法的个人,这本书假定读者在多元微积分和代数方面有某种程度的先验知识。

本书中的概念旨在解释 ML 领域中底层算法和技术的最新发展。涵盖广泛使用的主题,如贝叶斯方法,回归,分类,神经网络,图形模型,采样方法,等等,这本书非常适合理解 ML,统计,计算机视觉和挖掘。这本书配有大量练习和附加材料。

7.统计学习导论(R 语言应用)

作者:加雷斯·詹姆斯、丹妮拉·威滕、特雷弗·哈斯蒂和罗伯特·蒂布拉尼

出版商— 施普林格

难度等级:中级

在这里获取图书——亚马逊

《统计学习导论(R 语言应用)》封面

这本书,虽然需要一些线性回归的先验知识,却是理解统计学习概念的一个极好的工具。通过提供关于如何利用大型复杂数据集的平衡见解,它旨在教育广大统计人员和非统计人员,使他们能够理解手中的数据。

它涵盖了统计学习的几个重要概念,如线性回归,分类,基于树的模型,支持向量机,重采样方法,等等。各种例子和教程使学习过程更加愉快,它包括几个 R 实验室,演示这些统计方法的实施。

8.应用预测建模

作者:马克斯·库恩和杰尔·约翰逊

出版商— 施普林格

难度等级:中级

在这里获取图书——亚马逊

《应用预测模型》的封面

这本书被认为是许多预测建模概念的特别参考书,要求对统计学、R 编程语言和机器学习概念有很好的理解。作者着重解释数据收集、操作和转换过程,因为这在 ML 书籍中经常被忽略。

这本书的应用性质使它成为分析行业面临的实际问题的绝佳选择。读者可以深入数据预处理,分裂,模型调整,然后回归,分类,处理类不平衡,选择预测。

9.黑客的机器学习:案例研究和算法让你入门

作者:德鲁·康威&约翰·迈尔斯

出版商 —奥赖利媒体

难度等级:中级

在这里获取图书——亚马逊

《黑客的机器学习》一书的封面

正如标题所说,这本书不是给黑客看的,而是给那些对动手案例研究感兴趣的人看的。这本书需要很强的编程背景,旨在用驱动机器学习的算法来训练你。不同的章节集中于 ML 中的每个问题,例如分类、优化、预测和推荐。

这本书还训练你使用 R,以及如何分析数据集,并让你开始编写简单的 ML 算法。它不同于其他书籍的一个重要方面是它不太依赖数学来教授数学。

10.集体智慧编程:构建智能 Web 2.0 应用

作者:托比·塞格兰

出版商 —奥莱利传媒

难度等级:中级

在这里获取图书——亚马逊

《集体智慧编程》一书的封面

被许多人认为是机器学习的最佳指南,这本书更喜欢教你 ML 的实现,假设你知道 Python。它包括创建算法和程序的步骤,用于访问网站外的数据集,自己收集数据,以及分析和利用数据。

带你进入 ML 和统计,这本书包括爬虫,索引器,优化,PageRank 算法,过滤技术,决策树的例子。本书旨在引导你按照自己的节奏完成创建算法的整个过程,这本书做得很好。

11.统计学习的要素:数据挖掘、推理和预测

作者:特雷弗·哈斯蒂,罗伯特·蒂布拉尼,杰罗姆·弗里德曼

难度:专家

出版商 —施普林格

在这里获取图书——亚马逊

《统计学习的要素》的封面

这本书侧重于概念,而不是概念背后的数学。它收集了大量关于在几个部门实施统计学习的想法。充满了相关的例子和可视化,它应该是任何统计学家或数据挖掘爱好者的图书馆中必不可少的一块。

这本书涵盖监督和非监督学习,包括支持向量机,分类树,神经网络,助推,集成方法,图形模型,谱聚类,最小角度回归,路径算法等主题。

12.Python 机器学习

作者:塞巴斯蒂安·拉什卡和瓦伊德·米尔贾利利

出版者 — Packt

难度:专家

在这里获取图书——亚马逊

《Python 机器学习》一书的封面

假设你已经很好地理解了 Python 和机器学习的许多核心概念,这本书直接切入概念的实际实现。书中的概念包括 NumPy、Scikit-learn、TensorFlow2 和 SciPy 的最新解释。这本书通过从行业中面临的现实世界的挑战教你,为你承担现实世界的挑战做准备。它包括各种主题,如降维,集成学习,回归,聚类分析,神经网络,等等。

“最终,分类器的性能、计算能力以及预测能力在很大程度上取决于可用于学习的基础数据。训练机器学习算法所涉及的五个主要步骤可以总结如下:选择特征。选择绩效指标。选择分类器和优化算法。评估模型的性能。调整算法。”
塞巴斯蒂安·拉什卡, Python 机器学习

结论

在这个快速发展的时代,跟上这些进步并不断提升自己是当前的需要。有数百本关于机器学习和相关技术的书籍、指南和其他在线资源。机器学习一开始可能会令人吃惊,这就是为什么我们在本文中概述了十本最受欢迎的书籍,希望其中一些能引起你的兴趣。请随意推荐您认为可能对该列表有帮助的扩展。

注意:为了消除不同类型的问题,我想提醒你一个事实,这篇文章仅代表我想分享的个人观点,你有权不同意它。

更多有趣的阅读—

我希望这篇文章对你有用!以下是一些有趣的读物,希望你也喜欢

[## 面向所有人的顶级谷歌人工智能工具

使用谷歌人工智能中心将想法变为现实

towardsdatascience.com](/top-google-ai-tools-for-everyone-60346ab7e08) [## 数据科学家的最佳数据科学工具

数据科学工具,使任务可以实现

towardsdatascience.com](/best-data-science-tools-for-data-scientists-75be64144a88) [## 2020 年的数据科学趋势

新十年的关键数据科学趋势

towardsdatascience.com](/data-science-trends-for-2020-9b2ee27af499) [## 数据科学如何助推网飞

当有效使用时,数据可以神奇的方式改变您的业务,并将它带到新的高度。

towardsdatascience.com](/how-data-science-is-boosting-netflix-785a1cba7e45)

关于作者

克莱尔丁。是Digitalogy的内容制作者和营销人员,这是一个技术采购和定制匹配市场,根据全球各地的特定需求,将人们与预先筛选的&顶尖开发人员和设计师联系起来。在 LinkedinTwitterInstagram 上连接 Digitalogy

机器学习可以在不到五分钟内检测到新冠肺炎!

原文:https://towardsdatascience.com/machine-learning-can-detect-covid-19-in-less-than-five-minutes-23bba57aeaa3?source=collection_archive---------27-----------------------

疾控中心Unsplash 拍摄的照片

旨在快速检测冠状病毒的研究进展的信息和收获。

介绍

一群来自世界知名学术机构的研究人员,如牛津大学华威大学蒙彼利埃大学和可信的研究实验室,发明了一种在几分钟内检测新冠肺炎(新型冠状病毒)和其他呼吸道病原体的方法。

这一壮举是通过利用图像分析和机器学习技术,更具体地说是卷积神经网络,根据病毒特有的结构特征对呼吸道疾病的微观病毒进行分类而实现的。

照片由 L NUnsplash 上拍摄

本文介绍了与上述机构研究人员开展的工作相关的发表的研究论文中的关键信息和要点。

通过阅读这篇文章,你将理解用于创建新冠肺炎 5 五分钟检测系统和其他重要背景信息的方法背后的直觉和技术。

有些读者可能不熟悉本文中的一些术语和短语,这是完全可以理解的,因此,在本文的某些地方,一些章节提供了所用单词和关键术语的定义。

新型冠状病毒:引起新冠肺炎病的人类冠状病毒株。

病原体:致病生物或传染物。常见的病原体有病毒、细菌、真菌、朊病毒和寄生虫。

以前检测新冠肺炎的方法(新型冠状病毒)

你可能已经熟悉了检测新冠肺炎的方法,也许你最近做过一些新冠肺炎试验。一些新冠肺炎测试检测咽拭子样本中病毒的存在,而其他测试检测人类免疫系统产生的抗体来对抗疾病。

国家癌症研究所Unsplash 上拍摄的照片

以下是对通常用于检测新冠肺炎病毒的测试的更正式的解释和描述。

核酸扩增试验

核酸扩增测试通过识别特定的核酸序列来检测新冠肺炎;这意味着对病毒特有的独特的生物聚合物生物分子的检测。

这种检测程序的扩增部分是指产生新冠肺炎特有的遗传物质或 DNA 的拷贝。

就早期疾病诊断而言,与抗体检测相比,检测病毒 DNA 的存在实际上好得多。身体通常需要一段时间来产生抗体,以应对新冠肺炎病毒感染。

抗原和抗体检测

抗原是侵入性生物,可引发免疫系统产生抗体的反应。抗体通常会将自身结合到抗原上,导致感染和疾病,进而导致免疫系统中和抗原。

由 Brian 0918&# 153;—自己的作品,公共领域,https://commons.wikimedia.org/w/index.php?curid=404735

新冠肺炎的抗体测试通过检测血液中的抗体来检测个体中抗体的存在,从而揭示一个人以前是否感染过新冠肺炎病毒。

抗体测试不会显示一个人目前是否感染了新冠肺炎病毒,而抗原测试将确认一个人现在是否被感染。

抗原测试的工作原理是检测与入侵病原体相关的蛋白质的存在。

生物聚合物:这些是由活生物体产生的长重复分子链的材料,(RNA(核糖核酸)或 DNA(脱氧核糖核酸))。

五分钟检测程序如何工作

该程序的工作原理是传递标记病毒粒子的图像,这些图像经过处理后显示出特定的颜色信号。卷积神经网络对显微镜图像中的病毒颗粒信号进行分类。

以下是更详细的程序步骤:

  1. 该程序从通过咽拭子提取病毒颗粒开始。
  2. 收集的病毒样本用甲醛灭活。
  3. 下一步是通过短的荧光 DNA 与病毒表面的结合来即时标记完整的病毒颗粒。
  4. 标记后,使用壳聚糖包被的载玻片固定病毒颗粒,并置于其上。
  5. 通过使用显微成像收集病毒颗粒的衍射受限图像。
  6. 然后使用图像处理和机器学习技术对样本中的各种类型的病毒进行分类。

荧光标记策略和病毒检测的程序。

卷积神经网络(CNN)根据病毒颗粒表面荧光团的分布对病毒颗粒进行分类。CNN 利用了病毒颗粒表面荧光团分布的独特特性。

病毒颗粒具有独特的形状、大小、结构和表面化学性质,这反过来使得病毒颗粒表面荧光团的分布能够作为对病毒进行分类的独特特征。

作者 Gregor 1976——自有作品,公共领域,【https://commons.wikimedia.org/w/index.php?curid=1251744

呈现给 CNN 网络的图像包含被照亮为单一绿色或红色荧光信号的病毒粒子和黄色粒子。黄色颗粒对应于共同定位的绿色和红色荧光信号(具有红色和绿色荧光标记的病毒颗粒)。

根据研究,在不含新型冠状病毒病毒(病毒阴性)的咽拭子样品中,观察到几乎没有共定位信号。

在病毒阳性样品中更容易观察到共定位信号。有关提取图像的示例,请参见下面的图像。

左图:荧光显微成像显示共定位的红色和绿色信号为黄色颗粒(病毒阳性)。右图:病毒负面形象

在通过卷积神经网络前馈图像之前,基于定义的视场内图像信号的稀缺性(< 10 pixels) of image signals areas or abundance(> 100 像素)来过滤图像信号的区域。

自适应滤波 是用于从背景中分割病毒信号的图像处理方法。

用于确保病毒粒子信号在图像中普遍存在的另一种方法是通过基于协同定位条件的信号过滤。

符合设定的协同定位信号条件的信号将被保留,不符合条件的信号将从通过 CNN 的最终图像中过滤掉。

大多数机器学习实践者将上述过程视为在机器学习项目生命周期的数据准备阶段强制执行的确保数据完整性和清洁性的方法。

放置在协同定位信号周围的边界框

荧光团:一种化合物,通过其吸收和重新发射各种波长的光的能力而充当检测剂。

共定位:涉及荧光标记空间重叠的事件。

网络体系结构和 ML 技术

在这项研究工作中设计和实现的卷积神经网络架构由 15 层组成。

CNN 架构的设计分为三个阶段,最后才是分类头。

第一阶段在输入层之后,其中有一个 conv 层(8 个通道,2x2 滤波器大小,0 填充),随后是一个 ReLu,批量归一化和一个最大池层(池大小 2x2,步长 2)。第一阶段向下一阶段输出八个下采样特征图。

第二阶段由 conv 层(16 个通道,2×2 滤波器大小,填充为 1)组成,随后是 ReLu、批量归一化和最大池层(池大小为 2×2,步长为 2)。第二阶段向下一阶段输出 16 个下采样特征图。

第三阶段由 conv 层(32 个通道,3×3 的滤波器大小,填充为 1)组成,随后是 ReLu、批量归一化和无最大池层。

第三阶段的结果被传递到完全连接的层上。在典型的 CNN 中,conv 层的输出在传递到完全连接的层之前被展平为一维数组。

全连接层(致密层)包含任意数量的神经元/单元。全连接层的激活通过 softmax 层,在此对输入数据进行分类。

以下是本节包含的一些关键术语的快速定义,如果您已经熟悉这些术语,请随意跳过。

卷积层:卷积是一个数学术语,描述两组元素之间的点积相乘。在深度学习中,卷积运算作用于卷积层中的滤波器/内核和图像数据阵列。因此,卷积层只是一个包含滤波器和通过卷积神经网络的图像之间的卷积运算的层。

批量标准化层 :批量标准化是一种通过引入一个附加层来减轻神经网络内不稳定梯度影响的技术,该附加层对来自前一层的输入执行操作。这些操作对输入值进行标准化和规范化,然后通过缩放和移位操作转换输入值。

下面的 max-pooling 操作有一个 2x2 的窗口,并滑过输入数据,输出内核感受域内像素的平均值。

展平图层:取一个输入图形,将输入图像数据展平成一维数组。

Softmax 激活函数:一种激活函数,用于导出输入向量中一组数字的概率分布。softmax 激活函数的输出是一个向量,其中它的一组值表示一个类或事件发生的概率。向量中的值加起来都是 1。

超参数和附加信息

  • 当训练卷积神经网络时使用的学习速率被设置为 0.01,没有学习速率衰减。
  • 小批量:1000 个
  • 训练时期数:100
  • 验证频率:20 步

培训和测试

新型冠状病毒病毒与其他呼吸道疾病如流感和季节性人类冠状病毒(hCov)有相似的早期症状;因此,任何新冠肺炎检测方法必须有助于区分相似的病毒。

研究中使用的 CNN 网络在包含四种独特病毒的数据集上进行训练和验证,训练和验证分区分别为 70%和 30%。

研究人员确保实现的 CNN 可以区分具有相似形状、结构和表面化学的病毒。

根据研究论文的笔记,训练和验证阶段总共花了 12 分钟。

结果

经过训练的 CNN 架构的性能通过包含在研究论文中的混淆矩阵呈现。

混淆矩阵说明了分类算法在一组测试或评估数据上的性能,其中数据分类(标签)是已知的。

CNN 在受控环境中的实验室生长病毒和从患者身上获得的病毒临床样本上进行了测试。

下面是分类的性能和结果的详细信息。

实验室培养的病毒和受控测试

实验室培养的病毒和控制测试结果

测试了 CNN 对阳性和阴性 IBV(传染性支气管炎病毒)病毒样本进行分类的能力。IBV 是一种影响鸟类的冠状病毒。CNN 能够以 91.4%的准确度对阳性和阴性 IBV 单一病毒颗粒进行分类。

进行的另一项测试是 CNN 区分具有相似结构特性的病毒的能力。用于本次试验的病毒为 IBV 和其他三种流感病毒( UdornX31PR8 株)。

CNN 能够区分来自 IBV 样本的病毒,准确率为 95.5%(乌多恩)94.5%(PR8)。当任务是对病毒 X31 或 Udorn 病毒样本进行分类时,CNN 提供了 68.8%的性能,这两种病毒在结构特性方面非常相似。

非受控环境中的临床病毒样本

一个更可靠的测试突出了 CNN 的性能,那就是对来自病人的新型冠状病毒病毒样本进行分类。病毒样本取自新型冠状病毒病毒检测呈阳性和阴性的患者的咽拭子,以及其他人类冠状病毒株( OC43HKU1NL63 )

CNN 架构在从咽拭子病毒样本收集的数据上被训练和测试。

非受控环境中的临床病毒样本结果

经过训练的 CNN 在阳性和阴性新型冠状病毒之间的分类表现良好,准确率约为 70%,在 hCov 和阴性样本之间的分类准确率为 78%。

当 CNN 的任务是对新型冠状病毒或任何季节性人类冠状病毒的病毒样本进行分类时,分类准确率达到了 73%。

在实验室培养的病毒和临床样本之间观察到的性能准确性的降低归因于临床样本中病毒的复杂性;此外,实验室培养的样品不含会影响病毒样品完整性的外部残留细胞物质。

优势和推广计划

本文中提到的快速测试过程和技术的好处是显而易见的。

至关重要的是,我们作为一个社会,实施的方法,使目前的疫情处于控制之下。

以下是所讨论的快速测试技术提供的一些主要优势:

  • 在 2-5 分钟内提供高准确度的诊断结果。
  • 本文提到的研究中提出的快速新冠肺炎检测方法作为早期诊断工具是有益的,可以通过早期诊断帮助抑制感染的传播。
  • 可以有效区分类似于新型冠状病毒病毒的病毒,这在季节性冠状病毒在患者中更流行的冬季月份中将是有益的属性。
  • 在这种特定的新冠肺炎检测方法中使用的过程可以重新用于检测其他呼吸道病毒。
  • 研究论文中提出的检测技术可以在实验室环境之外使用。因此,我们可以看到这种检测技术在学校、养老院、医院和国际交通枢纽的部署。

就这种 5 分钟新冠肺炎探测技术何时向公众推出的时间框架而言,目前计划成立一家公司,该公司可以在 2021 年初开始产品开发。

值得一提的是一种快速检测技术,这种技术一直处于公共新闻的最前沿,这就是目前在英国健康和美容零售商 Boots 销售的 12 分钟新冠肺炎检测测试。这些测试设备来自 LumiraDx ,最初价格为 120 英镑,随着需求的增加,价格会下降。

[## 使用单粒子成像和深度学习在几分钟内检测和识别病毒

近几十年来,病毒爆发的频率和规模不断增加,集中体现在当前的新冠肺炎…

www.medrxiv.org](https://www.medrxiv.org/content/10.1101/2020.10.13.20212035v3)

我希望这篇文章对你有用。

要联系我或找到更多类似本文的内容,请执行以下操作:

  1. 订阅我的 邮件列表 获取每周简讯
  2. 跟我上
  3. 通过 LinkedIn 联系我

其他文章

[## 我如何使用智能手表传感器来防止面部触摸

一个值得追求的想法?

towardsdatascience.com](/how-im-using-smartwatch-sensors-to-limit-covid-19-infection-51abe04f81f9) [## 你可以通过这些 YouTube 视频了解 GPT 3

通过这些 YouTube 视频,在不到 3 分钟的时间内对 GPT 3 号有一个初步的了解

towardsdatascience.com。](/you-can-understand-gpt-3-with-these-youtube-videos-6a30887c928b)

对 ROC-AUC 指标的零数学直观理解

原文:https://towardsdatascience.com/machine-learning-classification-making-sense-of-the-roc-curve-30a510bba81d?source=collection_archive---------30-----------------------

没有数学或公式。是的图像和动画。

卡伦·艾姆斯利在 Unsplash 上的照片

了解轴

典型的 ROC 图如下所示:

在我们进入任何其他内容之前,我们需要理解轴的含义。不要陷入令人困惑的公式,这里有一个最简单的解释:

  1. x 轴(假阳性率,或 FPR)是模型标记为阳性(假阳性)的实际阴性样本的分数。
  2. y 轴(真阳性率,或 TPR)是模型标记为阳性(真阳性)的实际阳性样本的分数。

请注意两者之间的相似性!本质上,ROC 曲线是真阳性对假阳性曲线,两个轴都是标准化的。

与阈值的关系

每当我们看到一个线图,我们倾向于认为随着时间的线性进展,或一些参数表示在 x 轴上。当我们增加 x 轴上的参数时,线图会前进。思维过程通常是这样的:“对于 x 轴上给定的值,图形给我 y 轴上对应的值”。

但是 ROC 在这方面很微妙——它不是从 FPR 值(x 轴)到 TPR 值(y 轴)的映射,因为你不能真正计算 TPR 作为 FPR 的函数。那么,随着 ROC 曲线远离原点,什么在变化呢?答案是(请击鼓):门槛。

如果我们更深入地研究大多数分类模型,我们会发现它们不只是给一个数据点分配一个标签,而是给一个数据点分配一个分数,然后将该分数与一个阈值进行比较,以决定是将其分类为正面还是负面:

分类模型在幕后使用分数和阈值

因此,给定一个阈值,模型将为每个数据点生成一个分类。对于给定的一组分类,TPR 和 FPR 各有一个值。但是,随着阈值的变化,TPR 和 FPR 都将在 0 到 1 之间变化。这就是为什么我们说阈值随着 ROC 曲线的进展而变化。

极端情况

为了恰当地形象化这一点,让我们从考虑极端情况开始;这将为我们理解 ROC 曲线在其他情况下如何工作提供一个更好的视角。

首先,考虑阈值被设置为最大值的情况。没有比阈值更高的得分,也没有被模型标记为阳性。这是 ROC 曲线位于(0,0)时的情况:

现在考虑另一种极端情况——当阈值处于最小值时。所有事情的得分都高于阈值,并且所有事情都被模型标记为积极的。这是 ROC 曲线位于(1,1)时的情况:

介于两者之间的一切

贯穿这两个极端之间的一切看起来像这样:

随着模型阈值的降低,正面预测的总数将会增加。ROC 图表达了这些阳性预测是如何被分为真阳性和假阳性的。

ROC 曲线的理想特征

现在我们知道了 ROC 曲线代表什么,我们可以开始理解什么会使一个给定的 ROC 曲线“好”或“坏”。

让我们再来看看这些轴:

很明显,我们想要真阳性,不想要假阳性。对于坐标轴,我们想沿着 y 轴向上移动,但不想沿着 x 轴向前移动。然而,ROC 曲线从(0,0)一直到(1,1)…换句话说,无论如何,你都要穿过 x 轴。

所以 ROC 曲线的好坏必然与曲线的形状有关。为了理解什么形状被认为是好的,我们回到阈值图,试图理解什么使分类模型更好。很明显,一个给数据点打分的模型是这样的:

比这样计算数据点的公司更糟糕:

哪一个比这样的数据点更糟糕(理想情况):

如果我们将所有这些与它们的 ROC 曲线进行比较,一个清晰的模式开始显现出来:

如果更多的白点(实际上是正数据点)比黑点(实际上是负数据点)排名更高,ROC 曲线在 x 轴(FPR)上向前移动之前沿 y 轴(TPR)上升。TPR 上升越早,曲线下的面积越大:

这就是为什么您会经常看到 ROC-AUC(ROC-曲线下面积)或 AUROC(ROC 下面积)指标被用来衡量分类算法的性能。

本质上,更好的 ROC 曲线是曲线下具有更大面积的曲线,因为这意味着分类模型对更多正样本的排序高于负样本,即模型具有更好的正负数据点分离(在正确的方向上)。

结论

希望这些动画和解释能让你更直观地理解什么是 ROC 曲线,以及为什么我们选择 ROC 曲线下的面积作为分类算法性能的度量。

机器学习分类器与 Python 的比较

原文:https://towardsdatascience.com/machine-learning-classifiers-comparison-with-python-33149aecdbca?source=collection_archive---------6-----------------------

用于机器学习的 Python

评估和比较分类器性能

凯文·Ku 拍摄的图片可在 Unsplash 获得

机器学习分类器

机器学习分类器是用于在标记数据可用时预测数据点类别的模型(即监督学习)。一些最广泛使用的算法是逻辑回归、朴素贝叶斯、随机梯度下降、k-最近邻、决策树、随机森林和支持向量机。

选择正确的评估者

在解决机器学习问题时,为给定的工作确定正确的估计器是最关键和最困难的部分之一。每个估计值都适用于特定类型的数据和问题。 Scikit-learn ,机器学习最流行的 Python 库之一,提供了下面的图表来指导用户选择最合适的估计器的决策过程。

图片由 scikit-learn 提供scikit-learn.org

绩效评估指标

必须对分类模型进行评估,以确定它们执行特定任务的有效程度。虽然好的分类模型对于预测目的是有用的,但是差的分类模型导致不可靠的结果,因此对于用户是无用的。

绩效评估指标基于以下变量的总数:

  • 真阳性:结果被正确预测为阳性类别
  • 真阴性:结果被正确预测为阴性类别
  • 假阳性:结果被错误地预测为阳性类别
  • 假阴性:结果被错误地预测为阴性类别

其中一个轴是机器学习模型预测的标签,另一个轴是实际标签:

二元分类的混淆矩阵

有四个主要的性能指标用于评估分类模型的有效性:

  • 准确性:测试正确预测两个类别的能力
  • 精度:测试从所有预测的阳性类别中正确检测出阳性类别的能力
  • 回忆(灵敏度):测试从所有实际阳性类别中正确检测出阳性类别的能力
  • F1 得分:精确度和召回率的调和平均值

绩效指标公式

在下面的例子中,让我们评估五种不同分类模型(即逻辑回归、支持向量分类器、决策树、随机森林和高斯朴素贝叶斯分类器)在弗雷明汉心脏研究数据集(一项旨在确定导致心血管疾病的常见因素的研究)上的性能,以确定导致最可靠结果的模型。

下面的 Python 代码将分为五个主要步骤。包含的注释行提供了简短的解释,并指导您完成编码过程。

步骤#1:数据加载

弗雷明汉心脏研究

步骤 2:探索性数据分析

男性/女性比例

根据上面的图,弗雷明汉心脏研究包含更多与女性相关的数据点,而不是男性。

结果计数

上面的图表揭示了弗雷明汉心脏研究是一个严重不平衡的数据集。大多数数据点对应于负面类别(即十年内发展成心血管疾病的低风险)。要解决这个问题,需要进一步的数据平衡。

按性别统计的结果

有意思。尽管与男性相对应的数据点总数较低,但上图表明,男性患心血管疾病的风险高于女性。

步骤 3:数据清理

步骤 4:数据平衡

上图显示,在使用随机欠采样技术平衡数据集后,相同数量的类是相等的。

步骤#5:模型建立和性能评估

最终结果

模型的绩效评估得分表

结果解释

根据上表的结果,支持向量分类器获得了最好的准确度、召回率和 F1 分数,以及第二好的精确度分数,使其成为该数据集最可靠的机器学习分类器。另一方面,可以说决策树和高斯朴素贝叶斯模型具有最差的性能,因此,对于该数据集不是可靠的分类模型。

接下来是什么?

在支持向量分类器被识别为最可靠的机器学习分类器之后,下一步将包括调整其参数,以确定其性能是否可以进一步提高。

值得说明的是,在上述代码中机器学习分类器的实例化期间,它们的参数被设置为默认参数,除了逻辑回归模型中用于实现模型收敛的 max_iter 参数和支持向量分类器中的 dual 参数,因为样本的数量大于特征的数量。

现在轮到你了

在前面的示例中,分类模型是使用整个数据集(即,对应于男性和女性的数据点)构建的,它假设导致心血管疾病的因素对两性具有相同的权重。作为练习编码技能的一种方式,尝试按性别划分数据集,并为每个数据集建立分类模型。使用本文中讨论的评估指标比较它们的性能,并评估是为每种性别建立独立的分类模型更方便,还是为两种性别建立一个公共的分类模型更方便。

总结想法

机器学习和人工智能算法在解决问题和复杂任务方面有许多有用和多样的应用。除了数据科学,它们已经成为学术界和专业人士非常流行的研究趋势,在广泛的领域中出现了新的研究方向。研究人员继续为多种编程语言和软件更新和开发新的编程库和包,以促进这些算法的实现和执行。

Python 代表了一种伟大的免费开源编程语言,能够执行广泛的机器学习、人工智能、数据科学和数据分析任务。它最受欢迎的一些机器学习和深度学习库包括 scikit-learn、TensorFlow、Keras、PyTorch、Pandas 和 NLTK。数据科学家和分析师必须充分利用这些工具来解决现实生活中的复杂问题和任务,从而为组织、客户或研究领域带来附加值。

— —

如果你觉得这篇文章有用,欢迎在GitHub上下载我的个人代码。你也可以直接在 rsalaza4@binghamton.edu 给我发邮件,在LinkedIn上找到我。有兴趣了解工程领域的数据分析、数据科学和机器学习应用的更多信息吗?通过访问我的媒体 个人资料 来探索我以前的文章。感谢阅读。

——罗伯特

机器学习分类器:数据重采样器与 Python 的比较

原文:https://towardsdatascience.com/machine-learning-classifiers-data-resamplers-comparison-906442d04fde?source=collection_archive---------61-----------------------

用于机器学习的 Python

评估和比较重采样技术

图片由杰瑞米·托马斯提供,在 Unsplash

机器学习分类器

机器学习分类器是用于在标记数据可用时预测数据点类别的模型(即监督学习)。一些最广泛使用的算法是逻辑回归、朴素贝叶斯、随机梯度下降、k-最近邻、决策树、随机森林和支持向量机。

绩效评估指标

必须对分类模型进行评估,以确定它们执行特定任务的有效程度。虽然好的分类模型对于预测目的是有用的,但是差的分类模型导致不可靠的结果,因此对于用户是无用的。

绩效评估指标基于以下变量的总数:

  • 真阳性:结果被正确预测为阳性类别
  • 真阴性:结果被正确预测为阴性类别
  • 假阳性:结果被错误地预测为阳性类别
  • 假阴性:结果被错误地预测为阴性类别

其中一个轴是机器学习模型预测的标签,另一个轴是实际标签:

二元分类的混淆矩阵

有四个主要的性能指标用于评估分类模型的有效性:

  • 准确性:测试正确预测两个类别的能力
  • 精度:测试从所有预测的阳性类别中正确检测出阳性类别的能力
  • 回忆(灵敏度):测试从所有实际阳性类别中正确检测出阳性类别的能力
  • F1 得分:精确度和召回率的调和平均值

绩效指标公式

不平衡数据集

不平衡数据集是指不同类别中样本总数变化很大的数据集,导致机器学习分类器偏向样本数较大的类别(即多数类别)。下图说明了使用不同级别的类平衡训练线性 SVC(支持向量分类器)。

图片由 g .勒迈特等人提供,可在 Im balanced-learn . readthedocs . io获取

为了解决这个问题,有两组重采样技术用于平衡数据集:

欠采样技术

欠采样包括减少来自多数类的样本数量,以使其与来自少数类的样本数量相匹配。一些欠采样技术包括:随机欠采样、托梅克链接和压缩最近邻。

欠采样表示

过采样技术

过采样包括增加来自少数类的样本数,使其与来自多数类的样本数相匹配。一些过采样技术包括:随机过采样、SMOTE、SMOTE-NC、边界 SMOTE 和自适应合成。

过采样表示

对于下面的例子,让我们在应用了 11 种不同的重采样技术(随机欠采样、接近缺失 I、接近缺失 II、接近缺失 III、Tomek 链接、浓缩最近邻、SMOTE、边界 SMOTE、SMOTE-NC、自适应合成和随机过采样)以确定导致最可靠结果的技术之后,评估逻辑回归模型在弗雷明汉心脏研究数据集上的性能。

下面的 Python 代码将分为五个主要步骤。包含的注释行提供了简短的解释,并指导您完成编码过程。

步骤#1:数据加载

弗雷明汉心脏研究

步骤 2:探索性数据分析

男性/女性比例

根据上面的图,弗雷明汉心脏研究包含更多与女性相关的数据点,而不是男性。

结果计数

上面的图表揭示了弗雷明汉心脏研究是一个严重不平衡的数据集。大多数数据点对应于负面类别(即十年内发展成心血管疾病的低风险)。要解决这个问题,需要进一步的数据平衡。

按性别统计的结果

有意思。尽管与男性相对应的数据点总数较低,但上图表明,男性患心血管疾病的风险高于女性。

步骤 3:数据清理

步骤 4:不平衡的模型构建和性能评估

模型的性能衡量不平衡数据集中的分数

第 5 步:数据平衡

步骤#6:平衡的模型构建和性能评估

最终结果

模型的性能衡量平衡数据集中的分数

结果解释

根据上表中的结果,为在采样技术下与浓缩最近邻平衡的数据集开发的逻辑回归模型获得了最佳的精确度、召回率和 F1 分数,以及第三好的精确度分数,使其成为该数据集最可靠的模型。

与从为原始不平衡数据集开发的逻辑回归模型中获得的绩效指标得分相比,为平衡数据集开发的模型的绩效指标得分有所提高。精确度分数从 0.6135 增加到 0.6596,召回分数从 0.0777 增加到 0.7929,F1 分数从 0.1362 增加到 0.7188。然而,准确度分数从 0.8512 下降到 0.6260。根据上表中的结果,没有可提高模型精度得分的重采样技术,因为最高的一个是通过随机欠采样技术获得的值 0.6516。

接下来是什么?

在浓缩最近邻被识别为导致最可靠的机器学习模型的最佳重采样技术之后,下一步将包括调整其参数以确定其性能是否可以进一步提高。

值得说明的是,在机器学习分类器的实例化和上面代码中的重采样技术期间,它们的参数被设置为默认参数,除了逻辑回归模型中的 max_iter 参数用于实现模型收敛,以及一些重采样函数中的 random_state 参数用于可复制性。

现在轮到你了

在前面的示例中,仅开发了一个机器学习分类器(即逻辑回归),并使用多种重新采样技术进行了评估。然而,其他机器学习分类器(例如决策树、随机森林、支持向量分类器、高斯朴素贝叶斯分类器)的发展可能会导致更好的结果。尝试用其他机器学习分类器重复这个实验,以确定对于这个数据集,是否有更好的分类器和重采样技术的组合。

同样,机器学习模型是使用整个数据集(即对应于男性和女性的数据点)建立的,它假设导致心血管疾病的因素对两性具有相同的权重。作为练习编码技能的一种方式,尝试按性别划分数据集,并为每个数据集建立分类模型。使用本文中讨论的评估指标比较它们的性能,并评估是为每种性别建立独立的分类模型更方便,还是为两种性别建立一个公共的分类模型更方便。

总结想法

机器学习和人工智能算法在解决问题和复杂任务方面有许多有用和多样的应用。除了数据科学,它们已经成为学术界和专业人士非常流行的研究趋势,在广泛的领域中出现了新的研究方向。研究人员继续为多种编程语言和软件更新和开发新的编程库和包,以促进这些算法的实现和执行。

处理不平衡数据集并选择最合适的重采样技术是数据科学项目中的重要一步。适当的重采样技术选择可以导致更可靠的机器学习模型,而不适当的选择可能导致机器学习模型的偏差,不能预测准确的结果。本文展示了一种为给定数据集决定最佳重采样技术的方法。

Python 代表了一种伟大的免费开源编程语言,能够执行广泛的机器学习、人工智能、数据科学和数据分析任务。它最受欢迎的一些机器学习和深度学习库包括 scikit-learn、TensorFlow、Keras、PyTorch、Pandas 和 NLTK。数据科学家和分析师必须充分利用这些工具来解决现实生活中的复杂问题和任务,从而为组织、客户或研究领域带来附加值。

如果你觉得这篇文章有用,欢迎在 GitHub 上下载我的个人代码。你也可以直接在 rsalaza4@binghamton.edu 给我发邮件,在LinkedIn上找到我。有兴趣了解工程领域的数据分析、数据科学和机器学习应用的更多信息吗?通过访问我的媒体 简介 来探索我以前的文章。感谢阅读。

——罗伯特

银行营销活动:成本预测-EDA(I)

原文:https://towardsdatascience.com/machine-learning-costs-prediction-of-a-marketing-campaign-exploratory-data-analysis-part-i-758b8f0ff5d4?source=collection_archive---------16-----------------------

照片由萨姆森Unsplash 上拍摄

预测营销活动最佳目标候选人的数据科学方法

探索性数据分析—gon alo GUI mares Gomes

关于项目

该数据集存储了 2008 年至 2015 年葡萄牙一家银行的营销团队为吸引客户认购定期存款而实施的营销销售操作(电话营销)的信息,将结果分为“是”和“否”两个二进制分类变量。

在那之前,我们的策略是不加区别地争取最大数量的客户,并试图通过电话向他们销售金融产品。然而,这种方法除了花费许多资源之外,对于许多被这种类型的行为困扰的客户来说也是非常不舒服的。

为了确定营销活动的成本,营销团队得出结论:

  • 对于每个被确定为优秀候选人并因此被定义为目标但没有认购存款的客户,银行的成本为 500 欧元
  • 对于每个被确定为不良候选人并被排除在目标之外但会认购产品的客户,银行的成本为 2.000 欧元

机器学习问题和目标

我们面临一个二元分类问题。目标是训练最好的机器学习模型,该模型应该能够预测作为目标的候选人的最佳数量,以便将成本降至最低,并将效率最大化。

项目结构

该项目分为三类:

  1. EDA: 探索性数据分析
  2. 数据争论:清理和特征选择
  3. 机器学习:预测建模

在本文中,我将只关注第一部分,探索性数据分析(EDA)。

绩效指标

用于评估的指标是总成本,因为目标是确定活动的最低成本。

你可以在这里找到这个项目的全部代码。
可点击此处下载“银行 _ 营销 _ 营销活动. csv”数据集。

丹尼尔·麦金尼斯在 Unsplash 上的照片

首先要做的是导入所需的库和依赖项。

# import librariesimport pandas as pd
from pandas.plotting import table
import numpy as np
import seaborn as sns
import scipy.stats
import matplotlib.pyplot as plt
%matplotlib inline

加载数据集(我将把它指定为“df”)并检查第一行。

df = pd.read_csv('bank_marketing_campaign.csv') # load the datasetdf.head() # print the data

head()是一种用于显示数据帧中前‘n’行的方法,而tail() 用于显示最后‘n’行

标有“y”的因变量或目标(在右边最后一列)是一个二元范畴变量。让我们从将它转换成二进制数字开始,如果客户端订阅,它将假定值为 1,否则为 0。新列“目标”将替换“y”(将被删除)。

# converting into a binary numeric variabledf['target'] = df.apply(lambda row: 1 if row["y"] == "yes" else 0, axis=1)
df.drop(["y"],axis=1,inplace=True)

我还将重命名一些列,用下划线代替点。

# Renaming some columns for better typing and calling variablesdf.rename(columns={"emp.var.rate":"emp_var_rate", "cons.price.idx":"cons_price_idx", "cons.conf.idx":"cons_conf_idx", "nr.employed":"nr_employed"}, inplace=True)df.head()

将二进制类别目标转换为二进制数值变量,并重命名一些列

数据集的基本信息

  • 有多少功能可用?
  • 数据集中有多少客户端?
  • 有重复的记录吗?
  • 有多少客户订阅了定期存款,有多少没有?
# Printing number of observations, variables including the target, and duplicate samplesprint(f"Number of clients: {df.shape[0]}")
print(f"Number of variables: {df.shape[1]} incl. target")
print(f"Number of duplicate entries: {df.duplicated().sum()}")

客户端数量:41188
变量数量:16 包括目标
重复条目数量:5853

我必须得出结论,这些明显重复的样本实际上来自具有相同特征的人。

# How many clients have subscribed and how many didn't?absolut = df.target.value_counts().to_frame().rename(columns={"target":"clients"})
percent = (df.target.value_counts(normalize=True) *100).to_frame().rename(columns={"target":"%"})
df_bal = pd.concat([absolut,percent],axis=1).round(decimals=2)

print(f"[0] Number of clients that haven't subscribed the term deposit: {df.target.value_counts()[0]}")
print(f"[1] Number of clients that have subscribed the term deposit: {df.target.value_counts()[1]}")

display(df_bal)absolut.plot(kind='pie', subplots=True, autopct='%1.2f%%', 
             explode= (0.05, 0.05), startangle=80, 
             legend=False, fontsize=12, figsize=(14,6));

数据集高度不平衡:

[0]未认购定期存款客户数:36548
[1]已认购定期存款客户数:4640

数据集不平衡,0:“否”大约是 1:“是”的八倍

探索性数据分析

现在让我们检查变量类型、缺失值、相关性以及显示统计描述。

# Type of variables
df.dtypes.sort_values(ascending=True)age                 int64
pdays               int64
previous            int64
target              int64
emp_var_rate       float64
cons_price_idx     float64
cons_conf_idx      float64
euribor3m          float64
nr_employed        float64
job                object
marital            object
education          object
default            object
housing            object
loan               object
poutcome           object
dtype: object# Counting variables by type
df.dtypes.value_counts(ascending=True)int64      4
float64     5
object     7
dtype: int64# Detecting missing values
print(f"Are there any missing values? {df.isnull().values.any()}")Are there any missing values? False# Visualization of correlations (heatmap)
mask = np.triu(df.corr(), 1)
plt.figure(figsize=(19, 9))
sns.heatmap(df.corr(), annot=True, vmax=1, vmin = -1, square=True, cmap='BrBG', mask=mask);

Seaborn 热图(皮尔逊方法)

变量'emp_var_rate''nr_employed''euribor3m'非常多余。'nr_employed'与目标最相关。

为了对目前的数据有一个清晰和更准确的认识,我将展示一般的统计数据。

# General stats of numeric variables adding 'variance' valuesdescribe = df.describe()
describe.append(pd.Series(df.var(), name='variance'))

数字变量的一般统计

年龄:最小的客户 17 岁,最大的客户 98 岁,中位数为 38 岁,而平均年龄为 40 岁。分布向左倾斜。这可能表明异常值的存在。

Pdays :从上一次活动中最后一次联系客户后经过的天数。大多数客户都有 999 号码,这表明大多数人没有与银行联系,也没有被银行联系。那些 999 被认为是“超出范围”的值。

上一次:在本次活动之前,每个客户的联系次数。绝大多数人从未被联系过。

Emp_var_rate :就业变动率。在此期间,指数从[-3.4,1.4]不等。

Cons_price_idx :居民消费价格指数从【92.2,94.8】不等。

Cons_conf_idx :该期间消费者信心水平始终保持负值,变动幅度为[-51,-27]。这些负值可能是因为在记录数据的同一时期,由于全球金融危机,经济衰退严重影响了葡萄牙。

Euribor3m :在分析期间,Euribor 利率出现了巨大的变化【5%至 0.6%】。这种波动加上上文验证的负面信心加强了数据提供危机时期信息的假设。

活动期间,就业人数在 200 人左右。

df.describe(include=['object']) # General stats of categoric variables

类别变量的一般统计

工作:有 12 种类型的工作记录,其中管理角色是最常见的,几乎占所有客户端的 10.5k。

婚姻:大部分客户已婚,有近 25k 记录。

学历:12k 以上的人有大学学历。

违约:在所有 41.188 个客户中,32.588 个没有任何信用违约。

住房:几乎一半的客户都有住房贷款。

贷款:几乎 34k 客户没有任何个人贷款。

没有任何关于之前营销活动结果的信息。

所有变量的统计描述

为了能够对数字和类别变量进行分析,我将首先按照变量的类型分别定义和创建一个特性列表。

# creating indexescat_features = list(df.select_dtypes('object').columns)
int_features = list(df.select_dtypes('int64').columns)
float_features = list(df.select_dtypes('float64').columns)
num_features = int_features+float_features

EDA 过程的下一步包括提供数据集中所有变量的完整描述,从数字变量开始。

# Visualization of the numeric distributiondf[num_features].hist(figsize=(10,8), bins=25, xlabelsize=8, ylabelsize=8, alpha=0.9, grid=False)
plt.tight_layout();

数值分布的可视化

**Age**

# creating a dataframe
stats_age = {'Designation': ['Value'],
             'Variable': 'age',
             'Description': 'clients` age',
             'Type of variable': df.age.dtype,
             'Type of distribution': 'continuous',
             'Total observations': df.age.shape[0],
             'Missing values': df.age.isnull().sum(),
             'Unique values': df.age.nunique(),
             'Min': df.age.min(),
             '25%': int(df.age.quantile(q=[.25]).iloc[-1]),
             'Median': df.age.median(),
             '75%': int(df.age.quantile(q=[.75]).iloc[-1]),
             'Max': df.age.max(),
             'Mean': df.age.mean(),
             'Std dev': df.age.std(),
             'Variance': df.age.var(),
             'Skewness': scipy.stats.skew(df.age),
             'Kurtosis': scipy.stats.kurtosis(df.age)
            }st_age = pd.DataFrame(stats_age, columns = ['Designation',
                                          'Variable',
                                          'Description',
                                          'Type of variable',
                                          'Type of distribution',
                                          'Total observations',
                                          'Missing values',
                                          'Unique values',
                                          'Min',
                                          '25%',
                                          'Median',
                                          '75%',
                                          'Max',
                                          'Mean',
                                          'Std dev',
                                          'Variance',
                                          'Skewness',
                                          'Kurtosis'
                                             ])st_age.set_index("Designation", inplace=True)results = st_age.T # transposing the dataframe
resultsT = st_age
display(results)

由数据帧呈现的完整描述

非常重要的一点是,要将分布和离散可视化,如下所示。

# Visualization of 'age'
# creating a distribution graph and bloxplot combinedage = df.age
np.array(age).mean()
np.median(age)f, (ax_box, ax_hist) = plt.subplots(2, sharex=True, gridspec_kw= {"height_ratios": (0.5, 2)})mean=np.array(age).mean()
median=np.median(age)sns.boxplot(age, ax=ax_box)
ax_box.axvline(mean, color='r', linestyle='--')
ax_box.axvline(median, color='g', linestyle='-')sns.distplot(age, ax=ax_hist)
ax_hist.axvline(mean, color='r', linestyle='--')
ax_hist.axvline(median, color='g', linestyle='-')plt.legend({'Mean':mean,'Median':median})
ax_box.set(xlabel='')plt.show()

数据的分布和分散

百分点计算:1%,5%,95%,99%

display(df.age.quantile(q=[.01, .05, .95, .99]))0.01    23.0
0.05    26.0
0.95    58.0
0.99    71.0
Name: age, dtype: float64

为了能够根据目标可视化变量,我们必须首先定义两个组:必须订阅的客户端和没有订阅的客户端(让我们分别称它们为“好”和“坏”客户端)。

# Visualization variable vs. targetage_0 = df[df.target == 0].iloc[:,:1]
age_1 = df[df.target == 1].iloc[:,:1]a = np.array(age_0)
b = np.array(age_1)np.warnings.filterwarnings('ignore')plt.hist(a, bins=40, density=True, color="r", alpha = 0.6, label='Bad client')
plt.hist(b, bins=40, density=True, color="g", alpha = 0.6, label='Good client')plt.legend(loc='upper right')
plt.title('age', fontsize=14)
plt.xlabel('age')
plt.ylabel('absolute frequency');

相对于目标的可变“年龄”

从比例上看,年龄在 30 岁以下和 60 岁以上的用户比 30 岁至 60 岁的用户多。

让我们更进一步,使用cut 方法,按照年龄将订阅的客户分为三个类别:年轻(<=30), adult (> 30 到<=60), and senior (> 60)。

df['age_bins'] = pd.cut(df['age'], bins = [df['age'].min(), 30, 60, df['age'].max()],labels=['Young', 'Adult', 'Senior'])​group_age_target = df.groupby(['age_bins'])['target'].mean().multiply(100)display(group_age_target)group_age_target.plot.barh()
plt.xlabel('Subscribed [%]');

使用 cut()方法对订阅客户端进行分组

  • 45.5%的老年人(+60 岁)认购定期存款。
  • 不到十分之一的成年人(> 30 和<=60 years old) subscribed.
  • Young people were the 2nd group that subscribed to the deposit corresponding to 1/6 of all young people.
  • Senior subscribers alone were almost as much as Young and Adults subscribers, respectively, all together.

Following the previous structure, I’ll be only displaying visuals for a greater understanding. The full code can be seen 此处)。

由数据帧呈现的完整描述

百分点计算:1%,5%,95%,99%

display(df.pdays.quantile(q=[.01, .05, .95, .99]))0.01      3.0
0.05    999.0
0.95    999.0
0.99    999.0
Name: pdays, dtype: float64

接下来,可视化数据的分布以及相对于目标的变量。

左边是分布,右边是相对于目标的变量

仅考虑那些必须订阅的客户,让我们来数一数从上一次活动联系后过去了多少天。大多数人会在第 6 天和 7 到 8 天内做出反应,你可以在下面观察。

dummy = df.loc[(df['pdays']!=999) & (df['target'] == 1), 'pdays']
print('Median: {:.2}'.format(dummy.median()))
dummy.hist().grid(False)
plt.title('Histogram')
plt.xlabel('Couting days after contact \n for those who subscribed')

**Previous**

由数据帧呈现的完整描述

百分点计算:1%,5%,95%,99%

display(df.previous.quantile(q=[.01, .05, .95, .99]))0.01    0.0
0.05    0.0
0.95    1.0
0.99    2.0
Name: previous, dtype: float64

下图显示,之前联系的客户以高得多的利率认购了定期存款。

仅考虑从未联系过的客户,只有 10%订阅,而之前联系过两次或更多的客户,活动的成功率增加到 45%以上。

group = df.groupby(['previous'])['target'].mean().multiply(100)
group.plot.barh()
plt.xlabel('Subscribed [%]');print('How many people got previously contacted? {}'.format(df.loc[df['previous']!=0].shape[0]))print('How many people got contacted 7 times? {}'.format(df.loc[df['previous']==7, 'previous'].count()))print('How many people got previously contacted with success? {}'.format(df.poutcome.value_counts()[1]))print('How many people got previously contacted without success? {}'.format(df.poutcome.value_counts()[2]))
  • 之前联系了多少人?5625
  • 有多少人被联系了 7 次?一
  • 有多少人以前接触过成功?4525
  • 之前有多少人联系不上?1373

索引变量

数据集中有 4 个宏观评级变量或经济指标:‘EMP _ var _ rate’‘cons _ price _ idx’‘cons _ conf _ idx’‘euribor 3m’

让我们进一步挖掘,简要调查它们的相关性,并检查这些指标之间以及指标之间是否有任何趋势或模式。为此,我必须创建一个仅包含这些特定变量的列表,并并排显示它们(pairplot 方法)。

注意:我们将在这个项目的稍后部分(但是在另一篇文章中)回到数据争论:清理和特性工程一节中的相关性主题。

# creating a list
idx_list = ["cons_price_idx", "cons_conf_idx", "euribor3m", "emp_var_rate", "target"]df[idx_list].corr()

我们可以看到,euribor3mcons_price_idxemp_Var_rate高度相关。接下来,使用 pairplot 方法可视化指数变量之间的相关性。

sns.pairplot(df[idx_list], hue="target")
plt.show()

指数变量相关性的可视化(pairplot)

散点图中我们可以观察到什么?请记住,(蓝色)0 =否,(橙色)1 =是

  • euribor3memp_var_rate.正变化时增加
  • cons_conf_idxcons_price_idxemp_var_rate线性变化:物价和就业率越高,信心指数越低。
  • emp_var_rate(就业率)增加cons_price_idx(物价指数)也增加。

活动的产出会受到指数变量的影响吗?答案来自对分布图的观察。

  • euribor3m越低,订阅数越高。
  • cons_price_idx(消费者价格指数)增加时,客户订阅会产生强烈的负面反应。
  • emp_var_rate(就业率)为负时,对该活动的积极响应更高。

Nr _ 已就业

由数据帧呈现的完整描述

百分点计算:1%,5%,95%,99%

display(df.nr_employed.quantile(q=[.01, .05, .95, .99]))0.01    4963.6
0.05    5017.5
0.95    5228.1
0.99    5228.1
Name: nr_employed, dtype: float64

从分析中,我们知道被联系的人有更高的订阅率。上面的直方图显示,第一次联系专门针对已知客户,这导致了一个雇佣人数较少、效率更高的活动。

让我们继续讨论分类变量的描述。

职位

“作业”有 12 个唯一值。有一个标记为“unknown”的类被认为是缺失值(我暂时不会对缺失值做任何处理)。

stats_job = {'Designation': ['Value'],
            'Variable': 'job',
            'Description': 'type of job',
            'Type of variable': df.job.dtype,
            'Total observations': df.job.shape[0],
            'Unique values': df.job.nunique(),
           }st_job = pd.DataFrame(stats_job, columns = ['Designation',
                                      'Variable',
                                      'Description',
                                      'Type of variable',
                                      'Total observations',
                                      'Unique values',
                                          ])st_job.set_index("Designation", inplace=True)​results = st_job.T
resultsT = st_job
display(results)print(f"List of unique values: {df.job.unique()}")

由数据帧呈现的完整描述

客户的工作是如何分配的?

data_count = df['job'].value_counts().plot(kind='bar', figsize=(6,4), fontsize=12)
plt.title('Categorical variable \'job\'', fontsize=12)
plt.xlabel('Jobs')
plt.ylabel('Absolute frequency');

下面,我们可以找到绝对值(工作的总和)和它们的比例。5 个最常见的作业足以代表 80%的数据。

num_obs = df.job.value_counts()
num_o = pd.DataFrame(num_obs)
num_o.rename(columns={"job":"Freq abs"}, inplace=True)
num_o_pc = (df.job.value_counts(normalize=True) * 100).round(decimals=2)
num_obs_pc = pd.DataFrame(num_o_pc)
num_obs_pc.rename(columns={"job":"percent %"}, inplace=True)
n_obs = pd.concat([num_o,num_obs_pc], axis=1)display(n_obs)

job_0 = df[df.target == 0].iloc[:,1:2]
job_1 = df[df.target == 1].iloc[:,1:2]a = np.array(job_0)
b = np.array(job_1)np.warnings.filterwarnings('ignore')plt.hist(a, bins=40, color="r", alpha = 0.8, label='Bad client', align="left")
plt.hist(b, bins=40, color="g", alpha = 0.8, label='Good client', align="right")plt.legend(loc='upper right')
plt.title('job', fontsize=12)
plt.xlabel('Professional ocupation')
plt.xticks(rotation='vertical')
plt.ylabel('Absolute frequency');

这些课程是“管理”、“蓝领”、“技术人员”、“管理人员”和“服务人员”是大多数客户必须订阅的工作,但就比例而言,“学生”和“退休人员”是最具代表性的。

下面我们看到“退休”和“女佣”是最老的客户,也是比其他任何一个阶层接受订阅更多的客户。

type_pivot = df.pivot_table(
    columns="target",
    index="job",
    values="age", aggfunc=np.mean)type_pivot.sort_values(by=["job"], ascending=True).plot(kind="bar", title=("Type of customer by professional occupation and age"), figsize=(6,4), fontsize = 12);

婚姻的

由数据帧呈现的完整描述

“婚姻”有 4 个独特的价值。如下图所示,图表显示,占主导地位的阶层是 61%的“已婚”人士,而“离婚”客户占所有客户的 11%。

# pie chart
df['marital'].value_counts(dropna=False).plot(kind='pie', figsize=(14,9), explode = (0.01, 0.01, 0.01, 0.01), autopct='%1.1f%%', startangle=120);# table
marital_obs = df.marital.value_counts()
marital_o = pd.DataFrame(marital_obs)
marital_o.rename(columns={"marital":"Freq abs"}, inplace=True)
marital_o_pc = (df.marital.value_counts(normalize=True) *100).round(decimals=2)
marital_obs_pc = pd.DataFrame(marital_o_pc)
marital_obs_pc.rename(columns={"marital":"percent %"}, inplace=True)
marital_obs = pd.concat([marital_o,marital_obs_pc], axis=1)
marital_obs

按类别观察

教育

“教育”有 8 个独特的价值。前 4 个教育水平对应 80%的数据。拥有 4 年基础教育或不识字的客户年龄最大,容易订购该产品。

默认

有了 3 个唯一的值,类“yes”就没有意义,变量没有表达,完全不平衡。

房屋

该变量有 3 个唯一值,其中“未知”被解释为缺失值,代表 2%的观察值。“是”和“否”的比例非常接近,可能会降低其预测能力。

贷款

虽然,一般来说,“贷款”显示了大量的非用户,这个变量与“住房”有一些相似之处,在某种意义上,按比例,“是”和“否”是非常均匀的。这又一次降低了它的预测能力。

噘嘴

有趣的事实:在之前成功的促销活动中接触过的客户中,这次大多数都订阅了。

最常见的类别有哪些?

详细的分析给了我们大量关于数据、客户和变量行为的信息。我们来做一个概述。

n = len(cat_features)
i=1
plt.figure(figsize=(16,14))for feature in df[cat_features]:
plt.subplot(round(n/2),round(n/3), i)
df[feature].value_counts().plot.bar()
plt.xticks(rotation=90)
plt.title(feature)
i+=1plt.tight_layout();

最常见:

  • 工作:行政
  • 婚姻状况:已婚
  • 教育:大学学位
  • 违约信用:否
  • 住房:是的,但是没有住房贷款是非常接近的
  • 贷款:没有
  • poutcome:没有参加以前的活动

请注意,除了“poutcome”变量之外,所有特性都包含“未知”类别。

这些类别如何影响目标变量?

n = len(cat_features)
i=1
plt.figure(figsize=(16,14))for feature in df[cat_features]:
plt.subplot(round(n/2),round(n/3), i)
df.groupby([feature])['target'].mean().multiply(100).plot.barh()
plt.xlabel('Subscribed [%]')
plt.title(feature)
i+=1plt.tight_layout();

观察:

  • “学生”和“退休人员”的订阅比例最高(> 25%),而“蓝领”和“服务人员”的订阅比例最低。
  • “文盲”的用户比例最高(> 20%),另一方面,“基本 9y”、“基本 6y”和“基本 4y”的用户比例最低。
  • 有信用违约的人没有认购。
  • 之前联系过其他活动的人中有超过 60%的人进行了订阅。
  • 婚姻状况、有无贷款和住房对认购率没有太大影响。

结论

我一直专注于如何开始一个机器学习项目,从最重要的部分开始,让我们超越数据,探索性数据分析。这是一个非常重要的程序,因为如果你没有深刻理解你将要处理的数据,它将会是一片混乱。

在下一篇文章(数据清理和特征选择)中,我将进行特征工程和特征选择,清理数据集,处理我们可能会发现的异常以及插补和转换。

在最后一部分和第三篇文章(机器学习:预测建模)中,我们将训练一些机器学习模型,以便能够选择最佳模型,并找出预测营销活动最小成本的最重要特征。

  • 你可以在这里找到这个项目的全部代码。

查看您可能也会喜欢的其他文章:

[## 描述性统计:期望与现实(探索性数据分析——EDA)

一种简单的描述性统计方法来总结集中趋势的措施和传播的措施

towardsdatascience.com](/descriptive-statistics-expectations-vs-reality-exploratory-data-analysis-eda-8336b1d0c60b) [## 熊猫变得容易(指南— I)

有许多最常用的函数和方法的例子

towardsdatascience.com](/pandas-made-easy-the-guide-i-81834f075893) [## 营销活动的成本预测(数据清理和特征选择——第二部分)

预测营销活动最佳目标候选人的数据科学方法

towardsdatascience.com](/costs-prediction-of-a-marketing-campaign-data-cleaning-feature-selection-part-ii-6aa5298909b5)

就是这样!我希望你喜欢读这篇文章,就像我喜欢写它一样。

联系人

好的阅读,伟大的编码!

机器学习:模型构建的数据洞察

原文:https://towardsdatascience.com/machine-learning-data-insights-for-model-building-b6bdea0ac092?source=collection_archive---------30-----------------------

一种数据驱动的增量式机器学习模型构建方法

在这篇文章中,我将以最简单的方式,展示一个人如何以一种递增的激情来解决一个问题。这种方法可以解释为数据驱动的方法,因为我们将依赖数据本身所寻求的信息来做出一些决策。该数据集将包含 2014 年 5 月至 2015 年 5 月期间西雅图出售的房屋价格。在本文中,我们将尝试找出价格和其他参数之间的关系。

获取和观察数据

数据可以来自任何来源,然而,对于这篇特定的文章,我将使用来自 Kaggle 的数据(在公共领域下可用)。我们的数据会像这样。

我们数据集中的几列

这个数据直接从 描述熊猫 的样子;

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 21613 entries, 0 to 21612
Data columns (total 21 columns):
id               21613 non-null int64
date             21613 non-null object
price            21613 non-null float64
bedrooms         21613 non-null int64
bathrooms        21613 non-null float64
sqft_living      21613 non-null int64
sqft_lot         21613 non-null int64
floors           21613 non-null float64
waterfront       21613 non-null int64
view             21613 non-null int64
condition        21613 non-null int64
grade            21613 non-null int64
sqft_above       21613 non-null int64
sqft_basement    21613 non-null int64
yr_built         21613 non-null int64
yr_renovated     21613 non-null int64
zipcode          21613 non-null int64
lat              21613 non-null float64
long             21613 non-null float64
sqft_living15    21613 non-null int64
sqft_lot15       21613 non-null int64
dtypes: float64(5), int64(15), object(1)
memory usage: 3.5+ MB

分析数据

既然我们已经找到了数据集中的属性(或要素),我们可以绘制图表来查看可能分布的属性数量。一种方法是为每个属性绘制直方图。

直方图

查看一些属性的直方图,我们可以看到它们是分布的。事实上,这表示属性具有变化的值,从而导致预测属性(价格)的变化。为了看到我们将看到的相关性。俗称 皮尔逊相关系数

相关

我们可以看到 价格 多少会随着一套房子里几个地方的 号卧室卫生间平方英尺数字 而有所不同。这为我们提供了一个线索,因为这些属性作为我们模型的输入可能实际上是有意义的。请注意,我们是基于我们的数据而不是直觉做出这一决定的。很明显,价格会随着建筑面积的变化而变化。

您可能已经注意到,在我们的数据中,我们也给出了位置。我们不妨使用它们来看看位置作为输入是否有意义。对于该任务,我们可以将价格可视化为西雅图城市地图上的热图。

不同地点的价格

在上面的图中,价格以价格递增的顺序用蓝色到红色标出。虽然不是很明显,但是每个分散点的比例描述了房子覆盖的正方形区域。仅通过观察地块的颜色,我们可以说价格分布没有受到地理位置的显著影响(尽管在滨水区附近看到昂贵的房子是有意义的)。这让我们摆脱了位置信息,因为它不是决定价格的主要因素。

预处理数据

至于预处理步骤,我们对数据集进行标准化和缩放,使得每个属性都表示为范围 [-1,1] 内的一个数字。这对于使用神经网络训练模型非常有帮助。使用 sci-kit-learn 库本身可以很容易地逆转缩放转换。

建立模型

我尝试了几种使用均方根误差(RMS) 进行评估的模型。这是因为选择正确模型的决定可以通过选择报告最小 RMS 误差的模型来决定。

回归

回归几乎总是分析的首选。这是因为它能够为这种关系提供可靠的数学表达式。然而,在这个实验中,我的均方根误差为 0.71。虽然这个值可能没有意义,但是我们确实可以将这个值与其他模型进行比较。这里我使用了线性回归,它假设标签值和特征之间存在线性关系。

决策图表

决策树被训练为使用一个被遍历以估计目标值的树来挑选值。观察到的均方根误差为 0.87。这意味着模型在训练数据集中训练得太多了。我们称此为 过拟合 。这可以通过再次运行以预测返回 0.03 RMS 误差的训练数据集来确认。

随机森林

这可以被认为是对我们模型的改进。这是因为在随机森林中,随机的一组树被收集起来用于决策。树/估计器的数量可以预先设定。使用 100 个估值器得到的均方根误差为 0.68。我们对回归模型做了一点点改进。

人工神经网络

使用神经网络可以被认为是决策树的图形版本。然而,在神经网络中,我们将调整权重来估计最终输出。如果你有兴趣了解一些神经网络的基础知识,你可以阅读我以前的文章。

[## 神经网络导论

神经网络基础

towardsdatascience.com](/introduction-to-neural-networks-ead8ec1dc4dd)

我使用了一个非常简单的带有 Keras functional API 的架构。

i = tf.keras.layers.Input(8)
ix = tf.keras.layers.Dense(16, activation='relu')(i)
z = tf.keras.layers.Dense(1)(ix)model = tf.keras.Model(i, z)
model.compile(loss='mse', optimizer='sgd', metrics=['mse'])
model.summary()
tf.keras.utils.plot_model(model)

然而,我能够实现 0.64 的最低均方根误差。

结束语

  • 重要的是先观察数据,而不是在整个数据集上尝试几种方法
  • 有人可能会建议使用特征提取技术,如 PCA 或邻居嵌入。然而,具有除了真正相关的特征之外的特征可能会增加不必要的噪声,导致过度拟合。
  • 虽然我在这篇文章中没有发现,最近邻回归可能表现良好。这是因为我们打算预测的数据很可能在训练数据的闭合范围内。

我相信这篇文章将有助于人们从可视化数据开始,并使用这些见解建立一个适当的机器学习模型。

感谢阅读。完整的 jupyter 笔记本附后。

干杯!!

使用 Python 进行机器学习部署

原文:https://towardsdatascience.com/machine-learning-deployment-with-python-e64a37c3155a?source=collection_archive---------58-----------------------

鸣谢:L.J. Stroemsdoerfer(无艺术家)

机器学习部署绝对是现在的热门话题。我正准备用时下最热门的模因来支持我的第一句话,然而,我觉得业内的每个人都同意我的观点。有许多很酷的方法来部署和操作 ML 模型。然而,他们大多引入新的工具,使用他们自己的生态系统。这增加了一层新的复杂性,最终可能会产生锁定效应,因为您需要调整代码以最佳地适应平台。

开源概念,比如 Docker 和 Kubernetes 在这个问题上给予了更多的自由,但是,使用起来非常复杂。因此,我构建了一个 Python 库,允许您在 Kubernetes 上专业化、测试和部署您的模型,但是您不必为此而离开 Python。听起来好得难以置信?好吧,让我们看看你是怎么想的。

生产化图书馆

除了这个糟糕的包名——建议是非常受欢迎的——这个包允许你做一些漂亮的事情来简化和加速你的部署体验。

我们先来看看名字朗朗上口的库是做什么的。

它是做什么的?

简单回答:它允许你在不离开 Python 的情况下容器化你的 ML 模型。最重要的是,它在您的机器上构建一个本地 Kubernetes 集群来测试容器化的模型是否工作正常。如果你在想,等等,我没有本地的 Kubernetes 集群,不要担心,我内置了一些函数来处理这个问题。让我们仔细看看。

要开始您的生产化之旅,您可以首先设置您的本地“工作台”,我称之为“工作台”。这是一个小型集群,带有 Docker 注册表,运行在您机器上的 VM 中。任何以前做过这种噱头的人都知道,这样做有点烦人。使用 productionize,这是两行 Python 代码。

生产化的工作流。

一旦这个“工作台”开始运行,productionize 库就需要一个已经内置在 API 结构中的 ML 模型。为此,您可以使用 Flask 等工具,也可以使用其他工具。然而,我肯定会推荐 Flask,因为我真的很喜欢它的轻量级方法。

有了几行 Python 代码,您就可以将 API 容器化,并将其部署到本地工作台中进行测试。如果一切正常,那么您可以将容器推送到您可能喜欢的任何 Kubernetes 集群。那么,让我们来看看代码。

你怎么能这样做?

首先,您需要安装托管在 PyPi 上的库。我目前不支持康达,请原谅我。

之后,就可以导入库了。请注意,该库目前不支持 Jupyter 笔记本电脑,因为我没有使用 Jupyter 内核来设置虚拟机,Minikube 集群和所有其他细节组件。

该库包含两个主要的类。第一个是workbench()类,它负责在您的机器上完成所有这些令人惊奇的事情所需的工具。第二个是product()类,它处理你的 API 和它的容器化。

让我们从设置工作台开始。workbench()类将为你安装、管理和卸载 Docker、VirtualBox、Kubectl 和 Minikube。首先,我们初始化这个类。这将检查您的本地机器上的上述组件,并标记那些要安装的组件。

现在,我们可以安装缺少的组件,并对它们进行配置,使它们能够很好地相互协作。在接下来的步骤中,您可能需要输入您的 sudo 密码。

如果这一步出错,我为此添加了一个调试方法。假设 Minikube 安装失败,您可以运行:

一旦设置步骤完成,您就可以启动工作台,这实际上启动了您机器上的 Minikube 集群。

接下来,您应该在工作台上创建一个项目,这会创建一个 Kubernetes 名称空间。我建议你这样做,这会在你的集群上产生一些秩序感。

如果您厌倦了您的工作台,您可以使用stop_cluster()方法轻松地停止集群,甚至可以使用uninstall()方法干净地删除所有不需要的组件。

现在让我们继续学习product()课程。这个类将您的 ML API 转换成一个容器,并将其部署到工作台。首先,我们必须初始化这个类:

您现在可以准备部署了,这实际上将创建一个 Dockerfile 文件。我添加了这个中间步骤,以便您可以根据需要编辑 Dockerfile 文件。

无论您是否编辑了 docker 文件,现在都可以使用deploy()方法将它部署到本地工作台。

这将在 Minikube 注册表上创建 Docker 映像,使用您的容器部署一个 pod,并将服务公开给外部。在deploy()方法的输出中,您会找到指向您的 API 的链接。你可以用它来测试你的模型是否工作正常。如果是的话,你可以把它推到任何你想要的 Kubernetes 集群。您可以使用push_product()方法并传递您的 Kubernetes 集群的注册表链接来实现。

好吧,那是很多。我知道这个结构有点复杂,所以又总结了一遍。

将工作流程生产化到最佳状态。

GitHub 和 PyPi 上有更多的信息和文档。你可以去看看。此外,当然还有一些有趣的复活节彩蛋。

下一步是什么?

正如你所看到的,这个库提供了一些不错的特性,但是,它还远远没有完成。目前,productionize 只在 macOS 上运行。这是因为我使用家酿作为主要的软件包管理器。我已经在为 Ubuntu 开发一个版本了。任何 linux 发行版都是可管理的,然而,Windows 将是一个相当大的挑战。因此,如果你有建议或想法,请让我知道。此外,如果你给我一个关于https://github.com/LJStroemsdoerfer/productionize的问题,我会非常乐意处理任何 bug。

机器学习值得拥有自己的持续交付风格

原文:https://towardsdatascience.com/machine-learning-deserves-its-own-flavor-of-continuous-delivery-f4d1e76e6b69?source=collection_archive---------47-----------------------

mmmswan via flickr

当作为一个美国人在加拿大旅行时,事情感觉略有不同,但却惊人地相似。例如,麦当劳吸管上的红色竖线要粗一些。这很像我作为一名软件工程师在数据科学领域的旅行。

虽然数据科学世界很神奇,但我很怀念古典软件项目中 连续交付(CD) 的精炼状态。什么是持续交付?

马丁·福勒 发生以下情况时,您正在进行连续交付:

  1. 您的软件在其整个生命周期中都是可部署的
  2. 你的团队优先考虑保持软件的可部署性,而不是开发新的特性
  3. 任何人都可以在任何时候对他们的系统进行更改时获得快速、自动化的生产就绪性反馈
  4. 您可以按需将任何版本的软件部署到任何环境中

对于一个部署到 Heroku 的小规模软件项目来说,持续交付(以及它的超级活跃的兄弟持续部署 )是一幅轻松优雅的画面。您可以在几分钟内设置好 CI ,这意味着您的单元测试会在每次推送 git repo 时运行。你让 Review Apps 预览来自 GitHub pull 请求的应用。最后,每个git push to master 都会自动部署你的 app。所有这一切只需要不到一个小时的时间来配置。

现在,为什么同样的过程不适用于我们缠绕在单个predict函数上的纠结的纱线团呢?嗯,数据科学的世界不容易理解,除非你深入到它的内部省份。让我们看看为什么我们需要CD4ML以及你今天如何在你的机器学习项目中实现它。

为什么经典 CD 不适用于机器学习

我在一个机器学习项目中看到了 6 个关键差异,它们使得经典软件 CD 系统难以应用:

1.机器学习项目有多种可交付成果

不像传统的软件项目仅仅是为了交付应用程序而存在,机器学习项目有多种交付方式:

  • ML 模型——经过训练和序列化的模型,每个模型都有评估指标。
  • web 服务—通过 HTTP API 提供模型推理结果的应用程序。
  • 报告—生成的分析结果(通常来自笔记本),总结了关键发现。这些可以是静态的,也可以是使用像 Streamlit 这样的工具进行交互的。

拥有多个可交付成果——每个都有不同的构建过程和最终演示——比编译单个应用程序更复杂。因为其中的每一个都是彼此紧密耦合的——并且与数据紧密耦合——为每一个都创建单独的项目是没有意义的。

2.笔记本很难复习

git 分支上的代码审查是如此普遍,它们被烘烤到 GitHub 和其他托管版本控制系统中。GitHub 的代码审查系统对于*.py文件来说很棒,但是对于查看 JSON 格式文件的更改来说很糟糕。可惜笔记本文件(*.ipynb)就是这么存的。这尤其令人痛苦,因为笔记本——而不是将逻辑抽象成*.py文件——是几乎所有数据科学项目的起点。

3.测试不是简单的通过/失败

Elle O'Brien 介绍了使用 CI 进行模型评估的模糊性。

通过对代码分支运行单元测试套件,很容易指出一个经典软件 git 分支是否可以合并。这些测试包含简单的真/假断言(例如:“用户可以注册吗?”).模型评估更加困难,通常需要数据科学家手动审查,因为评估指标通常会向不同的方向变化。这个阶段更像是经典软件项目中的代码审查。

4.实验对比 git 分支

传统项目中的软件工程师在处理 bug 或增强时会创建小的、集中的 git 分支。虽然分支是轻量级的,但是它们不同于模型训练实验,因为它们通常最终被部署。模型实验?像鱼卵一样,绝大多数永远见不到开阔的水域。此外,与传统软件 git 分支相比,实验可能只有很少的代码更改(例如:调整一个超参数)。

5.非常大的文件

大多数 web 应用程序不在它们的 git 存储库中存储大文件。大多数数据科学项目都是如此。数据几乎总是需要这样。模型可能也需要这样做(在 git 中保存二进制文件也没有什么意义)。

6.可再现输出

对于传统软件项目的任何开发人员来说,重现应用程序在任何时间点的状态都很容易。该应用程序通常只在两个方面发生变化——代码和数据库的结构。在 ML 项目中很难达到一个可再现的状态,因为许多维度都可以改变(数据量、数据模式、特征提取和模型选择)。

一个简单的 CD 系统如何寻找机器学习?

使 CD4ML 变得生动的一些工具。

在优秀的机器学习连续交付中, Thoughtworks 团队提供了一个示例 ML 应用,它展示了一个 CD4ML 实现。让它运行起来涉及到许多移动部件:GoCD、Kubernetes、DVC、Google Storage、MLFlow、Docker 和 EFK 堆栈(ElasticSearch、FluentD 和 Kibana)。对于 Throughworks 的企业客户来说,组装这 10 个部分是容易做到的,但是对于较小的组织来说就有些困难了。精益组织如何实施 CD4ML?

以下是我的建议,按照我首先要做的事情排序。早期的项目更容易接近。后面的项目建立在基础之上,在适当的时候增加更多的自动化。

1.从 Cookiecutter 数据科学开始

在创建一个新的 Rails 项目之前,没有人会无所事事地去弄清楚他们想把自己的视图放在哪里;他们只是像其他人一样运行 rails new 来获得一个标准的项目框架。

**viaCookiecutter 数据科学

当我查看现有 Ruby on Rails 应用程序的源代码时,我可以很容易地浏览,因为它们都遵循相同的结构。不幸的是,大多数数据科学项目不使用共享的项目框架。然而,事情并不一定是这样的:从《烹饪与数据科学》开始你的数据科学项目,而不是想象出你自己独特的结构。

Cookiecutter Data Science 建立了一个适用于大多数项目的项目结构,创建了像datamodelsnotebookssrc这样的目录(用于共享源代码)。

2.nbdime 或 ReviewNB 获得更好的笔记本代码审查

nbdime 是一个 Python 包,使得查看笔记本文件中的更改更加容易。

很难在标准的比较工具中查看对*.ipynb的更改。对一个*.py脚本进行代码审查是微不足道的,但是对于一个 JSON 格式的笔记本来说几乎是不可能的。 nbdimeReviewNB 让这个过程更容易。

3.数据文件的 dvc

*dvc add data/ git commit -ma "Storing data dir in DVC" git push dvc push*

安装 dvc 并添加遥控器后,以上就是用 dvc 对您的data/目录进行版本控制所需的全部内容。

很容易提交大文件(esc。数据文件)复制到 git repo。Git 不能很好地处理大文件:它降低了速度,会导致回购文件的大小快速增长,而且无论如何你都不能真正地查看这些文件的差异。一个获得大量大文件版本控制的解决方案是数据版本控制(dvc) 。dvc 易于安装(只需使用pip)并且其命令结构模仿 git。

但是等等——您直接从数据仓库中查询数据,并且没有大型数据文件?这是不好的,因为它几乎保证了你的 ML 项目是不可复制的:数据和模式的数量几乎保证会随着时间而改变。相反,将这些查询结果转储到 CSV 文件中。存储很便宜,dvc 可以轻松处理这些大文件。

4.用于可再生训练管道的 dvc

dvc 不仅仅适用于大文件。正如 Christopher Samiullah 数据科学版本控制(DVC) 的第一印象中所说:

管道是 DVC 区别于其他能够处理大数据文件的版本控制工具的真正开始。DVC 流水线是典型的机器学习工作流(例如,数据加载、清理、特征工程、训练等)中有效的版本控制步骤。),以及预期的依赖项和输出。

您可以使用创建一个包含培训渠道的渠道阶段:

*dvc run -f train.dvc \ -d src/train.py -d data/ \ -o model.pkl \ python src/train.py data/ model.pkl*

dvc run命名这个阶段train,依赖train.pydata/目录,输出一个model.pkl模型。

稍后,您只需运行以下管道:

*dvc repro train.dvc*

这就是“可再生”的由来:

  • 如果依赖关系没有改变,那么dvc repo只需从远程存储中获取model.pkl。没有必要再次运行整个培训管道。
  • 如果依赖关系改变了,那么dvc repo会警告我们并重新运行这个步骤。

如果您想回到先前的状态(假设您有一个v1.0 git 标签):

*git checkout v1.0 dvc checkout*

运行dvc checkout会将data/目录和model.pkl恢复到之前的状态。

5.将慢速培训管道移至 CI 集群

重塑 DevOps 中,Elle O’brien 为使用 CI 来运行模型训练做了一个优雅的案例。我认为这很棒——CI 已经被用于在云中运行经典的软件测试套件。为什么不使用云中可用的更大的资源来为您的模型培训管道做同样的事情呢?简而言之,用您想要的实验变更来推进一个分支,并让 CI 进行训练和报告结果。

Christopher Samiullah 还涵盖了将培训转移到 CI 的内容,甚至提供了一个在 CI 流程中使用dvc repo train.dvcGitHub PR 的链接。

6.交付物特定的审核应用程序

Netlify 是一个针对静态站点的 PaaS,它允许您直接从 GitHub pull 请求中查看站点的当前版本。

像 Heroku 和 Netlify 这样的平台允许您直接从 GitHub pull 请求中查看应用程序的运行版本。这对于验证事情是否按预期运行是非常棒的。这对于向非技术团队成员展示工作非常有用。

使用 GitHub 动作做同样的事情,启动 Docker 容器来为您的交付服务。我会启动 web 服务和任何动态版本的报告(比如用 Streamlit 构建的东西)。

结论

就像健康饮食、刷牙、呼吸新鲜空气一样,在软件项目中实现持续交付没有任何负面影响。我们不能在机器学习项目上复制和粘贴经典的软件 CD 过程,因为 ML 项目将大型数据集联系在一起,这是一个缓慢的训练过程,不会生成明确的通过/失败验收测试,并且包含多种类型的可交付成果。相比之下,一个经典的软件项目只包含代码,并且只有一个可交付成果(一个应用程序)。

令人欣慰的是,现在有可能用现有的工具(git、Cookiecutter Data Science、nbdime、dvc 和 CI server)为非企业组织创建一个机器学习特定风格的连续交付( CD4ML )。

CD4ML 在行动我很想举一个机器学习项目的例子,它在 GitHub 上实现了一个精简的 CD4ML 堆栈,但是我在观众面前表现得更好。* 订阅此处,在示例应用程序构建完成时收到通知!*

在别处

原载于 2020 年 4 月 17 日https://booklet . ai

机器学习能源需求预测项目—第一部分数据清理

原文:https://towardsdatascience.com/machine-learning-energy-demand-prediction-project-part-1-data-cleaning-841a7b657723?source=collection_archive---------45-----------------------

让我们看看我们的机器学习项目规划基本编码工具如何在现实世界的项目中实现!今天,我们将讨论如何利用温度数据来预测我们每天消耗的能量。我们从导入和清理数据开始,然后绘制和描述我们的能源使用情况,最后建模

这是三个中的第一部分。请随意编码,完整的项目在 GitHub 上。

马太·亨利在 Unsplash 上的照片

我们早上醒来,打开加热器/空调,从冰箱里找到一些酸奶做早餐,刮胡子,打开电脑,打开音乐,最后开始工作。这些任务都有一个共同点——它们使用电力!我们对电力的严重依赖使得估算我们每天需要产生多少能量变得至关重要。

但是,如果这看起来很有挑战性,不要担心。我们会一步一步来。在每个阶段,链接回它与我们的 ML 领域指南的关系。

我们从寻找能量和温度数据开始(没有它我们做不了什么😊).我们的是从气象局和澳大利亚能源市场运营商,但请复制另一个国家(即美国)的过程。在快速而轻松的下载之后(幸运的我们),我们可以简单地回顾一下我们的电子表格。但是看看这些数据就可以发现一个可怕的事实——要处理的事情实在是太多了!数字无情的细胞,更多的数字和类别,真的让人应接不暇。我们如何将一系列电子表格组合在一起,以及我们如何能够对其进行分析、学习或建模,都不是很清楚。

作为乐观的人,我们首先记下数据是如何组织的。包含文件的文件夹,它们在哪里,每个文件包含什么。将我们对数据结构的理解与导入技术结合起来,自然会让我们克服第一个恐惧——用代码提供对数据的轻松访问。

接下来,我们寻求消除笨拙的混乱。我们需要清理温度&能量数据,确定哪些信息对我们的净能量使用有最大的影响!它又一次从对电子表格的简单观察开始,以粗略地掌握当前的数据类型。我们特别感兴趣的是发现奇怪的怪癖/重复出现的模式,这些模式 可以表明有问题。一旦我们跟踪了每一个预感,我们就能对问题的根源更加自信。这让我们能够自信地决定直接删除、保留和快速修复什么🤔(我们不想去兰博👹对一切)。简单的统计数据和图表构成了这一分析的基础!

此时,我们已经成功地完成了项目的第一个也是最重要的部分!在短暂的庆祝之后,我们可以继续合并两个独立的数据集(一个用于能量,一个用于温度)。这使我们能够将两者联系起来。最后,我们能够描绘出我们在每个令人羡慕的日子、月份和年份中如何使用能源的故事…借助于我们在图表中看到的趋势和模式!究竟什么会更令人满意?嗯,几件事…但我们不要忘记创建一个模型(这将是有趣的)炫耀给我们所有的朋友!让我们不要操之过急,虽然…这都将在未来两个教程。

第 1 章—导入数据

数据有各种各样的形状和大小,所以我们用来将所有东西编码的过程经常会有所不同。

通过分析可用的文件,我们发现了我们的数据是如何构成的。我们从高层次开始,注意到有许多 CSV 格式的温度和能量电子表格。尽管数量惊人,但这只是因为数据被分成了小块。每个 CSV 都是上一个 CSV 的延续。实际温度电子表格包含日期,以及各种温度、湿度和降雨量的测量值。我们的能源文件要简单得多,只包含日期、能源需求历史、价格(RRP)以及数据是手动还是自动记录的。测量是在 30 分钟的基础上进行的。

各个击破!

正如我们所见,所有这些信息汇集在一起,形成了对原始数据的直观理解。当然,我们还不了解执行分析所需的一切,但我们有足够的东西从原始数据过渡到可用代码 🥳!

为了转换成代码,我们将我们的发现与我们的导入技术进行比较。我们知道我们有一个要合并的电子表格列表,所以我们可以首先形成列表,然后使用 Pandas concat将它们堆叠在一起。

energy_locations = os.listdir("../Data/Energy")
temperature_locations = os.listdir("../Data/Temperature")

energy_CSVs = [pd.read_csv("../Data/Energy/" + location) for location in energy_locations]
temperature_CSVs = [pd.read_csv("../Data/Temperature/" + location) for location in temperature_locations if "Data" in location]energy_data = pd.concat(energy_CSVs, ignore_index=True)
temperature_data = pd.concat(temperature_CSVs, ignore_index=True)

现在,信不信由你,我们已经完成了 90%的导入,唯一剩下的就是确保我们的特性(列)被简洁一致地命名。通过重命名我们的列(如下所示),我们可以清楚地了解每列中的内容。未来的我们一定会感激不尽!

energy_data.columns
temperature_data.columnsIndex(['REGION', 'SETTLEMENTDATE', 'TOTALDEMAND', 'RRP', 'PERIODTYPE'], dtype='object')
Index(['hm', 'Station Number', 'Year Month Day Hour Minutes in YYYY', 'MM',
       'DD', 'HH24', 'MI format in Local time',
       'Year Month Day Hour Minutes in YYYY.1', 'MM.1', 'DD.1', 'HH24.1',
       'MI format in Local standard time',
       'Precipitation since 9am local time in mm',
       'Quality of precipitation since 9am local time',
       'Air Temperature in degrees C', 'Quality of air temperature',
       'Wet bulb temperature in degrees C', 'Quality of Wet bulb temperature',
       'Dew point temperature in degrees C',
       'Quality of dew point temperature', 'Relative humidity in percentage %',
       'Quality of relative humidity', 'Wind speed in km/h',
       'Wind speed quality', 'Wind direction in degrees true',
       'Wind direction quality',
       'Speed of maximum windgust in last 10 minutes in  km/h',
       'Quality of speed of maximum windgust in last 10 minutes',
       'Mean sea level pressure in hPa', 'Quality of mean sea level pressure',
       'Station level pressure in hPa', 'Quality of station level pressure',
       'AWS Flag', '#'],
      dtype='object')energy_data.columns = ["Region", "Date", "TotalDemand", "RRP", "PeriodType"]
temperature_data.columns = [
    "HM", "StationNumber", "Year1", "Month1", "Day1", "Hour1", "Minute1", "Year", "Month", "Day", "Hour", "Minute", "Precipitation", "PrecipitationQuality",
    "AirTemperature", "AirTemperatureQuality", "WetBulbTemperature", "WetBulbTemperatureQuality", "DewTemperature", "DewTemperatureQuality", "RelativeHumidity",
    "RelativeHumidityQuality", "WindSpeed", "WindSpeedQuality", "WindDirection", "WindDirectionQuality", "WindgustSpeed", "WindgustSpeedQuality", "SeaPressure",
    "SeaPressureQuality", "StationPressure", "StationPressureQuality", "AWSFlag", "#"
]

现在骄傲吧,因为我们刚刚完成了旅程的第一部分!现在我们已经开始行动了,从现在开始事情会变得更加顺利。

第 2 章—数据清理

格式化数据

每个人都会被丢失的数据逼疯,但隧道的尽头总会有一线光明。

有好消息也有坏消息,所以我先从好消息说起。我们已经经历了把所有东西都放在一起的初始阶段,所以我们现在对我们可以获得什么/如何获得它有一个基本的了解。我们可以使用energy_datatemperature_data数据框查看我们的数据!

现在是坏消息。虽然我们可能还没有注意到,但我们的数据远非完美。我们有大量缺失的(空的)单元格,以及重复的和格式错误的数据。但是不要灰心,因为这不是一场罕见的大灾难:它一直都在发生😎(有什么不喜欢的?)😎。

这个过程看起来很危险,因为一切看起来都…一团糟。现在洞察力和经验确实很有帮助,但是但是…这并不意味着对我们凡人来说这是不可能的!我们可以做一件事来克服这一点——像疯狂的科学家一样工作!我们可以识别数据集的怪癖/问题,然后测试我们想到的每一种技术🤯。我们的技术来自现场指南(永远不要重新发明轮子)!

只是为了确保我们没有跑偏,下面是我们正在寻找的问题:

  • 完全空的列/行
  • 重复值
  • 不准确/通用的数据类型

是的,现在只有三个,但是…别忘了我们不会稳健分析!因此,实际上以一种具体的方式处理这些问题确实需要一点努力(不要太狡猾,那是留给政治家的权利——无意冒犯)。

最后声明——有很多东西需要理解,所以请深呼吸,喝点咖啡,慢慢寻找规律。

energy_data
temperature_data

我们可以看到像PrecipitationQualityHM这样的列似乎始终具有相同的值。为了修正这一点,我们可以删除具有两个或更少唯一元素的列。

def remove_non_uniques(dataframe: pd.DataFrame, filter = []):
    remove = [name for name, series in dataframe.items() if len(series.unique()) <= 2 and not name in filter]
    dataframe.drop(remove, axis=1, inplace=True)
    return remove

print("Removed:")
remove_non_uniques(energy_data)
remove_non_uniques(temperature_data)Removed:
['PeriodType']

['HM',
 'PrecipitationQuality',
 'AirTemperatureQuality',
 'WetBulbTemperatureQuality',
 'DewTemperatureQuality',
 'RelativeHumidityQuality',
 'WindSpeedQuality',
 'WindDirectionQuality',
 'WindgustSpeedQuality',
 'SeaPressureQuality',
 'StationPressureQuality',
 '#']

也可以删除重复的行。这简单多了!

energy_data.drop_duplicates(inplace=True)
temperature_data.drop_duplicates(inplace=True)

最后一件事是检查我们的数据类型。这在这里似乎没有必要,但是建模和图形库对数据类型非常敏感。

这个过程非常简单,查看列/它包含的内容,然后将其与实际的数据类型进行比较。对于大量的列,最好从查看日期和类别开始,因为它们几乎总是被误解(作为对象、浮点数或整数)。一般来说,object应该只用于字符串。

energy_data.dtypes
temperature_data.dtypesRegion          object
Date            object
TotalDemand    float64
RRP            float64
dtype: object

StationNumber          int64
Year1                  int64
Month1                 int64
Day1                   int64
Hour1                  int64
Minute1                int64
Year                   int64
Month                  int64
Day                    int64
Hour                   int64
Minute                 int64
Precipitation         object
AirTemperature        object
WetBulbTemperature    object
DewTemperature        object
RelativeHumidity      object
WindSpeed             object
WindDirection         object
WindgustSpeed         object
SeaPressure           object
StationPressure       object
AWSFlag               object
dtype: object

在我们的例子中,我们有不止一组日期,而是两个(该死的,BOM 数据收集团队需要冷静)🥴.正如我们预测的那样,日期是整数,分布在多个列中(一个表示年,一个表示月、日、小时和分钟)。

我们可以先去掉重复的日期集(第二个是因为夏令时),然后我们可以解析剩余的日期列。这以我们期望的良好有序的方式格式化了我们的数据!

# Remove extra dates
temperature_data.drop(["Year1", "Month1", "Day1", "Hour1", "Minute1"], axis=1, inplace=True)

# Reformat dates into Pandas' datatime64 objects
# Replacing old format
temperature_data["Date"] = pd.to_datetime(temperature_data[["Year", "Month", "Day", "Hour", "Minute"]])
energy_data["Date"] = pd.to_datetime(energy_data["Date"])

temperature_data.drop(["Year", "Month", "Day", "Hour", "Minute"], axis=1, inplace=True)

现在,我们还可以看到一些关于站号(在哪里进行测量)、AWSFlag(是否手动收集数据)、温度、湿度、压力和降水测量的问题。我们确实需要改变这些数据类型,但是这样做我们需要稍微脱离书本,因为使用标准的.astype("category")转换数据类型会抛出一些错误。我们可以通过记下投诉的内容、解释投诉原因,然后尝试再次运行上述功能来解决这些问题。

为了确保我们都在同一页上,下面是我们正在处理的错误的简短摘要:

  • 前导/尾随空格(因此“12”变成了“12”)
  • 随机标签偶尔会出现(所以 99.99%的单元格会包含数字,但其中一个会包含“###”)
  • 有少量缺失的分类数据

我们可以通过使用.str.strip()删除前导和尾随空格。接下来,要删除 rouge 标签,我们可以使用 Pandas 的replace函数用np.NaN(用于空数据的默认数据类型)覆盖它。最后,我们可以假设任何丢失的数据都是手工收集的(最坏的情况)。fillnareplace函数都是需要的,因为熊猫对np.NaN和空字符串("")的处理是不同的。

def to_object_columns(lambda_function):
    string_columns = temperature_data.select_dtypes("object").columns
    temperature_data[string_columns] = temperature_data[string_columns].apply(lambda_function)to_object_columns(lambda column: column.str.strip())

temperature_data["AWSFlag"] = temperature_data["AWSFlag"].replace("", 0).astype("category")
temperature_data["AWSFlag"].fillna(0, inplace=True)
temperature_data["RelativeHumidity"] = temperature_data["RelativeHumidity"].replace("###", np.NaN)

to_object_columns(lambda column: pd.to_numeric(column))temperature_data.dtypesStationNumber                  int64
Precipitation                float64
AirTemperature               float64
WetBulbTemperature           float64
DewTemperature               float64
RelativeHumidity             float64
WindSpeed                    float64
WindDirection                float64
WindgustSpeed                float64
SeaPressure                  float64
StationPressure              float64
AWSFlag                     category
Date                  datetime64[ns]
dtype: object

我们还可以做最后一件事来改进数据的格式。这是为了确保用于标识温度和能量测量位置的列使用相同的类别。

因为我们每个地区只有一个电台,所以我们可以用简短的地区代码来代替单独的地区代码。请注意,这些信息是在数据集注释中提供的(不要担心,我们不需要记住 94029 是指维多利亚)。要进行这些转换,我们只需创建两个字典。每个键-值对表示旧代码,以映射到新代码(因此将“SA1”映射到“SA”,将 23090 映射到“SA”)。Pandas map函数完成剩下的工作。

energy_data["Region"].unique()
temperature_data["StationNumber"].unique()array(['VIC1', 'SA1', 'TAS1', 'QLD1', 'NSW1'], dtype=object)
array([94029, 86071, 66062, 40913, 86338, 23090])region_remove_number_map = {"SA1": "SA", "QLD1": "QLD", "NSW1": "NSW", "VIC1": "VIC", "TAS1": "TAS"}
station_to_region_map = {23090: "SA", 40913: "QLD", 66062: "NSW", 86071: "VIC", 94029: "TAS", 86338: "VIC"}

temperature_data["Region"] = temperature_data["StationNumber"].map(station_to_region_map)
energy_data["Region"] = energy_data["Region"].map(region_remove_number_map)

temperature_data.drop("StationNumber", axis=1, inplace=True)

关于我们的数据格式化的最后一点需要注意的是(承诺)。我们目前没有以任何特定的方式索引/排序我们的数据,即使它是一个时间序列。所以我们可以用set_index来改变它。

energy_data.set_index("Date", inplace=True)
temperature_data.set_index("Date", inplace=True)

处理缺失数据

到目前为止,我们已经确保我们所有的数据都可以轻松访问,没有任何麻烦。我们已经确保所有东西的格式都是正确的,现在我们可以使用它了…嗯,算是吧。虽然我们的数据格式正确,但这并不意味着它是有意义的、有用的,甚至是存在的!

我们可以度过这个难关,我们只需要有战略眼光。这里要记住的关键是:

不要做不必要的工作!

我们的最终目标不是修复一切,而是删除那些绝对无用的东西,提高那些可能特别有趣/有用的东西的质量。这个过程有助于我们知道我们正在做出可靠的、概括的和合理的预测或解释(否则整个过程就没有什么意义了)。

一个很好的方法是使用图表。通过可视化我们的数据,我们可以很容易地发现哪里缺少数据,哪里存在异常值,哪里两个特征相关。当然,我们不能在一个图上做所有这些,所以我们将从寻找缺失的数据开始。大间隙或频繁间隙的部分是我们正在寻找的潜在问题区域。如果这些不存在(即很少或没有丢失数据),那么我们的工作就会减少。

请记住,我们有两个数据集(不是一个),按州分类!由于数据是以不同的状态记录的,因此将它们组合在一起并不能正确地表示数据。因此,对于我们想要分析的每个特征,我们将有一系列的图(每个州一个)。不过我们稍微幸运一些,因为只有一个有意义的能量特征(TotalDemand),我们将看到它几乎没有丢失数据。

fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(20, 12), tight_layout=True)

energy_data.groupby("Region").get_group("TAS")["TotalDemand"]["2000":"2019"].plot(color= "red",title="Tasmania Energy Demand",ax=axes[0,0])
energy_data.groupby("Region").get_group("VIC")["TotalDemand"]["2000":"2019"].plot(color= "green",title="Victoria Energy Demand",ax=axes[0,1])
energy_data.groupby("Region").get_group("NSW")["TotalDemand"]["2000":"2019"].plot(color= "purple",title="New South Wales Energy Demand",ax=axes[0,2])
energy_data.groupby("Region").get_group("QLD")["TotalDemand"]["2000":"2019"].plot(color= "orange",title="Queensland Energy Demand",ax=axes[1,0])
energy_data.groupby("Region").get_group("SA")["TotalDemand"]["2000":"2019"].plot(color="blue",title="South Australia Energy Demand",ax=axes[1,1])

正如我们所看到的,这些图都是连续的,这就是我们如何确认没有丢失数据的主要来源。这里有各种各样的其他趋势,但我们将这些留到以后!

现在转到天气数据。这就是我们将看到图表的用处的地方!虽然可以简单地找到丢失数据的百分比,但是图表很容易显示空值的性质。我们可以立即看到它在哪里丢失了,这本身就表明应该使用什么方法(例如,删除数据、重新采样等)。

我们从看WetBulbTemperature开始。我们会看到它很大程度上是完整的,就像我们的能源数据。然后我们会看到AirTemperature,这将是...粗糙破烂。

为了简洁起见,这里只包括几个关键的图表。然而,更多的负载可以用图表表示(请仔细研究代码,看看还能做些什么)!AirTemperature的问题类似于以下特征中的问题:

  • 沉淀
  • 空气温度
  • 露点温度
  • 相对湿度
  • 风速
  • 风向
  • 风速
fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(20, 12), tight_layout=True)

temperature_data.groupby("Region").get_group("TAS")["WetBulbTemperature"]["2000":"2019"].plot(color= "red",title="Tasmania Wet Bulb Temperature",ax=axes[0,0])
temperature_data.groupby("Region").get_group("VIC")["WetBulbTemperature"]["2000":"2019"].plot(color= "green",title="Victoria Wet Bulb Temperature",ax=axes[0,1])
temperature_data.groupby("Region").get_group("NSW")["WetBulbTemperature"]["2000":"2019"].plot(color= "purple",title="New South Wales Wet Bulb Temperature",ax=axes[0,2])
temperature_data.groupby("Region").get_group("QLD")["WetBulbTemperature"]["2000":"2019"].plot(color= "orange",title="Queensland Wet Bulb Temperature",ax=axes[1,0])
temperature_data.groupby("Region").get_group("SA")["WetBulbTemperature"]["2000":"2019"].plot(color= "blue",title="South Australia Wet Bulb Temperature",ax=axes[1,1])

fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(20, 12), tight_layout=True)

temperature_data.groupby("Region").get_group("TAS")["AirTemperature"]["2000":"2019"].plot(color= "red",title="Tasmania Air Temperature",ax=axes[0,0])
temperature_data.groupby("Region").get_group("VIC")["AirTemperature"]["2000":"2019"].plot(color= "green",title="Victoria Air Temperature",ax=axes[0,1])
temperature_data.groupby("Region").get_group("NSW")["AirTemperature"]["2000":"2019"].plot(color= "purple",title="New South Wales Air Temperature",ax=axes[0,2])
temperature_data.groupby("Region").get_group("QLD")["AirTemperature"]["2000":"2019"].plot(color= "orange",title="Queensland Wind Air Temperatue",ax=axes[1,0])
temperature_data.groupby("Region").get_group("SA")["AirTemperature"]["2000":"2019"].plot(color= "blue",title="South Australia Air Tempeature",ax=axes[1,1])

图表中随机出现的几个月到几年的气温数据(空白部分)表明不值得进一步研究。这实际上并不是一件坏事,它让我们更加关注现在的:能量需求和湿球温度。

这些图表显示了大量或有规律的缺失数据,但是,它们没有显示随机分布的少量数据。为了安全起见,我们可以快速使用熊猫DataFrame.isnull来查找哪些值为空。它立即显示我们的能量数据处于完美的状态(没有任何遗漏),而大多数温度列有很大比例的遗漏!

我们将删除大多数特性,因为它们需要我们牺牲大量的行。我们想要保留的(即WetBulbTemperature)可以对其缺失值进行插值(根据其周围的值推断出该值应该是什么)。

def get_null_counts(dataframe: pd.DataFrame):
    return dataframe.isnull().mean()[dataframe.isnull().mean() > 0]get_null_counts(energy_data)
get_null_counts(temperature_data)Series([], dtype: float64)

Precipitation         0.229916
AirTemperature        0.444437
WetBulbTemperature    0.011324
DewTemperature        0.375311
RelativeHumidity      0.375312
WindSpeed             0.532966
WindDirection         0.432305
WindgustSpeed         0.403183
SeaPressure           0.137730
StationPressure       0.011135
dtype: float64remove_columns = ["Precipitation", "AirTemperature", "DewTemperature", "RelativeHumidity", "WindSpeed", "WindDirection", "WindgustSpeed"]
temperature_data.drop(remove_columns, axis=1, inplace=True)

# Note that using inplace currently throws an error
# So interpolated columns must be manually overridden
missing_columns = list(get_null_counts(temperature_data).keys())
temperature_data[missing_columns] = temperature_data[missing_columns].interpolate(method="time")

组合能量和温度数据

现在,到了最后一步。将两个数据框架结合成一个,这样我们就可以将温度数据与能源需求联系起来。

我们可以使用merge_asof函数来合并这两个数据集。该功能将最接近的值合并在一起。因为我们有按地区分组的数据,所以我们用by参数来指定。我们可以选择只合并相隔 30 分钟或更短时间的能量和温度条目。

energy_data.sort_index(inplace=True)
temperature_data.sort_index(inplace=True)

data = pd.merge_asof(energy_data, temperature_data, left_index=True, right_index=True, by="Region", tolerance=pd.Timedelta("30 min"))

为了检查合并是否成功,我们可以检查有多少空值。这是因为不成对的行会导致空值。

get_null_counts(data)
data.dropna(inplace=True)WetBulbTemperature    0.001634
SeaPressure           0.001634
StationPressure       0.001634
AWSFlag               0.001634
dtype: float64

现在终于可以看到一些干净理智的数据了!这是我们看到的第一张不会对健康和安全造成巨大危害的桌子。既然我们已经到了这个阶段,我们应该庆祝一下…从这里开始只会变得更好👊。

data

保存最终数据

pd.to_pickle(data, "../Data/Data.pickle")

https://www.kamwithk.com】最初发表于

机器学习能源需求预测项目——第二部分使用图表讲故事

原文:https://towardsdatascience.com/machine-learning-energy-demand-prediction-project-part-2-storytelling-using-graphs-9c62a7dfadd2?source=collection_archive---------54-----------------------

让我们看看我们的机器学习项目规划基本编码工具如何在现实世界的项目中实现!今天,我们将讨论如何利用温度数据来预测我们每天消耗的能量。我们之前导入并清理了我们的数据,现在将绘制并描述我们能源使用背后的故事!。

这是三部曲的第二部(第一部在这里)。请随意编码,完整的项目在 GitHub 上。

故事

我们早上醒来,打开加热器/空调,从冰箱里找到一些酸奶做早餐,刮胡子,打开电脑,打开音乐,最后开始工作。这些任务都有一个共同点——它们使用电力!我们对电力的严重依赖使得估算我们每天需要产生多少能量变得至关重要。

我们已经找到、导入并清理了我们的数据(好员工),所以我们可以继续讲述我们的用电情况。但是,如果这看起来很有挑战性,不要担心。我们会一步一步来。在每个阶段,链接回它与我们的 ML 领域指南的关系。

斯科特·格雷厄姆摄于Unsplash

我们从困难但必要的任务开始,解释我们的数据。我们的第一个想法是一次绘制出整个时间序列,但该死的一个有 4 个特征的图,每个特征在 20 年内每 30 分钟有大约 5 次测量,这是不漂亮的,有意义的或快速的。在把头撞向砖墙一段时间后,我们当然意识到我们可以描绘出具体的特征和关系,而不是一次性描绘出一切。由于损失不大,我们开始使用简单的汇总统计数据来查找最大值、最小值和平均值。这些给了我们每个专栏的大致概述,但是为了更进一步,我们来看看我们的特征与的相关性如何。

一旦我们理解了温度与能量需求高度相关(足够直观),我们就可以开始绘制一些图表了😉!虽然我们不能一次描绘出所有的事情,但是我们仍然希望掌握全局——我们的数据是如何随时间变化的。我们首先确定我们的问题——当我们寻找 20 年来的变化时,每 30 分钟一次的运动实际上是没有意义的,只会模糊画面。幸运的是,我们的字段指南解释说,我们可以通过重采样来绘制每周的平均值!现在我们知道了状态之间的一般增加和减少趋势。

在查看了能量和温度的单个数据后,我们继续寻找两者之间的关联。每个州的图表是不同的。趋势较大的州有更复杂的图形。这很复杂,我们没有数据来解释这些趋势,所以我们需要在以后删除它们。

现在我们只剩下一件事了——找出能源需求在一天和一周内是如何变化的。然后……很快,我们就成功地描述了每个令人振奋的日子、月份和年份的能源使用情况😎。此时,我们已经成功地完成了项目的大部分!在短暂的庆祝之后,我们可以开始建模了…但是不要操之过急,这将在下一个(最后的)教程中介绍。

*import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

from IPython.core.interactiveshell import InteractiveShell

InteractiveShell.ast_node_interactivity = "all"
pd.options.display.max_columns = None

data = pd.read_pickle("../Data/Data.pickle")*

时代

第 1 章—描述性统计

由于我们不能一次查看所有内容,所以我们希望对我们的数据有一个粗略的估计。自然的第一步是查看每一列的平均值、最小值和最大值。这些被称为描述性统计,Pandas 使用describe函数为我们计算它们。

因为我们想扩展这个来看看什么与能源需求相关(因为我们试图在以后预测它),我们将找到相关性。为了找到特性之间的相关性,Pandas 提供了corr函数。

统计数据显示:

  • TotalDemand平均 4619MW,最小 22 mW,最大 14580 MW。
  • WetBulbTemperature最低气温为零下 9 摄氏度,最高气温为 41 摄氏度
  • TotalDemandWetBulbTemperature最相关

尽管相关函数只考虑了线性关系(直线),但它仍然有助于了解哪些要素值得绘制并包含在我们的模型中。这里主要是WetBulbTemperature,但StationPressure也可能有用。

*data.describe()*
*data.corr()*

第 2 章——寻找长期趋势

20 年的能源

我们想知道我们如何使用能源的故事。有一个简单的方法可以做到这一点——图表🤓。我们可以从大尺度上看发生了什么开始,然后慢慢放大。

我们将分别查看每个状态,因为它们的趋势可能不一样。

*fig, axes  = plt.subplots(nrows=2, ncols=3, figsize=(20, 12), constrained_layout=True)

data.groupby("Region").resample("3W").mean()["TotalDemand"]["TAS"].plot(color="red", title="Tasmania Energy Demand", ax=axes[0,0])
data.groupby("Region").resample("3W").mean()["TotalDemand"]["VIC"].plot(color="green", title="Victoria Energy Demand", ax=axes[0,1])
data.groupby("Region").resample("3W").mean()["TotalDemand"]["NSW"].plot(color="purple", title="New South Wales Energy Demand", ax=axes[0,2])
data.groupby("Region").resample("3W").mean()["TotalDemand"]["QLD"].plot(color="orange", title="Queensland Energy Demand", ax=axes[1,0])
data.groupby("Region").resample("3W").mean()["TotalDemand"]["SA"].plot(color="blue", title="South Australia Energy Demand", ax=axes[1,1])*

重新采样后,解释图表仍然很困难。所以让我们慢慢来,一步一步来。

第一个值得注意的模式是能量总是在高点和低点之间波动。高点和低点并不总是一样的。

  • 塔斯马尼亚岛和南澳大利亚从大约 900 到 1400 不等
  • 维多利亚从 4500 年到 6500 年
  • 新南威尔士从 6000 到 10000
  • 昆士兰从 4500 到 7500

但是我们可以说趋势并不是一成不变的。能源使用可能会快速增加(昆士兰州,直到 2010 年),急剧下降(维多利亚州,2010 年后),甚至持续稳定(塔斯马尼亚州)!这种模式显然不是有规律的,也不是直接由温度引起的(因此无法使用历史温度和能量数据进行预测)。

虽然我们没有这些趋势的数据,但我们可以给出一个有根据的猜测。我们知道人口不稳定,不同的州人口增长率不同。技术和能源效率也有了巨大的提高,经济状况影响着人们使用能源的意愿。除此之外,全球变暖促使越来越多的人安装太阳能电池板(太阳能电池板产生的电能没有被计算在内)。由于我们没有任何关于这些特征的数据,在开始建模之前,我们将尝试去除这些趋势。

一年中的能量

现在让我们放大!我们将着眼于一年中发生的趋势。因为我们绘制的是 5 年而不是 20 年,我们当然需要更少的重采样

*fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(20, 12), constrained_layout=True)

data.groupby("Region").resample("W").mean()["TotalDemand"]["TAS"]["2015":"2020"].plot(color="red", title="Tasmania Energy Demand", ax=axes[0,0])
data.groupby("Region").resample("W").mean()["TotalDemand"]["VIC"]["2015":"2020"].plot(color="green", title="Victoria Energy Demand", ax=axes[0,1])
data.groupby("Region").resample("W").mean()["TotalDemand"]["NSW"]["2015":"2020"].plot(color="purple", title="New South Wales Energy Demand", ax=axes[0,2])
data.groupby("Region").resample("W").mean()["TotalDemand"]["QLD"]["2015":"2020"].plot(color="orange", title="Queensland Energy Demand", ax=axes[1,0])
data.groupby("Region").resample("W").mean()["TotalDemand"]["SA"]["2015":"2020"].plot(color="blue", title="South Australia Energy Demand", ax=axes[1,1])*

我们可以看出,能量需求通常在春季和秋季最低,而在冬季和/或夏季最高。塔斯马尼亚冬季的需求往往高于夏季。维多利亚州与此相似,但夏季的能源需求高峰更为频繁。另一方面,昆士兰州在夏季使用最多的能源。新南威尔士州和南澳大利亚州在夏天和冬天都有最大的能量!

塔斯马尼亚岛一直比较凉爽(作为一个小岛),不像炎热多汗的新南威尔士和南澳大利亚。这可以解释最大值/最小值出现的相对差异。

超过 20 年的温度

不过,温度和能量一样重要。所以我们也来看看吧!

*fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(20, 6), constrained_layout=True)

data.groupby("Region").resample("3W").mean()["WetBulbTemperature"]["TAS"].plot(color= "red", title="Tasmania Temperature", ax=axes[0,0])
data.groupby("Region").resample("3W").mean()["WetBulbTemperature"]["VIC"].plot(color= "green", title="Victoria Temperature", ax=axes[0,1])
data.groupby("Region").resample("3W").mean()["WetBulbTemperature"]["NSW"].plot(color= "purple", title="New South Wales Temperature", ax=axes[0,2])
data.groupby("Region").resample("3W").mean()["WetBulbTemperature"]["QLD"].plot(color= "orange", title="Queensland Temperature", ax=axes[1,0])
data.groupby("Region").resample("3W").mean()["WetBulbTemperature"]["SA"].plot(color="blue", title="South Australia Temperature", ax=axes[1,1])*

与能量图不同,温度图没有任何明显的趋势。然而,我们可以看到温度从最低 8 度左右到最高 22 度左右不等。虽然这张图没有显示各州之间温度的显著变化,但它们确实存在。塔斯马尼亚岛一直比较凉爽(作为一个小岛),不像炎热多汗的新南威尔士和南澳大利亚。

温度和能量相关性

我们知道温度和能量高度相关,但我们还不知道如何相关。好吧,让我们来看看!

*fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(20, 12), constrained_layout=True)

data.groupby("Region").get_group("TAS").resample("D").mean().plot(kind="scatter",x="WetBulbTemperature", y="TotalDemand", s=10, color= "red", ax=axes[0,0], title="Tasmania")
data.groupby("Region").get_group("VIC").resample("D").mean().plot(kind="scatter",x="WetBulbTemperature", y="TotalDemand", s=10, color= "green", ax=axes[0,1], title="Victoria")
data.groupby("Region").get_group("NSW").resample("D").mean().plot(kind="scatter",x="WetBulbTemperature", y="TotalDemand", s=10, color= "purple", ax=axes[0,2], title="New South Wales")
data.groupby("Region").get_group("QLD").resample("D").mean().plot(kind="scatter",x="WetBulbTemperature", y="TotalDemand", s=10, color= "orange", ax=axes[1,0], title="Queensland")
data.groupby("Region").get_group("SA").resample("D").mean().plot(kind="scatter",x="WetBulbTemperature", y="TotalDemand", s=10, color= "blue", ax=axes[1,1], title="South Australia")*

这些图表向我们展示了一件重要的事情,趋势越大,温度和能源需求之间的关系就变得越混乱(和复杂)。这就是为什么塔斯马尼亚岛的温度和能源需求曲线几乎是一条直线(尽管是一条粗线),而其他地方是曲线。换句话说,趋势越大,曲线越宽越粗!

由于我们没有任何人口或经济数据,趋势必须被删除(在下一个教程中)。

第 3 章——分析小时间框架

下图显示了冬季和夏季一天和一周内不同地区的能源需求对比。我们可以从一周(此处为 2017 年 11 月 6 日至 2017 年 6 月 17 日)开始,看看能源需求在一周内是如何波动的。我们只测试了一个小时间段,这是为了简洁(下面的相同模式也可以在其他地方看到)。

*fig, axes = plt.subplots(nrows=4, ncols=3, figsize=(20, 10), tight_layout=True)

# Winter
data["2017-06-11":"2017-06-17"].groupby("Region").get_group("TAS")["TotalDemand"].plot(color="red", title="Tasmania Winter", ax=axes[0,0])
data["2017-06-11":"2017-06-17"].groupby("Region").get_group("VIC")["TotalDemand"].plot(color="green", title="Victoria Winter", ax=axes[0,1])
data["2017-06-11":"2017-06-17"].groupby("Region").get_group("NSW")["TotalDemand"].plot(color="purple", title="New South Wales Winter", ax=axes[0,2])
data["2017-06-11":"2017-06-17"].groupby("Region").get_group("QLD")["TotalDemand"].plot(color="orange", title="Queensland Winter", ax=axes[1,0])
data["2017-06-11":"2017-06-17"].groupby("Region").get_group("SA")["TotalDemand"].plot(color="blue", title="South Australia Winter", ax=axes[1,1])

# Summer
data["2017-1-14":"2017-1-20"].groupby("Region").get_group("TAS")["TotalDemand"].plot(color="red", title="Tasmania Summer", ax=axes[2,0])
data["2017-1-14":"2017-1-20"].groupby("Region").get_group("VIC")["TotalDemand"].plot(color="green", title="Victoria Summer", ax=axes[2,1])
data["2017-1-14":"2017-1-20"].groupby("Region").get_group("NSW")["TotalDemand"].plot(color="purple", title="New South Wales Summer", ax=axes[2,2])
data["2017-1-14":"2017-1-20"].groupby("Region").get_group("QLD")["TotalDemand"].plot(color="orange", title="Queensland Summer", ax=axes[3,0])
data["2017-1-14":"2017-1-20"].groupby("Region").get_group("SA")["TotalDemand"].plot(color="blue", title="South Australia Summer", ax=axes[3,1])*

所有州每天的能源使用量都差不多。夏季和冬季有两个高峰。第一个较小,在白天(上午 5-9 点),而第二个较大,在晚上(下午 4-7 点)。这些发生在人们在家最活跃的时候(工作前后)。虽然这里只能显示一些图表,但这些模式确实会持续存在(交换不同的日期会显示这一点)。

夏季一周内的能量需求与冬季相似,但需求在一周内增加得更多!

我们现在可以继续查看某一天(此处为 2017 年 11 月 6 日)。

*fig, axes = plt.subplots(nrows=2, ncols=3, figsize=(20, 10), constrained_layout=True)

data["2017-06-11"].groupby("Region").get_group("TAS")["TotalDemand"].plot(title="Tasmania", ax=axes[0,0], color="red")
data["2017-06-11"].groupby("Region").get_group("VIC")["TotalDemand"].plot(title="Victoria", ax=axes[0,1], color="green")
data["2017-06-11"].groupby("Region").get_group("NSW")["TotalDemand"].plot(title="New South Wales", ax=axes[0,2], color="purple")
data["2017-06-11"].groupby("Region").get_group("QLD")["TotalDemand"].plot(title="Queensland", ax=axes[1,0], color="orange")
data["2017-06-11"].groupby("Region").get_group("SA")["TotalDemand"].plot(title="South Australia", ax=axes[1,1], color="blue")*

从这些图表中,我们可以看到,从早上 6 点到 9 点,以及从下午 3 点到 6 点,能源使用量逐渐增加。在上午 12 点到下午 3 点,我们的能源使用保持稳定。它通常在一天开始和结束后下降(可能是在大多数人睡着的时候)。夏季和冬季的需求基本相似。

照片由斯科特·格雷厄姆在 上 Unsplash

原载于https://www.kamwithk.com

机器学习工程师对软件工程师

原文:https://towardsdatascience.com/machine-learning-engineer-versus-software-engineer-fb59f8cba9dd?source=collection_archive---------7-----------------------

这两个角色有什么区别,他们是怎么想的?

截至 2018 年,软件工程已经发展到在美国拥有超过 100 万 员工,并且预计增长不会放缓。接下来是机器学习工程师,他处理自动化或决策问题,并对其应用尖端工具。

机器学习是在不确定性下做出决策的研究:给定一个训练数据集,当我看到新的东西时,我应该如何行动。

照片由希塔斯·贾达夫派克斯拍摄。

随着机器学习(特别是深度学习)在整个行业的普及,越来越多的工程师在日常生活中部署这些工具。利用深度学习为公司带来巨大利润的工具实际上是无穷无尽的:搜索推荐、语音转文本、语音助手、面部识别、广告等等。

实现这些模型与构建大型分布式软件系统的角色有何不同?心态相似,但专攻不同。

加州海岸——作者。

软件工程—构建数据网络

数据流是任何大规模软件项目的关键。工程师必须选择在本地设备上部署的正确算法,用什么语言开发(以及编译成什么语言),以及软件堆栈中有多少层。

软件工程师最终在语言、数据结构和算法领域工作。

  • 语言:开发和测试语言是软件工程师的工作环境。他们对不同语言的能力有了深入的了解,并且权衡的尺度也很大。Python 是最受欢迎的,因为下游决策变得更加流畅(我同意 Python)。
  • 数据结构:不同的数据结构决定了哪些计算机操作速度快——我们是想要快速访问数据(哈希表)吗?使用学习工具(张量)进行快速后处理?还是别的?不同的语言有不同的属性可以利用,最好的软件工程师对这些都像外语一样流利。
  • 算法:标准算法是技术面试的基础——排序、搜索等等——因为它们在规模上确实很重要。“ Big O ”符号是一种古怪的学习工具,但是当在部署的系统上工作时,这种思想可以大规模地转化。

在这里,软件工程师可能会失败:爱上他们自己系统的复杂性。

热爱自己系统的复杂性,这样你就可以在其中创造更多的东西,并在别人试图使用它时炫耀指标,这是一个超级能干的工程师的失败。简单是王道,因为它可以扩展并支持公司范围的协作。

Python 开发者环境。

好的软件工程最终会让机器学习的任务变得更容易。数据将更加可用和统一,以便提炼为产品和价值。

机器学习工程——构建知识网络

学习工程师正在提取记录的知识(数据)并创建决策边界。决策边界通常是非线性的,并且通常难以解释(例如交易代理或机器人规划者),但是它们是由数据通知的决策边界。

机器学习工程师在模型、部署和影响的空间中思考。

  • 模型:我什么时候应该使用深度模型或者贝叶斯近似?对于机器学习工程师来说,知道哪些系统概括得更好,可以在设备上进行微调,并且可以解释是关键。此外,对模型的专业知识使 ML PhD 成为科技公司如此有价值的雇员。
  • 部署:很多公司都在这个领域明确了自己的定位。设备级人工智能是消费电子公司(咳咳,苹果)目前的推动力,模型效率主导着数字巨人的成本。(脸书、谷歌等)。特斯拉凭借无与伦比的云汽车更新主宰着汽车自动化市场。接下来是单个工程师如何做出贡献— 针对特定任务的更多特定模型将在我们的生活中不断增加,模型的效率将改变互联网速度和电池寿命
  • 影响 : 伦理。我正在部署的模型是否以牺牲另一个子群的利益为代价而使一个子群受益?这是 ML 工程师需要的,因为你选择和训练的数据集将反映在你的产品中。考虑一下,如果一个数据集是从 100 个前 alpha 用户的样本中收集的,当它触及数百万双不知情的眼睛时,将如何翻译?数据透明度落后,个人需要承担责任。

机器学习工程师的不足之处:将他们的贡献困在过多的层级和工具中。

当调查实现选项时,其他机器学习者希望能够以模块化的方式提取和镜像有用的代码,从而实现快速发展。我试图利用多个最先进的项目,这些项目在内部陷入了太多的层次,以采取下一步措施,并使它们在现实世界中大规模产生影响——这就是为什么简单是王道。

我博士期间训练的不同模型的集合。左)高斯过程拟合物理优化的设计变量,中)深度动力学模型预测洛伦兹系统(经典混沌系统),右)不同类型的深度神经网络预测长期机器人轨迹。

主题——数码便宜,简单为王

这两个工程角色都利用了数字领域的迭代既便宜又快速的事实— 每个边缘用户都以低成本增加高价值。这样,最简单的方法往往会占主导地位,因为它们可能非常普遍— 简单方法在学习中具有更好的通用性,在软件中具有更好的接口

就像最优秀的软件工程师一样,最优秀的机器学习工程师也会富有创造力和效率。

最优秀的工程学生不会在给他们的盒子里进行优化,他们会寻找会彻底改变游戏性质的漏洞。在软件工程中,这是使用新工具和数据结构的形式,在机器学习工程中,这将是调整新的模型类型或如何部署。我怀疑随着软件工程变得越来越自动化,机器学习工程师将推动最好的公司。

这篇文章的灵感来自于人工智能播客上的一段对话,莱克斯·弗里德曼主持了吴恩达,讨论了大规模在线开放课程的影响,计算机科学是如何教授的,以及大型科技公司如何主导市场。

更多?订阅我关于机器人、人工智能和社会的时事通讯!

[## 自动化大众化

一个关于机器人和人工智能的博客,让它们对每个人都有益,以及即将到来的自动化浪潮…

robotic.substack.com](https://robotic.substack.com/)

机器学习进化——感知机的故事

原文:https://towardsdatascience.com/machine-learning-evolution-the-story-of-perceptron-b1de3f180ed6?source=collection_archive---------52-----------------------

这一切是如何开始到我们现在的位置

一个神经元细胞— 背景向量由 brgfx 从 freepik 创建

A 人工智能(AI)是新的电。它已经成为镇上的话题。像机器学习(ML)和深度学习(DL)这样的花哨词汇现在是企业界提供的每个产品或解决方案的强制性部分,以激励他们的客户和最终用户。但在现实中,这些不再仅仅是花哨的术语。

在过去的几十年里,人工智能的众多应用已经出现,这些应用正在解决现实世界的问题,使其成为一种全球现象。吴恩达是成千上万像我一样有抱负的机器学习者的导师,他将人工智能称为新的电力,并说:

正如 100 年前电力几乎改变了一切一样,今天我实际上很难想到一个我认为人工智能在未来几年内不会改变的行业。

每一家主要的技术公司都已经适应了这场计算机革命,因为他们了解主要的技术趋势,不能冒被甩在后面的风险。ML 会在这里停留一段时间,如果你是一个寻求提升你的投资组合技能的开发者,我建议你开始学习。另外,报酬也更高。

人工智能已经颠覆了所有主要行业。今天,由于其在医疗保健、神经科学、农业、安全、监控等领域的跨领域应用,人工智能和人工智能已经成为我们生活中不可或缺的一部分。多年来,人工智能已经进化,现在它有能力帮助人类。但是这一切都是从大约五十年前感知器发明的时候开始的。

在我们继续我们大约有 65 年历史的感知机故事之前,让我们先非正式地定义一下感知机:

感知器是一种方便的生物神经元的人工模型。它是一种用于监督学习的单层神经网络算法。它由输入值、权重和偏差以及激活函数组成。

单个感知器单元—作者图片

我们不讨论技术细节,让我们继续我们的故事。

感知器的崛起

感知器是神经网络的基本构件,由 Frank Rosenblatt 于 1957 年 1 月在纽约布法罗的康奈尔航空实验室发明。这项发明是名为“感知机——一种感知和识别自动机”的研究成果

韦氏词典将自动机定义为:

一种机器或控制机构,设计成自动遵循预定的操作顺序或对编码指令作出反应。

这是为期五年的研究的一部分,旨在设计一种能够学习复杂模式、模式感知和归纳的电子大脑模型。这项研究背后的直觉是构建一种具有类似人类功能的设备,如感知、概念形成、从经验中归纳的能力、识别复杂的信息模式以及感知不同大小、形状和方向的类似对象。

然而,为了执行所有这些操作,传统的计算机系统将需要存储数千个(如果不是数百万个)图案,然后每当需要时,搜索这些过量的图案以识别看不见的图案,这在计算上非常昂贵,并且不是识别图案或物体的经济方式。

为了解决这个问题,Frank Rosenblatt 提出了一个系统,该系统可能会根据生物大脑的原理工作,并使用概率方法而不是确定性方法来识别模式之间的相似性。

他的感知机模型由三个主要部分组成:

  • 感觉系统
  • 联想系统
  • 响应系统。

这三个主要系统中的每一个都将进一步包含相互连接的单元。可以根据正在识别的模式打开或关闭这些连接。感觉系统会接受输入模式。关联系统将打开或关闭特定的连接,并使用响应系统呈现输出。

感知器模型是通过构建名为 Mark 1 感知器的定制硬件来赋予生命的,它主要是为图像识别而设计的。它是一个黑匣子,很像当今的神经网络,有输入层、隐藏层和输出层。

Mark I Perceptron —康奈尔大学新闻服务记录,4–3–15 号。康奈尔大学图书馆珍本和手稿收藏部

反向传播到达现场

现在向前移动几十年,感知器的故事继续了 Geoffrey Hinton 在 1986 年提出的工作,当时他提出了一种新的学习程序,名为反向传播,后来成为现代神经网络模型的支柱。该技术通过调整神经网络模型的权重来最小化实际值和期望值之间的差异。它使神经网络学习或提取特征,并概括输入的模式或序列,以对看不见的数据表示做出相当准确的预测。

多层神经网络模型中的反向传播可视化—图片由作者提供

自那时以来,已经取得了许多进展。现在,我们已经有了 VGGNet、ResNet、Inception 等模型,可以快速准确地对对象进行分类。所有这些都是基于这样一个事实,即我们正试图模仿人脑。

但问题仍然存在,我们是否已经了解我们的大脑是如何识别我们日常生活中看到的物体的?随着每一天的过去,神经科学研究人员都在假设大脑理论,帮助我们理解我们的大脑如何学习、感知和记忆模式。

最先进的机器学习

杰夫·霍金斯提出了一个这样的理论,他称之为智力的千脑理论,它告诉我们大脑中被称为新皮层的部分是如何负责制作某个物体的各种模型,然后以分层的方式投票,以达成共识,告诉我们正在感觉、感知或看到什么。

该理论表明,当我们在现实生活中看到某个物体时,我们的新皮层中会有一组特定的神经元被激活。现在,如果我们面对一个不同大小和方向的相似物体,我们的新大脑皮层中会有一组相似的神经元被激活,这使我们能够概括我们在日常生活中看到的物体。事情没那么简单,但你可以大致了解一下。

这是一种不同于传统的 ML 或最先进的 DL 的方法,后者需要大量的输入表示来学习模式,然后进行预测。

可视化新大脑皮层中神经元的层次——图片由格尔德·奥特曼提供,来自皮克斯巴伊,由作者编辑,灵感来自努门塔·HTM

杰夫·霍金斯创立了 Numenta,致力于将最先进的神经科学理论,如智能的千脑理论与人工智能相结合,以创造真正智能的机器,这些机器的工作原理与生物大脑相同。我们可能还有很长的路要走,但我们肯定正朝着正确的方向前进。我们已经取得了重大进展,而感知机是这一切的核心。

故事继续…

作为一名有抱负的数据科学研究人员,我觉得我们欠计算世界的早期思想家很多。从 1642 年布莱士·帕斯卡发明第一台机械计算器开始。献给阿达·洛芙莱斯,他是第一个在 1842 年描述解决数学问题的一系列操作的人。艾伦·图灵,他在 1950 年创造了世界闻名的图灵测试,以及历史上更多的人。

随着人工智能领域目前的进步,我们往往会忘记导致我们今天能够做的出色工作的卑微开端。对任何研究人员来说,研究直觉并使用有意识的推理来证明直觉的能力是最大的财富。所以,让你的直觉驱使你走向科学的伟大,成为这一进化的一部分。

机器学习实验跟踪

原文:https://towardsdatascience.com/machine-learning-experiment-tracking-93b796e501b0?source=collection_archive---------6-----------------------

为什么实验跟踪对于进行真实世界的机器学习如此重要?

乍一看,构建和部署机器学习模型看起来很像编写代码。但是有一些关键的差异使得机器学习更加困难:

  1. 机器学习项目比典型的软件项目有更多的分支和实验。
  2. 机器学习代码一般不会抛出错误,只是表现不佳,使得调试变得格外困难和耗时。
  3. 训练数据、训练代码或超参数中的一个微小变化都会极大地改变模型的性能,因此重现早期的工作通常需要与之前的设置完全匹配。
  4. 运行机器学习实验可能非常耗时,而且计算成本可能会变得非常昂贵。

有组织地跟踪实验有助于解决所有这些核心问题。weights and bias(wandb)是一个简单的工具,可以帮助个人跟踪他们的实验——我与不同规模团队的几位机器学习领导者谈论过他们如何使用 wandb 来跟踪他们的实验。

开始使用 wandb 进行实验跟踪

查看现场仪表盘

ML 项目进展的基本单位是实验,所以大多数人以某种方式跟踪他们正在做的事情——通常我看到从业者从电子表格或文本文件开始跟踪他们正在做的事情。

电子表格和文档非常灵活——这种方法有什么问题?

这是几年前我在一个项目中使用的谷歌文档:

我确信这些笔记在当时很重要,但现在我不知道这些笔记是什么意思。

权重和偏差使得自动记录所有超参数(输入)和指标(输出)变得非常简单。

一个典型的项目在 wandb

这就是你如何在 pytorch 中设置 wandb(你可以在文档中找到其他常见的 ML 框架)。

**import wandb****wandb.init(config=args)** # track hyperparameters
**wandb.watch(model)** # track model metricsmodel.train()
for batch_idx, (data, target) in enumerate(train_loader):
  output = model(data)
  loss = F.nll_loss(output, target)
  loss.backward()
  optimizer.step() **wandb.log({“loss”: loss})** # track a specific metric

一旦设置好,Weights and Biases 就会默认监控很多东西。任何命令行参数都成为保存的超参数。pytorch 提供的任何值都成为度量。实验可以自动链接到最新的 git 提交或训练代码的确切状态。被动地收集信息真的很重要,因为持续地写下你可能关心的所有事情几乎是不可能的。

实验概述权重&偏差

写下关于你稍后构建的模型的定性注释也是极其重要的。在 Weights and Biases 中,您可以创建报告来跟踪模型度量的注释,并与您的团队共享您的发现和进展。

在后台收集系统指标就是一个很好的例子。Wandb 在后台收集系统使用指标,如分配的 GPU 内存、网络流量和磁盘使用情况。大多数情况下,您不需要查看所有这些信息,但是在您不再使用大部分 GPU 内存的情况下进行更改是很容易的,并且很难跟踪您何时进行了更改。如果你用 wandb 对你的训练代码进行一次测试,你将能够回顾你所有的实验,并看到用法在哪里发生了变化。

实时仪表盘中查看

使用实验跟踪来比较不同实验的结果

典型的 ML 工作流程包括运行大量实验。我们发现,在其他结果的背景下观察结果比单独观察一个实验更有意义。

同时查看大量实验很快就会变得混乱。有许多输入在变化,也有许多不同的可能输出。一些运行不可避免地会过早失败。

不同的实验风格导致不同的工作流程,但是我们发现记录下你可能关心的每一个指标,并用一些对你有意义的一致标签来标记实验,可以让事情在以后变得更有条理。

实时仪表盘中查看。

一旦你记录了大量的模型,你就有更多的维度需要检查,而不是一下子就能看到。我们发现的一个强大的可视化工具是平行坐标图。

查看实时仪表盘

这里每行是一个单独的实验,每列是一个输入超参数或输出度量。我突出显示了最高精度运行,它非常清楚地表明,在我选择的所有实验中,高精度来自低压差值。

跨实验查看是如此重要,以至于 wandb 允许您构建工作空间,您可以在其中选择像散点图这样的可视化图形组,然后立即查看所选运行的比较

查看具体例子

总的指标是好的,但是看具体的例子是必要的。函数 wandb.log() 可以处理各种数据类型,并自动可视化。

查看现场报道

测井图像

记录图像对于许多应用来说非常重要,可以在多次运行中查看图像。以下是构建 GAN 的不同方法以及不同规模和时间步长下的结果。

测井 Matplotlib 图

通常代码已经在 matplotlib 中跟踪了一些东西——如果你记录了图表,它将被永久保存,并且很容易恢复。事实上,你可以为你的训练代码的每一步记录一个独特的图表。

使用实验跟踪管理分布式培训

当进行分布式训练时,即使只是可视化结果也会变得更加困难。

在多台计算机上的分布式运行中,每个实例都可以调用 wandb init 并设置 group 和 job_type,如下所示:

wandb.init(group=”first-run”, job_type=”train”)

查看实时仪表盘

Wandb 将显示集合在一起的组中所有运行的指标,但也可以查看单个流程,看看它们的表现如何。

使用实验跟踪报告管理团队协作

随着团队的成长,跟踪一切变得越来越重要。Wandb 允许您构建静态报告,精确显示您使用聚合统计数据运行的实验,并具有深入挖掘的能力。

在 OpenAI 机器人团队中,wandb 报告是 ML 从业者记录他们所做工作并与同事分享的地方。当一个变化可能无意中损害了进展时,可视化是至关重要的。

在潜伏空间,每个团队项目会议都以审查最新的 wandb 实验报告开始,并围绕当前方法的效果以及下一步应该尝试什么实验进行讨论。

查看现场报道

使用实验跟踪作为模型的记录系统

随着团队的成长和模型被部署到产品中,记录所发生的一切变得越来越重要。在丰田研究所,wandb 实验链接被用作每一款 ML 车型的官方记录。如果在模型构建的下游发生了一些事情,他们可以将问题追溯到 wandb 培训运行。从一组实验中构建一份报告意味着对所做的工作有一个永久的记录,团队可以很容易地回去回顾到底发生了什么。

通过 eli5 的机器学习可解释性介绍

原文:https://towardsdatascience.com/machine-learning-explainability-introduction-via-eli5-99c767f017e2?source=collection_archive---------38-----------------------

从您的机器学习模型中提取洞察力

照片由 Unsplash 上的 h heyerlein 拍摄

介绍

根据我作为数据科学家的工作经验,大多数时候,你需要解释为什么你的模型有效,以及你的模型给出了什么样的洞察力。就洞察力而言,我指的不是模型准确性或任何指标,而是机器学习模型本身。这就是我们所说的机器学习的可解释性。

机器学习可解释性最直接的例子是带有普通最小二乘估计方法的线性回归模型。让我用一个数据集给你举个例子。请注意,我违反了一些普通的最小二乘假设,但我的观点不是创建最佳模型;我只是想有一个模型,可以提供一个洞察力。

#Importing the necessary package
import pandas as pd
import seaborn as sns
import statsmodels.api as sm
from statsmodels.api import OLS#Load the dataset and preparing the data
mpg = sns.load_dataset('mpg')
mpg.drop(['origin', 'name'], axis =1, inplace = True)
mpg.dropna(inplace = True)#Ordinary Least Square Linear Regression model Training
sm_lm = OLS(mpg['mpg'], sm.add_constant(mpg.drop('mpg', axis = 1)))
result = sm_lm.fit()result.summary()

我不会详细解释该模型,但线性模型假设在自变量(要预测的特征)和因变量(要预测的内容)之间存在线性。等式如下所示。

这里重要的是,每个自变量(x)都要乘以系数(m)。这意味着系数说明了自变量和因变量之间的关系。从上面的结果中,我们可以看到“model_year”变量的系数(coef)为 0.7534。这意味着‘model _ year’每增加 1,因变量‘mpg’值就会增加 0.7534。

线性回归模型及其系数是机器学习可解释性的一个例子。模型本身用于解释我们的数据发生了什么,并且洞察的提取是可能的。然而,并不是所有模型都能做到这一点。

黑盒模型的机器学习可解释性

基于树的特征重要性

随机森林等机器学习模型通常被视为黑盒。为什么?一个森林由大量的深层树组成,其中每棵树都使用随机选择的特征对袋装数据进行训练。通过检查每一棵树来获得全面的理解几乎是不可能的。

例如,xgboost 包中著名的 XGBoost 分类器几乎是一个利用随机森林过程的黑盒模型。这个模型被认为是一个黑盒模型,因为我们不知道在模型学习过程中发生了什么。让我们以同一个数据集为例来尝试一下。

#Preparing the model and the datasetfrom xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
mpg = sns.load_dataset('mpg')
mpg.drop('name', axis =1 , inplace = True)#Data splitting for xgboost
X_train, X_test, y_train, y_test = train_test_split(mpg.drop('origin', axis = 1), mpg['origin'], test_size = 0.2, random_state = 121)#Model Training
xgb_clf = XGBClassifier()
xgb_clf.fit(X_train, y_train)

就这样,我们有了模型,但是我们从数据中得到了什么启示吗?或者我们能知道依赖者和独立者之间的关系吗?。

你可能会说分类器拥有一个特征重要性方法,这是一个树模型,专门用来衡量特征的重要性。准确地说,它测量特征对模型的平均杂质减少的贡献。

tree_feature =  pd.Series(xgb_clf.feature_importances_, X_train.columns).sort_values(ascending = True)plt.barh(X_train.columns, tree_feature)
plt.xlabel('Mean Impurity Reduction', fontsize = 12)
plt.ylabel('Features', fontsize = 12)
plt.yticks(fontsize = 12)
plt.title('Feature Importances', fontsize = 20)

在一定程度上,这是一个机器学习可解释的例子。但是,您需要记住 xgboost 依赖于引导过程来创建模型。也就是说,这个特征的重要性可能会因为随机过程而发生。此外,该贡献仅表明该特征可以减少多高的总杂质(总的来说是所有产生的树的平均值)。

通过 eli5 的排列重要性

还有另一种方法可以从基于树的模型中获得洞察力,方法是逐个置换(改变位置)每个特征的值,并检查它如何改变模型性能。这就是我们所说的排列重要性方法。我们可以尝试使用 eli5 包将这种方法应用到我们的 xgboost 分类器中。首先,我们需要使用下面的代码来安装这个包。

#installing eli5pip install eli5
#or
conda install -c conda-forge eli5

安装后,我们将从现在开始使用 eli5 包进行机器学习解释。让我们从排列重要性开始。

#Importing the module
from eli5 import show_weights
from eli5.sklearn import PermutationImportance#Permutation Importance
perm = PermutationImportance(xgb_clf, scoring = 'accuracy' ,random_state=101).fit(X_test, y_test)
show_weights(perm, feature_names = list(X_test.columns))

排列重要性背后的思想是如何评分(准确度、精确度、召回率等。)shift 随特征存在与否,在上面的结果中我们可以看到,displacement 得分最高,为 0.3797。这意味着,当我们置换位移特征时,它将改变模型的精度高达 0.3797。正负符号后的值是不确定度值。排列重要性方法本质上是一个随机过程;这就是为什么我们有不确定值。

位置越高,这些特征对得分的影响越大。底部的一些特征显示了一个负值,这很有趣,因为这意味着当我们改变特征时,这个特征增加了得分。发生这种情况是因为偶然的特征排列实际上提高了分数。

通过测量杂质减少和排列重要性,我们已经知道了这两种方法。它们是有用的,但在某种意义上说,它们是粗糙的和静态的,很难理解个人对实际数据的决策。这就是为什么我们会使用基于树决策路径的 eli5 权重特征重要性计算。

通过 eli5 确定树特征的重要性

让我们使用 eli5 来检查 XGBoost 分类器特性的重要性。

show_weights(xgb_clf, importance_type = 'gain')

我们可以看到“位移”特征是最重要的特征,但我们还不明白我们是如何得到重量的。因此,让我们看看分类器如何尝试预测单个数据。

#Taking an example of test datafrom eli5 import show_prediction
show_prediction(xgb_clf, X_test.iloc[1], show_feature_values=True)

上表显示了我们的分类器如何根据给定的数据预测我们的数据。每个类别都有自己的概率,以及每个特征对概率和分数的贡献(分数计算基于决策路径)。分类器还引入了<BIAS>特征,它是模型基于训练集的分布输出的期望平均得分。如果你想了解更多,你可以查看这里的。

上表中最重要的是每个特征都对预测结果有贡献,因此特征贡献影响权重结果。权重是所有树中对最终预测有贡献的每个特征的百分比(如果将权重相加,它将接近 1)。

有了这个软件包,我们不仅可以根据功能性能得分,还可以根据每个功能本身对决策过程的贡献来衡量功能的重要性。

结论

有了 eli5,我们能够将黑盒分类器转变为更易解释的模型。我们仍然有很多方法可以用于机器学习的解释目的,你可以在 eli5 主页上查看。

如果您喜欢我的内容,并希望获得更多关于数据或数据科学家日常生活的深入知识,请考虑在此订阅我的简讯。

如果您没有订阅为中等会员,请考虑通过我的推荐订阅。

机器学习在嵌入式系统上是失败的。原因如下

原文:https://towardsdatascience.com/machine-learning-fails-when-it-comes-to-embedded-system-9ce6def9ba75?source=collection_archive---------6-----------------------

思考不同

深入了解嵌入式世界以及 ML 行业目前还不能解决的问题

丹尼尔·威德罗在 Unsplash 上的照片

今天,中文学习达到了顶峰,最终被广泛使用。你可以在机场看到人脸识别系统,在脸书看到个性化的广告。

虽然,当我们谈到将 ML 与嵌入式设备相结合时,仍然有相当大的差距

1.我们不明白嵌入式世界是什么

使用 ML,我们曾经拥有巨大的计算能力。

AlexNet 需要 727 MegaFlops 和 235Mb 内存来处理一个 227x227px 的小图像。例如,谷歌 Nexus S 上的 ARM Cortex-A8 每秒可以产生 66 兆次浮点运算。所以,你要等~11 秒才能推断。太多了!

*FLOP —浮点运算

查看更多信息 : 对各种 CNNARM 内核浮点性能及其效率的内存消耗和 FLOP 计数的估计。

我在大学里学过几门与 ML 相关的课程。我们做了很多很酷的作业。但即使在那里,我的 4GB GTX1050 也不足以训练所有的模型。

理解问题是制造正确产品的关键

一般 ML 工程师很少考虑计算资源。而且,他/她很少关心内存使用。为什么?因为它很便宜,甚至你的手机有很好的 CPU 和很大的内存。

提到上次聚会的照片,你还会觉得手机内存不足吗?假设您使用具有 256KB 闪存的 TrueTouch 感应控制器。是的,256KB。由于现有的固件,你不能使用所有这些。大约 100KB。看看你最后的型号。可能要大得多。

变得有趣了吗?我们继续:)

听到“嵌入式设备”你会怎么想?想象这幅画,并把它记在心里。

1.它是任何电动机械。甚至我的微波炉和洗衣机

马科斯·拉米雷斯在 Unsplash 上的照片

是的,你是对的!

如今,几乎所有的电子设备都是嵌入式设备。它内部可能有一个或几个控制器,负责每个确切的功能:触摸感应、发动机状态监控等。

2.Arduino 或/和树莓派

哈里森·布罗德本特在 Unsplash 上拍摄的照片

恭喜你,你又答对了!

它们是 DIY 项目中最受欢迎和广泛使用的工具包之一。是的,它们是嵌入式设备。

3.杰特森纳米和类似产品

英伟达照片

又对了。

这是一个特殊的开发工具包“又名迷你电脑”,专为在其上运行 ML 模型而开发。它非常强大,说实话,超级性感。

但是这里遗漏了一些东西

我有许多朋友正在做令人难以置信的硬件宠物项目。他们那里一般用 Arduino 或者 STM32(又名硬核 Arduino)。

智能头盔、机器人汽车和 ALU

我认识几个人工智能工程师,他们对 Jetson Nano 和类似的设备感到兴奋。他们认为这是嵌入式人工智能的未来。

英伟达照片

而现在。请想一想“这样的设备有多少是用在生产层面的?”

答案是——微小

想想你家里有多少电器设备。然后在你的车里增加大量的控制器。你工作中的安全系统。我可以列出一个很长的清单。

且每个设备都有一些控制器。通常,它是微型的,而且超级便宜。不能和杰特森或者树莓的资源和能力相比。

想象你有一个微控制器。它的主要任务是处理你在屏幕上的手指触摸。它有 ARM Cortex-M0 处理器,256KB 内存(其中只有 80–120 可供您使用)。这是一个实时系统,所以你有很少的时间来为你的模型做出推断,比如说 100 微秒。你的目标是改进或替换那里的一些算法。

祝你好运,欢迎来到“嵌入式人工智能”的世界。

嵌入式世界”由 1-2 美元的芯片组成,资源有限。这是在生产层面上使用的

2.纯基础设施

我一直在做我上面描述的项目。一切都很好。我开发了一个小型网络,它有可能适合那个微控制器。

马蒂·林恩·巴恩斯在 Unsplash 上拍摄的照片

将模型从我的电脑转移到设备的时间已经开始了!

  1. 量化。

那个处理器不能处理浮点数。即使可以,我们也不会使用它,因为这是一个相当复杂的操作,需要很多时间。

所以,我做了模型权重量化——将连续范围的值转换成有限范围的离散值。

你猜怎么着?PyTorch 和 TensorflowLite 都不完全支持。它们不支持所有激活功能(虽然我使用了非常简单的 HardTanh)。PyTorch 甚至无法将量化模型保存到文件中。

所以,我只能用手来做。

2。推理代码生成

您希望在该控制器上运行您的模型。对吗?所以,你需要 C 代码进行模型推断。

很悲哀,但你必须用手去做。为什么?PyTorch 没有推理代码生成的功能。相比之下,TFLite 有,但是它非常有限,也不支持常见的激活功能。

所以,我又用手做了一次。

我在工作中遇到过很多这样的情况。不是往 PyTorch 或者 TF 这边一拳,而是“呼救”。

* * 社区还有另外一面,那就是在找“嵌入式 AI”的专业工具,却找不到。**

有什么好消息吗?

我看到大型半导体公司对人工智能有巨大的兴趣,他们正在做非常有价值和重要的事情。它们值得再写一篇文章,所以我列出了几个,以免这篇文章太长。

  • CMS is-NN——面向 Arm Cortex-M 处理器的高效神经网络内核
  • 编译器可以产生高效的推理代码,并根据您所拥有的硬件进行优化
  • 还有很多其他很酷的东西

照片由艾哈迈德·哈桑Unsplash 上拍摄

觉得这篇文章有用?看看下面另一篇有趣的文章

[## 我们需要数学吗?想象一下我们没有它的生活

没有数学的世界之旅,以及为什么抽象是一切的关键

medium.com](https://medium.com/swlh/do-we-need-math-imagine-our-life-without-it-c458fda152b3)

机器学习领域指南

原文:https://towardsdatascience.com/machine-learning-field-guide-726989c928a1?source=collection_archive---------66-----------------------

没有 BS 指南和概述机器学习(真相),从开始到结束,垃圾到黄金

我们都必须处理数据,我们试图了解机器学习并将其应用到我们的项目中。但是大家好像都忘了一件事…远非完美,还有那么多要经历!别担心,我们会从头到尾讨论每一个小步骤👀。

你所需要的就是这些基础知识

照片由 国立癌症研究所 上传于 Unsplash

这一切背后的故事

我们都是从一个数据集或一个目标开始的。一旦我们发现、收集或搜集了我们的数据,我们就把它拉起来,目睹无情的数字细胞、更多的数字、类别,也许还有一些单词的压倒性景象😨!一个天真的想法闪过我们的脑海,用我们的机器学习能力来处理这一团乱麻…但是快速搜索揭示了我们在训练模型之前需要考虑的大量任务😱!

一旦我们克服了难以控制的数据带来的冲击,我们就会想方设法与强大的对手作战🤔。我们从尝试将数据导入 Python 开始。理论上是比较简单的,但是过程可以稍微……涉及。然而,只需要一点点努力(幸运的我们)。

没有浪费任何时间,我们开始数据清理去伪存真。我们的方法从简单开始——观察并移除。它工作了几次,但后来我们意识到…它真的对我们不公平!为了处理这些混乱,我们找到了一个强大的工具来补充我们的武器库:图表!通过我们的图表,我们可以对我们的数据、数据中的模式以及缺失的地方有所了解。我们可以内插(填充)或删除缺失的数据。

最后,我们接近我们高度期待的😎挑战,数据建模!稍加研究,我们就能发现哪些战术和模型是常用的。这是一个有点困难的破译,我们应该使用哪个,但我们仍然设法通过它,并把它都搞清楚了!

但是,如果不做一些令人印象深刻的事情,我们就无法完成一个项目。所以,一个最终的产品,一个网站,一个 app,甚至一个报告,都会带我们走很远!我们知道第一印象很重要,所以我们修复了 GitHub 库,并确保一切都有很好的记录和解释。现在,我们终于能够向世界展示我们的辛勤工作了😎!

时代

第 1 章—导入数据

数据有各种各样的形状和大小,所以我们用来把所有东西编码的过程经常是不同的。

说实在的,导入数据看起来很容易,但是有时候……有点讨厌。

数据清理最难的部分不是编码或理论,而是我们的准备工作!当我们第一次开始一个新项目并下载我们的数据集时,打开一个代码编辑器并开始输入是很诱人的…但是这不会给我们带来任何好处。如果我们想领先一步,我们需要为数据中最好和最差的部分做好准备。要做到这一点,我们需要从 basic 开始,通过手动检查我们的电子表格。一旦我们理解了数据的基本格式(文件类型以及任何细节),我们就可以将它们全部导入 Python。

如果我们运气好,只有一个电子表格,我们可以使用 Pandas [read_csv](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html)函数(让它知道我们的数据在哪里):

pd.read_csv("file_path.csv")

事实上,我们会遇到更复杂的情况,所以请注意:

  • 包含不需要的信息的文件(我们需要跳过)
  • 我们只想导入几列
  • 我们想重命名我们的列
  • 数据包括日期
  • 我们希望将来自多个来源的数据合并到一个地方
  • 数据可以分组在一起

尽管我们在讨论一系列场景,但我们通常一次只处理几个。

我们的前几个问题(导入数据的特定部分/重命名列)很容易处理,只需使用几个参数,如要跳过的行数、要导入的特定列以及我们的列名:

pd.read_csv("file_path.csv", skiprows=5, usecols=[0, 1], names=["Column1", "Column2"])

每当我们的数据分布在多个文件中时,我们可以使用 Pandas [concat](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.concat.html)函数将它们组合起来。[concat](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.concat.html)函数将一系列[DataFrame](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html)组合在一起:

my_spreadsheets = [pd.read_csv("first_spreadsheet.csv"), pd.read_csv("second_spreadsheet.csv")]
pd.concat(my_spreadsheets, ignore_index=True)

我们解析到[concat](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.concat.html)一个电子表格列表(就像之前一样导入)。当然,列表可以通过任何方式获得(所以一个奇特的列表理解或者每个文件的随意列表都可以),但是请记住我们需要的是数据帧,而不是文件名/路径

如果我们没有 CSV 文件,熊猫仍然工作!我们可以用 [read_csv](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html)换成[read_excel](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_excel.html)[read_sql](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_sql.html)或者另一个选项

在所有数据都在 Pandas 数据框架中之后,我们需要再次检查数据的格式是否正确。实际上,这意味着检查每个 series 数据类型,并确保它们不是通用对象。我们这样做是为了确保我们可以利用 Pandas 内置的数字、分类和日期/时间值功能。来看看这刚刚运行的DataFrame.dtypes。如果输出看起来合理(例如,数字是数字,类别是分类的,等等),那么我们应该可以继续。然而,通常情况并非如此,因为我们需要改变我们的数据类型!熊猫[DataFrame.astype](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.astype.html)可以做到这一点。如果这不起作用,应该有另一个熊猫函数用于特定的转换:

data["Rating"] = data["Rating"].as_type("category")
data["Number"] = pd.to_numeric(data["Number"])
data["Date"] = pd.to_datetime(data["Date"])
data["Date"] = pd.to_datetime(data[["Year", "Month", "Day", "Hour", "Minute"]])

如果我们需要分析不同的数据组(例如,我们的数据可能是按国家划分的),我们可以使用 Pandas groupby。我们可以使用groupby来选择特定的数据,并分别对每个组运行函数:

data.groupby("Country").get_group("Australia")
data.groupby("Country").mean()

其他更适合的技巧,如多重/分层索引,在特定场景中也有帮助,但是理解和使用起来更棘手。

第 2 章—数据清理

数据是有用的,数据是必要的,但是,它需要干净并且切中要害!如果我们的数据无处不在,那么它对我们的机器学习模型根本没有任何用处。

每个人都会被丢失的数据逼疯,但隧道的尽头总会有一线光明。

完成数据清理最简单快捷的方法是问我们自己:

我们数据中的哪些特征会影响我们的最终目标?

所谓最终目标,我们指的是我们正在努力预测、分类或分析的任何变量。这一点是为了缩小我们的范围,而不是陷入无用的信息。

照片由 亚当·诺瓦克斯基 在 Unsplash 上拍摄

一旦我们知道我们的主要目标特征是什么,我们就可以尝试找到模式、关系、缺失数据等等。一个简单而直观的方法就是绘图!快速使用 Pandas 勾画出数据集中的每个变量,并尝试查看每个变量的位置。

一旦我们发现了潜在的问题,或者数据中的趋势,我们就可以尝试解决它们。一般来说,我们有以下选择:

  • 删除丢失的条目
  • 删除整列数据
  • 填写缺失的数据条目
  • 对数据进行重新采样(即改变分辨率)
  • 收集更多信息

从识别丢失的数据到选择如何处理它,我们需要考虑它如何影响我们的最终目标。对于缺失的数据,我们删除任何似乎对最终结果没有重大影响的数据(即,我们找不到有意义的模式),或者似乎缺失太多而无法得出值。有时,我们还决定删除非常少量的缺失数据(因为这比填充数据更容易)。

如果我们决定摆脱信息,熊猫[DataFrame.drop](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.drop.html)可以被使用。它从数据帧中删除列或行。这很容易使用,但是记住默认情况下 Pandas 不会修改/删除源数据帧中的数据,所以必须指定inplace=True。注意到axis参数指定是否移除行或列可能是有用的。

当不删除一整列时,或者特别针对丢失的数据时,依靠一些漂亮的 Pandas 函数通常是有用的。为了删除空值,可以使用DataFrame.dropna。请记住,默认情况下,dropna会完全删除所有丢失的值。然而,将参数how设置为all或者设置阈值(thresh,表示需要删除多少空值)可以对此进行补偿。

如果我们有少量的不规则缺失值,我们可以用几种方法来填充它们。最简单的是DataFrame.fillna,它将缺失值设置为某个预设值。更复杂但灵活的选择是使用DataFrame.interpolate进行插值。插值本质上允许任何人简单地设置他们想要用来替换每个空值的方法。这些包括上一个/下一个值、线性值和时间值(后两个值根据数据进行推断)。无论何时与时间打交道,时间都是一个自然的选择,否则就要根据插值的数据量及其复杂程度做出合理的选择。

data["Column"].fillna(0, inplace=True)
data[["Column"]] = data[["Column"]].interpolate(method="linear")

如上所述,需要在一个只包含丢失数据的列的数据帧中传递插值(否则将抛出错误)。

每当我们看到定期丢失的数据或使用不同时标的多个数据源时(如确保可以合并以分钟和小时为单位的测量值),重采样就非常有用。直观地理解重采样可能有点困难,但当您对特定时间范围内的测量值进行平均时,这是非常重要的。例如,我们可以通过指定要获取每月值的平均值来获取每月值:

data.resample("M").mean()

"M"代表月份,可以替换为"Y"代表年份和其他选项。

尽管数据清理过程可能相当具有挑战性,但是如果我们记住我们最初的意图,它将成为一个更加合理和直接的任务!如果我们仍然没有所需的数据,我们可能需要回到第一阶段,收集更多的数据。请注意,丢失数据表明数据收集存在问题,因此仔细考虑并记下出现问题的位置非常有用。

为了完成,熊猫 [*unique*](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.unique.html) [*value_counts*](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.value_counts.html) 函数有助于决定直接移除哪些特征以及绘制/研究哪些特征。

第 3 章——视觉化

观想听起来很简单,事实也确实如此,但是很难做到……不过分复杂。对我们来说,把情节看作是创造的苦差事实在是太容易了。然而,这些坏男孩做了一件非常非常好的事情——直观地展示了我们数据的内部工作原理!请记住:

我们用图表数据来发现和解释一切是如何工作的。

因此,当陷入想法,或不太确定该做什么时,我们基本可以总是依靠识别有用的模式和有意义的关系。这可能看起来玄乎🥶,但它确实是有用的。

我们的目标不是绘制花哨的六边形图,而是描绘正在发生的事情,所以绝对任何人都可以简单地解读一个复杂的系统!

一些技巧无疑是有用的:

  • 当我们有太多数据时进行重采样
  • 绘图具有不同比例时的次坐标轴
  • 当我们的数据可以分类拆分时进行分组

要开始绘图,只需在任何系列或数据帧上使用熊猫.plot()!当我们需要更多时,我们可以深入研究 MatPlotLib、Seaborn 或一个交互式绘图库。

data.plot(x="column 1 name", y="column 2 name", kind="bar", figsize=(10, 10))
data.plot(x="column 1 name", y="column 3 name", secondary_y=True)
data.hist()
data.groupby("group").boxplot()

90%的情况下,这个基本功能就足够了(更多信息,请点击),如果没有,搜索应该会显示如何绘制特别奇特的图形😏。

Luke Chesser 在 Unsplash 上拍摄的照片

第 4 章——建模

简要概述

现在终于到了有趣的事情——得出结果。训练一个 scikit 学习模型看起来很简单,但是没有人去研究细节!所以,让我们诚实地说,不是每个数据集和模型都是平等的。

基于我们的数据,我们的建模方法会有很大的不同。有三个特别重要的因素:

  • 问题类型
  • 数据量
  • 数据的复杂性

我们的问题归结为我们是否试图预测一个类/标签(称为分类)、一个值(称为回归)或者一组数据(称为聚类)。如果我们试图在数据集上训练一个模型,其中我们已经有了我们试图预测的例子,我们称我们的模型有监督,如果没有,称无监督。可用数据的数量及其复杂程度预示着一个模型有多简单就足够了。具有更多特征(即列)的数据往往更复杂

解释复杂性的要点是理解哪些模型对我们的数据来说太好或太差

模型拟合优度告诉我们这一点!如果一个模型难以解释我们的数据(太简单),我们可以说它欠拟合,如果它完全矫枉过正(太复杂),我们说它过拟合。我们可以把它想象成一个从什么都没学到到什么都记住的光谱。我们需要取得平衡,以确保我们的模型能够我们的结论推广到新的信息。这通常被称为偏差-方差权衡。请注意,复杂性也会影响模型的可解释性。

修改了来自文档的 Scikit 学习图

复杂的模型需要更多的时间来训练,尤其是大型数据集。所以,升级电脑,运行一夜模型,冷静一段时间😁!

准备工作

分割数据

在训练一个模型之前,需要注意的是我们需要一些数据集来测试它(这样我们就知道它的表现如何)。因此,我们经常将数据集分成个独立的训练和测试集。这让我们可以测试我们的模型对新的未知数据的概括能力有多强。这通常是可行的,因为我们知道我们的数据很好地代表了现实世界。

实际的测试数据量并没有太大关系,但是经常使用 80%训练,20%测试。

在 Python 中用 Scikit 学习[train_test_split](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html)函数是这样做的:

train_data, test_data = train_test_split(data)

交叉验证是将数据集分成几个部分(即原始数据集的子集或部分)。这往往比使用单一测试/验证集更加健壮,并且能够抵抗过度拟合!几个 Sklearn 函数有助于交叉验证,然而,它通常直接通过网格或随机搜索来完成(下面讨论)。

cross_val_score(model, input_data, output_data, cv=5)

超参数调谐

有些因素我们的模型无法解释,因此我们设置了某些超参数。这些因型号而异,但我们可以通过人工试错法或网格或随机搜索等简单算法找到最佳值。使用网格搜索,我们尝试所有可能的值(蛮力😇)并从一些分布/选择中随机搜索随机值。这两种方法通常都使用交叉验证。

Sklearn 中的网格搜索通过一个parameters字典来工作。每个条目键表示要优化的超参数,值(一个列表或元组)是可供选择的值:

parameters = {'kernel':('linear', 'rbf'), 'C':[1, 10]}
model = = SVC()
grid = GridSearchCV(model, param_grid=parameters)

创建网格后,我们可以用它来训练模型,并提取分数:

grid.fit(train_input, train_output)
best_score, best_depth = grid.best_score_, grid.best_params_

这里重要的是要记住我们需要在训练上训练,而不是测试数据。尽管交叉验证用于测试模型,但我们最终会尝试获得训练数据的最佳拟合,并随后在测试集上测试每个模型:

test_predictions = grid.predict(test_input)

Sklearn 中的随机搜索工作方式类似,但稍微复杂一些,因为我们需要知道每个超参数采用什么类型的分布。虽然从理论上来说,T7 可以更快地产生相同或更好的结果,但它会随着情况的变化而变化。为了简单起见,最好坚持网格搜索。

型号选择

使用模型

有了 Sklearn,就像找到我们想要的模型名,然后为它创建一个变量一样简单。查看文档链接,了解更多细节!例如

support_vector_regressor = SVR()

基本选择

线性/逻辑回归

线性回归试图将直线拟合到我们的数据。它是最基本和最基本的模型。线性回归有几种变体,如 lasso 和 ridge 回归(这是防止过度拟合的正则化方法)。多项式回归可用于拟合更高次的曲线(如抛物线和其他曲线)。逻辑回归是另一种可用于分类的变体。

支持向量机

就像线性/逻辑回归一样,支持向量机(SVM 的)尝试用直线或曲线来拟合数据点。然而,SVM 的目标是最大化边界和每个点之间的距离(而不是让直线/曲线穿过每个点)。

支持向量机的主要优势是它们能够使用不同的内核。核是计算相似性的函数。这些内核允许线性和非线性数据,同时保持相当高的效率。内核将输入映射到一个更高维度的空间,因此出现了一个边界。这个过程对于大量的特征来说通常是不可行的。神经网络或其他模型可能是更好的选择!

神经网络

所有的嗡嗡声总是关于深度学习和神经网络。它们是复杂、缓慢且资源密集型的模型,可用于复杂的数据。然而,当遇到大型非结构化数据集时,它们非常有用。

使用神经网络时,一定要小心过度拟合。一种简单的方法是跟踪误差随时间的变化(称为学习曲线)。

深度学习是一个极其丰富的领域,因此这里有太多的内容需要讨论。其实 Scikit learn 是一个机器学习库,深度学习能力很少(相比 PyTorch 或者 TensorFlow )。

决策树

决策树是建模关系的简单快捷的方法。它们基本上是一个决策树,帮助决定一个数据点属于哪个类或标签。决策树也可以用于回归问题。虽然简单,但为了避免过度拟合,必须选择几个超参数。总的来说,这些都与树有多深以及要做多少决策有关。

K-表示

我们可以使用 k-means 将未标记的数据分成几个。通常,存在的簇的数量是选定的超参数。

K-means 的工作原理是试图优化(减少)一些称为惯性的标准(即函数)。可以认为这就像试图最小化从一组质心到每个数据点的距离。

合奏

随机森林

随机森林是根据数据的随机子集训练的多个决策树的组合(引导)。这个过程称为 bagging,它允许随机森林获得与复杂数据的良好拟合(低偏差和低方差)。

这背后的基本原理可以比作民主。

一个选民可能会投票给一个糟糕的候选人,但我们希望大多数选民做出明智、积极的决定

对于回归问题,我们平均每个决策树的输出,对于分类,我们选择最流行的一个。这个可能并不总是有效,但是我们假设它通常会有效(特别是对于包含多个列的大型数据集)。

随机森林的另一个优点是,由于 democratic-esc 引导过程,无关紧要的特性不会对性能产生负面影响!

超参数的选择与决策树的选择相同,但决策树的数量也不同。由于上述原因,更多的树等于更少的过度适应!

注意,随机森林使用随机子集,替换行和列!

照片由古伊列梅·卡埃塔诺在 Unsplash 上拍摄

梯度增强

像 AdaBoost 或 XGBoost 这样的集合模型通过将一个模型堆叠在另一个模型上来工作。这里的假设是,每个连续的弱学习者将纠正前一个学习者的缺陷(因此称为提升)。因此,模型的组合应该提供每个模型的优点,而没有其潜在的缺陷。

迭代方法意味着先前的模型性能影响当前的模型,并且更好的模型被给予更高的优先级。增强模型的表现略好于套袋模型(也称为随机森林),但也更有可能过度拟合。Sklearn 为分类回归提供 AdaBoost。

第 5 章—生产

这是整个过程的最后一步,但也是最重要的一步,🧐.我们已经投入了所有这些工作,所以我们需要坚持到底,创造一些令人印象深刻的东西!

有多种选择。对于面向数据的网站来说,Streamlit 是一个令人兴奋的选择,像 Kotlin、Swift 和 Dart 这样的工具可以用于 Android/IOS 开发。带有 VueJS 这样的框架的 JavaScript 也可以用来提供额外的灵活性。

在尝试了其中的大部分之后,我真诚地推荐坚持使用,因为它比其他的要容易得多!

在这里,重要的是从一个愿景开始(越简单越好),并试图找出哪些部分是最重要的。然后试着在这些方面下功夫。继续直到完成!对于网站来说,需要像 Heroku 这样的托管服务,这样世界上的其他人就可以看到我们所有努力的惊人的最终产品🤯😱。

即使上面的选项都不适合这个场景,一份报告或一篇文章涵盖我们做了什么,我们学到了什么,以及任何建议/经验教训,以及一个记录良好的 GitHub 库是必不可少的!确保自述文件是最新的。**

照片由 Unsplash 上的this engineering RAEng拍摄

感谢阅读!

真的希望这篇文章对你有所帮助!如需更新,请在 Twitter 上关注我

如果你喜欢这本书,你可能也会喜欢完整的编码实践者手册,里面介绍了你需要知道的每一个实用的编码工具。如果你不知道该做什么项目,可以考虑看看我的《从零到英雄》指南,关于选择项目和通过网络搜集收集自己的数据集的指南(T21)。

用于异常检测的机器学习:椭圆包络

原文:https://towardsdatascience.com/machine-learning-for-anomaly-detection-elliptic-envelope-2c90528df0a6?source=collection_archive---------21-----------------------

马可·蒙斯Unsplash 上拍摄的照片

小型数据科学

欢迎回到异常检测;这是一系列关注异常值检测的“小数据”科学中的第 6 篇。今天我写的是一个叫做EllipticEnvelope的机器学习算法,它是数据科学家工具箱中的又一个工具,用于欺诈/异常/异常值检测。

如果您错过了我以前的文章,或者您有兴趣了解关于这个主题的更多信息,请找到下面的链接:

椭圆形信封

那么什么是椭圆包络,算法背后的直觉是什么?

如果你上过几何课,你可能对椭圆很熟悉——一种在二维平面上呈椭圆形的几何形状。

椭圆形外壳的概念图

上图中的绿色区域是一个椭圆。因此,算法——椭圆包络——在给定数据集周围创建一个假想的椭圆区域。落在包络线内的值被视为正常数据,任何超出包络线的值都作为异常值返回。因此,自然地,上图中的红色数据点应该被该算法识别为异常值。从该图可以明显看出,如果数据具有高斯分布,则该算法工作得最好。

履行

sklearn是机器学习算法的瑞士军刀。因此毫不奇怪,它也有一个使用椭圆包络进行异常检测的模块。下面我用 5 个简单的步骤演示了一个使用虚拟数据点的实现。

步骤 1:导入库

# import libraries
import pandas as pd
import numpy as np
from sklearn.covariance import EllipticEnvelope
import matplotlib.pyplot as plt

第二步:获取训练数据

# create a dataframe
df = pd.DataFrame(np.array([[0,1], [1,1], [1,2], [2,2], [5,6]]), columns = ["x", "y"], index = [0,1,2,3,4])# show data in a scatterplot
plt.scatter(df["x"], df["y"], color = "r")
plt.grid()

步骤 3:准备输入

# convert dataframe to arrays
data = df[['x', 'y']].values

第四步:建模

定义模型时最重要的参数是设置“污染”参数,它基本上定义了将被识别为异常值的值的比例。参数值的范围在 0 到 0.5 之间

# instantiate model
model1 = EllipticEnvelope(contamination = 0.1) # fit model
model1.fit(data)

第五步:预测

# new data for prediction (data needs to be in arrays)
new_data = np.array([[10,10], [1,1], [1,1], [1,1]])# predict on new data 
pred1 = model1.predict(new_data)
print(pred1)

负值是异常值

总结和后续步骤

本文的目的是介绍椭圆包络——一种用于异常检测的机器学习算法——并使用 Scikit-Learn 库实现该算法。如果您现在已经清楚了关键概念,那么继续尝试在真实数据集上实现它,例如,在线可用的 Iris 数据集。您应该能够对这个数据集使用上面的 5 个步骤,只需要确保您选择了正确的列以使算法工作。

生物学的机器学习:新冠肺炎下一步将如何变异?

原文:https://towardsdatascience.com/machine-learning-for-biology-how-will-covid-19-mutate-next-4df93cfaf544?source=collection_archive---------1-----------------------

来源: Pixabay

基于 K-Means 和 PCA 的基因组序列分析

许多人不太了解病毒的一点是,就像地球上所有其他为生存而挣扎的生物一样,它们会进化或变异。

只要看看人类病毒来源于蝙蝠病毒 RNA 核苷酸序列的一个片段…

aaaatcaagcttgtgttgaagaagttacaacaatctggaaaaactaagtt

…以及人类新冠肺炎 RNA 核苷酸序列的一个片段…

aaaattaaggcttcattgattaggttaccacaacacactggaagaaactaagtt

……显然,冠状病毒已经改变了其内部结构,以适应其宿主的新物种(更准确地说,冠状病毒的内部结构约有 20%发生了突变),但仍保持足够的数量,以至于它仍然忠于其原始物种。

事实上,研究表明,新冠肺炎已经多次变异,以提高其生存能力。在我们战胜冠状病毒的斗争中,我们不仅需要找到如何摧毁病毒,还需要找到病毒如何变异以及如何应对这些变异。

在这篇文章中,我将…

  • 提供什么是 RNA 核苷酸序列的表层解释
  • 使用 K-Means 创建基因组信息聚类
  • 使用主成分分析可视化聚类

…并从我们执行的每个分析程序中获得洞察力。

什么是基因组序列?

如果你对 RNA 核苷酸序列有基本的了解,可以跳过这一部分。

基因组测序,通常比作“解码”,是分析从样本中提取的脱氧核糖核酸(DNA)的过程。每个正常细胞内有 23 对染色体,这是存放 DNA 的结构。

来源。图像免费共享和商业使用。

DNA 卷曲的双螺旋结构允许它展开成梯形。这个梯子是由成对的被称为碱基的化学字母组成的。DNA 中只有四种:腺嘌呤、胸腺嘧啶、鸟嘌呤和胞嘧啶。腺嘌呤只与胸腺嘧啶结合,鸟嘌呤只与胞嘧啶结合。这些碱基分别用 A、T、G 和 C 表示。

这些碱基形成了各种各样的代码,指导生物体如何构建蛋白质——正是 DNA 从本质上控制着病毒的行为。

DNA 转化为 RNA 再转化为蛋白质的过程。来源。图像免费共享和商业使用。

使用专门的设备,包括测序仪器和专门的标签,显示特定片段的 DNA 序列。由此获得的信息经过进一步的分析和比较,使研究人员能够识别基因的变化、与疾病和表型的关联,并识别潜在的药物靶点。

基因组序列是一长串的‘A’、‘T’、‘G’和‘C’,代表生物体对环境的反应。生物体的突变是通过改变 DNA 产生的。查看基因组序列是分析冠状病毒突变的一种强有力的方法。

了解数据。

数据可以在 Kaggle 这里找到,看起来是这样的:

每行代表蝙蝠病毒的一种变异。首先,花一分钟时间来欣赏大自然是多么不可思议——在几周内,冠状病毒已经创造了 262 种变异(还在增加)来提高存活率。

一些重要的列:

  • query acc.ver代表原病毒标识符。
  • subject acc.ver 是病毒突变的标识符。
  • % identity代表百分之多少的序列与原始病毒相同。
  • alignment length表示序列中有多少项相同或对齐。
  • mismatches代表变异和原始不同的项目数。
  • bit score代表一种度量,用于表示对准有多好;分数越高,排列越好。

每个列的一些统计度量(这可以在 Python 中用data.describe()方便地调用):

查看% identity栏,有趣的是看到一个突变与原始病毒的最小比对百分比——大约 77.6%。对于% identity来说,7%的相当大的标准偏差意味着有很大范围的变异。这是由bit score中的巨大的标准差支持的——标准差大于平均值!

可视化数据的一个好方法是通过关联热图。每个单元格表示一个要素与另一个要素的相关程度。

许多数据彼此高度相关。这是有意义的,因为大多数度量是彼此不同的。如果alignment lengthbit score高度相关,有一点需要注意。

使用 K-Means 创建变异聚类

K-Means 是一种用于聚类的算法,是机器学习中在特征空间中寻找数据点组的方法。我们的 K-Means 的目标是找到突变的簇,因此我们可以获得关于突变的性质以及如何解决它们的见解。

但是,我们仍然需要选择簇的数量 k 。虽然这就像在二维空间中画出点一样简单,但在更高维空间中这是无法实现的(如果我们想保留最多的信息)。像手肘法选择 k 这样的方法是主观的,不准确的,所以我们会改用剪影法。

剪影法是根据聚类与数据的吻合程度对 k 聚类进行评分。Python 中的sklearn库使得实现 K-Means 和 silouhette 方法变得非常简单。

看起来 5 个聚类似乎是数据的最佳聚类。现在,我们可以确定聚类中心。这些是每个聚类围绕的点,并代表 5 种主要突变类型的数值评估(在这种情况下)。

注意:这些特征已被标准化,以便将它们放在相同的比例上。否则,列将无法进行比较。

该热图按列显示了每个集群的属性。因为点是按比例缩放的,所以实际的注释值在数量上没有任何意义。但是,可以比较每列中的换算值。你可以直观地感受到每一个变异群的相对属性。如果科学家要开发一种疫苗,它应该针对这些主要的病毒群。

在下一节中,我们将使用 PCA 来可视化聚类。

聚类可视化的主成分分析

PCA,即主成分分析,是一种降维方法。它选择多维空间中的正交向量来表示轴,从而保留了最多的信息(方差)。

使用流行的 Python 库sklearn,可以通过两行代码实现 PCA。首先,我们可以检查解释的方差比。这是从原始数据集中保留的统计信息的百分比。在这种情况下,解释的方差比是0.9838548580740327,这是天文数字!我们可以确信,无论我们从主成分分析中得到什么样的分析,数据都是真实的。

每个新特征(主成分)是几个其他列的线性组合。我们可以用热图来想象一个列对于两个主要组件中的一个有多重要。

重要的是要理解第一个组分中具有高值意味着什么——在这种情况下,它的特征是具有更高的比对长度(更接近原始病毒),而组分 2 的主要特征是具有更短的比对长度(突变得离原始值更远)。这也体现在bit score的差异较大。

很明显,这种病毒有 5 条主要的变异链。我们可以带走很多洞察力。

四个病毒突变在第一个主成分的左侧,一个在右侧。第一主成分的签名是高alignment length。这意味着第一主成分的值越高,意味着alignment length越高(更接近原始病毒)。因此,组分 1 的较低值在遗传上与原始病毒更远。大多数病毒群与原始病毒有很大不同。因此,试图制造疫苗的科学家应该意识到病毒会发生变异**批次

结论

使用 K-Means 和 PCA,能够识别冠状病毒中的五个主要突变簇。开发冠状病毒疫苗的科学家可以使用聚类中心来获得关于每个聚类特征的知识。我们能够使用主成分分析在二维空间中可视化集群,并发现冠状病毒具有非常高的突变率。这可能是它如此致命的原因。

感谢阅读!

如果你喜欢,请随意查看我在冠状病毒方面的其他工作:

编者注: 走向数据科学 是一份以研究数据科学和机器学习为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里

用 Python 构建推荐系统的机器学习

原文:https://towardsdatascience.com/machine-learning-for-building-recommender-system-in-python-9e4922dd7e97?source=collection_archive---------4-----------------------

利用 Python 中基于模型的协同过滤构建推荐系统

作者照片

推荐系统广泛应用于产品推荐,如音乐、电影、书籍、新闻、研究文章、餐厅等的推荐。[1][5][9][10].

构建推荐系统有两种流行的方法:

协作过滤方法[5][10]通过从许多其他用户(协作)收集偏好信息来预测(过滤)用户对产品的兴趣。协同过滤方法背后的假设是,如果一个人 P1 和另一个人 P2 在一个问题上有相同的观点,P1 比随机选择的人更有可能在不同的问题上分享 P2 的观点[5]。

基于内容的过滤方法[6][9]利用产品特征/属性,根据其他用户以前的行为或明确的反馈(如对产品的评级),推荐与用户喜欢的产品相似的其他产品。

推荐系统可以使用这两种方法中的一种或两种。

在本文中,我使用 Kaggle 网飞奖数据[2]来演示如何使用基于模型的协同过滤方法在 Python 中构建一个推荐系统。

文章的其余部分安排如下:

  • 协同过滤概述
  • 用 Python 构建推荐系统
  • 摘要

1.协同过滤概述

正如[5]中所描述的,协同过滤背后的主要思想是一个人经常从另一个有相似兴趣的人那里得到最好的推荐。协同过滤使用各种技术来匹配具有相似兴趣的人,并基于共同兴趣进行推荐。

协同过滤系统的高级工作流程可以描述如下:

  • 用户对项目(例如,电影、书籍)进行评级以表达他或她对项目的偏好
  • 系统将评级视为用户对项目兴趣的近似表示
  • 系统将该用户的评分与其他用户的评分进行匹配,并找到评分最相似的人
  • 系统推荐相似用户已经评级很高但是还没有被该用户评级的项目

典型地,协同过滤系统分两步向给定用户推荐产品[5]:

  • 步骤 1:寻找与给定用户具有相同评级模式的人
  • 步骤 2:使用在步骤 1 中找到的人的评分来计算给定用户对产品的评分预测

这被称为基于用户的协同过滤。该方法的一个具体实现是基于用户的最近邻算法

作为替代,基于项目的协作过滤(例如,对 x 感兴趣的用户也对 y 感兴趣)以项目为中心的方式工作:

  • 步骤 1:建立项目对之间评级关系的项目-项目矩阵
  • 步骤 2:通过检查矩阵和匹配用户的评级数据来预测当前用户对产品的评级

有两种类型的协同过滤系统:

  • 基于模型的
  • 基于记忆的

在基于模型的系统中,我们使用不同的机器学习算法来开发模型,以预测用户对未评级项目的评级【5】。基于模型的协同过滤算法有很多,如矩阵分解算法(如奇异值分解 (SVD)、交替最小二乘(ALS)算法【8】)、贝叶斯网络聚类模型等。【5】

基于记忆的系统使用用户的评级数据来计算用户或项目之间的相似性。这类系统的典型例子是基于邻域的方法和基于项目/基于用户的 top-N 推荐[5]。

本文描述了如何使用 SVD 模型构建基于模型的协同过滤系统。

2.用 Python 构建推荐系统

本节描述如何用 Python 构建推荐系统。

2.1 安装库

有多个 Python 库可用于构建推荐系统(例如,Python scikitSurprise【7】, Spark 基于 RDD 的协同过滤 API【8】)。我在本文中使用 Python scikit Surprise 库进行演示。

惊喜库可以按如下方式安装:

pip install scikit-surprise

2.2 加载数据

如前所述,我在本文中使用了 Kaggle 网飞奖数据[2]。有多个数据文件用于不同的目的。本文中使用了以下数据文件:

训练数据:

  • 组合 _ 数据 _1.txt
  • 组合 _ 数据 _2.txt
  • 组合 _ 数据 _3.txt
  • 组合 _ 数据 _4.txt

电影片头数据文件:

  • 电影 _ 标题. csv

训练数据集太大,无法在笔记本电脑上处理。因此,出于演示目的,我只从每个训练数据文件中加载前 100,000 条记录。

一旦将训练数据文件下载到本地机器上,来自每个训练数据文件的前 100,000 条记录可以作为熊猫数据帧加载到内存中,如下所示:

def readFile(file_path, rows=100000):
    data_dict = {'Cust_Id' : [], 'Movie_Id' : [], 'Rating' : [], 'Date' : []}
    f = open(file_path, "r")
    count = 0
    for line in f:
        count += 1
        if count > rows:
            break

        if ':' in line:
            movidId = line[:-2] # remove the last character ':'
            movieId = int(movidId)
        else:
            customerID, rating, date = line.split(',')
            data_dict['Cust_Id'].append(customerID)
            data_dict['Movie_Id'].append(movieId)
            data_dict['Rating'].append(rating)
            data_dict['Date'].append(date.rstrip("\n"))
    f.close()

    return pd.DataFrame(data_dict)df1 = readFile('./data/netflix/combined_data_1.txt', rows=100000)
df2 = readFile('./data/netflix/combined_data_2.txt', rows=100000)
df3 = readFile('./data/netflix/combined_data_3.txt', rows=100000)
df4 = readFile('./data/netflix/combined_data_4.txt', rows=100000)df1['Rating'] = df1['Rating'].astype(float)
df2['Rating'] = df2['Rating'].astype(float)
df3['Rating'] = df3['Rating'].astype(float)
df4['Rating'] = df4['Rating'].astype(float)

训练数据的不同部分的不同数据帧被组合成如下一个:

df = df1.copy()
df = df.append(df2)
df = df.append(df3)
df = df.append(df4)df.index = np.arange(0,len(df))
df.head(10)

电影标题文件可以作为熊猫数据帧载入存储器:

df_title = pd.read_csv('./data/netflix/movie_titles.csv', encoding = "ISO-8859-1", header = None, names = ['Movie_Id', 'Year', 'Name'])
df_title.head(10)

2.3 培训和评估模式

Surprise 中的数据集模块提供了从文件、Pandas 数据帧或内置数据集(如 ml-100k(movie lens 100k)【4】加载数据的不同方法:

  • Dataset.load_builtin()
  • Dataset.load_from_file()
  • Dataset.load_from_df()

在本文中,我使用 load_from_df ()方法从 Pandas DataFrame 加载数据。

Surprise 中的 Reader 类用于解析包含用户、项目和用户对项目的评分的文件。默认的格式是每个评分按空格分隔的顺序存储在单独的行中:用户 项目 评分

该顺序和分隔符可使用以下参数进行配置:

  • line_format 是一个类似于“itemuserrating 的字符串,表示数据的顺序,字段名之间用空格隔开
  • sep 用于指定字段之间的分隔符,如空格、'、'等。
  • rating_scale 是指定评级尺度。默认值为(1,5)
  • skip_lines 表示文件开头要跳过的行数,默认为 0

我在本文中使用默认设置。用户评分分别对应数据帧的客户标识电影标识评分栏。

惊喜库[7]包含用于构建推荐系统的多种模型/算法的实现,例如奇异值分解、概率矩阵分解(PMF)、非负矩阵分解(NMF)等。本文使用了 SVD 模型。

下面的代码从 Pandas DataFrame 加载数据并创建一个 SVD 模型实例:

from surprise import Reader, Dataset, SVD
from surprise.model_selection.validation import cross_validatereader = Reader()data = Dataset.load_from_df(df[['Cust_Id', 'Movie_Id', 'Rating']], reader)svd = SVD()

一旦用于产品推荐的数据和模型准备就绪,就可以使用交叉验证来评估模型,如下所示:

# Run 5-fold cross-validation and print results
cross_validate(svd, data, measures=['RMSE', 'MAE'], cv=5, verbose=True)

以下是 SVD 模型的交叉验证结果:

一旦模型评估达到我们的满意程度,我们就可以使用整个训练数据集来重新训练模型:

trainset = data.build_full_trainset()
svd.fit(trainset)

2.4 推荐产品

在推荐模型被适当地训练之后,它可以被用于预测。

例如,给定用户(例如,客户 Id 785314),我们可以使用经训练的模型来预测用户对不同产品(即,电影名称)给出的评级:

titles = df_title.copy()titles['Estimate_Score'] = titles['Movie_Id'].apply(lambda x: svd.predict(785314, x).est)

为了向给定用户推荐产品(即电影),我们可以按照预测评级的降序对电影列表进行排序,并将前 N 部电影作为推荐:

titles = titles.sort_values(by=['Estimate_Score'], ascending=False)
titles.head(10)

以下是向客户 Id 为 785314 的用户推荐的前 10 部电影:

3.摘要

在本文中,我使用 scikit 惊喜库[7]和 Kaggle 网飞奖数据[2]来演示如何使用基于模型的协同过滤方法在 Python 中构建推荐系统。

如本文开头所述,数据集太大,无法在笔记本电脑或任何典型的个人电脑上处理。因此,出于演示目的,我只从每个训练数据集文件中加载了前 100,000 条记录。

在真实应用的设置中,我会推荐用 Surprise 搭配考拉或者用 Spark MLLib 中的 ALS 算法实现协同过滤系统,在 Spark cluster 上运行[8]。

Github [11]中提供了 Jupyter 笔记本以及本文中使用的所有源代码。

参考

  1. DLao,网飞——电影推荐
  2. Netflix 获奖数据,来自网飞竞赛的数据集,用于改进他们的推荐算法
  3. 推荐系统
  4. A.Ajitsaria,用协同过滤建立推荐引擎
  5. 协同过滤
  6. 基于内容的过滤
  7. 惊喜
  8. 南 Ryza,U. Laserson 等。艾尔。,Spark 高级分析,奥赖利,2015 年 4 月
  9. N.S. Chauhan,如何构建餐厅推荐引擎(第一部分)
  10. N.S. Chauhan,如何构建餐厅推荐引擎(第二部分)
  11. Y. Github 中的张、Jupyter 笔记本

用于能量分配的机器学习

原文:https://towardsdatascience.com/machine-learning-for-energy-distribution-2150d095520f?source=collection_archive---------54-----------------------

能源领域的机器学习——第三部分

能源分销公司的 9 个用例

来源:作者

分布式生产、可再生能源的兴起、向更智能电网的转变以及竞争性营销正在改变能源分配市场,并给公用事业的利润率带来压力。

越来越需要在一定范围内做出更明智的决策。为了保持竞争力,需要快速做出这些决定。机器学习正在成为最重要的工具,帮助你做出更好的定价决策,并与客户建立更好的关系。借助机器学习,您可以:

  • 预测价格和需求,
  • 优化零售价格,
  • 提供更好的报价,赢得更多客户,减少客户流失,预测客户终身价值,
  • 预测价值顺序,优化消费

准确预测能源价格

随着个人发电(使用太阳能或风能)变得越来越容易和便宜,消费者和企业越来越多地生产自己的电力。

个人发电允许人们制造、消耗和储存自己的能量。根据他们居住的地方,他们甚至可以将多余的电力卖给当地的电力公司。

机器学习可以帮助找到生产、储存或出售这种能源的最佳时间。理想情况下,能源应该在价格低的时候消耗或储存,价格高的时候卖回给电网。

当我们使用机器学习模型来查看历史数据、使用趋势和天气预报时,我们可以每小时做出更准确的预测。这有助于拥有个人和商业能源生成系统的人做出关于如何使用他们的能源的战略决策。

例如,自适应神经模糊推理系统(ANFIS)已被用于预测发电的短期风模式。这使得生产商能够最大限度地提高能源产量,并在价格达到峰值时将能源返销给电网。

准确预测能源需求

准确预测客户的能源需求对于任何公用事业提供商来说都至关重要。到目前为止,还没有足够的解决方案来储存大量的能量,这意味着能量需要在产生的同时就被传输和消耗。

我们正在使用机器学习来提高这些预测的准确性。历史能源使用数据、天气预报以及某一天运营的企业或建筑类型都在决定能源使用量方面发挥着作用。

例如,一周中炎热的夏天意味着更多的能源使用,因为办公楼空调的运行能力很高。天气预报和历史数据可以帮助及时识别这些模式,以防止夏季空调导致的轮流停电。

机器学习在各种影响因素(如星期几、时间、预测的风和太阳辐射、重大体育赛事、过去的需求、平均需求、气温、湿度和压力以及风向)中找到复杂的模式,以解释需求的发展。因为机器学习比人类能发现更多错综复杂的模式,所以它的预测更准确。这意味着您可以在购买能源时提高效率并降低成本,而不必进行昂贵的调整。

通过更好的交易优化价格

为电力等商品提供最优惠的价格是在开放的能源市场中生存的关键。当消费者可以选择谁提供他们的电力时,价格比较是不可避免的。

为了保持竞争力,公用事业提供商使用机器学习来根据价格最低的时间确定购买能源的最佳时间。

谈到商品追踪,有成千上万的因素影响着能源价格——从一天中的时间到天气的一切。我们可以使用机器学习来分析这些因素的微小变化,这有助于公用事业提供商在何时购买和出售能源方面做出更明智的决定。

但我们可以更进一步,对于我们的一个客户,我们结合了梯度推进、通用加法和深度学习模型,以更准确地预测未来一天的价格。我们还使用机器学习来帮助一家 B2B 能源分销商选择交易策略,以更便宜的价格购买期货。

在一些市场,这种分析导致消费者在一年内多次降价。

减少客户流失

在开放的能源市场中,客户可以选择公用事业供应商,了解哪些客户将会流失至关重要。在能源行业,流失率——在特定年份停止使用某项服务的客户的百分比——可能高达 25%。准确预测和防止客户流失对生存至关重要。

我们可以使用机器学习来帮助公用事业所有者预测客户何时准备大量生产。

通过使用跨行业数据挖掘标准流程(CRISP-DM)、AdaBoost 和支持向量机等技术,以及历史使用数据,公用事业提供商可以确定预测客户是否会流失的关键指标。

这些包括客户满意度、就业状况、能源消耗、房屋所有权或租赁状况等。这些因素中的任何一个变化都可能指向准备终止服务的客户。

当我们提前足够长的时间确定这些指标时,您可以通过与客户合作解决他们遇到的任何问题来防止流失。

预测客户终身价值

在开放的公用事业市场中,公用事业所有者和提供商必须更加关注客户终身价值(CLV)等指标。这有助于他们了解任何给定客户在合同期限内将花费多少。

机器学习能做的不仅仅是给你一个更准确的 CLV 预测。通过输入客户信息、消费习惯、位置、购买历史和支付行为等数据,我们可以使用深度神经网络等机器学习模型来预测单个客户的整体价值。

有了机器学习,我们甚至可以通过建议增加客户价值的方法来更进一步。这可能意味着向类似的客户提供高针对性的服务,或者利用自然语言处理(NLP)来帮助改善对可能准备流失的沮丧客户的服务。

预测赢得客户的概率

对于开放市场中的公用事业提供商来说,全面了解潜在客户对于保持竞争优势至关重要。

但是机器学习能做的不仅仅是给你提供这个完整的画面。它还可以提供您做出数据驱动的营销决策所需的信息..这意味着当一个人登陆你的网站时,你就能判断出这个人是否会成为你的顾客。

我们可以使用机器学习来收集人们随身携带的信息——比如他们住在哪里,他们使用哪种电脑,他们的浏览历史,搜索历史,以及他们访问你的网站的次数——并得出这个人作为消费者的准确图片。

由此,机器学习不仅可以确定那个人成为客户的可能性(这就是所谓的评分),还可以确定将他们变成客户的最佳策略。这包括使用高度有针对性的广告和提供非常个性化的体验——例如,当一个四口之家的人访问网站时,在主页上使用一个四口之家的照片。

向客户提供极具针对性的优惠

在开放的能源市场中,消费者可以选择公用事业供应商。个性化的优惠对于吸引新客户和留住现有客户至关重要,尤其是因为品牌忠诚度已经不像以前那么高了。

我们可以使用机器学习来帮助您获得所需的洞察力,以提供直接针对特定客户需求的不可抗拒的优惠。

通过分析消费习惯和客户数据,机器学习可以帮助你确定在任何给定时间向特定客户提供的最佳优惠。

例如,如果数据表明客户正准备搬家,您可以在他们的新位置发出免除连接费的提议。这种个性化的优惠让你在竞争中领先,减少客户流失的可能性。

优化能源消耗

人们很早就意识到了能源消耗,无论是在家里还是在工作中。但是,如果不进行大量的手工计算,我们只能获得能源使用的总体感觉,而不知道哪些电器或设备使用最多。

智能电表和物联网设备的兴起改变了这一切。非侵入式设备负载监控(NIALM),也称为分解,是一种使用机器学习在设备特定级别分析能耗的算法。

我们可以帮助您找出哪些设备的运行成本最高。这将有助于家庭和企业客户调整他们的消费习惯,以节省资金和减少能源使用。他们可以少用高价电器,或者换成更节能的型号。

预测能源价格的价值顺序

公用事业供应商在能源来源方面有很多选择——从风能、太阳能等可再生能源到化石燃料和核能。到了销售电力的时候,这些不同的来源被组织成一个基于价格的价值顺序。这决定了这些不同来源的电力出售的顺序。

因为我们可以访问来自各种来源的数据,所以我们可以使用机器学习来分析实时数据和历史数据。机器学习算法也更善于考虑影响价格的所有不同因素——如天气、需求、各种来源的可用能源量、历史使用情况等。–预测优化的奖励等级。

这有助于你做出更明智的决定,从哪里获得力量。这在有大量可再生能源的市场上尤其有用,例如,因为很难保证这些来源的能源可用性。

T 他的文章是机器学习在能源行业应用的 3 部分系列文章之一:

  1. 第一部分— 用于能源生成的机器学习
  2. 第二部分— 用于能量传输的机器学习
  3. 第二部分(本文)——针对能量分布的机器学习

用于能源生产的机器学习

原文:https://towardsdatascience.com/machine-learning-for-energy-generation-302069a942f?source=collection_archive---------43-----------------------

能源领域的机器学习——第一部分

发电厂 ML 的 4 个用例

来源:作者

如果你正在管理风力发电场或任何其他发电厂,那么你很清楚:维护、人为错误、停机和规划效率低下每年会造成数百万美元的损失

在更简单的统计学进展甚微的情况下,机器学习被证明是一种非常有效的工具,可以:

  • 更快更准确地预测故障
  • 检测人为错误,在它们变成大问题之前
  • 优化电厂计划,提高您的盈利能力
  • 预测优序,优化不同电源的调度

预测涡轮机故障

风是一种很好的可再生能源,但是风力涡轮机的维护费用是出了名的昂贵。它占每千瓦时成本的 25%。并且在问题发生后解决问题可能会更加昂贵。

机器学习可以帮助您提前解决这个问题,通过在涡轮机出现故障之前发现问题来降低维护成本。当风力发电场位于难以到达的地方时,例如海洋中部,这一点尤为重要,因为这使得维修成本更高。

监控和数据采集(SCADA)收集的实时数据有助于提前识别系统中可能出现的故障,从而防止故障发生。

例如,我们可以使用来自涡轮机内传感器的数据,如油、油脂和振动传感器,来训练机器学习模型,以识别故障的前兆,如低水平的润滑剂。这种方法可以提前 60 天预测故障。

减少潜在的人为错误

来源:作者

每年,人为错误占发电厂故障的 25%。除了每年损失高达 3000 万兆瓦时的发电量,这还会导致客户服务中断,甚至更糟——想想切尔诺贝利和三里岛就知道了。这也意味着与修复错误和让系统重新上线相关的不必要成本。

为了解决这个问题,我们可以使用机器学习来支持控制室操作员做出的决定。

机器学习提供持续的系统监控,帮助您检测异常。我们还会自动建议一个行动计划来防止情况变得更糟。它甚至可以在需要人工干预之前处理问题。

这降低了由于注意力分散、缺乏知识或反应速度而导致的人为错误的风险——有时控制室操作员根本无法快速阻止问题。

通过优化调度和定价提高电厂的盈利能力

如今,我们拥有的海量数据正在帮助人们就如何经营企业做出更好的决策。公用事业也不例外。能源价格的波动性意味着,运营一家发电厂可能或多或少有利可图,这取决于一天中简单的时间。

但是,由于公用事业市场节奏如此之快,很难手动跟踪做出这些决策所需的所有数据。

我们可以使用机器学习来帮助。通过将价格和使用的历史数据输入机器学习算法,你可以预测运营他们工厂的最佳时间,从而赚更多的钱。机器学习可以找到使用率高但用于生产能源的原材料价格低的时候。这些极其准确的预测创建了一个优化的发电计划,使盈利能力最大化。

预测能源价格的价值顺序

来源:作者

公用事业供应商在能源来源方面有很多选择——从风能、太阳能等可再生能源到化石燃料和核能。到了销售电力的时候,这些不同的来源被组织成一个基于价格的价值顺序。这决定了这些不同来源的电力出售的顺序。

因为我们可以访问来自各种来源的数据,所以我们可以使用机器学习来分析实时数据和历史数据。机器学习算法也更善于考虑影响价格的所有不同因素,如天气、需求、各种来源的可用能源量、历史使用情况等。-创建优化的奖励等级。

这有助于你做出更明智的决定,从哪里获得力量。这在有大量可再生能源的市场上尤其有用,比如风能,因为很难保证这些能源的可用性。

T 他的文章是机器学习在能源行业应用的 3 部分系列文章之一:

  1. 第一部分(本文)–用于能源生产的机器学习
  2. 第二部分-用于能量传输的机器学习
  3. 第二部分-针对能量分配 的机器学习

原载于https://www.datarevenue.com

用于能量传输的机器学习

原文:https://towardsdatascience.com/machine-learning-for-energy-transmission-750f518ae282?source=collection_archive---------54-----------------------

能源领域的机器学习——第二部分

传输系统运营商的 6 ML 应用。

来源:作者

在电网中输送电力会带来一系列独特的问题。从能源盗窃到电网故障,一切都可能干扰这一过程。而且,每次出了问题,都要花费时间和金钱去纠正。

机器学习已经成为一种越来越强大的工具,有助于降低与能源传输相关的风险。它可以帮助您:

  • 预测和预防电网故障
  • 通过实时监控和人工智能预测防止限电
  • 检测电网故障
  • 平衡网格
  • 区分电力系统干扰和网络攻击
  • 检测能源盗窃

1.预测和预防电网故障

大规模停电给公众带来了混乱,并且每年给公用事业提供商造成大约 490 亿美元的损失。

如果大规模停电很少发生,这不会是什么大问题,但影响超过 50,000 人的停电近年来急剧增加。这意味着公用事业公司需要找到预测和管理这些中断的新方法。

如今,智能电网正在产生大量数据,这意味着预测和管理停电比以往任何时候都更容易。传统电网是单向的(意味着它们只向一个方向传输电力),而智能电网则是双向的。他们可以在提供电力的同时从电网中的每一个可能的来源获取数据。他们从智能电表、物联网设备和发电站等来源收集和监控数据,提供清晰、实时的电力使用情况。

机器学习可以使用这些数据来预测和防止电网中的大规模停电。它有助于识别数据中不明显的模式,这些模式可能是电网故障的前兆,这有助于维护团队预防故障。

2.通过实时监控和人工智能预测防止电力不足

电网在向客户提供持续能源方面有许多障碍需要克服。天气模式、使用、内部故障,甚至像雷击和野生动物干扰这样的意外事件都会影响电力输送。

机器学习越来越多地用于帮助预测潜在的限电情况。通过将历史数据输入人工智能并运行蒙特卡罗模拟来预测潜在的结果,电网运营商可以使用机器学习来识别可能导致电网故障的条件。他们可以据此采取行动。

相位测量单元(PMU)和智能电表等传感器可以实时提供使用信息。当我们将这些工具与历史和模拟数据结合起来时,人工智能可以使用网格平衡和需求响应优化等技术来帮助减轻潜在的网格故障。否则会影响数百万人的事件可以被控制在更小的范围内,并以更少的资金更快地得到解决。

3.检测电网故障

大多数公用事业提供商目前用于检测电网故障的方法消耗了大量不必要的时间和资源。这就造成了这样一种情况,即电力传输中断,用户没有电,而故障是先定位,然后修复的。

机器学习可以更快更准确地找到故障,帮助您最大限度地减少对客户的服务中断。例如,我们可以将支持向量机(SVM)与离散小波变换(DWT)相结合来定位线路中的故障。

当我们将 DWT(一种捕捉频率和位置信息的数值和函数分析形式)应用于传输线上记录的瞬态电压时,我们可以通过计算天线模式电压小波(对于地上传输导线)和接地模式电压小波(对于地下传输导线)来确定故障的位置。到目前为止,这种方法已经成功地检测了架空和地下输电线路的故障起始角、故障位置、负载水平和非线性高阻抗故障。

4.平衡网格

脸书预言家算法预测风力

平衡电网——确保能源供应与能源需求相匹配——是输电运营商最重要的工作之一。但是可再生能源严重依赖天气,这使得它们更难预测。

输电运营商每年花费数百万美元来修复导致发电量过多或过少的规划错误。在依靠可再生能源和化石燃料发电的混合系统中,这些错误必须在最后一刻通过购买更多的能源或补偿电厂的过剩来纠正。

准确了解需求水平何时达到峰值,可让公用事业提供商连接到二次电源(如传统发电)以支持可用资源并确保持续的服务供应。

机器学习是预测可再生能源产量的最准确的方法。当我们应用像长短期神经网络(LSTMs)这样的高级方法时,AI 可以权衡所涉及的许多因素——风、温度、阳光和湿度预测——并做出最佳预测。这为运营商节省了资金,也为电厂保留了资源。

我们还可以将历史数据输入机器学习算法,如支持向量机(SVM),以准确预测能源使用量,并确保足够的水平和持续的供应。

5.区分电力系统干扰和网络攻击

网络攻击越来越多地被用来攻击重要的基础设施,比如劫持公用设施和索要现金。这可能需要很长时间和大量的资金来解决。例如,在科罗拉多州,在一次网络攻击后,他们花了三个星期才解开数据。他们不得不引入额外的人员来梳理记录,以确保他们客户的个人信息不被泄露,这是同一家公用事业公司在两年内第二次发生这种情况。

检测这些攻击至关重要。

开发人员正在使用机器学习来区分故障(例如短路)或电网干扰(例如线路维护)和智能网络攻击(例如数据注入)。

由于欺骗是这些攻击的一个重要组成部分,因此需要训练该模型来寻找可疑活动,如欺骗发生后留下的恶意代码或机器人。一旦模型经过训练,它就可以监控系统并更快地捕捉可疑活动。

我们可以应用的一种方法是使用符号动态过滤(一种基于信息论的模式识别工具)的特征提取来发现子系统之间的因果关系,而不会使计算机系统负担过重。在测试中,它准确地检测到 99%的网络攻击,真阳性率为 98%,假阳性率不到 2%。如此低的误报率意义重大,因为误报是检测网络攻击的最大问题之一。

6.检测能源盗窃

在能源领域,“非技术性损失”意味着能源盗窃或欺诈。

有两种常见的非技术性损失。第一种情况是,客户使用的能源比电表报告的多。第二个是流氓连接从付费用户那里窃取能源。为了实现这一点,坏人可以完全绕过智能电表,或者在系统中插入芯片,改变电表跟踪能源使用的方式。抄表员也可以被贿赂报告更低的数字(尽管由于智能电表,这越来越难做到)。

因为这些非技术性损失每年花费960 亿美元,公用事业提供商正在转向机器学习来解决这个问题。

我们可以帮助您挖掘历史客户数据,以发现表明盗窃或欺诈的违规行为。这些可能是不寻常的使用高峰,报告和实际使用之间的差异,甚至是设备篡改的证据。

本文是机器学习在能源行业应用的 3 部分系列文章之一:

  1. 第一部分— 发电的机器学习
  2. 第二部分——能量传输 机器学习
  3. 第二部分— 用于能量分配的机器学习

基因组学的机器学习

原文:https://towardsdatascience.com/machine-learning-for-genomics-c02270a51795?source=collection_archive---------14-----------------------

如何转换您的基因组数据以适应机器学习模型

机器学习已经普及。然而,它不是生物信息学和计算生物学领域的常见用例。使用机器学习技术的工具非常少。大多数工具都是在确定性方法和算法的基础上开发的。在这篇文章中,我将介绍我们如何安排我们的数据,以便在机器学习模型中有效地使用它们。

图片来自 PixabayClker-Free-Vector-Images

应用领域

在基因组学中有很多场景我们可能会用到机器学习。聚类和分类的主要领域可用于基因组学的各种任务。其中一些如下:

聚类(无监督学习)

  1. 宏基因组重叠群的宁滨
  2. 质粒和染色体的鉴定
  3. 聚类读入染色体,以便更好地组装
  4. 作为读取集合的预处理器的读取聚类

分类(监督学习)

  1. 将较短的序列分类(门、属、种等)
  2. 序列的系统发育推断
  3. 质粒和染色体的检测
  4. 寻找编码区域
  5. 人类基因组学中的染色体预测

虽然我已经列出了几个我有经验的领域,但是这个清单可能还会更长。

数据转换和模型选择

在转换和模型选择这两个步骤中,我认为前者更重要。这是因为如果没有数据表示的坚实基础,我们可能无法从模型中获得最大收益。然而,即使我们的模型看起来很差,拥有干净和信息丰富的数据也可以表现得更好。我们可以考虑两类数据。

顺序数据

顺序数据是指输入模型的数据顺序与数据集中数据的实际顺序相对应的数据。让我们看看下面的例子。

  1. 蛋白质编码区的预测
    在这个场景中,我们将会看到连续的核苷酸碱基和它们的顺序。否则就没有意义了。在这种情况下,我们可以将数据转换为包含连续的三聚体单词的句子。
  2. 分类标签预测
    在这种情况下,我们需要更高的精确度,因为寡核苷酸频率在物种之间可能非常相似,而在某些物种之间具有非常低的唯一性。因此,我们将着眼于创建大于 5 或 7 的 k 值的 k-mer 句子。

让我们考虑下面的例子。我将使用两个物种铜绿假单胞菌( CP007224.1) 和发酵乳杆菌 (AP008937.1) 来演示转化为 k-mer 单词句子(显示了前 50 个碱基)。

**Pseudomonas aeruginosa** TTTAAAGAGACCGGCGATTCTAGTGAAATCGAACGGGCAGGTCAATTTCC**Lactobacillus fermentum** TTGACTGAGCTCGATTCTCTTTGGGAAGCGATCCAAAATTCATTCCGTAA

现在,我们可以将其转换为三聚体单词,如下所示。

**Pseudomonas aeruginosa** TTT TTA TAA AAA AAG AGA GAG AGA GAC ACC CCG CGG GGC GCG CGA GAT ATT TTC TCT CTA TAG AGT GTG TGA GAA AAA AAT ATC TCG CGA GAA AAC ACG CGG GGG GGC GCA CAG AGG GGT GTC TCA CAA AAT ATT TTT TTC TCC**Lactobacillus fermentum** TTG TGA GAC ACT CTG TGA GAG AGC GCT CTC TCG CGA GAT ATT TTC TCT CTC TCT CTT TTT TTG TGG GGG GGA GAA AAG AGC GCG CGA GAT ATC TCC CCA CAA AAA AAA AAT ATT TTC TCA CAT ATT TTC TCC CCG CGT GTA TAA

现在我们有了单词的句子,处理过程变得类似于情感分析。关键的想法是保持句子的长度,你可以根据序列的平均长度来决定。

适用于顺序数据的模型

由于上述场景中 k-mers 的顺序很重要,我们可以很容易地使用递归神经网络(RNN)长短期记忆模型(LSTM) 。这是因为它们能够将项目的顺序保持为一种时间关系。

然而,在上面的场景中,您必须使用标记化,然后是单词嵌入层。确保将编码器和记号赋予器保存到一个文件中(序列化),这样您就有了用于以后预测的编码器。这里 kmer_strings 是我创建的句子,是指定的标签。

tokenizer = Tokenizer()
tokenizer.fit_on_texts(**kmer_strings**)
vocab_size = len(tokenizer.word_index) + 1
encoded_docs = tokenizer.texts_to_sequences(**kmer_strings**)binarizer = preprocessing.LabelBinarizer()
labels_encoded = binarizer.fit_transform(**classes**)

以下是我几天前使用 Keras Sequential API 进行序列分类时使用的一个模型。我将单词从最初的 32 个维度嵌入到 5 个维度中(有 32 个独特的三聚体合并了下游链的反向互补)。

model = Sequential()
model.add(Embedding(vocab_size, 5))
model.add(Bidirectional(LSTM(5)))
model.add(Dense(30, activation = 'relu'))
model.add(Dropout(0.2))
model.add(Dense(20, activation = 'relu'))
model.add(Dropout(0.2))
model.add(Dense(2, activation = 'softmax'))

如果您的分类是多标签,您需要使用 sigmoid 激活功能代替 softmax 功能。

无序数据

对于相似序列之间的相关性比序列的唯一可识别性更重要的情况,我们倾向于使用无序数据。这些通常以寡核苷酸频率向量的形式表示。例如,铜绿假单胞菌( CP007224.1) 和发酵乳杆菌 (AP008937.1)的标准化频率如下所示。

两个物种的三聚体频率模式

我们可以看到它们遵循完全不同的模式。请注意,我们已经失去了三聚体的实际顺序,但留下了一个代表来唯一地识别这两个物种。然而,在 k=3 的时候,你很可能会遇到近亲物种之间的碰撞。这是一篇关于如何基于这些模式进行集群的有趣文章;

[## 基于组成的宏基因组序列聚类

基于寡核苷酸组成的宏基因组序列聚类

towardsdatascience.com](/composition-based-clustering-of-metagenomic-sequences-4e0b7e01c463)

下面的文章可能会对如何非常有效地使用 DBSCAN 有所帮助。

[## 如何有效地使用 DBSCAN

有效使用最常引用的聚类算法的完整指南

towardsdatascience.com](/how-to-use-dbscan-effectively-ed212c02e62)

现在您已经看到了数据,您可以使用类似于下面的模型来进行分类。

model = Sequential()
model.add(Dense(30, activation = 'relu', input_shape=(32,)))
model.add(Dropout(0.2))
model.add(Dense(20, activation = 'relu'))
model.add(Dropout(0.2))
model.add(Dense(2, activation = 'softmax'))
model.compile(loss='binary_crossentropy', optimizer='adam')

请注意,当您为此决定更长的 k-mers 时,您的输入维度将增加 4 的幂次。此外,计算如此长的向量也需要很长时间。您可能希望阅读下面的文章,这篇文章解释了如何使用一个简单易用的小脚本来实现这一点。

[## DNA 序列的矢量化

ACGT 序列到 k-mer 频率向量的有效转换

medium.com](https://medium.com/computational-biology/vectorization-of-dna-sequences-2acac972b2ee)

现有工具很少

现在,您已经看到了如何在机器学习模型中使用可变长度的基因组序列,让我展示几个实际做到这一点的工具。

  1. plas class(2020 出版,PLOS )
    对 k-mer 频率向量使用逻辑回归来检测它们是否来源于质粒序列或染色体片段。这是一个基于二元分类的工具。
  2. plas flow(2018 出版,核酸研究 )
    该工具预测门级分类,预测给定的重叠群是质粒还是染色体。在 k-mer 频率向量上使用神经网络。
  3. MetaBCC-LR ( 出版,2020,生物信息学 )
    使用 t-分布式随机邻居嵌入(t-SNE)对基因组长阅读进行降维,以执行宏基因组阅读的三聚体向量的宁滨。

除了这几个工具(我用过的和我写的第三个),在不同的研究领域有更多的工具。LSTMs 用于基因预测和编码区检测。

然而,机器学习技术在该领域有巨大的潜力可以展示。

我希望你读过一些有用的书。干杯!

用于销售线索管理的机器学习

原文:https://towardsdatascience.com/machine-learning-for-lead-management-4f15e52e732a?source=collection_archive---------12-----------------------

斯科特·格雷厄姆Unsplash 上拍照

线索是许多企业的生命线。销售线索是接触潜在客户的起点。简而言之,“线索”代表关于潜在客户的记录,通常包括一些联系信息,如电子邮件地址和电话号码,还可能包括关于客户的其他属性(例如,产品偏好和人口统计数据)。营销和销售部门在销售线索管理上花费了大量的时间、金钱和精力,我们将采用这一概念来涵盖销售线索生成、资格认定和货币化这三个关键阶段。

在本文中,我们将探讨机器学习如何通过为智能、动态和高度可扩展的领导管理方法提供基础来为企业创造切实的价值。我们将使用一个案例研究来使讨论不那么抽象,更容易理解。

销售线索管理的三个关键阶段

在深入案例研究之前,至少有必要对我们将要考虑的销售线索管理的三个关键阶段有一个高度的了解:

  • 产生潜在客户通常通过开展营销活动,让潜在客户了解企业正在销售的产品,并表明他们对这些产品的兴趣,从而产生一份长长的潜在客户名单。例如,在在线环境中,网站可能会询问您的电子邮件地址,以便您注册他们的邮件列表和时事通讯,并不时向您发送特殊产品报价和折扣。网站还可以收集行为跟踪数据(例如,您访问了哪些内容,访问的频率和时间),并进行定期调查,以开发更丰富的线索档案。
  • 销售线索资格是指根据各种标准对销售线索进行评估和优先排序。可能的标准包括容易获得或转换(客户对产品说“是”的可能性)、容易交付(企业是否有必要的资源和能力按要求向客户交付产品)、利润潜力(由于高度差异化的产品和客户的高支付意愿,企业可以实现的利润率的大小)和战略适合度(向这一特定客户群销售是否符合公司的战略)。
  • 销售线索货币化着眼于从合格的销售线索中获取收入的可能方式。货币化的机会通常由业务范围(尤其是其在供应链中的位置和垂直整合的水平)和潜在的可扩展性决定。高度垂直整合的企业可以通过直接向潜在客户销售来实现销售线索的货币化;如果产品的利润率很高,这可能特别有利可图。处于供应链上游的纵向一体化程度较低的企业可以通过将合格的销售线索出售给拥有交付产品手段的下游企业来实现货币化。潜在的可扩展性将受到供应方因素(如生产能力和销售队伍的规模)和需求方因素(如市场规模、增长率、补充和替代产品的可用性)的制约。

个案研究

现在,我们将通过一个案例研究来了解机器学习如何在实践中应用于销售线索管理。我们的案例围绕着一个虚构的招聘机构 Valiant Recruiters Ltd. ,它帮助客户公司找到技术职位空缺的完美候选人。

Valiant 本质上是一家在线企业;它维护着一个全面的在线门户网站,提供当前的空缺职位,并通过在几个在线渠道,包括专业社交网站和其他求职网站上开展广告活动来吸引潜在的候选人。潜在候选人可以通过上传简历或直接联系 Valiant 招聘人员在 Valiant 的门户网站上注册;在每种情况下,都会在 Valiant 的候选人数据库中创建一个相应的销售线索档案。Valiant 专注于数据科学职位,通常会通过成功地将候选人安置在客户公司来获得可观的佣金。如果候选人由于任何原因(例如,没有合适的空缺,候选人的偏好超出了 Valiant 的专业领域,招聘人员满负荷工作)而无法转换,Valiant 保留将销售线索档案出售给选定的合作招聘机构(多面手和利基参与者)的选项,这些机构可能更适合转换销售线索。

因此,线索管理是 Valiant 商业模式的核心。作为数据科学业务的专家,Valiant 的首席执行官敏锐地意识到了使用机器学习来改善和扩展公司领导管理方法并最终提高底线的潜力。在过去的六个月里,首席执行官领导了一项计划,旨在确定和实施贯穿线索管理所有三个阶段(生成、资格认定和货币化)的高效机器学习用例。

创造更好的销售线索

Valiant 在围绕数据科学的宣传达到空前高潮之际推出了领先管理计划。数据科学家的工作仍然是一个相当新的现象,但行业专家已经将其誉为“21 世纪最性感的工作”(例如,见这篇 HBR 文章)。各公司都在争相招聘数据科学家,对 Valiant 招聘服务的需求非常火爆。与此同时,许多数据科学角色的定义松散但利润丰厚的性质是这样的,对于 Valiant 来说,仅仅产生线索不是问题——产生好的线索才是问题。Valiant 开展的任何营销活动似乎都会收到来自拥有广泛技能和经验的候选人的大量申请。然而,Valiant 汇编的统计数据显示,跨活动的销售线索转化率往往很低。大量的营销预算和招聘资源似乎被浪费在了不良线索上。

在这种背景下,Valiant 的首席执行官已经将营销活动的优化确定为机器学习的一个高影响力用例。特别是,该公司的一名常驻数据科学家承担了构建智能优化器的任务,以提高营销活动的绩效。图 1 显示了优化器在线索生成中的作用的简化概念视图。

图 1:优化营销活动的逻辑(来源:自有插图)

为了理解图 1 背后的逻辑,假设 Valiant 要进行一场营销活动,产生大量的销售线索。这些销售线索将由营销活动优化器根据其预期投资回报(ROI)是否高于某个阈值进行实时评估;在实践中,也可以使用 ROI 以外的性能指标。现在,如果新产生的潜在客户的预期投资回报率高于所需的阈值,优化器将向营销活动管理工具提供正面反馈,否则将提供负面反馈。正反馈告诉该工具加强当前的营销活动策略,而负反馈则是纠正营销活动策略,以便将来获得的销售线索能够根据需要清除预期的 ROI 阈值。

简单地说,这种情况下的投资回报率可能是成功安置候选人的佣金除以这样做的成本(包括招聘顾问花费的时间、起草合同的法律费用和其他管理费用)。但是,我们无法在销售线索产生时计算出销售线索的实际投资回报,因为我们不知道销售线索最终是否会转化。因此,预期的投资回报率根据潜在客户实际转化的概率来贴现投资回报率——这就是机器学习可以产生巨大影响的地方。通过使用已关闭销售线索及其结果的历史数据,Valiant 的数据科学家可以构建一个模型来预测新销售线索的转化概率。预期 ROI 需要清除的阈值可能与 Valiant 的首席执行官定期为公司设定的战略目标和关键成果(okr)相关。

此外,机器学习也是通过确定如何以及在何种程度上纠正或加强营销活动来操作反馈循环的关键;这需要将学习逻辑嵌入活动管理工具中,以便它能够对优化器的反馈做出有意义的反应,并随着时间的推移改进营销活动(例如,通过更好地跨渠道分配广告支出,并优化广告消息传递,以便对目标受众更有说服力)。

准确确认销售线索

一旦新产生的潜在客户进入 Valiant 的候选人数据库,他们需要尽快获得资格,以便招聘顾问知道如何进行。以下是 Valiant 的销售线索资格认定流程可能会考虑的一些基本问题:

  • 转换的容易程度:该销售线索转换的可能性有多大,例如,我们能否将该候选人推荐给我们的某个客户,或者将该销售线索出售给合作招聘机构?这种销售线索转化的速度有多快?候选人是立即寻找新的角色,还是在六个月后?
  • 交付便利:【Valiant 转化该销售线索的难度(或工作量)有多大?公司有合适的顾问来指导候选人吗?候选人会不会太挑剔?
  • 潜在利润:这条线索能给 Valiant 带来多少利润?一旦有了线索,公司通常会收到相当于候选人在客户公司起薪 20%的佣金。因此,在其他条件相同的情况下,求职者在市场上的起薪越高越好。或者,将线索出售给合作机构会有多有利可图?
  • 战略契合度:这种领导特征适合数据科学角色吗?还是更适合另一个角色(比如软件工程、业务分析、产品管理)?

虽然手动确认每个潜在客户有其优势(当潜在客户数量较低时,它可能更便宜、更有效),但对于像 Valiant 这样快速增长、高数量的企业来说,它也有一些主要限制(不可能正确地手动审查每个潜在客户档案,并且依赖于人工参与使得难以快速高效地扩展)。此外,上述问题围绕易获取性、交付等。,往往一开始就不能高度肯定地回答。考虑到 lead qualification 问题固有的不确定性因素,该问题的自动化解决方案也应该理想地考虑这种不确定性。Valiant 的 CEO 强烈预感到,一个基于机器学习的解决方案可能正好符合要求。

首席执行官心目中的解决方案实际上相当于预测性销售线索资格。机器学习模型的合适的目标变量可以是转换的概率和转换的时间(作为转换容易程度的代表)、候选人和招聘顾问之间的交互的数量和长度以及所讨论的问题的复杂性(作为交付容易程度的代表)、通过将候选人安排在过去所实现的利润(作为潜在利润的代表)、以及从客户端招聘经理接收的关于过去的候选人对广告角色的适合性的反馈的性质(作为战略适合的代表)。这些结果的可能预测值可以从领导档案数据和 Valiant 可以访问的任何其他行为跟踪数据中得出。显然,一些结果和预测变量可能比其他变量更容易获得,因此数据收集和准备将是成功实现机器学习模型的关键。

现在,假设 Valiant 的数据科学家建立了一个模型来预测潜在客户的转化结果(即,公司是否能够成功安置候选人)。图 2 给出了这种模型可能实现的预测性能的简化视觉表示。从图中的快照可以看出,该模型总共对 25 个销售线索进行了分类(显示为点)。虚线右侧的引线被分类为潜在命中,而虚线左侧的引线被分类为潜在未命中;本质上,该模型已经预测了每个销售线索转化的概率,并且转化概率大于 50%的销售线索已经被分类为命中。此外,到目前为止,所有 25 条线索都已关闭,那些实际转换的线索(真实命中)显示为绿色,而那些没有转换的线索(真实未命中)显示为灰色。

图 2:销售线索资格模型的预测性能(来源:自有插图)

为了更好地感受图 2 所示模型的预测性能,Valiant 的数据科学家可以计算一些常用指标:

  • 准确性:这反映了被正确分类为命中或未命中的线索数量,即(6 + 14) / 25 = 20 / 25 = 80%。
  • 精度:这显示了有多少预测的命中结果后来变成了实际的命中结果,即 6 / (6 + 2) = 6 / 8 = 75%
  • 回忆:这度量了模型正确预测为可能命中的实际命中数,即 6 / (6 + 3) = 6 / 9 = 67%

因此,我们看到该模型总体上具有较高的预测准确性,尽管其预测有点保守(比召回更精确)。通常需要考虑模型的精确度和召回率之间的权衡-更严格的模型往往会实现更高的精确度但更低的召回率,而更宽松的模型则相反。在 Valiant 的销售线索资格中,精确度和召回率都很重要。一旦推广了销售线索资格模型,招聘顾问就会被告知,首先要处理那些被预测为热门的销售线索(甚至可以按照潜在转换概率的降序排列),然后再处理其余的线索。因此,高模型精度可确保顾问通过优先处理最终转化频率更高的潜在客户来充分利用他们的时间。然而,高召回率也很重要,因为忽略被模型错误地分类为错过的好线索会导致错过机会;这对于 Valiant 在一年中业务不景气的时候的财务表现尤其不利,因为招聘顾问很少有合格的销售线索。

最后,值得注意的是,根据上述任何资格标准(转换的可能性、交付的容易程度等),销售线索的吸引力。)会随着时间而改变。通过每一次电话和会面,招聘顾问都有希望更好地了解候选人的偏好、技能和工作前景。在动态的业务环境中,客户端的需求也可能发生变化。即使是 Valiant 自己的战略重点也可能从仅仅安置数据科学家和数据工程师发展到还安置商业智能工程师和其他邻近角色。销售线索资格认定流程今天对某个销售线索的评分可能与一个月后不同。这一点的一个关键含义是,所有活动的销售线索都应经常重新存储,以反映销售线索档案和评估环境的变化。重新评分可以简单地在预定的、定期的基础上(例如,每周)发生,或者由特定事件的发生而触发(例如,与候选人的电话、新客户的获得、对 Valiant 的 OKRs 的改变)。

有效地将销售线索货币化

在确认销售线索后,Valiant 可以通过转换销售线索(成功安置候选人)或将销售线索出售给合作伙伴机构来实现盈利。机器学习至少可以通过五种关键方式推动货币化:计划行动、定价销售线索、包装销售线索、向客户推销销售线索以及向合作伙伴机构传递销售线索——我们可以称之为“销售线索货币化的 5p”。让我们依次看看这些 Ps。

计划行动:

为确认销售线索而构建的预测模型对于计划如何处理给定的销售线索非常有用。例如,如果某个销售线索在所有资格标准中排名都很高,那么给予它高优先级可能是有意义的;这可能意味着在其他线索之前处理它,并将其分配给 Valiant 的一位更有经验的招聘顾问,以增加成功关闭线索的机会。相比之下,如果求职者不适合数据科学职位和/或近期内不打算找新工作,那么在转换容易度、交付容易度和战略契合度等资格标准上,销售线索可能排名较低;在这种情况下,如果可能的话,Valiant 最好将销售线索出售给合作伙伴机构。

定价线索:

如果 Valiant 希望销售销售线索,能够为其分配货币价值就变得尤为重要。理论上,Valiant 可以从给定的销售线索中获取的最高销售价格是最高出价者愿意支付的价格。如果销售价格高于产生销售线索的成本,那么 Valiant 就能获利。然而,在一开始,Valiant 可能需要报出一个合适的价格,而不一定知道潜在潜在潜在潜在买家的支付意愿,这就是来自潜在买家资格认定阶段的预测模型可以再次派上用场的地方。特别地,引导价格可以通过跨资格标准的预测概率(或分数)来加权,以平均产生一定水平的利润。

为了了解这是如何工作的,为了简单起见,假设我们只关心潜在客户的转换是否容易。如果销售线索很容易转化(转化率超过某个阈值),我们称之为“高质量”,否则称为“低质量”。实际上,我们可能期望高质量销售线索的销售线索生成成本和销售价格高于低质量销售线索。用数学术语来说,让 C(高)C(低)分别是高质量和低质量线索的线索生成成本,让 R(高)R(低)分别是 Valiant 可以从高质量和低质量线索中获得的现实销售价格或收入。如果预测生成的销售线索的一小部分 p 是高质量的,那么总预期利润将是 p(R(高)-C(高))+ (1-p)(R(低)-C(低))。至关重要的是,Valiant 可以切换公式中的杠杆( pRC ),以确定实现预期盈利水平的必要条件,并相应地为销售线索定价。

封装引线:

除了单独销售线索之外,Valiant 还可以将多个线索打包销售给有意愿的合作伙伴机构。在这种情况下,购买机构的支付意愿可能是铅包整体质量的函数。据推测,主要由高质量销售线索组成的包装可能会获得较高的价格,而销售线索购买者在不同的资格标准方面可能会有更具体的要求。拥有机器学习模型来预测多个资格标准的线索质量,将使 Valiant 能够很好地包装线索,以满足特定买家的定制要求。例如,Valiant 可以将具有某种预期的转换和交付简易性、盈利潜力等的销售线索打包在一起。

值得注意的是,虽然在人才招聘的背景下,以这种方式包装销售线索可能看起来很新颖,但这种做法在金融和保险等其他行业中实际上相当成熟,在这些行业中,销售线索包是使用复杂的数学模型构建的,以符合某些“风险概况”(例如,“AAA”,“BB”)—Valiant 可能会从这些行业借用一些概念来构建自己的销售线索包。

向客户推销销售线索,向合作机构传递销售线索:

机器学习可以用来帮助 Valiant 向客户推销线索,并以类似的方式将其传递给合作伙伴机构。在这两种情况下,Valiant 都面临着企业对企业(B2B)的交易场景。客户通常会将特定数据科学角色的人员配备外包给 Valiant,并附带特定条件(例如,员工的技能和经验水平、薪资范围、开始日期)。如果 Valiant 推荐了一位最终被录用的候选人,它就能获得佣金,不管 Valiant 在招聘过程中为寻找、审查和指导候选人付出了多少努力。因此,能够预测特定地区和时间范围内人才库的质量可以明确帮助 Valiant 决定是否值得与客户签订合同。与此同时,向合作伙伴机构销售线索意味着将 Valiant 的一些有限资源(招聘人员、预算、时间)从客户工作重新分配给销售线索——只有在特定背景下销售线索的预期价值高于从事客户工作时,这才有战略意义。同样,了解人才库可以帮助 Valiant 决定如何以最佳方式分配资源。

图 3 显示了预测模型如何指导战略性 B2B 交易。横轴根据具有高预测质量的线索的比例( p )来描述所生成的线索的质量(例如,在特定城市和一年中的特定时间)。纵轴显示了给定交易在不同的 p 值下的预期利润。图 3 示出了 Valiant 可能必须在两个示例交易之间进行选择的比较。请注意,尽管在 p 值较低的情况下,交易 1 不如交易 2 有吸引力,但一旦高质量销售线索的比例超过值 p* ,交易 1 就会变得更有吸引力。在其他条件都相同的情况下,如果 Valiant 能够得出 p* 和 p 的值,那么它就有可能做出合理的战略决策,这正是预测性销售线索资格模型的用途。

图 3:战略性 B2B 交易(来源:自有插图)

包裹

机器学习可以帮助企业产生更好的线索,以更高的准确性证明它们,并最终更有效地将其货币化。鉴于每个阶段的目标不同,机器学习帮助解决的问题以及解决方案的性能和局限性在三个阶段都有所不同。

值得注意的是,尽管 Valiant 是一家虚构的公司,旨在通过示例来帮助解释机器学习的价值,但 Valiant 在销售线索管理方面面临的问题,以及使用机器学习解决这些问题的机会,都牢牢植根于现实。事实上,Valiant 的案例研究代表了几个类似数据科学项目的某种风格化融合,我和其他人过去都参与过这些项目。除了招聘之外,从金融和保险到旅游和汽车零售的各种行业都可以从更智能和可扩展的领导管理方法中受益匪浅。

最后,虽然越来越有可能购买软件即服务(SaaS)解决方案来进行销售线索管理,但对于公司来说,推动自己的销售线索管理议程仍然很重要。除其他事项外,议程应阐明铅管理的动机(“为什么”),规定 SaaS 系统的成功标准(例如,最低准确度、精确度等)。),并将它们链接回战略 KPI(例如,转换率、利润等)。)这将是公司高管和投资者最关心的问题。

机器学习介绍——面向经理

原文:https://towardsdatascience.com/machine-learning-for-managers-1599a26ca145?source=collection_archive---------35-----------------------

权威指南

机器学习项目成功所需的一切。

源作者

构建机器学习解决方案不同于构建通用软件解决方案。监督机器学习项目涉及一些独特的方面和潜在的陷阱。

在本指南中,我们将回顾交付一个成功的机器学习解决方案所需的所有见解。

对于更高层次的概述,也看一看什么是人工智能?首席执行官需要知道的一切人工智能的 4 个关键成功因素

这篇文章是写给谁的?

这篇文章是为那些为大中型企业构建机器学习解决方案的人而写的。如果你想学习机器学习是为了好玩或者获取一般知识,那么自己或者和一个没有经验的团队建立一个概念证明是完全可以的。但我们将假设你的任务是建立一个大规模的机器学习项目,承担真正的风险(如果失败)并产生真正的价值(当成功时)。

什么是机器学习,为什么它很重要?

虽然机器学习可以在许多不同的领域增加巨大的价值,但它也经常被夸大。我们都看过科幻电影,人们可能会很容易认为机器学习是赋予机器人类水平的智能。事实上,虽然机器学习可以在许多方面帮助你,但最好将其视为一种分析数据的专门工具,而不是解决任何问题的灵丹妙药。

什么是机器学习?

机器学习最终是在结构化数据中寻找模式并做出预测。这些可以是(而且经常是)对未来将要发生的事情的预测。但这不是你在机器学习解决方案中找到术语“预测”的唯一方式。通常这也意味着预测一些问题的答案,比如:“这张照片里是哪种狗?”后一种预测不是基于时间的预测(展望未来),而是这样一种预测:“如果问这个特定的问题,一个无所不知的先知会给出什么答案?”

机器学习和传统软件有什么不同?

机器学习也可以认为是“从数据中学习”。传统的软件解决方案是围绕演绎构建的(一个聪明的人确定一组规则,并将它们编码为一系列 if 语句,然后这些规则可以应用于数据),而机器学习解决方案是围绕归纳构建的(机器学习算法通过查看大量示例自动发现规则,然后这些规则可以应用于更多数据)。

传统的软件解决方案是围绕演绎构建的,而机器学习解决方案是围绕归纳构建的。

传统编程与机器学习——来源作者

机器学习和 AI 有什么不同?

作为题外话,我们将在整篇文章中使用术语“机器学习”,但在通常的用法中,术语“人工智能”或“AI”经常被代替使用。更详细的讨论见机器学习 vs .人工智能。他们不是同一个

为什么机器学习很重要?

机器学习,尤其是最近的进步,几乎肯定能给你的业务带来新的机会,无论你在哪个领域。机器学习受到如此多关注的原因之一是因为它被用于推动几个看似不相关的领域的突破,包括:

  • 图像处理(比如面部识别);
  • 声音处理(例如,带字幕的自动字幕视频);
  • 文本处理(比如不同自然语言之间的翻译);
  • 时间序列处理(例如预测未来能源使用量);
  • 数字建模(例如,估算一栋房子的合理价格,或者某个特定客户购买某种产品的概率)。

这些领域中的每一个都扩展到更多的子领域(例如,我们用于面部识别的相同算法也可以在 X 射线中检测癌症),更重要的是,非常相似的算法可以用于所有这些领域,这意味着一个算法的进步可以导致许多领域的进步。这适用于几乎每一个领域,包括医药营销金融,以及交易

这些领域中的机器学习都是由巨大的(并且不断增长的)数据集实现的。机器学习的改进释放了这些数据的更多价值,因此数据本身变得更有价值。随着对数据的更多关注,机器学习模型会进一步改进,从而形成良性循环。

机器学习是否很适合你的公司和项目?

机器学习有如此大的潜力,几乎每个公司都想使用它。但这并不意味着它总是一个好主意。

作为一名业务经理,你会面临两种风险:

  • 迫使机器学习成为一种解决方案,在这种情况下,它不能增加价值,以努力保持现代化和相关性;
  • 未能在解决方案中利用机器学习,而 it 增加价值。

虽然每种情况都是独特的,但关于机器学习是否对你的公司或项目有益,还是有一些好的经验法则。

机器学习解决方案可能非常适合的常见迹象。

  • 你依靠人工来完成看似重复的任务。这些“重复性”任务通常没有完全定义,也不像看起来那样重复。例如,如果你雇佣一些人来撰写销售电子邮件或处理支持案例,机器学习解决方案可能能够帮助他们提高效率,但它无法取代他们,因为他们的许多任务都依赖于同情心和创造力。
  • 你期望收集大量数据。团队抢先实施机器学习是很常见的,因为他们希望他们的应用程序一旦成功就能处理大数据。在这些情况下,最好先集中精力收集和组织数据,手动获得洞察力,然后在稍后阶段考虑机器学习

机器学习解决方案可能不适合的常见迹象。

请记住,这些只是指导方针。几乎每个公司都能在某个地方找到机器学习用例。问题是你现在是否需要机器学习,投资回报率(ROI)会是多少。如果您的公司仍然很小,或者您只有一点点数据,您可能会从手动分析数据中获得更大的投资回报。但如果不是,机器学习很可能会帮你创造价值。

在生产中运行的机器学习解决方案实际上是什么样子的?

花 2-3 周时间拼凑一个 PoC(概念验证)可能很有诱惑力:一个可以接受你的公司拥有的一些数据并产生一些潜在有用的预测的模型。有数以百万计的教程向您展示如何使用一些标准库,用几行代码实现这一点,并且很容易认为生产您的模型会很容易。不会的。虽然许多人可能认为创建第一个模型会让他们走完 80%的机器学习解决方案之路,但之前构建和生产过机器学习解决方案的人会知道,PoC 更接近于旅程的 10%

  • 数据:用于发现已有模式,建立模型;
  • 代码:用于定义和服务模型,并与其他服务集成;
  • 模型:用于生成预测。

所有机器学习解决方案都可以大致分为三个概念:

机器学习解决方案:概念验证与生产-来源作者

在比较 PoC 和生产解决方案时,这三者看起来非常不同。

ML 解决方案中只有一小部分是真正的机器学习代码。-来源作者

生产解决方案也有更多的活动部分。概念验证通常涉及构建一个简单的模型,并验证它是否能够生成通过快速健全检查的预测。一切都可以在同一台机器上完成。相比之下,这只是生产流程的第一部分。在生产阶段,你需要一个强大的培训服务器和一个跟踪不同模型的良好流程。在将训练好的模型与您现有的生产服务集成之前,您需要一种方法来测试它们,大规模地执行推理,并监控一切以确保它们都是可靠的。最后,您将多次迭代这个过程,因为您可以改进数据、代码或模型组件。

你需要什么样的团队来生产机器学习解决方案?

当你在建立一个机器学习团队时,雇佣有学术背景的研究人员是很有诱惑力的。如果他们发明了新的机器学习算法,他们一定是使用这些算法的最佳人选,对吗?不总是。

雇用一名研究人员为你构建一个机器学习解决方案,通常就像雇用一名设计凯膳怡电器的人为你做饭一样。虽然研究人员提出了解决问题的新方法,并具有深厚的理论专业知识,但他们在使用现有工具、遵循良好的工程实践以及做出困难的时间/质量权衡方面往往缺乏更多的实践专业知识。

雇用一名研究人员为你构建一个机器学习解决方案,通常就像雇用一名设计凯膳怡电器的人为你做饭一样。

通常情况下,你希望有人能够使用现有的机器学习算法和工具——就像厨师使用标准食材和厨房电器熟练地拼凑出美味的一餐——而不是从头开始设计新工具。

术语仍然不完全一致,但你通常会找到至少一名机器学习工程师——专门为企业构建机器学习解决方案的人。

应该找还是建立一个机器学习团队?

你需要做出的主要选择是建立自己的机器学习团队还是聘请咨询公司。建立自己的团队可能需要很多年,如果你不需要立即看到结果,并且如果你希望机器学习成为你和你的竞争对手之间的关键区分因素,这可能是唯一正确的选择。

如果你建立了一个团队,你也可以选择提升现有员工的技能,而不是雇佣新员工。在这种情况下,您可能想知道是向您的数学家传授工程技能,还是向您的工程师传授数学和统计技能。无论哪种方式,这都是一个困难的飞跃,但一个好的工程师通常可以在大约 2 年内学到足够的数学和统计学知识(特别是如果他们已经有一些基础背景的话),成为一个伟大的机器学习工程师,而统计学家通常需要更长的时间来掌握所有的工程背景和所需的工具集(通常在 5 年左右)。

有效的机器学习团队应该是什么样子——来源作者

一个好的机器学习团队不仅仅依靠机器学习工程方面的专业知识。软件工程、DevOps 和管理方面的专业知识同样重要,常见的结构可能如下所示:

数据营收,我们团队的每个人都是机器学习工程师。这使我们比那些将机器学习视为达到目的的手段而不是目的本身的公司更有优势。但我们仍然花了 2 年的时间反复试验,建立了一个优秀的团队,花了 4 年时间,我们才完全相信我们招聘机器学习工程师的过程(我们现在每 150 名合格的申请人中就有 1 人被聘用)。

如果你认为人工智能是帮助你超越竞争对手的主要因素,那么建立一个团队是有意义的。如果机器学习只是让你达到顶峰的一部分,那么引入外部专家可能会更好。

但是雇佣中介也有风险,尤其是如果你雇佣了错误的中介。所以你需要知道如何选择机器学习咨询公司

机器学习项目的理想结构是什么?

仅仅构建机器学习解决方案的技术部分本身就具有挑战性。组织好整个项目需要商业和技术技能的罕见结合,在你开始之前,你会想好一个好的工作流程的所有不同阶段。

规划一个机器学习项目最重要的事情之一就是考虑到生产进行规划。如果你的目标是概念验证,那么这就是你将得到的。虽然这是一个好的开始,但是您希望从事 PoC 工作的人员不断地优先考虑投入生产的目标。

PoC 和生产之间的一个很好的中间阶段是试生产阶段。这看起来几乎完全像一个生产解决方案,但它可能在范围、面向多少用户或使用多少数据方面受到限制。

从一开始,你就应该仔细构建研究和实验阶段的结构和时间表。重要的是,每个人都知道目标是:“x 天内我们能得到的最好的模型是什么?”而不是“我们能得到的最好的模型是什么?”否则,你将永远陷入“再做一次实验”的怪圈。

弄清楚闪亮的新机器学习解决方案将会影响到公司的哪些内部和外部部门也是至关重要的。如果你要替换另一个团队开发的非机器学习解决方案,请记住,他们可能会依赖他们的方法。“此处未开发”是一个很难跨越的障碍,无论是在您公司内部的团队之间,还是在外部团队和您的团队之间。

在你开始建造之前,确保你的模型可以缩放。通常,一个解决方案在 PoC 甚至是试点阶段都工作得很好,但是机器学习解决方案具有密集和独特的资源需求,如果没有适当的规划,它很容易淹没您的基础架构。确保您的解决方案足够高效,可以扩展到在您的完整数据集上进行培训,并处理您希望它上线后收到的请求数量。

在更高的层面上,确保你在开始之前已经考虑了我们的机器学习项目清单中的一切。

为什么你仍然可能失败:常见的陷阱

  • 人们可能不信任你的模型:即使你的模型产生了非常准确的预测,如果你不能解释你是如何得到答案的,也很难赢得你的团队和你的客户的信任。在你致力于机器学习解决方案之前,你应该理解任何关于可解释性和可解释性的硬性要求。在某些领域,比如药理学,可解释性也可能是一个法律要求。
  • 你可能会构建一个不可维护的解决方案:仅仅有一个现在可以工作的模型是不够的。您的解决方案需要维护、更新和修复。您将需要一个良好的管道来将模型、代码和数据的更改引入到未来的生产中,否则您将会得到一个今天有效明天无效的模型,并且在您的需求发生变化时无法修复。拥有一个已经犯过这些错误并从中吸取教训的有经验的团队是避免这种情况的好方法。
  • 你的模型可能过于复杂:即使你的模型产生正确的结果,在构建机器学习解决方案的所有工作完成之后发现一个更简单的解决方案也是令人惊讶的。例如,您的研究可能会发现,您可以通过查看一年前同一天的价格来预测价格。因此,在您构建任何模型之前,您应该首先创建最合理的基线,并在项目期间将其用作基准测试。
  • 你的模型可能会伤害或威胁某个特定的业务部门:虽然机器学习通常会增强而不是取代人类的才能,但在某些情况下,人们可能会将你的解决方案视为对他们工作的威胁。例如,一个金融专业人员的整个职业生涯可能围绕着寻找数据模式,也许你的模型自动化了其中的每一个方面。坦率地说出你的模型的目标是什么,以及它是否会影响你公司现有的角色。与你的团队讨论他们的角色可能会如何改变,以及使用 ML 来完成一些更单调乏味的任务如何能让他们专注于算法不能做的事情。
  • 外部因素可能会发生变化:机器学习解决方案自然对它们接受训练的数据非常敏感。如果外部事件意味着当前数据与历史数据非常不同,您可能会看到模型的可靠性急剧下降。例如,根据 2019 年 4 月的时态数据训练的模型在 2020 年 4 月可能非常不准确,因为新冠肺炎危机打破了许多模式和预期。
  • 你的模型可能会显示偏差:在机器学习训练的数据中存在人类偏差是很常见的。例如,美国司法程序中用来决定提前释放哪些囚犯的 COMPAS 系统被发现有明显的种族偏见。如果你的机器学习解决方案存在偏见,尽早发现这一点是至关重要的,而不是在项目投入生产后就关闭整个项目。

我们已经提到了陷入 PoC 阶段的危险,有错误的团队,或者当机器学习不适合特定问题时使用机器学习。但是在前进之前,您应该知道更多潜在的陷阱:

构建机器学习解决方案肯定是一项艰巨的任务!我们希望你读完这篇文章后会对此更有信心。

https://www.datarevenue.com】最初发表于

新生儿重症监护的机器学习

原文:https://towardsdatascience.com/machine-learning-for-neonatal-intensive-care-15b3874da1f6?source=collection_archive---------43-----------------------

告知最困难的决定

Unsplash 上的 Hush Naidoo 拍摄的照片

一个微小的新人类被机器和传感器包围着。一位医生担忧地看着。她知道几率。

29%

23 周出生婴儿的存活率。她把想法放在一边,做她能做的事。

NICU 内部

新生儿重症监护病房(NICU) 是一个做出改变人生决定的环境。新生儿学家使用各种来源的信息来构建新生儿的状况图,以确保他们得到正确的医疗护理。这些训练有素的专家根据源源不断的患者数据做出判断,以确保尽可能多的婴儿能够随父母回家。

正确解读这些海量数据并确定适当的护理是一项极其困难的任务。然而,机器学习正被用来识别和开发可以增强这些决策过程的方法。在这个最重要的领域,机器学习被应用于改善患者结果的方式有四种。

预测出生窒息

当婴儿在分娩过程之前、之中或之后缺氧时,就会发生出生窒息,这是五岁以下儿童死亡的第五大原因。它与同样大量的死产有关,并且由于由此导致的器官损伤,经常会导致长期残疾和损伤。

在设备齐全的医院,这种情况的诊断是通过观察血液中的酸水平,使用试探法,如阿普加试验,并通常寻找其他神经问题或呼吸窘迫的迹象。尽管有这些程序,症状可能并不总是立即明显,直到为时已晚。特别是,某些发展中国家的医院可能不具备能够进行常规决定性测试的设备或基础设施。

乌本瓦 是一款移动应用,使用语音识别领域的技术来检测新生儿哭声中出生窒息的早期迹象。2015 年,Charles Onu 开发了一个原型基于支持向量机的机器学习模型,它可以在实验室环境中以 89%的准确率对已知窒息婴儿的记录进行正确分类。2017 年,查尔斯和他的团队将这个模型构建成了一个原型移动应用,有可能成为一个广泛可用的工具,可以部署到资源匮乏的环境中。

一个主要障碍是缺乏窒息婴儿的临床注释数据(即哭声记录)。查尔斯和乌本瓦大学的其他人最近探索了一个想法,即迁移学习可以用来应用从成人言语中习得的表征,以克服训练数据的缺乏。

检测癫痫发作

新生儿癫痫发作是一种需要紧急护理的严重疾病——如果癫痫发作未被发现和治疗,可能会导致脑损伤甚至死亡。与较大的儿童和成人不同,婴儿的癫痫症状在临床上并不总是可见的,这使得他们很难被发现。

唯一可靠的检测方法是通过脑电图或 EEG 监测大脑的电活动——但这些信号是不断产生的,通常需要训练有素的专业人员来正确解释输出。

在 2011 年, Temko 等人发表了一篇论文,他们在论文中训练了另一个基于支持向量机的模型,将脑电图活动片段分类为癫痫发作/非癫痫发作事件。他们的模型能够在测试脑电图数据中检测到高达 100%的癫痫事件——尽管有一些假阳性结果。然而,该模型的灵敏度可以根据可以容忍的假阳性的数量来调整。调整到没有假阳性指示的水平,该模型仍然能够检测超过 50%的癫痫发作,这仍然是一个重要的和有希望的成就。

莎伦·麦卡琴在 Unsplash 上的照片

脓毒症的早期识别

当身体对感染反应过度,随后的免疫反应开始对身体自身的器官和组织造成损害时,就会发生脓毒症。这种情况与高死亡率有关,并且可能是如此具有破坏性,以至于被认为有风险的新生儿通常被尽快给予抗生素,直到败血症被排除。相对较少的足月儿(不是早产的婴儿)会受到败血症的影响,但是早产儿的风险要高得多。三分之一的极早产儿(出生时胎龄小于 28 周)在重症监护期间会发生败血症。
早期诊断对于最大限度地提高良好临床结果和恢复的机会至关重要,但诊断脓毒症的困难在于其迹象是非特异性的——也就是说,许多其他疾病和状况都可能产生类似的症状。

2019 年, Masino 等人 开始研究机器学习模型是否可以用来在婴儿败血症被临床怀疑前四小时识别它。他们在 30 个特征上训练了 8 个不同的机器学习模型,这些特征是在领域专业知识的帮助下选择的。从婴儿身上收集的这些特征包括生命体征、临床评估结果以及从各种实验室程序(如血液测试)中获得的值。发现八个模型中的六个表现良好,实现了 0.85-0.87 的 AUC。进一步的研究正在进行中,以确定这些模型是否可以在试验中提高临床效率。

预测呼吸窘迫综合征

新生儿呼吸窘迫综合征(NRDS)是生命第一个月死亡的主要原因之一。即使在发达国家,死亡率也可能高达 60 %( T10 ),而且很大一部分存活下来的婴儿仍然会发展成改变生活的障碍。 NRDS 发生在 10%的早产儿身上,通常发生在婴儿尚未产生足够的肺部所需物质来防止气道塌陷的时候。在严重的情况下,需要机械通气。

2016 年,数字诊断公司 SIME Dx 宣布,它已经开发出一种测试,可以准确预测哪些婴儿有患呼吸窘迫综合征的风险。这项测试利用了一种装置,该装置使一束红外光穿过胃液样本——一种通常从出生婴儿身上采集的物质。一个独特的签名产生了,然后通过管道进入 SIME 的人工智能工具,以高度的灵敏度预测 NRDS。反过来,这使医生能够判断哪些婴儿需要治疗,哪些不需要,确保及时护理,减少不必要的程序。2018 年,SIME 宣布了一种完全自动化测试的新设备,目前正在商业化的道路上。

结论

看到一个戴着呼吸机的小婴儿,人们不禁感到一阵激动,也许还有一种宇宙不公平感。除了我们保护和支持孩子的进化本能,每一个新生命都伴随着一种更深刻的价值感。那双不可思议的明亮而好奇的眼睛是一个光圈,背后隐藏着难以想象的无价潜力。一套独特的想法和观点将会改变世界。每一个不能被拯救的婴儿都是全人类的损失。

如果我们能提高 NICU 婴儿的存活率——哪怕只有一个百分点——谁知道会带来什么新的想法和观点。机器学习和人工智能可以帮助我们释放这种潜在的人类潜力,一次一个模型。

更多信息和积分

Andrew Hetherington 是英国伦敦的一名见习精算师和数据爱好者。

  • LinkedIn 上与我联系。
  • 在 andrewhetherington.com 查看我的网站。
  • 看看我在 GitHub 上摆弄什么。

图片:婴儿在保育箱里,由 Hush Naidoo 拍摄。戴着氧气面罩的婴儿。

科学废物管理的机器学习

原文:https://towardsdatascience.com/machine-learning-for-scientific-waste-management-a27e7c561d64?source=collection_archive---------55-----------------------

喀拉拉邦——上帝自己的国家(照片由 Avin CPUnsplash 上拍摄)

顶点案例研究

了解 ML 如何帮助防止气候变化和保护社区健康

T 他的案例研究是通过 Coursera 完成的 IBM 应用数据科学顶点项目的一部分。本研究的目的是为印度南部喀拉拉邦的高知市列举合适的城市垃圾管理地点。我选择高知市进行这个案例研究,不仅是因为它是我的故乡,而且高知市过去和现在都在努力有效地管理城市垃圾。

高知市——概述

高知湖(来源:照片由 Unsplash 上的 gaurav kumar 拍摄)

高知市(有时称为科钦市)是一个港口城市,至少有 600 年的贸易历史,主要是与中国、欧洲和阿拉伯商人,这使该市成为喀拉拉邦的金融中心。举几个例子,科钦证券交易所——喀拉拉邦唯一的证券交易所,国际集装箱转运站,造船工业,信息园——政府经营的信息技术园,露露购物中心——亚洲最大的购物中心证明了高知市的经济重要性[1]。高知市不仅是一个理想的商业场所,而且还提供负担得起的住房选择。高知也是一个旅游景点,吸引了来自世界各地的游客。所以基本上高知市都是限量版的全合一套餐。

废物管理危机

高知市雅鲁藏布江废物管理设施(来源:[5])

高知市每天产生约 380 吨垃圾,其中 150 吨可生物降解,其余为塑料垃圾[2]。目前,城市垃圾被送往雅鲁藏布江垃圾管理设施进行处理。从这个工厂建立之初,公众、环保主义者的抱怨和担忧就成了报纸上反对工厂选址和工厂选址方式的头条新闻。许多居民被政府带着补偿金迁移了。河水污染,因为该工厂与两条淡水河流接壤,而且由于选择废物管理工厂的位置时采用了不科学的方法,工厂的生命遭到了破坏。目前的工厂位置已经让雅鲁藏布江居民的生活变得悲惨——来自食物垃圾的令人作呕的恶臭和令人讨厌的家蝇和蚊子。此外,用于处理的输入废物是可生物降解的和塑料废物的混合物,并且可生物降解的材料在户外分解,因为据报道在工厂中的处理过程缓慢,这导致另一个恐怖——气候变化,因为可生物降解的材料正在分解,从而释放出甲烷,一种温室气体。此外,巨大的火灾越来越频繁,有毒气体扩散到整个城市,扰乱城市生活数日[3]。

雅鲁藏布江发生火灾(来源:《印度时报》)

由于这一事实,市政当局已经暂停从家庭收集垃圾,直到找到合适的解决方案。喀拉拉邦污染控制委员会进行了一项关于城市垃圾管理的研究,报告称垃圾发电不是解决高知市垃圾管理危机的经济有效的解决方案[4]。由于高知正在增长,每天产生的垃圾也在增加。布拉马普拉姆设施目前超负荷运转,因为除了商业和住宅废物之外,还必须容纳医疗废物,这使危机进一步复杂化。即使找到了管理城市垃圾的理想解决方案,工厂目前的位置对地下水储备以及流经的两条河流的质量构成了严重威胁。目前的工厂位置是一场灾难,将影响高知居民的生活以及高知的经济健康。

案例研究路线图

有几份报告和关切涉及在雅鲁藏布江最终确定当前城市废物管理设施的位置时采用的不科学方法。[5]

雅鲁藏布江的人们在工厂建成后逃离家园(来源:参考文献[2])

确定当前工厂位置的谬误的一个重要证据是它靠近高知自己的 IT 园区 InfoPark,离工厂只有 5 公里。另一个证据是,该地区是沼泽,地下水渗透废物分解的化学副产品的风险。所有这些问题促使我寻找一个理想的厂址来建立一个新的废物处理厂——一个不会损害自然和社会的工厂。然后下一个问题来了,怎么做?

这个想法是找到世界上最干净的城市,并在选择的城市中模拟该城市的垃圾管理设施的位置/邻近区域。在这里,我使用的逻辑是——如果有一个清洁的城市,那么它就有一个高效的废物管理设施,背后将有强大和成功的管理实践,这些管理实践将受到强大的环保和社会承诺的规则和政策的约束。因此,模拟这种废物管理设施的位置将等同于模拟那些非常成功的规则和政策。然后,我去打猎,发现加拿大的卡尔加里市是世界上最干净的城市之一,我选择它是因为卡尔加里市一直在世界上最干净的 10 个城市中占有一席之地。

卡尔加里市(来源:drpukka/Instagram)

卡尔加里市有两个商业废物管理设施,我选择了其中的一个,只是通过方便取样——东卡尔加里设施。然后,是时候用数学方法来表示东卡尔加里工厂了。这个问题的答案是,Foursquare API。它为全球数百万个场馆提供位置数据。使用 Foursquare API,获得了东卡尔加里设施 5000 米范围内的场馆,并使用场馆类别生成了东卡尔加里设施的向量。现在,要模拟的参考位置已准备就绪,是时候获取感兴趣的城市高知市所在的 Ernakulam 区的社区列表了。这些社区中的一些将被选为建立新的废物管理工厂的最佳选择。使用 BeautifulSoup 的 Webscraping 提取 Ernakulam 的所有邻居列表,使用 Geopy 提取所有这些邻居的地理位置数据。然后,就像东卡尔加里设施一样,Ernakulam 的每个街区都被表示为一个场地类别向量。然后是最后的预处理阶段——确保东卡尔加里社区和 Ernakulam 社区通过相同的场所类别来表示。用外行人的话来说,我确保所有的社区都在相同的基础上进行比较!

预处理后,东卡尔加里设施点矢量被合并到包含 Ernakulam 邻域的数据帧中,这就是我们的聚类数据集。

下一步是对邻域进行 K-均值聚类,并分割出不同的邻域,但在此之前,要进行肘形曲线分析,以确定最佳聚类数。有了最佳的聚类数,K-Means 被执行,并且我们的理想邻域(即东卡尔加里设施的邻域)被确定,并且 Ernakulam 的邻域属于相同的聚类。邻里模拟的最初部分已经结束。考虑到雅鲁藏布江现有废物管理设施的缺陷,我们对聚类后获得的 Ernakulam 社区列表进行了第二级细化。

最后结局

网络搜集和地理定位数据采集产生了 45 个基于邮政编码的 Ernakulam 社区。预处理阶段将邻域减少到 32 个。这样聚类数据集就准备好了,肘曲线分析表明聚类的最佳数量是 4。

获取最佳聚类数的肘形曲线分析

K-means 聚类在下面的可视化中进行了描述:

邻域聚类的可视化。蓝圈是高知中心,大头针标记是雅鲁藏布江废物管理设施

Ernakulam 有 16 个社区与东卡尔加里设施属于同一个集群。

但是,作为最后一步,考虑到雅鲁藏布江现有设施的一个重要缺点——靠近水体,我决定过滤掉获得的 Ernakulam 邻域。这一过滤过程进一步将选择的数量减少到 7 个(Palarivattom、Kaloor、Ernakulam North、Thammanam、Kadavanthra、Panampilly Nagar 和 Vyttila 是选择),如下图所示:

结论

高知回水邮轮旅游(来源)

长期以来,高知市在废物管理方面正经历着一场重大危机,这项研究提出了 7 个适合使用机器学习科学地建立新工厂的地点。现在,城市管理人员可以评估这些建议,并从中找出最佳点,从而加快城市管理,减少决策失误。由于模拟了世界上最干净的城市之一的垃圾管理设施,城市管理者可以使用卡尔加里市的垃圾管理政策和规则,并根据高知市的要求进行一些调整。因此,所有这些决定将使废物管理过程更加有效,从而可以防止废物在设施中堆积,从而最大限度地减少由此产生的甲烷排放量——这是对联合国可持续发展目标(目标 11) [7]的一种贡献。使用这种方法可以缓解严重的公共健康问题,如由于雨水停滞导致的疟疾等流行病,以及由于工厂位置不科学导致的肺部或皮肤疾病。本研究未考虑地理、政治和社区行为差异,考虑这些变量后,结果可能会有所不同。未来可能的扩展包括:基于密度的空间聚类应用研究(DBSCAN)、环境热点或人口密度变量包含、不同地理定位数据供应商的使用。这个项目的另一个优点是,它可以适用于政府和企业的目的,以及无论州或国家。

参考

  1. 高知经济
  2. 布拉马普拉姆邦火灾频发
  3. 高知废物管理危机
  4. 雅鲁藏布江的垃圾发电不划算
  5. 公众对雅鲁藏布江电站的担忧
  6. 全球十大最干净城市
  7. 联合国可持续发展目标

用于股票预测的机器学习。定量方法

原文:https://towardsdatascience.com/machine-learning-for-stock-prediction-a-quantitative-approach-4ca98c0bfb8c?source=collection_archive---------4-----------------------

训练用于股票价格预测的多个模型并分析它们的结果

马库斯·斯皮斯克在 Unsplash 上的照片

使用机器学习来预测股价可能具有挑战性,而可能很难。模拟股票价格的动态可能很难,在某些情况下,甚至是不可能的。

在本文中,我将介绍一些使用机器学习预测股票价格的技术。我们将看到一些模型的运行,它们的性能以及如何改进它们。所有的计算都将使用著名的 Pandas、NumPy 和 Scikit-learn 库在 Python 中完成。

数据准备

对于这个例子,我将使用微软过去 10 年的每日股票价格,从雅虎财经下载 CSV 格式。除了交易量之外,该数据集还包括最高价、最低价、开盘价和调整后的收盘价。

首先,让我们加载数据集。为了简单起见,我将用“调整后收盘价”来代替“收盘价”。

df = pd.read_csv("MSFT.csv",index_col=0)df['Close'] = df['Adj Close']
df = df.drop("Adj Close",axis=1)

生成输入要素

价格本身不足以产生有用的预测。对于本例,我将添加以下指示器,它们将用作我们模型的输入:

  • 移动平均线(最近 N 天的平均价格)
  • 布林线(移动平均线加上或减去一定量的标准差)
  • 唐奇安通道(过去 N 天的滚动最高价和最低价)

我们再加上周期为 5,10,20,50,100 200 的简单均线

for sma_period in [5,10,20,50,100,200]:
    indicator_name = "SMA_%d" % (sma_period)
    df[indicator_name] = df['Close'].rolling(sma_period).mean()

现在让我们添加布林线,设置如下:

  • 20 个周期,2 个标准差
  • 20 个周期,1 个标准差
  • 10 个周期,1 个标准差
  • 10 个周期,2 个标准差
df['BollingerBand_Up_20_2'] = df['Close'].rolling(20).mean() + 2*df['Close'].rolling(20).std()df['BollingerBand_Down_20_2'] = df['Close'].rolling(20).mean() - 2*df['Close'].rolling(20).std()df['BollingerBand_Up_20_1'] = df['Close'].rolling(20).mean() + df['Close'].rolling(20).std()df['BollingerBand_Down_20_1'] = df['Close'].rolling(20).mean() - df['Close'].rolling(20).std()df['BollingerBand_Up_10_1'] = df['Close'].rolling(10).mean() + df['Close'].rolling(10).std()df['BollingerBand_Down_10_1'] = df['Close'].rolling(10).mean() - df['Close'].rolling(10).std()df['BollingerBand_Up_10_2'] = df['Close'].rolling(10).mean() + 2*df['Close'].rolling(10).std()df['BollingerBand_Down_10_2'] = df['Close'].rolling(10).mean() - 2*df['Close'].rolling(10).std()

最后,让我们加上均线周期相同的唐契安通道。

for channel_period in [5,10,20,50,100,200]:
    up_name = "Donchian_Channel_Up_%d" % (channel_period)
    down_name = "Donchian_Channel_Down_%d" % (channel_period)

    df[up_name] = df['High'].rolling(channel_period).max()
    df[down_name] = df['Low'].rolling(channel_period).min()

现在我们想在的几个时间滞后中使用所有这些功能(即最后一天、最后两天等等),所以我们需要全部延迟一些时间。对于本例,我们将把它们从 1 天改为 10 天。

newdata = df['Close'].to_frame()
for lag in [1,2,3,4,5,6,7,8,9,10]:
    shift = lag
    shifted = df.shift(shift)
    shifted.columns = [str.format("%s_shifted_by_%d" % (column ,shift)) for column in shifted.columns]
    newdata = pd.concat((newdata,shifted),axis=1)

看一下数据集,我们现在会注意到像 SMA _ 5 _ shifted _ by _ 3 这样的特征。意思是“前 3 天计算的 5 期移动平均线”。

最后,我们将创建目标变量,这是我们希望预测的数字。对于这个例子,假设我们想预测未来 5 天的收盘价。

forward_lag = 5newdata['target'] = newdata['Close'].shift(-forward_lag)
newdata = newdata.drop('Close',axis=1)newdata = newdata.dropna()

我们现在有了大量的数据(2302 行× 311 列),如下图所示。

在训练集和测试集中拆分

像往常一样,我们将把数据集分成训练测试集。训练集将用于训练我们的模型并调整超参数,而测试集将仅用于性能计算。

随机执行分割

X = newdata.drop("target",axis=1)
Y = newdata['target']X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=42)

特征选择

310 个特性是一个很大的数字。只拿最重要的非常有用。对于本例,我们将根据每个特征和目标的皮尔逊相关系数的绝对值对特征进行排序。这个想法是只选择与目标最相关的 50 个特征。

correlations = np.abs(X_train.corrwith(y_train))features =  list(correlations.sort_values(ascending=False)[0:50].index)X_train = X_train[features]
X_test = X_test[features]

现在我们可以从模型开始。

线性回归

先说有史以来最简单的回归模型,那就是线性回归

首先,我们将训练模特。

lr = LinearRegression()lr.fit(X_train,y_train)

然后我们计算模型的预测

y_pred = lr.predict(X_test)

预测可以与真实测试集数据进行比较,以计算预测误差。对于这个例子,我将使用平均绝对误差

mean_absolute_error(y_test,y_pred)

误差为 1.325

我们最终可以绘制测试集的真实值预测值来检查它们是否位于穿过 0 的 45°线上

plt.scatter(y_test,y_pred)
plt.xlabel("Real")
plt.ylabel("Predicted")
plt.title("Linear regression")plt.show()

如你所见,真实值和预测值非常相似。

随机森林

下一个模型是来自 sklearn 库的随机森林回归器

由于随机森林模型有许多超参数,通过随机搜索微调它们是有用的。我们要调整的超参数是树的数量特征的数量

我们将使用 5 重交叉验证执行 20 步随机搜索,计算每重的平均绝对误差,然后在 5 重中取平均值。最小化误差(即最大化带负号的误差)的超参数值是最佳值。

rf = RandomizedSearchCV(RandomForestRegressor(),
param_distributions =  {
                  'n_estimators':np.arange(10,500,5),
                  'max_features':np.arange(1,10,1)
               },
                  cv=5, n_iter = 20,
                  iid=False,random_state=0,refit=True,
                  scoring="neg_mean_absolute_error")rf.fit(X_train,y_train)

超参数的最佳值是:

用用于线性回归的相同代码计算的平均绝对误差是 0.868

这是散点图。

随机森林显示出比线性回归更低的误差。

梯度推进树回归器

我们现在可以尝试使用梯度推进树回归器,它使用推进技术来提高模型精度。

我们仍然有两个超参数,它们是在提升序列中使用的树的数量和特征的最大数量。

gb = RandomizedSearchCV(GradientBoostingRegressor(),
param_distributions =  {
               'n_estimators':np.arange(10,500,5),
               'max_features':np.arange(1,10,1)
            },
          cv=5, n_iter = 20,
          iid=False,random_state=0,refit=True,
          scoring="neg_mean_absolute_error")gb.fit(X_train,y_train)

超参数的最佳值是:

平均绝对误差为 0.916,下面是散点图。

GBR 是一个很好的模型,但有一个略高于随机森林的误差。

k 个最近邻居

KNN 在许多应用程序中是一个非常强大模型,我们将在这个例子中使用它。我们将最近邻从 1 更改为 20,并将评分公式从“统一”(每个邻居都具有相同的权重)更改为“距离”(每个邻居都由它与输入向量之间的距离的倒数进行加权)。

由于这个超参数空间非常小,我们可以很容易地使用网格搜索来代替随机搜索。

knn = GridSearchCV(KNeighborsRegressor(),
param_grid =  {
            'n_neighbors':np.arange(1,20,1),
            'weights':['distance','uniform']
            },
          cv=5, 
          iid=False,refit=True,
          scoring="neg_mean_absolute_error")knn.fit(X_train,y_train)

最佳值是:

平均绝对误差为 0.830,这是散点图。

到目前为止,这是产生最低误差的模型。

神经网络

我们将使用单层人工神经网络完成我们的模型搜索,该网络具有 5000 个最大历元、自适应学习速率,并使用随机梯度下降优化算法。

我们的超参数是隐藏层的神经元的数量(我们将从 1 到 50 跨越)和它们的激活函数(T21)的数量(将跨越逻辑和逻辑)。

在将训练数据交给人工神经网络之前,我们必须对它们进行缩放。我们将使用最小最大缩放器将每个特征缩放到0–1 区间

scaler = MinMaxScaler()scaler.fit(X_train)nnet = RandomizedSearchCV(MLPRegressor(max_iter=5000,learning_rate = 'adaptive',solver='sgd'),
param_distributions =  {
     'hidden_layer_sizes':[(x,) for x in np.arange(1,50,1)],
     'activation':['logistic','relu']
},
cv=5, n_iter = 20,
iid=False,random_state=0,refit=True,
scoring="neg_mean_absolute_error")

这些是最好的价值:

平均绝对误差为 1.407,这是散点图。

KNN 是量子交易的圣杯吗?不全是

到目前为止,一切似乎都在告诉我们,KNN 是最强大的模特。事实上,并非如此。

一切都取决于我们如何执行培训/测试分割。如果我们随机分割记录,测试集中的一些记录可能非常接近训练集中的其他记录。这就是为什么 KNN 和树工作得很好。

如果我们把前 70%** 的数据作为训练,把后 30% 的数据作为测试,会怎么样?测试记录现在与训练记录不同,所以事情会发生巨大的变化。**

我们可以通过下面的代码来执行这种分割,它替换了前面的 train_test_split 代码

X = newdata.drop("target",axis=1)
Y = newdata['target']train_size = int(X.shape[0]*0.7)X_train = X[0:train_size]
y_train = Y[0:train_size]X_test = X[train_size:]
y_test = Y[train_size:]

我们现在可以重复每个型号的培训程序。在计算误差之前,让我们看一下散点图。

很明显,KNN 和树现在表现很差。线性回归和神经网络仍然抵制。****

以下是每个模型的平均绝对误差:

  • 线性回归:2.379
  • 随机森林:42.591
  • 梯度推进回归量:42.594
  • k 最近邻:42.885
  • 神经网络:2.366

现在最好的模型是神经网络

发生了什么事?

请记住,我们正在使用经典的机器学习方法来模拟一种现象,这实际上是一个时间序列。记录并非完全互不相关,因此随机训练/测试分割可能是错误的。这就是为什么交易系统通常是以历史数据的第一部分作为训练集,只有最近的数据作为测试集。

此外,KNN 和树只能预测与它们被训练的输出相似的输出。线性回归和神经网络是参数公式,因此一旦参数已经通过训练过程固定,它们可以无限制地预测任何可能的值。

股票价格可以从 0 变到无穷大,这就是为什么我们需要一个数学模型而不是拓扑或几何模型。

提高线性回归的性能

我们都喜欢神经网络,但让我们面对一个简单的事实:在这个例子中,ANN 的表现比线性回归略好。这不是一个戏剧性的性能改进。

我认为当模型是简单的时候,机器学习会更有效。这就是为什么,为了这个目的,我宁愿选择线性回归

有没有办法让提升的性能?当然可以。

还记得随机森林和梯度推进回归器吗?它们的预测能力依赖于装袋助推技术。前者创建多个训练数据集重新采样原始记录并随机选择特征子集,而后者创建一系列模型,从之前的错误中学习

使用 sklearn 的 BaggingRegressorAdaBoostRegressor 模块,这些技术可适用于任何型号。

为了将 Bagging 应用于线性回归,我们将使用下面的代码。它对模型的数量和特征的数量执行超参数优化。

**lr_bag = RandomizedSearchCV(BaggingRegressor(LinearRegression()),
param_distributions =  {
               'n_estimators':np.arange(10,500,5),
               'max_features':np.arange(1,10,1)
          },
          cv=5, n_iter = 20,
          iid=False,random_state=0,refit=True,
          scoring="neg_mean_absolute_error")lr_bag.fit(X_train,y_train)**

最佳值是:

平均绝对误差为 2.343,下面是散点图。

最后,我们可以使用 Boosting 技术优化模型的数量(我们可以使用简单的网格搜索,因为我们只有一个超参数)。

代码如下:

**lr_boost = GridSearchCV(AdaBoostRegressor(LinearRegression()),
param_grid =  {
               'n_estimators':np.arange(20,500,5)
      },
      cv=5, 
      iid=False,refit=True,
      scoring="neg_mean_absolute_error")lr_boost.fit(X_train,y_train)**

最佳值是:

平均绝对误差为 2.580,散点图为:

到目前为止,通过使用 bagging 的线性回归获得了最佳结果。

可能的后续步骤

预测股票价格很难,而且非常困难。应该经常这样做,以便从最近的价格波动中吸取教训,并试图更好地预测未来的

线性回归在 Bagging 技术的帮助下表现最佳,Bagging 技术减少过度拟合并试图减少输入特征之间的共线性

下一步可能是使用递归神经网络,特别是长短期记忆( LSTM )模型。在过去的几年里,它们越来越受欢迎,并证明了它们模拟非线性问题的能力。

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

零售需求预测的机器学习

原文:https://towardsdatascience.com/machine-learning-for-store-demand-forecasting-and-inventory-optimization-part-1-xgboost-vs-9952d8303b48?source=collection_archive---------2-----------------------

零售店需求预测方法的比较研究(XGBoost 模型与滚动平均法)

UnsplashNeONBRAND 拍摄的照片

一、需求计划优化问题陈述

对于大多数零售商来说,需求计划系统采用固定的、基于规则的方法来进行预测和补货订单管理。

(1)需求计划优化问题陈述—(图片由作者提供)

这种方法对于稳定和可预测的产品类别足够有效,但是在库存和补货优化方面会显示出它的局限性。

这种潜在的优化可以通过以下方式降低运营成本:

  • 库存优化:店铺库存与实际需求相匹配,减少所需存储空间(租赁成本)
  • 补货优化:优化每笔订单的补货数量,使仓库与商店之间的补货次数最小(仓储&运输成本)

示例:拥有 50 家店铺的零售商

在这项研究中,我们将从 Kaggle 挑战中获取一个数据集:商店商品需求预测挑战

范围

  • 2013 年 1 月 1 日至 2017 年 12 月 31 日的交易
  • 91.3 万笔销售交易
  • 50 独特的 SKU
  • 10 店铺

💌新文章直接免费放入你的收件箱:时事通讯

(更新)改进模型

我一直致力于该模型的改进版本,并在下面的文章中分享我的见解(带完整代码)。目标是了解添加业务特征(价格变化、销售趋势、商店关闭等)对模型准确性的影响。

[## 零售预测的机器学习-特征工程

供应链优化了解与缺货、商店关闭日期或其他相关的额外功能的影响

www.samirsaci.com](https://www.samirsaci.com/machine-learning-for-retail-sales-forecasting-features-engineering/)

Github 库:链接

二。销售预测 XG boost

最初的数据集已被用于 Kaggle 挑战赛,在该挑战赛中,各团队竞相设计预测销售的最佳模型。

Kaggle 挑战的初始数据框架

这里的第一个目标是使用 XGBoost 设计一个预测模型;该模型将用于优化我们的补货策略,确保库存优化并减少从您的仓库发货的数量。

1.添加日期功能

2.列车的每日、每月平均值

3.将每日和每月平均值添加到测试和滚动平均值中

4.用于检查相关性的热图

皮尔森相关热图—(图片由作者提供)

让我们保留月平均值,因为它与销售额的相关性最高,并删除彼此高度相关的其他特征。

5.清理特征、训练/测试分割和运行模型

6.结果预测模型

预测与实际销售—(图片由作者提供)

基于这一预测模型,我们将构建一个模拟模型来改进商店补货的需求计划。

决赛成绩

数据帧特征

  • 日期:交易日期
  • 货号: SKU 号码
  • 店铺:店铺编号
  • 销售:销售交易的实际值
  • sales_prd: XGBoost 预测
  • 错误 _ 预测:销售 _prd —销售
  • repln: 补货天数的布尔值(如果该天在['星期一','星期三','星期五','星期日']中,则返回 True)

[## 萨米尔 Samir 供应链组合的数据科学

🏭使用高级数学概念的供应链网络优化👨‍🏭仓储的持续改进…

samirsaci.com](http://samirsaci.com)

三。需求计划:XGBoost 与滚动平均值

1。使用滚动平均值的需求计划

预测需求的第一种方法是以前销售的滚动平均值。在第 n-1 天结束时,您需要预测第 n 天、第 n+1 天、第 n+2 天的需求。

  1. 计算最近 p 天的平均销售量:滚动平均(第 n-1 天,…,第 n-p 天)
  2. 将此平均值应用于第 n 天、第 n+1 天、第 n+2 天的销售预测
  3. 预测需求=预测日 n +预测日(n+1) +预测日(n+2)

使用滚动平均法的需求预测—(图片由作者提供)

2。XGBoost 与滚动平均值

有了 XGBoost 模型,我们现在有两种滚动平均法需求计划方法。

让我们试着比较这两种方法在预测准确性方面的结果:

  1. 准备第 n-1 天补货
    我们需要预测第 n 天、第 n +1 天、第 n+2 天的补货量
  2. XGB 预测给我们一个需求预测
    Demand _ XGB = Forecast _ Day(n)+Forecast _ Day(n+1)+Forecast _ Day(n+2)
  3. 滚动平均法给我们一个需求预测
    Demand _ RM = 3 x Rolling _ Mean(Day(n-1),Day(n-2),..日(n-p))
  4. 实际需求
    需求 _ 实际=实际 _ 日(n) +实际 _ 日(n+1) +实际 _ 日(n+2)
  5. 预测误差Error _ RM =(Demand _ RM—Demand _ Actual)
    Error _ XGB =(Demand _ XGB—Demand _ Actual)

使用 XGBoost 和滚动平均的方法—(图片由作者提供)

a .参数整定:p 天滚动平均值

在将滚动平均值结果与 XGBoost 进行比较之前;让我们尝试找出 p 的最佳值,以获得最佳性能。

滚动平均值的最小误差—(图片由作者提供)

结果:-(p = 8)与(p = 1)的预测误差为 35%

因此,基于销售事务配置文件,我们可以通过使用过去 8 天的平均值来预测第二天的销售额,从而获得最佳的需求计划绩效。

b. XGBoost 对滚动平均值:p = 8 天

误差 XGBoost 与滚动平均值的关系—(图片由作者提供)

结果: -使用 XGBoost 与滚动平均值的预测误差为 32%

预测误差(x 轴:商店编号,y 轴:商品编号,z 轴:误差)——(图片由作者提供)

四。结论和下一步措施

关注我的 medium,了解更多与供应链数据科学相关的见解。

1.结论

利用滚动平均法进行需求预测,可以将预测误差降低 35% ,并找到最佳参数 p 天

然而,我们可以通过用 XGBoost 预测代替滚动平均值来预测第 n 天、第 n+1 天和第 n+2 天的需求,从而将误差降低 32%,从而获得更好的性能。

库存管理流程

2.可持续方法:绿色库存管理

(图片由作者提供)

如果我们降低商场补货的频率,会对二氧化碳排放量产生什么影响?

在这种情况下,研究如何使用数据分析来模拟商店补货频率的变化,并衡量对整体环境影响的影响。

[## 绿色库存管理-案例研究

可持续发展如何减少时尚零售物流运作的二氧化碳排放量?

www.samirsaci.com](https://www.samirsaci.com/green-inventory-management-case-study/)

关于我

让我们在 LinkedinTwitter 上连线,我是一名供应链工程师使用数据分析来改善物流运作和降低成本。

如果你对数据分析和供应链感兴趣,可以看看我的网站

[## Samir Saci |数据科学与生产力

专注于数据科学、个人生产力、自动化、运筹学和可持续发展的技术博客

samirsaci.com](https://samirsaci.com)

参考

[1] Kaggle 数据集,商店商品需求预测挑战,链接

商店配送计划的机器学习

原文:https://towardsdatascience.com/machine-learning-for-store-demand-forecasting-and-inventory-optimization-part-2-replenishment-6ded544be81b?source=collection_archive---------18-----------------------

设计补货策略,优化库存,减少从仓库发货的次数

Wynand van Poortvliet 在 Unsplash 上拍摄的照片

本文是商店需求预测系列文章的一部分。您可以在以下链接中找到第一篇文章,其中解释了 XGBoost 模型的实现:Article 1

💌新文章直接免费放入你的收件箱:时事通讯

一、补货策略和顺序

1。需求计划&交付计划

数据集:销售交易—(来源:Kaggle)

范围

  • 2013 年 1 月 1 日至 2017 年 12 月 31 日的交易
  • 91.3 万笔销售交易
  • 50 独特的 SKU
  • 10 店铺
  • 每周补货天数:周一、周三、周五、周日
  • 24 订单创建和从仓库发货之间的提前期
  • 商店营业时间从上午 10:00下午 08:00
  • 晚上 09:00 从仓库发货

补充序列—(图片由作者提供)

根据我们的交付周期要求,商店必须在关门前一天创建补货订单。

我们的补货算法将测量库存水平

  • 上午 10:00:开业前
  • 下午 08:00:店铺关门后,发货前(如果是补货日)

商店开业前上午 10:00 记录的库存水平—(图片由作者提供)

目标:库存日 n+1(上午 10:00)= alpha x 产能(alpha in [0,1])

  1. 第 n-1 天:准备补货
    数据输入:库存第 n-1 天(晚上 09:00),销售预测第 n 天,第 n+1 天,第 n +2 天
  2. 目标:第 n+ 2 天的库存(08:00 pm) 在下一次交货前确定库存水平: (09:00 pm) 第 n+2 天
  3. 需求计划 Day_n 补货需要覆盖 Day_n、Day_n+1、Day_n+2 的需求,以达到下一次发货前 Day_n+2 结束时的库存水平目标。
  4. 约束 交货后库存必须低于最大产能

需求计划方程式—(图片由作者提供)

约束方程—(图片由作者提供)

2。不同战略模拟的 KPI 设置

库存短缺事件 我们的补货策略将根据其能力进行评估,以准确估计达到库存目标第 n+2 天的补货数量。这一估计可能被低估:

例子

库存短缺事件示例—(图片由作者提供)

  1. 第 n-1 天:准备补货订单
    -仓库开始准备订单
  2. 第 n 天:当天结束时收到的发货 -日常交易减少的库存
    -当天结束时收到的订单
  3. 第 n+1 天:库存短缺 -从第 n 天继承的库存水平不足以满足第 n+2 天的需求,直到装运在当天结束时到达。

按日平均库存水平(%),
100×存储数量(件)/存储最大容量(件)

库存优化:在不发生库存短缺事件的情况下,达到可能的最低值

减少补货频率 利用销售预测,补货策略可以减少补货次数。

减少补给频率的示例—(图片由作者提供)

上例显示了一个跳过补货日的例子;第 n 天的库存高于最低库存,足以满足第 n+1 天的需求。

备注:该 KPI 高度依赖库存水平(%);在低库存水平下,很难跳过补货而不冒缺货事件的风险。

[## 萨米尔·萨奇

数据科学博客,专注于仓储,运输,数据可视化和机器人流程自动化…

samirsaci.com](http://samirsaci.com)

二。补货方式 1:满储能力

我们首先从一个简单的补货策略开始,补货订单数量的计算基于:

  • 第 n-1 天:第 n-1 天补货订单
    输入数据:库存 _ 第 n-1 天(09:00 pm)、产能(物料)
  • 订单数量达到最大产能

补给公式—(图片由作者提供)

  1. 初始数据:创建销售数据框架、库存记录、物料产能和补货数据

注意

  • 最大存储容量= 10 x 最大日销售量(以后可以调整)
  • 补充天数:“星期一”、“星期三”、“星期五”、“星期日”

2。方法 1: 需求=产能 _ 最大值-库存 _ 天数 _n-1 (09:00 pm)

3。按天运行模拟:销售交易,库存补货,库存≥0

模拟结果

  • 产能= 10 x 最大日销售额
  • 补充天数:“星期一”、“星期三”、“星期五”、“星期日”

存储利用率(%) =库存数量/容量最大值—(图片由作者提供)

平均补货数量(件/行)——(图片由作者提供)

库存短缺事件:0
跳过的补货次数:0

四。结论和下一步措施

关注我的 medium,了解更多与供应链数据科学相关的见解。

1.结论

方法 1 很简单,可以优化。正如预期的那样,我们的平均存储利用率接近 100%,没有补货天数。

平均补货量图表也向我们展示了销售交易趋势是周期性的,并且遵循一个趋势。

2.后续步骤

  • 库存水平:以最低库存水平为目标,确保不发生库存短缺事件
  • 订单频率:使用我们的预测模型减少补货

关于我

让我们在 LinkedinTwitter 上连线,我是一名供应链工程师,正在使用数据分析来改善物流运营和降低成本。

如果你对数据分析和供应链感兴趣,可以看看我的网站

[## Samir Saci |数据科学与生产力

专注于数据科学、个人生产力、自动化、运筹学和可持续发展的技术博客

samirsaci.com](https://samirsaci.com)

参考

[1]商店项目需求预测挑战(Kaggle),链接

[2] Samir Saci ,零售需求预测的机器学习(2020),链接

基于 creme 的流数据机器学习

原文:https://towardsdatascience.com/machine-learning-for-streaming-data-with-creme-dacf5fb469df?source=collection_archive---------7-----------------------

在线机器学习可以改变你对生产中的数据科学的看法

若昂·布兰科在 Unsplash 上的照片

动机

将机器学习模型部署到生产环境中是一项艰巨的任务。目前,通常的做法是有一个离线阶段,在这个阶段,模型是在数据集上训练的。该模型随后被部署到网上,对新数据进行预测。因此,模型被视为静态对象。为了从新数据中学习,必须从头开始重新训练模型。这种部署模式有时被称为λ架构

lambda 架构的模型生命周期,来源:在线机器学习的好处

lambda 架构无处不在,在整个行业都是如此。事实上,AutoML 平台如 DataRobotH2O 正是这么做的。你给他们数据,他们给你提供一个 API,在这个 API 后面有一个模型。自动化程度较低的工具也是如此,比如 MLflow 、Amazon Sagemaker、 CubonacciAlteryx 。这也是不太知名的项目如 CortexClipper 所采用的方法。我不是在敲打这些工具;事实上,我觉得它们都很棒,它们为彼此提供了健康的竞争。

机器学习模型以这种方式部署,因为它们受到模型学习能力的限制。事实上,机器学习算法通常假设所有的训练数据都是一次性可用的。这在文献中被称为批量学习。从历史上看,统计学家和 ML 研究人员最感兴趣的是将模型“拟合”到数据集,然后就不管它了。只有一小部分研究致力于设计能够在有新数据时自我更新的模型。

拥有能够增量学习的模型不是很好吗?想一想:拿一个在大学天天上课的学生来说。当一节课开始时,学生已经积累了过去所有课的知识。老师并不是每次想让他的学生学习新思想时都从第一堂课开始。那太疯狂了,对吧?这正是许多机器学习实践者正在做的事情。

原来,批量学习还有一个不太为人知的妹妹,叫在线学习。正如你可能已经猜到的,在线学习包含了所有能够一次进行一次观察的模型。在线学习是一种范式转变,因为它允许改变我们思考机器学习部署的方式。除了对新数据进行预测,在线模型还能够从中学习。事实上,在线学习的预测和学习阶段可以交织成有时被称为 kappa 架构的东西。

kappa 架构的模型生命周期,来源:在线机器学习的好处

在 kappa 架构中,数据被视为一个流。一旦一个模型被一个新的数据更新,那么这个数据就可以被有效地丢弃。换句话说,你不必存储一个历史训练集,并不时地重新训练你的模型。另一个好处是你的模型总是最新的。自然的结果是你的模型能够处理 概念漂移 ,当数据的分布随着时间的推移而演变时就会发生这种情况。此外,模型生命周期更容易考虑,因为学习和预测步骤都是一次处理一个输入。与此同时,批处理模型必须尽可能频繁地重新训练,以应对概念漂移。这需要持续监控,并使维护更加困难。通过批量学习,您还必须确保您用于训练模型的功能在生产中也是可访问的。

批处理机器学习很棒,在很多情况下都很好用。然而,在线机器学习对于某些用例来说是更合适的解决方案。它只对新数据不断到来的应用有意义:垃圾邮件过滤、推荐系统、物联网传感器、金融交易等。正如我们刚刚提到的,当数据中的模式不断发展并需要模型适应时,在线模型尤其出色。根据我的经验,许多实践者试图把方钉装进圆孔:批处理机器学习不适合在流环境中使用。我看到批量模型在生产中直线下降,因为它们不能从新数据中学习。

使用在线机器学习模型还可以降低运营成本,无论是在计算能力还是人工干预方面。首先,您不需要强大的硬件来处理流数据集,因为一次只有一个流元素存在于内存中。事实上,在线机器学习可以有效地部署在树莓派上。其次,您的数据科学家可以花更少的时间来处理模型再训练,因为模型更新被纳入在线机器学习,因此可以花更多的时间在具有更多附加值的任务上。

那么,为什么我们不都使用在线机器学习呢?嗯,我们有些人是。大玩家——你知道我指的是谁——正在使用在线模型进行广告点击率预测以及新闻推送推荐。在线机器学习并不是主流观念。罪犯很容易找到。 Kaggle 竞赛将数据科学呈现为一项科学实验,其中数据被分成训练集和测试集。大学课程和 MOOCs 教给学生最流行的机器学习算法,大多是批处理算法。最后,像 scikit-learn 这样的流行库鼓励用户从保存在内存中的矩形数据集的角度来思考,而不是从流数据的角度。

在我看来,人们不使用在线机器学习的主要原因仅仅是因为没有很多可用的工具来这样做。有很好的工具来分析流数据,如 SamzaFlink,但它们不允许进行任何严肃的机器学习。还有从大数据集学习的工具,比如 SparkVowpal WabbitDaskVaex 。然而,这些工具并没有完全接受在线范式,并且大多数仍然假设您正在使用静态数据集,尽管它并不适合内存。

介绍 creme 图书馆

大约 15 个月前,我发现了在线机器学习。从那时起,这是一个启示,我一直在努力分享我的观点。为此,我开始编写一个名为 creme 的 Python 库。名字来源于增量学习,是在线学习的代名词。接下来,我的一些朋友加入了我的行列: Geoffrey Bolmier (他目前正在为 scikit-learn 工作)raphal SourtyRobin VaysseAdil Zouitine 。我们最近发布了 0.5 版本,并开始看到它被一些公司用于概念验证。

creme 是一个通用库,因此涵盖了机器学习的许多领域,包括特征提取和模型选择。你可以把 creme 想象成在线机器学习的 scikit-learn(科学知识)——我们意识到这听起来有多么雄心勃勃。

作为一个非常简单的介绍性示例,假设您想要计算一个值序列的平均值。自然的方法是累加所有的值,然后将总数除以值的个数。然而,有一种在线算法是精确的,甚至不需要在开始之前知道值的数量。它被称为韦斯特算法,实现起来很简单。在线平均值可以在 creme 中计算如下:

creme 中的运行平均值

计算移动平均值可能看起来没什么了不起,但它为更高级的技术打开了大门,如目标编码:

creme 中的目标编码

您会注意到在前面的代码片段中,TargetAgg有两个方法:fit_one,它更新模型,和transform_one,它将输入转换成特性。在这种情况下,TargetAgg有一个transform_one方法,因为它是一个转换器(咄)。其他估算器,比如linear_model.LinearRegression,有方法fit_onepredict_one。分类器,比如tree.DecisionTreeClassifier,也有一个predict_proba_one 方法。

关于 creme 要知道的另一件事是特性存储在字典中。字典是实用的,因为它们是隐含稀疏的:0 值根本不包含在字典中。这允许扩展到具有数百万个要素的大型数据集。此外,字典没有固定的长度,这意味着即使您添加或删除功能,creme 模型也会起作用。最后,使用字典意味着每个功能都有一个名称,这是一种人性化的设计。注意,我们不使用 numpy 或 pandas,尽管 creme 支持这两种格式。相反,我们主要依赖 Python 的标准库,它为使用字典提供了强大的原生支持。正如我们将在后面看到的,这不会影响性能,事实上恰恰相反。

现在是严肃的事情:让我们在数据流上训练一个分类器。例如,我们将使用网站钓鱼数据集,该数据集描述网页并指示它们是否是钓鱼企图。我们将使用来自linear_model模块的逻辑回归。我们将通过使用metrics.Accuracy的一个实例来度量模型的性能,正如您已经猜到的,它可以在线更新。

学习网站钓鱼数据集

正如您在上面的代码片段中看到的,预测和学习步骤是交错进行的。在这种情况下,我们按顺序对数据集进行流式处理,但是您可以完全控制如何设置。通过使用在线机器学习,特别是 creme,你不再受到你需要所有数据来训练一个模型的阻碍。另一件需要注意的事情是,我们已经使用了一个管道,通过逻辑回归构建了一个标准的缩放步骤。管道是 creme 的一等公民,我们强烈鼓励使用它们。您可以查看我们的用户指南以获取更多示例。在 creme 中,管道有方便的方法,如model.draw():

网站钓鱼渠道的图形表示

请注意,并不是所有的算法都有在线的等效算法。例如,核支持向量机不可能适合流数据集。同样,CART 和 ID3 决策树也不能在线训练。然而,还有一些鲜为人知的在线近似方法,例如用于支持向量机的随机傅立叶特征和用于决策树的 Hoeffding 树。creme 提供了许多东西,我们强烈建议您查看它的 GitHub 页面在线文档。以下是一些亮点:

  • reco模块包含推荐系统的算法,很像惊喜,但在线。
  • 时间序列预测,用time_series模块。
  • 您可以通过model_selection模块中的SuccessiveHalvingRegressorSuccessiveHalvingClassifier进行在线选型。我们也有整合多臂强盗算法的计划。
  • 在线不平衡学习。
  • 渐进式验证,是交叉验证的在线对应物。
  • 决策树和随机森林。
  • 带有大量优化器的线性模型。

对在线学习的主要批评是它比批量学习慢。事实上,因为数据是一次处理一个元素,所以我们不能充分利用矢量化。一种解决方案是小批量,这是在线学习和批量学习的有效折衷。然而,对于 creme,我们决定一次只处理一个元素,因为它更容易推理,并且极大地简化了模型部署。由于这种设计选择,在在线学习场景中,creme 实际上比 scikit-learn、Keras 和 Tensorflow 要快得多。下表总结了在不同库中实现的线性回归的结果:

在线线性回归基准

你可以在这里找到运行基准测试的代码。这并不意味着 creme 可以比其他库更快地处理数据集,这意味着当一次处理一个元素的数据时,creme 会更快。其他库迎合批量学习场景,而不是在线学习。根据您的数据科学经验,这可能看起来像一个利基案例。然而,与批量学习相比,以这种方式处理数据使得模型部署和维护变得轻而易举。

部署

一旦你设计了一个在线机器学习模型,部署它就相对简单了。假设您希望通过 web 请求与您的模型进行交互,那么您必须实现的 API 非常简单。本质上,您需要一条路线来更新模型,另一条路线来进行预测。您可能还想实现一些路由来监控模型的性能。真的是这样:您不需要考虑模型再培训,也不需要担心您的模型不够最新。这就是 lambda 架构的美妙之处。将数据视为一个流会给表带来很多好处。最重要的是,creme 是一个很好的选择,因为它使用字典,很容易在 JSON 之间进行翻译,JSON 是 API 的通用语

为了演示部署用 creme 构建的模型有多简单,我们实现了一个名为 chantilly 的小工具。这个工具只不过是一个 Flask 应用程序,它提供了上传模型、让模型学习、获得预测和监控指标的必要途径。它还提供了一个当前非常简单的实时仪表板。尚蒂伊仍处于起步阶段,我们有计划让它变得更加有趣和简单易用。

chantilly 存储库包含一个基于纽约市出租车数据集的示例。数据集包含出租车行程的详细信息及其持续时间。目标是预测旅行需要多长时间。简而言之,我们能够利用这个历史数据集,以与事件发生时完全相同的方式模拟一系列事件。因此,我们能够建立一个值得信赖的基准和一个可靠的想法,我们的模型将执行。这非常重要:能够正确地重现生产场景有助于建立对模型的信任。对于批量模型,你永远无法确定你的模型会有怎样的表现。当然,你可以做交叉验证,但这并不能完全模拟本地的生产场景。

请注意,我们并不打算让 chantilly 成为一个通用的工具。我们认识到,每个数据科学团队都有自己特定的模型部署方式。因此,chantilly 主要旨在成为一个简单易读的例子,说明如何为机器学习模型实现 lamda 架构。尽管如此,我们将继续在尚蒂伊开展工作,并提供与现有基础设施合作的方式。例如,chantilly 目前提供了一个流 API 来监控指标更新。这允许您编写一个简短的脚本,将这些更新发送到连接到 Grafana 仪表板的 InfluxDB 数据库。

更进一步

creme 是一个年轻的库,但我们已经从数据科学团队那里得到了一些很好的反馈,他们正在使用它来证明概念。以下是关键要点:

  • 在线模型可以一次学习一个实例。
  • 在线模型不需要重新培训,因为他们是在飞行中学习的。
  • 在线机器学习简化了模型部署和维护。

如果你想了解更多关于 creme 的信息,我们鼓励你查看 GitHub 库以及用户指南API 参考。让我们在 GitHub 上出演也有助于我们接触到更多的观众。

我们对新员工的入职非常感兴趣。如果你的兴趣已经达到顶峰,你想成为团队的一员,那么欢迎联系我们!

我们也很高兴(自由地)与数据科学团队携手合作,看看 creme 是否符合您的需求,以及我们可以在哪些方面改进它。

机器学习基础:特征和相似性

原文:https://towardsdatascience.com/machine-learning-foundations-features-and-similarity-a6ef2901f09f?source=collection_archive---------17-----------------------

机器学习背后的一些基础的实用解释

照片由维姆·范因德Unsplash 拍摄

机器学习的世界充满了对“特征向量”、“维度”、“空间”和“距离”的引用。除非你已经有了很强的数学背景,否则所有这些都是无法抗拒的。在这篇文章中,我将解释一些基本知识。

特征

为了让程序执行机器学习任务,我们需要一种用数字表示对象的方法。例如,如果我们想让我们的软件识别声音,我们需要一种用数字来表示声音的方法。识别图像或文本也是如此。

我们在机器学习中用来表示物体方面的数字叫做特征

在计算中,我们已经有了对象的标准数字表示。例如,图像由描述屏幕上每个像素颜色的 RGB 值组成。声音由 PCM 音频样本组成,描述音频信号随时间的响度。

虽然我们可以使用这些数字表示来训练机器学习系统,但通常不希望这样做。原因是:

  • 处理大量数据(例如,每幅图像数百万像素)在计算上非常昂贵
  • 标准数字表示包含大量冗余信息

为了解决这个问题,我们采用了一个过程,将这些细粒度的值转换成更少数量的更具描述性的特征。这个过程被称为特征提取。可以认为特征存在于从更接近机器表示(不太抽象)的低级特征到更接近人类感知(更抽象)的高级特征的层次结构中。

用于表示声音的常见特征可能是:音调、响度、亮度和噪声。更高级的特征可以是速度、音调和情绪。用于表示文本的特征可以是“单词存在”、“单词计数”和“词频”。

图一。从原始数据到特征值的特征工程。信用:谷歌开发者

在传统的机器学习中,用于描述对象的特征通常是通过结合先验知识、直觉、测试和自动特征选择来获得的。这个过程叫做特征工程。在最近的深度学习技术中,特征提取本身可以是机器学习过程的自动部分。

确定哪些特征最好地描述了特征之间重叠最少的对象的过程被称为特征选择

尺寸和空间

我们现在知道特征是表示对象的某个方面的值。为了在不同物体的特征之间进行比较,从空间上考虑它们是方便的。我们可以将每个特征标签视为一个维度,将每个特征视为该维度内的一个位置。我们用来描述一个物体的所有维度的组合称为一个特征空间

起初,这一切看起来令人困惑!这是因为我们倾向于认为“空间”是一个以米或英尺为单位的三维实体。然而,可以应用于 3D 物理空间的所有相同的几何也可以应用于具有任意维数的数学空间,其中每个维数代表任意数值范围。

让我们考虑一个实际的例子…

假设我们有一个描述声音的特征…“平均响度”,它的值是-6 分贝。这给了我们一个维度和一个特征值(-6)。我们可以在一条线上从空间上表示这一特征:

图二。一维空间表示的平均响度特征

现在,让我们再添加两个特性,“平均频率”(单位为赫兹)和持续时间(单位为秒)。这给了我们的特征空间总共三个维度。我们现在可以将声音表示为三维空间中点:

图 3。用三维空间中的一个点表示的声音,维度为赫兹、秒和分贝

但不止于此!与物理空间不同,特征空间可以有任意多个维度。因此,如果我们加上“平均亮度”、“平均噪音”和“攻击时间”,这将总共给出六个维度。

特征向量

描述对象的一组特征被称为特征向量。起初,这似乎是一个令人困惑的概念。我们从学校数学中知道,矢量是有方向和大小的东西。向量的典型例子是“位移”和“速度”。我们可能熟悉这样的图表:

图 4。从 A 点到 B 点的位移矢量 a

这显示了向量 a (红线)作为二维中从点 A 到点 B 的位移。矢量的大小范数可以使用以下等式计算:

‖a‖₂ = √((x₂-x₁)² + (y₂-y₁)²)

a 是表示 a,大小的数学符号,上面的公式称为欧几里德范数或 L2 范数。代入我们得到的积分值:

√((3--4)² + (9-3)²) = √(7² + 6²) = 9.2

所以我们的向量 a 的大小是 9.2,但是这和我们机器学习的特征向量有什么关系呢?我们图 3 中的声音(A)只是 3D 空间中的一个“点”,对吧,不是“矢量”?

实际上,我们可以将图 3 中的声音视为一个矢量,将它的位置与原点相关联(坐标 x=0,y=0,z= 0)。从原点延伸到给定点的矢量称为位置矢量。当人们谈论机器学习中的“向量”时,他们通常指的是位置向量。

重新绘制图 3 以显示声音 A 的位置向量,我们得到以下结果,其中红色箭头是向量:

图 5。指示位置向量的声音 A 的特征向量(红色箭头)

为了计算我们的特征向量的长度,我们可以再次使用 L2 范数。所以:

‖a‖₂ = √((0--6)² + (440-0)² + (3.4-0)²)

你可以看到,对于一个位置向量,原点总是零,所以原点项可以省略。因此,我们对于特征“点”向量的 L2 范数的概括公式变成:

‖a‖₂ = √(x₁² + ··· + xᵢ²)

其中 x₁是我们特征向量中的第一个元素,xᵢ是第 I 个元素。插入声音 A 的值,这就变成了

‖a‖₂ = √((-6)² + 440² + 3.4²) = 440.05

因此,声音 A 的三维特征向量的长度为 440.05。

缩放和标准化

你会注意到,到目前为止显示的声音 A 的特征空间没有按比例绘制。如果有,它看起来会更像这样:

图 6。“按比例”特征空间近似

因此,我们的特征向量的大小或长度由一个单一的特征决定:频率(Hz)。因此我们的星等是 440.05,非常接近我们的频率值。我们实际上可以将声音的持续时间增加一倍到 6.8 秒,而这只会将我们的特征向量的长度增加 0.04。这是坏事!

数据范围的这种可变性会给许多机器学习算法带来问题,因为一些特征会被视为比其他特征更重要。因此,通常在将特征向量提交给机器学习系统之前应用特征缩放。这可确保输入数据的结构不会“偏向”范围较大的某些要素。

一种广泛使用的缩放方法是 标准化 (或 Z 分数标准化)。大多数机器学习库都有一个用于标准化的内置函数,但是在纯 python 中,例如,它可能看起来如下:

def standardise(v):
    mean = sum(v)/len(v)
    std_dev = math.sqrt((1/len(v) * sum([ (x_i - mean)**2 for x_i in v])))
    return [(x_i - mean)/std_dev for x_i in v]

因此,假设我们有 5 个声音,每个声音的特征向量如下:

图 7。5 种声音的示例特征向量。

如果我们将这些值标准化,就会得到以下结果:

图 8。5 种声音的标准化特征向量

请注意,每个功能的范围现在都大大缩小了,彼此大致相当。这使得数据更适合机器学习应用,在我们的情况下,消除了对“平均频率”特征的偏见。

注意,如果数据需要在特定范围内(例如 0..1)然后应该使用最小-最大缩放比例

距离和相似性

机器学习中最普遍的工具之一是测量两个对象之间“距离”的能力。这使我们能够衡量这些物体有多相似。距离可以被认为是相似性的倒数,随着物体之间距离的增加,相似性降低。

相似性用于推荐系统、分类器、聚类算法和其他机器学习技术。对相似性和距离度量的坚实理解是正确理解机器学习的基础。

我们现在知道,我们可以将一组特征视为 n 维空间中的一个向量。我们还知道,我们可以归一化我们的特征,以便在该空间内特征值之间进行有意义的比较。测量不同特征向量之间的距离则更进一步。

让我们将两个声音(A 和 D)的标准化特征向量添加到我们的 3D 图形中。

图 9。声音 A 和声音 D 的归一化 3D 特征向量

我们可以看到,每个声音的标准化特征被绘制为 3D 空间中的一个点。

为了衡量声音有多相似,我们需要计算连接两点(声音 A,声音 B)的向量的长度。如下所示。

图 10。声音 A 和声音 D 的点之间的矢量 AD (红线)

从前面我们知道,要计算向量的长度,我们可以使用 L2 范数。所以为了计算声音 A 和声音 D 之间的距离,我们需要计算矢量 AD 的 L2 范数。回顾上面的 L2-诺姆公式,我们得到:

‖*AD*‖₂ = √((x₂-x₁)² + (y₂-y₁)² + (z₂-z₁)²)

其中xyz是图的维度,x₂和 x₁分别是声音 d 和声音 a 的 x 坐标。

代入这两个声音的归一化坐标,得到:

‖*AD*‖₂ = √((1.35--1.65)² + (-0.53--0.81)² + (1.85--0.65)²) = 3.91

现在我们有了一组代表 5 个物体(在我们的例子中是声音)的标准化特征向量和一个计算两个物体之间距离的方法。这使我们能够根据与源对象的相似性对我们的对象进行分组!因此,根据上面的表格,我们可以计算出所有其他声音的相似度,然后根据相似度排序。这给出了:

图 10。声音 A 到 E 的特征向量按与 A 的距离排序

这为一系列技术提供了基础,如聚类和 k-NN 分类,鼓励读者进一步探索。

在这个例子中,为了便于可视化,我们只使用了三个特性。然而,一个典型的应用程序会包含更多的特性,通常在 20 到几百个之间。在这种情况下,两个(非原点)点之间的 l2 范数(或欧几里德距离)可以概括为:

*d*(p, q) = √((*q*₁-*p*₁)² + ··· + (qᵢ-pᵢ)²)

其中,qᵢ是点 q 的第 I 维的值,pᵢ是点 p 的第 I 维的值

有许多其他方法来计算两个特征向量之间的相似性,例如余弦相似性,其测量方向上的差异而不是距离。这些将在以后的文章中讨论。

最终注释

在这篇文章中,我介绍了特征特征向量、特征归一化和测量特征向量之间的距离的概念。这已经通过使用声音的标称特征(响度、频率、持续时间)的工作示例来完成。需要记住的重要一点是,这些“声音特征”仅用于说明目的。在现实世界的场景中,这些可能不是有用的特性,具体取决于比较或测量的是什么。

特征选择是机器学习和数据科学“艺术”的一部分。下一步,鼓励读者探索一系列的真实世界数据集,并尝试应用本文中的概念来探索数据。

机器学习和数据科学隔离免费在线课程

原文:https://towardsdatascience.com/machine-learning-free-online-courses-from-beginner-to-advanced-f50982dce950?source=collection_archive---------9-----------------------

来源:西蒙·艾布拉姆斯@ Unsplash-免费库存图片

从初级到高级。充分利用 covid 19-锁定

上周,我发表了一篇文章,推荐 4 门免费数学课程,用于隔离和提升你的数据科学技能。反应是惊人的,我真诚地希望你们中的许多人已经喜欢上了这些课程的内容。尽管如此,一些人对这个故事做出了回应,并在上面留下了私人笔记,专门询问机器学习课程。

这就是为什么在我发表了这篇文章后,我在上面添加了一个投票,以准确衡量你对几个主题的兴趣,并帮助我对进一步的内容进行优先排序。令人惊讶的是,超过 1100 人回答了问题,53%的人询问了入门或高级机器学习课程。

来源:对前一篇文章中作者投票的回复

这就是为什么今天我发布了一套新的课程,只专注于机器学习,并将其分为 3 个级别:初级、中级和高级。然而,请继续关注,因为在未来的故事中,我将发布关于数据可视化的独家内容。

重要提示:几个人写信给我回应我上周的故事,说 Coursera 只提供一周的免费服务。即使这是真的,正如我在故事中的“提示”中提到的,Coursera 的大多数课程和专业都有审核它们的选项。你不会获得证书,但你可以使用课程的大部分资源。我个人觉得这已经足够了。注册时,只需选择审核课程的选项。Coursera 将为您提供免费试用,但就在“开始免费试用”按钮后面,您应该会发现一个小文本,上面写着“审核课程”。这很棘手,但我已经仔细检查了我推荐的所有课程,所以它们都应该是免费的:)

A.初级课程

1。 机器学习

地点:Coursera

参与机构:斯坦福

所需时间:54 小时

先决条件:它不需要任何东西,但我认为对微积分,尤其是线性代数的一些理解将有助于充分利用这门课程。

点评:这门课的授课老师吴恩达,是机器学习和人工智能领域的传奇人物。他是斯坦福大学的教授,Coursera 的创始人之一,开发了机器学习的首批在线课程之一,该课程仍可在 YouTube 上观看。

课程本身的摘要:

本课程提供了机器学习、数据挖掘和统计模式识别的广泛介绍。主题包括:(一)监督学习(参数/非参数算法,支持向量机,核,神经网络)。㈡无监督学习(聚类、降维、推荐系统、深度学习)。㈢机器学习的最佳做法(偏差/差异理论;机器学习和 AI 中的创新过程)。

涵盖的主题:

  • 线性回归
  • 逻辑回归
  • 正规化
  • 神经网络
  • 支持向量机
  • 无监督学习
  • 降维
  • 异常检测
  • 推荐系统

2。 机器学习用 Python

地点:Coursera

参与机构:IBM

所需时间:22 小时

先前要求:与先前课程相同,即基础数学。

评论:尽管课程说的是“中级水平”,但我个人认为这对该领域的新人来说是一个很好的起点。如果你正在寻找比斯坦福大学以前的课程更短的课程,这也是一个很好的选择,因为这需要不到一半的时间。

课程本身的摘要:

本课程使用一种平易近人且广为人知的编程语言 Python 深入研究机器学习的基础知识。在本课程中,我们将回顾两个主要部分:首先,您将了解机器学习的目的以及它在现实世界中的应用。第二,你将对机器学习的主题有一个总体的了解,比如监督与非监督学习、模型评估和机器学习算法。

涵盖的主题:

  • 回归
  • 分类
  • 使聚集
  • 推荐系统

B.中级课程

3。 神经网络和深度学习

地点:Coursera

涉及机构:deeplearning.ai

所需时间:30 小时

先决条件:需要 Python 编码和高中数学水平的经验。先前的机器学习或深度学习知识是有帮助的。

评论:在我看来,一旦你掌握了 ML 的基本概念,并且熟悉了 Python,下一步可能是熟悉 TensorFlow,因为现在很多计算量很大的算法都是用它运行的。还有,快速的事实,吴恩达也是 deeplearning.ai 的幕后推手,因此也是这门课程的幕后推手。

课程本身的摘要:

在本课程中,您将学习深度学习的基础。学完本课后,您将:

-了解驱动深度学习的主要技术趋势
-能够构建、训练和应用完全连接的深度神经网络
-知道如何实现高效(矢量化)的神经网络
-了解神经网络架构中的关键参数

这门课程还教你深度学习实际上是如何工作的,而不是仅仅给出一个粗略的或表面的描述

涵盖的主题:

  • 深度学习简介
  • 神经网络基础
  • 浅层神经网络
  • 深度神经网络

4。 卷积神经网络

地点:Coursera

涉及机构:deeplearning.ai

所需时间:20 小时

前期要求:需要一些 TensorFlow 知识,Python 编码,高中水平的数学。

评论:继上一个课程之后的理想课程。

课程本身的摘要:

本课程将教你如何建立卷积神经网络,并将其应用于图像数据。由于深度学习,计算机视觉比两年前工作得更好,这使得许多令人兴奋的应用成为可能,从安全的自动驾驶到准确的人脸识别,再到放射图像的自动读取。

涵盖的主题:

  • 卷积神经网络的基础
  • 深度卷积模型:案例研究
  • 目标检测
  • 特殊应用:人脸识别和神经类型转移

C .高级课程

5。 高级机器学习专业化

地点:Coursera

参与机构:国立研究大学高等经济学院(俄罗斯)

所需时间:10 个月,每周 6 小时

先决条件:为已经在这个行业中的人设计,在机器学习和数学方面有坚实的基础。

评论:这是一个完整的专业,所以从技术上来说,如果你觉得你不需要它,或者你已经在工作中或以前的课程中涉及到这些主题,你可以跳过其中的任何课程。

课程本身的摘要:

深入探究现代人工智能技术。你将教计算机看、画、读、说、玩游戏和解决工业问题。这个专业介绍了深度学习,强化学习,自然语言理解,计算机视觉和贝叶斯方法。顶级 Kaggle 机器学习实践者和 CERN 科学家将分享他们解决现实世界问题的经验,并帮助您填补理论和实践之间的差距。

涵盖的主题:

  • 深度学习简介(32hs)
  • 如何赢得数据科学竞赛:向顶级 Kagglers 学习(47hs)
  • 机器学习的贝叶斯方法(30hs)
  • 实用强化学习(30 小时)
  • 计算机视觉中的深度学习(17hs)
  • 自然语言处理(32 小时)
  • 通过机器学习应对大型强子对撞机的挑战(24 小时)

再说一遍,这就是现在所有的窥视。

别忘了看看我的其他一些故事:

访问我在 Medium 上的个人资料,查看我的其他故事。还有如果你想直接在你的邮箱里收到我的最新文章,只需 订阅我的简讯 😃

最后,我很想听听你接下来想读什么!以下是我对未来故事可能主题的简单调查:

回头见!

机器学习:从构思到网络应用

原文:https://towardsdatascience.com/machine-learning-from-ideation-to-a-web-app-ed5ccd3e1df1?source=collection_archive---------36-----------------------

使用 Python 和 Flask 的端到端数据科学之旅,包括数据收集、Web 抓取、数据清理、特征工程、模型训练和云部署

像素上的像素生成的图像

我之前所有关于实用 ML 方面的文章都主要围绕您的数据科学之旅中 ML 管道的单一主题。然而,在这里,我的目标是带您经历整个端到端的旅程,从数据收集开始,到任何地方的任何人都可以访问的云部署的 ML 模型结束。

除了通常怀疑的数据管理、特征工程、特征选择、模型训练和验证,我们还将看到如何执行网络搜集(通过 BeautifulSoup ),以及使用 FlaskHeroku 上部署一个 ML 模型。我希望带您经历一次实用的数据科学之旅,突出 ML 项目中一些相对无趣且耗时的任务。

预测问题

我们在这个项目中的目标将是预测任何两个国家之间的一日国际(ODI) 板球比赛的获胜者,即分类问题。

对于那些不熟悉板球的人来说,这个游戏的工作原理如下:

  • 两支各有 11 名选手的队伍争夺 ODI
  • 每个队在每一局最多有 50 次击球或投球出局的机会
  • 掷硬币获胜的一方(通过掷硬币或掷球棒)可以决定先掷球棒还是先掷保龄球
  • 该队击球手首先在单局中设定目标得分。每局比赛持续到击球一方“全部出局”(即 11 名击球手中有 10 名“出局”),或者第一方分配的所有回合都完成为止
  • 第二个击球的队试图得分超过目标得分以赢得比赛。从团队保龄球第二的角度来看,他们试图在击球队达到目标得分之前击败第二队或完成分配的回合
  • 比赛的结果可以是实际结果(一方获胜,另一方输掉比赛),平局(在分配的回合结束时双方得分相同),或平局/没有结果/放弃(在不可能比赛或由于天气条件或其他玩家无法控制的情况下比赛仍未结束的情况下)

一旦我们有了训练有素的模型,我们将:

  • 为我们的模型所需的所有独立变量构建一个带有输入表单的 HTML 前端——需要 HTML 知识(本文没有明确涉及)
  • 使用 Flask 框架构建应用程序的后端
  • 在 Heroku 上部署 web 应用程序,使其公开可用并可通过 URL 访问

数据收集

我们的主要数据来源将是与男性 ODI 相关的四个公开数据集此处。这些数据是从criinfo 的 Statsguru 搜集来的,包括了从 1971 年 1 月第一次对外直接投资到 2020 年 3 月所有对外直接投资的基本细节。这四个 CSV 具有每个游戏的以下必要信息:

  • 相关的比赛细节,包括比赛国家的名称、比赛日期、比赛场地和结果

ODI _ 结果

  • 单个运动员的击球和保龄球统计,例如得分、击球次数、击球次数、投球次数等。

ODI _ Burgess(截断的列)

我们将在数据管理阶段将这些数据帧连接在一起。尽管这些文件中提供了丰富的信息,但它们仍然缺少其他一些重要信息,如下所示:

  • 投掷结果,我们将从每场比赛的记分卡中刮出,正如在 Howstat 上主持的那样
  • 国际板球理事会(ICC) ODI 球员排名——根据 ICC 的官方国际击球和保龄球排名。我们将从 ICC 排名中收集这些信息

折腾信息的网络抓取

Web 抓取是从网站中提取信息,并将其存储在本地计算机或代码中的过程。Python 拥有多个 web 抓取库,允许我们将来自网站的原始数据作为 python 代码的一部分。我们将使用 BeautifulSoup 来实现这个目的,因为它使用起来非常简单,同时拥有几个与文本操作和解析相关的高级功能。

BeautifulSoup 的工作方式是获取一个网站,然后将其 HTML 元素解析为一个 BeautifulSoup 对象。然后,我们可以使用 HTML 标记和它的树状结构,根据它在 BeautifulSoup 对象中的位置提取特定的文本。例如,BeautifulSoup 可以帮助我们:

  • 查找所有链接
  • 找到第一个表格,给我它的第一个(或任何其他)单元格的内容
  • 查找特定类的所有链接
  • 在表格中查找特定文本,然后在下一个单元格中给我该文本

要了解网站的结构、使用的 HTML 标签以及如何使用 BeautifulSoup 处理特定网站的 HTML 标签,需要一些 HTML 的基础知识。

Howstat 上每个 ODI 在匹配的 URL 中都有一个唯一的匹配代码。我们将在一个for循环中使用这些唯一的匹配代码来收集曾经玩过的每个 ODI 的以下信息:

  • 团队名称
  • 掷硬币获胜的队
  • 比赛日期
  • 比赛场地的名称

比赛日期和场地名称将用于匹配和合并 toss 结果与我们的比赛细节的主要数据集。网站上显示的相关信息如下——在所有匹配中保持一致:

通过一点点的试验和错误,我确定了 Howstat 上的匹配代码(主要是顺序的),并将它们保存在一个 CSV 文件中。一旦这个 CSV 作为数据帧上传,我们将在一个for循环中检查每个比赛代码,从每个比赛的 Howstat 记分卡中提取所需的信息,并保存为一个单独的数据帧。前提很简单:

  • 定义每个记分卡的基本 URL,在我们的例子中是:http://www.howstat.com/cricket/Statistics/Matches/MatchScorecard_ODI.asp?MatchCode={code}&Print=Y
  • 解析 HTML 内容并保存为一个 BeautifulSoup 对象。
  • 在解析的 HTML 中查找所有表格。我们没有找到带有 toss 信息的特定表格,因为源 HTML 没有任何唯一的表格标识。您可能会遇到一些特定的用例,在这些用例中,您想要的表是用一个惟一的类在 HTML 中定义的。如果是这样的话,那么不需要找到所有的表,只需用 BeautifulSoup 的find_all方法的class_参数就可以找到目标表。回到我们的用例,对于 BeautifulSoup 对象中表格的每个元素:
  1. 如果元素的文本是Match Date,查找并保存下一个元素。下一个元素将是比赛的实际日期
  2. 如果元素的文本是Toss,查找并保存下一个元素。下一个元素将是赢得掷币的队的名字
  3. 如果元素的文本是Venue,查找并保存下一个元素。下一个元素是比赛场地的名称
  • 将上述每个匹配的三个数据点添加到字典中
  • 将字典转换成数据帧,以便有效地处理数据

现在你有了它,一个由所有 ODI 播放过的 toss 信息组成的数据帧,尽管废弃的文本仍需要一些清理。

toss_df(网页抓取后)

到目前为止执行的步骤代码:

数据管理和更多的网页抓取

我们现在将承担某些数据清理、预处理和合并任务,为最终摄入分类算法准备数据。

ODI _ 结果数据框架

我们将首先清理保存每个游戏高级细节的ODI_results数据帧。注意它的结构:每个游戏有两个记录:一个来自每个游戏团队的视角。例如,如果英格兰在某一天赢了澳大利亚的比赛,那么这场比赛将有以下两个记录:

  • 一个从英格兰的角度来看,显示英格兰赢得了这场比赛,和
  • 另一个来自澳大利亚的视角,澳大利亚输掉了这场比赛

此外,请注意,数据框中没有将对方国家的名称作为单独的一列。相反,它与Match栏捆绑在一起,就像这样:团队 1 对团队 2。我们将执行以下步骤:

  • 通过拆分Match列,去除结果列的前导和尾随空格,并使用一个简单的numpy.where方法,创建一个新的Opposition特性
  • 删除不需要的列,只保留下列内容:Result, Home/Away, Ground, Match Date, Country, Opposition
  • Match Date列转换为datetime格式

ODI_results_clean

ODI _ 局数数据帧

现在我们将处理我们的ODI_innings数据帧,这需要做更多的清理工作。让我们先了解一下它的结构:

  • 每一个参加比赛的运动员的名字都在一排
  • 每个玩家的游戏特定统计数据在列中。击球和保龄球统计都有其特定的列
  • 由于一名球员可以在同一场比赛中同时击球和投球,因此来自同一支球队的 11 名球员在每场比赛中都被包括两次,首先是他的击球统计数据,然后是他的保龄球统计数据。Innings Number列区分了这两个集合

我在手动 EDA 过程中注意到的一些问题:

  • 某些特定比赛的重复记录,其中相同局的统计重复
  • 在几个例子中,球员的名字被重复,所以统计数据是两个不同的球员,但有相同的球员名字。这意味着我们不能执行一揽子drop_duplicates操作。相反,我们需要选择列的子集来识别重复项
  • 我们还需要修改一些拼写,使其与 ICC 排名列表中的拼写一致——这是我们即将进行的抓取排名信息的网络抓取任务的先决条件
  • 由于 ICC 规则允许在特定条件下的比赛中使用替补球员,一些球员有 12 个球员的信息(而不是标准的 11 个)。我们将在此阶段保留所有 12 名球员的信息,稍后再处理

数据清理任务类似于我们在ODI_results上执行的任务,包括:

  • 基于要素子集删除重复的记录/行
  • 删除不需要的列,只保留下面的列:Players, Opposition, Ground, Match Date, Country。在特征工程的稍后阶段,我们将返回到一些被删除的列
  • 清理Opposition列(删除v,重命名特定的列,使两个数据帧的命名一致:ODI_resultsODI_innings
  • Match Date列转换为datetime格式

ODI _ 局数 _ 清洁

合并 ODI_results 和 ODI _ Burgess

现在,我们应该将两个清理过的数据帧合并为一个。我们的目标是在ODI_results_clean数据帧中添加 24 列,每一列都有参赛队和非参赛队的 12 名球员的名字:

上面的数据结构确保了我们将每个游戏的数据放在一行中。这是一个相当棘手的过程,涉及多个mergeunstack操作,但我会尽力解释我的方法:

  • 首先,将Match DateGroundCountry上的ODI_results_cleanODI_innings_clean合并,让游戏国玩家以长格式加入ODI_results_clean。在这个上下文中,长格式意味着用一列来保存玩家的名字,因此,每场比赛将跨越多行——类似于ODI_innings_clean。注意这里使用的是left join 而不是inner join,因为我们希望保留来自ODI_results_clean的所有数据,即使 ODI _ Burgess _ clean 中没有相应球队的球员信息
  • 然后执行类似的merge操作,只是这一次使用Opposition栏代替Country(以获得对手队球员的姓名),连同Match DateGround
  • 我们希望合并两个新的长格式数据框架,在单独的列中包含所有细节和每个队的球员。然而,在合并过程中,如果不复制玩家的名字,我们就不能以他们当前的形状做到这一点。在应用合并操作之前,我们希望有一个“平面”数据帧结构,其中每个国家的比赛数据都在一行中,即所有球员都在列中。我们将通过使用groupbyunstack方法的自定义函数来实现这一点
  • 一旦我们从比赛和对手的角度获得了 2 个“平面”数据帧,我们将执行一个简单的内部合并来将这两个数据帧连接在一起。我们使用了一个内部连接,因为我们想确保只有普通的行被连接,因为我预计ODI_innings_clean不会有特定球队的球员信息,无论是官方 ODI 状态还是其他
  • 替换一些球员名字的拼写,以确保我们的数据和 ODI 排名之间的拼写一致,我们将废弃。我通过手工试错法发现了这一点,如果您有来自多个来源的数据,这在一定程度上是必需的

迄今为止执行的数据管理操作代码:

ICC ODI 等级的网页抓取

接下来是最后一点网络抓取,从官方 ICC ODI 排名网站获取截至比赛日所有球员的 ICC ODI 排名。实现这一点的高级工作流如下:

  • ODI_matches数据帧分解回“long”格式,这样就只有一个Players列,单个匹配将跨越多行。这样做将有助于我们合并后刮排名

对于 ODI 播放的每个唯一日期:

  • 刮出击球和保龄球的前 100 名球员,并将他们保存在单独的数据框中
  • 获取当天参加比赛的球员姓名,并保存到第三个数据帧
  • 合并这三个数据帧
  • 在运动员姓名、击球等级和保龄球等级上逐个拆分合并的数据帧,使这三个信息集在三个数据帧中,运动员和等级在列中
  • 沿着列将三个未堆叠的数据帧连接在一起
  • 将结果 DF 附加到列表中

for循环的末尾,我们将有一个多个数据帧的列表,其中包含 ODI 比赛的每个日期的球员姓名、保龄球和击球等级。最后一步是对该列表进行简单的连接,以生成一个综合的最终数据帧(final_result),该数据帧包含以下 7,738 行 78 列的信息:

  • 国家名称
  • 反对派名称
  • 主场/客场——从这个国家的角度来看,这场比赛是主场还是客场
  • 地面
  • 比赛日期
  • 结果—我们的目标变量
  • 24 名运动员的名字,国家和反对派各 12 名
  • ICC ODI 保龄球 24 名球员的排名(np.nan以防球员排名在前 100 名之外)
  • ICC ODI 名选手的击球等级(np.nan如果选手不在前 100 名之内)

toss_df 数据帧

下一步是清理我们的toss_df数据帧,并将其与ODI_matches数据帧合并。一些高级任务包括:

  • Match栏中提取比赛和对手队的名称
  • Ground栏中提取准确的地面名称
  • 作为网页抓取的结果,Toss Won by列中的一些记录包括Result:。这种情况更有可能发生在那些被放弃的、未完成的或其他不可能有结果的匹配中。我们将放弃这些记录
  • 更新一些Ground名称,使其与ODI_matches数据帧一致
  • final_result数据帧合并成final_data数据帧

下一个数据管理任务的代码如下:

特征工程

我们已经有了相当多的信息来开发一个预测性的工作模型,但是我们可以添加和评估更多的信息。

比赛月份

我认为天气会对 ODI 比赛的结果产生影响。我们可以添加一年中的月份来代表这些信息。

赢/赔率

这是一个国家在任何给定日期赢得的累计比赛数与输掉的比赛数之比。根据我们目前收集的信息,我们可以很快确定这一点。

击球/保龄球平均得分和每次得分(RPO)

接下来,我们将根据原始ODI_innings数据框架中的局数信息,为每个团队计算以下四个新特性:

  • 平均打击率:每次击球失败得分
  • 保龄球平均得分:每门失分
  • 击球 RPO:每次击球得分
  • 保龄球 RPO:每次投球失分

这四个特征将根据每个国家截至比赛日期(但不包括比赛日期)的累计统计数据进行计算。计算它们所需的相关列有:

ODI _ Burgess _ for _ averages 数据框架

我们只有计算四个新特征所需的六个特征中的五个,因为我们在游戏中被一个团队遗漏了Innings Wickets Taken。但是这很容易计算,因为我们有每场比赛对手的Innings Wickets Taken。一个队失去的三柱门相当于对方得到的三柱门。

然后,一旦我们有了计算四个新特性所需的所有六列,我们将遍历所有国家,计算每个国家到比赛日期为止(但不包括比赛日期)这六个变量的累积值。一旦我们有了累积的统计数据,我们只剩下计算四个新特性了。我们的新数据框架将如下所示:

ODI_team_averages 数据框架

接下来,我们将删除除最后四列之外的所有列,并与final_data数据帧合并。

掷硬币赢了

我们还可以将Toss Won By列更新为类似于Toss Won?的内容,以表明游戏团队是否赢得了比赛。这将把列转换成二进制格式,并通过虚拟/一位热码编码消除潜在的稀疏数据帧。

玩家排名

请记住,对于某些游戏,我们有十二个玩家(由于游戏期间的玩家替换),但对于我们的模型训练和预测,我们不能有超过十一个玩家。这是因为在一场比赛开始前,一个队不能有超过 11 名队员。

为了适应这种情况,并且只有在我们的数据集中有 12 名玩家的比赛中,我们才会更新任何一名玩家的等级,使其等于截至Match Date的所有 12 名玩家的平均等级。

我们的特征工程已经接近尾声了,但是也许让我们也尝试一些额外的东西。目前,我们每场比赛总共有 44 个排名栏——这可能有点太多了,可能会导致“维数灾难”。如果我们可以在一个单独的列中总结每个队的击球和保龄球等级信息,会怎么样?这可能会将排名列的数量从 44 减少到 4。

但在此之前,我们应该估算缺失的等级。排名缺失是由于在比赛当天,球员不在 ICC ODI 排名前 100 名之列,即他们的排名高于 100。我会用一个常量101来代替缺失的等级。您可以尝试一些其他常数,但我认为这是最合适的,因为较高的常数可能会由于有点离群而导致误解。

我们可以选择任何描述性统计数据来表示 11 名球员的击球和保龄球信息,只要外行人在预测过程中能够快速计算出来。我将计算总和、平均值和中值,并在特征选择期间进一步评估。

我们现在已经完成了所有的特性工程,产生了 14 个新特性。

特征工程活动的所有代码如下:

特征选择

参考我以前的文章,重温我将在这里使用的特性选择技术。

分类特征选择—卡方检验

执行卡方检验以确定我们的分类特征是否与目标变量相关,结果如下:

卡方检验

显然,我们在这里得到了令人惊讶的结果——我本以为投掷结果和场地会对比赛结果产生重大影响。然而,根据我们手头的数据,鉴于它们的高 p 值,情况似乎并非如此。

我们有可能在有和没有这两个特性的情况下运行模型验证指标,并从那里得到它。但对于这个项目,我们将在模型训练之前放弃这些功能。

数字特征选择— F 统计量

对数值特征进行 ANOVA F-统计测试可得出以下结论:

  • Match Month对于预测来说没有统计学意义(再次令人惊讶)
  • 所有其他特征本身都具有统计学意义
  • 与总等级和平均等级相比,四个中值等级特征的 F 统计量非常低:我们不会考虑将它们用于模型训练
  • 总等级和平均等级的 F 统计量是相同的,所以如果我们愿意,可以使用任何一个
  • 作为一个粗略的启发,如果我们将Country Total Batting Rank特征的 F 统计量与每个Country_Batting Rank_x列的 F 统计量之和进行比较,后者大于前者。

因此,我将放弃所有 12 个描述玩家等级的额外特征,这些特征是在上一个特征工程中创建的(和Match Month),继续我们对单个玩家等级的建模。

特征选择的代码如下:

模型培训和验证

最后,我们来到机器学习的有趣部分——模型训练。我们将使用简单的逻辑回归算法进行预测。

我还尝试了特定的其他算法(例如,XGBoost、Random Forest、Ada Boost、Gradient Boosting),但是除了 Random Forest,其他三种算法并没有导致预测准确性的实质性提高。

在删除了基于特征选择步骤的列之后,我们只需要在拟合逻辑回归模型之前从分类特征中创建虚拟变量。

对于全面的模型评估,我们将执行[RepeatedStratifiedkFold](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.RepeatedStratifiedKFold.html)交叉验证,重复十次,以准确度作为我们的评估标准,因为我们的数据不是不平衡的。

我们的平均准确度分数为 68.66%,这是一个合理的准确度,如果不是非常高的话。但我想这是意料之中的,因为比赛的本质是个人的才华可以让一场比赛从一个失败的位置变成一个团队的胜利位置。

我们也可以画一个 ROC 曲线,确定合适的概率阈值来区分预期的赢和输。

受试者工作特征曲线

使用 Youden 的 J 统计量,我们的理想概率阈值达到 48.27%,也就是说,该阈值将产生最大的区分能力,以区分预期的赢和输。

我们的最后一步将是通过我们的 web 应用程序(Final_LR_Model.pkl)简单地处理模型以实现预测。

所有建模和验证相关的代码是:

为数据捕获构建一个 HTML 前端

那么我们现在如何使用我们的模型进行预测呢?有几种方法可以做到这一点:我们可以将特性传递给模型,并调用predictpredict_proba方法,或者我们可以与他人共享腌好的文件来预测他们自己(只要他们了解 python)。

但这两种方法都需要人工干预来加载数据并将其传递给模型。如果我们希望向世界开放我们的模型,允许任何人在任何时间做出他们的预测,而不需要与 python 和其他技术任务进行任何直接交互,会怎么样?

为了实现这一点,我们可以开发一个网站来捕获用户输入,将其传递给 Flask 后端进行预处理和预测,并通过另一个网页将模型输出返回给用户。本质上,我们想要像这种的东西——这是我们部署在云上的模型,让世界可以访问它,并且不需要 python、机器学习等知识。

开发一个网站需要一定程度的 HTML 和 CSS 样式表知识,这超出了本文的范围。然而,设计一个简单的输入表单并不需要成为专家。一些免费的在线平台和软件提供模板,或者允许通过简单的拖放界面进行 HTML 开发。

HTML 代码告诉浏览器在屏幕上显示什么,而 CSS 文件告诉它如何在屏幕上显示 HTML 内容。CSS 是一种通过指定背景颜色、字体大小和颜色、边距等来控制网页布局的有效方法。

请参考我们 web 应用程序的 HTMLCSS 代码,并注意以下几点:

  • HTML 代码(连同任何相关的图像)应该在一个“模板”文件夹内。templates 文件夹应该与 Flask 应用程序位于同一层,我们将在后面介绍它
  • 源代码应该位于名为“static”的文件夹中。静态文件夹应该与 Flask 应用程序位于同一级别。注意,这个文件夹的名称可以是您想要的任何名称,只要它在 HTML 代码中被适当地引用
  • 我们将在 templates 文件夹中有两个 HTML 代码:一个用于捕获用户输入(home.html),另一个用于显示模型输出(result.html)
  • home.html文件将包含几个下拉菜单和文本字段来捕捉用户输入。对于分类特征,最好使用下拉菜单来限制用户输入我们的模型未知的值。例如,CountryOppositionHome/Away特性

定义下拉菜单的示例代码:

<select class="element select large" id="element_2" name="element_2" required="required">     
<option value="" selected="selected"></option>    <option>Afghanistan</option>
<option>Australia</option>    
<option>Bangladesh</option>    
<option>England</option>    
<option>India</option>    
<option>Ireland</option>    
<option>New Zealand</option>    
<option>Pakistan</option>    
<option>Scotland</option>    
<option>South Africa</option>    
<option>Sri Lanka</option>    
<option>West Indies</option>    
<option>Zimbabwe</option>  
</select>

定义整数文本字段的示例代码(例如,玩家的保龄球等级):

<input id="element_99" name="element_99" class="element text large" type="number" step=".01" required="required" value=""/>

定义浮动文本字段的示例代码(例如击球率):

<input id="element_3" name="element_3" class="element text large" type="number" step=".01" required="required" value=""/>

让我们来看看这些标签的一些主要元素:

  1. <select>…</select>指定一个下拉框
  2. <option>…</option>指定每个下拉选项
  3. id是字段的唯一标识
  4. name是字段的唯一名称,我们的 Flask 应用程序可以使用它来引用特定的字段
  5. class是对 CSS 代码中定义的特定样式指南的引用
  6. number指定只接受整数作为输入
  7. step允许输入浮点数
  8. required确保用户不能将字段留空
  9. value是表单加载时用户看到的默认值
  • CSS 代码在 HTML 文件的<head>…</head>标记中被引用,如下所示(其中‘static’是保存 CSS 代码‘style . CSS’的文件夹名,[url_for](https://flask.palletsprojects.com/en/1.1.x/api/#flask.url_for)是生成动态 URL 的内置 Flask 方法):
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='./style.css') }}">
  • result.html中的主要元素是对作为{{pred}}pred变量的引用,它显示存储在 Flask 应用程序中的值

通过 Flask 开发 Web 应用程序的后端

我们将使用 Flask 框架开发 web 应用程序的后端。可以把 Flask 想象成一个库,可以像 Python 中的其他库一样导入。所以基本上,我们的应用程序将是一个简单的 Python 文件(扩展名为.py,而不是扩展名为.ipynb的笔记本),除了所有其他 Python 功能之外,它还利用了 Flask。

我们后端应用程序的代码如下:

app.py

为了让上面的代码不言自明,我尽了最大努力做了很好的注释,但是让我们从更高的层面来看一下:

  • 导入所有需要的库
  • 实例化名为app的 Flask 应用程序
  • 加载我们的腌渍模型(Final_LR_Model.pkl),它和app.py在同一个文件夹中
  • 创建两个列表:cols带有输入列的名称,即在应用虚拟编码之前模型使用的特征,以及col_list带有虚拟编码特征的名称
  • 通过 Flask 的[render_template](https://flask.palletsprojects.com/en/1.1.x/api/#flask.render_template)方法显示home.html网页
  • 将所有用户输入保存在列表int_features中,并将需要预测的国家名称保存在country变量中
  • 在应用虚拟编码(cols)之前,将输入列表转换成一个 NumPy 数组,然后转换成一个 dataframe,其列与我们模型中的列相同
  • 创建分类特征的虚拟变量,并重新索引生成的数据帧,以确保它具有我们的模型所需的所有虚拟编码列(通过带有labels = col_list参数的pd.reindex)
  • 通过predic_proba预测一场比赛获胜的概率,转换成浮点数,通过一个简单的if语句确定该国有望赢得比赛还是输掉比赛
  • 通过render_template显示result.html网页,将您选择的字符串分配给pred变量
  • 运行应用程序

就是这个!

但是,让我们先在本地测试我们的应用程序,然后再将它部署到云中。启动 Anaconda 提示符(或您选择的任何终端),导航到包含app.pyFinal_LR_Model.pkl和模板&静态文件夹的文件夹,并使用以下命令运行它:

python app.py

忽略版本冲突版本(您可能看不到),在 web 浏览器中打开 URL。你应该看到你漂亮的home.html并且能够输入测试值并做出预测。

恭喜你!你现在已经构建了你的第一个 ML 应用程序。接下来,我们将把这个应用程序从您的本地机器带到云中,以便其他人可以通过 URL 使用它。

Heroku 上的云部署

Heroku 为云部署提供平台即服务(PaaS)。有几种方法可以完成 Heroku 部署,但最简单的可能是通过 GitHub 库。

除了我们在本地测试应用程序时使用的两个文件和两个文件夹,在 Heroku 部署之前,我们还需要 GitHub 存储库中的两个文件:

  • requirements.txt 是一个文本文件,包含执行应用所需的 python 包的名称。这些是为成功执行应用程序而在环境中安装的必备软件包

requirements.txt

你应该非常熟悉上述所有要求。可以把 Gunicorn 看作一个中间件,它允许您的 Flask 应用程序与托管它的服务器进行通信。从技术上讲,它是一个 Python Web 服务器网关接口(WSGI) HTTP 服务器

  • Procfile(没有任何文件扩展名)是一个应用程序中的进程类型列表,即一个给 web 服务器的指令列表,指示当有人登录到该应用程序时应该首先执行哪个文件。下图中的一行代码告诉服务器使用 Gunicorn WSGI 打开一个 web 应用程序,并在一个名为app.py的文件中运行一个名为app(这是我们在app.py中定义的应用程序名称)的应用程序

Procfile

在这个阶段,你的 GitHub 库应该是这样的:

https://github.com/finlytics-hub/ODI

按照以下步骤完成 Heroku 部署:

  • 登录你的 Heroku 账户(注册这种规模的项目是免费的),在你的仪表盘上点击“创建新应用”

Heroku 仪表板

  • 输入您想要的应用程序名称和首选地区,然后单击“创建应用程序”

创建新应用程序

  • 在“部署方法”下选择 GitHub,并连接到您的 GitHub 帐户

选择并连接到 GitHub

  • GitHub 可能会要求您在允许通过 Heroku 访问您的 GitHub 帐户之前进行身份验证
  • 一旦你的 GitHub 账户连接到 Heroku,搜索并连接到你的目标 GitHub 库

连接到 GitHub 存储库

  • 连接到存储库后,在“手动部署”选项下部署其所需的分支

部署分支

  • 等待一段时间,Heroku 从存储库中取出所有需要的代码,在其服务器上安装所有需要的库,并完成部署。一旦完成,Heroku 将确认你的成功部署(或其他),并给你一个选项来查看你的应用程序在一个特定的网址

成功部署

部分了解我们可通过互联网访问的应用程序:

部署的应用程序(部分快照)

现在你有了它——一个完整的工作机器学习模型,用 Python 开发,部署在云上,任何人都可以全天候访问!

结论

这是一次非常旋风般的旅行,我希望您会一直跟着我,同时也学习一些新的概念、工具、技术和方法。

你也可以在这里找到完整的笔记本

如果您想讨论任何与数据分析、机器学习、金融或信用分析相关的问题,请随时联系 me

下次见,摇滚起来!

机器学习:GridSearchCV & RandomizedSearchCV

原文:https://towardsdatascience.com/machine-learning-gridsearchcv-randomizedsearchcv-d36b89231b10?source=collection_archive---------12-----------------------

使用 GridSearchCV 和 RandomizedSearchCV 进行超参数调整

JESHOOTS.COMUnsplash 上拍照

简介

在这篇文章中,我想谈谈我们如何通过调整参数来提高机器学习模型的性能。

显然,为了改进我们的模型,了解我们想要调整的参数的含义是很重要的。出于这个原因,在谈论 GridSearchCV 和 RandomizedSearchCV 之前,我将首先解释一些参数,如 C 和 gamma。

第一部分:SVC 中一些参数的概述

逻辑回归支持向量分类器中,决定正则化强度的参数称为 C

对于一个高 C ,我们将有一个更少的正则化,这意味着我们试图尽可能地适应训练集。相反,当参数 C值较低时,算法会尝试调整到“大多数”数据点,并提高模型的泛化能力。

还有一个重要的参数叫做伽马。但在谈论它之前,我认为了解一点线性模型的局限性是很重要的。

线性模型在低维空间中非常有限,因为线和超平面具有有限的灵活性。使线性模型更加灵活的一种方法是添加更多要素,例如,添加输入要素的交互或多项式。

用于分类的线性模型只能使用线来分隔点,这并不总是更好的选择。因此,解决方案可以是在三维空间中表示点,而不是在二维空间中。事实上,在三维空间中,我们可以创建一个平面,以更精确的方式对我们数据集的点进行划分和分类。

有两种方法可以将你的数据映射到一个更高维的空间中:多项式核,计算所有可能的多项式,直到原始特征的某个程度;以及径向基函数(RBF) 核,也称为高斯核,其测量数据点之间的距离。这里 gamma 的任务是控制高斯核的宽度。

第二部分:GridSearchCV

正如我在我的上一篇文章中所展示的,交叉验证允许我们评估和改进我们的模型。但是还有另一个有趣的技术来改进和评估我们的模型,这个技术叫做网格搜索

网格搜索是一种调整监督学习中参数,提高模型泛化性能的有效方法。通过网格搜索,我们尝试了感兴趣的参数的所有可能组合,并找到了最佳组合。

Scikit-learn 提供了 GridSeaechCV 类。显然,我们首先需要指定我们想要搜索的参数,然后 GridSearchCV 将执行所有必要的模型拟合。例如,我们可以创建下面的字典,它提供了我们想要为我们的模型搜索的所有参数。

parameters = {‘C’: [0.001, 0.01, 0.1, 1, 10, 100], 
‘gamma’: [0.001, 0.01, 0.1, 1, 10, 100]}

然后,我们可以用 SVC 模型实例化 GridSearchCV 类,并应用 6 个交叉验证实验。当然,我们还需要将数据分成训练集和测试集,以避免过度拟合参数。

from **sklearn.model_selection** import **GridSearchCV** from **sklearn.model_selection** import **train_test_split** from s**klearn.svm** import **SVC** search = GridSearchCV(SVC(), parameters, cv=5)X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

现在,我们可以用我们的训练数据来拟合我们已经创建的搜索对象。

search.fit(X_train, y_train)

因此,GridSearchCV 对象搜索最佳参数,并在整个训练数据集上自动拟合新模型。

第三部分:随机搜索

当我们有很多参数要试,训练时间很长的时候,RandomizedSearchCV 就非常有用了。对于这个例子,我使用随机森林分类器,所以我想你已经知道这种算法是如何工作的。

第一步是写出我们想要考虑的参数,并从这些参数中选择最好的。

param = {‘max_depth: [6,9, None], 
         ‘n_estimators’:[50, 70, 100, 150], 
          'max_features': randint(1,6),
          'criterion' : ['gini', 'entropy'],
          'bootstrap':[True, False],
          'mln_samples_leaf': randint(1,4)}

现在我们可以创建我们的 RandomizedSearchCV 对象并拟合数据。最后,我们可以找到最佳参数和最佳分数。

from **sklearn.model_selection** import **RandomSearchCV** from **sklearn.ensemble** import **RandomForestClassifier**rnd_search = RandomizedSearchCV(RandomForestClassifier(), param, 
n_iter =10, cv=9)rnd_search.fit(X,y)
rnd_search.best_params_
rnd_search.best_score_

结论

因此,当我们处理少量的超参数时,网格搜索是很好的。但是,如果要考虑的参数数量特别多,并且影响的大小不平衡,那么更好的选择是使用随机搜索。

感谢你阅读这篇文章。您还可以通过其他方式与我保持联系并关注我的工作:

  • 订阅我的时事通讯。
  • 也可以通过我的电报群 初学数据科学 取得联系。

机器学习指南—边做边学

原文:https://towardsdatascience.com/machine-learning-guide-learning-by-doing-afe732afde39?source=collection_archive---------26-----------------------

强化你技能的指南

与 Raj 在 Unsplash 上的公路旅行照片

我坚信学习如何做某事的一个有效方法就是实际去做。“边做边学”的风格也适用于机器学习。当然,对概念和理论的全面理解是必要的,但如果不能实现实际的模型,我们的机器学习技能将是不够的。

在这篇文章中,我将带您了解构建机器学习模型的过程,从探索性数据分析开始,最终达到模型评估。这将是一个简单的模型,但它肯定会帮助你理解的概念和程序。我将尝试详细解释每个步骤,并提供代码。

我们将尝试从拍卖中预测汽车的价格。数据集可在 kaggle 上的这里获得。该员额的主要部分是:

  1. 探索性数据分析
  2. 数据预处理
  3. 构建和评估模型

1。探索性数据分析(EDA)

让我们从将数据集读入熊猫数据帧开始,并查看它:

import numpy as np
import pandas as pddf = pd.read_csv("/content/USA_cars_datasets.csv")df.shape 
(2499, 13)df.head()

该数据集包括 2499 辆汽车的 13 个特征。在确定汽车价格时,有些特征很重要,而有些则是多余的。例如,“vin”、“lot”和“未命名:0”列对价格没有影响。这三列代表一辆车的 ID。由于数据集取自美国的一个网站,我认为国家一栏只包括“美国”。让我们检查一下:

df.country.value_counts()
usa       2492  
canada       7 
Name: country, dtype: int64

并非所有但绝大多数都是“美国”,所以在我们的模型中使用“国家”列作为特征是没有意义的。因此,我们不会在模型中使用的列有:

  • vin,批次,未命名:0,国家

让我们使用 drop 函数删除这些列:

df.drop(['Unnamed: 0','vin', 'lot','country'], axis=1, inplace=True)

除了要删除的列列表之外,我们还传入了两个参数。 Axis=1 表示我们正在删除列,并且 inplace 参数设置为 True 以保存数据帧中的更改。

现在数据帧的列数减少了:

我们将构建一个受监督的机器学习模型来执行一个回归任务。监督学习意味着我们有一个想要预测的目标。监督学习可以分为两大类:

  • 回归:目标变量是连续的
  • 分类:目标变量是离散的

价格列是我们的目标变量(因变量),其他列是我们将用来预测价格的特性(自变量)。

缺失值

让我们检查一下数据集中是否有任何缺失值:

df.isna().sum().sum()
0

该数据集经过预先清理,因此没有任何缺失值,但是检查和处理缺失值是一个很好的做法。在大多数情况下,我们会有缺失值,并且应该学会如何检测和处理它们。 df.isna()。sum() 返回每列中缺失值的数量。通过再加一个总和,我们可以看到整个数据帧中缺失值的总数。以下是关于如何查找和处理缺失值的详细帖子:

[## 用熊猫处理缺失值

关于如何检测和处理缺失值的完整教程

towardsdatascience.com](/handling-missing-values-with-pandas-b876bf6f008f)

数据类型

检查列的数据类型很重要,如果有不合适的数据类型,就进行更改。

他们看起来很好。如果数据集有很多观察值(行),我们可以使用“category”数据类型代替 object,以减少内存使用。

目标变量

我总是从检查目标变量开始。目标变量是我们难以预测的。最后,我们将根据我们的预测与目标的接近程度来评估模型。因此,很好地了解目标变量是一个很好的实践。让我们检查目标变量的分布。我们首先需要导入将在 EDA 过程中使用的数据可视化库:

import matplotlib.pyplot as plt
import seaborn as sns%matplotlib inline #render visualizations in the notebookplt.figure(figsize=(10,6))
sns.distplot(df['price']).set_title('Distribution of Car Prices')

价格变量不是正态分布的。它是右偏的,意味着分布的尾部右侧比左侧长。另一种证明偏斜度的方法是比较平均值和中值。如果平均值高于中值,则分布是右偏的。Mean 是平均值,median 是中间的值。因此,如果平均值高于中位数,我们有更多的样本在中位数的上边。

如预期的那样,平均值高于中值。所以,昂贵的汽车比便宜的汽车多。

独立变量

品牌和型号

我们有 8 个特点。让我们从探索“品牌”特征开始:

df.brand.value_counts().size
28

有 28 个不同的品牌,但前 6 个类别包含了大多数汽车。

几乎 94%的汽车属于六个品牌。剩下的 6%分布在 22 个不同的品牌中。我们可以将这 22 个品牌标为其他。我们首先创建一个包含这 22 个品牌的列表,然后在“品牌”列上使用熊猫替换功能:

other = df.brand.value_counts().index[6:]
len(other)
22#replace 22 brands with "other"
df.brand = df.brand.replace(other, 'other')

让我们检查一下操作是否成功:

边做边检查是一个好习惯。如果你只在最后检查,你可能很难找到错误的原因。

是时候检查价格是否根据不同的品牌而变化了。箱线图是完成这项任务的信息工具。

plt.figure(figsize=(12,8))sns.set(style='darkgrid')
sns.boxplot(x='brand', y='price', data=df)

方框中的线表示平均价格。福特汽车的平均价格最高,但请记住,数据集中几乎一半的汽车是福特汽车。在构建和评估我们的模型时,这可能是有用的。还有一些极端值(即异常值)用圆点表示。我们稍后将处理异常值。箱线图的高度表示数值的分布程度。该数据集包括的道奇汽车比雪佛兰汽车多,但雪佛兰汽车的价格比道奇汽车更分散。各种各样的模型可能会导致这种传播。让我们来看看每个品牌有多少型号:

虽然道奇车比雪佛兰车多,但雪佛兰的车型数量是道奇的两倍多,我认为这就是价格差异的原因。让我们再次使用箱线图来查看不同型号的价格分布:

plt.figure(figsize=(12,8))sns.set(style='darkgrid')
sns.boxplot(x='model', y='price', data=df[df.brand == 'dodge']).\
set_title('Prices of Different Dodge Models')

我选择道奇品牌作为例子。如箱线图所示,价格范围因型号而异。

整个数据集中有 127 个模型,但 50 个模型覆盖了几乎 94%的汽车,因此我们可以将剩余的模型标记为其他。

标题状态

我们已经涵盖了品牌和型号。让我们检查一下“标题 _ 状态栏。它表明汽车是干净的还是可回收的,这是决定价格的一个因素。我们来确认一下:

我们没有很多打捞车,但它是一个具有显著价格差异的必备功能。

颜色

“颜色”列与“品牌”列在类别数量上相似。

有 49 种不同的颜色,但 90%的汽车属于 6 种不同的颜色。我们可以像在“品牌”栏中一样,将剩余的颜色标记为其他颜色。

让我们看看现在有哪些颜色:

平均价格很接近。同时检查极值(即异常值)是一个很好的做法。

sns.set(style='darkgrid')plt.figure(figsize=(12,8))
sns.boxplot(x='color', y='price', data=df)

颜色与价格

上图告诉我们两件重要的事情:

  • 颜色不是价格的决定性因素。不同颜色的平均价格和价差并没有太大的变化。因此,最好不要将“颜色”作为一个特征包含在我们的模型中。
  • 存在异常值,我们需要以某种方式处理它们。否则,模型将尝试捕获它们,这将阻止模型很好地推广到数据集。

我们有一些价格极高的汽车。这些异常值不会以特定的颜色进行分组。从上图来看,似乎所有的异常值都在 45000 以上。让我们检查一下我们有多少异常值,并决定我们是否能够放弃它们:

45000 以上的汽车有 102 辆,占整个数据集的 4%。我想我们可以放弃这些样本。在某些情况下,4%太多了,所以如何标记和处理异常值取决于你。离群值没有严格的定义。

剔除异常值后的价格箱线图

年份和里程

年份和里程肯定会改变汽车的价格,所以我们将在模型中使用这些功能。我更喜欢通过从当前年份中减去“年份”来将“年份”列转换为“年龄”:

age = 2020 - df.iloc[:,3].values
df['age'] = agedf = df.drop(['year'], axis=1)

条件

条件表明拍卖结束的时间,我认为这可能会增加需求,从而提高价格。但是,我们不能使用它当前的格式。我们应该用一个合适的数据类型来表示它,这个数据类型是显示分钟数的整数。

有许多方法可以完成这项任务。请随意尝试不同的方法。我会这样做:

  1. 在空格上拆分条件列,并扩展到具有三列的新数据框架(例如,10-天-左)
  2. 将第二列转换为适当的分钟值(例如,用 1440 替换天,用 60 替换小时)
  3. 然后将第一列乘以第二列,得到拍卖结束的剩余时间(分钟)。

注意:条件列中有一些行带有“列表已过期”。对于这些行,我将用零替换“Expired ”,用一替换“Listing ”,这样剩余时间就变成零。

a = {'days':1440, 'hours':60, 'minutes':1, 'Expired':0}
df_condition[1] = df_condition[1].replace(a)df_condition[0] = df_condition[0].replace('Listing',1)
#convert to numeric to do multiplication
df_condition[0] = pd.to_numeric(df_condition[0]) df_condition['time'] = df_condition[0] * df_condition[1]#create a new column in the original dataframe
df['time_left'] = df_condition['time']

原始数据帧:

EDA 过程中另一个有用的工具是相关矩阵,它可以用来发现连续特征之间的相关性。 corr() 方法可应用于数据帧,结果也可使用热图可视化:

corr = df[['price','mileage','age', 'time_left']].corr()plt.figure(figsize=(10,6))
sns.heatmap(corr, cmap='Blues').set_title('Correlation Matrix')

价格似乎与剩余时间无关,但价格与年龄或里程数之间存在显著的负相关。这是意料之中的,因为旧车更便宜。

2。数据预处理

我们已经探索了数据集,并清理了它的一部分。但是,我们还没有完成。

我们有品牌和颜色等分类特征。这些特征需要用模型可以处理的格式来表示。我们不能只在模型中输入字符串。我们首先需要将类别转换成数字(标签编码)。如果分类变量不是有序的(也就是说,它们没有等级顺序),仅仅做标签编码是不够的。我们需要用二进制列来表示类别。这可以使用“虚拟或“一个热”编码来完成。例如,我们可以将“闪避”标签设为 3,将“GMC”设为 1。如果我们只对非有序分类变量进行标签编码,模型会认为类别 3 比类别 1 更重要,这是不正确的。一种热编码将每个类别表示为一列,该列只取两个值,1 和 0。对于“道奇”品牌的汽车,只有“道奇”一栏的值变成 1,其他栏都是 0。通过这种方式,我们可以确保类别之间没有层次结构。

我们还需要标准化数字数据,以便这些值在相同的范围内。否则,模型可能会更重视较高的值。例如,“里程”列中的值远高于“年龄”列中的值。我们可以在[0,1]的范围内对这些值进行归一化,使得每列的最大值变为 1,最小值变为 0。

虚拟编码

由于我们数据集中的分类变量不是有序的,标签编码是不够的。因此,我们可以直接应用 pandas get_dummies 函数,用分配给每个类别的列来表示分类变量。

dummy_variables = pd.get_dummies(df[['brand','model','title_status']], drop_first=True)dummy_variables.shape
(2394, 57)dummy_variables.head()

正常化

我们可以通过一些简单的数学运算手动进行标准化,但我更喜欢使用 scikit-learn 的 MinMaxScaler() 函数。

num_features = df[['mileage', 'age', 'time_left', 'price']]sc = MinMaxScaler()
num_features = sc.fit_transform(num_features)

正如我们所看到的,所有的值都在 0 和 1 之间。

预处理完成后,我们可以组合分类和数字特征。下一步是分离自变量和目标(因变量)。

cat_features = dummy_variables.valuesdata = np.concatenate((cat_features, num_features), axis=1)X = data[:, :data.shape[1]-1]
y = data[:, data.shape[1]-1]print(X.shape)
print(y.shape)
(2394, 60)
(2394,)

我们有 60 个自变量和一个目标变量。

在预测分析中,我们建立机器学习模型,对新的、以前从未见过的样本进行预测。整个目的就是能够预测未知。但是模型不能凭空做出预测。我们向模型展示一些样本并训练它。然后,我们期望模型对来自相同分布的样本进行预测。为了训练模型,然后测试它,我们需要将数据集分成两个子集。一个是培训,一个是测试。

使用 scikit-learn 的 train_test_split 函数可以很容易地完成训练集和测试集的分离。

from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state=42)

我们将使用 80%的数据进行训练,剩余的 20%用于测试模型。

3。构建和评估模型

我将实现两种不同的模型。

  • 岭回归:线性回归与 L2 正则化的一种变体。正则化增加了对模型中较高项的惩罚,从而控制了模型的复杂性。如果增加一个正则项,该模型试图最小化损失和模型的复杂性。限制复杂性可以防止模型过度拟合。
  • 梯度推进回归器:一种使用推进将许多决策树结合起来的集成方法。这是一个比岭回归更高级模型。

岭回归

from sklearn.linear_model import Ridge#Create a ridge regressor object
ridge = Ridge(alpha=0.5)#Train the model
ridge.fit(X_train, y_train)#Evaluate the model
print('R-squared score (training):{:.3f}'.
format(ridge.score(X_train, y_train)))print('R-squared score (test): {:.3f}'
.format(ridge.score(X_test, y_test)))R-squared score (training): 0.626 
R-squared score (test): 0.623

r 平方是一个回归得分函数。它衡量目标变量中有多少变化是由自变量解释的。R 平方值越接近 1,模型的性能越好。训练集和测试集的 r 平方得分非常接近,因此模型不会过度拟合。似乎正规化运作良好。然而,该模型在预测能力方面的性能不够好,因为 R 平方得分不接近 1。

梯度推进回归器

from sklearn.ensemble import GradientBoostingRegressor#Create a GradientBoostingRegressor objectparams = {'n_estimators': 600, 'max_depth': 5,
'learning_rate': 0.02, 'loss': 'ls'}
gbr = GradientBoostingRegressor(**params)#Train the model
gbr.fit(X_train, y_train)#Evaluate the model
print('R-squared score (training): {:.3f}'
.format(gbr.score(X_train, y_train)))print('R-squared score (test): {:.3f}'
.format(gbr.score(X_test, y_test)))R-squared score (training): 0.755 
R-squared score (test): 0.703

如结果所示,R 平方分数有显著增加。

最后的想法

训练集和测试集的值之间有细微的差别,但我认为就我们现有的数据而言,这是可以接受的。我们可以创建一个模型,它在训练集上的 R 平方值非常接近 1,但在测试集上的性能将非常低。

主要原因是数据有限。对于复杂的模型,我们通常需要大量的数据来构建一个体面和健壮的模型。数据集中的分类变量有许多类别,但没有足够的数据用于每个类别。因此,改进模型首先要做的是寻找更多的数据。

另一种提高性能的方法是超参数调整。超参数定义了我们可以调整的模型的属性。例如,我对梯度推进回归器的以下超参数尝试了不同的值:

  • n_estimators :要执行的升压阶段的数量。
  • max_depth :单个回归树的最大深度。
  • learning_rate :每棵树的贡献因学习率而缩小。

没有严格的规则来确定这些参数的最佳值。我们需要找到正确的平衡。请随意尝试这些参数的不同值,看看性能如何变化。请不要局限于我们在探索性数据分析部分所做的。您总是可以更深入地研究数据集,找出数据的相关性和底层结构。

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

机器学习——处理缺失数据

原文:https://towardsdatascience.com/machine-learning-handling-missing-data-27b09ab146ba?source=collection_archive---------47-----------------------

开始使用数据前如何清理数据的指南。

这里是我们将在教程中使用的数据: 点击这里

当数据中有空值时,它们通常会以 NAN 值的形式出现在 IDE 中。在开始数据训练之前,您需要处理这些缺失的数据。我们有两种基本的方法可以做到这一点。我们可以删除缺少值的行,或者填充它们。

图 1: 来自 PC 的数据集截图

上面你可以看到有多少单元格丢失了数据。

检查是否存在 nan

数据集真的很大,那么如何快速找到空值呢?

我们可以使用isNull()方法找到任何可能出现的 NAN 值。我们可以使用.sum()方法获得每列所有 NAN 值的计数

代码片段: dataset.isnull().sum()

下面是上面数据集的部分示例:

图片 2: 从电脑上截取的截图

我们在这里看到' 年龄 '有 2 南值和' 死亡县 '有 1100。这段代码片段为我们提供了数据集中每列 NAN 值的准确数量。

处理南价值观。

根据如何处理 NAN 值的数据集,您有几种选择。

1.删除丢失的值

在上例中,我们看到' 日期 '有 2 个 NAN 值

现在对我来说,' Date '可能是我的处理所必需的,所以我想删除任何没有日期值的行。

为了实现这一点,我们可以使用内置方法,dropna().这个方法自动删除任何带有 NAN 的行。但是,我们将希望使用特定的列,所以让我们看看如何做到这一点

a .删除列中缺少值的行

代码片段: dataset.dropna(subset=['ColumnName1', 'CoulmnName2'], how='any')

这里我们看到不再有任何与 NAN 相关的日期行。

快速旁注, 如果任何选中的列有 NAN ,则how=’any’将删除该行。在这个例子中,我只看了一列,所以没关系,但是假设subset=[‘Date’, ‘Age’]。如果' Date '或 'Age' 有一个 NAN 值,该行将被删除。

如果我们希望仅当 【日期】&【年龄】都是 NAN 时才删除该行,我们可以使用how=’all’,它在删除该行之前检查所有值是否都是 NAN 。

b .删除所有带有 NAN 的行

可能的情况是,当任何列有 NAN 时,我只想删除任何行。使用.dropna()方法很容易做到:

代码片段: dataset = dataset.dropna(how=’any’)

但是在我们的例子中,执行这个操作会删除所有的行,所以它不是很有用。

c.删除所有列都是 NAN 的行

有时会发生这样的情况,有些行只包含所有的 NAN 值。要删除这些不必要的行,我们可以:

代码片段:

2.填充缺失值

因此,有时我们的数据几乎是完美的,但我们只是有一些需要填充的缺失值,以便我们可以处理数据。

a .填写分类数据

让我们以“种族”一栏为例。如果我们用value_counts()方法查看数据集中的值,确保设置dropna=False以便我们也可以计算 NAN 值,而不仅仅是类别,我们会得到这样的结果:

代码片段 : dataset[‘Race’].value_counts(dropna=False)

我们在这里看到' 种族 '列中有 13 个 NAN 值。幸运的是,我们已经有了像“”或“ 其他 ”这样的类别可以使用。

在这种情况下,我们将所有 NAN 值映射到“”类别是有意义的,因为我们不知道这些值是否属于任何主要类别或属于“ 其他 ”类别。**

要做到这一点,我们只需要使用下面的.fillna()方法,我们可以将所有缺失的值赋给' 未知的 '。

代码片段 : dataset[‘ColName’].fillna(value= ‘Replace’, inplace=True)

然后砰!所有的 NAN 值已经被映射到' 未知的 '就像我们想要的那样。

b.填写数字数据

如果我们以' 年龄 '为例,我们可以从我们之前的运行(图 3)中看到有 3 行,其中年龄为 NAN 。现在,由于这不是很多丢失的数据,通常我们可以删除它们,因为它可能不会影响我们的训练。但是假设我们需要处理它们,我们可以采用什么策略呢?

替换为列的平均值、中间值或最频繁值

根据具体情况,您可能希望用平均值、中值或众数来替换这些值。在这种情况下,mean 是有意义的,但是让我们用三种方法来做。

平均值 : dataset[‘col’].fillna((dataset[‘col’].mean()), inplace=True) 最频繁 : dataset[‘col’].fillna(dataset[‘col’].mode().iloc[0], inplace=True)
中位数 : dataset[‘col’].fillna((dataset[‘col’].median()), inplace=True)

在这个年龄示例中,我们可以看到索引 0、12 和 4887 是 NAN 值****

运行 median 的代码(并进行一些舍入)后,我们得到了看起来更好的东西。

****

马库斯·温克勒在 Unsplash 上拍摄的照片

这就是处理丢失数据的基本方法。通常情况下,您应该能够只使用这里的代码,或者通过谷歌搜索一些罕见的情况。

下期龙珠 Z:更多预处理!

机器学习具有不确定性。为它而设计。

原文:https://towardsdatascience.com/machine-learning-has-uncertainty-design-for-it-f015a249a444?source=collection_archive---------41-----------------------

通过正确的设计,我们可以将更多的数据科学见解产品化并发布,即使是不完美的、概率性的见解。

信用:怀特莫卡。经许可使用。

我们生活在机器学习的时代。这意味着我们制造的产品越来越少以我们所知的事实进行交易:相反,它们越来越依赖于概率的东西,比如推论、预测和推荐。根据定义,这些东西具有不确定性。不可避免的,他们会

但这并不意味着它们没有产品价值。毕竟,你可能宁愿知道有 50%的可能性会下雨,也不愿完全没有预报。如何从必然出错的算法中解锁用户价值?我们可以做预测所做的事情:设计我们的产品时要坦率地面对不确定性。

在机器学习的时代,设计能够传达其确定度的产品可以成为一个巨大的竞争优势:

  • 可以解锁新价值。我们可以将更多的数据科学见解产品化和发布,即使是不完美的、概率性的见解,方法是让用户能够自己判断如何使用它们,而不是为它们做出决定而什么都不发布。
  • 可以降低风险。传达不确定性是一种免责声明:用户可以权衡证据并得出结论,风险自担,而不是必须从表面上接受产品的声明,并为不透明、不正确的结论负责。
  • 可以提高可用性。好的设计让用户看到产品在做什么:系统状态的可见性是第一个尼尔森诺曼对用户界面设计的启发。不确定性的可见性让用户免去了自己计算某样东西有多可靠的痛苦。

所有这些的问题是什么?不确定性是很难设计的。机器学习用概率表达不确定性,但概率不是产品:正常人不想钻研p-值和置信区间,设计师也不想创造出充满星号和技术细节的复杂怪物。此外,非专家不太擅长解释原始概率,有时会把它们变成可怕的战略决策。

我们应该传达产品中的不确定性,但我们需要有效的、以用户为中心的设计解决方案来做到这一点。在本文中,我将描述三种很好的设计模式:

  • 展示你的作品
  • 揭示个人数据点
  • 让用户完成拼图

为了使事情具体化,我将主要从 Context 中提取例子,这是我们的法律数据分析产品,从数百万司法意见的语言中提取有用的见解。这是将机器学习产品化的一个很好的试验场,因为我们的律师用户群可能会对概率高度怀疑,并且完全不原谅错误。在设计适合他们的产品方面,我们学到了很多!

设计模式#1:展示你的作品

这里的公式很简单:提供你的概率洞察力(机场现在有点忙… ),让用户知道你的算法是如何得出的(…基于对这个地方的访问)。谷歌地图是这样做的:

这可以让你的洞察力更有说服力,也更有用:用户可以调整他们在方法中看到的任何特定的偏见或限制,并自己决定对结论有多大的信心。

在上下文中,我们的见解是基于司法文件的书面语言。下面,我们的语言算法发现,专家证人贾尔斯博士和律师事务所汤普森&奈特之前有联系:他们过去似乎有过反对对方(在决定是否聘用贾尔斯博士时知道这一点是件好事)。我们的设计展示了引导算法得出这一结论的确切语言。这有助于用户验证结论,并加深了对这位专家和律师事务所如何认识的了解:

在推荐引擎的世界里,展示你的作品也很方便。下面的设计以一个完整的句子的形式做到了这一点:

这种设计非常明确地告诉用户该算法如何工作:本质上,该算法只是招募过去的客户作为推荐者,这是一种被称为协作过滤的聪明技术。通过完全透明,设计免除了满足潜在期望的算法,这是不确定要满足的,比如推荐非常相似、相关或诱人的产品。

最后,有时展示你的作品会成为主要的吸引力。在拉威尔定律中,我们建立了一个实验性的动议结果预测器,它计算一项动议将被法院批准的百分比机会,并显示不同的因素(如类型的主张辩护)如何根据经验使批准的可能性更大或更小。我们通过简单的可视化展示了因素权重:

我们向预测者展示的律师对理解这些个体因素的运作更感兴趣——他们在起草动议时可以控制的可操作的事情——而不是对结果的精确预测。预测是困难和不确定的,但是展示我们(模特)的作品给了我们的律师一个有用的参考他们的工作。

设计模式#2:显示单个数据点

如今,这些不起眼的个体数据点可能看起来像是一种遗迹,许多设计关注于如何将大规模数据集抽象为人类可消化的概括,通常是以数据仪表板的形式。但是一般化会给我们带来麻烦,尤其是当数据稀疏的时候。矛盾的是,大数据意味着我们现在比以往任何时候都有更多可能的小数据集,这是将大数据集切割成我们感兴趣的内容的结果。我们应该针对小数据固有的不确定性进行设计。

此外,在大大小小的数据集中,当数据实际上遵循与我们假设的不同的分布时,急于下结论会带来麻烦。潜在的分布可能是偏斜的双峰的,甚至是相反的,就像这个辛普森悖论的例子:

对于一个产品来说,披露个体的原始数据点可能更安全——也常常更有用——从而传达其关于任何结论可靠性的 不确定性。考虑我们的一个上下文设计的前后情况,显示专家证人成功获得法庭认可的证词的记录:

最初的设计需要大量的“汇总统计数据”,我们称之为——多个条形图,表明专家在各种情况下的证词接受率。问题是许多专家只有一两个结果,这不足以可信地为这些图表提供动力。我们最终会笨拙地宣布许多 0%和 100%的准入率,每个都有一个数据点支持——这在技术上没有错,但意味着专家如何作证有太多的确定性。相反,我们的最终设计将专家证词的每一个挑战可视化,让用户发现模式,并自己判断他们应该对这些模式有多确定。

设计模式#3:让用户完成拼图

机器学习可以做令人惊讶的事情——但它仍然不能解决所有问题,并且这个难题的一些部分最好交给人类。一种算法可能擅长寻找碎片,但对整体解决方案仍不确定。我们的设计应该为用户安排这些部分——并让他们自己完成拼图。

当涉及到人工智能尚未真正解决的高阶问题时,这个想法最有趣,比如解释因果。我们的上下文用户看到随着时间的推移影响特定公司的诉讼激增,并想知道是什么导致了这些激增。我们的设计将法律案件和新闻故事安排在平行的时间线上,邀请用户自己推断因果关系。在这里,用户可能会假设,涉及 Chipotle 的法律案件的激增可以用稍早一些的关于 Chipotle 和大肠杆菌的新闻标题来解释:

像这样的问题— 为什么会发生什么,接下来会发生什么,你应该怎么做— 很难解决,明确回答也有风险。但是这两个我们都不一定要做,至少不完全要做。通过建议性地布置算法找到的拼图,产品设计可以激发用户思考、充实和评估的想法——将人类置于循环中以从不完美的机器学习中提取价值。

最终想法

为不确定性而设计让我们能够解锁全新的产品,而机器学习对于传统设计来说可能不够准确。我提供了产品设计传达不确定性的三种方式:展示他们的作品,揭示个体数据点,让用户完成拼图。但是,随着机器学习的扩展,以及用户对不确定性的思考更加复杂道德和法规呼吁透明,我们揭示不确定性的设计解决方案的范围肯定会扩大。我很期待看到我们的成果。

机器学习和听力损失

原文:https://towardsdatascience.com/machine-learning-hearing-loss-d60dab084e3f?source=collection_archive---------34-----------------------

Liviu C.Unsplash 上的照片

关于机器学习如何使听力损失者受益的简要文献综述。

机器学习已经扩展到许多不同的领域和学科。尝试新的领域是成长和学习新事物的最好方式。以下是研究人员如何应用机器学习来改善聋人和重听人的生活的总结。

论文(按顺序)

所有这些论文都可以在没有任何大学赞助或付款的情况下获得。

  1. 为什么那些使用美国手语交流的人没有更好的辅助技术?
  2. 机器学习的语法面部表情识别
  3. 一种机器学习方法,用于为助听器调配处方
  4. 视听:聋人和重听人的声音检测

会说话的手套

Keith Kirkpatrick 的这篇文章介绍了聋人和重听人在与不懂手语的人交谈时遇到的问题。

机器人,自然语言处理,美国手语,可穿戴设备

解释问题

重听人依靠口译服务,无论是面对面的还是在线的,在医生办公室、法庭或咖啡店与听觉世界进行交流。然而,这些服务并不总是可用的,在线口译受到移动互联网问题的困扰:速度慢、不一致或不存在。

Franck V.Unsplash 上拍摄的照片

一个可能的解决方案

解决译员缺乏的一个办法是可以将美国手语翻译成英语的手套。通过嵌入的运动传感器,手套记录用户的运动,并将运动转化为正确的手势。可以使用几种不同的 ML 算法来找到正确的符号:K 均值、卷积神经网络(CNN)、递归神经网络(RNN)。

漫长的路要走

SignAloud 和 BrightSign 是这篇文章中重点提到的两家公司。BrightSign 被认为优于 SignAloud,因为用户可以录制自己版本的标志,以便更好地翻译。然而,这两种产品都达不到真正的解释,因为它们没有考虑面部表情。面部表情是美国手语的一个重要组成部分,如果不考虑面部表情,很多意思就会消失。这就是为什么你会看到美国手语翻译在为官员翻译时摘下面具。

佛朗哥·安东尼奥·乔瓦内拉在 Unsplash 上拍摄的照片

此外,像这样的手套在聋人群体中受到了负面的影响。聋人团体希望看到更多的聋人或重听人参与这些产品的开发,而不仅仅是测试。

检测符合语法的面部表情

巴西的研究人员开发了一个 ML 模型来检测巴西手语 Libras 中的语法面部表情。

计算机视觉,MLP,神经网络

照片由 Unsplash 上的 Anastasia Vityukova

问题是

面部表情是每一种手语的重要组成部分。同样的手势,但不同的面部表情可以把一个句子从陈述句变成疑问句,或者否定整个句子。不幸的是,大多数研究集中于检测特定的标志或预定义的句子。

这对实时自动翻译是一个巨大的障碍。

可能的解决方案

在这篇论文中,研究人员和聋人定义了九种不同的 gfe 供模型识别。他们在各种不同的句子中使用这些识别的 gfe 记录聋人,并使用这些数据训练多层感知器(MLP)。

结论

他们的模型结果喜忧参半。该模型能够很好地识别一些面部表情,但它无法识别 9 个 gfe 中的 4 个。作者确实做了两个观察。

  1. 识别 gfe 需要时间(时间序列)数据。(RNN>CNN)
  2. 不是所有的 gfe 都是一样的。一些需要深度信息,而另一些发现它很嘈杂。

这项研究是实现手语到口语实时翻译的又一个跳板。

助听器优化

来自韩国的研究人员使用国家声学实验室(nal)的数据来创建优化助听器验配过程的模型。

深度学习,人工神经网络,迁移学习

马克·佩顿Unsplash 上的照片

装配助听器

获得助听器的过程类似于获得眼镜。听力学家为患者播放一系列声音,询问他们听起来如何,然后相应地调整助听器。

这个过程得到了 NAL 助听器软件的帮助,该软件可以帮助找到正确的值。然而,这仍然是一个不完美的猜谜游戏。

有一个更好的起点意味着更少的调整,可以为重听人带来更好的生活质量。

输入和输出

患者的听力损失信息被用作神经网络(NN)的输入,助听器的插入增益是输出。

助听器配置有六种不同的频段。作者将听力损失信息(输入)编码为 252 位,并使用六种不同的频率作为输出。

结果

作者发现,神经网络模型能够在 1%的误差范围内预测每个频率的正确增益水平。

定制声音检测

华盛顿大学的学生开发了一个应用程序,使用 ML 来识别特定于用户环境的声音。

照片由 NeONBRANDUnsplash 上拍摄

在这篇短文中,学生们概述了目前存在的通用声音检测应用程序的问题。大多数时候,应用程序对于个人或环境来说并不是唯一的,这降低了声音检测的准确性。

为了解决这个问题,学生们开发了一个应用程序,允许用户记录他们环境中特有的声音,并根据这些声音训练定制模型。

结果是为每个聋人和重听人定制了一个声音检测系统。

机器学习和其他一切

[## 机器学习与自闭症

关于机器学习如何影响自闭症诊断和治疗的简要文献综述。

towardsdatascience.com](/what-is-machine-learning-doing-for-autism-6e86daa3b12a)

机器学习:隐藏的技术债务和解决方案

原文:https://towardsdatascience.com/machine-learning-hidden-technical-debts-and-solutions-407724248e44?source=collection_archive---------44-----------------------

埃尔努尔摄影站拍摄的照片

随着机器学习系统被广泛采用,解决各种行业(汽车、BFSI、娱乐、医疗、农业……)的复杂现实问题,随着时间的推移,改进和维护这些系统变得比开发和部署更加昂贵和困难。由于数据和其他特定 ML 问题的额外挑战,这些 ML 系统的长期维护比传统系统更加复杂[1]。在本文中,我们讨论了 ML 系统的一些隐藏的技术缺陷,下表总结了一些可能的缓解策略。

软件工程中的抽象是可维护系统的最佳实践之一。严格的抽象边界有助于表达给定软件组件的输入和输出的不变量和逻辑一致性。但是很难在 ML 系统中实施如此严格的抽象边界,因为系统的预期行为是使用数据学习的,并且几乎没有办法将抽象与数据的异常分开。[3]

纠缠

具体来说,假设我们有一个在模型中使用 f1,…,fn 特性的 ML 系统。因为特征分布的改变或添加新特征或删除现有特征改变了所有特征的重要性权重以及目标输出。这被称为改变任何东西都会改变一切(CACE) 现象,不仅适用于输入特征,还适用于超参数、学习设置、采样方法、收敛阈值、数据选择以及基本上所有其他可能的调整[2]。

为了减轻这种情况,一种可能的解决方案是在预测变化发生时检测预测变化并诊断变化的原因,这种预测变化的一个原因可能是特征分布(漂移)的变化,这可以使用类似于 TensorFlow 数据验证 的工具来发现,该工具支持模式偏斜、特征偏斜和分布偏斜检测。例如,如下图所示,通过可视化特征值的分布,我们可以捕捉到特征分布的这些问题。

来自 TensorFlow 扩展数据可视化指南的图像显示了特征分布

未充分利用的数据依赖关系

这些依赖是由于遗留功能、ε功能、相关功能和捆绑功能造成的。

传统特性是早期模型开发中包含的特性,随着时间的推移,这些特性会因新特性而变得多余。

捆绑功能,当一组功能被评估并发现有益时,由于时间压力或类似的影响,在没有仔细调查所有功能的情况下,添加了捆绑中的所有功能,以提高衡量标准。

ε特征是包含在模型中的特征,因为它们在准确性或其他度量方面提供了非常小的增益。

相关特征是与其他特征具有高度相关性的特征。

为了减轻这些未充分利用的依赖性,人们可以依靠留一特征评估、 主成分分析、套索 规则化自动编码器 ,使用类似【SHAP的可解释工具,或者使用 提升树估计器

例如,SHAP 汇总图可以帮助我们确定特征的重要性以及特征值分布及其对预测的影响。下图显示了波士顿房价数据集的增强回归树模型的汇总图。

1.LSTAT 是影响模型预测的最重要的特征,并且较低的特征值正有助于预测,而较高的特征值负有助于预测。

2.CHAS 和 ZN 特征没有预测能力,可以安全地从模型中移除。

SHAP python 包还支持单个预测解释图、依赖图等。这也可以用于诊断预测变化。

图片来自 SHAP Git 仓库,Xgboost Boston 模型的汇总图

反馈回路

这种债务主要存在于活的 ML 系统中,如果 ML 系统随着时间的推移得到更新,这通常最终会影响它们自己的行为。这些环可以以许多不同的形式(直接或间接)存在,并且不容易被检测到。

例如,推荐系统经常根据用户活动持续推荐来自相似演员、流派等的项目。这种信念被放大或强化的现象被称为回音室。常见的缓解策略是通过收集显式反馈,包括搜索行为等,使这些闭环推荐系统开环。

反模式

ML 系统中的实际学习或推理代码只占整个系统代码的一小部分,如下图所示,在 ML 系统中出现许多反模式是很常见的,应该避免。

真实世界 ML 系统的构建模块。图片来自 MLOps 解决方案

  1. 粘合代码:这种反模式是由于支持代码使数据适合使用特定的 ML 模型/库而产生的,这可以通过使用标准预处理库来减轻,如tensor flow Transform,它使用 Apache Beam 进行分布式计算,使用 Apache Arrow 进行矢量化 NumPy
  2. ****管道丛林:随着新的数据源被增量地添加到模型中,这导致代码充满了连接、采样步骤等。这可以通过一种全新的方法减轻,即在模型开发冻结后从零开始开发管道代码,或者更全面地考虑数据收集和特征提取。
  3. ****死的实验代码路径:作为胶合代码或管道丛林的结果,很多时候实验是通过实现实验代码路径来执行的,然而随着时间的推移,这些代码路径难以保持向后兼容性。通常的标准做法是审查并删除这些代码路径,以减轻这种债务。

配置债务

由于机器学习系统每一步的可配置选项的范围,如使用哪些功能、如何选择数据、特定于模型的参数、预处理或后处理、模型部署等,这种债务可能会累积。这些配置错误可能代价高昂,导致严重的时间损失、计算资源浪费或生产问题。

为了减轻的配置负担,通常的做法是将与模型、超参数搜索、预处理或后处理相关的参数保存在 YAML 文件、模块化模板、Jinja2 模板、基础设施代码等中。

在这篇博客中,我们看到了一些 ML 方面,如模型纠缠、数据(发现、来源、管理、版本),以及这些数据和 ML 特定方面如何导致比传统系统更多的隐藏技术债务。此外,我们如何使用可视化、端到端机器学习框架(如 TensorFlow Extended )和最佳软件工程实践来缓解这些问题。在 ML 系统中存在更多的 ML 债务,涉及服务、监控、测试、再现性、过程管理等。我们将在以后的文章中讨论它们的缓解策略。

参考

  1. https://papers . nips . cc/paper/5656-hidden-technical-debt-in-machine-learning-systems . pdf
  2. https://www . Microsoft . com/en-us/research/uploads/prod/2019/03/amershi-icse-2019 _ Software _ Engineering _ for _ Machine _ learning . pdf
  3. https://storage . Google APIs . com/pub-tools-public-publication-data/pdf/43146 . pdf
  4. https://cloud . Google . com/solutions/machine-learning/mlops-continuous-delivery-and-automation-pipeline-in-machine-learning
  5. https://christophm.github.io/interpretable-ml-book/
  6. https://www . ka ggle . com/reisel/how-to-handle-correlated-features
  7. https://matthewmcateer . me/blog/machine-learning-technical-debt/

机器学习:它是如何工作的;更重要的是,它为什么会起作用?

原文:https://towardsdatascience.com/machine-learning-how-does-it-work-and-more-importantly-why-does-it-work-7876f8d80277?source=collection_archive---------22-----------------------

ML 的本质与 Hoeffding 不等式

早在 2017 年,我被介绍到一个很酷的世界。这个词本身就非常有趣。我很感兴趣,想知道更多。所以,就像任何正常人一样,我打开浏览器,输入“什么是机器学习?

作者图片

这个维恩图出现了。以及其他有共同后缀的词:监督学习,非监督学习,强化学习,深度学习。接下来是复杂程度递增的其他词:数据、分类、回归、模型、聚类、集成、支持向量、神经网络等,等等。

在花了将近一年的时间试图理解所有这些术语的含义,将获得的知识转换成工作代码,并利用这些代码解决一些现实世界的问题之后,我终于明白了一些重要的事情。

塞巴斯蒂安·加布里埃尔Unsplash 上拍摄的照片

机器学习太牛逼了!

但是为什么会起作用呢?

太傻了。这是我一开始就应该问的问题。一年后不会。但是你知道..亡羊捕牢,未为晚也。

当我在网上搜索答案时,我没有找到任何相关的内容。太奇怪了。互联网应该有一切的答案,对不对?

这让我很激动。我想要答案。我花了一段时间才找到它。这篇文章,我的第一篇文章,就是这个发现的结果。现在互联网对我的一个问题有了答案。

什么?

机器学习是一种工具,你可以使用它来学习生成数据的过程背后的模型 。您获取流程创建的数据,并使用它来建模流程。好处?如果您对流程建模,您可以通过计算模型输出来预测流程输出。

以社交媒体为例。每次你使用你的社交媒体账户,你都会以帖子、浏览、喜欢、不喜欢、评论等形式创建数据。你的社交媒体活动是一个过程,这个过程创造了数据。您创建的数据用于模拟您的兴趣,以便您可以在时间线中看到更多相关内容。

怎么会?

让我们用一个简单假设的例子来理解 ML 是如何工作的。

马尔科·塞斯奇在 Unsplash 上的照片

一个场景

你是十四世纪的自然哲学家。你从不同的高度(可能是从一个人造奇迹的不同楼层)扔下金属球,记录它到达地面的时间。因为你是一个非常酷的人,你使用机器学习来模拟这个过程。

您记录了高度值为 1 米、2 米、3 米…100 米的数据,并使用一些古老的绘图技术绘制了这些数据。(笛卡尔坐标系是一个世纪后发明的)

作者图片

要求

要让机器学习发挥作用,你需要三个先决条件:

  1. 数据。它通常被称为样本。你记录球体从不同高度落下到达地面的时间。另一方面,总体是样本的通用集合,即球体从所有高度到达地面所用时间的数据。
  2. 数据中的模式。它通常被称为目标函数。这个目标函数定义了总体。ML 的全部意义在于得到一个逼近目标方程的数学方程。
  3. 这种模式无法用数学方法确定。因为如果可以钉住,就不会要求 ML(不考虑测量带来的各种误差)。

在我们的例子中,您已经记录了数据,并且它有一个模式。因为你来自十四世纪,你不会知道基本的运动学。所以你不能用数学方法把模式钉在数据后面。

现在请不要认为一个十四世纪的人怎么会知道 ML 而不知道基础物理。这都是假设,正如我所说,你是一个非常酷的自然哲学家。

最后,您开始将球体到达地面的时间建模为其下落高度的函数。你用你所有的 ML 知识,为上面的过程做了一个模型。

为什么?

你做的任何模型都会有样本内误差:E(in)。这是当你试图在你用来对过程建模的样本中进行预测时所得到的误差。在我们的示例中,当您试图预测 1 到 100 米范围内的高度时,这将是模型中的误差。

如果模型在您使用的样本之外运行,那么它就可以工作。我们姑且称之为 E(out)。在我们的示例中,当您试图预测超过 100 米的高度或非整数高度(如 1.5 米)时,这将是模型的错误

回想一下,ML 的全部目的是得到一个逼近目标函数的数学模型。

对于理想模型,E(in) = E(out) = 0

同样,如果事情是理想的,我们就不需要 ML。为了量化 E(in)和 E(out)之间的变化,我们引入了一个新术语,称为容差(δ)。我们使用公差来确定我们的模型性能。如果样本内和样本外误差的绝对变化在容差范围内,我们宣布您使用的建模方法有效。

对于一个好的模型,|E(in) — E(out)| ≤ δ

不等式的轻微重新定位可以用来定义一个坏的模型

对于坏模型,|E(in) — E(out)| > δ

如果一个模型是坏的,那么你使用的机器学习技术不起作用

赫夫丁不等式

赫夫丁不等式是概率论中的一个概念。它给出了样本估计值和样本期望值之间的最大偏差。为了简化上面的陈述,我们来看一个具体的例子,均值(average)。

P[ |μ — ν| > δ ] ≤ 2exp(-2δ N)

有很多希腊字母。让我们一个一个地研究它们

  1. μ是预期值。这是人口的平均值
  2. ν是估计值。这是样本的平均值
  3. δ是公差水平
  4. exp 是指数函数
  5. n 是样本的大小(即数据中记录的数量)
  6. p[某物]是某事发生的概率

我们可以把这个概念推广到我们的问题上。样本内误差 E(in)是样本的估计值。样本外误差 E(out)是样本的期望值。将赫夫丁不等式应用于这种情况,我们得到:

P[ |E(in) — E(out)| > δ ] ≤ 2exp(-2δ N)

考虑到模型复杂性(M ),我们可以将上述等式概括为:

≈ P[ ML 不工作]≤2 MEX(-2δN)

耐受性的影响

作者图片

对于一个合适的近似值,公差值应该非常小。随着你降低你的耐受水平,ML 在该δ失败的概率增加。需要注意的是,由于这一事实,δ = 0 ( E(in) = E(out) = 0)的理想模型是无法实现的。

样本量的影响

作者图片

随着样本量的增加,ML 失败的概率降低。因此,数据中的观察次数越多越好。

模型复杂性的影响

模型复杂度与概率值成线性关系。并且概率值总是小于或等于 1。因此,模型的复杂性会极大地影响 ML 的成功。如果复杂性增加,成功的概率就会降低。

成功的建模方法背后的想法是平衡模型的复杂性和样本大小,因为容差总是保持较低(这就是过拟合和欠拟合等术语发挥作用的地方)

ML 为什么起作用→ML 什么时候起作用

又是那个场景!

你,作为一个十四世纪的自然哲学家,已经成功地利用机器学习对一个球体从一定高度掉落到地面所需的时间进行了建模。

为什么你认为这种方法行得通吗?

您使用的 ML 方法之所以有效,是因为当您尝试对流程进行建模时,您平衡了模型复杂性和您拥有的样本大小(具有合理的容差),从而将失败的可能性降至最低。

如果你想建立一个复杂的模型,那么你需要一个大的样本量来获得良好的泛化能力。所以,

你平衡了模型复杂度和样本量,ML 就起作用了。

照片由马库斯·斯皮斯克Unsplash 拍摄

ML 背后的概念已经存在了 60 多年(感知器是在 50 年代发明的)。但是最近几年,这个领域有了巨大的发展。

你会经常听到“大数据”和“深度学习”这些术语。虽然前者意味着数据集的一般样本量急剧增加,但后者证明了当今建模流程的复杂性可能会增加。

希望这篇文章对你有所帮助。如果你已经达到这一点,感谢花 8 分钟左右的时间来阅读我的漫谈!

【机器学习】如何做特征选择

原文:https://towardsdatascience.com/machine-learning-how-to-do-the-feature-selection-2de56182cd9b?source=collection_archive---------26-----------------------

成为一名数据科学家。

你的第一份数据科学相关工作的一个重要问题

当我参加一个数据科学相关工作的面试时,面试官问了我以下问题。事后我在面试的时候也问了应聘者同样的问题:给定一个大型数据集(1000 多列,100000 行(记录)),你会如何选择有用的特征来建立(监督)模型?

这是一个很好的问题,可以区分你的数据科学知识是学生水平还是专业水平。当你是一名学生时,你从一个美丽而干净的数据集中学习算法。然而,在商业世界中,数据科学家在数据清洗方面投入了大量精力,以建立机器学习模型。

回到我们的问题:

给定一个大型数据集(超过 1000 列,10000 行(记录)),如何选择有用的特征来构建(监督)模型?

事实上,这个问题没有绝对的答案,不过是测试你的逻辑思维和解释能力。在这篇文章中,我将分享一些方法(特性选择)来处理它。

Kaggle 笔记本上传到这里,这里我使用的数据集是保诚人寿承保数据:

[## 功能选择笔记本

使用 Kaggle 笔记本探索和运行机器学习代码|使用来自保诚人寿保险评估的数据

www.kaggle.com](https://www.kaggle.com/kkhuiaa/feature-selection-notebook)

此任务旨在预测人寿保险投保人的风险水平(承保)。关于特性选择的更多实现,您也可以查看 Scikit-learn 文章。

首先,我们读取数据:

作者图片

在这里,我将做一些简单的数据清理。大多数机器学习模型实现不接受字符串输入,因此我们必须将它们转换成数值。由于我们的目标是有序目标(即监督学习),通过基本的 OneHotEncoder 转换分类变量会遭受“维数灾难”(通常在模型训练中也需要更多时间)。

相反,我们对分类列所做的如下:基于它的分类值,我们计算 Y 目标的相应平均值(通过“GroupBy”)并对它进行排序,从 0 到该列的唯一分类值的数量减 1。这种映射可用于测试数据或以后的生产。

然后,我们按照标准程序填写缺失值:

作者图片

0.足球队选拔的类比

假设你有 200 名足球运动员,你想选择其中的 11 人组成最好的足球队。你会如何选择他们?

unsplash 照片,由 Alora Griffiths 上传

1.无监督方法

在足球运动员选择的类比中,无监督方法评估每个运动员的基本信息,如身高、身体质量指数、年龄和其他健康指标。这些都不是足球特有的(无人监管),但绝大多数优秀的足球运动员都应该有很好的身体基础。

  • 删除丢失率高的列
    第一种也是最简单的方法是在无监督的方法中删除列。我们可以删除缺少太多值的列。
(59381, 127)
(59381, 126)
  • 删除差异小的列
    另一种方法是删除差异太小的列,因为这些列通常提供的信息很少。
number of columns after dropping by variance threshold: 16
  • PCA
    PCA 是一种更高级的执行特征选择的方式。主要优点是变换后的特征现在是独立的;然而,转换后的特征很难解释。关于 Scikit-learn 的 PCA 实现,您可以查看这篇文章

2.监督方法

更复杂的方法是通过监督学习来实现。回到我们对足球队选择的类比,我们分两轮进行:

在第一轮比赛中,我们对每个球员的足球技能(监督下)进行评估,如点球,射门,短传能力,并进行排名。假设我们现在可以从 200 名选手中选出前 50 名选手。

第二轮,既然要在 50 个玩家中找出 11 个玩家的最佳组合,就需要评估这 50 个玩家会如何合作。我们将最终找到最好的 11 名球员。(为什么不直接做第二轮?运行每个迭代需要很多时间,所以我们需要在第一轮进行初步测试。)

从技术上讲,第一轮是“按模型选择特征”,第二轮是“递归特征消除”(RFE) 。现在让我们回到机器学习和编码。

  • 基于模型的特征选择 一些 ML 模型被设计用于特征选择,例如基于 L1 的线性回归和 Ext remely Ra 随机化 (Extra-trees model)。与 L2 正则化相比,L1 正则化倾向于将不重要特征的参数强制为零。(知道为什么吗?)极度随机化的树随机地分裂叶子(不是通过信息增益或熵)。重要的特征应该仍然比不重要的特征更重要(通过基于杂质的特征重要性来测量)。

    我们用三个模型来评估它:

CPU times: user 15.9 s, sys: 271 ms, total: 16.2 s
Wall time: 14.3 s========== LogisticRegression ==========
Accuracy in training: 0.4138598854833277
Accuracy in valid: 0.41020945163666983
Show top 10 important features:

作者图片

========== ExtraTreesClassifier ==========
Accuracy in training: 0.3467497473896935
Accuracy in valid: 0.3467213977476055
Show top 10 important features:

作者图片

========== RandomForestClassifier ==========
Accuracy in training: 0.3473391714381947
Accuracy in valid: 0.34581622987053995
Show top 10 important features:

作者图片

我们还为每个模型绘制了模型重要性排名:

作者图片

由于基于 L1 的逻辑回归具有最高的准确性,因此我们将仅通过逻辑回归选择(从图中)前 60 个特征:

selected _ model = ' logistic regression '
number _ of _ features = 60
selected _ features _ by _ model = importance _ fatures _ sorted _ all[importance _ fatures _ sorted _ all[' model ']= = selected _ model]。索引[:特征数量]。tolist()

  • 递归特征消除(RFE)
    第二部分是选择最佳特征组合。我们通过“递归特征消除”(RFE) 来实现。我们不是构建一个模型,而是构建 n 个模型(其中 n =特征的数量)。在第一次迭代中,我们通过所有 60 个特征来训练模型,并计算交叉验证准确性和所有列的特征重要性。然后我们去掉最不重要的特征,所以我们现在有 59 个特征。基于这 59 个特征,我们重复上述过程,并且我们在最后一个单个特征处结束。这种方法需要时间,但会给你一个可靠的特征重要性排序。如果时间不允许用于大型数据集,可以考虑在每次迭代中采样或丢弃更多要素。

作者图片

CPU times: user 7min 2s, sys: 334 ms, total: 7min 2s
Wall time: 26min 32s

如你所见,随着更多特征的训练,验证准确度将最终饱和(大约 0.475)。我们现在可以查看我们的功能重要性排名:

作者图片

同样,没有黄金法则来执行特征选择。在生产的商业世界中,我们必须平衡硬件能力、所需时间、模型的稳定性和模型性能。找到最佳的列组合后,我们现在可以选择最佳的超参数集。

机器学习——如何评价你的模型?

原文:https://towardsdatascience.com/machine-learning-how-to-evaluate-your-model-1dabbdc849a4?source=collection_archive---------29-----------------------

机器学习算法的基本评价指标和方法

就在最近我讲了一些基本的机器学习算法,即 K 近邻线性和多项式回归逻辑回归。在所有这些文章中,我们使用了来自 Udacity 的流行汽车燃油经济性数据集,并对汽车进行了某种分类,即按照车辆“尺寸”分类或根据驱动轮分类。此外,每次我们计算训练和测试数据的基本模型精度,并试图将我们感兴趣的汽车放入模型中以检查其性能。

这一切都很好,但有时人们可能会面临一个数据集,其中的类分布不是很好,就像这个例子中的 3920 辆不同的汽车。这会导致问题吗?在这样的数据集上,一个基本的精度评估就足够了吗?

Kaggle 上可以找到这样一个数据集的主要例子。这是流行的信用卡欺诈数据集。是什么让这个数据集与众不同?与有效交易相比,信用卡欺诈的数量非常少。更多关于后者。🙂

布鲁斯·马尔斯在 Unsplash 上拍摄的照片

在本文中,我将使用这个数据集来解释一些最流行的机器学习模型的评估指标。

文章的结构:

  • 介绍
  • 混淆矩阵
  • 数据集加载和描述
  • 模型描述
  • 模型评估
  • 结论

享受阅读吧!

介绍

类别不平衡是分类数据中非常普遍的现象。它实际上意味着什么?通常,我们会得到一些二进制或多类数据,其中一个类相对于其他一个或多个类处于少数。除了上面提到的信用卡欺诈例子,常见的例子是健康问题、交通事故、航空事故或任何其他事件,在这些事件中,我们有非常负面的结果,这种情况很少发生,与大量正面结果相反,反之亦然。

如果衡量一个旨在对这类数据进行分类的模型的准确性,会发生什么情况?

即使模型很糟糕,我们也能得到很高的精确度。为什么会这样呢?

我们举个简单的例子。我们想要一个能预测我们旅途中轮胎是否漏气的模型。还记得你轮胎瘪了的时候吗?可能,不要或者你从来没有过。这种事情很少发生。因此,如果模型必须预测我们在旅途中不会有爆胎,在不知道任何可能导致爆胎的因素或特征的情况下,如果我们将模型设置为总是预测“最频繁”的结果,即我们永远不会有爆胎,则模型可以正确预测大多数结果。

这种模型被称为虚拟分类器。它们完全独立于训练数据特征。Scikit-Learn 有一个 DummyClassifier 类(我们将在后面使用)。

混淆矩阵

在我们继续举例之前,我想提一下模型评估过程中的一个重要术语。混乱矩阵。它极大地帮助我们将模型的结果可视化。让我们来看看爆胎问题的混淆矩阵。想想爆胎是积极的结果时的情况(即使不是🙂).我知道这有点令人困惑,但就机器学习算法而言,零(0)标签代表负面结果,而一(1)标签代表正面结果。在我们的例子中,大多数结果(0)是当我们在旅途中没有一个轮胎漏气时。虽然我们很少会有一个单位,这是一个标签的结果。

大概这就是为什么它被称为“混乱矩阵”🙂。玩笑归玩笑,解释如下。

二元混淆矩阵的简单可视化

绿色方块代表我们的模型预测正确结果的情况,真正(TP)模型预测我们将得到一个漏气轮胎,我们实际上有一个漏气轮胎,真负(TN)模型预测没有漏气轮胎,我们实际上没有漏气轮胎。

红色方块表示模型预测错误的情况,或者是假阴性(FN ),即模型预测轮胎不漏气,但实际上我们有一个漏气的轮胎,或者是假阳性(FP ),即模型预测轮胎漏气(阳性结果),但我们没有漏气的轮胎。

数据集加载和描述

和往常一样,首先我们导入依赖项。

接下来,我们加载数据集。这一次,我们使用一个不平衡的数据集,来自 Kaggle 。该数据集包含有关信用卡交易的数据,其中大多数是合法的(284 315),而极少数是欺诈的(492)。V1、V2、V3、…、V28 列是通过五氯苯甲醚获得的主要成分。(来自源站点的描述)主要组件将被用作我们的线性模型的特征。

信用卡交易数据集的条形图(按作者)

此外,我们将把数据分成训练样本和测试样本。

模型描述

我们将使用逻辑回归模型。要阅读更多关于线性回归的内容,请查看本文。

为了创建模型,我们需要从 sklearn.linear_model 导入 LogisticRegression 类。

该模型预测积极和消极的结果。

array([0, 1], dtype=int64)

让我们通过将策略设置为“most _ frequent”来创建虚拟分类器。这意味着分类器将基于训练数据中最常出现的结果来预测结果。我们使用 sklearn.dummy 中的 DummyClassifier 类。

array([0], dtype=int64)

正如所料,虚拟分类器根据最频繁出现的事件来预测结果,在这种情况下是零,这意味着这是一个有效的交易。

模型评估

混淆矩阵

我们已经定义了什么是混淆矩阵,现在让我们为我们的两个模型计算它。首先,我们需要从 sklearn-metrics 导入混淆矩阵类。首先,我们将计算逻辑回归模型的矩阵。

array([[71072,    10],        

       [   40,    80]], dtype=int64)

根据结果,逻辑回归模型预测:

真否定(TN) = 71 072

误报(FP) = 10

假阴性(FN) = 40

真阳性(TP) = 80

让我们看看虚拟分类器的矩阵是什么样的。

array([[71082,     0],        
       [  120,     0]], dtype=int64)

重要的是要注意,矩阵的对角线显示了成功的预测(“当模型预测正确时”),以及真正的否定和真正的肯定。虚拟分类器将所有情况预测为阴性,即零,这就是为什么虚拟分类器的混淆矩阵显示 71 082 个真阴性和 120 个假阴性,这意味着它将所有交易预测为有效。

另一方面,逻辑回归分类器预测了 71 072 个真阴性(正确预测有效交易)、1 0 个假阳性(预测欺诈,但实际有效)、40 个假阴性(预测有效,但实际欺诈)和 80 个真阳性(正确预测欺诈)。

既然我们已经讨论了模型的可能结果,我们可以开始计算指标了。

准确(性)

指标列表中的第一项是模型准确性,这可能是衡量预测性能时最基本和最常用的指标。

准确度表示正确(真实)预测值与所有结果之间的比率,或者换句话说,真阴性和真阳性与所有结果之间的比率。这意味着,我们可以对矩阵的对角线求和,然后除以所有四个结果的和。

在这里,我们可以清楚地看到,为什么在评估不平衡的数据集时,准确性会给出错误的信心。使用我们的逻辑回归模型,我们仅获得比虚拟分类器稍好的准确性。这清楚地表明,其他评估指标是必要的,尤其是在处理类之间有很大差异的数据时。

分类误差

分类误差可以被视为准确性的对立面,它被计算为偏离对角线的计数(假阴性和假阳性)的总和,也是模型预测错误的结果的数量。

让我们为我们的模型计算一下。

同样,这两个指标看起来都很好,即使对于我们的虚拟分类器也是如此。但是事情应该很快会改变。

回忆

召回也称为真阳性率、灵敏度或检测概率,因为它计算真阳性结果(当模型预测到欺诈交易时)与真阳性和假阴性之和(假阴性结果是当模型预测没有欺诈,但实际交易是欺诈时)之间的比率。

当具有高数量的真阳性和避免假阴性非常重要时,这个度量是重要的,一个主要的例子是检测一些医学问题的算法。或者甚至我们的信用卡例子是好的,如果我们说想要确定我们的模型正确地预测所有的欺诈交易,而且避免将欺诈归类为有效交易。基本上,回忆给我们一个想法****实际阳性的比例被正确预测

让我们计算两个模型的召回率。

精确

Precision 计算真阳性(当模型预测到欺诈交易时)与真阳性和假阳性之和(当模型预测到实际为欺诈的有效交易时)之间的比率。简单地说,它表明了我们的模型在预测正面类别(欺诈性银行交易或爆胎)方面有多“精确”。

Precision 计算真阳性(当模型预测到欺诈交易时)与真阳性和假阳性之和(当模型预测到实际为欺诈的有效交易时)之间的比率。简单地说,它表明了我们的模型在预测正面类别(欺诈性银行交易或爆胎)方面有多“精确”。

首先,我们需要解决的是,在虚拟分类器的情况下,我们得到“零除”错误,因为对于虚拟模型,真阳性和假阳性的总和(混淆矩阵的右栏)都是零。

其次,我们的逻辑回归模型给出了 88.89 %的精度值,这非常好,因为这意味着预测的欺诈交易中有 88.89%确实是欺诈。

假阳性率(FPR)

假阳性率或有时称为特异性,表示假阳性值(当模型预测实际上是欺诈的有效交易时的情况)与所有真阴性(当模型预测有效交易时的情况,并且它确实是有效交易)和假阳性的总和之间的比率。此指标有助于我们确定错误分类的负面实例的比例,换句话说,有多少有效交易被分类为欺诈。

****

同样,由于零阳性预测,我们的虚拟模型产生零假阳性率。而我们的逻辑回归模型的 FPR 为 0.00014,这意味着只有 0.014%的有效交易被该模型归类为欺诈。

F1 分数(F 分数)

在评估机器学习算法时,另一个非常受欢迎的指标是 F1 分数。这是根据召回率和精确度计算的指标。它被计算为两个值的调和平均值。对于两个数字的特殊情况,调和平均值计算如下:

此外,还有一个更一般形式的等式,它允许用户修改精度召回的权重:

β参数允许用户强调召回率或精确度的影响,如下所示:

给予 Precision 更大的权重: β = 0.5 (模型性能受误报的影响更大——欺诈交易被预测为有效)

给予 Recall 更多权重: β = 2 (模型性能受假阴性影响更大——有效交易被预测为欺诈)

让我们计算一下这两款车型的 F1 分数。

同样,我们可以观察到一个合适的模型,如逻辑回归模型,比虚拟模型产生更好的结果。

奖励内容:sklearn —分类 _ 报告

在文章的最后,我想指出 sklearn 提供了一个 classification_report 函数,它可以同时计算召回率、精确度和 F1 分数指标。此外,它还为我们提供了标记结果案例的选项。让我们看看如何在我们的案例中使用它。

支持 ”列显示为所需标签的结果数。在我们的测试数据中,有 71 082 笔有效交易和 120 笔欺诈交易。

结论

在本文中,我介绍了机器学习算法的一些基本评估指标和方法。此外,我们看到了当我们有一个不平衡的数据集时,准确性指标有时会非常误导人。在这种情况下,我建议使用这里介绍的其他指标。

作为奖励,我添加了 sklearn — classification_report 函数,它提供了一种快速简单的方法来评估我们的算法。

请随时查看我的 github 页面上的 Jupyter 笔记本

我希望这篇文章是清楚和有帮助的。关于这篇文章或我的工作的任何问题或建议,请随时通过 LinkedIn 联系我。

查看我在介质上的其他文章。

感谢您花时间阅读我的作品,干杯!🙂

posted @ 2024-10-15 13:41  绝不原创的飞龙  阅读(128)  评论(0)    收藏  举报