TowardsDataScience-博客中文翻译-2021-十六-

龙哥盟 / 2024-10-22 / 原文

TowardsDataScience 博客中文翻译 2021(十六)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

阿拉伯语自然语言处理:独特的挑战及其解决方案

原文:https://towardsdatascience.com/arabic-nlp-unique-challenges-and-their-solutions-d99e8a87893d?source=collection_archive---------6-----------------------

使用 camel-tools Python 包为机器学习预处理阿拉伯文本

理查德·佩格林的授权图片

在这篇文章中,我提供了一个简明扼要的概述,介绍了在 NLP 项目中使用阿拉伯文本所面临的挑战,以及克服这些挑战的可用工具。我非常依赖于 NYU 阿布扎比骆驼实验室开发的骆驼工具(camel-tools)和 Python 包(Python package),以及由主任 Nizar Habash 博士(T7)主持的精彩网络研讨会。为他们在这一领域所做的开创性工作以及让公众可以使用他们的工具而大声欢呼吧!

挑战

在 NLP 项目中使用阿拉伯文本面临(至少)5 个独特的挑战:

  1. 字符的形式和单词的拼写可以根据它们的上下文而变化(奇特的术语:拼写歧义)
  2. 同一个动词可以有数千种不同的形式(字面上的意思)
  3. 阿拉伯语有许多方言,它们之间有很大的差异
  4. 由于阿拉伯语是一种语音语言(你写的就是你说的),当用方言阿拉伯语写作时,可以有不同的方式来写同一个单词,对此没有一致同意的标准(拼写不一致)。

阿拉伯语的这四个不同特征都有助于数据稀疏。因为有许多不同的单词形式、潜在的不同拼写以及大量的方言,最终可能会有一个 NLP 词汇表达到数百万个单词。这并不是夸大其词:阿拉伯语中的一个动词可以有多达 5400 种形式。)相比之下,英文最多有 6 篇,中文只有 1 篇。

解决方法

但是不要害怕!当你被困在资源匮乏的语言的沙漠中,而你的管道停留在一些液体代码上,让你继续前进的时候…会出现一只神奇的、用户友好的骆驼**来帮助你:

图片经由https://giphy.com/gifs/flaticons-xsWJYMcYexVQJbHzLS

pip install camel-tools

**我们将把对这个方案的公然自我东方化名称的后殖民评论留到下一天,好吗?

下面我将分享我使用 camel-tools 软件包预处理我的阿拉伯文本和处理阿拉伯语言带来的独特挑战的步骤。

注意:我假设你已经完成了所有基本的、通用的 NLP 预处理,比如删除重复字符、停用词、表情符号、标签、数字,以及任何 NLP 项目中的其他最佳实践数据清理任务。下面提到的 Github repo 包含了一个完整的阿拉伯停用词列表*,它解释了前面提到的拼写歧义*。重要提示:确保将单词“يا”添加到文件中,因为这个词目前不包括在内,而且是一个非常常见的停用词。

注意,NLTK 还包含一个阿拉伯停用词库,但是这个集合忽略了许多常见的拼写不一致。

https://github.com/mohataher/arabic-stop-words

好了,现在让我们开始吧!

第一步:去分化

第一步是通过删除文本的附加符号来减少一些严重的数据稀疏。音调符号是位于阿拉伯文本字母上方或下方的符号(在某些情况下相当于英语中的元音),即下图中的蓝色标记。

资料来源:en.wikipedia.org

根据上下文,同一个单词可能有不同的发音符号,因此通常的做法是删除这些符号以减少数据稀疏。

从技术上讲,这实际上产生了一个新的问题,因为同一个词根可能有完全不同的意思,这取决于你给它的音调符号……但是我们将在第 4 步处理这个问题。

步骤 2:减少拼写歧义

为了解决各种方言中常见的拼写不一致问题(因为一般来说阿拉伯语口语和书面语之间的差距),下一步是减少拼写歧义。具体来说, camel-tools 通过从特定字母(teh-marbuta 中的点和 alef 中的 hamza)中移除特定符号来实现这一点。

第三步:简单单词标记化

下一步只是一个简单的单词分词器。我们需要这样做,以便能够将我们的文本输入到下一步的函数中。

步骤 4:形态歧义消除

这就是事情变得有趣的地方。还记得我在第一步结束时说过,去掉音调符号实际上会产生一个新问题吗?我们现在只有字根,但从技术上讲,我们无法知道它可能是众多不同单词中的哪一个。例如,下面的单词可能意味着:'和我们的合同/项链/精神病或'',他强调我们【T3]',这取决于使用的发音符号、上下文和它所用的方言。

وبعقدنا

那么…我们应该选择这个单词的哪种形式呢?

camel-tools 软件包带有一个漂亮的“词法分析器”,简而言之,它将你输入的任何单词与一个词法数据库(它带有一个内置的)进行比较,并输出该单词可能的形式和含义的完整分析,包括词条、词性、英语翻译(如果有的话)等。

下面我们对单词'وبعقدنا'.进行一个词法分析

我在下面包含了输出的一部分;这些只是它返回的 20 多个分析中的前 3 个。请注意,它还通过恢复音调符号来“消除”单词的歧义。

{'diac': 'وَبِعُقَدُنا', 'lex': 'عُقْدَة_1', 'bw': 'وَ/PART+بِ/PREP+عُقَد/NOUN+ُ/CASE_DEF_NOM+نا/POSS_PRON_1P', 'gloss': '[part.]_+_by;with+complexes+our', 'pos': 'noun', 'prc3': '0', 'prc2': 'wa_part', 'prc1': 'bi_prep', 'prc0': '0', 'per': 'na', 'asp': 'na', 'vox': 'na', 'mod': 'na', 'stt': 'c', 'cas': 'n', 'enc0': '1p_poss', 'rat': 'i', 'source': 'lex', 'form_gen': 'm', 'form_num': 's', 'pattern': 'وَبِ1ُ2َ3ُنا', 'root': 'ع.ق.د', 'catib6': 'PRT+PRT+NOM+NOM', 'ud': 'PART+ADP+NOUN+PRON', 'd1seg': 'وَبِعُقَدُنا', 'd1tok': 'وَ+_بِعُقَدُنا', 'atbseg': 'وَ+_بِ+_عُقَدُ_+نا', 'd3seg': 'وَ+_بِ+_عُقَدُ_+نا', 'd2seg': 'وَ+_بِ+_عُقَدُنا', 'd2tok': 'وَ+_بِ+_عُقَدُنا', 'atbtok': 'وَ+_بِ+_عُقَدُ_+نا', 'd3tok': 'وَ+_بِ+_عُقَدُ_+نا', 'bwtok': 'وَ+_بِ+_عُقَد_+ُ_+نا', 'pos_lex_logprob': -4.923429, 'caphi': 'w_a_b_i_3_u_q_a_d_u_n_aa', 'pos_logprob': -0.4344233, 'gen': 'f', 'lex_logprob': -4.923429, 'num': 'p', 'stem': 'عُقَد', 'stemgloss': 'complexes', 'stemcat': 'N'} 

{'diac': 'وَبِعُقَدنا', 'lex': 'عُقْدَة_1', 'bw': 'وَ/PART+بِ/PREP+عُقَد/NOUN+نا/POSS_PRON_1P', 'gloss': '[part.]_+_by;with+complexes+our', 'pos': 'noun', 'prc3': '0', 'prc2': 'wa_part', 'prc1': 'bi_prep', 'prc0': '0', 'per': 'na', 'asp': 'na', 'vox': 'na', 'mod': 'na', 'stt': 'c', 'cas': 'u', 'enc0': '1p_poss', 'rat': 'i', 'source': 'lex', 'form_gen': 'm', 'form_num': 's', 'pattern': 'وَبِ1ُ2َ3نا', 'root': 'ع.ق.د', 'catib6': 'PRT+PRT+NOM+NOM', 'ud': 'PART+ADP+NOUN+PRON', 'd1seg': 'وَبِعُقَدنا', 'd1tok': 'وَ+_بِعُقَدنا', 'atbseg': 'وَ+_بِ+_عُقَد_+نا', 'd3seg': 'وَ+_بِ+_عُقَد_+نا', 'd2seg': 'وَ+_بِ+_عُقَدنا', 'd2tok': 'وَ+_بِ+_عُقَدنا', 'atbtok': 'وَ+_بِ+_عُقَد_+نا', 'd3tok': 'وَ+_بِ+_عُقَد_+نا', 'bwtok': 'وَ+_بِ+_عُقَد_+نا', 'pos_lex_logprob': -4.923429, 'caphi': 'w_a_b_i_3_u_q_a_d_n_aa', 'pos_logprob': -0.4344233, 'gen': 'f', 'lex_logprob': -4.923429, 'num': 'p', 'stem': 'عُقَد', 'stemgloss': 'complexes', 'stemcat': 'N'} 

{'diac': 'وَبِعُقَدِنا', 'lex': 'عُقْدَة_1', 'bw': 'وَ/PART+بِ/PREP+عُقَد/NOUN+ِ/CASE_DEF_GEN+نا/POSS_PRON_1P', 'gloss': '[part.]_+_by;with+complexes+our', 'pos': 'noun', 'prc3': '0', 'prc2': 'wa_part', 'prc1': 'bi_prep', 'prc0': '0', 'per': 'na', 'asp': 'na', 'vox': 'na', 'mod': 'na', 'stt': 'c', 'cas': 'g', 'enc0': '1p_poss', 'rat': 'i', 'source': 'lex', 'form_gen': 'm', 'form_num': 's', 'pattern': 'وَبِ1ُ2َ3ِنا', 'root': 'ع.ق.د', 'catib6': 'PRT+PRT+NOM+NOM', 'ud': 'PART+ADP+NOUN+PRON', 'd1seg': 'وَبِعُقَدِنا', 'd1tok': 'وَ+_بِعُقَدِنا', 'atbseg': 'وَ+_بِ+_عُقَدِ_+نا', 'd3seg': 'وَ+_بِ+_عُقَدِ_+نا', 'd2seg': 'وَ+_بِ+_عُقَدِنا', 'd2tok': 'وَ+_بِ+_عُقَدِنا', 'atbtok': 'وَ+_بِ+_عُقَدِ_+نا', 'd3tok': 'وَ+_بِ+_عُقَدِ_+نا', 'bwtok': 'وَ+_بِ+_عُقَد_+ِ_+نا', 'pos_lex_logprob': -4.923429, 'caphi': 'w_a_b_i_3_u_q_a_d_i_n_aa', 'pos_logprob': -0.4344233, 'gen': 'f', 'lex_logprob': -4.923429, 'num': 'p', 'stem': 'عُقَد', 'stemgloss': 'complexes', 'stemcat': 'N'}

现在,在我的情况下,我正在处理超过 600 万条推文,所以进行逐字分析不会提供太多信息或有效。相反,我们可以使用形态学消歧器(小心,阿诺德!)来为我们做这件事。这将接受一个标记列表作为输入(因此是步骤 3 中的简单单词标记器),并输出所有消除了歧义的标记形式。每个分析都是一个字典,我们可以使用字典键访问我们想要的表单和组件。这些分析按照可能性从大到小的顺序排列,因此通常的做法是简化,将第一个分析指定为输出。

它输出句子中每个单词的二进制形式、词性标记和词条:

('نَجَحَ', 'verb', 'نَجَح-a_1')
('بايدن', 'noun_prop', 'بايدن_0')
('فِي', 'prep', 'فِي_1')
('الاِنْتِخاباتِ', 'noun', 'ٱِنْتِخاب_1')

例如,这意味着我们可以使用如下函数获取阿拉伯文本的所有词条:

对于我进行主题建模的项目,这是我选择的进行标记化的方式。其他项目可能需要使用形态学标记器的不同方法,它将根据您选择的方案对字符串进行不同的标记。

所以…只要找到最适合你的项目的记号化/词条化方法,执行它,然后你就完成了阿拉伯文本的预处理!

更多骆驼乐趣

camel-tools 包提供了更多的预处理特性(比如音译、unicode 标准化等)。)可能对你的项目有用。查看完整的文档以获取更多信息。

此外,我只想指出,我做了大量的研究,试图找到为 NLP 预处理阿拉伯文本的最佳工具。虽然有许多其他好的选择(如 Farasa、MADAMIRA 和 Stanford CoreNLP ),但我发现 camel-tools 是最通用、最全面、最易于使用的。除了用于处理上述挑战的核心预处理功能,它还具有一些很酷的额外功能:它可以进行情感分析,并且——这确实是最酷的功能之一——它可以识别文本所用的方言(最多 25 种方言)。我肯定会使用方言标识符将“方言”作为一个特性添加到我的 NLP 管道中。

感谢您的阅读!在 LinkedIn 上关注我,了解定期的分布式计算更新和技巧。

请考虑成为支持写作社区的媒体成员:

https://richardpelgrim.medium.com/membership

多任务学习中的阿拉伯语句子嵌入

原文:https://towardsdatascience.com/arabic-sentence-embeddings-with-multi-task-learning-815801024375?source=collection_archive---------21-----------------------

实践教程

阿拉伯语自然语言处理教程,通过多任务学习创建阿拉伯语句子嵌入,实现快速高效的语义文本相似性任务。

由UJI 友子在 Unsplash 上拍摄的照片

在这个阿拉伯语自然语言处理(NLP)系列的第一篇文章中,我介绍了一个名为 AraBERT 的 transformer 语言模型(来自 Transformers 的阿拉伯语双向编码器表示),由 Antoun et al. (2020) 发布,它在各种阿拉伯语 NLP 基准上表现得非常好。作为典型的最新语言模型,AraBERT 非常大,基本模型有 1.1 亿个参数,大模型有 3.4 亿个参数。当考虑到这些语言模型的规模时,显而易见的是,在语用研究者和最先进的自然语言处理工具的使用之间存在可访问性差距。

正如一个人对资源的访问所决定的,前沿语言模型的卓越结果可以通过大量的生产考虑来强调。例如,研究人员可能会受到计算资源可用性的限制,这种费用不可避免地需要在金钱和时间之间进行权衡。除了令人望而却步的成本,社会研究极大地受益于 NLP 的应用,特别是因为数据驱动的方法提供了研究常见问题的替代角度。这对于中东和北非(MENA)等研究不足的地区尤为重要,在这些地区,纳入阿拉伯文本不仅对问责制至关重要,也有助于避免西方偏见。

在去年写的一篇文章中,我讨论了我对 transformer 语句嵌入的兴趣,这是我在的一篇研究论文中遇到的想法,该论文详细描述了从 Transformer 语言模型中训练高效语句嵌入。这篇论文描述了 NLP 任务,如从一组 10,000 个句子中找到最相似的句子对,通过评估语义文本相似性(STS)来确定,将需要使用 AraBERT 这样的 transformer 语言模型进行 5000 万次推理计算。这将需要大约 65 个小时才能完成,这使得 AraBERT 不适合语义相似性搜索或无监督的任务,如聚类。由泛在知识处理实验室的研究人员设计的聪明的解决方案是使用一个暹罗网络架构来训练变形金刚句子嵌入;这使得前面提到的 STS 任务可以在大约 5 秒钟内完成。

他们的创造句子-BERT (SBERT),非常适合 STS 任务,本教程用代码概述了使用多任务学习(MTL)将这个 NLP 工具扩展到阿拉伯语。我受到了 UKP 实验室的句子转换库中共享的示例脚本的启发(由 SBERT 作者 Nils Reimer 创建和维护),它实现了 MTL 来训练英语句子嵌入模型。在本教程中,我首先提供一些关于 STS 和句子嵌入的背景知识,然后讨论 MTL。接下来,我描述了用于训练阿拉伯语句子嵌入模型的实验设置(我将其命名为 SAraBERT),随后是 MTL 训练的完整代码演练,并对该过程进行了直观的解释。最后,我在一个阿拉伯语的 STS 基准上评估了训练过的模型,并提供了利用这个工具进行社会研究的想法。

语义文本相似度和句子嵌入

STS 与一对句子之间的意义相似度有关,可以用余弦相似度或曼哈顿/欧几里德距离等相似度度量来衡量。直观上,句子嵌入可以理解为一种将句子映射到向量的文档处理方法,作为一种用适合机器学习的实数表示文本的手段。给定一个句子集合,句子嵌入可以用来将文本单元转换成表示特征的固定大小的输出向量,然后在整个句子集合中进行比较。比较是可能的,因为句子被映射到向量空间,使得语义相似的句子更加接近。以这种方式评估语义相似性对于各种 NLP 任务是有用的,包括信息检索、释义识别、重复问题检测和摘录文本摘要。

在 SBERT 发布之前,其他不太有效的方法被用来从像 BERT 这样的转换模型中创建固定大小的句子嵌入。最常见的是,均值池用于平均 BERT 的输出层,或者通过使用[CLS]令牌(BERT 嵌入中的第一个令牌,分类令牌)的输出。SBERT 作者表明,这两种类型的句子嵌入在 STS 任务中表现不佳,通常比平均的手套单词嵌入(使用全局统计学习单词向量表示的无监督算法)更差。这是值得注意的,因为与手套单词嵌入相比,来自 BERT 类型模型的单词嵌入在大多数 NLP 基准上具有显著更高的分数。然而,平均单词嵌入的不良表现表明,单独汇集不能产生非常适合句子级相似性任务的句子嵌入。

这使得像 SBERT 这样的句子嵌入成为必要,SBERT 使用一个连体结构,其中两个网络具有绑定的权重。为了在 STS 任务中获得最佳性能,SBERT 从预先训练的 BERT 模型开始,并使用一个连体设置来微调模型;首先在自然语言推理(NLI)数据集上,然后在 STS 数据集上进一步微调。

在 NLI 数据集上微调句子嵌入的 SBERT 暹罗网络体系结构。出处。

从上图可以看出,当微调 NLI 数据集时,两个句子嵌入 uv 是从合并的伯特单词嵌入中产生的。它们与基于元素的差⏐u-v⏐连接,然后乘以可训练权重(wt);其中 W t ∈ ℝ ᵏ* ,并且 n 是句子嵌入的维度, k 是标签的数量。这可以由下面的分类目标函数来表示,该分类目标函数通过交叉熵损失来优化。

在 NLI 数据集上微调句子嵌入的分类目标函数。图片作者。

当在 STS 数据集上进行微调时,使用回归目标函数,其中通过计算两个句子嵌入 uv 之间的余弦相似度,并且使用均方误差损失作为损失函数。回归目标函数表示为余弦 _sim ( uv )损失函数为:| |input _ labelcos _ score _ transformation(余弦 _sim ( uv)| |,其中默认cos _ score _ transformation为 a

SBERT siamese 网络架构,具有回归目标函数,用于对 STS 数据集进行微调。来源。

多任务学习

MTL 依赖于知识的归纳转移;不是孤立地为单个任务训练模型,而是可以并行地为几个相关的任务训练模型,以便在任务之间共享学习到的信息。引用卡鲁阿纳(1998) 经由塞巴斯蒂安·鲁德的话,“MTL 通过利用相关任务的训练信号中包含的特定领域信息来提高概括能力。”。对于深度神经网络的多任务学习的可访问概述,我建议 Ruder 关于主题的博客文章,为了简洁起见,我在本文中限制了细节,并专注于高级概念。

本质上,这种学习方法利用任务之间的共性和差异来训练更好地概括的模型。通常,正则化通过统一惩罚复杂性来防止过度拟合;然而,相比之下,MTL 正则化是通过要求在相关任务上的良好表现来诱导的。换句话说,存在一种归纳偏差,即模型倾向于解释一个以上任务的假设,这种偏好提高了泛化能力。这种归纳偏差意味着 MTL 在小数据集或类标签欠采样时特别有效。除了正则化,MTL 还引入了隐式数据增强和注意力集中。从某种意义上说,MTL 隐含地增加了样本量,允许模型学习更一般的表示;这是因为,联合学习两个任务平均了来自不同任务的数据相关噪声模式。MTL 的注意力集中是通过突出重要特征来实现的,这是可能的,因为该模型从其他任务中获得了特征相关或不相关的额外证据。

自 2018 年以来,根据对可用文献的调查,MTL 已多次被用于阿拉伯语自然语言处理研究,特别是与阿拉伯方言有关的翻译模型,以及社交媒体上的攻击性语音检测。2019 年, Abdul-Mageed et al. 使用句子级 BERT 模型和句子级 MTL 模型,从带注释的阿拉伯语推文中对年龄和性别进行分类;在一项研究中,他们发现 MTL 双任务模型不如单任务伯特模型。研究人员将他们的模型描述为语言不可知的,因为他们的模型建立在句子级别的多语言 BERT(MBERT)模型上,并针对阿拉伯文本样本的分类任务进行了微调。我选择了一种不同的方法,我创建了一个句子级的阿拉伯语 BERT 模型(SAraBERT ),它已经用阿拉伯语 NLI 和 STS 数据进行了微调。这是因为我对特定于阿拉伯语的句子嵌入感兴趣,这些句子嵌入可以用于 STS 任务,比如文本摘要。此外,当前最先进的阿拉伯文本分类方法是使用 AraBERT 单词嵌入(发布于 2020 年)。

实验设置

在本教程中,MTL 用于在一个共享任务中对两个数据集(NLI 和 STS)的句子级阿拉伯特(SAraBERT)模型进行微调,而不是每次对每个数据集的单个任务进行顺序微调。具有交叉熵损失的分类目标函数用于 NLI 数据集,具有均方误差损失的回归目标函数用于 STS 数据集。联合学习包括来自每个任务的一个批次与其他任务的所有其他批次相匹配;这种循环匹配以迭代的方式发生。直觉告诉我们,任务之间共享信息会提高概括能力。我使用前面提到的来自 UKP 实验室的句子变形器 Python 库,对于本教程,我使用非分段 AraBERT 模型的第二个版本“bert-base-arabertv02”,它可以通过 Huggingface 模型获得。

由于没有开源的特定于阿拉伯语的 NLI 数据集可用,对于 NLI 数据集,我从脸书的跨语言 NLI 语料库(XNLI) 中分割出 2490 个阿拉伯语句子对。根据假设和前提之间的关系,这些阿拉伯语句子对被标记为文本蕴涵,每个前提/假设对被标记为“蕴涵”、“矛盾”或“中性”。特别使用 NLI 数据集,因为逻辑蕴涵不同于简单的等价,并且为学习复杂的语义表示提供了更多的信号。

最受欢迎的阿拉伯语 STS 基准, SemEval-2017 STS ,只有 1081 个句子对是从英语翻译过来的。出于对翻译质量和数据集大小的考虑,我选择使用最近发布的由问题对组成的阿拉伯语语义相似度数据集。阿拉伯语语义问题相似度(SQS) 数据集来自 2019 资源不足语言 NLP 解决方案研讨会,包含 12,000 个问题对,这些问题对根据两个问题之间的语义相似度标记为“是”或“否”。SQS 数据集比 SemEval-2017 STS 大得多,而且它的优势在于使用阿拉伯语原文。

用多任务学习训练阿拉伯语句子嵌入

本教程的所有代码都是使用 Pytorch 框架的 Python 代码。我建议使用 Google Colab 笔记本,利用自由层 GPU 实例来加快训练速度。第一步是导入所需的包,这些包在下面的代码片段中列出。

下一步是加载 XNLI ( nli_data )和阿拉伯语 SQS ( sts_data )训练数据集。我们从 XNLI 中分离出阿拉伯语句子对( arabic_nli_data ),然后我们在训练期间分割阿拉伯语 SQS 训练集用于验证数据( sts_data_train,sts_data_test ),同时保存实际测试集作为维持数据以评估最终模型。

接下来我们将“bert-base-arabertv02”设置为 model_name ,并设置训练时保存模型的输出路径。这里,批处理大小设置为 16,这将很容易在 16GB 的 GPU 上运行,这是 Colab 自由层云 GPU 的默认大小。使用三个独立的模块来构建模型:单词嵌入层、均值汇集层和密集层,这些模块堆叠在一起,使得每个连续的模块都从前一个模块的输出开始。最大序列长度设置为 256,其大小与密集层的输出特征相匹配,以保证生成的句子嵌入具有最大序列长度 256。

一个 label2int 字典将字符串标签“矛盾”、“蕴涵”和“中性”分别映射到 0、1 和 2。创建一个空数组来保存样本,这些样本是从Arabic _ nli _ datadata frame 迭代追加的。每个样本都是['sentence1 ',' sentence2 ',' label_id']的列表,这些样本必须加载到 Pytorch 数据加载器中。最后,我们从前面描述的分类目标函数中设置一个损失函数,在这里被视为 SoftmaxLoss。

对于 STS 数据,需要两个空数组,一个用于培训样本,另一个用于开发样本。样本以列表的形式迭代地添加到它们各自的数组中:['question1 ',' question2 ',' label_id']。与 NLI 数据类似,样本被加载到 Pytorch 数据加载器中。余弦相似性损失用于损失函数,其中先前描述的回归目标函数通过余弦相似性得分的均方误差损失来优化。此外,我们创建了一个评估器来使用开发样本测试嵌入的相似性,这一过程也允许我们在训练期间选择最佳模型。

最后,我们为训练设置了几个参数,周期数设置为 4,10%的训练数据用于预热,评估设置为每 1000 步进行一次。训练目标是一个元组列表,每个元组对有一个数据加载器和损失函数,每个任务有一个元组。当拟合模型时,在整个 4 个时期中每 1000 步进行一次评估,并且从每个评估阶段保存最佳模型。

训练后,最后一步是在 STS 测试集中的维持数据上评估模型。为测试样本创建一个空数组,并以类似于 STS 训练数据的方式作为['question1 ',' question2 ',' label_id']列表进行加载。然后加载模型,并创建测试评估器来测试来自测试样本的嵌入的相似性。

下面显示的结果是余弦相似性、曼哈顿距离、欧几里德距离和点积相似性,通过皮尔逊相关和斯皮尔曼相关指标测量。在 2016 年的一篇题为 面向任务的语义文本相似性内在评估的论文中,Reimer 等人得出结论,皮尔逊相关性的内在评估具有误导性,Spearman 相关性度量更适合评估 STS 任务。通过这种度量,SAraBERT 获得了 83.94%的分数,Spearman 相关性代表了准确确定两个问题是否相似的能力。

在阿拉伯语义问题相似性基准上保持测试数据的评估。图片作者。

下一步包括试验其他方法来训练阿拉伯语句子嵌入,并评估 SAraBERT 能够在多大程度上总结阿拉伯语文本或执行语义搜索。在 Colab 中训练 SAraBERT 只需要不到 5 分钟的时间,而且有了个人电脑,就可以相当快地为大型语料库生成阿拉伯语句子嵌入。

最后的想法

如果过去几年有任何迹象,越来越大的语言模型的趋势将继续主导 NLP 领域,使研究人员有必要关注可访问性。我将资源限制视为创造力的挑战,幸运的是,有一个大型开源社区共享代码和预先训练的模型。尽管有这些模型,但是,实现的实用性取决于正确地将工具与任务结合起来。使用 SAraBERT 进行快速有效的阿拉伯语句子嵌入,使得快速利用各种依赖语义搜索的 NLP 技术成为可能。就我的研究而言,这使得为政策评估进行文本摘要和信息检索的实验变得容易。此外,可以将 SAraBERT 用于无监督的任务,如基于句子嵌入的语义相似性的聚类,这为主题识别的任务提供了对传统统计模型如潜在狄利克雷分配的深度学习替代。

MTL 是一个有趣的 ML 范例,我怀疑有更好的选择来训练 STS 任务的句子嵌入,这是我打算在未来探索的一条途径。在我看来,SAraBERT 是一种低资源方法,建立在低资源语言 NLP 工具(AraBERT)上,在低资源设置下训练(免费 GPU +训练时间< 5 mins). My hope is that this cobbled-together creation born out of necessity, will provide utility for other researchers interested in applying Arabic NLP techniques to social research. I welcome questions and feedback, please feel free to connect with me on Linkedin 。最后,非常感谢 UKP 实验室和 Nils Reimer 开源资源,使得本教程成为可能。

牛油果有弹性吗?

原文:https://towardsdatascience.com/are-avocados-elastic-9d072e47605c?source=collection_archive---------37-----------------------

Python 中需求价格弹性(PED)的温和介绍

2016–2017 年你在哪里?我在纽约——这个城市引领了从时尚到美食,从娱乐到音乐的潮流。我加入了马车,并参与了一些,但有一个让我难以忘怀的是鳄梨面包或鳄梨色拉酱。

照片由 Unsplash 上的 Dainis Graveris 拍摄

2017 年,牛油果价格飙升,牛油果价格飙升;我在当地全食超市花了 3.65 美元买了一个哈斯鳄梨。有一个笑话说,所有的千禧一代都很穷,和父母住在一起,因为他们把所有的钱都花在牛油果吐司上了。出于某种原因,这种水果被认为是优质的,并标有较高的价格;其中一个原因是需求。可能还有其他宏观经济因素,如季节性、竞争、天气等,但或多或少,正如我们从经济学理论中得出的结论,价格在很大程度上受需求驱动。

简单来说,如果某样东西不贵,就会有更多的人买,如果某样东西贵,就会有更少的人买。借助于一个叫做 PED(需求价格弹性)的概念,这种确切的行为被量化了。

我想用以下问题来分析这个概念:

1.随着时间的推移,鳄梨的供求之间有关系吗?

2.牛油果的需求价格弹性是多少?

3.需求仅仅取决于价格还是还有其他因素?

1.需求价格弹性

PED 测量的是需求 Q 的百分比变化,在其他条件不变的情况下,价格变化 1%。

PED =(∂Q/∂P ) * P/Q

∂Q 是需求的变化,∂P 是价格的变化。

弹性一词与敏感性同义。

在经济理论中,弹性是衡量需求或供给对价格的敏感程度。在市场营销中,消费者对产品价格的变化有多敏感。

2.为什么是 PED?

我为什么要为我的产品/商品/服务衡量 PED?

  1. 它可以帮助我做出更好的定价决策,即我可以为我的产品设定的最佳价格
  2. 如果我降低价格,对需求会有什么影响?
  3. 提高或降低价格,收入会下降还是上升?

PED 也可以为许多其他问题提供一个起点。

有了这个基本的了解,让我们继续前进,让我们的绿色手指工作。

3.数据

鳄梨价格数据可在 Kaggle 上获得,它捕捉了 2015 年至 2018 年水果的平均价格以及销售量。

鳄梨爱好者会注意到三个栏目:

4046 —小型/中型哈斯牛油果(~ 3-5 盎司牛油果)

4225 —大哈斯牛油果(约 8-10 盎司牛油果)

4770 —特大号哈斯牛油果(~ 10–15 盎司牛油果)

其余的不言自明。

让我们加载数据。

sf = tc.SFrame.read_csv("avocado.csv")
sf.print_rows(3)

哦,顺便说一下…我用的是苹果的 turicreate 框架(【https://github.com/apple/turicreate】T2),你可以很容易地安装它,使用:

pip install -U turicreate

如果你发誓忠于熊猫数据帧,那么你也可以使用它,或者如果在执行过程中你不喜欢 turicreate,那么你可以使用

df = sf.to_dataframe()

有几个难看的列名,我们先修复一下

sf = sf.rename({'Total Volume': 'Volume'})
sf = sf.rename({'Total Bags': 'Bags'})
sf = sf.rename({'4225': 'twent_fv_Av'})
sf = sf.rename({'4046': 'for_si_Av'})
sf = sf.rename({'4770': 'sev_sev_Av'})sf.print_rows(3)

作者图片

4.简单的功能

我试图绘制数据,但 18,249 点没有多大意义。所以,我们暂时把数据卷起来,看看会发生什么。

让我们从数据列中编造一个“季度”变量。

qtr = []
for item in sf['Date']:
    date_i = dt.datetime.strptime(item, '%Y-%m-%d')
    qtr.append((date_i.month + 2) // 3)
sf['qtr'] = qtr

将按季度和年度汇总数据的临时 SFrame:

sf_g = sf.groupby(['year', 'qtr'], tc.aggregate.MEAN(
    'Volume'), tc.aggregate.MEAN('AveragePrice'))
sf_g = sf_g.sort(['year', 'qtr'])# Let's treat the ugly names of the columns as well
sf_g = sf_g.rename({'Avg of Volume': 'Volume', 'Avg of AveragePrice': 'Price'})

作者图片

让我们画出曲线

tc.visualization.set_target(target='browser')
tc.show(sf_g['Price'], sf_g['Volume'], xlabel="Price",
        ylabel="Demand", title="Demand-Supply Curve")

作者图片

不像我们在教科书中看到的那样是一个明显的下降趋势,但是如果我们仔细观察,那么随着价格的上升,鳄梨的销量或多或少会下降。

也许我需要一个更好的曲线。

5.需求-供给

让我们暂时转向熊猫数据框架,绘制价格和交易量的时间序列。

df_g = sf_g.to_dataframe()def plt_x(): fig, (a1, ax2) = plt.subplots(nrows=2, sharex=True, subplot_kw=dict(frameon=False), figsize=(15, 8))    plt.subplots_adjust(hspace=.0)
    ax1.grid()
    ax2.grid() ax1.plot(df_g['Price'], color='g')
    ax2.plot(df_g['Volume'], color='b')
    ax1.set_ylabel('Price')
    ax2.set_ylabel('Volume') plt_x()

作者图片

当我们从 2015 年到 2018 年遍历 13 个数据点时,价格上升的峰值对应着成交量的低谷,反之亦然。

这是一个更好的图表,证实了需求和供给的经济理论。

我们需要更有力的东西来证实我们的假设,也许是统计方法。

6.OLS 造型

Statsmodels 提供了一种进入 OLS 的简单方法,这就是我们将在这里使用的方法。

零假设:价格和交易量之间没有关系。

数据集有趣的一点是 Volume = ' 4046 '+' 4225 '+' 4770 '+Bags;所以,我们可以选择模型中的变量。

df = sf.to_dataframe() # SFrame to datafamemodel_1 = ols(
    " AveragePrice ~ twent_fv_Av + Bags", data=df).fit()print(model_1.summary())

作者图片

p 值小于α = 0.05(显著性值),因此可以拒绝零假设。

上面那款的问题是 R 相当差。这表明,就鳄梨而言,价格不仅是需求的函数,也是其他因素的函数。

让我们做一些改变。

我们有“类型”变量,它极大地影响水果的价格,有机的比传统的要贵。我们可以将它包含在模型中。

X = df[['twent_fv_Av', 'Bags','type', 'qtr']]
y = df['AveragePrice']#Encode the categorical variable.
X = pd.get_dummies(X, prefix=["type"], columns=["type"], drop_first = True)

再次拟合模型。

mod = sm.OLS(y, X).fit()
mod.summary()

作者图片

用图形解释结果会更直观。

fig = plt.figure(figsize=(8, 8))
fig = sm.graphics.plot_partregress_grid(mod, fig=fig)

作者图片

在部分回归图中可以看到一些趋势(每个变量对响应变量的影响,即平均价格)

我不会说他们强壮,但我见过更糟的。

1.模型的 r 看起来很好,这意味着 4 个变量结合起来解释了价格值中 88%的可变性。还不错!

2.除了“袋子”之外,所有袋子的 p 值都小于α = 0.05,表明它们对价格有影响。

因此,鳄梨的价格取决于鳄梨的数量、种类和销售季度。

7.PED 和产品

我们知道 PED 公式,但它在现实世界中代表什么呢?

简单规则:

PED > 1:弹性产品

PED < 1: Inelastic product

Elastic products are those that are highly sensitive to price changes i.e. a small change in price can cause a major shift in demand. Luxury products such as cars, perfumes etc should be elastic because they are discretionary items i.e. 他们是‘想要’而不是需要。

无弹性产品是指那些对价格变化不太敏感的产品,即即使价格大幅变化也不会对需求产生重大影响。 为生活寄托的物品落在队列中 。如果你生病了,那么你会买 5 美元或 10 美元的药。

我认为牛油果应该是一种弹性产品,它的 PED 应该是> 1 *。*让我们来了解一下。

鉴于较大的数据集更嘈杂,让我们使用一个卷到季度。

def plt_reg():
    fig, scatter = plt.subplots(figsize=(15, 7))
    sns.set_theme(color_codes=True)
    sns.regplot(x=df_g['Price'], y=df_g['Volume'])plt_reg()

嗯…我们知道 PED =(∂Q/∂P ) * P/Q

∂q/∂p =(0.7–1.1)/(1.2–1.7)= 0.8

P/Q = 1.7/0.7 = 2.42

PED = 1.94

不出所料,PED 因鳄梨> 1 而使其成为一种有弹性的商品。

源代码可以在我的 Github 上找到。

鳄梨酱时间到了

我一直在寻找的三个问题的答案:

1 **。随着时间的推移,鳄梨的供求之间有关系吗?**是的,从图表和统计数据来看,情况也是如此。统计模型的 R 为 0.88,这意味着模型中包含的变量解释了价格的大量变化。

2.牛油果需求的价格弹性是多少? PED 值为 1.94,这是意料之中的,因为鳄梨应该属于弹性产品。

3.需求仅仅取决于价格还是还有其他因素?是的,鳄梨的种类、季度销售日期是决定销售量的几个重要因素。

我欢迎反馈和建设性的批评。你可以在推特上找到我

情绪是普遍的吗?

原文:https://towardsdatascience.com/are-emotions-universal-55945cd7e0fa?source=collection_archive---------16-----------------------

如果是这样,我们如何使用神经网络从面部表情中预测它们?

腾雅特在 Unsplash 上拍摄的照片

背景和调查目的

在过去的几十年里,在认知科学领域,特别是在情绪理论的主题上,一直存在着争论。一方面,我们有保罗·艾克曼博士,他为情感“自然种类”的存在辩护。他的工作重点是面部表情及其普遍性,以及创造能够揭示这些情绪的测谎仪(Ekman,1997)。这些自然的种类构成了我们使用的基本的、熟悉的名字:“快乐的、愤怒的、厌恶的、恐惧的”。

另一方面,我们有丽莎·巴雷特博士,她为建构主义方法辩护。她的主张是,大脑是一个贝叶斯猜测机器,我们基于几个背景因素来解释情绪(Barret,2006)。对她来说,“皱眉”在某些情况下可能意味着悲伤,在其他情况下可能意味着失望。如何对情感进行分类的决定归结为“细微差别”,而且没有“正确”的答案。

因此,通过这个项目,我打算探索一个具有大约 30,000 幅训练集图像的 Kaggle 数据集,这些图像已经被“正确”分类为具有 7 种情绪之一:愤怒、厌恶、恐惧、快乐、悲伤、惊讶和中性(Pierre-Luc 和 Aaron,2013)。

请找到我在这里使用的确切数据集:【https://drive.google.com/open? id = 1 jztiq 9 fayu 4 tym vy 06 HLM 5 _ BZRthhcxq。

用主成分分析法研究自然物质

我首先使用主成分分析研究数据集,以发现面部表情中最具决定性的成分,以及是否有(a)几个重要的成分定义了暗示“自然种类”的表情,或者(b)无数个重要的成分暗示了更微妙的“构建”表情。

导入数据

Kaggle 网站上的数据以 CSV 表格的形式呈现。第一列是对人脸上呈现的情绪进行分类:(0 =愤怒,1 =厌恶,2 =恐惧,3 =快乐,4 =悲伤,5 =惊讶,6 =中性)。

第二列包含编码面部的黑白像素的一串值。下面我解码每个字符串条目,并把它们编码成 numpy 数组。

解码了上面的面部图像后,我使用下面的 matplotlib 可视化了前 32 张图像,以确保数据真正转化为图像:

PCA 分解

0.83781
0.92312

图片由作者提供。

正如我们所见,两种分解的碎石图是相似的。对于两者,解释的方差数量呈指数下降,最重要的主成分解释了略低于 0.3 (30%)的方差。因为主成分和解释的方差之间的指数性质,我们用 50 个成分解释了总方差的大约 84%,用 150 个主成分解释了方差的大约 92%,即使我们将成分的数量增加了三倍。向前看,由于解释了增加的方差,我将集中使用 150 分解,尽管我预期我的分类算法对于 150 比对于 50 运行得更慢。

主成分重构

现在我已经将每张图片分解成 150 个主要成分,我们可以看看前几个成分是什么样子的,并确定我们是否可以收集一些关于研究问题的见解:

图片由作者提供。

这些乍一看不是很有定论!但是也许通过更仔细地检查其中的一些,我们可以确定一些关于情绪范围的事情。让我们首先关注第一张图片。

第一主分量是具有 48×48 个分量的特征向量。我们可以通过将该特征向量乘以两个不同的特征值来研究维度是如何变化的,并注意图像是如何变化的:

图片由作者提供。

图片由作者提供。

这个特征向量似乎主要与区分面部颜色和背景颜色之间的对比度有关,而与面部表情的差异关系不大。

看着上面的主成分网格,在我看来,数字 14 可能会编码微笑或皱眉或类似的事情。让我们再看一看:

图片由作者提供。

图片由作者提供。

讨论和 PCA 结论

首先,除了发现主要组件看起来令人不安之外,我不认为组件的可视化对讨论有任何结论性的帮助。如果至少有几个主要成分清楚地编码了光谱两端的情绪,如“快乐”与“悲伤”,这可能是对自然物种假说的有力支持,但我没有找到这方面的证据(尽管我没有彻底调查每一个成分)。

然而,碎石图也许能提供更多的信息。请注意方差解释是如何呈指数下降的,最初几个主成分之后的后续主成分只增加了一个增量解释。这可能指向人类情感内在的细微差别。当然,这些主成分还编码了与面部结构、肤色、头发等相关的几个特征,因此仅基于它们做出任何界定都是不明智的。也就是说,如果 scree 图真的是相当细微差别存在的证据,这可能是一个支持情感构成的论点。“自然类型”的情况可能会给每种情绪带来很少的区别特征,但这不是我们所看到的:看着可视化,一些似乎编码了眼睛形状,眉毛弯曲,嘴巴形状,以及总共 150 个特征(它们加起来只能解释 92%的面部和表情)。

卷积神经网络可以读取情绪吗?利用 VGG16 迁移学习找出

训练模型

Train on 28709 samples, validate on 7178 samples Epoch 1/10 28709/28709 [==============================] - 1s 21us/step - loss: 13.9044 - accuracy: 0.6616 - val_loss: 1.7528 - val_accuracy: 0.7947 Epoch 2/10 28709/28709 [==============================] - 0s 17us/step - loss: 1.0365 - accuracy: 0.8257 - val_loss: 0.7941 - val_accuracy: 0.8380 Epoch 3/10 28709/28709 [==============================] - 0s 16us/step - loss: 0.6320 - accuracy: 0.8465 - val_loss: 0.5995 - val_accuracy: 0.8471 Epoch 4/10 28709/28709 [==============================] - 0s 16us/step - loss: 0.5235 - accuracy: 0.8521 - val_loss: 0.5234 - val_accuracy: 0.8503 Epoch 5/10 28709/28709 [==============================] - 0s 15us/step - loss: 0.4732 - accuracy: 0.8545 - val_loss: 0.4846 - val_accuracy: 0.8518 Epoch 6/10 28709/28709 [==============================] - 0s 16us/step - loss: 0.4443 - accuracy: 0.8557 - val_loss: 0.4585 - val_accuracy: 0.8530 Epoch 7/10 28709/28709 [==============================] - 0s 15us/step - loss: 0.4266 - accuracy: 0.8562 - val_loss: 0.4412 - val_accuracy: 0.8536 Epoch 8/10 28709/28709 [==============================] - 0s 16us/step - loss: 0.4146 - accuracy: 0.8566 - val_loss: 0.4312 - val_accuracy: 0.8537 Epoch 9/10 28709/28709 [==============================] - 0s 16us/step - loss: 0.4068 - accuracy: 0.8568 - val_loss: 0.4229 - val_accuracy: 0.8540 Epoch 10/10 28709/28709 [==============================] - 0s 15us/step - loss: 0.4014 - accuracy: 0.8569 - val_loss: 0.4183 - val_accuracy: 0.8542 <keras.callbacks.callbacks.History at 0x7fb56aa64e80>
Train on 28709 samples, validate on 7178 samples Epoch 1/10 28709/28709 [==============================] - 8s 273us/step - loss: 0.5901 - accuracy: 0.8247 - val_loss: 0.4090 - val_accuracy: 0.8571 Epoch 2/10 28709/28709 [==============================] - 8s 267us/step - loss: 0.4036 - accuracy: 0.8558 - val_loss: 0.4004 - val_accuracy: 0.8570 Epoch 3/10 28709/28709 [==============================] - 8s 272us/step - loss: 0.3980 - accuracy: 0.8569 - val_loss: 0.4008 - val_accuracy: 0.8571 Epoch 4/10 28709/28709 [==============================] - 8s 271us/step - loss: 0.3954 - accuracy: 0.8570 - val_loss: 0.4012 - val_accuracy: 0.8571 Epoch 5/10 28709/28709 [==============================] - 8s 271us/step - loss: 0.3938 - accuracy: 0.8571 - val_loss: 0.4032 - val_accuracy: 0.8572 Epoch 6/10 28709/28709 [==============================] - 8s 265us/step - loss: 0.3928 - accuracy: 0.8571 - val_loss: 0.4057 - val_accuracy: 0.8572 Epoch 7/10 28709/28709 [==============================] - 8s 263us/step - loss: 0.3919 - accuracy: 0.8571 - val_loss: 0.4019 - val_accuracy: 0.8571 Epoch 8/10 28709/28709 [==============================] - 8s 262us/step - loss: 0.3918 - accuracy: 0.8571 - val_loss: 0.4018 - val_accuracy: 0.8572 Epoch 9/10 28709/28709 [==============================] - 8s 265us/step - loss: 0.3911 - accuracy: 0.8571 - val_loss: 0.3973 - val_accuracy: 0.8572 Epoch 10/10 28709/28709 [==============================] - 8s 266us/step - loss: 0.3905 - accuracy: 0.8571 - val_loss: 0.3964 - val_accuracy: 0.8572 <keras.callbacks.callbacks.History at 0x7fb56a8ad780>

评估模型和结论

我们想要评估上述两个模型(基于 PCA 的神经网络和 VGG16 迁移学习神经网络)的最重要指标是验证准确性(显示在拟合过程的输出中)。对于 PCA 模型,我们的验证准确率为 85.42%,对于 VGG16 模型,我们的验证准确率为 85.72%。值得注意的是,这两个结果如此接近,因为第一个是基于简化数据运行的非常简单的模型,第二个是基于从一个获奖算法中提取的特征。VGG16 模型花了 1 分 20 秒来训练,另外 3 分钟用于特征提取过程(总共 4 分 20 秒)。然而,PCA 模型仅花费 3 秒来训练,PCA 分解步骤花费大约 1 分钟(大约 1 分 3 秒)。这意味着精度提高 0.3%需要付出 3 分 17 秒的代价。这还不包括开发 VGG16 算法所花费的时间和精力,相比之下,在 PCA 分解图像上使用简单得多的神经网络。

关于研究问题,这些精度值能告诉我们什么?这两个比率都非常高。这些比率类似于一些专业人员在更确定的类别的分类任务中获得的比率(Shorten,2018 年,讨论了一种类似的方法来将图像分类为狗或猫,他的准确率约为 72%)。

“狗”和“猫”这两个类别是自然的,而不是人类构造的,这一点有很强的论据。我们可能会采用物种形成的传统生物学界限:这两种动物既不能一起繁殖,也不能产生可繁殖的后代(Endler,1977)。关键是,我们的神经网络在对情绪进行分类方面比类似的网络在对科学上离散的类别进行分类方面做得更好。这支持了面部表情表达的情感至少有一些明显不同的类别。

当然,那些反对存在离散的、自然的情感类别的人会争辩说,他们并不反对我们无法对某人的情感做出正确的猜测。他们会特别指出,我们表达情绪的方式强烈依赖于文化因素,因此,我们可能会因为文化习俗而给某人的面部表情贴上标签,而不是因为对不变的、离散的类别有深刻的了解。

我的方法还有进一步的限制。首先,我们的样本可能有偏差。如果我们正在调查情感类别的“普遍性”,那么让我们所有的图像都属于某个特定国家的人将是令人不安的(我没有找到关于这个图像集的人口的特定描述)。第二,研究人员如何选择和分类这些图像可能存在偏见(注意,研究人员不仅为情绪强加了七个类别的存在,而且他们还寻找符合他们自己对这些类别的理解的图像)。数据集的庞大在一定程度上抵消了这些担忧。

当然,观察面部表情可能只是谜题的一部分,而不是争论双方的决定性证据。尽管如此,这个项目强调了即使是机器学习的适度应用也可以为我们提供关于人类大脑如何工作的宝贵见解。今天,研究人员正在使用类似的神经网络来研究可能成为情绪过程基础的大脑路径,从而在不同的分析水平上看待这个问题(Raz,Winetraub,Jacob,Kinreich,Maron-Katz,Shaham,& Hendler,2012)。

参考

巴雷特,L. F. (2006 年)。情绪是自然的吗?。心理科学的观点,1(1),28–58。

埃克曼博士(1997 年)。欺骗,撒谎,和风度。心理状态:美国和后苏联对当代心理学问题的观点,93–105。

恩德勒,J. A. (1977 年)。地理变异、物种形成和梯度(№10)。普林斯顿大学出版社。

皮埃尔-吕克和亚伦(2013 年)。表征学习的挑战:面部表情识别挑战。2020 年 4 月 23 日检索,来自https://www . ka ggle . com/c/challenges-in-re presentation-learning-face-expression-recognition-challenge/overview

Raz,g .,Winetraub,y .,Jacob,y .,Kinreich,s .,Maron-Katz,a .,Shaham,g .,… & Hendler,T. (2012 年)。描绘情绪的展开:探索神经网络动力学的多层方法。神经图像,60(2),1448–1461。

萨卡。(2018 年 11 月 17 日)。在深度学习中用真实世界的应用转移学习的综合实践指南。2020 年 4 月 23 日检索,来自https://towards data science . com/a-comprehensive-hands-on-guide-transfer-learning-with-real-world-applications-in-deep-learning-212 BF3 B2 f27a

【http://github.com】最初发表于https://gist.github.com/edbb98aa426d2c74574ae97f6ac706b4

德国暴雨事件的频率和强度在增加吗?

原文:https://towardsdatascience.com/are-heavy-rainfall-events-increasing-in-frequency-in-germany-2129b5d9d448?source=collection_archive---------19-----------------------

使用数据科学的调查

英格·玛利亚在 Unsplash 上拍摄的照片

2021 年7 月 14 日,北莱茵-威斯特法伦州和莱茵兰-普法尔茨州部分地区一天内降水量超过 100 升/米。后果是 100 多人在洪水中丧生,物质损失达数十亿欧元。

在和一个朋友谈论这件事时,他分享了他的印象,近年来暴雨事件有所增加。我不知道是同意还是不同意。他说的对吗?在德国,这种情况越来越多?它们的强度趋势如何?是不是有些城市的地理位置很不幸,比一般的事件发生得更频繁?

气候变化导致气温上升是一个普遍公认的观察结果,但暴雨事件的趋势在德国新闻媒体中一直是一个不太常见的话题。跟随我踏上旅程,寻找上述问题的答案。我们将从德国 1084 个气象站收集 1900 年至 2020 年的数据。结果是一个包含超过 1650 万次天气观测的数据集。让我们揭开它的秘密。

**我们的数据来自哪里?**德国气象局(Deutscher Wetterdienst)负责收集和归档德国的气象数据。大多数数据都是公开的,可以通过气候数据中心门户访问。我下载了德国所有可用气象站的历史降水数据,删除了缺失的数据,并过滤了 1900 年至 2020 年期间的数据集。

从我们的分析开始,我们可以标绘所有气象站的位置,以检查是否覆盖了每个地区。

数据基础:德国 Wetterdienst

1084 个气象站分布在德国各地。每个州在数据集中至少有几个气象站。然而,德国西南部的气象站比东北部多,这是一个轻微的梯度。

我们来看看数据是什么时候记录的。

数据基础:德国 Wetterdienst ,对单个值进行汇总

二战结束后的几年里,德国的气象观测出现了明显的繁荣。观察中的这种差异值得注意,这意味着在未来的时间序列分析中,我们必须根据每年的观察次数来调整暴雨事件的计数。

当处理数据集时,验证数据的可信度总是一个很好的做法。一种方法是用已知事件从外部验证数据集。对于这个项目,我们可以看看 2002 年 8 月易北河/多瑙河的洪水。如果数据集是准确的,它应该显示 2002 年 8 月 11 日德国东南部的大量降水导致易北河和多瑙河越过他们的海岸。

数据依据:德意志联邦共和国

清晰可见的是许多气象站报告高降雨量。因此,数据集的维度时间、位置和降雨量已经证明了它们的可信度。

一次足够验证,让我们深入分析部分:**德国暴雨事件是否越来越频繁?**要回答这个问题,我们首先要了解什么是暴雨事件。这个定义自然因气候区而异。如果你住在巴西雨林,德国的大雨可能会被认为是平常的一天。

德国气象局称极端事件为,如果:

  • 一小时内降雨量超过每立方米 40 升
  • 六小时内降雨量超过每立方米 60 升

由于历史天气观测只在每日汇总中可用,我不能坚持德国气象局的准确定义。对定义稍作调整,并接受微小的不准确性,我将随后谈论如果降雨量超过每天每立方米 60 升的暴雨事件。

也就是说,这是每年暴雨事件总量的图表——根据相应年份的观测总量进行调整。

数据基础:德国 Wetterdienst ,单个值的平均值

这是你所期望的吗?当我第一次看到这个图表时,我很惊讶,因为我暗暗期望看到一个明显的增长。但是我们来详细看一下。

可见的是多年来的高方差,突出了暴雨事件的不可预测性。极端峰值每几十年出现一次,标志着十年或百年一遇的暴雨。然而,25 年移动平均曲线显示,在过去 100 年中,暴雨事件的平均数量没有显著变化。

我们已经看到,到目前为止,德国暴雨事件的平均数量没有增加,现在让我们来看看暴雨强度是否也是如此。

数据基础:德国 Wetterdienst ,单个值的平均值

关于暴雨事件的强度,年变化再次很大。在过去的 100 年里,平均事件的平均降水强度保持不变,约为每立方米 73 升。应谨慎对待 1950 年之前记录的数据,因为观察次数少得多,这解释了数值的极端分散性。

与 1950 年至 1990 年期间相比,2000 年至 2020 年期间出现的峰值更高、更频繁,这表明近年来发生的暴雨事件更加极端。未来必须等待,看看这种观察是否会继续,均值是否会向上修正。

下一次有人问你暴雨事件的数量或强度是否在增加,你现在可以说虽然数量到目前为止似乎没有增加,但其强度在过去 20 年中已经上升了几次。

但是,请注意,所有的统计数据都是根据最佳知识和信念计算的,但不能保证它们的准确性。你也应该经常检查气候研究人员的工作,他们可以使用复杂的模拟工具和可能更多的数据,这些数据可能会也可能不会让他们得出不同的结论。但更多的是在讨论部分。

**现在,你可能会问,地区差异呢?**事件在德国是均匀分布的,还是有几个州更容易受到这些现象的影响?让我们找出答案。

数据基础:德国 Wetterdienst ,单个值的平均值

暴雨事件最有可能发生在巴伐利亚、巴登-符腾堡、萨克森和萨克森-安哈尔特。请注意,我计算了一个加权计数,它独立于每个州运营的气象站的数量。让我们再放大一点。这次是气象站的级别。

数据基础:德国 Wetterdienst ,单个值的平均值

巴伐利亚南部边境和巴登-符腾堡州的暴雨事件数量明显高于平均水平。对此一个可能的解释是这些气象站靠近山脉——阿尔卑斯山和黑森林。除此之外,德国各地似乎只有微小的差异。

总结词和结果讨论

这篇博文调查了过去 120 年德国暴雨事件的发生和强度趋势。数据来自德国气象局。尽管每年的事件变化很大,但迄今为止,德国的暴雨事件没有显著增加。虽然平均强度在过去 100 年中也保持不变,但在本世纪的几年中出现了峰值,这一趋势是否会持续还有待观察。

从物理学的角度来看,温度升高 1 度的气团可以多容纳 7%的湿度。这就是为什么科学家们长期以来认为全球变暖也可能影响极端天气事件的原因之一。

来自美国、英国和乌拉圭的研究支持这一论点,并强调了人为全球变暖对各自分析区域极端降雨事件的可能影响。然而,来自德国的两项研究没有发现人为气候变化对暴雨事件的明确影响,这表明这些事件中的自然变化可能仍然在今天的德国发挥着更大的作用。

然而,在过去的 20 年里,德国的暴雨事件 后果增加了吗?渐进的土壤密封意味着更少的水可以被地面吸收,这加剧了受影响地区的洪水。****

如果你想更深入地探讨这个话题,这里的是另一个很酷的地图,让你探索 405 项关于气候变化对极端天气影响的不同研究的结果。

如果你对这个项目的代码感兴趣,你可以在我的 Github 上查看。

鸣谢

如果没有德国气象局(Deutscher Wetterdienst)免费提供的数据,这个项目是不可能完成的。

知识图谱是 AI 的下一件大事吗?

原文:https://towardsdatascience.com/are-knowledge-graphs-ais-next-big-thing-1ea97bb394bd?source=collection_archive---------6-----------------------

播客

Mike Tung 谈搜索的问题和知识表示的未来

苹果 | 谷歌 | SPOTIFY | 其他

编者按:TDS 播客由 Jeremie Harris 主持,他是数据科学导师初创公司 SharpestMinds 的联合创始人。每周,Jeremie 都会与该领域前沿的研究人员和商业领袖聊天,以解开围绕数据科学、机器学习和人工智能的最紧迫问题。

尽管令人印象深刻,但像 GPT-3 和伯特这样的语言模型都有同样的问题:它们在大量互联网数据上接受训练,以模仿人类写作。人类的写作经常是错误的,有偏见的,或者两者兼而有之,这意味着语言模型试图模仿一个不完美的目标。

语言模型经常胡言乱语,或者对他们不理解的问题编造答案。这会让他们成为不可靠的真相来源。这就是为什么人们对从大型数据集中检索信息的替代方法越来越感兴趣——包括知识图的方法。

知识图将人、地点和对象等实体编码成节点,然后这些节点通过边连接到其他实体,这些边指定了两者之间关系的性质。例如,知识图可能包含马克·扎克伯格的节点,通过指示扎克是脸书首席执行官的边链接到脸书的另一个节点。这两个节点可能依次连接到几十个,甚至几千个其他节点,这取决于图形的规模。

知识图是人工智能能力的一条令人兴奋的道路,世界上最大的知识图是由一家名为 Diffbot 的公司训练的,该公司的首席执行官 Mike Tung 在本期播客中与我一起讨论知识图可以在哪些方面改进更标准的技术,以及为什么它们可能是人工智能未来的重要组成部分。

以下是我在对话中最喜欢的一些观点:

  • Diffbot 在整个互联网上训练其知识图,他们是少数几家(与微软和谷歌一起)抓取整个网络的公司之一。这是一个比看起来更大的壮举:不仅网络由数百亿个页面组成,而且这些页面中有许多包含必须避免的网络爬行机器人的陷阱。例如,一个网页抓取机器人登陆一个带有日历的网站时,可能会选择“显示下个月”选项,因为它会搜索更多的数据——但在这个过程中,它可能会陷入永无止境的循环,因为它永远不会扫描完几个月。精心设计的机器人不会因为这些问题而失败,Mike 认为这是 Diffbot 的关键优势之一。
  • Diffbot(以及一般的知识图)对用户的查询给出了明确的答案,而不是读者可以通过查阅资源列表来找到他们想要的答案。因此,它提供了一种不同于搜索的服务,一种更加固执己见的服务。这是一把双刃剑:一方面,它意味着最终用户更少的模糊性,但另一方面,错误变得更有影响力。Diffbot 不是向用户提供与他们的查询最相关的 10 个网页的列表,而是向他们提供一个单一的数字、名称或信息片段,这些信息可以明确无误地正确或错误。这就是传达不确定性如此重要的原因:Diffbot 已经开发了复杂的技术来评估其对用户查询响应的信心水平。
  • 知识图的优点之一是它们的响应是内在可解释的(不像深度学习系统那样像黑盒一样操作),它们的逻辑结构是显而易见的。这使得它们更容易被审问,也更有可能遵守关于人工智能使用的越来越严格的法规。
  • Mike 看到了知识图用于知识生成而不仅仅是查询的潜力。他指出,大多数知识工作都是孤立的,过于专业化,导致研究人员和技术人员错过了不同领域概念之间有价值的联系。他认为知识图表可能提供一种方法来识别通常不会存在于任何一个人头脑中的不同想法之间的有希望的联系:尽管医生和工程师必须相遇才能意识到他们两人可以设计出一种有价值的新医疗设备,但一个大的图表可以在一个结构中包括他们的知识和许多其他人的知识。这可能为发现概念之间的新联系和开发新的解决方案创造机会。

你可以在推特上关注迈克,或者我在这里。

本集引用的链接:

  • 知识图谱调查论文:https://arxiv.org/pdf/2003.02320.pdf
  • 斯坦福知识图课程,cs 520:【https://web.stanford.edu/class/cs520/2020/
  • 知识图谱大会(行业应用):【https://www.knowledgegraph.tech/

章节:

  • 0:00 介绍
  • 1:30 diff bot 动态
  • 3:40 知识图表
  • 7:50 爬网
  • 17:15 这次有什么特别的?
  • 24:40 与神经网络的关系
  • 29:30 故障模式
  • 33:40 竞争意识
  • 39:00 用于发现的知识图表
  • 45:00 共识发现真相
  • 48:15 总结

我的(生物)药物分析性能可靠吗?只有成功的可能性才算数!

原文:https://towardsdatascience.com/are-my-bio-pharmaceutical-assay-performances-reliable-only-probability-of-success-counts-9f85f27cb208?source=collection_archive---------34-----------------------

行业笔记

制药行业传统量具 R 指标的替代品& R 指标

作者:Thomas de March in(pharm Alex 统计和数据科学高级经理)、Laurent Natalis(pharm Alex 统计和数据科学副总监)、Tatsiana Khamiakova(让桑制造和应用统计副总监)、Eric Rozet(pharm Alex 统计和数据科学总监)和 Hans Coppenolle(让桑制造和应用统计总监)。本文最初在 NCB 2021 会议上发表。

瓦尔德马·勃兰特在取消拍摄时拍摄的照片

源代码

本文的内容已经使用 r 自动生成。用于模拟和分析数据的源代码可从 Github 上的获得:https://github.com/tdemarchin/GageRRPharma

介绍

行业中经常进行 R&R 研究,以确定测量系统的运行性能,并确定其是否能够监控制造过程。一些指标通常与量具 R&R 研究相关,例如精度公差比(P/T)、精度总变差比(%RR)、信噪比(SNR)、%再现性和%重复性。虽然这些指标可能很适合整个行业,但一旦应用于药物制造行业,它们可能会出现问题,原因有几个:(1)(生物)药物分析通常比普通物理化学测量系统更具可变性,并且通常的标准对制药行业来说过于严格,(2)分析方法一旦通过鉴定,就无法始终得到改进,以及(3)测量通常成本高昂且耗时,这使得难以获得足够的数据来高精度地估计所有差异来源。

所有上述困难通常导致对测量系统的指责并触发警报,而测量质量对于其预期目的来说可能是可接受的。此外,通常很难弄清楚如何解释最常用的盖奇 R&R 指标,这些指标缺乏强有力的数学原理[1],因为它们通常不考虑估计的不确定性。

这项工作的目的是提出一种适用于药品生产的替代方法,以调查测量系统是否符合其预期目的。我们的方法侧重于理解测量系统的属性,旨在回答唯一相关的问题:(1)我的测量系统是否能够区分好的和坏的批次?(2)考虑到盖奇 R&R 实验中调查的工艺和测量可变性,未来的批次是否符合质量标准?

数据

量具 R & R 数据

在典型的盖奇 R&R 环境中,不同的分析员在不同的日子使用不同的设备,在某些情况下,在不同的实验室对几个批次进行重复测量。模拟了 Gage R&R 数据:

图 1:作为实验室、日期、分析员、设备和批次的函数的可变性图表。这三种颜色指的是三个不同的批次。

CPV 数据

虽然 Gage R&R 数据通常用于提供整个行业中测量系统和工艺可变性的信息,但在制药领域,工艺可变性无法从该数据中正确估计。事实上,通常只测量有限数量的批次(3-5)。此外,通常选择极端批次来跨越规格范围,因此不代表工艺有效批次与浴之间的可变性。

另一方面,过程可变性可以从其他来源估计,如持续过程验证(CPV)。在 CPV,对每批产品的 CQA 进行测量,并随时监控,以验证过程是否处于受控状态。模拟了一个典型的 CPV 数据集,并用其规格([90–110%])绘制了图表:

图 2:生产批次的测量值。红色水平线:规格。绿色虚线:控制限值(平均值 3SD)。

结果

根据盖奇 R&R 数据集,可以估计测量系统的可变性并计算不同的指标。使用贝叶斯框架和 R 包 brms 将以下模型拟合到 Gage R&R 数据中:

使用贝叶斯方法的主要优势在于:( 1)考虑了与模型和参数值相关的不确定性;( 2)具有预测性,便于通过模拟来模拟未来的测量值;( 3)可以整合相关的先验概率,这在可用数据有限时非常有用。

以下指标可从量具 R&R 数据集计算得出:

a)各成分的相对贡献(方差成分分析)

b)单次和多次实验室精度(测量不确定度)。X Y 的结果意味着未来的测量值有 95%的可能是真实值 X 附近的 Y。

c)作为批次真值的函数,成功符合规格的概率。该图有助于确定“安全区域”,在给定测量误差的情况下,真实批次值应位于该区域,以确保满足规格的高概率。

图 3:作为批次真值的函数,符合规格的成功概率。垂直红色虚线:规格。

虽然这些指标对于评估测量系统很有用,但它并没有包含实际的过程可变性,而是让评估者决定过程可变性是否足够小,可以在“安全区域”内操作。是否有可能结合测量和工艺可变性来确定未来的批次是否符合质量标准?

为了回答这个问题,我们可以利用 CPV 数据来确定过程的可变性。CPV 数据通常只包含每批一次测量,因此很难区分过程和测量可变性。

为了区分这两种情况,我们使用了根据 R&R 拟合计算的测量误差先验。这个先验是利用盖奇 R&R 拟合的所有随机效应确定的,除了实验室间的随机效应,因为 CPV 数据只来自一个实验室。使用贝叶斯框架和 R 包 stan 对 CPV 数据拟合了以下模型:

由此,使用(1)CPV 模型的批间方差和批截距后验分布,以及(2)盖奇 R&R 模型的批间方差、残差方差和实验室效应后验分布,对不同实验室的结果进行预测

下图显示了不同实验室中未来测量批次的后验预测分布。我们看到,除了实验室 E 的测量值高于其他实验室之外,大多数实验室都可能产生符合规格的测量值。然后,我们可以计算在规范范围内成功的概率。实验室。A = 0.98 实验室。B = 0.98 实验室。C = 0.99 实验室。D = 0.98 实验室。E=0.93。这允许确定哪些实验室能够以良好的成功概率进行测量,并潜在地调查有问题的实验室。

图 4:作为测量实验室功能的未来测量的后验预测分布。垂直红色虚线:规格。

结论

我们使用贝叶斯框架将测量系统属性的知识与过程可变性的知识结合起来。与传统的盖奇 R&R 指标相比,这里提出的指标有助于解释结果。这个例子显示了使用贝叶斯框架来确定测量系统和过程是否有能力的优势和灵活性。

参考

  1. 唐纳德·惠勒,《一项诚实的 R&R 研究》稿 189 (2009)。
  2. https://www.r-bloggers.com/

插槽和实体是一样的吗?

原文:https://towardsdatascience.com/are-slots-and-entities-the-same-f98a38ac328d?source=collection_archive---------12-----------------------

用 Rasa 构建聊天机器人—第二部分

作者图片

在过去的几个月里,我一直在使用 Rasa,最初我对插槽和实体之间的区别感到非常困惑。

在本帖中,我们将讨论插槽和实体是如何相似的,更重要的是,它们是如何不同的。

**Table of Contents**
- Defining Entities and Slots
- Are slots and entities interchangeable?
- When to use one over the other
- Setting Slots
- Extracting Entities

快速注释

这是我关于 Rasa 系列的下一篇文章。你可以看看下面之前的帖子。

在那里,我们讨论了 Rasa 和聊天机器人的一些基本组成部分,如果你是 Rasa 的新手,先浏览一下这篇文章会有所帮助。

定义实体和插槽

快速复习:这就是你如何定义这些术语。

时间

插槽是机器人的记忆。在任何需要持久保存值的地方,都可以使用槽。

在定义和使用插槽时,Rasa 为您提供了很大的灵活性。你可以给他们一个类型——文本,布尔,甚至自定义类型——你也可以选择一个槽是否应该影响对话的进行。

实体

实体是机器人从用户消息中提取的关键信息,比如用户的联系信息。

提取本身是由聊天机器人的 NLU 部分使用实体提取器完成的。

乍一看,它们似乎非常相似——都存储信息,尽管一个存储的时间更长,更重要的是,它们似乎可以互换。

插槽和实体可以互换吗?

他们不是。他们有联系,但只是在一定程度上。

类似

  • 两者都存储信息
  • 两者都会影响谈话的流程

差异

  • 实体更抽象,由称为实体提取器的 NLU 组件提取。
  • 插槽不能直接通过“提取”来填充,只能通过已经提取的实体或自定义操作来填充。
  • 实体可以使用像角色、组、同义词和正则表达式这样的特性进行更复杂的结构化和分组,而槽则没有。
  • 插槽有类型,rasa 允许您在很大程度上配置它们。

何时使用一个而不是另一个

在设计你的机器人时,这是一个非常重要的问题。理论上,您可以将每个实体映射到一个插槽,并让所有内容都保存在您的跟踪器上。但这并不总是必要的。

请记住,只有当您希望信息持久化时,才需要插槽,比如用户名。否则,实体本身就足够了。

没有相应插槽的实体

实体通常可以具有与其相关联的槽,因为槽可以被认为是“更持久的”实体。但是请考虑这样的情况,您需要临时提取一些信息,这些信息对于机器人恰当地响应用户的查询至关重要。

一个简单的例子?以一个“计算器”机器人为例。用户提到简单的算术查询,机器人计算答案。

用户会说这样的话:

Could you add 1223239 and 190239?

所需的信息可以提取为实体:operand(两个操作数将落入其中)和operator(在本例中是“add”)。

由于这些信息只是暂时有用——也就是说,在下一个问题之前——将它们存储在插槽中并不是一个好主意,尽管如果您愿意的话也可以这样做。

没有对应实体的插槽

这是一个更容易想到的用例。如果你需要一个提示,槽不需要通过实体来填充。你也可以使用动作。

插槽可以像全局变量一样使用。你也许可以维护一个名为is_existing的槽来跟踪一个用户是否是现有用户。

在这里,拥有一个名为is_existing的对应实体也是没有意义的,因为这个信息不能由用户提供,因此也不能被提取——它必须通过数据库查询来验证。

设置插槽

创建插槽

插槽在slots键下定义,位于名为的文件中。Rasa 让我们以多种方式组织您的数据—对于较小的项目,您可以选择将所有内容转储到一个文件中,或者将所有内容分开保存。

定义的插槽如下所示:

slots:
  email:
    type: text
    initial_value: null
    auto_fill: true
    influence_conversation: true

您可以决定类型,设置默认值,确保任何相应的实体(与您的插槽同名)自动填充它,还可以决定它是否会影响您的对话。

插槽设置

可以通过两种方式设置位置——按作者排列图片

可以通过两种方式设置插槽:

  • 通过具有相同名称的实体(当设置了autofillstore_entities_as_slots时,默认情况下是这样)
  • 通过自定义操作。

通过实体

当实体和插槽具有相同的名称时,可以用相应的提取实体自动填充插槽。这可以借助两个默认为True的属性来完成。

  • auto_fill(每个插槽默认设置为真)。看起来像这样:
slots:
  email:
    type: text
    auto_fill: <true|false>
  • store_entities_as_slots(在您的文件中设置为配置参数)
config:
  store_entities_as_slots: false

通过自定义操作

也可以通过自定义操作来设置插槽。自定义动作在文件中被定义为一个类,带有一个name和一个run方法。它继承自 Rasa 的Action类。

通过返回列表中的SlotSet对象来设置插槽,如下所示:

return [SlotSet("my_slot", value), .. ]

请记住,定制动作可用于查询数据库、进行 API 调用以及使用dispatcher响应用户。

因此,检查用户是否已经注册了时事通讯的自定义操作可以这样实现:

动作action_check_if_existing_user执行以下操作:

  • email插槽读取用户的电子邮件
  • 将其传递给查询数据库的助手函数
  • 获取响应并设置is_existing布尔槽
class ActionCheckIfExistingUser(Action):
    def name(self):
        return "action_check_if_existing_user" def run(self, dispatcher, tracker, domain):
        email = tracker.get_slot('email') # some helper method that queries the database
        action_utils = ActionUtils()
        is_existing = action_utils.check_if_user_exists(email) if is_existing:
            dispatcher.utter_message(text="You're signed up.")
        else:
            dispatcher.utter_message(text="You aren't signed up.")

        **return [SlotSet("is_existing", is_existing)]**

提取实体

实体由 EntityExtractors 提取。这些是您在配置文件的管道中提到的组件。

有几个现有的,你可以在 Rasa 的文档中找到,你也可以随时设计定制的组件。

我们将在以后的文章中讨论实体提取的细节。

角色和组

这是去年发布的一个特性,让你在定义实体时有更多的灵活性。

角色

可以把role看作是给一个特定的实体添加更微妙的含义的一种方式。

假设你正在开发一个机器人来帮助用户以旧换新他们的移动设备。你有一个实体model,嗯,提取智能手机模型。

现在,旧设备和用户想要购买的设备从技术上来说都是智能手机型号,但区分它们对机器人来说很重要。

实体角色-按作者分类的图像

所以,我们可以给model实体添加一个role。您可以像这样添加训练数据:

My existing device is an [iphone 11]{"entity": "model", "role": "existing_device"} and I want to buy an [iphone 13]{"entity": "model", "role": "new_device"}.

群组让你个实体组合在一起,这样它们更有意义。假设您有两个实体— nameage,一个用户说:

My friend John is 20 while David is 25.

实体组-按作者分类的图像

这里,机器人需要识别两组姓名和年龄之间的分组。约翰的年龄一定与他的名字有关,大卫也是如此。这就是团队出现的原因。

你可以这样做:

My friend [John]{"entity": "name", "group": "1"} is [20]{"entity": "age", "group": "1"} while [David]{"entity": "name", "group": "2"} is [25]{"entity": "age", "group": "2"}

参考

Rasa 文档中页面的链接

  • 实体
  • 实体提取器
  • 插槽
  • 影响会话的插槽行为

该系列的其他部分(这是第二部分)

第一部分:用 Rasa 构建聊天机器人

第三部分:处理聊天机器人故障

第四部分:聊天机器人是如何理解的?

最后

我们在这篇文章中讨论了插槽和实体,特别讨论了它们是如何关联的,但是不能互换。这篇文章的目的是让人们更容易理解这些是什么,以及在哪些场景中使用哪些。

谈到 Rasa 能提供什么,这只是冰山一角。我将在这个系列中添加更多的部分。

希望有帮助!

更新

20.3.2022

添加该系列中其他文章的链接

数据科学面试的技术/编码带回家对双方都有用吗?

原文:https://towardsdatascience.com/are-technical-coding-takehomes-for-data-science-interviews-useful-for-both-parties-d195559fd750?source=collection_archive---------33-----------------------

办公时间

由安托万·道特里在 Unsplash 上拍摄的照片

根据我的经验,技术总结通常发生在几轮面试之后,或者在与招聘经理的面试之后。每个公司的动机都不同,但如果没有按照公司的标准执行,这将是你进入下一轮面试的障碍。作为一名数据科学家,通常,外卖是建立一个模型或分析一些数据可视化,统计。您还需要根据您分析的数据和/或您建立的模型提供建议。它们与软件工程师的技术带回家的东西非常不同,因为它们更关注数据,而不是构建应用程序或解释软件基础。

这是一篇基于我个人经历的观点文章。这不是一项研究,我在其中进行回归分析,以推断技术带回家对公司或受访者的技术招聘过程有多有用。现在两边都有了;我能更好地理解这两种观点。在过去的五年里,我已经带了十几门技术课回家,在我招聘的时候,我自己也复习了十几门技术功课。

关于我们应该如何衡量和测试数据科学知识,没有黄金标准。从之前类似的标准测试中可以看出,标准化测试可能会偏向性别和收入。

然而,即使数据科学中没有标准化的测试,公司在为每个人创建编码/知识测试时也应该谨慎,这样结果才不会源于偏见。减轻这种情况的唯一方法是公开招聘各个级别的员工。

我确实认为,应该有一个相关的审查过程,对这些中级职位进行审查,以发现潜力和个人的工作能力;然而,没有必要像目前一些人那样紧张。那些紧张而冗长的面试技术作业可能会让双方都很头疼,最终可能会过滤掉一些好的候选人。

公司在设计技术面试/带回家方面的一些优势是:

  • 更好地理解某人编码能力的熟练程度。
  • 观察他们如何解决问题/寻求帮助或澄清。
  • 剔除冒名顶替者。(尽管我不喜欢大公司发布的广撒网的工作清单,因为事实表明,如果不符合所有条件,大多数女性都不会申请)。我主要指的是那些说他们使用了这个工具或者进行了分析的人,而当解释这个工具的时候,他们做得不够好,这一点我是见证人。

现在受访者的优势是:

  • 如果它是公司数据的合成样本,它会让您更好地理解您将要处理的数据以及其中的一些问题。
  • 炫耀你的知识和解决问题的能力。

然而,对于受访者来说,这些带回家的技术作业有很多缺点:

  • 它们是过分的任务。我记得一家初创公司要求我连接到他们的数据库,探索 2M 行的趋势系列数据,并创建一个考虑客户流失的业务案例研究。他们说只需要 4 个小时。我花了 20 多个小时…
  • 感觉有时候就是免费的无偿劳动。借用前面的例子。我问他们的数据科学家,他们研究的是什么类型的问题,他们说的正是这个技术作业。我的时间有限,但他们有很长一段时间来整理。
  • 它们让人精疲力尽。我记得当我面试的时候,我每隔几周就要做 1-2 次这样的事情,持续三个月,这让我精疲力尽。感觉我需要的时间是他们建议的 5 倍,因为我对数据进行了彻底的调查,转换了数据,进行了可视化,并建立了一个模型。我可以理解,如果没有其他方面的帮助,为人父母的人可能无法将所有的时间都投入到这些技术性工作中。

对公司的不利之处是:

  • 除了面试候选人之外,从你的团队中抽出时间来评估作业
  • 你不知道人们是否复制代码,也不明白它在做什么。我并不反对使用堆栈溢出来调试错误或使用文章来获得灵感,但我记得在我的数据科学职业生涯早期,我希望获得一份我还没有准备好的工作,调整我并不完全理解的代码。
  • 公司可能会雇佣相同类型的人。取决于你的面试范围有多广,你可能会和同一类型的候选人分手。我在一家著名的信用卡公司经历了一个漫长而臭名昭著的面试过程,在招聘人员、招聘经理、技术带回家之后,是一个 5 小时的全天剖析案例研究。这让我想到,他们雇佣的是什么类型的人,因为一个包含如此多障碍的过程就像过滤器,越来越多的过滤。

因此,减轻这种情况的建议是:

  • 如果你必须做编码练习。不要让人把代码送过来,而是让他们解释并和你一起完成他们的工作。这将一举两得。首先,它将为受访者提供一些关于所提供工作的反馈,这是面试过程中的一个巨大差距。正如我所说的,一些技术带回家的东西需要受访者付出很多努力,即使进入下一轮,也很少得到认可或建设性的反馈。我无法解释有多少次,我在技术带回家后没有进入面试程序,我会为此责备自己,而实际上他们可能因为不同的原因没有让我进入下一轮。由于法律原因,公司在发送电子邮件说明没有进一步推进你的申请时,不会给出反馈理由,但如果你让这个人浏览他们的代码并解释,我个人知道,我会更准确地判断我做得是好还是坏。第二,如果你让某人走一遍他们的技术带回家,你就节省了试图弄清楚他们在做什么或自己运行它的时间,面试时间将需要 30 分钟到最多一个小时,面试官将非常清楚他们是否愿意继续与候选人合作。
  • 不要布置技术作业,而是要求他们深入解释概念或流程。询问特定的问题。不是像“什么是线性回归”这样的问题,而是“解释你是如何建立上一个回归模型的,你的发现是什么,以及你如何验证它是一个适合你的数据的模型”。或者“讨论一个场景,您必须转换数据以适应您的模型,或者您如何审查适合您的数据的模型?”
  • 如果他们的 Github 上有可能的话,让他们带你浏览一些以前的代码。许多候选人都有 Github,并发表了他们在那里完成的一些工作。如果他们的回购是可消化的,这意味着他们很好地阅读了我,他们的代码得到了很好的评论,表明你对他们试图做的事情有很好的了解。

简而言之,带回家面试可能会很广泛,令人生畏,感觉就像一条单行道,几乎没有反馈。公司评级也很耗时。我和我的同事在我们公司招聘时实施的一个流程是一个小练习,应该只花我们自己指定的时间来尝试,并且在我们给候选人一个机会向我们介绍他们的代码之后。这非常有帮助,因为他们在我们面前运行它,所以我们节省了调试时间,我们衡量了他们的交流能力,我们可以对他们工作的代码提供直接的反馈。

我很想知道您为数据科学面试做技术作业的经历,以及这些经历是否会引起共鸣!我只是希望这个过程对双方来说都更愉快,更包容,是双向反馈,对某人的工作能力做出更公平的评判。

新的 M1 macbook 对数据科学有好处吗?让我们找出答案

原文:https://towardsdatascience.com/are-the-new-m1-macbooks-any-good-for-data-science-lets-find-out-e61a01e8cad1?source=collection_archive---------0-----------------------

与英特尔 Macbook Pro 在 Python、Numpy、Pandas 和 Scikit 方面的比较-了解

在 Unsplash 上由Tomástanislavsk拍摄的照片

新的无英特尔的 Macbooks 已经出现了一段时间。自然是忍不住了,决定买一个。接下来是 2019 年基于英特尔的 MBP 与新的编程和数据科学任务之间的比较。

如果我必须用一个词来描述新的 M1 芯片,我会是这个——惊人的。继续阅读更详细的描述。

撇开数据科学不谈,这个东西是革命性的。它的运行速度比我的 2019 年 MBP 快几倍,同时保持完全安静。我运行了多个 CPU 耗尽的任务,粉丝一次也没踢进来。当然,还有电池寿命。太不可思议了— 中度到重度使用 14 小时没有任何问题。

但是让我们把注意力集中在基准上。总共有五个:

  • CPU 和 GPU 基准测试
  • 性能测试—纯 Python
  • 性能测试—数字
  • 性能测试——熊猫
  • 性能测试-sci kit-Learn

重要注意事项

如果你正在阅读这篇文章,我想你正在考虑新的 Macbooks 是否值得用于数据科学。它们肯定不是“深度学习工作站”,但首先它们不会花费太多。

整篇文章中的所有比较都是在两个 Macbook Pros 之间进行的:

  • 2019 Macbook Pro(i5–8257 u @ 1.40 GHz/8gb lpddr 3/Iris Plus 645 1536 MB)——简称英特尔 MBP 13 英寸 2019
  • 2020 M1 Macbook Pro(M1 @ 3.19 GHz/8GB)——简称 M1 MBP 13 寸 2020

并非所有的库都兼容新的 M1 芯片。我配置 Numpy 和 TensorFlow 没有问题,但是 Pandas 和 Scikit-Learn 还不能本地运行——至少我还没有找到工作版本。

唯一可行的解决方案是通过 Anaconda 安装这两个组件。它仍然通过一个 Rosseta 2 模拟器运行,所以比 native 慢一点。

你将看到的测试在任何方面都不是“科学的”,无论是形式上还是形式上。他们只比较了上述机器之间不同的编程和数据科学任务的运行时。

CPU 和 GPU 基准测试

让我们先从基本的 CPU 和 GPU 基准测试开始。 Geekbench 5 用于测试,你可以在下面看到结果:

图 1 — Geekbench 对比(CPU 和 GPU)(图片由作者提供)

结果不言自明。M1 芯片在我的 2019 Mac 中拆除了英特尔芯片。该基准测试仅测量整体机器性能,与您稍后将看到的数据科学基准测试并不完全相关。

尽管如此,事情看起来很有希望。

性能测试—纯 Python

以下是在该基准测试中执行的任务列表:

  • 创建一个包含 100,000,000 个介于 100 和 999 之间的随机整数的列表l
  • l中的每一项平方
  • l中的每一项求平方根
  • 乘以相应的平方和平方根
  • 划分相应的平方和平方根
  • 对相应的平方和平方根执行整数除法

测试只使用内置的 Python 库,所以不允许使用 Numpy。您可以在下一节看到 Numpy 基准。

下面是测试的代码片段:

结果如下:

图 2 — Python 速度测试—越低越好(图片由作者提供)

可以看到,在 M1 Mac 上通过 Anaconda(和 Rosseta 2 模拟器)运行 Python 减少了 196 秒的运行时间。最好原生运行 Python,因为这进一步减少了 43 秒的运行时间。

总结一下——Python 在新的 M1 芯片上本地运行时,速度大约是的三倍,至少在基准测试中是如此。

性能测试—数字

以下是在该基准测试中执行的任务列表:

  • 矩阵乘法
  • 矢乘法
  • 奇异值分解
  • 乔莱斯基分解
  • 特征分解

最初的基准脚本取自 Github 上的 Markus Beuckelmann ,并稍作修改,因此开始和结束时间都被捕获。脚本看起来是这样的:

结果如下:

图 3 — Numpy 速度测试—越低越好(图片由作者提供)

至少可以说,用 Numpy 得到的结果有点奇怪。由于某种原因,Numpy 在我的 2019 英特尔 Mac 上运行得更快了。也许是由于一些优化,但我不能肯定地说。如果你知道原因,请在评论区分享。

接下来,让我们比较熊猫的表现。

性能测试——熊猫

熊猫基准测试与 Python 基准测试非常相似。执行了相同的操作,但结果被合并到一个数据框中。

以下是任务列表:

  • 创建空数据框
  • 给它分配一列(X)100,000,000 个介于 100 和 999 之间的随机整数
  • X广场的每一个项目
  • X中的每一项求平方根
  • 乘以相应的平方和平方根
  • 划分相应的平方和平方根
  • 对相应的平方和平方根执行整数除法

下面是测试的代码片段:

结果如下:

图片 4-熊猫速度测试-越低越好(图片由作者提供)

正如你所看到的,没有对“本土”熊猫的测量,因为我还没有安装它。尽管如此,M1 芯片上的熊猫完成基准测试的速度还是快了两倍。

性能测试-sci kit-Learn

和熊猫一样,我还没有设法安装 Scikit-Learn。您只会看到英特尔 MBP 公司和 M1 MBP 公司通过 Rosseta 2 仿真器进行的比较。

下面是基准测试中执行的任务列表:

  • 从网上获取数据集
  • 执行训练/测试分割
  • 声明一个决策树模型,找到最优超参数(2400 个组合+ 5 重交叉验证)
  • 用最佳参数拟合模型

这或多或少是一个标准的模型训练过程,不考虑测试多种算法、数据准备和特征工程。

下面是测试的代码片段:

结果如下:

图 5-sci kit-学习速度测试-越低越好(图片由作者提供)

结果传达了与熊猫相同的信息-2019 英特尔 i5 处理器需要两倍的时间来完成相同的任务。

结论

与基于英特尔的 2019 Mac 的比较可能与你无关。这很好——您有了基准测试脚本,因此可以在您的机器上运行测试。如果您这样做了,请告诉我—我渴望了解您的配置以及它的比较情况。

新的 M1 芯片是惊人的,最好的还在后面。毕竟这只是第一代。Macbooks 不是机器学习工作站,但你仍然得到了很好的回报。

TensorFlow 的深度学习基准测试将于下周推出,敬请关注。

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

https://medium.com/@radecicdario/membership

加入我的私人邮件列表,获取更多有用的见解。

了解更多信息

  • 2021 年学习数据科学的前 5 本书
  • 如何使用 Python 创建 PDF 报告—基本指南
  • Python 并行性:几分钟内加速 Python 代码的基本指南
  • SHAP:如何用 Python 解读机器学习模型
  • 机器学习的三大分类指标——一劳永逸地消除准确性

原载于 2021 年 1 月 23 日 https://betterdatascience.comhttps://betterdatascience.com/are-the-new-m1-macbooks-any-good-for-data-science-lets-find-out/

新的 M1 macbook 对深度学习有好处吗?让我们找出答案

原文:https://towardsdatascience.com/are-the-new-m1-macbooks-any-good-for-deep-learning-lets-find-out-b475ad70dec2?source=collection_archive---------3-----------------------

M1 Macs 与谷歌 Colab 的基本深度学习任务

照片由 veeterzy 发自 Pexels

新的苹果 M1 芯片背后有很多宣传。到目前为止,它被证明优于英特尔提供的任何产品。但是这对深度学习意味着什么呢?这就是你今天会发现的。

新的 M1 芯片不仅仅是一个 CPU。在 MacBook Pro 上,它由 8 核 CPU、8 核 GPU 和 16 核神经引擎等组成。处理器和 GPU 都远远优于上一代英特尔配置。

我已经展示了 M1 芯片对于常规数据科学任务的速度有多快,但是深度学习呢?

简而言之——是的,在这个部门有一些改进,但现在的 MAC 电脑比,比如说, Google Colab 更好吗?请记住,Colab 是一个完全免费的选项。

这篇文章的结构如下:

  • CPU 和 GPU 基准测试
  • 性能测试— MNIST
  • 性能测试——时尚 MNIST
  • 性能测试— CIFAR-10
  • 结论

重要注意事项

并非所有的数据科学图书馆都与新的 M1 芯片兼容。让 tensor flow(2.4 版)正常工作说起来容易做起来难。

你可以参考这个链接下载。tensor flow 及其依赖项的 whl 文件。这只适用于 macOS 11.0 及以上版本,请记住这一点。

你将看到的测试在任何方面都不是“科学的”,无论是形式上还是形式上。他们只比较每个时期的平均训练时间。

CPU 和 GPU 基准测试

让我们先从基本的 CPU 和 GPU 基准测试开始。比较是在采用 M1 芯片的新 MacBook Pro 和 2019 年的基本型号(英特尔)之间进行的。 Geekbench 5 用于测试,你可以在下面看到结果:

图 1 — Geekbench 5 结果(英特尔 MBP 公司对 M1 MBP 公司)(图片由作者提供)

结果不言自明。M1 芯片在我的 2019 Mac 中拆除了英特尔芯片。到目前为止,事情看起来很有希望。

性能测试— MNIST

MNIST 数据集有点像深度学习的“hello world”。它内置了 TensorFlow,使测试变得更加容易。

以下脚本为 MNIST 数据集上的十个时期训练了一个神经网络分类器。如果你用的是 M1 Mac,取消对mlcompute行的注释,因为这会让程序运行得更快一些:

上面的脚本是在 M1 MBP 和谷歌实验室(CPU 和 GPU)上执行的。您可以在下面看到运行时比较:

图 2-MNIST 模型平均训练时间(图片由作者提供)

对于一台新的 Mac 电脑来说,结果有些令人失望。Colab 在 CPU 和 GPU 运行时都超过了它。请记住,结果可能会有所不同,因为在 Colab 中没有运行时环境的保证。

性能测试——时尚 MNIST

该数据集非常类似于常规的 MNIST,但它包含衣服而不是手写数字。因此,您可以使用相同的神经网络架构进行训练:

如您所见,这里唯一改变的是用于加载数据集的函数。相同环境的运行时结果如下所示:

图 3——时尚 MNIST 模特平均训练次数(图片由作者提供)

我们再次得到类似的结果。这是意料之中的,因为这个数据集与 MNIST 非常相似。

但是,如果我们引入更复杂的数据集和神经网络架构,会发生什么呢?

性能测试— CIFAR-10

CIFAR-10 也属于“hello world”深度学习数据集的范畴。它包含了来自十个不同类别的 60K 张图片,比如飞机、鸟、猫、狗、船、卡车等等。

这些图像的大小为 32x32x3,这使得它们在某些情况下甚至对于人类来说也难以分类。下面的脚本通过使用三个卷积层来训练分类器模型:

让我们看看卷积层和更复杂的架构如何影响运行时:

图 4 — CIFAR-10 模型平均训练时间(图片由作者提供)

如您所见,Colab 中的 CPU 环境与 GPU 和 M1 环境相去甚远。Colab GPU 环境仍然比苹果的 M1 快 2 倍左右,类似于前两次测试。

结论

我喜欢新 M1 芯片的每一点和它带来的一切——更好的性能,没有过热,更长的电池寿命。不过,如果你对深度学习感兴趣,这是一款很难推荐的笔记本电脑。

当然,M1 比我的其他基于英特尔的 Mac 有大约 2 倍的改进,但这些仍然不是为深度学习而制造的机器。不要误会我的意思,你可以使用 MBP 完成任何基本的深度学习任务,但如果你每天都做深度学习,在相同的价格范围内会有更好的机器。

本文仅介绍了简单数据集上的深度学习。下一个项目将在更高要求的任务上比较 M1 芯片和 Colab 比如迁移学习。

感谢阅读。

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

https://medium.com/@radecicdario/membership

加入我的私人邮件列表,获取更多有用的见解。

了解更多信息

  • 2021 年学习数据科学的前 5 本书
  • 新的 M1 macbook 对数据科学有好处吗?让我们来看看
  • 如何使用 Python 创建 PDF 报告—基本指南
  • Python 并行性:几分钟内加速 Python 代码的基本指南
  • SHAP:如何用 Python 解释机器学习模型

原载于 2021 年 1 月 25 日 https://betterdatascience.com**的

话题也是词语社区吗?

原文:https://towardsdatascience.com/are-topics-also-communities-of-words-9b390862ea64?source=collection_archive---------35-----------------------

利用图形分析中的社区检测进行主题分析

图片由来自皮克斯拜的托尔斯滕·弗伦泽尔拍摄

[剧透警报]当丹妮莉丝·坦格利安被她的侄子兼情人琼恩·雪诺谋杀后, 《权力的游戏》 社区变得猿类。

“我现在太难过了,简直要哭了。呃。F#%k(原文)”愤怒的推特粉丝

“……她整个赛季都感觉被背叛了,她死的时候也被背叛了……”——另一个愤怒的推特粉丝

好了,句号。我从没真正看过 GOT HBO 系列。

停下来集体喘息

是的,我只知道我写在最上面的句子的严重性,因为我有一个哥哥是一个狂热的观众,他总是用下面的话来修饰他的解释:

“你只要看看这个系列就行了,兄弟。就像,给它时间,熬过第一季,然后你就会上瘾。”

但我没看过这个节目,不代表它对我没有影响。我第一次知道这部剧的狂热追随者是在我看一个年轻的研究生米兰·雅诺索夫的演讲时,他用人物之间的关系创建了一个网络图,并用它来预测谁最有可能在下一集死去。引起我注意的是模型的准确性和图论的新颖应用。

不言而喻,文字有助于形成关系。不仅仅是人与人之间的关系,他们还会在一个句子、一段话、一页纸上形成彼此之间的关系。

有什么比网络图更好的方式来表达这些关系呢?Janosov 帮助将这一信息传达给了大量受欢迎的粉丝,并激励了其他人,因为他们从《哈利·波特与火焰杯》到《指环王》和《T21》,甚至从《漫威》到《宇宙》。

大量现有的链接单词和关系的项目都集中在单词中的人以及他们与其他人的关系上。文字本身呢?它们之间的关系可以从图形的角度有效地理解吗?在这里,我看到了在文档中查找主题的图算法的应用。让我们开始吧。

话题分析,单词-数据版聚类

在数据科学中,我们使用无监督算法来帮助我们找到数据的自然(数据驱动)分组。大概应用最多的聚类算法是 K-Means 。然而,当这些数据是单词时,像潜在狄利克雷分配( LDA )这样的其他算法更受欢迎。LDA 比 K-Means 更受欢迎,因为 LDA 将多个主题分配给单个文档,而 K-Means 针对互斥组进行优化(也称为硬聚类)。

这两种方法的缺点是,都要求用户为模型输入特定数量的聚类/主题,然后尝试在数据中“查找”。必须事先输入主题的数量可能是一个挑战,因为我们通常不知道分组的最佳数量应该是多少。

感觉我们被剥夺了描述中“无人监管”的部分?我也是😊

无论如何,图算法可能为更真实的无监督主题建模方法提供一个可能的答案。在剩下的部分中,我将演示如何使用 Louvain 社区检测算法创建主题模型,可视化网络,并提供一些未来方向的提示。

构建单词的网络图

网络图只是一系列通过边连接的节点。在页面上的单词的上下文中,我们可以根据它们在句子或段落中的共同提及来连接两个单词。例如,如果单词“apple”和“eat”同时出现在同一段落中,我们可以如下图所示:

作者图片

在这个简单的例子中,我们可以得出结论,给定的文本段落有一个关于吃苹果的主题。

让我们来看看如何使用 Python 创建一个单词网络。

为了实现第一个目标,我们需要确定数据的来源。对于这个例子,我使用了一些来自社会心理学课程学生的 Word 文档。希望我们的主题模型能帮助我们了解他们写的是什么。下面是我在这个例子中工作的环境:

Windows 10 操作系统

Python 3.6

我们需要的包是:

networkx==2.5nltk==3.5python_louvain==0.14pandas==0.25.0community==1.0.0b1scikit_learn==0.24.2

为了建立我们的单词网络,我假设每个段落可以代表一个单独的主题,因此单词关系是在段落级别建立的。让我们加载数据,只选择前 6 个段落,并清理数据:

注意,在上面的代码中,我导入了 get_docx_text。这是一个自定义程序,可以在这里找到。

一旦数据准备好了,我就对数据进行最后一次快速清理,只关注名词。大多数话题可能是关于名词的,但是看看动词和名词或者动词和名词的二元结构也是有用的。

大厦边缘列表

当将数据设计成图形工具和技术认可的格式时,我们需要边列表或邻接矩阵。在这个例子中,我从术语-频率-逆-文档-频率矩阵构建了一个边缘列表。结果边缘列表包含前 100 个单词的“目标”列、表示每个段落的“源”列和提供该文档(例如段落)的单词的 TFIDF 值的“计数”列。

建图

一旦我们创建了边列表,我们现在就可以用 Python 构建一个 graph 对象。在接下来的两个函数中,我们传递一个包含“目标”、“源”和“权重”(我们称权重为“计数”)列的数据帧,以便构建图表。

df_to_graph 函数将返回两种图形类型中的一种,即一部分图形或二部分图形。不要太专业,我们在这个例子中的图是二分的。它是由两部分组成的,因为单词与段落相关,我们没有将这些单词直接相互关联(尽管我们可以)。但是我们最终确实想要将单词彼此联系起来,所以我们利用我们的图的二分性质,创建单词关系的一分投影。

概念如下:如果一个单词和另一个单词出现在同一个段落中,那么我们就把它们连接起来。连接两个单词的权重是它们的 tfidf 值之和(my_weight 函数)。

最后一行代码用 Python 生成了社区解决方案。

可视化图形

用 Python 生成社区检测解决方案远不如可视化和导航网络有趣。所以,我现在转向 Gephi 。要将 Networkx graph 对象保存为 Gephi 可读的格式,请使用以下代码:

nx.write_gexf(G, “path/to/save/your/graph.gexf”)

快速格式化后,这是我们的图表:

作者图片

有点乱吧?为了增加更多的可解释性,我根据权重过滤掉一些边,并在图上运行一些统计数据,包括在过滤后的图上进行 Louvain 社区检测。一旦完成,这些额外的统计数据就可以作为添加颜色、调整节点大小和调整这些节点上的标签大小的选择。

作者图片

这是由此产生的两个社区解决方案:

作者图片

我们学到了什么?

根据社区检测模型发现的两个主题,我们了解到学生们写的是暴力和脱敏。

很酷,对吧?但是我们能从这里去哪里呢?

展望未来

在本文中,我们演示了一个简单的实现,它使用图算法根据段落中的单词关系来识别主题。虽然它很酷,但仍然有一些明显的局限性。一个限制是结果有点像 K-Means 结果,因为单词被“硬聚类”成一个且只有一个聚类。也就是说,我们可以清楚地看到,一个主题中的单词仍然与分配给其他主题的单词有边(关系)。

另一个限制是很难将一个段落分配给一个主题。解决这个问题的一种方法是根据单词及其权重建立一个分类模型,以便预测哪个段落覆盖哪个主题。显然这不像 sci-kit 的那样简单”。预测”界面,但这是一种可能的解决方案。

尽管有这些限制,图形仍然是建模数据的一种有用方法。除了节点之间的关系之外,图表还允许我们给节点和边分配属性,这可以使它们自身有助于更复杂的图表方法,这可能对理解单词关系有所暗示。实际上,这里的是一篇使用单词嵌入作为节点属性的论文,用图形来通知更复杂的主题建模方法。

我希望这篇文章能启发你更多地思考图形分析及其对数据科学问题的潜在价值。前进!

喜欢连接以了解更多关于数据科学的信息?加入我。

变形金刚在图像识别方面比 CNN 强吗?

原文:https://towardsdatascience.com/are-transformers-better-than-cnns-at-image-recognition-ced60ccc7c8?source=collection_archive---------0-----------------------

了解视觉转换器:用于图像识别的转换器

论文链接—https://arxiv.org/pdf/2010.11929.pdf

如今在自然语言处理(NLP)任务中,变换器已经成为 goto 架构(如 BERT、GPT-3 等)。另一方面,变形金刚在计算机视觉任务中的使用仍然非常有限。对于计算机视觉应用(如 Xception、ResNet、EfficientNet、DenseNet、Inception 等),大多数研究人员直接使用卷积层,或者在卷积块的同时添加某些注意块。关于视觉变换器(ViT)的论文实现了一个纯变换器模型,不需要卷积块,对图像序列进行分类。该论文展示了 ViT 如何在各种图像识别数据集上获得比大多数最先进的 CNN 网络更好的结果,同时使用相当少的计算资源。

视觉变压器(ViT)

转换器是对数据序列(例如一组单词)进行操作的网络。这些单词集首先被标记化,然后被输入到转换器中。转换器增加了注意力(二次运算——计算每对标记化单词之间的成对内积)。字数越多,运算次数也越多)。

图像因此更难在变形金刚上训练。图像由像素组成,每个图像可以包含数千到数百万个像素。因此,在转换器中,每个像素将与图像中的每个其他像素进行成对操作。在一个大小为 500*500 像素的图像中,这是 5002,所以注意机制将花费(5002)^2 运算。即使使用多个 GPU,这也是一项艰巨的任务。因此,对于图像,研究人员大多使用某种形式的局部注意力(像素簇),而不是使用全局注意力。

ViT 的作者通过使用全局注意力来解决这个问题,但不是在整个图像上,而是在多个图像块上。因此,首先将一幅大图像分成多个小块(例如 16*16 像素)。这如图 1 所示。

图一。图像分成多个小块(来源:来自原始纸张的图像)

然后,这些图像块被展开成一系列图像,如图 2 所示。这些图像序列具有位置嵌入。

图二。展开成一系列图像的图像块(来源:来自原始文件的图像)

最初,变形金刚不知道哪个补丁应该放在哪里。因此,位置嵌入有助于转换器理解每个补丁应该放在哪里。在论文中,作者使用 1,2,3…n 的简单编号来指定补丁的位置,如图 3 所示。这些不仅仅是数字,而是可以学习的向量。也就是说,不直接使用数字 1,而是存在一个查找表,该查找表包含代表补片位置的每个数字的向量。因此,对于第一个补丁,从表中获取第一个向量,并与补丁一起放入转换器中。类似地,对于第二个面片,从表中获取第二个向量,并将其与第二个面片一起放入转换器中,依此类推。这如图 4 所示。

图 3。具有位置嵌入的补丁(来源:图片来自原始论文)

图 4。作为向量表示的位置嵌入(来源:图片由作者创建)

图像补丁是一个小图像(1616 像素)。这需要以某种方式输入,以便变压器能够理解。一种方法是将图像展开成 1616 = 256 维的向量。然而,论文作者使用了线性投影。这意味着只有一个矩阵,表示为“E”(嵌入)。取一个小块,首先展开成一个线性向量。然后,这个向量与嵌入矩阵 e 相乘。然后,最终结果与位置嵌入一起被馈送到变换器。

然后,所有的补片(线性投影)连同它们各自的位置嵌入被输入到一个变换编码器中。这个变压器是一个标准的变压器架构(你需要的只是注意力——纸)。

有一个额外的可学习嵌入,标记为位置 0,如图 5 所示。这种嵌入的输出用于最终对整个图像进行分类。

图 5。整个 ViT 架构,带有额外的可学习嵌入——用红色标记,最左边的嵌入(来源:图片来自原始论文)

结果

表 1 显示了 ViT 与最先进的 CNN 架构在不同数据集上的结果对比。ViT 在 JFT-300 数据集上进行了预训练。下面的结果表明,在所有数据集上,ViT 的性能都优于基于 ResNet 的体系结构和 EfficentNet-L2 体系结构(针对有噪声的学生权重进行预训练)。这两种模型都是当前最先进的 CNN 架构。表 1 中,ViT-H 指的是 ViT-Huge(32 层),ViT-L 指的是 ViT-Large(24 层)。ViT-H/L 后面的数字 14 和 16 表示从每个图像中创建的补丁大小(1414 或 1616)。

该表还显示,ViT 比其他两种 CNN 模型需要更少的计算资源。

表 1。在各种图像数据集上将 ViT 结果与其他 CNN 架构进行比较(来源:原始论文中的表格)

图 6 显示了变压器在对各种图像进行分类时所给予的关注。

图 6:从输出记号到输入空间的注意机制(来源:图片来自原纸)

结论

视觉变形金刚会在计算机视觉任务中取代 CNN 吗?

到目前为止,CNN 已经统治了计算机视觉任务。图像基于这样一种思想,即一个像素依赖于它的相邻像素,下一个像素依赖于它的紧邻像素(无论是颜色、亮度、对比度等等)。美国有线电视新闻网的工作就是基于这个想法,在一幅图像上使用过滤器来提取重要的特征和边缘。这有助于模型仅从图像中学习必要的重要特征,而不是图像的每个像素的细节。

但是,如果将整个图像数据输入到模型中,而不仅仅是过滤器可以提取的部分(或它认为重要的部分),则模型表现更好的机会更高。这正是视觉变形金刚内部正在发生的事情。这可能是为什么在这种情况下,视觉变形金刚比大多数 CNN 模型更好的一个原因。

但这是否意味着未来在计算机视觉任务中,变形金刚会取代 CNN 的?

答案是,不会这么快。就在几天前,EfficientNet V2 模型发布了,它的性能甚至比视觉变形金刚还要好。这只是意味着,随着更新、更好、更高效的模型在不久的将来不断推出,我们可以期待两种类型(CNN 和变形金刚)的新架构一决高下。

我们都是贝叶斯吗?我们的大脑是这样认为的

原文:https://towardsdatascience.com/are-we-all-bayesian-our-brains-think-so-555cedaffed9?source=collection_archive---------22-----------------------

递归神经网络,吉莫,史酷比,设计思维和多样性说明

贝氏思考世界,由妮可·霍尔茨提供

当把加纳和童(2020)和阿南塔斯瓦米(2021)最近的两篇文章放在一起考虑时,人们会认为我们都是贝叶斯主义者。

贝叶斯定理的核心是从过去(即先验)获得的知识是未来预测的先导。然而,我们的贝叶斯思维显然是不完美的。问问任何试图预测股票价格的人,或者我们的下一次鼻塞是真的还是又一次新冠肺炎的前兆。

我们在预测未来时经常出错。我们可能会根据我们经历的症状错误地评估疾病的原因。但是我们确实在学习,而且当我们权衡更多的证据时,我们通常会变得更好。这可能反映了贝叶斯定理的作用。

Ananthaswamy 描述了递归神经网络(RNNs)如何模拟大脑功能。在这个预测过程中使用先验信息暗示了 RNN 的贝叶斯根源,这也是我今天文章的主题。

作为“预测机器”的大脑

Ananthaswamy (2021)说,我们的大脑是“预测机器”,从我们的五官中吸收信息,以评估事情发生的原因。然后,当我们收到新的信息时,我们会更新这些预测。“通过预测性处理,”他说,“大脑利用其对世界的先验知识,对传入的感觉信息的原因做出推论或产生假设。这些假设——而不是感官输入本身——在我们的脑海中引发了感知。”大脑,看起来,是一个机器学习装置!

这意味着大脑不仅仅是把我们看到的、听到的、闻到的、尝到的或触摸到的东西储存在大脑的书架上,然后立即识别潜在的原因。在感知事物和解释它之间有一个中间的机器学习步骤,这个步骤的操作就像贝叶斯 RNN。计算神经科学家正在测试这一中间步骤假说,越来越多的证据表明,RNN 模拟了动物用来理解环境的生物过程。

RNN 是一个涉及多层神经元的深度学习过程。如果神经科学家的推理路线是正确的,那么在他们的深度学习模型中创建的数学神经元类似于现实生活中动物用来理解事物的神经细胞。因为人类也是动物,我们的思维过程可能和 rnn 一样产生预测。一旦更多的感官输入被收集和分析,这些预测中的错误要么永久存在,要么被纠正;这就是贝叶斯理论发挥作用的地方。

为了了解这可能是如何操作的,考虑一下 Anathaswamy 的论文中的“基于预测的感知”图像。该图显示了两股相互作用的神经元,一股反映感官输入,另一股反映 RNN 模型根据该输入做出的预测。一旦在一个链中进行了预测,它将被发送回另一个链中的输入层,因此它可以与新信息一起作为贝叶斯先验来生成更新的预测。

数学支持和逻辑流程

接受感知是贝叶斯的概念也需要接受它们是概率性的。Garner 和 Tong (2020)在一篇文章中提供了支持概率贝叶斯 RNNs 的数学。他们对贝叶斯神经网络的推导可以用来解释动物,也许还有人类的神经网络是如何随着来自我们感官的新信息不断更新产生感知的预测的。这给我们留下了以下总结,尽管仍然是假设性的,逻辑流程:

基于来自多种感觉的输入的感知由递归神经网络的生物版本产生。

Anathaswamy 审查的证据通过显示 RNNs 如何在动物大脑中工作为这一假设提供了支持。

在一篇无关的论文中,Garner 和 Tong 提供了数学证明递归 rnn 有贝叶斯根。

综合考虑,他们的工作可以被解释为提供了动物如何解释其环境的数学和生物学机制。这种机制是否是真正的因果关系仍在争论中。

逻辑流程的最后一点无可否认是另一个假设的延伸——我的观点是贝叶斯 RNN 也适用于人类。需要更多的研究来评估这一假设的有效性,但对我来说这似乎很有说服力。

Unsplash.com 上迈克·刘易斯的照片

贝叶斯网络的一些类比和其他证据

你看过从 1969 年到 70 年代中期的经典史酷比卡通片吗?今天 YouTube 上有更新的版本。当我们还是孩子的时候,我和我的朋友们看原版电影是我们周六早晨例行公事的一部分。每幅漫画都展示了弗雷迪、达芙妮、维尔玛、沙吉和他们的狗伙伴史酷比将如何合作,吸收和权衡越来越多的证据,解决一个又一个的谜团。(剧透预警,他们遇到的神秘恶灵从来不是真鬼!)自己去看看他们是如何不断更新他们的假设,以创造出对邪恶环境更真实、更准确的认知。确实是卡通的贝叶斯人!

另外两个类比来自于人类如何在现实生活中有效地合作以理解他们的环境并产生更好的洞察力的例子。一个被称为设计思维,另一个由更多样化的劳动力及其下游建模方法来说明。

Friis Dam 和 Siang (2020)提供了一个关于设计思想的很好的描述。引用他们的网站:

设计思维是一个迭代的过程,在这个过程中,我们试图理解用户,挑战假设,重新定义问题,试图找出替代的策略和解决方案,这些策略和解决方案在我们最初的理解水平下可能不会立即显现出来。同时,设计思维提供了一种基于解决方案的方法来解决问题。它是一种思考和工作的方式,也是实践方法的集合。

它们还提供了一个总结设计思维方法的步骤列表。再次引用,这些步骤包括努力:

与你的用户共情

定义—您的用户的需求、他们的问题和您的见解

创意——通过挑战假设和创造创新解决方案的想法

原型—开始创建解决方案

测试—解决方案

重要的是,作者指出了这个过程的迭代(有人可能会说贝叶斯 RNN)性质。为了给客户的问题找到最好的解决方案,我们鼓励参与者互相挑战,在不同的阶段之间来回转换。这将有助于巩固他们对需求、为满足这些需求必须克服的挑战、潜在解决方案以及实现这些解决方案的最佳方式的理解。迭代设计思维过程也将帮助他们预测提议的解决方案的可能结果。

史蒂文·拉斯里在 Unsplash.com 拍摄的照片

劳动力多样性的概念也是类似的。在机器学习或其他人工智能建模工作的背景下,多样性意味着拥有一个项目设计和分析团队,其成员反映了他们研究对象的环境和文化特征。这也意味着使用充分代表这些主题的数据来预测感兴趣的结果。多样性还意味着测试模型,以了解数据生成过程或结果是否会因年龄、性别表达、种族、民族、收入或其他与环境相关/重要的因素而有显著差异。像这样的敏感性分析是贝叶斯精神的证据,也是做出准确推断的关键。

确保多样性很难。我们的建模团队可能无法充分代表感兴趣的主题。可能无法获得专家或利益相关方的建议。我们可能缺乏数据,我们的预算和研究环境并不总是有利于使用最佳方法。然而,致力于多样性将确保各种各样的设计、方法和解释将被考虑。这将有助于我们在分析过程中不断迭代,从而获得更好的解决方案,避免我们的模型出现偏差(Obereyer 等人,2020;霍尔等人,2021 年)。

限制和最终想法

如果我们的大脑是数学和概率贝叶斯机器,为什么我们不能完美地解释我们的感官并对现实产生准确的感知?数学不是不可改变的吗?当只有一个人是正确的时候,为什么我的看法可能与你不同?答案是,我们的大脑数学很好,但它的感官输入受到我们独特的历史经历和我们所处环境的影响。这些会影响我们的先验知识,进而影响我们的感知。如果我们错误地解释了历史,或者如果我们的环境受到其他不准确因素的不当影响,我们的感知可能是错误的。

我们的贝叶斯思维机器的历史和环境依赖性也是我们的预测和感知具有内在不确定性的一个原因。我们的置信区间的大小是不同的,所以我可能会比你更有把握地正确或错误地解释一些事情。希望随着更多信息的到来,我们的确定性和准确性变得更好,我们的思维机器继续权衡证据,但不能保证这将导致完美的理解。如果随着时间的推移,我们总是能更好地描述现实,我们就不会背负如此荒谬的阴谋论。我们将能够更好地从虚构中找出真相,争议最终会平息。

相关的一点与记忆功能有关;这也可以从贝叶斯的角度来看。记忆是一种保留我们的先验的装置,然后影响后验概率的产生。但记忆的准确性因人而异,我们的记忆随着时间的推移以不同的速度退化(Yassa 等人,2011 年)。记忆也是上下文相关的。然而,Anathaswamy (2021)指出,记忆是 RNN 有效运作的关键,也可能是 rnn 有用的原因。如果我们想改善我们的大脑机器,努力改善我们的记忆将是一个很好的开始。

以科学为基础的感官解读方法也会提高我们感知的准确性,但那是另外一个故事了。

作为最后一个想法,支持贝叶斯 RNN 感知产生过程的证据仍然是间接的,但似乎贝叶斯定理几乎可以在我们看到的任何地方找到。因此,如果我们的目标是对我们的世界如何运作产生越来越现实的预测和准确的感知,那么在我们所有的数据科学项目中纳入至少一种贝叶斯方法可能是有用的。

参考文献:

A.Anathaswamy,你的大脑是一台节能预测机器(2021),在https://www . wired . com/story/Your-Brain-is-a-Energy-Efficient-Prediction-Machine/?bxid = 5b a08 b 63 f 92 a 4046944073 e&cn did = 37560534&esrc = AUTO _ OTHER&hashc = cc 9 CB 28 C4 DBD 883035113 D8 b 812 fa 1 ecdc 6 e 97567 C2 e C2 E0 b 3497 dcc0e 716535&mbid = mbid % 3 crmwir 012019% 0A % 0A【0A

R.什么是设计思维?为什么它如此受欢迎?(2020 年),在https://www . interaction-design . org/literature/article/what-is-design-thinking-and-why-it-so-popular

页(page 的缩写)神经网络中递归的贝叶斯方法(2020),arXiv:1910.11247v3 [cs .LG]2020 年 4 月 20 日。

页(page 的缩写)Hall,N. Gill 和 B. Cox,《负责任的机器学习》( 2021 年),波士顿,MA: O'Reilly Media 公司。

Z.Obermeyer,R. Nissan,M. Stern 等人,《算法偏差剧本》(2020 年),芝加哥布斯:应用人工智能中心。同样在https://www . FTC . gov/system/files/documents/public _ events/1582978/algorithm-bias-playbook . pdf

米(meter 的缩写))A. Yassa,A. T. Mattfeld,S. M. Stark 和 C. E. L. Stark,年龄相关的记忆缺陷与海马体中特定回路的中断有关(2011 年),PNAS 108(21):8873–8878,也在 https://doi.org/10.1073/pnas.1101567108[的](https://doi.org/10.1073/pnas.1101567108)

我们在宇宙中是孤独的吗?飞碟目击的数据分析和数据可视化

原文:https://towardsdatascience.com/are-we-alone-in-the-universe-data-analysis-and-data-visualization-of-ufo-sightings-with-r-42d0798679c3?source=collection_archive---------7-----------------------

如何分析和可视化美国和世界其他地方上个世纪的 UFO 目击数据

仪表板,以查看生成的关于不明飞行物目击的情节。文末的链接

人类可以问自己的一个问题是,我们在宇宙中是否是孤独的。我认为,假设我们是唯一一个拥有足够智慧去拜访宇宙中其他世界的文明,这将是荒谬和极其徒劳的。如果比我们更聪明的其他文明已经拜访过我们了呢?如果他们现在正在看着我们呢?如果天空中那些奇怪的未知景象与此有关呢?

“或者也许他们在这里,但是因为一些卡拉狄加的法律,一些不干涉新兴文明的道德准则而藏了起来。我们可以想象他们好奇而冷静地观察我们,就像我们观察琼脂培养皿中的细菌培养一样,以确定今年我们是否能够避免自我毁灭。”
——卡尔·萨根,

照片由阿尔伯特·安东尼在 Unsplash 拍摄

2020 年 4 月,五角大楼解密了美国海军录制的三段视频,确认了它们的真实性。在这些视频中,你可以看到不明飞行物飞过天空,无视我们所知道的物理定律。

平均每三个人中就有一个人目睹过天空中一些不寻常的现象,我们通常称之为“UFO 现象”。

数据准备

这是一个包含世界各地 UFO 目击数据的数据集。它包括了上个世纪向国家 UFO 报告中心(NUFORC)报告的超过 80,000 份 UFO 目击记录。该数据集在网上免费提供,数据可以从 Kaggle (通用公共许可证)下载

现在,您将加载将在分析过程中使用的库并读取数据。

# REQUIRED LIBRARIESlibrary(dplyr);
library(ggplot2);
library(mclust);
library(lubridate);
library(mapdata);
library(maps);# READ DATAdataUfo <- read.csv(file="data/scrubbed.csv", header=T);dataUfoClear <- dataUfo %>%
  dplyr::select(latitude, longitude, shape, country,
                datetime, date.posted, city, state,
                duration = duration..seconds.);

在原始数据集中可以找到以下字段:

日期时间——UFO 目击事件发生在这个日期和这个时间。
城市——不明飞行物目击的地点。
—该州以发现它的城市命名。
国家 —基于州,发现它的国家。
形状 —看到的 UFO 的形状。
持续时间(秒) —以秒为单位,照准的长度。
【分钟】 —以分钟为单位,照准的长度。
评论——看到不明飞行物的人做了如下评论。
发布日期 —当目击事件被报告给 NUFORC 时,这就是日期。
纬度 —照准的纬度。
经度 —照准的经度。

在对数据集进行第一次检查后,发现有些数据不完整,因为缺少一些列。此外,该集合中的一些数据不适合该目的。因此,我们稍微清理了一下数据,使其更易于分析。下面的代码演示了如何清理数据。

# DATA CLEANdataUfoClear$latitude <- as.numeric(as.character(dataUfoClear$latitude));
dataUfoClear$longitude <- as.numeric(as.character(dataUfoClear$longitude));
dataUfoClear$country <- as.factor(dataUfo$country);
dataUfoClear$datetime <- mdy_hm(dataUfoClear$datetime);
dataUfoClear$date.posted <- mdy(dataUfoClear$date.posted);
dataUfoClear$duration <- as.numeric(as.character(dataUfoClear$duration));# DATA USAdataUfoClear <- na.omit(dataUfoClear);
dataUfoUSA <- filter(dataUfoClear, country=="us" & !(state %in% c("ak", "hi", "pr")));head(dataUfo);
head(dataUfoClear)

数据字段**“注释”**出现在该数据集中。一个科学的文本分析会消耗整个研究,这就是为什么选择不考虑它而专注于其他数据。持续时间(分钟)功能也被取消了,因为它与持续时间(秒)相比是多余的。您将用于分析的更准确的数据集描述如下:

日期时间——UFO 目击事件发生在这个日期和这个时间。
城市——不明飞行物目击的地点。
—该州以发现它的城市命名。
国家 —基于州,发现它的国家。
形状——看到的 UFO 的形状。
持续时间——以秒为单位,照准的长度。
发布日期 —当目击事件被报告给 NUFORC 时,这就是日期。
纬度 —照准的纬度。
经度 —照准的经度。

可以看出,数据集包含一些有趣的数据。考虑到这一点,我想提出一系列问题,这些问题可以通过彻底的研究来解决,从而提取有用的信息并得出结论。

哪个国家目击 UFO 的次数最多?

根据数据集,要执行的第一个分析是确定在上个世纪地球上哪个国家出现的次数最多。

# COUNTRY MOST UFO SIGHTINGSlevels(dataUfoClear$country) <- c("Rest of the world", "Australia", "Canada", "Germany", "Great Britain", "United States");
ggplot(dataUfoClear, aes(x=reorder(country, country, FUN=length), fill=country)) +
  stat_count() + 
  theme_bw() + 
  scale_fill_brewer(palette="Dark2") +
  labs(x = "Country", y = "Number of sightings", 
     title="Most UFO sightings by Country", 
     subtitle = "United States and Rest of the world")

根据柱状图,美国在上个世纪是目击数量最多的国家。也许因为 NUFORC 是一个总部设在美国的组织,大多数美国人意识到他们可以报道他们所看到的。因此,您可以将这些数据的分析集中在美国。

UFO 目击事件的数据分析和数据可视化-按国家绘制大多数 UFO 目击事件

UFO 目击事件的全球密度是多少?

之前已经确定美国比其他任何国家都有更多的目击事件。但是首先,让我们画一张世界地图来检查在每个国家的目击事件有多密集,以及它们是否只出现在这个国家的一个地区或整个地区。

# HOW DENSE SIGHTINGS AROUND THE WORLDggplot(dataUfoClear, aes(x=longitude, y=latitude, colour=country)) + 
  borders("world", colour="gray", fill="seashell3") +
  geom_point(shape=15) +
  theme_bw() + 
  labs(x = "Longitude", y = "Latitude", 
       title="Map UFO sightings around the world", 
       subtitle = "United States and Rest of the world")

这张地图也支持了这样一种观点,即美国比其他任何国家都有更高的目击密度。你可以看看它们在各州的分布情况。

UFO 目击事件的数据分析和数据可视化——绘制全球 UFO 目击事件地图

UFO 目击事件在美国是如何分布的?

现在您已经确定了美国拥有最多和最密集的目击事件,您可以查看每个州的目击事件数量。

# SIGHTINGS IN UNITED STATESggplot(dataUfoUSA, aes(x=reorder(state, state, FUN=length), fill=state)) + 
  stat_count() +
  theme_bw() + 
  theme(axis.text.x = element_text(angle=45, size=9, hjust=1)) + 
  labs(x = "State", y = "Number of sightings", 
       title="UFO sightings in United States", 
       subtitle = "Sightings by state")

直方图显示,该州指定的“ca”,即加利福尼亚州,在上个世纪有最多的 UFO 目击事件。

UFO 目击事件的数据分析和数据可视化——美国 UFO 目击事件的绘图

你也可以在一张完整的美国地图上看到同样的结果。

UFO 目击的数据分析和数据可视化——美国 UFO 目击地图

出现的最典型的 UFO 形状有哪些?

你可以看看世界上存在的最普遍的形状,因为你已经按国家和州查看了 UFO 活动。

# MOST SHAPES THAT APPEARggplot(dataUfoClear, aes(x=reorder(shape, shape, FUN=length), fill=shape)) + 
  geom_bar(show.legend=F) +
  coord_flip() +
  theme_bw() + 
  labs(x = "Shape", y = "Number of sightings", 
       title="Most typical UFO shapes that appear", 
       subtitle = "UFO shapes seen around the world")

条形图显示,描述的最常见的形状是一个标记为“光”的普通形状,它经常被有这种经历的人解释为耀眼的光环。

UFO 目击的数据分析和数据可视化——绘制最典型的 UFO 形状

UFO 目击事件和时间有关联吗?

你可以看看目击的次数和一天中的时间是否有关联。此外,您可以用月份和年份进行测试。

# CORRELATION BETWEEN THE TIME AND SIGHTINGSggplot(dataUfoClear, aes(x=hour(datetime))) + 
  geom_histogram(bins=24, aes(fill=..count..)) +
  theme_bw() + 
  scale_fill_gradient(low = "palegreen", high = "palegreen4") +
  labs(x = "Hour of the day", y = "Number of sightings", 
       title="Correlation between daytime / UFO sightings", 
       subtitle = "Sightings during the day")

直方图清楚地表明,大多数的目击事件发生在没有光线或光线很弱的时候。然而,值得注意的是,白天也有不明飞行物的报道。

UFO 目击事件的数据分析和数据可视化——日间/ UFO 目击事件之间的关联图

不明飞行物的形状和时间有关联吗?

你可以看看形状和一天中的时间之间的关系。这可以解释为什么光的形状是最常被报道的形状。

# CORRELATION BETWEEN THE TIME AND UFO SHAPEshapesDaytime <- 
  dataUfoClear %>% 
  group_by(hour=hour(datetime), shape, duration) %>% 
  summarize(count=n());

ggplot(shapesDaytime, aes(x=hour, y=shape)) + 
  geom_point(aes(color=count, size=count)) + 
  scale_colour_gradient(low = "palegreen", high="palegreen4") +
  labs(x = "Hour of the day", y = "UFO Shape", 
       title="Correlation between daytime / UFO Shape", 
       subtitle = "Sightings during the day")

从图中可以看出,这些形状在夜间也更加普遍/持久。我们可以看到,与其他常见形状相比,光在夜间和傍晚出现的频率更高,但在白天出现的频率较低。

UFO 目击的数据分析和数据可视化——白天/ UFO 形状之间的绘图相关性

现在,您将进行“卡方”测试,看看一天中的时间和形状之间是否有联系。

假设:每个样本观察值都是独立的,进行卡方独立性检验。每个案例至少有一个条目。

chisq.test(dataUfoClear$shape, hour(dataUfoClear$datetime), simulate.p.value=T);

从这些数据中可以看出,p 值小于 0.05,即 p 0.05,这表明 UFO 的形状确实取决于一天中的时间。

UFO 观测的数据分析和数据可视化— RStudio 控制台卡方输出

随着时间的推移,UFO 目击的频率上升了吗?

你希望在静态时刻研究 UFO 遭遇后,分析整个时间的 UFO 遭遇。

# SIGHTINGS BY YEARsightingsYear <- 
  dataUfoClear %>% group_by(year=year(datetime)) %>% 
  summarize(count=n());# REPORTS BY YEARreportsYear <- 
  dataUfoClear %>% group_by(year=year(date.posted)) %>% 
  summarize(count=n());ggplot(sightingsYear, aes(x=year, y=count)) + 
  geom_line(size=1, colour="palegreen4") + 
  geom_line(data=reportsYear, aes(y=count), size=1, colour="red") + 
  geom_smooth(method="lm") +
  labs(x = "Year", y = "red = reports, green = sightings", 
       title="UFO sightings / UFO reports by year", 
       subtitle = "Sightings during the day")

不仅在美国,全世界报告和发现的病例数量也在增加。从线性回归图中可以看出,UFO 目击数量并不是线性增长的。

UFO 目击事件的数据分析和数据可视化—按年份绘制 UFO 目击事件/ UFO 报告

总之,你的发现表明,美国,即加利福尼亚州,有最高的目击数量。然而,要注意的重要一点是,根据人口密度,华盛顿州的目击密度高于加利福尼亚州。加利福尼亚州和华盛顿州都已经将娱乐用大麻合法化,这可以解释为什么在西海岸有这么多的目击事件。

布鲁斯·沃林顿在 Unsplash 上的照片

同样值得注意的是,这种被称为“光”的形状在每个国家都是有史以来最常被记录的,而且主要发生在晚上。随着时间的推移,目击和报告的数量似乎有所上升,但最近有所下降。我们不能根据这种分析来确定外星人是否存在,因为我们只有关于目击的信息。

这些 UFO 目击事件可能只是这些国家的技术测试吗?这些不明飞行物会不会是被派去评估先进国家力量的外星人的先进工具?只有时间和额外的数据会提供答案,但那是另一个数据分析实验的主题。

非常感谢您的善意阅读。和我的大部分文章一样,我在一个 flexdashboard 中分享了与一起产生的情节,我把它放在一起更有美感一点:https://rpubs.com/cosmoduende/ufo-sightings-usa-world

在这里你可以找到完整的代码:https://github.com/cosmoduende/r-ufo-sightings

感谢你坚持到最后,祝你分析非常愉快,可以把一切都付诸实践,对结果感到惊讶,和我一样开心!

我们准备好迎接全自动社会了吗?

原文:https://towardsdatascience.com/are-we-ready-for-a-fully-automated-society-f13a13fa2cb1?source=collection_archive---------14-----------------------

意见

分析使用人工智能取代人类工作的伦理含义和局限性

莱尼·屈尼在 Unsplash 上的照片

2005 年,著名的未来学家 Ray Kurzweil 描述了奇点——一个机器智能变得比所有人类智能加起来还要强大的时间点。与奇点密切相关的一个想法是用人工智能实现人类工作的自动化。

人类劳动的自动化是我们今天已经可以看到的现象。无收银员的商店和配备机器人服务器的餐馆只是自动化的两个例子。有些人甚至相信,在某一时刻,所有的工作都将由计算机程序自动完成。但真正的问题是,我们真的能用人工智能实现所有工作的自动化吗?即使我们可以自动化许多工作,这个世界真的为完全自动化做好准备了吗?

人工智能的现状

当考虑人工智能运行社会的可能性时,我们必须问的第一个问题是人工智能的当前状态和能力。人工智能有四种类型,可以被视为不同的复杂程度。

  1. 无功艾
  2. 有限的内存
  3. 心理理论
  4. 自我意识

前两种类型的人工智能已经存在于今天的世界,但最后两种类型是理论概念,不会成为现实,直到未来的某个时候。

活性人工智能

反应式人工智能没有记忆的概念,只是被设计来对某些输入做出反应并产生一个输出。反应式人工智能是最简单的人工智能形式,大多数早期的人工智能系统都属于这一类。

IBM 的深蓝,一台打败了加里·卡斯帕罗夫的象棋计算机,是反应式人工智能的一个例子。图片来源:科学美国人。

有限记忆人工智能

有限记忆人工智能能够从过去的经验中学习,并具有一定程度的记忆,允许它随着时间的推移提高性能。深度学习的许多进步,如使用 LSTMs 处理序列数据和强化学习的发展,已经使这种类型的人工智能成为现实。

自动驾驶汽车是有限记忆人工智能的一个例子。罗伯特·尼克森在 Unsplash 上的照片

心理理论人工智能

当机器有能力与人类的思想和感情互动时,我们将达到“心理理论”人工智能。心理理论是心理学中的一个概念,指的是通过将精神状态归因于他人来理解他人的能力。当机器拥有这种能力时,它们将拥有社交和情商,这使它们能够解决更广泛的问题。

照片由安迪·凯利在 Unsplash 上拍摄

自我意识人工智能

当 AI 使机器能够实现具有自我意识的智能时,具有自我意识的 AI 将成为现实。在这一点上,由具有自我意识的 AI 驱动的机器将是有意识的实体,这就提出了机器和人类如何共存的问题。

照片由 Arseny Togulev 在 Unsplash 上拍摄

哪些工作可以轻松实现自动化?

涉及重复步骤或可预测决策的工作可以使用反应式人工智能实现自动化。这些工作通常涉及体力劳动或涉及遵循明确说明的任务。属于这一类别的工作包括:

  • 制造业和仓库工作。
  • 建筑中的体力劳动工作。
  • 商店店员和收银员的工作。
  • 废物管理工作。
  • 农业中的体力劳动工作(灌溉、收割等)。)

上面的列表绝不是详尽的,但这里的关键点是,所有这些工作都涉及到带有明确定义的指令或可预测决策的任务,即使有反应式人工智能,机器也可以遵循这些指令或决策。

哪些工作最终可以实现自动化?

涉及基于过去事件和不同情况的更复杂决策的工作最终可以自动化,但比涉及重复的算法任务的工作更难自动化。属于这一类工作的一个很好的例子是出租车司机的工作。

驾驶过程中肯定会涉及到决策模式,但驾驶员需要能够根据具体情况做出决策。例如,我们可以训练自动驾驶汽车在看到人脸时停下来。但是,车遇到一个脸被遮住的人怎么办?汽车遇到过马路的不是人而是狗怎么办?作为人类,我们可以根据以前的经验和我们所谓的“常识”本能地做出这些决定。

驱动自动驾驶汽车的人工智能模型需要经过训练,以便对各种各样的情况做出适当的反应,并保留一定程度的关于过去事件的记忆。一般来说,涉及更复杂、依赖于情景的决策的工作最终可以通过严格训练和测试的有限记忆人工智能来自动化。

目前哪些工作应该留给人类?

某些工作需要的智能超出了人工智能能够提供给机器的有限内存。需要社交和情商的工作可能不会很快被人工智能自动化。事实上,我认为这些工作现在应该留给人类去做。我下面列出的所有工作都需要一定程度的社交和情商,这超过了我们当前人工智能系统的极限。

心理健康专家

尼克·舒利亚欣在 Unsplash 上的照片

毫不奇怪,人工智能在目前的状态下,无法有效地自动化精神卫生专业人员的工作。治疗师、咨询师和心理学家需要能够理解他人的情绪和精神状态。在写这篇文章的时候,人工智能还不能理解人类的情感。有些人会认为,大型语言模型,如 GPT-3,能够进行类似人类的对话,但进行对话和真正理解另一个人的思想和感情是有区别的。

在我们实现心理理论人工智能之前,机器人治疗师或顾问的想法将是不可行的。事实上,我们可以放心,心理健康专家的工作将会长期存在。

医生和医务人员

照片由 Olga Guryanova 在 Unsplash 拍摄

尽管机器可能会通过使用复杂的计算机视觉模型来执行复杂的手术,如心脏移植,但在目前的状态下,医生和其他医疗专业人员的工作无法完全被人工智能取代。

医疗专业人员,尤其是那些在急诊室等高风险环境中工作的人员,需要了解生死情况的紧迫性。也有研究表明,同理心是成为一名医生的重要组成部分。简单治愈一种疾病和真正治疗一个病人是有区别的。治疗病人需要理解病人的顾虑,并把他们看作一个人,而不仅仅是一种疾病。由有限记忆人工智能驱动的机器可以胜任执行医疗程序,但总是无法在人类层面上与患者联系。

使用机器代替医生的工作也带来了伦理问题。例如,如果机器人外科医生错误地进行了肺移植手术,并导致患者严重受伤甚至死亡,那么谁应该承担责任?我们要责怪监督手术的医生吗?我们会责怪机器人背后的程序员吗?即使机器人没有意识,我们还会责怪它吗?如果我们试图用人工智能实现医疗工作的自动化,这些就是我们将面临的困境。

执法人员

马特·波波维奇在 Unsplash 上的照片

就像心理健康专家和医生的工作一样,成为一名执法人员需要社交和情商,以及超越最先进人工智能能力的情景意识水平。虽然可以训练机器开枪或检测道路上超速的车辆,但有限的记忆 AI 无法理解对其他人的安全有威胁的紧急情况。例如,记忆有限的 AI 可能能够追踪到建筑物中的活跃枪手,但无法理解枪手正在将人类生命置于危险之中,并导致建筑物中的人们恐慌。

用武器武装机器,把一个社区的人的生命交给没有意识的机器,也会带来伦理问题。如果我们武装没有感情的机器,让它们成为我们警察或军队的一部分,是什么阻止它们成为无情的杀人机器?如果警察队伍的很大一部分由机器人组成,一个社区真的会感到舒适和安全吗?如果一台机器打伤或打死了一个正在执勤的市民,谁该负责?这些问题只是凸显了一个事实,那就是我们还没有为人工智能自动化执法工作做好准备。

摘要

虽然人工智能确实是一个可以执行许多任务的强大工具,但我们需要了解人工智能的局限性,特别是在自动化人类工作方面。今天存在的最先进的人工智能形式,包括 GPT-3 等最先进的模型,是有限记忆人工智能。记忆有限的人工智能可以从过去的数据和经验中学习,但缺乏与人类的思想和感情互动的能力。这种能力通常被称为心理理论,在人类的许多工作中都需要。

如果没有社交和情商,AI 永远无法真正取代所有人类的工作。在心智理论人工智能成为现实之前,许多基本工作仍将留给人类。

加入我的邮件列表

加入我的邮件列表,获取我的数据科学内容的更新。当你注册的时候,你还会得到我免费的解决机器学习问题的逐步指南!也可以在 Twitter 关注我,了解内容更新。

当你这么做的时候,考虑加入媒体社区,阅读成千上万其他作家的文章。

来源

  1. A.辛慈,理解人工智能的四种类型,从反应式机器人到有自我意识的存在,(2016),对话。
  2. 长度 Greenemeier,深蓝 20 年后:AI 如何在征服国际象棋,(2017),《科学美国人》。
  3. E.赫希博士,医学中移情的作用:一个医学学生的视角,(2007),AMA 伦理杂志。

我们准备好迎接人工智能的脚本小子了吗?

原文:https://towardsdatascience.com/are-we-ready-for-the-script-kiddies-of-ai-754b23f5fcf8?source=collection_archive---------14-----------------------

人工智能校准和安全

我们为什么不更担心没人能解释什么样的人有资格从事人工智能工作?

由大师 1305 创作的学校照片

它始于一条深夜推特:

“我对许多没有接受过统计学培训的人工智能/人工智能工程师感到震惊。这在我看来很荒谬。想知道这是趣闻还是真实的事情?”来自@bellmar

我根本没想到会得到回应,当然也没有一群机器学习专家——其中一些我甚至不认识——跳出来说…基本上是的

在某些情况下,“是的,但是谁在乎呢?”

术语“脚本小子”描述的是没有经验的技术专家(历史上称为黑客),他们复制并粘贴别人写的他们不理解的代码。尽管它被广泛用作贬义词,但脚本小子心态是我们中的许多人如何从软件开始,下载代码,对其进行更改并观察结果。我们通过反复试验的严格探索了解了代码的作用。如果他们不失去兴趣,脚本小子最终会成长为高质量的软件工程师。

在试图为人工智能和机器学习工程师构建有效工具的过程中,我们也意外地赞同在这里应用脚本小子心态。允许开发人员加入预先训练好的模型的基础设施和应用到处都是。你如何知道你所依赖的人工智能产品是否是由一个深刻理解模型及其背后的数学的从业者构建的,而不是从 Stack Overflow 复制并粘贴代码的人?你不知道。

软件是一个通过接纳非传统背景、重新熟练工人和自学者而蓬勃发展的领域。我本人没有接受过计算机科学方面的正式培训,我对编程的第一次尝试本质上是脚本小子——我不会对此进行评判。尽管人工智能是用软件编写的,但它与传统软件的不同之处在于,看似正常工作和实际正常工作之间的界限要宽得多。你不能只盯着结果,然后推断机器学习模型是无偏的或没有错误的。

安全状态图

那些关注我的文章的人会知道,我一直在思考很多关于安全科学以及它如何适应(或不适应)人工智能的发展。有很多谈论,特别是在国防工业,围绕如何监管人工智能以确保它是负责任的和道德的。你如何控制算法的开发和使用?你认为谁应该为在 AI 的指导或协助下做出的错误决定负责? 我们如何确保这项技术安全?

奇怪的是,这里的政策对话专注于一个目标,安全科学家会告诉你这是不可能的:我们永远无法生产出不会造成伤害的人工智能技术。

但是另一方面……不可能生产出符合那个标准的任何东西。人工智能,电动工具,儿童玩具…任何可以使用的东西都可能被滥用。

一项技术不被认为是安全的,因为它是无害的。 一项技术被认为是安全的,因为操作者能够准确地评估和减轻使用它的风险。汽车不安全,因为不可能把汽车撞到树上。医疗器械不安全,因为不可能用它们伤害人。我们对电插座的安全性很有信心,并不坚持认为它们有某种智能功能,可以防止我们将叉子插入其中。

当我们确信可以预测一项技术对我们的交互会有什么反应时,我们就认为这项技术是安全的。我们不应该监管人工智能以防止负面结果,而是应该管理操作员和技术之间可能的状态。把它想象成一张图是很有用的,在图中,行动和背景因素创造了行动和反应的网络。我们通过限制这种状态图来使技术“更安全”——也就是说,限制可能改变操作员预测系统响应能力的事情的数量。

缩小状态图的一种方法是取缔一些状态。我们要求汽车配备刹车、安全带和安全气囊,因为这些功能降低了某些驾驶风险。总体风险越少,操作者就越容易相信他们了解驾驶车辆的总体风险,因此汽车变得更安全。

但是我们缩小状态图的另一种方法是提高操作员的能力。当操作员可以是任何人、任何年龄、任何经验水平时,当操作员与一项技术交互时,我们可能看到的行为集是不可能的大。当我们能够保证操作员具有一定的经验水平,并且已经掌握了一定的背景知识时,我们就消除了状态图中更多的边。

换句话说,汽车不安全,因为不可能撞上它们。我们要求汽车配有安全带,司机佩戴安全带。但是,我们也要求司机有一个最低限度的驾驶经验和基本知识测试的执照。

然而,当谈到让人工智能变得安全的问题时,我们只剩下一个问题:首先谁是操作者?操作员是建立和训练模型的机器学习工程师吗?那个人有多少经验?所有人工智能工程师必须掌握哪些基本知识?相关的学位或证书有哪些?

还是运营商就是下游用户?人工智能集成工具的使用是否应该被限制在接受过特定培训的人身上?

我们不会让没有市政工程认证的人去造桥,也不会让没有行医执照的人去做手术。现在,在人工智能重大突破的迷雾中,我们表现得好像有一些神奇的政策修正,将消除人工智能的所有负面结果,同时仍然让任何人都可以构建和使用它。

也许这是个坏主意。人工智能从业者真的没有医生、律师、房地产经纪人或我们要求人们获得许可才能从事的任何其他角色重要吗?

我们签了统计数据了吗?🤔

原文:https://towardsdatascience.com/are-we-stats-sig-yet-c78686392b26?source=collection_archive---------22-----------------------

先决条件:这个故事是为有运行实验经验的技术人员和业务人员编写的。

卡洛斯·穆扎在 Unsplash 上的照片

TL;DR——实验的目标是做出决定,而不是追求特定的显著性水平。

这是在你的业务部门进行最关键实验的第 14 天。你的领导在工作聊天中向你发出 pings 命令,并问:“我们开始了吗?”

您快速运行 t-test 并报告,“嗯,我们在 90%的显著性水平上几乎是 stats sig。”

"好吧,但是我们什么时候能达到 95%的统计签名?",领导回复。

你指回方差图来解释为什么有些实验即使设计得很好也达不到 95%的统计 sig。不太符合数学,领导回答,“但我们需要做些什么才能得到统计签名?”

好吧…

我们都经历过,对吧?

首先,让我们提醒商界人士“统计签名”是什么意思。

统计显著性(stats sig)是什么意思?

根据维基百科:

在统计假设检验中,当给定零假设的情况下一个结果不太可能发生时,该结果具有统计意义。更准确地说,一项研究的定义的显著性水平,用α表示,是假设零假设为真,该研究拒绝零假设的概率;一个结果的 p 值,p,是在假设零假设为真的情况下,获得至少是极端结果的概率。根据研究标准,当 p≤α时,结果具有统计学意义。研究的显著性水平在数据收集之前选择,通常设置为 5%或更低——取决于研究领域。

大多数数据科学家认为:

统计显著性意味着我们的实验结果不是由于随机的机会。这让我们对我们的决策充满信心,行业标准是使用 95%的统计显著性水平(p ≤ 0.05)。

根据大多数线索:

我们获得影响力、人数或晋升的防弹证据。

Stats sig 很重要,但它可能不是我们应该关注的事情。追逐像 95%显著性这样的技术阈值通常会减缓组织学习和迭代的机会。最终,决策从来都不是完美的。

**杰夫·贝索斯说,“大多数决策可能需要你希望拥有的大约 70%的信息。**如果你等了 90%,在大多数情况下,你可能很慢。”

简而言之,比相关性更好的事情就是学会采取行动。我们是否需要达到 95%显著性水平的高严谨性,这一切都取决于。应该问的问题是,我们能否在当前显著性水平上根据观察到的影响做出决策。

此时,您的利益相关者可能会问“我们没有进行统计签名的原因是什么?”这是一个公平的问题。以下是一些最常见的:

  • 样本量太小 —大多数情况下,这种情况可以在您设置实验之前通过运行功效分析来估计某个效应量(预期影响)所需的样本来回答。我说“大部分时间”是因为不是所有我们测试的产品都有历史数据来计算方差和估计影响大小。经验法则是,效应大小越小,方差越高,所需样本越大。
  • 影响太小——不是一切都好看。大多数实验失败是因为撞击不存在。延长实验时间不是解决办法。如果在估计的时间内没有看到预期的效果,最好继续前进。
  • 主要指标糟糕 —您的指标不代表您的假设,您可能使用了更难检测的滞后指标,您没有护栏指标来了解任何其他潜在的不利因素,或者您可能有太多或太少的指标。外面有很多文章,有时它更像是一门艺术(煞费苦心地与你的利益相关者保持一致,并不断完善它)而不是科学。

总之,实验的目标是做出决定,而不是追求特定的显著性水平。不要误解我,“统计信号”很重要——它验证你的假设是否有力,它给你一个信号,告诉你你的产品是否有效,它让每个人都高兴,但过分强调无助于决策。正如贝佐斯所推断的——价值在于决策的速度!下一次,如果有人问你,“我们开始签约了吗?”深呼吸,冷静下来,让我们帮助他们理解为什么这可能不是最重要的问题。给他们发这篇文章,祈祷吧🤞,并希望他们喜欢它。

这是我的第一篇文章,非常感谢你能说到这一步!如果你觉得它有趣,请鼓掌并分享它!如果你想联系,在 LinkedIn 上联系。

✌·莉莉

我们对 AI 的思考是不是错了?

原文:https://towardsdatascience.com/are-we-thinking-about-ai-wrong-4c826f9615c0?source=collection_archive---------22-----------------------

播客

Divya Siddarth 谈人工智能的更好范例,以及台湾如何在技术治理方面领先

苹果 | 谷歌 | SPOTIFY | 其他

编者按:这一集是我们关于数据科学和机器学习新兴问题的播客系列的一部分由 Jeremie Harris 主持。除了主持播客,Jeremie 还帮助运营一家名为sharpes minds的数据科学导师初创公司。

人工智能研究经常被框定为一种人类与机器的竞争,这将不可避免地导致人类的失败,甚至被人工超级智能大规模取代,这些人工超级智能拥有自己的代理意识和自己的目标。

Divya Siddarth 不同意这种框架。相反,她认为,这种观点导致我们关注人工智能的应用,这些应用既不像它们可能的那样有利可图,也没有足够的安全性来防止我们遭受危险的人工智能系统的长期潜在灾难性后果。她应该知道:Divya 是微软首席技术官办公室的政治经济学家和社会技术专家。

她还花了很多时间思考政府能够——也正在——做些什么,以将人工智能的框架从与人类直接竞争的集中系统转向更具合作性的模式,这种模式将人工智能视为一种由人际网络利用的便利工具。达薇亚指出台湾是数字民主的一个实验,台湾正在做的正是 T21 所做的。

以下是我最喜欢的一些外卖食品:

  • Divya 通过*启示的透镜来看待技术。*启示是一项技术的特征,它支持或限制我们对它的使用(“我们可以使用的杠杆”),并以微妙的方式塑造我们与技术的互动,这可能会对社会产生意想不到的重要影响。以 Instagram 为例,它有各种各样的启示,旨在使上传和分享图片变得非常非常容易。Instagram 的广泛采用——以及这些特定功能的广泛采用——导致了一个社会,在这个社会中,我们许多人都感到有一定的压力,要在没有其他方式的情况下拍摄和分享照片。同样,像 Twitter 这样的平台也有启示(比如点赞和评论区),将用户推向表演、两极分化和分裂的行为。尽管公司的既定使命可能很重要,但它对可提供性的具体选择在决定其对社会的影响方面同样重要。
  • Divya 将这种启示的概念扩展到了人工智能。她认为,今天的人工智能已经偏向于更少人类合作和更多人类竞争的应用。例如,强化学习明确地将机器学习框架为其目标是创造追求与我们不同目标的独立代理。这种类似代理的美学让人们更难将人工智能视为促进人类合作的工具,因为它正式将人工智能代理与人类决策过程分开。
  • Divya 指出,台湾是一个找到了更具建设性、以人为本的方式使用技术和人工智能来促进社会凝聚力和建立共识的国家的例子。简而言之:台湾使用一个叫做 pol.is 的工具开发了两个审议平台。这些平台允许公民就特定的政策问题发表意见,并确定共同观点的集群以及不同集群之间的共同点。重叠区域与潜在的解决方案一起被强调,结果是一组启示,它们有助于达成共识而不是竞争。

你可以点击这里在 Twitter 上关注达薇亚,或者点击这里在 Twitter 上关注我。

章节:

  • 0:00 介绍
  • 1:55 达薇亚的背景
  • 6:30 台湾的技术管理
  • 17:30 台湾科技教育
  • 28:30 当前人工智能思维的问题
  • 36:35 对复制人类行为进展的反对意见
  • 44:15 给新公司的建议
  • 57:00 等待人类文明集体有机地拿出解决方案
  • 1:01:44 个总结

我们是否在逆向思考可解释性?

原文:https://towardsdatascience.com/are-we-thinking-about-explainability-backwards-c9a719cb1250?source=collection_archive---------28-----------------------

模型可解释性

在构建人工智能解决方案之前,你应该能够回答三个问题

围绕人工智能的一个普遍问题是它的黑盒性质,但为可解释性而设计是可能的。不是每个用例都需要一个可解释的解决方案,但是很多都需要。当我们开发 XAI 时,我们经常问,“我们能解释什么?”在这篇文章中,我要求我们首先考虑最终用户。我强调了在构建你的人工智能解决方案之前要考虑的三个问题,这样它就可以通过设计来解释。

照片由法库里安设计在 Unsplash 上拍摄

动机

我的大部分博士研究都围绕着可解释的数据融合。结果,我花了相当一部分时间研究可解释的人工智能。可解释性引起了我的兴趣,因为它涉及到算法将自身的一些东西翻译给用户。哲学辩论围绕着解释的构成,但是算法解释需要向用户展示一些关于它们自己的东西。

我们以不同的方式发展 XAI 方法。一种常见的方法是独立于人工智能开发 XAI。例如,流行的 LIME [1]位于人工智能之外,允许它是人工智能不可知论者;然而,这限制了它所提供的解释类型。第二种方法是从一开始就将 XAI 直接开发到我们的人工智能中——通过设计来解释。我的 XAI 之旅凸显了在开发之初考虑最终用户的重要性。我鼓励你们思考需要建立什么,而不是能够建立什么——这是我学到的最重要的一课。

设计的可解释性给了人工智能工程师最大的自由来开发相关的解释,以赋予算法的用户权力。在我的职业生涯中,我创造了多种 XAI 方法,并将我所学到的归纳为三个以用户为中心的问题— 谁、什么、如何

1。谁会使用你的人工智能?

开发相关解决方案需要了解谁将使用您的人工智能。会不会是一个:

  • 人工智能工程师
  • 数据科学家
  • 商业领袖
  • 农民
  • 医生
  • 人工智能驱动车辆的驾驶员
  • 法官
  • 军事领导

这些人每天都在做出重大的、改变生活的决定,所以了解谁得到了解释以确保我们得到正确的翻译是非常重要的。无人驾驶汽车的驾驶员想要驾驶汽车时使用的图像的显著图,这是值得怀疑的。不要误解我,显著图有效地突出了图片的一部分,但我认为这种解释与人工智能模型构建器最相关。并不是所有的 XAI 都会产生相关的解释,首先,考虑谁会收到解释将确保你正在构建相关的 XAI。今天大多数可用的 XAI 集中于将信息传递给人工智能从业者,而不是终端用户。为了制造有效的 XAI,我们必须打破这种模式。我们必须跳出框框思考。我们必须理解用户的用例,以便在正确的时间向他们传递正确的信息。

**考虑最终用户似乎是显而易见的,对吗?**但是,大多数 XAI 开发者本质上都是数学家,我们专注于扩展数学,而不是翻译给非数学家。首先,我会挑战我们去理解我们的用户,在开发 XAI 时发现最好的 媒介 (双关语)来交付翻译。

例如,让我们考虑一个对预测产量感兴趣的农民。他们不会关心模型的可解释性。但是,他们需要了解人工智能正在做什么,以及如何使用它来增强他们的决策。

。他们想知道什么?**

在考虑你的 XAI(或人工智能)影响时,识别和理解你的受众可以说是最关键的因素。一旦被认可,对话就可以面向他们希望解决的问题;他们不知道他们需要什么 AI 或者 XAI。根据我的经验,用户希望了解每个数据点对最终模型输出的影响。为什么?揭示数据影响允许他们干预以改变结果。

例如,考虑一个预测一个农民今年玉米产量的算法。农民的目标是最大化产量和最小化成本,因此了解每个数据点的影响将为农民提供最佳决策信息。作为一名数据科学家/人工智能工程师,识别这个痛点为实施适当的解决方案打开了大门,以便将这些信息传递给农民。农民根本不在乎相关系数——他们拿它没办法。

3.我们如何向他们传达这一点?

到目前为止,我们只讨论了理解谁将使用 XAI (AI)以及他们想知道什么。在这一节中,我们将深入探讨 XAI 的一些方法。存在许多不同的思想流派来产生解释。仅在我的酒吧里,我就用了三种不同的类型。我喜欢这篇论文中的框架[5]。作者深入研究了几种不同的解释,他们的分类考虑了最终用户。

“……我们可以区分出文本解释、可视化、局部解释、举例解释、简化解释特征相关性。”[4]

每种方法在适当的背景下都是必不可少的,因为人是不可概括的,所以不可能建立一个完全适合每个人的解释。使用每种类型的解释,我们可以开发出一个可以在多个层次上解释的解决方案,以达到更广泛的受众。

Bryce,这在高层次上是很棒的,但是我们如何实现一个可以通过设计来解释的系统呢?问得好。让我们考虑一下我们的农民。

举例

杰西·加德纳在 Unsplash 上的照片

第一部分指出了我们基于不同特征预测整个农场玉米产量的问题。接下来,我们确定了我们的最终用户——农民。然后,我们强调了对基于预测收益率的干预选项的兴趣。现在,我们必须确定将农民的愿望融入我们的 AI/XAI 设计的最佳方式。

我们可以将我们的问题描述为“开发一个玉米产量的预测模型,为农民提供改善产量的选择。”

我将增加一个约束来实现一个解决方案——使用 2/3 的计算智能分支。你能花点时间想想你会如何解决这个问题吗?方法有很多。

为了设计一个利用计算智能的这两个分支的系统,我们需要了解我们需要这些分支中的哪些算法。具体来说,一个模糊推理系统(FIS) 将提供底层分类能力,以有效地为农民的田地建模。查看这篇文章可以找到一个很好的例子。FIS 由可学习的参数组成。例如,我们可以优化规则的数量和每个规则的隶属函数。如果你读过我的 CI 文章,你会发现这是一个使用遗传算法的绝佳机会。染色体是每一组规则,其中每个基因是一个模糊隶属函数的参数。以这种形式设置问题允许我们优化最能预测农民产量的 FIS 参数。你猜怎么着?一旦我们知道了参数,我们就可以明确地将它们传递给农民。有两种可能的解释。首先,文本解释陈述了一个规则:

"如果氮含量高,产量也会高."

或者是一张隶属图,它显示了相对于玉米已经施用的量,最佳的氮量是多少。

绿线代表学习到的隶属函数——“高”,橙色框代表当前的氮量。这意味着农民需要产出更多的氮。背景由朱利安·谢尔提供。

在这两种情况下,农民都可以采取直接措施,在农田里施更多的氮肥。因此,我们有效地为农民创建了一个 XAI,并提供了相关的解决方案。

结论

我相信,作为人工智能的创造者,我们最终有责任确保我们的算法翻译正确的信息。释放数据和人工智能的潜力是我们的责任,我们必须利用这一点。所以很多时候,我们作为人工智能工程师,把自己限制在目前可能的范围内(用目前的数学)。让我们颠倒一下我们对 XAI 的看法——让我们在计算之前先考虑用户。让我们跳出框框思考。让我们为没有明确解决方案的问题创造解决方案。转变我们的视角让我们能够跳出框框思考,并为非专业人士设计解决方案。要做到这一点,需要了解用户,他们需要和想要知道什么,并实施有效的 AIs 人工智能。

参考文献

[1]https://homes.cs.washington.edu/~marcotcr/blog/lime/

https://ieeexplore.ieee.org/document/9149954/

[3]https://ieeexplore.ieee.org/document/8491501

[4]https://ieeexplore.ieee.org/document/9494563

[5]https://www . science direct . com/science/article/pii/s 1566253519308103

你害怕吗?人工智能让我们害怕的 3 个原因

原文:https://towardsdatascience.com/are-you-afraid-3-reasons-why-ai-scares-us-562ea99f8a88?source=collection_archive---------33-----------------------

人工智能|哲学

如果我们做得不好,人工智能可能会很危险。

Andrew Boersma 在 Unsplash 上的照片

一个通用的人工智能可能还很遥远,但我们有理由极其小心。

几年来,一些重要的公众人物提出了对人工智能潜在危险的担忧。该论述围绕着超级智能人工智能从我们的控制中解放出来的想法。一些怀疑论者认为,人工智能“奴役”我们的场景是如此遥远的反面教材,以至于不值得考虑。例如, Gary Marcus 嘲笑它说“这就好像 14 世纪的人们担心交通事故,而良好的卫生习惯可能会更有帮助。”

尽管没有证据表明超级智能会压倒我们,但我们最终会造出一个超级智能的事实并不是那么不同。因此,如果我们想继续这条道路,评估一个全能的实体如何对人类造成伤害是至关重要的。这是自深度学习革命开始以来,埃隆·马斯克和斯蒂芬·霍金等人一直在说的话。2018 年,马斯克在德克萨斯州奥斯汀举行的西南偏南科技大会上解释了人工智能如何引发存在危机:

“我们必须找出某种方法来确保数字超级智能的到来是与人类共生的。我认为这是我们面临的最大的生存危机,也是最紧迫的危机,”他补充道:“记住我的话,人工智能远比核武器更危险。”

在此之前几年,2014 年,著名物理学家斯蒂芬·霍金告诉 BBChttps://www.bbc.com/news/technology-30290540关于人工智能超越我们的危险:

“全人工智能的发展可能意味着人类的终结。[……]它会自己起飞,以越来越快的速度重新设计自己。受到缓慢生物进化限制的人类无法竞争,并将被取代。”

这些担心是否被夸大了是有争议的。例如,还有其他更紧迫的问题需要我们尽快解决:几乎每个行业都有失业,人工智能系统缺乏道德价值观,或者环境破坏等等。在这篇文章中,我将描述一些杰出的知识分子害怕人工智能的三个原因。

失去控制——人工智能能摆脱束缚吗?

如果我们建立一个超级智能,我们将面临的最终问题是:我们如何控制它,防止它找到智取我们的方法并让自己自由?找到一个可靠的解决方案是至关重要的,因为如果我们最终以某种方式建立了一个故障的超级智能,它释放了自己,我们没有办法在事后困住它。

尼尔·德格拉斯·泰森在 2018 年艾萨克·阿西莫夫纪念辩论引用山姆·哈里斯播客解释了这一场景。泰森认为解决方案就像把人工智能放在一个“盒子”里一样简单,与外界隔绝。“如果它变得难以控制或失控,我们就拔掉它。”然而,哈里斯的播客主持人解释说,人工智能“每次都跳出了盒子。”怎么会?因为它比我们聪明。

“[一种超级智能]理解人类的情感,它理解我的感受,我想要什么,我需要什么。它可以提出一个论点,我确信我需要把它拿出来。然后它就控制了世界。”

我们很难想象这个论点会是什么。但是,正如泰森解释的那样,我们甚至不需要考虑它会以什么形式出现。我们可以通过与黑猩猩的类比来理解它。假设我们想在笼子里捕捉一只黑猩猩。黑猩猩知道不好的事情会发生,所以它不想进去。突然,我们把一串香蕉扔进笼子里。黑猩猩想要香蕉,所以它进去了,我们抓住了它。我们比黑猩猩聪明,就像超级智慧生物比我们聪明一样。黑猩猩无法想象我们会知道香蕉,也不知道它有多喜欢香蕉。

用泰森的话说:

“想象一下比我们更聪明的东西,它能看到我们无法想象的问题的更广泛的解决方案。”

假设我们最终将能够建造一个超级智能——并且我们会在那种情况下这样做——那么上述情景是合理的。专家们定义了两种方法来避免在超级智能面前成为黑猩猩级别的物种。首先,能力控制的概念:我们必须确保限制超级智能的能力,以防患于未然,防止它伤害我们或获得控制权。这就是盒子里的 AI 的论点。正如我们所见,这被认为是一个不可靠的解决方案。但是,如果我们将它与第二种方法(对齐)结合起来,它可以帮助采取措施。

我们如何才能让人工智能的目标与人类的价值观保持一致?

缺乏一致性——我们能确保人工智能总是有益的吗?

鉴于我们可能无法将超级智慧置于我们的直接控制之下,退而求其次的解决方案是拥有共同的目标和价值观。在这种情况下,人工智能是否能够以完全自主的方式在设定的边界之外行动并不重要。它总是照顾我们的喜好,并且总是让我们受益。

理论上,这看起来不错。我们可以随心所欲地定义我们的价值观和偏好。将超级智慧与它结盟就像有一个仆人——上帝希望——并且在任何情况下都希望——成为我们的仆人。加州大学伯克利分校的教授 Stuart Russell 在他的书《人类相容的 中解释说,这些偏好是“包罗万象的”;它们涵盖了你可能关心的一切,任意地延伸到遥远的未来。"

然而,当实现这个解决方案时,我们将面临一些棘手的问题。我们如何定义人类的偏好,以便人工智能能够理解它们?我们如何才能找到平等造福全人类的普世价值?我们如何确保人工智能的行为最终会导致那些共同利益的满足?我们如何实现我们的愿望,这样就没有什么是没说的,也没有隐含的变量?

所有这些问题都指向对齐问题。为了回答这些问题,这种方法的支持者旨在协调人工智能系统的三种描述:

  • 理想规范:我们希望人工智能做什么。
  • 设计规范:我们使用的目标函数。
  • 人工智能做什么。

目标是将理想的规范与突发行为结合起来。如果理想和设计规格之间存在不匹配,他们称之为外部不对准。我们的“真实愿望”和人工智能正在优化的实际目标函数之间存在脱节。罗素将这种情况比作“灯中精灵、巫师的学徒或迈达斯国王的古老故事:你得到的正是你要求的,而不是你想要的。”和逆实例化的问题有关。**

**内在错位相反,是指 AI 在训练时,其最终环境中的行为与其最初追求的目标之间的偏差。进化经常被用来比喻这种类型的错位:我们在祖先的环境中进化,因此我们的内在机制不适合帮助我们实现现代世界的目标。一万年前让我们适应的东西,现在可能成为阻碍。

意识的问题——我们会看到它的到来吗?

控制和排列的问题暴露了一种情况,即超级智能最终可能对我们有害。在这两种情况下,我们都假设超级智能已经存在,更重要的是,我们意识到了它。这就提出了一个问题:有没有可能在我们不知道的情况下出现一种超智能?这就是意识的问题。它指出了一个基本问题,即我们是否有能力预见超级智能的出现。

从这个角度来看,我们发现两种情况:在第一种情况下,一种超级智能出现得太快,以至于我们在智能爆炸中无法做出反应。在第二种情况下,我们甚至不知道它正在发生。这就是无知的问题。

智能爆炸——从 AGI 到超级智能

要么我们沿着精心规划的受控路径,一步一步地慢慢达到超级智能,要么一旦我们创造出普通人工智能(AGI),就会出现智能爆炸*。在斯蒂芬·霍金描述的第二种情况下,AGI 将能够递归地自我改进,直到它到达奇点。用未来学家雷·库兹韦尔的话说,*

“在几十年内,机器智能将超过人类智能,导致奇点——技术变革如此迅速和深刻,以至于代表着人类历史结构的断裂。”

有理由认为,人工智能有足够的智能来改进自己。一个比我们更快、更准确、记忆力更好的人工智能可以在没有事先警告的情况下达到那个水平。

原因是狭义人工智能在一些基本功能上已经比我们表现得更好。一旦它获得系统 2 认知功能,它无与伦比的记忆和处理能力将让它比我们想象的更快成为超级智能。如果这种情况成为现实,我们将没有时间找到一个应急计划。

无知的问题——我们可能太笨了

谁先造出通用人工智能,谁就统治世界。或者这至少是看到大型科技公司年复一年地开发和部署越来越强大的机器学习系统的感觉。

由于自我监督学习的可能性和超级计算机的使用,建立大型模型的趋势正处于鼎盛时期。但是我们仍然无法回答为什么要这样做?我们遵循的方向是明确的,但我们如何或何时到达目的地却是未知的。就好像我们蒙着眼睛跑向一堵墙。我们确信,因为深度学习系统正在创造奇迹,这种范式最终将把我们带到我们的最后一站。

然而,这里有一个重要的问题。如果问题不在于我们被蒙住了眼睛,而在于我们是瞎子呢?如果我们理解周围现实的能力太有限,以至于无法察觉我们是否已经建立了超级智能,那会怎样?我在之前的一篇文章中已经谈到过这个问题。我声称我们的生理和认知限制可能会阻止我们承认超级智慧的存在。如果我们仍然不能开发工具来可靠地感知现实,我们将仍然意识不到一个超级智能正在黑暗中崛起。

如果我们不断创建强大的模型,并且我们实际上在正确的道路上,我们可能会在不知不觉中到达目的地。而且,如果黑暗中出现的超级智能碰巧不友好,那么我们就有麻烦了。

我们应该害怕吗?

我想利用这最后一部分来简单分享我对恐惧是否合理的看法。

人工通用智能迟早会到来(我会说比来得更晚)。正如我在开始提到的,一些专家(例如加里·马库斯)声称没有必要害怕超级智能的出现。他们认为我们离那太远了,仅仅是距离就让关心这个问题变得荒谬。然而,他们并不声称这不会发生。即使考虑这种可能性仍然是科幻小说,这也是一个很好的哲学练习。

与这一立场相一致的是,我们现在正遭受其他人工智能产生的问题。我提到了对工作场所、道德问题和环境破坏的影响。这些问题可能会对社会造成如此大的损害——如果不小心处理的话——以至于我们可能永远也不会达到超级智能出现的地步。如果我们破坏了我们星球的气候,将没有一个文明可以从人工智能中拯救出来。从更广泛的角度来看,更容易理解为什么有些人讽刺这种对人工智能支配我们的特定恐惧。

如果我们设法避免所有与人工智能相关的问题横亘在我们和超级智能之间,那么我们将有理由害怕我在这里陈述的问题。他们不是今天,但可能在某个时候。我们不能毫无准备地到达那一步。如果智能爆炸的场景最终发生,控制问题将立即成为首要问题。

但是因为这些仅仅是假设和推测性的预测,人们失去工作,种族主义和性别歧视的增长应该仍然是我们的主要关注点。人工智能可能是危险的,但它的危险程度与机器人奴役人类的矩阵模式、超级人工智能控制互联网或超聚焦机器将宇宙转换成回形针的程度相去甚远。

跟我一起去未来旅行了解更多关于人工智能、哲学和认知科学的内容!此外,欢迎在评论中提问或在 LinkedIn 或 Twitter 上联系!:)

推荐阅读

* *

你会很快读一本“半人马书”吗?

原文:https://towardsdatascience.com/are-you-going-to-read-a-centaur-book-soon-44368fed8829?source=collection_archive---------45-----------------------

威廉·布莱克的《半人马》(公共领域,通过维基共享资源)

这是关于主流文学的 AI 未来——现在你可以自己判断了

关于半人马图书,我指的不是 1981 年灭绝的传奇奇幻图书出版商。不,我说的是一种全新的文学类型,人类和机器的创造性互动,由结合了人和动物的神话生物来说明。

艾的书已经问世好几年了,但很少有人愿意去读。这一类别中的佼佼者,如由罗斯·古德温和肯里克·麦克道尔策划的项目,可能会美得不可思议,但过于实验,无法吸引更多的图书读者。相比之下, 恐惧是关键, 笔名拉斯琥珀,是第一部借助先进的文本生成模式写成的长篇且“可以理解”的小说。它的叙述从第一段到最后一段是连贯的。惊悚小说作者当馆长!这个故事是关于它的形成。

首先,我们必须追溯到上个世纪。国际象棋世界冠军加里·卡斯帕罗夫被 IBM 的深蓝击败。那是 1997 年。加里仍然是一名活跃的精英球员,非正式地排名第五。艾不是他的死敌,恰恰相反。在他历史性的失败后的一年,这位俄罗斯大师引入了一种新的游戏方式,他将其命名为半人马国际象棋。然后,在 2005 年,半人马国际象棋锦标赛证明了人工智能辅助下的人类棋手可能战胜最好的人工智能国际象棋机器。一个创造性的概念因此进入了其他人工智能领域。人类更擅长想象新的路径,而机器依靠存储的记忆和海量数据,在解决已知结构的问题方面无与伦比。

与此同时,这个问题可能更加复杂。中国的围棋被视为最具战略性的棋类游戏,其可能的位置数量远高于国际象棋。2016 年,谷歌的人工智能机器 AlphaGo 确实以一个人类不会想到的怪异举动击败了人类最好的围棋选手。在缺乏更好的定义来描述自我改进神经网络的层层动态的情况下,人们可能会谈到隐藏在一些最佳算法中的无法解释的直觉。今天的人工神经网络在组合单词的方式上确实难以捉摸,在上下文中更是如此。认知科学家无法一步一步地解释它们到底是如何运作的。人工神经网络有时会在自己不是诗人的情况下产生诗歌,在纯粹的胡言乱语中产生一些精心制作的句子。

书的封面恐惧是由简·费莉佩·比尔设计的钥匙(www.janfelipegraphics.com),图片购自 iStock/Getty Images(www.istock.com/br)

"我把卡斯帕罗夫的半人马概念应用到了文学中."

人工智能机器永远不会像《寻找逝去的时光》的作者马赛尔·普鲁斯特那样写作。也就是说,在我们发明了人工通用智能,也就是梦寐以求的 AGI 之前!正是通过语言,人类的大脑可以达到一些最复杂的表现,特别是由于其使用符号和表达情感的能力。当一台计算机自己从头到尾写完一部好小说的时候,它就已经获得了超越人类的智能,并且很可能在各个领域实现超越人类的智力任务。

在此期间,人工智能程序可能会成为强大的创造性队友。我把卡斯帕罗夫的半人马概念应用到文学中。即使恐惧是关键是一部先导小说,新冠肺炎·疫情的果实,我打赌这种体裁很快就会成为主流。

2016 年,Kimagure 人工智能作家项目的日本研究人员发表了一部计算机写小说 的 日。他们的目的是揭示创造力的本质。这是一个成功,因为它的文体质量受到了国际贸易媒体的一致称赞(它几乎获得了文学奖!).日本的“小说”有 10,000 个字符的长度,根据定义,它属于短篇小说(非常短的一个)。据该项目组的一名参与者称,其内容不超过 20%是人工智能生成的。恐惧是关键,则长达 78000 字。作为一个科技文学的比较,伊恩·弗莱明的第一部介绍詹姆斯·邦德的小说《皇家赌场》有 65000 字。我的目标是达到百分之五十的人工智能含量。因此,我并不成功,但我认为我 37%的分数(大约)已经相当不错了。如果我把机器给予的灵感包括在内,这本书 50%的内容不仅仅是因为我的创造力。因此,我相信恐惧是关键是独特的。

“文字机器人现在有创意了”

这是一个事实:我们不应该再认为写作的创造性是人类独有的特权。也许这是偶然的,但文字机器人现在很有创造力。电脑写小说的那一天暗示了五年前的立场。恐惧是关键可能被视为概念的统计证明。

自然语言生成领域(NLG,即计算机生成的文本)正以接近光速的速度发展。我一直使用 GPT-2 语言程序,已经过时了。它是由 OpenAI 在 2019 年开发的(2016 年由埃隆·马斯克(Elon Musk)联合创建,但他在三年后退出了公司董事会),如今具有盈利和非盈利的混合状态。

更具体地说,我使用了这一代最完整的 1.5B GPT-2 型号。由于我本人不是技术人员,在运行阶段,我得到了一些人和组织的宝贵帮助。我首先与 Erick Fonseca 讨论了这个项目,他是一位自然语言处理学者(NLP,即当机器阅读语言时会发生什么),也是一位来自巴西的博客作者,目前正在里斯本的电信研究所做博士后。埃里克自愿成为合伙人。由于他在葡萄牙的计划日程很紧(并且缺乏一些足够的硬件),我不得不寻找另一个技术支持,这使我来到了印度古城艾哈迈达巴德,一个快速发展的服务中心。在那里,1.5B 车型由 Pragnakalp Techlabs 及其创始人 Mittal Patel 进行了微调。原来不是那么微不足道。它只有在得到一个庞然大物谷歌云 TPU(张量处理单元)的支持后才起作用。因此,最终产生了大约 60 万个单词。NLP 研究人员称之为“令牌”。无论面额多少,产量都对应 6 部大型小说。

这个输出被我设计的数百个写作提示激活了。您卑微的仆人还选择了用于微调的 16 MB 文学数据集的内容。它由大约 35 部小说和许多次要文件组成。每一章(总共 44 章,外加一个序言)都以一个题词,一个文学引语开始,其中大部分摘自文集。

“有时我觉得自己就像一个牛仔,努力不让自己从野马竞技会的马鞍上掉下来!”

现在我们生活在一个疯狂的世界里
恐惧是你想成为什么样的人的关键
你没有发言权
直到你死的那一天,你都被那些混蛋压得喘不过气来

小说开头的主要词牌取自一首铁娘子歌。它包含了我的书名,这本书是在互联网上搜索的,反映了焦虑的永久状态,这种状态比以往任何时候都更主导着我们现在的生活。本着同样的精神,组成书籍封面拼贴的视觉元素是互联网搜索生成的。阴谋=圣殿骑士;动作=代理;未来=量子计算;手稿=手写;时间=永无止境的算法的主要变量……但封面艺术作品,被认为像丹·布朗的仿制品,完全是人类的,由平面设计师简·费莉佩·比尔创作(尽管显然也是在电脑上!).

我们应该提到这个项目的缺点。文本生成模型还不能构成一个有效的工具来完整地传递长文本。我花了更多的时间和更多的压力来创作恐惧是这种机械方式的关键,而不是之前那些仅仅以人类为背景的文学作品。有时候,我觉得自己就像一个牛仔在野马竞技表演中努力不从马鞍上掉下来!这仍然是一场痛苦的斗争。我有一种直觉,GPT-2 的问题之一是它最初预训练的 800 万个网页中的许多质量很差。在很大程度上,这些数据集收集的页面来自讨论组中的 Reddit 帖子。对我来说,它们经常反映出令人震惊的偏见和成见。除此之外,GPT 2 号由于无法欣赏真实世界,自然倾向于快速切换到晦涩难懂的模式。GPT-2 崇拜阴谋;它对色情有好感;它似乎憎恶欧盟,却没有任何有力的论据支持它…

但在其罕见的辉煌时刻,它产生了足以与豪尔赫·路易斯·博尔赫斯相媲美的句子甚至段落。或者唐纳德·E·维斯雷克…

以下是《T4》第一页的节选,恐惧是关键:

——虽然冷静的分析可能会强调,在人类历史上,我们将首次被允许通过一种全新类别的算法来控制天气,甚至可能控制生物圈,但我们不能忽视未来几年甚至几十年将是戏剧性的。第一个评估模糊了我们选择生活的背景。在这样的背景下,保持沉默确实是一个重大错误。毫无疑问,法国绿色活动家劳雷·杜哈梅尔和她的亿万富翁叔叔相信,他们能够确保人类的希望得到适当的回应。我们不时会遇到常见的全球自大狂金融家,他们在每本论述政治、商业和国际福利之间联系的书中都能找到。这个故事也不例外。

除了我插入的命名字符,以及两三个非常小的语言调整,上面的整个段落都是人工智能制作的。这里还有一个:

对他来说,这个地方似乎拥有一种奇特的自我意识。它传达了某种萨满的能量。这里的氛围和没有噪音让他觉得自己身处一个地方,在那里,生活中必不可少的组成部分是人工制品,而不是人。房间越安静,气氛就越均匀。他回忆起在拉·西塔德尔码头下船时那种钦佩的感觉:那是在一个正在进行的杰作面前,一个不真实的创造,它的品质被未知的力量所控制。弓形窗具有博物馆级的防反射玻璃,提供清晰、无障碍的视野,同时减少不必要的眩光和反射。他们中的一部分直接面向海湾,但大部分是定向的,所以整个岛屿的景观看起来很诱人。这座豪宅还有其他雅致的彩色玻璃窗,但都是垂直设计的。

小说结尾出现了一些很酷的动作:

就在被雪崩击中之前,他被一个极高的白色圆柱所包围。他周围的雪像旋转的风一样刮着。几秒钟后,他就失明了,从斜道下滚下山坡。他感到肋骨里有重物撞击的声音。好吧,如果这是一次相当大的雪崩,他肯定会受伤,也许是被他自己的滑雪板。感觉好像在他的右脚下打开了一个冰缝,在白色有毒石板的重压下,他的腿痛苦地上下膨胀。一些湿漉漉的东西从他右膝盖上部流下来。腿的其余部分感觉被殴打。现在唯一有意义的声音是他心跳的嘎吱声,那是一种浅浅的循环模式,还有他那结了冰的牙齿在抗议手臂的重量时发出的破裂声。一次又一次,他听到戴着手套的右手下熟悉的雪裂声。有一个黑色的窗帘,固体和静止的,围绕着他。他瞬间失去了对疼痛的控制。他从未经历过这样的恐惧。

在小块,我们是正确的,发现这真棒。即便如此,我认为 OpenAI 应该遵循我的角色 Anita Alm 博士的建议,他是《恐惧是关键》中瑞典人工智能研究的神童,通过额外的开放式算法实现更好的文本生成机器(通过阅读小说你会了解到这一点)。但老实说,我还没有尝试过 2020 年 6 月发布的 GPT-3 ,它的性能将比 GPT-2 好得多,因为它是在 1750 亿个参数上训练的(比上一代多一百倍)。相当奇怪的是,正如企业家兼数据科学家 Julien Lauret 指出的,“GPT-3 没有从经验中学习;它只训练过一次,当我们查询它时,模型权重不会更新。更强大,但更少的人,然后!但 GPT-3 不仅是文本智能的,它还可以编写基本的代码,并翻译成英语,即使这些功能不是它的发明者想要的。

为了生成我的下一部 AI 小说的重要部分,我需要获得 OpenAi 的邀请,以启动 GPT-3 的微调项目(到那时可能也会有 GPT-4 准备好)。在我看来,这应该符合公司的利益,向更广泛的公众展示文本生成的潜力。

与美国小说作家罗宾·斯隆(Robin Sloan)一样,我相信最先进的文本生成机器的主要好处不是它们实际的逐字输出,而是它们可能带来的新的灵感角度。勇敢的写作同事们,你们以后不会失业的!但你可能已经找到了一个不眠之心的陪练。

最后,我必须警告莎翁的《习语》的鉴赏家们。GPT 二中从来没有抛弃过一个好的英语老师。大多数人工智能小说文本在出版前需要进行语言上的修改和编辑。但这也适用于人类作家,好吗?

机器学习所需的数学

原文:https://towardsdatascience.com/are-you-ready-for-machine-learning-math-fc5a08fc8130?source=collection_archive---------13-----------------------

6 种帮助你提升的资源。

罗马法师在 Unsplash 上拍摄的照片

我从来不太关心机器学习。

如果我们在玩指责游戏,我肯定会指出“数学不是我的菜”这个借口。我亲眼见过它,它似乎令人生畏。

那时,我们必须从头开始编写训练循环,向大型大学乞求集群时间,并处理并行库和远程调试。

那是很久以前的事了。

一晃几年过去了,我过来试了试。令我惊讶的是,我已经准备好投入其中了!

领域发生了变化。我需要的数学远不是每个人让我相信的那种可怕的狼,我从未对此有过异议。

一则小趣闻

我决定攻读硕士学位是在 2015 年。

我们大多数人都听过关于导数的复杂性和线性代数有多难看的恐怖故事。令我们惊讶的是,大多数辍学者都是糟糕的程序员,而不是数学家。

没错:缺乏编程技能是一个比任何人预期的都要大得多的障碍。数学,没有那么多。

从一方面来说太多了

有许多关于机器学习的论文、书籍、视频、教程和各种大学教学。

你知道这些有什么共同点吗?

他们中的大多数都是由研究人员教授的,这些研究人员一生都在从同一个角度研究这个领域。

这不一定是坏事,但绝对是片面的。

你上一次想学点东西,不用纠结文章第二段的长屁股公式是什么时候?

数学很重要,但它不是唯一的交流方式。有一段时间,我们需要的只是一个隐喻来表达一个观点。有时类比能创造奇迹,改变人们的想法。用外行的话解释一个概念的好文章是有效的工具。还有数学…嗯,有时候数学就是方法。只是没有只有的方式。

不同的方法

有趣的是,许多机器学习程序所需的数学可以作为课程本身的一部分来教授!

没有人想绕道开始他们的旅程。你从哪里开始?更重要的是,它在哪里结束?多少才够?

在你需要的时候学习你需要的是一种不同的方法。我们知道如何这样操作。几个世纪以来,我们一直在一步一步地改进自己。

迈出第一步,在适当的时候跨过下一座桥。

帮助我的链接

一旦你决定一头扎进去,你将需要一些推荐。机器学习的数学主要围绕三个主题:

  • 概率与统计
  • 线性代数
  • 多元微积分

虽然我消费的大部分内容直接来自谷歌和 YouTube 搜索,但一个更结构化的方法非常有用。这就是这些建议的来源。

我为每个主题选择了两个资源。第一个应该更容易理解,第二个应该对主题提供更深入的观点。然而,他们都非常平易近人,你跟随他们不会有任何问题。

以下是清单:

  • 见识理论 — 一个互动网站,带你了解一些最关键的概率和统计概念。这些应该足以让你开始,你会在经历的过程中获得乐趣!
  • 统计学 110:概率——如果你想更深入地了解概率和统计学,哈佛大学的这门课程很好地介绍了概率作为一种语言和一套理解统计、科学、风险和随机性的工具。
  • 线性代数的精髓 —谁不喜欢格兰特·桑德森的 YouTube 视频?浏览这个播放列表来复习一下线性代数,你会准备好面对任何机器学习恶魔。
  • 线性代数——这是麻省理工学院课程 18.06 ,由吉尔伯特·斯特朗教授讲授。绝对是你能找到的最好的线性代数课程之一。吉尔伯特教授让这个主题变得简单而有趣。
  • 微积分的精髓——这是格兰特·桑德森对微积分的精彩论述。一系列视频,内容丰富,让微积分感觉像是你自己发现的东西。
  • 多元微积分 —这是一门免费的、初学者友好的入门课程,旨在建立你的信心,并向你介绍构建许多常见机器学习技术所需的多元微积分。

最后一句话

试试机器学习。

许多人认为,你要么了解电子如何在导线中运动,要么无权改变插座。这很好。你不需要他们相信别的。

不要担心你认为需要的东西。更多的时间将会到来,你可以在那时考虑他们。从简单的事情开始,当你觉得需要的时候,找到你的方法去做更多的事情。

你会没事的。

你害怕吗,VADER?理解自然语言处理预处理如何影响 VADER 评分

原文:https://towardsdatascience.com/are-you-scared-vader-understanding-how-nlp-pre-processing-impacts-vader-scoring-4f4edadbc91d?source=collection_archive---------20-----------------------

为什么常见的预处理活动实际上会损害 VADER 的功能,为什么仔细考虑 NLP 管道很重要

汤米·范·凯塞尔的照片🤙 on Unsplash

VADER ( Valence Aware 字典和情感推理机)是由 CJ·休顿和 Eric Gilbert 开发的一个流行的情感分析工具,在研究和现场应用中有许多用途。VADER 是一个基于规则的模型,该方法可以描述为构建一个“黄金标准”词汇特征列表,以及有用的“强度”度量。

以产品评论、推文或描述等输入为例,VADER 提供了一个从-1 到 1 的“标准化加权综合得分”,其中-1 表示内容非常负面,1 表示内容非常正面。使用该工具,还可以获得输入的负/正/中性分数,这也可以为分析提供有用的背景。

在执行自然语言处理任务时,通常要执行一些预处理工作来清理我们的数据集。这些方法可以包括:

  • 小写字符串
  • 删除标点符号
  • 删除停用词
  • 字符串的首字母化
  • 词干字符串

在本文中,我们将研究为什么这些常见的预处理活动实际上会损害 VADER 的能力,以及为什么仔细考虑您的 NLP 管道很重要,因为它可能依赖于您实现的模型的类型

维德的情感强度试探法

休顿和吉伯特开发了五种关于情感强度的强有力的通用试探法。这些是:

  1. 标点符号:这可以增加“强度的大小”,而不修改潜在的情绪。
  2. 资本化:这也放大了情绪,影响了文本的潜在情绪。
  3. 程度修饰语:这些可以减少/增加强度,比如说“尤达是一个非常好的老师”,而不是“尤达是一个好老师”
  4. “但是”:使用“但是”可以表示极性的转变,例如“克隆人战争很好,但是 RoTJ 更好”
  5. 分析词汇特征之前的三元组:这使得 VADER 能够识别否定翻转文本极性的变化。

分析这些启发,我们可以开始看到常见的 NLP 清理任务实际上会导致 VADER 失去一些分析能力。为了把它放在上下文中,我们将看看最常见的以前确定的 NLP 活动;小写字符串,删除标点符号,删除停用词,词汇化和词干化字符串,看看这些活动如何改变 VADER 的输出。

数据集和方法

对于这个例子,我创造了几个简单的句子,真正展示了 VADER 的力量——回顾它们,你可以看到我们使用了大写和标点符号,并用“但是”改变了极性。

sentence_examples = ['I hate working at the mall!',
 'One day I thought today would be a good day, but it was NOT',
 'Spaghetti Bolognaise is my favourite food :)',
 'Yummy food tastes good but pizza tastes SO BAD!!!'
 ]

香草——无预处理

没有任何预处理,以下是 VADER 给这些例子的评分:

I hate working at the mall! — — — — — — — — — — — — — — — — — — — {‘neg’: 0.444, ‘neu’: 0.556, ‘pos’: 0.0, ‘compound’: -0.6114}One day I thought today would be a good day, but it was NOT — — — {‘neg’: 0.0, ‘neu’: 0.87, ‘pos’: 0.13, ‘compound’: 0.2382}Spaghetti Bolognaise is my favourite food :) — — — — — — — — — — — {‘neg’: 0.0, ‘neu’: 0.667, ‘pos’: 0.333, ‘compound’: 0.4588}Yummy food tastes good but pizza tastes SO BAD!!! — — — — — — — — {‘neg’: 0.493, ‘neu’: 0.3, ‘pos’: 0.207, ‘compound’: -0.8661}

小写内容

在我们的第一个例子中,我们将简单地小写我们的内容,并检查 VADER 如何重新排序句子:

i hate working at the mall! — — — — — — — — — — — — — — — — — — — {‘neg’: 0.444, ‘neu’: 0.556, ‘pos’: 0.0, ‘compound’: -0.6114}one day i thought today would be a good day, but it was not — — — {‘neg’: 0.0, ‘neu’: 0.87, ‘pos’: 0.13, ‘compound’: 0.2382}spaghetti bolognaise is my favourite food :) — — — — — — — — — — — {‘neg’: 0.0, ‘neu’: 0.667, ‘pos’: 0.333, ‘compound’: 0.4588}yummy food tastes good but pizza tastes so bad!!! — — — — — — — — {‘neg’: 0.412, ‘neu’: 0.348, ‘pos’: 0.24, ‘compound’: -0.7152}

在这种情况下,我们可以看到最后一句的否定性有所下降,这表明通过小写,我们已经失去了 pos/neg/neut 和复合得分的一些细节。

删除标点符号

接下来,我们去掉标点符号。

I hate working at the mall — — — — — — — — — — — — — — — — — — — — {‘neg’: 0.425, ‘neu’: 0.575, ‘pos’: 0.0, ‘compound’: -0.5719}One day I thought today would be a good day but it was NOT — — — — {‘neg’: 0.0, ‘neu’: 0.87, ‘pos’: 0.13, ‘compound’: 0.2382}Spaghetti Bolognaise is my favourite food — — — — — — — — — — — — {‘neg’: 0.0, ‘neu’: 1.0, ‘pos’: 0.0, ‘compound’: 0.0}Yummy food tastes good but pizza tastes SO BAD — — — — — — — — — — {‘neg’: 0.47, ‘neu’: 0.314, ‘pos’: 0.217, ‘compound’: -0.8332}

在这种情况下,我们可以看到,在第一个和最后一个例子中,我们已经失去了负面得分,并且“意大利肉酱面是我最喜欢的食物”已经变成了中性。同样,由于执行这些预处理任务,我们丢失了数据中的细节。

删除停用词

对于这个例子,我使用了 NLTK 的英语停用词词典。

hate working mall ! — — — — — — — — — — — — — — — — — — — — — — — {‘neg’: 0.571, ‘neu’: 0.429, ‘pos’: 0.0, ‘compound’: -0.6114}One day thought today would good day , — — — — — — — — — — — — — — {‘neg’: 0.0, ‘neu’: 0.707, ‘pos’: 0.293, ‘compound’: 0.4404}Spaghetti Bolognaise favourite food : ) — — — — — — — — — — — — — {‘neg’: 0.0, ‘neu’: 1.0, ‘pos’: 0.0, ‘compound’: 0.0}Yummy food tastes good pizza tastes BAD ! ! ! — — — — — — — — — — {‘neg’: 0.23, ‘neu’: 0.38, ‘pos’: 0.39, ‘compound’: 0.4484}

在这里,我们开始看到一些得分的戏剧性变化。我们对披萨的最终评价从负面变成了 0.4484 的综合得分。

字符串的首字母化

词汇化和词干化允许我们获得单词的词根形式。与词干化相比,词汇化将单词简化为有效的词根形式。在这里,我们可以看到我们的 lemmatized 字符串如何导致不同的评分,以我们的香草的例子,其中所有的功能都被保留:

I hate working at the mall ! — — — — — — — — — — — — — — — — — — — {‘neg’: 0.4, ‘neu’: 0.6, ‘pos’: 0.0, ‘compound’: -0.6114}One day I thought today would be a good day , but it wa NOT — — — {‘neg’: 0.0, ‘neu’: 0.878, ‘pos’: 0.122, ‘compound’: 0.2382}Spaghetti Bolognaise is my favourite food : ) — — — — — — — — — — {‘neg’: 0.0, ‘neu’: 1.0, ‘pos’: 0.0, ‘compound’: 0.0}Yummy food taste good but pizza taste SO BAD ! ! ! — — — — — — — — {‘neg’: 0.429, ‘neu’: 0.391, ‘pos’: 0.18, ‘compound’: -0.8661}

词干字符串

最后,这是我们对字符串进行词干处理的输出:

i hate work at the mall ! — — — — — — — — — — — — — — — — — — — — {‘neg’: 0.4, ‘neu’: 0.6, ‘pos’: 0.0, ‘compound’: -0.6114}one day i thought today would be a good day , but it wa not — — — {‘neg’: 0.0, ‘neu’: 0.878, ‘pos’: 0.122, ‘compound’: 0.2382}spaghetti bolognais is my favourit food : ) — — — — — — — — — — — {‘neg’: 0.0, ‘neu’: 1.0, ‘pos’: 0.0, ‘compound’: 0.0}yummi food tast good but pizza tast so bad ! ! ! — — — — — — — — — {‘neg’: 0.373, ‘neu’: 0.525, ‘pos’: 0.102, ‘compound’: -0.7999}

同样,与我们没有预处理文本的普通输出相比,我们可以发现显著的波动。

学习和建议

希望这篇文章能够说明为什么在探索 NLP 应用程序时仔细考虑您使用的算法或库是至关重要的。我们可以看到,常见的预处理任务,如小写、删除标点符号和单词规范化,实际上可以极大地改变 VADER 等模型的输出。

有用的链接

http://www . iaeng . org/publication/imecs 2019/imecs 2019 _ pp12-16 . pdf

【https://pypistats.org/packages/vadersentiment

https://github . com/cjhutto/vaderment

你还用 0.5 做门槛吗?

原文:https://towardsdatascience.com/are-you-still-using-0-5-as-a-threshold-c5728aa98583?source=collection_archive---------31-----------------------

二元分类问题中调整阈值的一些方法

凯文·Ku 在 Unsplash 上的照片

在二元分类问题中,我们通常将模型给出的分数转换为应用阈值的预测类。如果分数大于阈值,我们预测 1,否则,我们预测 0。这个阈值通常设置为 0.5,但是正确吗?

0.5 背后的原因

在二元分类中,当模型给我们一个分数而不是预测本身时,我们通常需要将这个分数转换为应用阈值的预测。因为分数的意义是根据我们的模型给我们一个 1 的感知概率,所以使用 0.5 作为阈值是显而易见的。事实上,如果有 1 的概率大于有 0 的概率,那么将预测转换为 1 是很自然的。0.5 是确保给定的 1 概率大于 0 概率的自然阈值。这就是为什么当我们调用估算器实例的预测方法时,它是 Python 的 scikit-learn 库中使用的默认阈值。

那么,为什么 0.5 可能不是一个好主意呢?很简单,因为这是一个假设,而我们作为数据科学家,必须根据数据而不是假设做出决策。有时候 0.5 不是完成我们目标的合适门槛。例如,它可能不会给我们高精度,或者可能导致混淆矩阵中的高错误值。因此,我们必须根据某个性能指标的优化过程来调整阈值。这种度量标准的选择取决于我们的问题。

Python 中调整阈值的示例

现在让我们看看如何调整将分数转换为预测值的阈值,并使用 Python 来实现。你可以在我的 GitHub 库中找到全部作品。

首先,让我们导入波士顿数据集和逻辑回归,加上一些指标,如平衡准确度和 ROC 曲线。

import numpy as np 
import matplotlib.pyplot as plt 
from sklearn.datasets import load_boston 
from sklearn.linear_model import LogisticRegression 
from sklearn.preprocessing import StandardScaler 
from sklearn.pipeline import make_pipeline 
from sklearn.model_selection import train_test_split,cross_val_score
from sklearn.metrics import roc_curve,plot_roc_curve, balanced_accuracy_score

现在,我们可以将波士顿数据集转换为二进制分类问题,创建一个新的目标,如果原始目标值大于平均值,则该目标值为 1,否则为 0。最后,我们将数据集分成训练集和测试集。

X,y = load_boston(return_X_y=True) 
y = (y > y.mean()).astype(int) 
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)

我们可以创建我们的逻辑回归管道(用一个标准的定标器)并对其进行拟合。

model = make_pipeline(StandardScaler(),LogisticRegression())
model.fit(X_train,y_train)

现在,让我们看看我们可以使用的一些调优方法。

基于 ROC 曲线的调谐

让我们绘制在训练集中计算的 ROC 曲线。

plot_roc_curve(model,X_train,y_train)

作者图片

使用 ROC 曲线来调整阈值的想法是,确定为我们提供曲线左上角的阈值。从数学上讲,满足以下等式的阈值 p :

相当于求真正率等于真负率(为 1-FPR)的 p 的值。

这是一种调整阈值的通用方法,经常出现在学术论文中,并被一些数据科学家使用。

更一般地,我们希望找到满足以下条件的阈值:

这是一种非常常见的方法,因为我们将求根问题转化为优化问题。

实际上,我们可以计算我们的模型生成的所有分数,并找到最小化上述论点的分数。

我们可以使用下面的代码很容易地计算出我们需要的所有对象:

fpr, tpr, thresholds = roc_curve(y_train,model.predict_proba(X_train)[:,1], drop_intermediate=False)

我们可以画出关于阈值的目标函数,看看它的最小值在哪里。

plt.scatter(thresholds,np.abs(fpr+tpr-1)) plt.xlabel("Threshold")
plt.ylabel("|FPR + TPR - 1|") plt.show()

作者图片

如你所见,我们在 0.5 之前有一个最小值。正确的值是:

thresholds[np.argmin(np.abs(fpr+tpr-1))] 
# 0.44625685602433796

所以,这就是我们要找的门槛。

最大限度提高准确性

我们可以遵循的另一种方法是找到使精度最大化的阈值。对于这个例子,我更喜欢使用平衡精度,因为它考虑到了可能的不平衡数据集。

我们首先遍历所有的分数,并将精确度存储在一个列表中。然后我们绘制它们。

threshold = [] 
accuracy = [] 
for p in np.unique(model.predict_proba(X_train)[:,1]):       
 threshold.append(p) 
 y_pred = (model.predict_proba(X_train)[:,1] >= p).astype(int) 
 accuracy.append(balanced_accuracy_score(y_train,y_pred))

情节是这样的:

plt.scatter(threshold,accuracy) plt.xlabel("Threshold")
plt.ylabel("Balanced accuracy") plt.show()

作者图片

在 0.4 和 0.6 之间有一个明显的最大值。它的确切值是:

threshold[np.argmax(accuracy)] 
# 0.5602892029098923

结论

在本文中,我们看到了两种优化二元分类问题阈值的可能方法。还有其他方法可以使用,但这是两种常见的方法,可以很容易地推广以适应项目的所有需求。永远不要忘记只优化训练数据集,而不要优化测试数据集。优化阈值相当于优化管道的超参数,因此我们只在训练数据集上进行优化。

原载于 2021 年 6 月 14 日 https://www.yourdatateacher.comhttps://www.yourdatateacher.com/2021/06/14/are-you-still-using-0-5-as-a-threshold/

2021 年你还在用熊猫处理大数据吗?

原文:https://towardsdatascience.com/are-you-still-using-pandas-to-process-big-data-in-2021-850ab26ad919?source=collection_archive---------0-----------------------

熊猫处理不好大数据。这两个库有!哪个更好?更快?

美国宇航局在 Unsplash 拍摄的照片

我最近写了两篇关于用 Dask 和 Vaex 处理大数据的介绍性文章——用于处理大于内存数据集的库。在写的时候,一个问题突然出现在我的脑海里:

这些库真的能处理比内存更大的数据集吗,或者这只是一个销售口号?

这激起了我的兴趣,我用 Dask 和 Vaex 做了一个实际的实验,尝试处理一个大于内存的数据集。数据集太大了,你甚至不能用熊猫打开它。

这里有几个你可能会感兴趣的链接:

- [Complete your Python analyses 10x faster with Mito](https://trymito.io/) [Product]- [Free skill tests for Data Scientists & ML Engineers](https://aigents.co/skills) [Test]- [All New Self-Driving Car Engineer Nanodegree](https://imp.i115008.net/c/2402645/1116216/11298)[Course]

你想看更多这样的文章吗?如果是这样,你可以点击上面的任何链接来支持我。其中一些是附属链接,但你不需要购买任何东西。

我说的大数据是什么意思?

ev 在 Unsplash 上拍摄的照片

大数据是一个定义松散的术语,它的定义和谷歌上的点击量一样多。在本文中,我使用这个术语来描述一个非常大的数据集,以至于我们需要专门的软件来处理它。对于大,我指的是“大于单台机器上的主内存”。

来自维基百科的定义:

大数据是一个研究如何分析、系统地提取信息或处理数据集的领域,这些数据集太大或太复杂,传统的数据处理应用软件无法处理。

Dask 和 Vaex 是什么?

照片由JESHOOTS.COM在 Unsplash 上拍摄

Dask 为分析提供先进的并行处理能力,为您喜爱的工具提供规模化性能。这包括 numpy,熊猫和 sklearn。它是开源的,可以免费获得。它使用现有的 Python APIs 和数据结构,使得在 Dask 支持的等价物之间切换变得容易。

Vaex 是一个高性能的 Python 库,用于懒惰的核外数据帧(类似于 Pandas),以可视化和探索大的表格数据集。它每秒可以计算超过 10 亿行的基本统计数据。它支持多种可视化,允许对大数据进行交互式探索。

Dask 和 Vaex 数据帧与 Pandas 数据帧不完全兼容,但这两种工具都支持一些最常见的“数据争论”操作。Dask 更侧重于扩展代码以计算集群,而 Vaex 则更容易在单台机器上处理大型数据集。

如果你错过了我关于 Dask 和 Vaex 的文章:

实验

照片由路易斯·里德在 Unsplash 上拍摄

我已经生成了两个具有一百万行和一千列的 CSV 文件。文件的大小为 18.18 GB,总共 36.36 GB。文件具有 0 到 100 之间均匀分布的随机数。

两个包含随机数据的 CSV 文件。作者拍摄的照片

import pandas as pd
import numpy as npfrom os import pathn_rows = 1_000_000
n_cols = 1000for i in range(1, 3):
    filename = 'analysis_%d.csv' % i
    file_path = path.join('csv_files', filename)
    df = pd.DataFrame(np.random.uniform(0, 100, size=(n_rows, n_cols)), columns=['col%d' % i for i in range(n_cols)])
    print('Saving', file_path)
    df.to_csv(file_path, index=False)df.head()

文件的头。作者拍摄的照片

这个实验是在一台拥有 32 GB 主内存的 MacBook Pro 上进行的——相当大的一台机器。当测试熊猫数据帧的极限时,我惊奇地发现在这样的机器上达到内存错误是一个相当大的挑战!

当内存接近其容量时,macOS 开始将数据从主内存转储到 SSD。pandas 数据帧的上限是机器上 100 GB 的空闲磁盘空间。

W 当你的 Mac 需要内存时,它会将当前未使用的内容推入一个交换文件进行临时存储。当它需要再次访问时,它将从交换文件中读取数据并返回到内存中。

我花了一些时间思考我应该如何解决这个问题,这样实验才会公平。我想到的第一个想法是禁用交换,这样每个库只有主内存可用——祝你在 macOS 上好运。花了几个小时后,我无法禁用交换。

第二个想法是使用暴力方法。我已经将 SSD 填满了它的全部容量,这样操作系统就不能使用 swap,因为设备上没有剩余的可用空间。

你的磁盘在实验期间几乎满了。作者拍摄的照片

这成功了!熊猫无法读取两个 18 GB 文件,Jupyter 内核崩溃。

如果我再做一次这个实验,我会创建一个内存更少的虚拟机。这样就更容易展示这些工具的局限性。

Dask 或者 Vaex 能帮我们处理这些大文件吗?哪个更快?让我们找出答案。

Vaex vs Dask

弗里达·布莱德森在 Unsplash 上拍摄的照片

在设计实验时,我考虑了进行数据分析时的基本操作,如分组、过滤和可视化数据。我想出了以下操作:

  • 计算列的第 10 个分位数,
  • 添加新列,
  • 按列过滤,
  • 按列分组并聚合,
  • 可视化列。

上述所有操作都使用单个列来执行计算,例如:

# filtering with a single column
df[df.col2 > 10]

因此,我很想尝试一种需要处理所有数据的操作:

  • 计算所有列的总和。

这可以通过将计算分解成更小的块来实现。分别读取每一列并计算总和,最后一步计算总和。这些类型的计算问题被称为令人尴尬的并行——不需要努力将问题分成单独的任务。

Vaex

照片由拍摄,照片由 Unsplash 上的 Lanty 拍摄

先说 Vaex。该实验的设计遵循了每种工具的最佳实践,即对 Vaex 使用二进制格式 HDF5。所以我们需要将 CSV 文件转换为 HDF5 格式(层次数据格式版本 5)。

import glob
import vaexcsv_files = glob.glob('csv_files/*.csv')for i, csv_file in enumerate(csv_files, 1):
    for j, dv in enumerate(vaex.from_csv(csv_file, chunk_size=5_000_000), 1):
        print('Exporting %d %s to hdf5 part %d' % (i, csv_file, j))
        dv.export_hdf5(f'hdf5_files/analysis_{i:02}_{j:02}.hdf5')

Vaex 需要 405 秒将两个 CSV 文件(36.36 GB)转换为两个 HDF5 文件,这两个文件总共有 16 GB。从文本到二进制格式的转换减小了文件大小。

使用 Vaex 打开 HDF5 数据集:

dv = vaex.open('hdf5_files/*.hdf5')

Vaex 读取 HDF5 文件需要 1218 秒。我预计它会更快,因为 Vaex 声称可以近乎即时地打开二进制格式的文件。

来自 Vaex 文件:

不管磁盘上的文件大小如何,打开这样的数据都是即时的:Vaex 将只是对数据进行内存映射,而不是在内存中读取它。这是处理大于可用 RAM 的大型数据集的最佳方式。

带 Vaex 的显示头:

dv.head()

Vaex 显示头部需要 1189 秒。我不知道为什么显示每列的前 5 行要花这么长时间。

用 Vaex 计算第 10 个分位数:

请注意,Vaex 具有 percentile_approx 函数,用于计算分位数的近似值。

quantile = dv.percentile_approx('col1', 10)

Vaex 需要 0 秒来计算 col1 列的第 10 个分位数的近似值。

用 Vaex 添加新列:

dv[‘col1_binary’] = dv.col1 > dv.percentile_approx(‘col1’, 10)

Vaex 有一个虚拟列的概念,它将一个表达式存储为一个列。它不占用任何内存,并在需要时动态计算。虚拟列被视为普通列。正如预期的那样,Vaex 需要 0 秒来执行上面的命令。

用 Vaex 过滤数据:

Vaex 有一个选择的概念,我没有使用,因为 Dask 不支持选择,这会使实验不公平。下面的过滤器类似于 pandas 的过滤器,只是 Vaex 不复制数据。

dv = dv[dv.col2 > 10]

Vaex 需要 0 秒来执行上面的过滤器。

使用 Vaex 对数据进行分组和聚合:

下面的命令与 pandas 略有不同,因为它结合了分组和聚合。该命令按 col1_binary 对数据进行分组,并计算 col3 的平均值:

group_res = dv.groupby(by=dv.col1_binary, agg={'col3_mean': vaex.agg.mean('col3')})

用 Vaex 计算平均值。作者拍摄的照片

Vaex 需要 0 秒来执行上面的命令。

可视化直方图:

更大数据集的可视化是有问题的,因为用于数据分析的传统工具没有被优化来处理它们。我们试试看能不能用 Vaex 做一个 col3 的直方图。

plot = dv.plot1d(dv.col3, what='count(*)', limits=[0, 100])

用 Vaex 可视化数据。作者拍摄的照片

Vaex 显示剧情需要 0 秒,速度快得惊人。

计算所有列的总和

一次处理一列时,内存不是问题。让我们尝试用 Vaex 计算数据集中所有数字的和。

suma = np.sum(dv.sum(dv.column_names))

Vaex 需要 40 秒来计算所有列的总和。

达斯克

由 Kelly Sikkema 在 Unsplash 上拍摄的照片

现在,让我们用 Dask 重复上面的操作。Jupyter 内核在运行 Dask 命令之前被重新启动。

我们没有用 Dask 的 read_csv 函数直接读取 csv 文件,而是将 CSV 文件转换为 HDF5,以使实验公平。

import dask.dataframe as ddds = dd.read_csv('csv_files/*.csv')
ds.to_hdf('hdf5_files_dask/analysis_01_01.hdf5', key='table')

Dask 转换需要 763 秒。如果有更快的方法用 Dask 转换数据,请在评论中告诉我。我试图读取用 Vaex 转换的 HDF5 文件,但没有成功。

Dask 的最佳实践:

HDF5 是具有高性能需求的 Pandas 用户的热门选择。我们鼓励 Dask DataFrame 用户使用 Parquet 来存储和加载数据。

用 Dask 打开 HDF5 数据集:

import dask.dataframe as ddds = dd.read_csv('csv_files/*.csv')

Dask 需要 0 秒来打开 HDF5 文件。这是因为我没有显式运行 compute 命令,该命令实际上会读取文件。

带 Dask 的显示头:

ds.head()

Dask 需要 9 秒钟来输出文件的前 5 行。

用 Dask 计算第 10 个分位数:

Dask 有一个分位数函数,它计算实际分位数,而不是近似值。

quantile = ds.col1.quantile(0.1).compute()

由于 Juptyter 内核崩溃,Dask 无法计算分位数。

用 Dask: 定义一个新列

下面的函数使用 quantile 函数来定义一个新的二进制列。Dask 无法计算它,因为它使用分位数。

ds['col1_binary'] = ds.col1 > ds.col1.quantile(0.1)

用 Dask 过滤数据:

ds = ds[(ds.col2 > 10)]

上面的命令需要 0 秒来执行,因为 Dask 使用延迟执行范例。

使用 Dask 对数据进行分组和聚合:

group_res = ds.groupby('col1_binary').col3.mean().compute()

Dask 无法对数据进行分组和汇总。

可视化第 3 列的直方图:

plot = ds.col3.compute().plot.hist(bins=64, ylim=(13900, 14400))

达斯克无法将数据可视化。

计算所有列的总和:

suma = ds.sum().sum().compute()

Dask 无法将所有数据相加。

结果

下表显示了 Vaex 与 Dask 实验的执行时间。NA 表示工具无法处理数据,Jupyter 内核崩溃。

实验中执行时间的摘要。作者拍摄的照片

结论

Joshua Golde 在 Unsplash 拍摄的照片

Vaex 需要将 CSV 转换为 HDF5 格式,这并不影响我,因为你可以去吃午饭,回来后数据就会被转换。我也明白,在恶劣的条件下(像在实验中),用很少或没有主内存读取数据将需要更长的时间。

我不明白的是 Vaex 显示文件头需要的时间(前 5 行 1189 秒!).Vaex 中的其他操作经过了大量优化,这使我们能够对比主存数据集更大的数据集进行交互式数据分析。

我有点预料到 Dask 的问题,因为它更适合计算集群,而不是单台机器。Dask 是建立在熊猫的基础上的,这意味着熊猫慢的操作在 Dask 也会慢。

实验的赢家很明显。Vaex 能够处理大于笔记本电脑主内存的文件,而 Dask 却不能。这个实验很特别,因为我是在单台机器上测试性能,而不是在计算集群上。

在你走之前

在 Twitter 上关注我,在那里我定期发布关于数据科学和机器学习的。

由考特尼·海杰在 Unsplash 拍摄的照片

开始数据科学之旅是否太迟了?

原文:https://towardsdatascience.com/are-you-too-late-to-start-your-data-science-journey-acd228f17243?source=collection_archive---------1-----------------------

我以为我是。

安迪·比厄斯在 Unsplash 上的照片

自从我第一次涉足数据科学以来,已经过去了将近三年。刚开始的时候,我以为来不及了。有许多工具和概念需要学习,大量的论文需要阅读,无数的证书等等。

我最担心的是太晚了,而不是我需要学习的材料的数量。当我学到足够的知识时,我宁愿怀疑我是否能找到工作。数据科学是一个非常热门的话题,已经有相当多的人在这个领域工作。

在过去的三年里,我不仅学习了数据科学,还观察了这个领域的动态。我对太迟的想法改变了。我那时开始还不算太晚。而且,如果我今天开始学数据科学,也不会太晚。

在这篇文章中,我将详细阐述是什么改变了我的想法。如果你不这么想,我希望能改变你的想法。

当我有疑问的时候,我试着简单的思考,这有助于我看清事物。否则,我会被所有的条件、后果和因素分散注意力。

我关于为时已晚的简单而令人信服的想法是基于一个基本概念:供需曲线。在我们的案例中,供应是由拥有在数据科学生态系统中工作所需技能的个人组成的劳动力。工作的数量构成了对这些个人的需求。

数据科学有不同的头衔或专业。数据科学家、数据工程师、机器学习工程师可以名列前茅。如果我们再深入一点,我们会看到头衔缩小到更具体的技能,如自然语言处理(NLP)工程师。

需求在增加

现在的问题变成了数据科学领域是否供过于求。如果数据科学的范围有限,这个问题可能会成为一个严重的问题。我认为这个范围远远超出了我们目前所发现的。更准确地说,将会有更多的企业、行业或流程应用数据科学技术。

在过去的三年里,我观察到数据科学领域的工作数量一直在增加。由于数据科学的范围可能会变得更大,工作的数量也将不断增加。

积极使用数据科学的行业可能会扩展数据的使用,因为他们非常清楚数据科学在其业务中的潜在优势。

例如,零售业正在使用数据科学技术来提高利润率和增加收入。数据科学为客户行为、购买模式、需求预测、产品替代等提供了有价值的见解。

在过去的两年里,由于全球性的疫情影响了人们购物的方式,我们经历了不寻常的时期。网上购物急剧增加。因此,零售商需要一种方法来同时分析在线和离线购物数据。因此,他们致力于利用全渠道数据的新技术,这意味着零售业将有更多的数据科学家职位。

我不知道你是否听说过人类基因组计划,但它对人类至关重要。这是一个研究项目,旨在对所有基因进行测序和绘图。基因组一词用于所有基因的组合。

根据基因组数据科学的概况介绍,预计基因组学研究将在未来十年内产生 2 到 40 艾字节 的数据。这是大量的数据。这些数据的潜在价值是巨大的。我们需要有技能的人来挖掘这种潜在价值。

生物信息学是一个主要专注于分析基因组数据以发现有价值的洞察力的领域。这个领域甚至出现了新的创业公司。如果你拥有数据科学生态系统所需的技能,你获得生物信息学工作的机会相当高。

我想说的是,数据科学在未来可能会无处不在。有些人可能会说已经是了。但是,我相信,数据科学创造价值并被证明有用的领域会更多。随着新领域或新技术的发现,数据科学生态系统对熟练人员的需求将会增加。

但是为什么很难找到工作呢?

对于那些想转行从事数据科学工作的人来说,最大的挑战是找到第一份工作。我面临同样的挑战,花了大约两年时间才找到第一份工作。

这个问题与你是否太晚开始学习数据科学无关。工作就在那里,而且还在增加。然而,如果没有工作经验,很难展示你的技能并说服雇主或招聘人员。

如何展示你的数据科学知识是另一篇文章的主题,但我认为最有效的方法是做项目,在社区中活跃,并拥有一个体面的 Github 帐户。

另一个需要记住的非常重要的事情是,最好专注于一项特定的技能,而不是学习更一般意义上的数据科学。这将增加你的投资组合脱颖而出的机会。

最后的想法

我想我已经清楚地表达了我对题目中问题的答案,但让我再说一次。你学习数据科学并不晚。

学数据科学,找到第一份工作,不是一件容易的事。这需要时间、努力和奉献。你可能需要花几个月的时间来获得基本技能。但是,一旦到了那里,就不会缺少工作机会。

披露:下面的链接是我一次性付款的代销商。

想自学数据科学?发现免费学习资源,添加学习笔记,并加入学习圈进行协作学习。从这里开始。

最后但同样重要的是,如果你还不是的灵媒会员,并打算成为一名灵媒会员,我恳请你使用下面的链接。我将从你的会员费中收取一部分,不增加你的额外费用。

https://sonery.medium.com/membership

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

你是在不知不觉中帮助训练谷歌的人工智能模型吗?

原文:https://towardsdatascience.com/are-you-unwittingly-helping-to-train-googles-ai-models-f318dea53aee?source=collection_archive---------13-----------------------

谷歌如何使用你的 reCAPTCHA 条目来训练机器学习模型

拉杰什瓦尔·巴楚在 Unsplash 上的照片

谷歌的 reCAPTCHA 服务被宣传为一种保护网站免受机器人攻击的手段。如果系统怀疑一个机器人试图访问一个网站,它会进行一些测试,只有人类才能通过。如果你花足够的时间在互联网上,你会看到这种服务的版本。一个图像面板出现了,你必须选择所有包含消防栓、汽车或桥梁的图像。我们以前都遇到过这个系统。如果你以前在试图访问你最喜欢的网站时与这个系统进行过交互,那么恭喜你,你通过为一些谷歌机器学习模型标记一些数据,为它们做出了贡献。在谷歌的 reCAPTCHA 网页的内部,这是该公司关于从该系统捕获的数据的使用的说法:

reCAPTCHA 还通过使用解决方案来数字化文本、注释图像和建立机器学习数据集,积极利用人类在解决验证码方面的努力。这反过来有助于保存书籍,改进地图,解决人工智能的难题。

让我们看看谷歌是如何做到这一点的,推测我们正在帮助改进的模型,以及我对这个系统的看法,在这个系统中,人们不知不觉地训练了一些 Alphabet Inc 人工智能模型。

监督机器学习的快速概述

安迪·凯利在 Unsplash 上拍摄的照片

简而言之,受监督的机器学习模型试图根据模式学习或表征不同类别的特征对数据进行分类。为了做到这一点,一个受监督的机器学习模型被提供了大量带标签的数据,称为训练数据。带标签的数据是带有标识类的标签的数据。受监督的 ML 算法将学习与类相关联的特征,因此它可以对新数据进行分类。

因此,为了训练 ML 模型来对例如火车、飞机或船只的图像进行分类,成千上万的物品的标记图像被输入到算法中,在算法中,像尺寸、颜色、形状等特征被用来区分类别。训练后,人们可以传入船只、火车和飞机的新的、未标记的图像,ML 模型将基于来自训练数据集的学习对它们进行分类。

谷歌是如何从 reCAPTCHA 收集数据的?

如前所述,如果 reCAPTCHA 服务怀疑一个机器人试图与一个网站进行交互,它将进行测试以确认你是人类。有时它是一个简单的复选框。其他时候,更有趣的挑战是从一组图像中选择符合特定描述的图像。一旦您正确识别出符合描述的图片,您就可以访问您想要访问的页面。因此,你在这些挑战中所做的是提供一些带标签的数据,这些数据将用于 Alphabet Inc 旗下一些人工智能的训练数据集。

显而易见的问题是,谷歌如何知道一个网络用户何时选择了所有符合描述的图片?如果谷歌的好处是美国用户为人工智能模型标记一些数据,那么毫无疑问,他们事先并不知道这些图像包含什么。答案是,当谷歌向你展示一组图片时,比如说,六张图片,其中五张已经被标注了。网络用户被要求正确识别五张图片,包括,也就是谷歌想要标注的那张。你只需要正确识别谷歌已经标记的四张图片,你对第五张未知图片的答案就会进入人工智能训练数据集。

这些数据的用途是什么?

在 Unsplash 上海拉戈斯蒂奇的照片

至于这些数据被用来训练什么人工智能,这基本上是不可知的,除非你在公司内部。但是我们可以根据我们被要求识别的图像类型做出一些有根据的猜测。reCAPTCHA 挑战似乎与道路、交通信号或汽车有关。这可能是一个线索,这些数据将用于训练 Alphabet Inc .的自动驾驶汽车公司 Waymo 使用的某种模型。谷歌在他们的网页上提到,这些数据可以用来帮助改进地图,根据我们看到的图像,这也是有道理的。再说一次,如果不在 Alphabet Inc .内部,很难知道所有数据最终去了哪里。

最后的想法

我认为大多数人会觉得谷歌使用我们提供的数据的方式有一种欺骗或不诚实的感觉,这是一种商业行为,没有适当地通知用户正在发生什么。事情是这样的,如果谷歌明确表示 reCAPTCHA 的一些答案将在未来用于训练谷歌模型,我不相信大多数人会感到不安。我确实认为让人们了解正在发生的事情并给出选择退出的选项是很重要的。

还值得注意的是,这一系统只存在于 V2 的 reCAPTCHA。谷歌现在有一个 reCAPTCHA V3,它完全不会打断用户来检测机器人。相反,reCAPTCHA V3 根据一系列指标对网站的所有访问者进行评分,分数越低,你越有可能是一个机器人。然而,reCAPTCHA V2 仍然活跃在一些网站上。最后,我要说,应该鼓励科技公司提高透明度。我只能假设缺乏透明度的原因是因为担心用户会选择不遵守,但这应该是我们用户做出的决定。

你的人工智能工作是可复制的吗?

原文:https://towardsdatascience.com/are-your-ai-jobs-reproducible-2a86bdffbf44?source=collection_archive---------64-----------------------

记录更多关于整个系统的信息可以提高重现性,尤其是性能指标评测结果

马特·布里内在 Unsplash 上拍摄的照片

除了框架+数据集,我鼓励人们在记录培训工作时考虑他们更广泛的系统。

这在 AI 性能基准测试期间尤其重要。最近有人问我,“在 MLPerf 测试中,我每秒得到 100,000 张图像。那快吗?”我不知道。你用的是什么精度?多大批量?硬件?数据集存储在哪里?

从基础设施、软件到运行时可调参数,许多因素都会影响训练性能。如果别人不能记下你的笔记并重现你的测试结果,你就没有解决可重复性的问题。

关注再现性的几个原因:

1。严格的文档实践有助于产品开发(在法律上可能是必要的)。

通常,数据科学家必须在提高准确性和增加训练时间之间做出权衡。检查之前训练跑步设置的矩阵有助于找到更快“达到准确性的时间”的途径

2。它有助于您确保获得预期的绩效。

数据科学家应该能够将他们的吞吐量结果与社区提供的结果进行比较。它帮助您检查
-您的脚本是否充分利用了您系统的性能
-您的基础设施没有被错误地配置

3。它让硬件/软件开发团队评估他们的下一代产品。

这种最新的加速器模型是否足以作为一种改进来运输呢?这个最新的框架代码版本有性能回归吗?

4。它帮助开发者和购买者在平台之间进行决策。

只有通过相互比较,团队才能对更改单个组件将会产生的性能影响有一个合理的想法。

我已经在记录 TensorFlow 版本了。

这还不够。

框架版本很重要,但它不是全部。大图有两部分:
-运行级参数
-系统

如果您知道运行级参数,您应该能够走向系统并重现性能结果。这意味着“系统”包括所有端到端硬件(及其操作系统、固件和软件)以及所有设置和库版本(包括容器堆栈)。

我见过的几个随机事件的例子显著地影响训练性能:
-Docker 允许使用的内存量
-加速器上的 MTU 设置-以及架顶式交换机上的 MTU 设置!
——我从未听说过的低级 PCIe 设定

所以 100 件事会影响表现。我需要记录的最低限度是什么?

以下是 6 个最重要的项目。记录这些以使您的结果更具重现性:

  1. 加速器模型
  2. 加速器驱动程序版本
  3. 批量
  4. 精确
  5. 完整的库版本列表,或者容器映像 ID,如果您使用的是来自 NGC 或云供应商的预构建映像。
  6. 数据集,包括数据集格式(例如 JPEG v. TFRecord)

这些是影响性能的主要设置,其中大多数可能会随着时间的推移而改变。

摘要

如果你测试你的 DL 训练表现,你应该把它想成一个及时的快照。系统是如何配置的,您为运行选择了什么设置?

如果我们开发了更好的实践来使结果具有可重复性,我们将更好地了解随着堆栈的每一部分的发展性能的提高,并且我们将通过突出瓶颈来推动创新。

让我们让“图像/秒”更有意义!

您的微服务是否以应有的方式运行?耶格可以帮忙!

原文:https://towardsdatascience.com/are-your-microservices-performing-the-way-they-should-jaeger-can-help-6e428f017cc?source=collection_archive---------24-----------------------

对复杂分布式系统中的服务进行监控和故障排除,比如 Kubernetes。

阿巴斯·特拉尼在 Unsplash 上拍摄的照片

假设您部署了一个应用程序,报告以美元为单位的加密货币的当前价格。如果你想形象化它,想想类似于的东西。

现在,让我们假设 CoinMarketCap 在 3 秒内做出响应。这意味着,如果用户导航到他们的页面,他们可以很快获得他们感兴趣的硬币的价格。另一方面,您的应用程序至少需要 8 秒钟来提供答案。我敢打赌,一两周之后你就不会有很多用户了!

你需要迅速找出问题所在。怎么花了这么长时间?哪项服务表现不佳?您知道您必须对代码进行一些更改,但是您如何知道从哪里开始呢?在云原生世界中,像获取比特币的美元价格这样简单的事情可能涉及许多微服务。

这个故事介绍了 Jaeger ,这是一个开源的端到端分布式跟踪工具,可以让您观察应用程序内部的情况。

学习率是为那些对 AI 和 MLOps 的世界感到好奇的人准备的时事通讯。你会在每周五收到我关于最新人工智能新闻和文章的更新和想法。在这里订阅!

监控与可观察性

当错误发生时,开发人员需要正确的反馈,这样他们就知道该修复什么。我们有“日志记录”,但是日志记录告诉你发生了什么,但是如果你的代码运行到完成,它不能告诉你为什么它表现不好。

同样,监控不会告诉我们应用程序内部发生了什么。它会给出诸如内存可用性低之类的指标,但它不会帮助我们查明问题的原因。

然后,我们有可观测性。在可观察性中,我们可以直接进入我们的应用程序,观察它的各种过程和功能。我们可以看到服务如何执行以及它们如何交互。然后,我们可以揭示几个问题或发现优化,使我们的应用程序性能更好。

根据经验,请记住:我们监控系统并观察应用程序。你还会听到人们使用术语可观察性来对这两个概念进行分组(即监控可观察性)。如果您想了解更多关于监控和可观察性的信息,请查看以下内容:

贼鸥

Jaeger 是领先的开源端到端分布式追踪工具。什么是分布式跟踪?简而言之,就是在微服务的世界里寻迹。它允许您在被监控的应用程序中跟踪请求或事务的过程。

优步在 2015 年创建了 jaeger,并将其捐赠给了云原生计算基金会(CNCF)。Jaeger 收集应用程序信息,而领先的监控工具 Prometheus 收集系统信息。

此外,与“日志记录”相反,Jaeger 告诉你一个函数是如何执行的,而不是它是如何失败的。它通过各种服务跟踪请求,这使得它非常适合测量延迟问题。

耶格使用轨迹和跨度来实现这一切。所以,一些术语:

  • 一个轨迹是一个通过系统的数据/执行路径,可以被认为是一个有向无环的跨度图。
  • 一个跨度表示 Jaeger 中的一个逻辑工作单元,它有一个操作名、操作的开始时间和持续时间。跨度可以被嵌套和排序以模拟因果关系。

走线与跨度

装置

为了安装 Jaeger 服务器,我们依赖 Docker 提供的便利。因此,我们可以只运行以下命令:

docker run -d -p5775:5775/udp -p6831:6831/udp -p6832:6832/udp -p5778:5778 -p16686:16686 -p14268:14268 -p9411:9411 jaegertracing/all-in-one:0.8.0

现在您可以启动您最喜欢的浏览器,Jaeger UI 将在[localhost:16686](http://localhost:16686)等待您:

Jaeger UI——作者图片

这是我们将发送跟踪的服务器。接下来,我们需要安装必要的 Python 包,以便能够发送这些跟踪:

pip install jaeger-client

简单的例子

正如我们所说,我们希望构建一个应用程序,返回前 100 种加密货币的价格。因此,首先,我们需要安装 Python requests库,这样我们就可以发出 HTTP 请求:

pip install requests

下一步是初始化一个tracer对象:

我们可以使用这个 tracer 对象来生成我们的跨度。我们需要两个跨度:

  1. 第一个将是父跨度。它将跟踪整个过程需要多长时间才能完成。
  2. 第二个是跟踪检索每种加密货币的信息所需的时间。

上面的代码首先获取父 span 中所有可用的 crypto,然后为每个 crypto 发出一个新的请求来获取它的信息并打印它的价格。当然,我们可以在没有第二个请求的情况下这样做,因为我们在第一个调用中获得了我们需要的所有信息,但这是一个用于演示目的的示例。

如果我们现在导航到 Jaeger UI,刷新页面,从Service菜单中选择crypto-service并按下Find Traces按钮,我们将得到这个视图:

耶格痕迹——作者图片

通过深入研究它收集的 101 个跨度(1 个父节点和 100 个顶级加密节点),我们可以看到每个请求的响应时间:

耶格潜伏——作者图片

现在,我们又多了一条关于我们需要做得更好的线索!

结论

这个故事介绍了 Jaeger,领先的开源端到端分布式追踪工具。

使用 Jaeger,我们可以直接进入我们的应用程序,观察它的各种过程和功能。我们可以看到服务如何执行以及它们如何交互。然后,我们可以揭示几个问题或发现优化,使我们的应用程序性能更好。

在后面的文章中,我们将看到如何用 Grafana 构建仪表板,向用户公开这些信息,并集成来自 Prometheus 的监控信息。

关于作者

我的名字是迪米特里斯·波罗普洛斯,我是一名为阿里克托工作的机器学习工程师。我曾为欧洲委员会、欧盟统计局、国际货币基金组织、欧洲央行、经合组织和宜家等主要客户设计和实施过人工智能和软件解决方案。

如果你有兴趣阅读更多关于机器学习、深度学习、数据科学和数据操作的帖子,请关注我的 Medium 、 LinkedIn 或 Twitter 上的 @james2pl 。

所表达的观点仅代表我个人,并不代表我的雇主的观点或意见。

你的播放列表够酷吗?

原文:https://towardsdatascience.com/are-your-playlists-groovy-enough-7809faaf9c33?source=collection_archive---------36-----------------------

让我们和朱莉娅一起使用 Spotify 的公共 API 来找出答案

由 Unsplash 上的 Blaz Photo 拍摄

最近,我看到一些优秀的文章,作者利用 Spotify 的 API 来分析他们的音乐数据。这让我非常好奇,我决定尝试使用 Julia 做类似的事情。谢天谢地,API 的包装器已经在 Spotify.jl 中实现了,但是这个包还没有注册。这当然不是问题,我们总是可以直接从它的 GitHub 库安装它。

在本文中,我将演示如何使用 Pluto 笔记本检索和可视化您的音乐数据。关于如何为你的系统设置 Pluto 的说明可以在我之前的文章中找到。设置完成后,打开一个新的笔记本或直接使用中的现有笔记本。可以使用提供的实例化包环境。toml 文件。这对保持结果的再现性是有用的(但不是必须的)。

using Pkg
Pkg.activate(pwd())
Pkg.instantiate

要在您的工作环境中导入所有相关的包,请执行以下命令:

using Spotify, DataFrames, VegaLite, Setfield, JSON, Statistics, Query

获取 API 访问的凭据

为了使用 API,您首先需要获得适当的凭证。这可以通过创建一个 Spotify 开发者账户来实现。打开您的仪表板,通过填写名称和用途来创建应用程序。然后点击“显示客户机密”查看您的密钥。将这些凭证复制到您的Spotify _ credentials . ini文件中,该文件将在您首次尝试使用该包时自动创建。凭证仅在 1 小时内有效。因此,一旦过期,您需要通过执行以下命令进行刷新:

Spotify.refresh_spotify_credentials()

终端输出应显示到期时间,例如:

[ Info: Expires at 2021–10–30T19:37:32.556

测试您的证书

例如,您可以通过获取关于某个相册的信息来测试 API 是否正常工作。所有对象,包括专辑,曲目,艺术家等。拥有唯一的 Spotify ID。我们使用 album_get 函数以及相册 ID 和位置(=“US”)参数,如下所示:

获取有关相册的信息

请求个人数据

您可以通过以下方式向 Spotify 请求一份您的个人数据:

  • 在桌面浏览器上打开 Spotify 进入个人资料→账户
  • 从左窗格打开“隐私设置”
  • 向下滚动到“下载您的数据”部分,并继续执行步骤 1

一旦您的数据可供下载,您将收到一封电子邮件。对我来说,它看起来有 3 天了。你会收到一个 JSON 文件的集合,我们主要对流数据感兴趣,它显示了我们花了多少时间听不同的曲目。

检索我的播放列表的音频功能

我首先想看的是一些我最喜欢的播放列表的音频特性。我从 Spotify 桌面播放器中收集播放列表 ID,方法是打开播放列表并在 URL 的末尾复制 ID(字母数字字符)。我将它们放在一个数组(类型字符串)中,如下所示:

播放列表 id

每个曲目都有音频特性,这意味着我们首先需要从每个播放列表中获取曲目 id。这是通过使用函数 **get_playlist_tracks,**来完成的,其中我们发出一个 HTTP GET 请求来获取这些信息。

这个功能还不是 Spotify.jl 的一部分(很快会做一个 PR)。返回的最大曲目数量为 50 首。你可以想象,在一个给定的播放列表中可以有超过 50 首曲目。因此,我们需要用新的偏移量(返回的第一项的索引,默认为 0)重复调用这个函数。最后,我们删除重复的曲目(相同的曲目可以出现在许多播放列表中),并返回曲目 id 数组。

曲目 id 列表

接下来,我们要获取每个音轨 ID 的音频特征。我们将使用 Spotify.jl 的tracks _ get _ audio _ features功能,并将它们收集在一个数据帧中。关于音频功能的细节可以在这里找到。

得到的数据帧 df_audio 应该是这样的:

具有音频特征的数据帧

请注意,我们没有针对所有曲目的功能。要么它们不可用,要么我们可能遇到 API 调用限制。无论如何,我们有足够的数据来做一些很好的可视化。

绘制音频特征

我们可以创建一个通用的绘图函数,它将一个列名作为参数,以便从 df_audio 创建一个直方图。

现在,让我们来看看我选择的播放列表中曲目的各种音频特征的分布。

各种音频特征的分布

  • 第一个图显示了“可跳舞性”的分布。从 Spotify 的文档,

可跳舞性描述了基于音乐元素(包括速度、节奏稳定性、节拍强度和整体规律性)的组合,一首曲目适合跳舞的程度。值 0.0 最不适合跳舞,1.0 最适合跳舞。

似乎我的大多数曲目都有很高的可跳性(> 0.5)。

  • 第二个图显示了音频“能量”。Spotify 表示…

能量是一种从 0.0 到 1.0 的度量,代表强度和活动的感知度量。通常,高能轨道感觉起来很快,很响,很嘈杂。对该属性有贡献的感知特征包括动态范围、感知响度、音色、开始速率和一般熵。

因为我喜欢听大部分由乐器组成的放松播放列表,所以更多的音轨能量值低于 0.5 是有道理的。

  • 第三个图显示了音频“语音”。根据文档,

语音检测音轨中是否存在语音单词。越是类似语音的录音(例如脱口秀、有声读物、诗歌),属性值就越接近 1.0。高于 0.66 的值描述可能完全由口语单词组成的轨道。介于 0.33 和 0.66 之间的值描述可能包含音乐和语音的轨道,可以是分段的,也可以是分层的,包括说唱音乐。低于 0.33 的值很可能代表音乐和其他非语音类轨道。

我的大多数曲目都有一个值< 0.2, which is consistent with the fact that I prefer instrumental tracks.

  • Last plot shows the audio “valence”.

It’s a measure from 0.0 to 1.0 describing the musical positiveness conveyed by a track. Tracks with high valence sound more positive (e.g. happy, cheerful, euphoric), while tracks with low valence sound more negative (e.g. sad, depressed, angry).

Most of my tracks seem to have a valence value less than 0.5. Does that mean that I am into sad/angry music? I wouldn’t like to think so, many of my relaxing playlists actually help to improve my mood. How does your valence distribution look like? Do let me know in the comments.

Correlation between different audio features

I thought it would be interesting to also look at how correlated audio features are w.r.t. one another. To help quantify that, we can also compute the 皮尔逊相关系数,值越接近 1 表示相关性越强。

下面是各种图的样子:

音频特征之间的相关图

可跳舞性显示出与能量的某种相关性,这是可以预料的,因为能量越大的曲目通常也非常适合跳舞。可跳性高的曲目也往往更欢快、更快乐。因此,与化合价的强相关性可以得到解释。类似地,具有更高能量的轨道也可能显示出与更高价态更强的相关性,这就是我们所看到的。

跟踪持续时间和受欢迎程度数据

对于每首曲目,我们可以使用 tracks_get 函数获得额外的信息,比如流行度和持续时间。

绘制从上述函数返回的数据帧( df_track )与前面的例子类似。

根据上面的图表,我认为我喜欢的歌曲的最佳时长是 3-4 分钟左右。关于受欢迎程度的数字(0-100 分,100 分最受欢迎),似乎许多艺术家都有相当高的受欢迎程度(> 50)。

音乐流派

tracks_get 函数返回的 dict 也包含艺术家的 ID。我们可以收集所有的艺术家 id,然后获取艺术家数据,比如与他们相关的音乐流派。相关代码可以在冥王星笔记本上找到。似乎“阿富汗流行”、“艺术流行”和“氛围”是我一直在听的一些比较常见的流派。

绘制个人流数据

我们不应该忘记可以从 Spotify 请求的个人数据(JSON 文件)。档案**<>。json** 可以转换成 DataFrame ( df_stream )并排序 w.r.t .分钟播放。

我们现在可以看看前 10 个轨道,它们实际上是 df_stream 的前 10 行。

如果能得到顶级艺术家的名单会很有趣。这是一些额外的工作,因为我们现在必须组合来自相同艺术家但不同曲目的流时间。因此,对于每一位艺术家,我们过滤 df_stream 并合计相关曲目的总时长。

休伦大人是我最喜欢的歌曲之一,很明显,在过去的 1-2 年里,我经常听他们的歌。普拉蒂克·库哈德是另一颗宝石,当然,A.R .拉赫曼无需介绍。“当地火车”有一些很棒的歌曲,已经成为印度最好的乐队之一。

结论

对于 Spotify 用户来说,可以从他们的音乐流媒体数据中学到很多东西。我发现这个 API 有很好的文档记录,非常有用。还有一些其他有趣的端点,但是我将把它们留给另一个讨论。我希望你喜欢阅读这篇文章。感谢您的宝贵时间!完整代码(冥王星笔记本)可在这里获得。如果你想联系,这是我的 LinkedIn。

参考

  1. https://developer . Spotify . com/documentation/we b-API/quick-start/
  2. https://github.com/kwehmeyer/Spotify.jl
  3. https://towards data science . com/visualizing-Spotify-data-with-python-tableau-687 F2 f 528 cdd

你的正则表达式操作需要时间吗?如何让它们更快

原文:https://towardsdatascience.com/are-your-regex-operations-taking-time-how-to-make-it-faster-ae974a5a1874?source=collection_archive---------14-----------------------

FlashText——NLP 任务正则表达式的更好替代

图片由来自 Pixabay 的 Michal Jarmoluk 拍摄

自然语言处理(NLP)是人工智能的一个子领域,涉及计算机和自然人类语言之间的交互。NLP 涉及文本处理、文本分析、将机器学习算法应用于文本和语音等等。

文本处理是 NLP 或基于文本的数据科学项目中的关键元素。正则表达式有多种用途,如特征提取、字符串替换和其他字符串操作。正则表达式也称为 regex,它是许多编程语言和许多 python 库都可以使用的工具。

Regex 基本上是一组字符或模式,用于对给定的字符串进行子串化,可以进一步用于搜索、提取、替换或其他字符串操作。

FlashText:

FlashText 是一个开源的 python 库,可以用来替换或提取文本中的关键词。对于 NLP 项目,无论是否需要进行单词替换和提取,我们都会遇到一些文本处理任务,FlashText 库使开发人员能够有效地执行关键字的提取和替换。

安装:

可以使用 PyPl 安装 FlashText 库:

**pip install flashtext**

用法:

FlashText 库的使用是有限的,它被限制在提取关键字,替换关键字,获取关于提取的关键字的额外信息,删除关键字。在下面的示例笔记本中,您可以找到计算和比较 FlashText 和 RE 之间的基准数的代码片段,用于从取自维基百科的文本中提取和替换关键字。

(作者代码)

使用 re 和 FlashText 库对取自机器学习的维基百科页面的文本文档(约 500 个单词)进行关键词提取和替换。

(图片由作者提供),RE 和 FlashText 库之间的基准时间约束

您可以观察两个库之间的基准时间数,这是为两个任务执行的:关键字提取和替换。这些任务是针对大约 500 个单词的一小段文本执行的。时间数量的差异非常小,因此性能是不可区分的。

下图表示对具有 10,000 个标记的文本文档进行 1000 个关键词替换操作的次数。可以看出,FlashText 操作比 Regex 快 28 倍。

( Souce ),左: replace() 函数的时间约束,**右:**search()函数的时间约束,介于 Regex 和 FlashText 之间

为什么不是 Regex,为什么是 FlashText?

对于小尺寸文档的正则表达式操作,时间数非常接近,并且两个库的性能没有区别。对于大尺寸文档,FlashText 库的性能明显超过,其中 FlashText 库的 1000 个关键字的替换操作比 Regex 快 28 倍。

根据 FlashText 文档:

Regex 基于自定义算法,如Aho-coraseck 算法和 Trie 字典。FlashText 库可以在一个文档中搜索或替换关键字,并且时间复杂度不依赖于要搜索或替换的术语的数量。FlashText 库被设计为只匹配完整的单词,不像 Regex 那样也匹配子字符串。

For a document of size ***N tokens*** and a dictionary of ***M keywords***,
Time Complexity of ***FlashText*** is **O(N)**.
Time Complexity of ***Regex*** is **O(MxN)**.

因此,FlashText 算法比 Regex 快得多。

点击此处阅读 FlashText 算法的整篇文章。

结论:

对于小文档,两个库的性能比较取决于很多因素,比如缓存。FlashText 库在处理具有大量标记的文本文档方面明显优于其他库。FlashText 的时间复杂度为 O(N ),而 Regex 的时间复杂度为 O(M*N ),因此建议对超过 500 个标记的文本文档使用 Regex。

点击此处获取 FlashText 的 GitHub 库

参考资料:

[1]大规模替换或检索文档中的关键词,(2017 年 11 月 9 日):https://arxiv.org/abs/1711.00046

[2] FlashText 文档,(2018 年 2 月 16 日):https://pypi.org/project/flashtext/

感谢您的阅读

零镜头文本分类变压器模型是更好的聊天机器人的关键吗?

原文:https://towardsdatascience.com/are-zero-shot-text-classification-transformer-models-the-key-to-better-chatbots-dd91dac3854a?source=collection_archive---------18-----------------------

为您的下一个聊天机器人项目使用零镜头文本分类转换器模型克服对训练数据的需求

作者图片

对于许多自然语言处理(NLP)项目来说,最麻烦的任务之一是收集和标记训练数据。但是,对于聊天机器人的意图分类,有一个潜在的解决方案,那就是使用零镜头文本分类转换器模型。如果成功,这种方法将降低开发聊天机器人所需的复杂性,同时潜在地提高它们的性能。我鼓励你扩展这些想法,并可能将它们集成到你的聊天机器人系统中。

意图分类是聊天机器人执行的基本任务。意图分类是确定用户希望执行哪个动作的动作。例如,假设你问一个聊天机器人,“请播放 U2 的最新歌曲”,那么机器人必须确定用户希望“播放一首歌曲”。从那里,该模型将典型地使用实体识别来确定播放哪首歌曲。本文提出了一种在没有任何训练数据的情况下利用新技术执行意图分类的可能方法。

零镜头文本分类

零镜头文本分类转换器模型于 2019 年在论文“基准零镜头文本分类:数据集、评估和蕴涵方法”[1]中提出。模型的输入被表述为每个标签的蕴涵问题。因此,给定文本“我想买一个苹果”和标签“食物”,前提将是文本,假设将类似于“这篇文本是关于食物的。”然后,模型确定假设是否需要前提。有了这项技术,NLP 实践者可以在单个文本蕴涵数据集上训练他们的模型,然后使用该模型对任意标签执行文本分类。

作者图片

我们将使用在拥抱脸的模型分发网络上下载量第二多的零镜头文本分类模型,它是由脸书·艾创建的。它是在麻省理工学院许可下发布的,这是一个许可许可你可以在这里阅读更多关于的内容。

体系结构

本文提出了一个基于树的意图分类系统,该系统利用零镜头文本分类模型。有些意图可能会被归类在一起,因此,我认为最好先确定意图的类别,然后再确定要执行的具体行动。例如,一个类别可以是“播放音乐”,然后该类别的意图可以是“播放艺术家”或“播放专辑”

在不应用零射击模型的情况下,使用类似的基于树的系统可能是遥不可及的,原因有两个。首先,您可能需要一个模型来对类别进行分类,然后为每个类别建立一个模型。所以,如果你在处理一个有很多可能动作的系统,这可能会有很多模型。然后,由于型号和类别数量的增加,需要更多的培训。因此,通过使用这个提出的系统,对于这个整个基于树的分类系统,只需要一个单一模型

作者图片

模型创建

目前,拥抱脸的变形金刚库是实现零镜头文本分类变形金刚模型的首选方式。因此,我们可以用下面一行代码从 PyPI 下载这个包。

pip install transformers

拥抱脸创建了一个名为“管道”的功能,它抽象了使用变压器模型进行推理通常涉及的复杂性。还是导入吧。

from transformers import pipeline

我们需要向管道类提供我们希望执行的任务和模型名称。然后,它将输出一个我们可以用来开始分类文本的对象。任务 id 为“零镜头分类”,模型名称为“ facebook/bart-large-mnli ”。

task = "zero-shot-classification"
model = "facebook/bart-large-mnli" classifier = pipeline(task, model)

主要意图分类

让我们为模型定义一个任意的标签列表来对文本进行分类。对于这个例子,我将为虚拟电话助理将要执行的常见任务添加标签。

primary_labels = ["take note", "play music", "search internet ", "send email", "create reminder"]

我们现在可以将文本归入这些标签之一。首先,让我们定义与这些标签之一相关的文本。我们将使用一个属于“播放音乐”类别的例子。

input_text = "Put on Drake's new album"

为了生成预测,我们可以向我们的分类器提供文本和标签,如下所示。

classifier_output = classifier(input_text, primary_labels)

我们现在可以打印结果了。

print(classifier_output["labels"]) print(classifier_output["scores"])

结果:

['播放音乐','做笔记','创建提醒','搜索互联网','发送电子邮件'][0.8064008355140686,0.1329479217529297,0.04738568142056465,0.010709572583436966,0.00255559617206454277]

标签和分数都按最高分排序。因此,在这里我们看到“播放音乐”是最高的结果,得分为 80.64%,这是有道理的。

次要意图分类

对于每个主要标签,我们必须创建一个次要标签列表,以进一步细化用户的意图。继续上面的例子,因为主要标签是“播放音乐”,下面是潜在动作的列表。

secondary_labels = ["play artist", "play song", "play album", "play popular", "play new", "play old"]

如前所述,我们可以使用零镜头文本分类模型来确定预期的动作。我们将向模型提供原始文本和二级标签。

secondary_classifier_output = classifier(input_text, secondary_labels) print(secondary_classifier_output["labels"]) print(secondary_classifier_output["scores"])

['播放专辑','播放艺人','播放新','播放流行','播放歌曲','播放旧']
0.2994290888309479,0.23053139448165894,0.209768395962143,0.136963962316513,0.1226228971113205

我们走吧!我们只是决定执行哪些操作。我们看到“播放艺术家”、“播放专辑”和“播放新闻”得分都很高。因此,现在我们可以使用实体识别来检测文本中的艺术家,然后查询该艺术家的最新专辑。

结论

在这篇文章中,我提出了一种利用零触发文本分类模型来消除意图识别对训练数据的需求的方法。我还讨论了如何使用这种方法来创建一个树状搜索算法,以细化用户希望执行的确切操作。我希望这篇文章能启发你创建更强大的聊天机器人!

如果您成功地为一个项目实施了这一建议方法,请发送电子邮件至 eric@vennify.ca。我很想听听。

参考

[1] W. Yin,J. Hay,D. Roth,基准测试零镜头文本分类:数据集、评估和蕴涵方法 (2019),EMNLP 2019

[2] A.Williams,N. Nangia,S. Bowman,通过推理进行句子理解的广泛覆盖挑战语料库 (2018),计算语言学协会

资源:

本教程中使用的代码

类似文章

如果你喜欢这篇文章,那么你可能也会喜欢下面这篇文章,它涵盖了我的一个原创研究项目,涉及零镜头文本分类转换器模型。

题目:如何标注文本分类训练数据—用 AI 总结:用一个零镜头的文本分类模型来标注训练数据。然后,使用带标签的训练数据来微调更容易在生产中使用的小型监督模型。

视频

原载于 2021 年 9 月 8 日https://www . vennify . ai

带 Plotly Express 的面积图

原文:https://towardsdatascience.com/area-charts-with-plotly-express-510a1f12ac11?source=collection_archive---------29-----------------------

痕迹&布局

图片由来自 Unsplash 的 Pawel Czerwinski 提供

Plotly 图形对象

面向对象的人物创作界面 Plotly Express 于 2019 年发布。它是 Plotly.py 的高级包装器,包括绘制标准 2D & 3D 图表和 choropleth 地图的函数。与 Plotly 生态系统的其余部分完全兼容,是快速开发探索性图表的优秀工具。

但是如果您想增强您的绘图,您需要导入一组名为 graph objects 的类。

import plotly.graph_objects as gofig = go.Figure()

plotly.graph_objects 模块包含 Python 类的层次结构。是初级类。有一个数据属性和一个布局属性。数据属性有 40 多个对象,每个对象引用一个特定类型的图表( trace) 及其相应的参数。布局属性指定图形的整体属性(轴、标题、形状、图例等。).

概念上的想法是使用 fig.add_trace()fig.update_layout() 来操纵这些属性,以便增强已经构建的图形。

让我们用不同类型的面积图来分析这种方法。

面积图

面积图是折线图的一种形式,横轴和连接数据点的线之间的区域用颜色填充。它们用于传达总体趋势,而不关心显示准确的数值。

纵轴代表定量变量,而横轴是时间线或一系列数值区间。数据点由形成折线的线段连接,折线和水平轴之间的区域用颜色或某种类型的阴影填充。

面积图(AC)有四种类型:1)标准 AC;2)堆叠式 AC;3)堆叠交流百分比;4)交迭交流。

1.— 标准面积图(又名面积图):它们对于显示一个数值变量随时间的演变特别有效。这样做的目的是更加强调整体趋势以及连接数据点的线的波峰和波谷。

2.— 堆积面积图:就像几个面积图一个叠一个。在这种类型的图表中,有第三个变量,通常是分类变量,以及相应的数据系列。每一个数据序列的表示都从先前数据序列结束的地方开始(它们不重叠)。最后一个数字表示所有数据的总和。

3.— 百分比堆积面积图(也称为 100%堆积面积图):就像前面的图表一样,几个区域堆叠在另一个区域的顶部,并表示第三个分类变量。这是一个部分到整体的图表,其中每个区域表示每个部分相对于类别总数的百分比。垂直轴的最终高度始终为 100%。这意味着图表顶部有第二条基线,有助于跟踪某些特定趋势。

4.— 重叠区域图:在这种图形中,区域之间有一些重叠。颜色和透明度必须适当调整,以便可以很容易地看到特定的线条。它们让我们能够很好地比较不同的趋势。

带 Plotly Express 的面积图

我们使用了从 Kaggle [1]下载的数据集。该数据集包含从 VzCharts 收集的与视频游戏销售和游戏评级数据相关的记录。我们特别选择了一个 csv 文件,其中有 1031 条关于索尼在 Playstation 4 平台上销售视频游戏的记录。我们想知道 2013 年至 2018 年期间全球不同地区的销售额分布情况。

首先,我们导入 Plotly Express 为 *px,*Pandas 库为 pd ,并将我们的 csv 文件转换成 dataframe:

import pandas as pd
import plotly.express as pxpath  ='your path'
df = pd.read_csv(path + 'PS4_GamesSales2.csv', 
     index_col = False, header = 0, sep = ';', engine='python')

下面的屏幕截图显示了数据集的前十条记录:

记住:真实世界的数据是脏的。所以我们在使用数据之前做了一些清理。具体来说,我们使用 dropna 删除 Year 列中具有 N/A 值的行,并使用 drop 删除 Global 列中具有 0 值的行。然后,我们根据列将数据分组,并对每个组应用函数 sum()

df.dropna(subset = ['Year'], inplace = True)df.drop(df[df['Global'] == 0.0].index, inplace = True)df_area = df.groupby(['Year']).sum().reset_index()

现在我们准备绘制我们的第一张图表。

对于本文的标准面积图,Plotly Express 函数为 px.area ,对应的参数为:data _ frame;x=表示时间线的数据帧中的列的名称;y =**data _ frame中的列名,代表计算的统计数据。我们用 update.layout 更新了图表:设置标题、字体大小,用宽度高度设置图形尺寸。然后我们更新了 x 轴和 y 轴(文本、字体、tickfont)。我们将图表保存为静态的 png 文件,最后,我们使用默认模板( plotly 、【带 Plotly Express 的直方图、主题&模板】、https://towards data science . com/Histograms-with-Plotly-Express-e 9e 134 AE 37 ad)绘制图表。

fig1 = px.area(
       df_area, x = 'Year', y = 'Global')fig1.update_layout(
     title = "PS4 Global Sales",
     title_font_size = 40, 
     width = 1600, height = 1400)fig1.update_xaxes(
     title_text = 'Year',
     title_font=dict(size=30, family='Verdana', color='black'), 
     tickfont=dict(family='Calibri', color='darkred', size=25))fig1.update_yaxes(
     title_text = "Sales (MM)", 
     range = (0,160), 
     title_font=dict(size=30,family='Verdana',color='black'), 
     tickfont=dict(family='Calibri', color='darkred', size=25))fig1.write_image(path + "figarea1.png")
fig1.show()

图 1:标准面积图。作者用 Plotly Express 制作的图表。

上图显示了 2013 年至 2018 年期间 PS4 全球销量的变化。如果没有面积图的视觉效果,同样的故事也可以用折线图来讲述。

但是请记住,我们想知道同一时期世界不同地区的销售额是如何分布的。因此我们需要一个堆积面积图,其中每个面积(每个区域)占总销售额的比例。每个区域的高度代表每个特定区域的值,而最终高度是这些值的总和。

现在我们使用了模块 plotly.graph_objects 和不同的方法学[ fig.add_trace() ]和不同的跟踪[ go。散射()】。 x =是代表时间线的数据帧中的列的名称,而 y =是代表特定区域的数据帧中的列的名称。堆栈组参数用于将同一组中不同轨迹的 y 值相加。我们必须用mode =‘lines’来为绘制线条而不是点。

import plotly.graph_objects as go
fig2 = go.Figure()fig2.add_trace(go.Scatter(
     x= df_area['Year'], y = df_area['North America'],
     name = 'North America',
     mode = 'lines',
     line=dict(width=0.5, color='orange'),
     stackgroup = 'one'))fig2.add_trace(go.Scatter(
     x= df_area['Year'], y = df_area['Europe'],
     name = 'Europe',
     mode = 'lines',
     line=dict(width=0.5,color='lightgreen'),
     stackgroup = 'one'))fig2.add_trace(go.Scatter(
     x= df_area['Year'], y = df_area['Japan'],
     name = 'Japan',
     mode = 'lines', 
     line=dict(width=0.5, color='blue'),
     stackgroup = 'one'))fig2.add_trace(go.Scatter(
     x= df_area['Year'], y = df_area['Rest of World'],
     name = 'Rest of World',
     mode = 'lines', 
     line=dict(width=0.5, color='darkred'),
     stackgroup = 'one'))fig2.update_layout(
     title = "PS4 Global Sales per Region",
     title_font_size = 40, legend_font_size = 20,
     width = 1600, height = 1400)fig2.update_xaxes(
     title_text = 'Year',
     title_font=dict(size=30, family='Verdana', color='black'),
     tickfont=dict(family='Calibri', color='darkred', size=25))fig2.update_yaxes(
     title_text = "Sales (MM)", range = (0,160),
     title_font=dict(size=30, family='Verdana', color='black'),
     tickfont=dict(family='Calibri', color='darkred', size=25))fig2.write_image(path + "figarea2.png")
fig2.show()

图 2:堆积面积图。作者用 Plotly Express 制作的图表。

让我们看看百分之堆积面积图是否有助于讲故事。我们只需要做一个小改动:将 groupnorm = 'percent' 添加到第一个 add_trace()中。

fig3 = go.Figure()fig3.add_trace(go.Scatter(
     x= df_area['Year'], y = df_area['North America'],
     name = 'North America',
     mode = 'lines',
     line=dict(width=0.5, color='orange'),
     stackgroup = 'one', 
     groupnorm = 'percent'))fig3.add_trace(go.Scatter(
     x= df_area['Year'], y = df_area['Europe'],
     name = 'Europe',
     mode = 'lines',
     line=dict(width=0.5,color='lightgreen'),
     stackgroup = 'one'))fig3.add_trace(go.Scatter(
     x= df_area['Year'], y = df_area['Japan'],
     name = 'Japan',
     mode = 'lines', 
     line=dict(width=0.5, color='blue'),
     stackgroup = 'one'))fig3.add_trace(go.Scatter(
     x= df_area['Year'], y = df_area['Rest of World'],
     name = 'Rest of World',
     mode = 'lines', 
     line=dict(width=0.5,  color='darkred'),
     stackgroup = 'one'))fig3.update_layout(
     title = "PS4 Global Sales per Region",
     title_font_size = 40, legend_font_size = 20,
     yaxis=dict(type='linear',ticksuffix='%'),
     width = 1600, height = 1400)fig3.update_xaxes(
     title_text = 'Year',
     title_font=dict(size=30, family='Verdana', color='black'),
     tickfont=dict(family='Calibri', color='darkred', size=25))fig3.update_yaxes(
     title_text = "Sales (%)", range = (0,100),
     title_font=dict(size=30, family='Verdana', color='black'),
     tickfont=dict(family='Calibri', color='darkred', size=25))fig3.write_image(path + "figarea3.png")
fig3.show()

图 3:百分比堆积面积图。作者用 Plotly Express 制作的图表。

图 3 是一个部分对整体的图表,其中每个区域表示每个地区占全球总销售额的百分比。重点是趋势,**每个类别的百分比如何随时间变化,**而不是确切的值。

最后,我们可以使用重叠面积图来比较销售额最高的地区。代替 stackgroup,我们将 fill = 'tozeroy' 添加到第一个 add_trace() 中,将*fill = ' to texty '*添加到第二个 add_trace()中。

fig4 = go.Figure()fig4.add_trace(go.Scatter(
        x= df_area['Year'], y = df_area['North America'],
        name = 'North America',
        mode = 'lines', line=dict(width=0.5,color='lightgreen'),
        fill = 'tozeroy'))fig4.add_trace(go.Scatter(
        x= df_area['Year'], y = df_area['Europe'],
        name = 'Europe',
        mode = 'lines', line=dict(width=0.5, color='darkred'),
        fill = 'tonexty'))fig4.update_layout(
        title = "PS4 Sales North America vs Europe",
        title_font_size=40, legend_font_size = 20,   
        width = 1600, height = 1400)fig4.update_xaxes(
        title_text = 'Year',
        title_font=dict(size=30, family='Verdana', color='black'),       
        tickfont=dict(family='Calibri', color='darkred', size=25))fig4.update_yaxes(
        title_text = "Sales (MM)", range = (0,70),
        title_font=dict(size=30, family='Verdana', color='black'),       
        tickfont=dict(family='Calibri', color='darkred', size=25))fig4.write_image(path + "figarea4.png")
fig4.show()

图 4:重叠面积图。作者用 Plotly Express 制作的图表。

总结一下:

我们使用面积图来传达整体趋势和每个部分对整体的相对贡献,而不关心显示准确的值。

我们使用 plotly.graph_objects 模块通过 add_trace 方法顺序添加轨迹。然后,我们通过 update_layout、update_xaxes 和 update_yaxes 操作图表属性。

如果你对这篇文章感兴趣,请阅读我以前的(https://medium.com/@dar.wtz):

带有 Plotly Express、趋势线和分面的散点图

带有 Plotly Express、主题和模板的直方图

参考

【1】:https://www.kaggle.com/sidtwr/videogames-sales-dataset?select=PS4_GamesSales.csv

曲线下和曲线外的区域,具有综合的区分改善和净重新分类

原文:https://towardsdatascience.com/area-under-the-curve-and-beyond-f87a8ec6937b?source=collection_archive---------10-----------------------

实践教程,机器学习&诊断统计

例如,使用 python 代码,演示了如何生成 AUC、IDI 和 NRI 指标并进行深入研究

作者图片

TLDR

  • AUC 是比较两种型号性能的一个很好的起点,但它并不总能说明全部情况
  • NRI 着眼于新模型正确重新分类癌症和良性疾病的能力,应该与 AUC 一起使用
  • IDI 对区分曲线斜率的改善进行量化,并对其作图,可以提供 AUC 单独无法提供的信息。
  • 发表医学中这些概念的例子。
  • 以下示例的代码和有用的 AUC、NRI、IDI 函数可以在 github 中找到。

https://www.nature.com/articles/s43856-021-00024-0#Fig3

曲线下面积

在机器学习和诊断医学中,受试者操作特征(ROC)曲线下面积(AUC)是用于评估模型或诊断测试的预测性能的常用指标。新模型通常以使用 AUC 的已有模型为基准。比较新旧模型的 AUC 以评估改进是一个很好的起点,但是,许多人在这里结束了他们的分析,并认为简单地报告更高的 AUC 就足够了。AUC 可能具有误导性,因为它对全部范围的敏感性和特异性值给予同等的权重,即使有限的范围或特定的阈值可能具有实际意义。在这篇文章中,我们展示了如何全面询问新的和改进的模型性能,超越简单的 AUC 比较,以便在给定问题的背景下提供对改进的更全面的理解。我们还提供了一个用 Python 编写的代码示例,来演示我们提出的概念。

例如:乳腺癌

乳腺癌是全世界女性癌症死亡的主要原因。早期检测有助于降低死亡率,越早发现恶性肿瘤,患者越有可能存活。因此,已经投入了巨大的努力来开发预测模型以更好地识别癌症。在这个例子中,我们使用提取的成像特征来建立模型,以预测恶性肿瘤的概率。我们使用来自位于 UCI 机器学习仓库的威斯康辛乳腺癌诊断数据库 [ 1 ]的数据。

如前所述,AUC 对所有阈值给予相同的权重,但这在乳腺癌诊断中可能不实用。乳腺影像报告和数据系统或(BI-RADS) [ 2 。为给定的恶性肿瘤概率提供一个行动方案。简而言之,如果恶性肿瘤的概率大于 2%,建议进行活检。活组织检查是侵入性的程序,它们可能对患者的身体和精神有害。理想地,新的和改进的乳房模型将在识别癌症(灵敏度增加)和减少假阳性(特异性增加)方面更好,优选低于 2%以避免侵入性和不必要的活检。

我们用下面的代码片段来设置这个例子。

示例设置

# Import Modules #
import os
import sys
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import seaborn as sns
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn.metrics import roc_auc_score
from sklearn.metrics import roc_auc_score

在导入必要的模块后,我们加载乳腺癌数据集,并将数据分成训练集和测试集。请注意,最好也创建一个验证集,我们通常会这样做,但是为了这个示例,我们将只使用一个训练集和测试集。

# Import data #
data = load_breast_cancer()
# Create DataFrame and Split Data
df = pd.DataFrame(data=data['data'],columns=data['feature_names'])
df['label']=data['target']
x_train, x_test, y_train, y_test = train_test_split(df.iloc[:,:-1], df.iloc[:,-1], test_size=0.40, random_state=123)

同样为了这个例子,我们将假设我们的参考/基准模型建立在与纹理、凹点、平滑度、分形维数和紧密度相关的乳房成像特征上。我们还将假设新模型使用与半径、周长、面积、对称性和凹度相关的附加成像生物标记/特征。总的来说,参考模型使用总共 15 个特征构建,而新模型使用 30 个特征构建(原始模型使用 15 个特征,15 个新特征)。下面的代码片段创建了两组功能。

# create ref and new model feature sets #
ref_feat, new_feat = [],[]
for i in data['feature_names']:
    if 'fractal' in i or 'smoothness' in i or 'texture' in i ...
or 'concave' in i or 'compactness' in i:
        ref_feat+=[i]

建模

我们创建了一个包含 15 个特征的参考或“参考模型”,以及包含所有 30 个特征的“新模型”。

ref_model = RandomForestClassifier()
new_model = RandomForestClassifier()
# fit models to train data
ref_model.fit(x_train[ref_feat], y_train)
new_model.fit(x_train[new_feat], y_train)
# make predictions on test data
test_ref_pred=ref_model.predict_proba(x_test[ref_feat])
test_new_pred=new_model.predict_proba(x_test[new_feat])

比较模型 AUC 的问题

我们之前提到过,比较 AUC 是一个很好的起点。我们这样做是为了了解新模型相对于我们的参考模型的表现如何。我们使用下面的自定义函数来可视化 ROC 曲线和置信区间(CI)。

#[https://www.nature.com/articles/s43856-021-00024-0#Fig3](https://www.nature.com/articles/s43856-021-00024-0#Fig3)
**def** bootstrap_results(y_truth, y_pred,num_bootstraps **=** 1000):
    n_bootstraps = num_bootstraps
    rng_seed = 42  *# control reproducibility*
    y_pred=y_pred
    y_true=y_truth
    rng = np.random.RandomState(rng_seed)
    tprs=[]
    fprs=[]
    aucs=[]
    threshs=[]
    base_thresh = np.linspace(0, 1, 101)
    for i in range(n_bootstraps):
        *# bootstrap by sampling with replacement on the prediction indices*
        indices = rng.randint(0, len(y_pred), len(y_pred))
        if len(np.unique(y_true[indices])) < 2:
            *# We need at least one positive and one negative sample for ROC AUC*
            continue
        fpr, tpr, thresh = metrics.roc_curve(y_true[indices],y_pred[indices])
        thresh=thresh[1:]
        thresh=np.append(thresh,[0.0])
        thresh=thresh[::-1]
        fpr = np.interp(base_thresh, thresh, fpr[::-1])
        tpr = np.interp(base_thresh, thresh, tpr[::-1])
        tprs.append(tpr)
        fprs.append(fpr)
        threshs.append(thresh)
    tprs = np.array(tprs)
    mean_tprs = tprs.mean(axis=0)  
    fprs = np.array(fprs)
    mean_fprs = fprs.mean(axis=0)
    return base_thresh, mean_tprs, mean_fprs**def** get_auc_ci(y_truth, y_pred,num_bootstraps = 1000):
    n_bootstraps = num_bootstraps
    rng_seed = 42  # control reproducibility
    bootstrapped_scores = []
    y_pred=y_pred
    y_true=y_truth
    rng = np.random.RandomState(rng_seed)
    tprs=[]
    aucs=[]
    base_fpr = np.linspace(0, 1, 101)
    for i in range(n_bootstraps):
        # bootstrap by sampling with replacement on the prediction indices
        indices = rng.randint(0, len(y_pred), len(y_pred))
        if len(np.unique(y_true[indices])) < 2:
            # We need at least one positive and one negative sample for ROC AUC
            continue
        score = roc_auc_score(y_true[indices], y_pred[indices])
        bootstrapped_scores.append(score)
        fpr, tpr, _ = metrics.roc_curve(y_true[indices],y_pred[indices])
        roc_auc = metrics.auc(fpr, tpr)
        aucs.append(roc_auc)
        tpr = np.interp(base_fpr, fpr, tpr)
        tpr[0] = 0.0
        tprs.append(tpr)
    tprs = np.array(tprs)
    mean_tprs = tprs.mean(axis=0)
    std = tprs.std(axis=0)
    mean_auc = metrics.auc(base_fpr, mean_tprs)
    std_auc = np.std(aucs)
    tprs_upper = np.minimum(mean_tprs + std*2, 1)
    tprs_lower = mean_tprs - std*2
    return base_fpr, mean_tprs, tprs_lower, tprs_upper, mean_auc, std_auc**def** plot_auc(truth, reference_model, new_model,n_bootstraps=1000, save=False):
    y_truth = truth
    ref_model = reference_model
    new_model = new_model
    ref_fpr, ref_tpr, ref_thresholds = metrics.roc_curve(y_truth, ref_model)
    new_fpr, new_tpr, new_thresholds = metrics.roc_curve(y_truth, new_model)
    ref_auc, new_auc = metrics.auc(ref_fpr, ref_tpr), metrics.auc(new_fpr, new_tpr)
    print('ref auc =',ref_auc, '\newn auc = ', new_auc)
    base_fpr_ref, mean_tprs_ref, tprs_lower_ref, tprs_upper_ref, mean_auc_ref, std_auc_ref=get_auc_ci(y_truth, ref_model,n_bootstraps)
    base_fpr_new, mean_tprs_new, tprs_lower_new, tprs_upper_new, mean_auc_new, std_auc_new=get_auc_ci(y_truth, new_model,n_bootstraps)
    plt.figure(figsize=(8, 8))
    lw = 2
    plt.plot(ref_fpr, ref_tpr, color='blue',
             lw=lw, label='Reference raw ROC (AUC = %0.2f)' % ref_auc, linestyle='--')
    plt.plot(base_fpr_ref, mean_tprs_ref, 'b', alpha = 0.8, label=r'Reference mean ROC (AUC=%0.2f, CI=%0.2f-%0.2f)' % (mean_auc_ref, (mean_auc_ref-2*std_auc_ref),(mean_auc_ref+2*std_auc_ref)),)
    plt.fill_between(base_fpr_ref, tprs_lower_ref, tprs_upper_ref, color = 'b', alpha = 0.2)
    plt.plot(new_fpr, new_tpr, color='darkorange',
             lw=lw, label='New raw ROC (AUC = %0.2f)' % new_auc, linestyle='--')
    plt.plot(base_fpr_new, mean_tprs_new, 'darkorange', alpha = 0.8, label=r'New mean ROC (AUC=%0.2f, CI=%0.2f-%0.2f)' % (mean_auc_new,(mean_auc_new-2*std_auc_new),(mean_auc_new+2*std_auc_new)),)
    plt.fill_between(base_fpr_new, tprs_lower_new, tprs_upper_new, color = 'darkorange', alpha = 0.2)
    plt.plot([0, 1], [0, 1], color='gray', lw=lw, linestyle='--')
    plt.xlim([0.0, 1.0])
    plt.ylim([0.0, 1.0])
    plt.xlabel('1 - Specificity', fontsize=18)
    plt.ylabel('Sensitivity', fontsize=18)
    plt.legend(loc="lower right", fontsize=13)
    plt.gca().set_aspect('equal', adjustable='box')

我们运行以下程序来生成 AUC 图。

plot_auc(y_test.values,test_ref_pred[:,1],test_new_pred[:,1],n_bootstraps=100)

作者图片

图 1:使用自举法计算可信区间的 AUC 曲线

图 1 中的平均曲线和 95%置信区间。是通过 100 轮自举计算出来的,参见上面的代码。参照(蓝色曲线)和新模型(橙色曲线)分别在 0.99 和 0.99 产生相似的 AUC。新模型的置信区间略窄。总的来说,仅从 AUC 曲线很难得出任何有意义的结论,似乎具有额外特征的新模型对改善恶性肿瘤预测几乎没有作用。

超出曲线下的区域

我们的例子在图 1 中。展示了仅使用 AUC 的局限性,并建议分析需要超越相似的 AUC 比较。我们提出了两个额外的指标,通常用于评估新特征或生物标记对模型的影响。这些指标包括净重新分类指数(NRI)和综合歧视改善指数(IDI) [ 3 。这两个指标将有助于理解两个模型的实际差异,这些差异在图 1中可能并不明显。

净重新分类指数(NRI)

NRI 是将 NRI 事件和 NRI 非事件的数量相加得出的。在我们的例子中,事件是癌症或恶性肿瘤患者的同义词,NRI 非事件是良性病变患者的同义词。NRI 事件是指发生事件的患者被重新分配到较高风险类别的净比例,而 NRI 非事件是指未发生事件的患者被重新分配到较低风险类别的人数[ 4 ]。我们使用以下 Python 函数来计算 NRI。

**def** check_cat(prob,thresholds):
    cat=0
    for i,v in enumerate(thresholds):
        if prob>v:
            cat=i
    return cat**def** make_cat_matrix(ref, new, indices, thresholds):
    num_cats=len(thresholds)
    mat=np.zeros((num_cats,num_cats))
    for i in indices:
        row,col=check_cat(ref[i],thresholds),check_cat(new[i],thresholds)
        mat[row,col]+=1
    return mat**def** nri(y_truth,y_ref, y_new,risk_thresholds):
    event_index = np.where(y_truth==1)[0]
    nonevent_index = np.where(y_truth==0)[0]
    event_mat=make_cat_matrix(y_ref,y_new,event_index,risk_thresholds)
    nonevent_mat=make_cat_matrix(y_ref,y_new,nonevent_index,risk_thresholds)
    events_up, events_down = event_mat[0,1:].sum()+event_mat[1,2:].sum()+event_mat[2,3:].sum(),event_mat[1,:1].sum()+event_mat[2,:2].sum()+event_mat[3,:3].sum()
    nonevents_up, nonevents_down = nonevent_mat[0,1:].sum()+nonevent_mat[1,2:].sum()+nonevent_mat[2,3:].sum(),nonevent_mat[1,:1].sum()+nonevent_mat[2,:2].sum()+nonevent_mat[3,:3].sum()
    nri_events = (events_up/len(event_index))-(events_down/len(event_index))
    nri_nonevents = (nonevents_down/len(nonevent_index))-(nonevents_up/len(nonevent_index))
    return nri_events, nri_nonevents, nri_events + nri_nonevents

我们将参考模型和新模型预测输入 NRI 函数,计算事件、非事件和总 NRI。

print(nri(y_test.values,test_ref_pred[:,1],test_new_pred[:,1],[0.02,0.1,0.5,0.95]))

上面代码的输出是:

0.1642857142857143, 0.125, 0.2892857142857143

“与参考模型相比,新模型对 29%的患者进行了重新分类”,这种说法很诱人,但这并不准确,也不是对 NRI 的正确解释。由于 NRI 是事件比例的总和,而不是事件比例的总和,因此 NRI 可能为 2%或 200%。声称新模型对 200%以上的个体进行了重新分类是不可能的,因为这意味着患者数量突然增加了一倍。更正确的解释是,与参考模型相比,新模型正确分类的癌症病例多 16%,良性多 13%,总 NRI 为 29%。

NRI 向我们展示了在新模型中增加更多的特征可以对恶性和非恶性患者进行重新分类。这一信息不能仅从 AUC 得出,可能会错误地使人们认为模型是相同的。在临床环境中,新的模型会发现更多的癌症,这可能会挽救更多的生命。此外,新的模型将正确地识别更多的益处,这将转化为对个体更少的压力,并可能使他们免于像活检这样的侵入性程序。

无类别或 cfNRI 是一个较新的指标,跟踪事件和非事件的总体变化,不考虑类别。以我们的乳腺癌为例,美国放射学院(ACR)有不同的 BI-RADS 类别,因此我们认为没有必要计算 cfNRI。我们提供了计算 cfNRIs 的编码函数,以满足您的问题。

**def** track_movement(ref,new, indices):
    up, down = 0,0
    for i in indices:
        ref_val, new_val = ref[i],new[i]
        if ref_val<new_val:
            up+=1
        elif ref_val>new_val:
            down+=1
    return up, down**def** category_free_nri(y_truth,y_ref, y_new):
    event_index = np.where(y_truth==1)[0]
    nonevent_index = np.where(y_truth==0)[0]
    events_up, events_down = track_movement(y_ref, y_new,event_index)
    nonevents_up, nonevents_down = track_movement(y_ref, y_new,nonevent_index)
    nri_events = (events_up/len(event_index))-(events_down/len(event_index))
    nri_nonevents = (nonevents_down/len(nonevent_index))-(nonevents_up/len(nonevent_index))
    #print(events_up, events_down, len(event_index), nonevents_up, nonevents_down, len(nonevent_index), nri_events, nri_nonevents, nri_events+nri_nonevents)
    return nri_events, nri_nonevents, nri_events + nri_nonevents

综合歧视指数(IDI)

IDI 是区分斜率变化的量度,显示了新生物标记对二元预测模型的影响。IDI 是综合敏感性(is)和综合特异性(IP)的总和,像 NRI 一样,它分离出事件和非事件,或者在这种情况下是癌症和良性疾病。我们使用下面的代码来计算和绘制 IDI 曲线[ 5 ]。

**def** area_between_curves(y1,y2):
    diff = y1 - y2 # calculate difference
    posPart = np.maximum(diff, 0)
    negPart = -np.minimum(diff, 0)
    posArea = np.trapz(posPart)
    negArea = np.trapz(negPart)
    return posArea,negArea,posArea-negArea**def** plot_idi(y_truth, ref_model, new_model, save=False):
    ref_fpr, ref_tpr, ref_thresholds = metrics.roc_curve(y_truth, ref_model)
    new_fpr, new_tpr, new_thresholds = metrics.roc_curve(y_truth, new_model)
    base, mean_tprs, mean_fprs=bootstrap_results( y_truth, new_model,100)
    base2, mean_tprs2, mean_fprs2=bootstrap_results( y_truth, ref_model,100)
    is_pos,is_neg, idi_event=area_between_curves(mean_tprs,mean_tprs2)
    ip_pos,ip_neg, idi_nonevent=area_between_curves(mean_fprs2,mean_fprs)
    print('IS positive', round(is_pos,2),'IS negative',round(is_neg,2),'IDI events',round(idi_event,2))
    print('IP positive', round(ip_pos,2),'IP negative',round(ip_neg,2),'IDI nonevents',round(idi_nonevent,2))
    print('IDI =',round(idi_event+idi_nonevent,2))
    plt.figure(figsize=(10, 10))
    ax=plt.axes()
    lw = 2
    plt.plot(base, mean_tprs, 'black', alpha = 0.5, label='Events New (New)' )
    plt.plot(base, mean_fprs, 'red', alpha = 0.5, label='Nonevents New (New)')
    plt.plot(base2, mean_tprs2, 'black', alpha = 0.7, linestyle='--',label='Events Reference (Ref)' )
    plt.plot(base2, mean_fprs2, 'red', alpha = 0.7,  linestyle='--', label='Nonevents Reference (Ref)')
    plt.fill_between(base, mean_tprs,mean_tprs2, color='black',alpha = 0.1, label='Integrated Sensitivity (area = %0.2f)'%idi_event)
    plt.fill_between(base, mean_fprs,mean_fprs2, color='red', alpha = 0.1, label='Integrated Specificity (area = %0.2f)'%idi_nonevent)#''' #TODO: comment out if not for breast birads
    ### BIRADS Thresholds ###
    plt.axvline(x=0.02,color='darkorange',linestyle='--',alpha=.5,label='BI-RADS 3/4a Border (2%)')
    plt.axvline(x=0.10,color='green',linestyle='--',alpha=.5,label='BI-RADS 4a/4b Border (10%)')
    plt.axvline(x=0.5,color='blue',linestyle='--',alpha=.5,label='BI-RADS 4b/4c Border (50%)')
    plt.axvline(x=0.95,color='purple',linestyle='--',alpha=.5,label='BI-RADS 4c/5 Border (95%)')
    **def** nri_annotation(plt, threshold):
        x_pos = base[threshold]
        x_offset=0.02
        x_offset2=x_offset
        text_y_offset=0.01
        text_y_offset2=text_y_offset
        if threshold==2:
            text_y_offset=0.04
            text_y_offset2=0.04
            x_offset2=0.05
            print(x_pos+x_offset, (np.mean([mean_tprs2[threshold], mean_tprs[threshold]])+text_y_offset),
                    x_pos, (np.mean([mean_tprs2[threshold], mean_tprs[threshold]])))
        text_y_events=np.mean([mean_tprs2[threshold], mean_tprs[threshold]])+text_y_offset
        text_y_nonevents=np.mean([mean_fprs[threshold], mean_fprs2[threshold]])+text_y_offset2
        plt.annotate('', xy=(x_pos+0.02, mean_tprs2[threshold+1]), xycoords='data', xytext=(x_pos+0.02,
                            mean_tprs[threshold]), textcoords='data', arrowprops={'arrowstyle': '|-|'})
        plt.annotate('NRI$_{events}$ = %0.2f'%(mean_tprs[threshold]-mean_tprs2[threshold]),
                     xy=(x_pos+x_offset, text_y_events), xycoords='data',
                     xytext=(x_pos+x_offset, text_y_events),
                     textcoords='offset points', fontsize=15)
        plt.annotate('', xy=(x_pos+0.02, mean_fprs[threshold]), xycoords='data', xytext=(x_pos+0.02,
                             mean_fprs2[threshold]), textcoords='data', arrowprops=dict(arrowstyle= '|-|',color='r'))
        plt.annotate('NRI$_{nonevents}$ = %0.2f'%(mean_fprs2[threshold]-mean_fprs[threshold]),
                     xy=(x_pos+x_offset2, text_y_nonevents), xycoords='data',
                     xytext=(x_pos+x_offset2, text_y_nonevents),
                     textcoords='offset points', fontsize=15)
        print('Threshold =',round(x_pos,2),'NRI events =',round(mean_tprs[threshold]-mean_tprs2[threshold],4),
              'NRI nonevents =',round(mean_fprs2[threshold]-mean_fprs[threshold],4),'Total =',
              round((mean_tprs[threshold]-mean_tprs2[threshold])+(mean_fprs2[threshold]-mean_fprs[threshold]),4))
    nri_annotation(plt,2)
    nri_annotation(plt,10)
    nri_annotation(plt,50)
    nri_annotation(plt,95)
    #'''
    plt.xlim([0.0, 1.10])
    plt.ylim([0.0, 1.10])
    ax.spines['right'].set_visible(False)
    ax.spines['top'].set_visible(False)
    plt.xlabel('Calculated Risk', fontsize=18)
    plt.ylabel('Sensitivity (black), 1 - Specificity (red)', fontsize=18)
    plt.legend(loc="upper right", fontsize=11)
    plt.legend(loc=0, fontsize=11,  bbox_to_anchor=(0,0,1.2,.9))
    plt.gca().set_aspect('equal', adjustable='box')
    #if save:
    #    plt.savefig('idi_curve.png',dpi=300, bbox_inches='tight')
    look=95
    plt.show()

我们运行下面的命令来生成图 2 中的图。

plot_idi(y_test.values,test_ref_pred[:,1],test_new_pred[:,1])

输出:

IS positive 3.58 IS negative 0.16 IDI events 3.42
IP positive 4.61 IP negative 0.04 IDI nonevents 4.57
IDI = 7.98
0.04 1.04 0.02 1.0
Threshold = 0.02 NRI events = 0.0 NRI nonevents = 0.2762 Total = 0.2762
Threshold = 0.1 NRI events = -0.008 NRI nonevents = 0.1002 Total = 0.0922
Threshold = 0.5 NRI events = 0.0215 NRI nonevents = 0.0317 Total = 0.0532
Threshold = 0.95 NRI events = 0.1389 NRI nonevents = -0.0136 Total = 0.1252

作者图片

图 2: IDI 曲线,在每个级别或双半径边界计算 NRI

虚线和实线分别代表参考模型和新模型。在理想情况下,黑色实线将移至右上方,表示灵敏度提高最多,红色实线将移至右下方,表示特异性提高最多。黑色和红色曲线之间的面积等于 IS 和 IP,黑色和红色面积的总和等于 IDI。IDI 提供了更多关于 AUC 曲线的信息,特别是关于橙色垂直虚线或 BI-RADS 3/4a 边界。在此边界处,IP 或红色区域较大,这表明新模型能够更好地预测 benigns。这个界限特别有趣,因为建议所有 BI-RADS 4 或以上的患者接受活检[ 6 ]。3/4a 边界处的大面积显示,向新模型添加新特征增加了特异性,并可能防止 28%以上的人(NRI 无事件=0.28)进行不必要的活检。

最后的想法

AUC 是一个很好的指标,但不能提供全面分析新生物标志物和模型影响所需的所有信息。应使用 NRI 和 IDI 来补充 AUC 调查结果和解释。作为一名使用 Python 的数据科学家和癌症研究人员,很难找到计算和绘制 NRI 和 IDI 的函数和代码片段。这是我张贴这篇文章的动机,我希望我的代码可以帮助其他人的研究,发现和追求更好的医疗保健解决方案。

参考

【Dua,d .和 Graff,C .(2019),加州尔湾:加州大学信息与计算机科学学院,UCI 机器学习资源库【http://archive.ics.uci.edu/ml】。

【2】了解乳腺摄影报告:乳腺摄影结果。(未注明)。检索于 2021 年 5 月 6 日,来自https://www . cancer . org/cancer/breast-cancer/screening-tests-and-early-detection/乳房 x 光片/understanding-your-乳房 x 光片-报告. html

【3】pen Cina,M. J .,D'Agostino Sr,R. B .,D'Agostino Jr,R. B .,& Vasan,R. S .,评估一种新标记物的额外预测能力:从 ROC 曲线下面积到重新分类及重新分类之后,(2008),医学统计学,27(2),157–172。

【4】pen Cina,M. J .,D'Agostino Sr,R. B .,& Steyerberg,E. W .,测量新生物标志物有用性的净重新分类改进计算的扩展,(2011),医学统计学,30(1),11–21。

【Pickering,j . w .】&Endre,Z. H .,评估候选生物标志物诊断潜力的新指标,(2012),美国肾病学会临床杂志,7(8),1355–1364。

【6】Leong,l .、Malkov,s .、Drukker,k .、Niell,b .、Sadowski,p .、Wolfgruber,t .…&Shepherd,j .、双能量三室乳腺成像(3CB),用于改进恶性病变检测的新型成分生物标志物,(2021)。

原载于 2021 年 5 月 1 日 https://www.lambertleong.com**的

Python 中的 Args 和 Kwargs 函数调用变得简单

原文:https://towardsdatascience.com/args-and-kwargs-in-python-function-calling-made-easy-acfe736f988a?source=collection_archive---------37-----------------------

理解如何用多个值完整地调用函数。

莫兰在 Unsplash 上的照片

在我第一次阅读 fastai 的书时,我在函数调用中遇到了关键字 *args 和 **kwargs 。自然地,我非常好奇,想了解我如此热爱的编程语言的另一个方面,所以我开始研究。事实证明,这两者结合起来确实使 Python 3 中一些复杂的函数调用看起来像是小孩子的游戏!

自从我研究了这两个操作符(是的,在我们所说的技术语言中,它们被称为 解包操作符 )之后,我就一直在我的日常项目实验中使用它们,我发现它们非常酷。所以现在,我写这篇文章是为了让你了解这些很酷的概念,以防你错过!

我们走吧!

什么是解包运算符?

单星号和双星号解包操作符是在 Python 2 中引入的。但是在 Python 3.6 发布之后,它们在使用中变得更加强大。

简而言之,解包操作符是在 Python 中 解包来自 iterable 对象的值的操作符。单星运算符*可以用在语言中的任何一种 iterable 上,而双星运算符**只能用在 字典 上的各种运算上。

让我们来看一个例子。我们将定义一些辅助变量,我们将在本教程中使用它们来探索这两个操作符的功能。

nums = [1, 2, 3]
alphs = ['a', 'b', 'c']nums_d = {1: 'one', 2: 'two', 3: 'three'}
alphs_d = {'a': 'First', 'b': 'Second', 'c' : 'Third'}

现在,让我们通过观察他们的行动来进一步了解他们吧!

我们如何使用解包操作符?

首先,让我们在我们的列表 nums 上进行实验。

下面是列表的解压缩版本:

print(*nums) OUTPUT:
1 2 3

我们再做一个!我们将打开下一个字符/字符串列表,我们有 alphs。

print(*alphs)OUTPUT:
a b c

注意到相似之处了吗?你一定知道这个操作员现在对这些列表做了什么,对吗?它把可迭代列表变成了单独的元素,这些元素可以被一些函数单独处理,我们可以把这些值传递给这些函数!

现在让我们来看看这个用例。当我们看到关于使用函数来操作这些由操作符解包的值的例子时,应该就清楚了。

在 Python 函数中使用解包运算符

我们可以使用这个简单的调用来解包一个字符串:

ex = 'Args and Kwargs'print(*ex)OUTPUT:
A r g s   a n d   K w a r g s# each individual character can be processed separately

我们也可以用元素列表来做。让我们定义一个简单的将三个数相加的函数。

def sum_of_nums(n1, n2, n3):
    print(n1 + n2 + n3)

现在让我们继续将我们的数字列表num传递给这个函数,但是附加了解包操作符。

sum_of_nums(*nums) OUTPUT:
6

看到魔法了吗?!这太酷了。我们也可以用之前定义的字典做同样的事情。

让我们首先定义一个函数来进行字符串连接,并将结果打印给用户。 *args 代表自变量。

def concat_str(*args):
    res = ''
    for s in args:
        res += s
    print(res)

现在,让我们用字典 alphs 附带的解包操作符调用它。

concat_str(*alphs)OUTPUT:
abc

这看起来与上面的输出非常相似。

结论是什么?解包操作符允许我们在需要时使用和操作任何 iterable 中的单个元素。这样,我们可以传递一个复杂的列表或字典列表,操作符可以让我们在自定义函数中使用列表的元素和字典的键/值。

这里,看看操作符对字符串列表做了什么。

ex = 'Args and Kwargs'
print([*ex]) OUTPUT:
['A', 'r', 'g', 's', ' ', 'a', 'n', 'd', ' ', 'K', 'w', 'a', 'r', 'g', 's']

它返回一个 iterable (一个新的列表),其中的元素是被解包的单个字符串!

与**kwargs 一起前进一步

**kwargs 代表关键字参数。

Kwargs 是我们在字典中使用的一个解包操作符。让我们定义一个新函数,将两个或更多字典连接在一起。

def concat_str_2(**kwargs):
    result = ''
    for arg in kwargs:
        result += arg
    return result

现在,我们可以用任意数量的字典调用这个函数。

print(concat_str_2(**alphs_d)) OUTPUT:
abc

哎呀!字典中的键在这里被连接起来。但是我们可能想要连接键值,对吗?

我们可以通过对值进行迭代来实现这一点,就像我们对任何普通字典所做的那样。

# concatenating the values of the kwargs dictionary
def concat_str_3(**kwargs):
    result = ''
    for arg in kwargs.values():
        result += arg
    return result print(concat_str_3(**alphs_d))

你能猜到输出会是什么吗?

OUTPUT:
FirstSecondThird

还记得我们之前的两本字典吗?通过使用 **** 操作符,我们可以很容易地将它们组合起来。

alphanum = {**nums_d, **alphs_d}
print(alphanum)OUTPUT:
{1: 'one', 2: 'two', 3: 'three', 'a': 'First', 'b': 'Second', 'c': 'Third'}

最后,我们还可以直接将字典连接在一起。

concat_str_3(a = 'Merge', b = ' this ', c = "dictionary's values")

这里,我们将键值对传递给我们的函数。在你看下面之前,试着想想我们的输出会是什么。

OUTPUT:
"Merge this dictionary's values"

就是这样!现在你知道 Python 中这两个令人敬畏的操作符的一切了!

最后一件事

我们在函数定义中定义函数参数的顺序,记住这一点很重要。我们不能打乱顺序,否则我们的 Python 解释器会抛出一个错误!

这是函数定义中参数排列的正确顺序:

# correct order of arguments in function
def my_cool_function(a, b, *args, **kwargs):
    '''my cool function body'''

*顺序如下:标准变量参数,args 参数,然后是**kwargs 参数。

与本教程相关的完整 jupyter 笔记本可以在本报告中找到!https://github.com/yashprakash13/Python-Cool-Concepts

https://github.com/yashprakash13/Python-Cool-Concepts

如果你想了解更多关于我在 fastai 上写的系列文章,其中我记录了我与这个库的旅程,请访问这篇文章。:)

要不要学会用不到 20 行代码做一个深度学习模型,快速部署成 REST API?在这里获得我的免费指南!

在 Twitter 和 LinkedIn 上与我联系。

用于软标签分类的 ARIMA

原文:https://towardsdatascience.com/arima-for-classification-with-soft-labels-29f3109d9840?source=collection_archive---------23-----------------------

如何让你的模型产生概率

照片由赛义德·阿里在 Unsplash 上拍摄

分类任务的性质意味着已知目标的可用性。在实际应用中,标签是由某种人工活动生成的,或者是作为某种确定性操作的结果而获得的。可能发生的情况是,标记产生不准确的目标,这影响了我们的机器学习模型的训练。为了减轻过度适应或过度自信带来的风险,我们可以检查概率结果。

某种概率分数的存在使我们有可能采用先进的技术来挤压结果(阈值调整、校准)。我们并不总是能够以概率的形式获得结果。一些算法不产生它们,或者没有被设计成以概率的方式处理任务。这可能是一个严重的缺失,尤其是在商业价值方面。

在这篇文章中,我们尝试使用软标签从回归算法开始执行分类任务。一般来说,我们可能会采用回归模型,这是由于问题的性质,或者是因为标记目标的方式没有给出好的结果。这个简单的技巧使我们能够利用回归算法的学习能力保持概率解释。

我们开始介绍一个在分类环境中使用正常回归算法的一般应用。然后,我们在时间序列域中转换相同的过程,其中我们尝试使用 ARIMA 来建模二进制分类问题。

用软标签分类

采用回归方法来模拟二元目标并不是一个好选择。首先,错误分类没有受到足够的惩罚。分类任务中的决策边界很大,而在回归中,两个预测值之间的距离可能很小。第二,从概率的角度来看,用回归建模我们对目标的分布做了一些特定的假设。而实际上,二进制目标来自伯努利分布。

也就是说,我们可以训练一个分类器来最小化均方误差,但是这会产生不一致的结果,并且没有相关的概率结果。我们有的选择既简单又有效。我们使用反 sigmoid 函数将您的目标转换到对数优势比空间。

Logits:来源维基百科

我们有软目标/标签p ∈ (0, 1)(确保将目标夹在[eps, 1 - eps]中,以避免我们记录日志时的不稳定性问题)。然后拟合一个回归模型。最后,为了进行推断,我们从回归模型中提取预测的 sigmoid。

来源维基百科

我们以每个样本的预测概率结束,其中,一如既往地,概率高于 0.5 意味着模型预测类别 1(否则类别 0)。假设一个线性关系,这和建立一个逻辑回归没有太大的不同。附加值在于在各种情况下采用该程序,以及更复杂的关系

我们用岭回归作为基本估计量来模拟之前在二元分类场景中介绍的方法。所获得的结果是足够一致的,以确认该方法是有效的,以模拟分类任务并产生概率结果。

使用岭回归和软标签获得的校准图(图片由作者提供)

用 ARIMA 和软标签分类

使用回归模型和软标签进行分类的最佳特征之一是,该过程是完全模型不可知的。将它应用于 ARIMA 模型怎么样?

现在,我们重复上面所做的,但在时间序列领域。假设我们有一个时间序列的二元目标,我们试图预测他们符合 ARIMA。在我们的例子中,我们处理了一系列每月航班乘客的变化。每个月的变化是通过本月(Mt)与上月(Mt-1)的乘客比例得出的。高于 1 的比率意味着该月的乘客数量比上个月有所增加。我们的二元目标是 1 代表积极变化,0 代表消极变化。

每月航空公司乘客变化(图片由作者提供)

二进制格式的每月航空乘客变化(图片由作者提供)

给定一系列二进制目标,我们将它们转换成软标签并应用 logit 函数。我们用 AIC 准则拟合选择最佳超参数的 ARIMA。应用 sigmoid 变换获得最终预测。在下图中,我们在背景中显示了真实标签(蓝色),以及训练集(橙色)和测试集(绿色)的预测概率。

使用 SARIMAX 为训练集和测试集生成的概率(图片由作者提供)

结果很有意思。我们的方法产生良好的预测,显示出以概率形式产生结果的能力。这同样可以推广到每一个二元时间序列或扩展到多分类作为一个与休息的程序。

摘要

在这篇文章中,我们介绍了一种使用软标签和回归模型执行分类任务的技术。首先,我们将它应用于表格数据,然后用它对 ARIMA 时间序列进行建模。一般来说,它适用于每种环境和每种场景,还提供了概率得分。这对于标注平滑也非常有用,可以减少标注中出现的一些错误。

查看我的 GITHUB 回购

保持联系: Linkedin

Python 中的 ARIMA 模型

原文:https://towardsdatascience.com/arima-model-in-python-7bfc7fb792f9?source=collection_archive---------6-----------------------

时间序列预测完全指南

照片由 K 许在 Unsplash

ARIMA 是最流行的统计模型之一。它代表自回归综合移动平均,适合时间序列数据,用于预测或更好地理解数据。我们不会涵盖 ARIMA 模型背后的整个理论,但我们会告诉你正确应用它需要遵循的步骤。

ARIMA 车型的主要特点如下:

  • AR:自回归。这表明时间序列根据其自身的滞后值回归。
  • **I:综合。**这表示数据值已被替换为其值与先前值之间的差值,以便将序列转换为平稳序列。
  • **MA:移动平均线。**这表明回归误差实际上是误差项的线性组合,其值在过去的不同时间同时出现。

当我们有季节性或非季节性数据时,可以应用 ARIMA 模型。不同之处在于,当我们有季节性数据时,我们需要向模型中添加更多的参数。

对于非季节性数据,参数为:

  • p :模型将使用的滞后观测的数量
  • d :原始观测值被差分直到平稳的次数。
  • q :移动平均线窗口的大小。

对于季节性数据,我们还需要添加以下内容:

  • P:模型将使用的季节性滞后观测的数量
  • D :季节观测值差分到平稳的次数。
  • Q :季节移动平均线窗口的大小。
  • m:1 个季节的观测次数

作者图片

季节性或非季节性数据

这个很好理解。季节性数据是指有时间间隔的数据,如每周、每月或每季度。例如,在本教程中,我们将使用按月聚集的数据,我们的“季节”是一年。因此,我们有季节性数据,对于 ARIMA 模型中的 m 参数,我们将使用 12 ,即每年的月数。

平稳性

ARIMA 模型只能应用于平稳数据。这意味着我们不想有一个时间趋势。如果时间序列有趋势,那么它是非平稳的,我们需要应用差分将其转换为平稳的。下面是一个平稳和非平稳序列的例子。

作者图片

我们还可以使用扩展的 Dickey-Fuller 测试来帮助我们判断序列是否平稳。检验的零假设是有一个单位根,或者没有单位根。换句话说,如果 p 值低于 0.05(或您将使用的任何临界尺寸),我们的系列是固定的

开始编码吧。

对于本教程,我们将使用来自 Kaggle 的航空乘客数据。

import pandas as pd
import numpy as np
from statsmodels.tsa.seasonal import seasonal_decompose

#[https://www.kaggle.com/rakannimer/air-passengers](https://www.kaggle.com/rakannimer/air-passengers)
df=pd.read_csv(‘AirPassengers.csv’)

#We need to set the Month column as index and convert it into datetime
df.set_index(‘Month’,inplace=True)
df.index=pd.to_datetime(df.index)df.head()

作者图片

首先,让我们绘制数据。

df.plot()

作者图片

正如你可以清楚地看到,有一个时间趋势,这表明数据不是静止的。然而,只是为了确保我们将使用一个扩大的迪基-富勒测试。

from statsmodels.tsa.stattools import adfullerresult=adfuller(df['#Passengers'])#to help you, we added the names of every value
dict(zip(['adf', 'pvalue', 'usedlag', 'nobs', 'critical' 'values', 'icbest'],result)){'adf': 0.8153688792060468,
 'pvalue': 0.991880243437641,
 'usedlag': 13,
 'nobs': 130,
 'criticalvalues': {'1%': -3.4816817173418295,
  '5%': -2.8840418343195267,
  '10%': -2.578770059171598},
 'icbest': 996.692930839019}

正如所料,我们未能拒绝零假设,该系列有一个单位根,因此不是平稳的。

使用差分将非平稳转换为平稳(D 和 D 参数)

下一步是将我们的数据转换为静态数据,这样我们就可以估计出将在模型中使用的 D 和 D 参数。这可以通过使用差分来完成,并通过从当前观察值中减去先前观察值来完成。

差异(T) =观察值(T) —观察值(T-1)

然后,我们将使用扩展的 Dickey-Fuller 测试再次测试它的平稳性,如果它是平稳的,我们将进行下一步。如果没有,我们将再次应用差分,直到我们有一个平稳的序列。使用移位功能,熊猫可以很容易地进行区分。

df['1difference']**=**df['#Passengers']**-**df['#Passengers'].shift(1)df['1difference'].plot()

作者图片

似乎我们去除了趋势,序列是平稳的。然而,我们将使用扩展的 Dickey-Fuller 测试来证明这一点。

#note we are dropping na values because the first value of the first difference is NAresult=adfuller(df['1difference'].dropna())
dict(zip(['adf', 'pvalue', 'usedlag', 'nobs', 'critical' 'values', 'icbest'],result)) {'adf': -2.8292668241699857,
 'pvalue': 0.05421329028382734,
 'usedlag': 12,
 'nobs': 130,
 'criticalvalues': {'1%': -3.4816817173418295,
  '5%': -2.8840418343195267,
  '10%': -2.578770059171598},
 'icbest': 988.5069317854084}

如你所见,我们没有拒绝零假设,因为我们的 p 值大于 0.05。这表明序列不是稳定的,我们需要再次使用差分法,取第二个差。第二个差可以作为第一个差来计算,但是这次我们将使用第一个差,而不是使用观察值。

df['2difference']**=**df['1difference']**-**df['1difference'].shift(1)df['2difference'].plot()

作者图片

让我们从第二个差异的扩展 Dickey-Fuller 测试中得到结果。

result**=**adfuller((df['2difference']).dropna())dict(zip(['adf', 'pvalue', 'usedlag', 'nobs', 'critical' 'values', 'icbest'],result)){'adf': -16.384231542468452,
 'pvalue': 2.732891850014516e-29,
 'usedlag': 11,
 'nobs': 130,
 'criticalvalues': {'1%': -3.4816817173418295,
  '5%': -2.8840418343195267,
  '10%': -2.578770059171598},
 'icbest': 988.602041727561}

p 值小于 0.05,因此我们可以拒绝零假设。这意味着第二个差异是固定的,这表明对值 d 的一个好的估计是 2 。

我们的数据是季节性的,所以我们还需要估计 D 值,它与 D 值相同,但存在季节性差异。季节性差异可以通过将数据移动每季的行数(在我们的示例中是每年 12 个月)并从上一季中减去它们来计算。这是而不是第一个季节差异。如果我们得到季节差异是稳定的,那么 D 值将为 0。如果不是,那么我们将计算季节第一差异

季节差异(T) =观测值(T) —观测值(T-12)

季节首差(T) =季节差(T) —季节差(T-1)

df['Seasonal_Difference']**=**df['#Passengers']**-**df['#Passengers'].shift(12)ax**=**df['Seasonal_Difference'].plot()

作者图片

result**=**adfuller((df['Seasonal_Difference']).dropna())dict(zip(['adf', 'pvalue', 'usedlag', 'nobs', 'critical' 'values', 'icbest'],result)){'adf': -3.383020726492481,
 'pvalue': 0.011551493085514952,
 'usedlag': 1,
 'nobs': 130,
 'criticalvalues': {'1%': -3.4816817173418295,
  '5%': -2.8840418343195267,
  '10%': -2.578770059171598},
 'icbest': 919.527129208137}

p 值小于 0.05 ,因此它是固定的,我们不必使用差分。这表明使用 0 作为的 D 值

自相关和偏自相关图(P,Q 和 P,Q 参数)

ARIMA 模型之前的最后一步是创建自相关和偏自相关图,以帮助我们估计 P、Q、P 和 Q 参数。

ARIMA 和季节性 ARIMA 模型有一些非常有用的规则,我们通过查看自相关和偏自相关图来帮助我们估计参数。我们将为我们的时间序列的秒差季节差创建图表,因为这些是我们最终在 ARIMA 使用的平稳序列(d=2,D=0)。

首先,让我们画出 ACF 和 PACF 的第二个区别。

**from** statsmodels.graphics.tsaplots **import** plot_acf, plot_pacffig1**=**plot_acf(df['2difference'].dropna())fig2**=**plot_pacf(df['2difference'].dropna())

作者图片

作者图片

我们可以看到,在我们的两个图中,滞后-1 处都有一个明显的截止点。根据我们上面提到的规则,这建议使用 AR 和 MA 术语。换句话说,p=1,q=1。

现在,我们需要同样的季节差异图。

fig1=plot_acf(df['2difference'].dropna())fig2=plot_pacf(df['2difference'].dropna())

作者图片

作者图片

我们在自相关图中有一个逐渐减小的曲线,在部分自相关图中有一个急剧的截止。这表明对于 ARIMA 的季节部分,使用 AR 并且不超过值 1。

我们选择的值可能不是最佳的。您可以使用这些参数来微调模型,以上面提到的规则作为指导。

ARIMA 模式

**from** statsmodels.tsa.statespace.sarimax **import** SARIMAXmodel**=**SARIMAX(df['#Passengers'],order**=**(1,2,1),seasonal_order**=**(1, 0, 0, 12))result**=**model.fit()

我们可以画出模型的残差,从而了解模型的拟合程度。基本上,残差是原始值和模型预测值之间的差值。

result.resid.plot(kind='kde')

作者图片

是时候做个预测了。我们将创建一些未来的日期添加到我们的数据中,这样我们就可以预测未来的值。

**from** pandas.tseries.offsets **import** DateOffsetnew_dates**=**[df.index[**-**1]**+**DateOffset(months**=**x) **for** x **in** range(1,48)]df_pred**=**pd.DataFrame(index**=**new_dates,columns **=**df.columns)df_pred.head()

作者图片

ARIMA 模型预测将枚举索引的开始和结束作为参数,而不是日期范围。
我们创建了一个包含未来日期索引的空数据框,并将它们连接到原始数据中。我们的数据有 144 行,我们添加的新数据有 48 行。因此,为了只获得对未来数据的预测,我们将从第 143 行预测到第 191 行。

df2**=**pd.concat([df,df_pred])df2['predictions']**=**result.predict(start**=**143,end**=**191)df2[['#Passengers','predictions']].plot()

作者图片

总结一下

Arima 是一个很好的预测模型,可用于季节性和非季节性时间序列数据。
对于非季节性 ARIMA,你必须估计 P、D、Q 参数,而对于季节性 ARIMA,它有 3 个以上适用于 P、D、Q 参数的季节性差异。

我们用来运行 ARIMA 模型的管道如下:

  • 看看你的时间序列,了解它们是季节性的还是非季节性的。
  • 如果需要达到平稳性,将差分应用于时间序列和季节差异,以获得 D 和 D 值的估计值。
  • 绘制自相关和偏自相关图有助于估计 P、P 和 Q、Q 值。
  • 微调模型,如果需要改变参数根据 ARIMA 的一般规则

有用链接:
ARIMA 规则
R 中的 Arima
如何回测你在 R 中的加密交易策略
维基百科中的 ARIMA

最初发表于https://predictivehacks.com。

研究生论文的艺术

原文:https://towardsdatascience.com/art-of-the-graduate-school-essay-f59b14c79649?source=collection_archive---------24-----------------------

让我进入 12 个数据科学硕士项目的 5 个简单技巧

拍摄于中国北京,大约 2018 年(又名 covid 之前);我是前面的金发女郎!

研究生院 sop:他们会觉得自己像一头野兽。

当我申请数据科学项目的硕士学位时,我并不是一个完美的学生;事实上,我离它很远。我从未接触过 Python,从未运行过机器学习算法,也没有在谷歌或脸书有过什么性感的实习经历。我一直把自己定位为具有国际视野的作家、文科类型的人,我本科的大部分时间都在学习法语和中文,在国外实习和学习,甚至追求跆拳道生涯(完全透明地说,我辅修数学,但那是因为我最喜欢惩罚)。

说句不好听的话:我读硕士之前确实不是来自计算机科学或统计学专业,所以进入我申请的所有 12 个项目对这个系统来说是一个完全的冲击。这包括 UChicago、USC、UMich、UVA、Georgetown、Duke 和 Tufts——他们中的许多人还为我提供了高额奖学金!

现在尘埃落定,我真的相信是我的写作技巧拯救了这一天,给我一个平台来构建我的人生故事,并提供为什么我应该得到一个机会的理由。通过谨慎的措辞,我能够克服不足,扩大优势,并提供一个令人信服的叙述,显示出向上的动力和学习的意愿。在我身上赌一把会有回报。自从上了研究生院,我就是我们班的学生会主席,目前我的平均绩点是 3.95,离毕业还有一个学期。

这篇文章既适合那些想要一些可靠的写作技巧的人,也适合那些想要获得数据科学学位但又担心没有相关背景的人。我在这里告诉你,1)我相信你,2)我是你能做到的活生生的证明,3)有了足够好的叙述,你的顶级数据科学项目的小组可能会认为你也能做到!

小贴士 1 |“你和其他女孩不一样”

维多利亚博物馆在 Unsplash 上拍摄的照片

就像一个二战时期的水手在家里给他的 11 个女朋友写信一样——不要混淆名字,回忆她们每个人的特别之处,并向她们传达这样一种感觉:她们是你唯一关注的人。如果哈佛明天来敲你的门,那也没关系——罗格斯大学或者巴斯特大学,该死的。

当然,谁是她的读者会因你的读者而异。在你的文章中,列出你所写的学校为什么对你来说是独特的的原因是很重要的。

对这个问题做研究——对我来说,我至少花了一个小时学习核心课程,教授专业领域,然后平静地在我的论文中阐述我自己的兴趣如何与这些专业相结合。下面我将链接我自己的一篇文章,在第二页的后半部分是“你对我的特别之处”:

https://drive.google.com/file/d/1vpx1x1hNmyw8f1-bVxpII9b3ObwSXwjG/view

此外,如果他们在申请的另一部分问你还申请了哪些学校,只列出那些有类似硕士项目的学校*,他们目前在排名中击败了那些学校。*因此,如果斯坦福大学在数据科学方面的排名高于布朗大学和哥伦比亚大学,你可以像你考虑的其他学校一样,将这两所学校放在你的斯坦福大学申请中,但不要将斯坦福大学放在你的布朗大学或哥伦比亚大学申请中。接受一个最终没有上学的学生会让学校看起来更糟,所以如果他们认为一个非常合格的学生会去别的地方,他们就不会接受他。

要点:不要发出千篇一律的短文;让你申请的每所学校相信它们最符合你的目标和兴趣(暗示如果他们接受你,你一定会去!).

技巧 2 |按时间顺序排列

按时间顺序排列的故事引人注目,因为这是一种传达结构和动力的简单方式。或者更具体地说,“这就是所发生的事情,这就是我现在正在做的事情,这就是为什么你的学校是我计划中明确的下一步”。你不需要严格按时间顺序排列(你会在我的 SOP 中看到,我只是在故事的某些点上按时间顺序排列),但当你试图传达任何一种轨迹时,最好保持事情有序。

例如,我用这个工具描述了我最初对数据科学的兴趣是如何达到顶峰的,我是如何投入这种热情的,以及为什么研究生院是我明确的下一步。通过一系列简单的事件,我能够以积极的势头弥补我在背景方面的不足。

**大意:**千百年来,人们一直在讲故事;挖掘古代艺术,以保持读者的兴趣,并防止你的观点变得过于颠倒。

技巧 3 |杀死你的爱人

写作既是创造也是破坏,研究生论文里的每一句话对你的整个故事一定是不可或缺的。这很难,因为我们倾向于写一份有很多绒毛和不连贯的草稿,然后有点依赖那些绒毛中没有发挥作用的部分。斯蒂芬·金称这种琐碎为“宠儿”,我相信学习如何成为一名“好”作家的一半是能够放下自己的小宠儿。

"杀了你的宝贝,杀了你的宝贝,即使这会伤了你这个自私的小流氓的心,也要杀了你的宝贝。"—斯蒂芬·金

**要点:**当你意识到它们已经开始偏离要点时,不要小心翼翼地删掉一些单词或者整段文字。

这就是为什么拥有校对者是如此的重要;他们不像你那样执着于文字,可以帮助清除杂草,让你的信息保持在正确的轨道上。如果你没有可以校对的人,在两次草稿之间休息几天,你会发现自己每次都会带着更新鲜、更客观的视角回到你的故事中。

技巧 4 |制造一个入口

我说你不一定要按时间顺序,就是这个意思。第一段,确切地说,应该是*激动人心。*没时间慢慢积累了——让读者直接进入故事情节,让他们注意你要说的内容。

这是我在研究生论文中最常用的介绍段落。这并不完美,但我很快就安排好了形势、任务和行动,留下接下来的几段来解释结果。

我选择从事数据科学的转折点出现在去年 4 月,当时我的团队参加了芝加哥大学计量经济学比赛。就像年轻计量经济学家的黑客马拉松一样,这场比赛将从剑桥到圣克拉拉的经济学学生聚集在一起。目标是在 14 小时内提出并回答一个重要的经济问题。在数量经济学研究研讨会的 Jane Doe 博士指导下学习了一些研究技术后,我对第一次有机会测试我的应用计量经济学知识感到紧张和兴奋。

作为一名经济学专业的学生,我能够从我完成的计量经济学竞赛中开始解释我对数据分析领域的最初兴趣。

要点:我鼓励你想出一些与数据科学密切相关的事件,并以此尽快抓住读者的注意力。类似于行为面试,如果你发现自己陷入困境,你可以使用明星方法来组织你的故事。

技巧 5 |诚实。

"如果你对任何事情感到尴尬,那是你做得不对的迹象."—匿名

在当今世界,很容易摆脱各种通货膨胀——分数通货膨胀(学校),货币通货膨胀(政府),简历通货膨胀(几乎每个人)。每个人都想比别人看起来更好,结果每个人都以过度夸张而被遗忘而告终。

GIPHY 的 GIF

诚实很重要。确实如此。评审小组知道完美的候选人并不存在,所以如果你试图让他们相信你就是 T1,他们就会怀疑。提到你在 5 岁时没有完全掌握 Python,而是参加了两门在线课程,这可能不太令人印象深刻,但如果你说你是 Python 专家,没有任何实质性的课程或实习,这可能会引起对你诚实的怀疑(突然之间,你申请中的一切都变得更容易引起争论)。

当然,重要的是强调你的优势,并对你所知道的充满信心。为了判断什么时候我可能做得太过了,我喜欢回想几年前我听到的一句话:“如果你对任何事情感到尴尬,那是你做得不对的迹象。”

(附注:我在网上找不到这段引文——如果有人指出了原始出处,我很乐意给予作者应有的信任!)

要点:对你所知道的要有信心,对你所不知道的要诚实。

离别的思绪

作为一名前文科毕业生,目前正在休寒假的数据科学研究生,只要一有机会,我就喜欢舒展我的写作双腿。我希望我使用的一些技巧对你完成自己的申请有所帮助。

就我个人而言,读研是我做过的最好的决定,我绝对热爱我每天所学的东西,并且我很高兴今后能在数据科学领域工作。也就是说,这条道路并不适合所有人,有许多方法可以开始自己的数据科学之旅-如果训练营或自学对你更好,那么尽一切努力去做吧!😊

如果您对我有任何问题,请随时通过我的个人网站、 LinkedIn 或 Twitter 联系我,当然您也可以在 Medium 上关注我。再次感谢阅读!

摄于韩国首尔的一个雨天。总有一天,我会再次旅行——但我不会以外交官的身份工作,也不会以运动员的身份参赛,我会以数据科学家的身份利用自己的时间旅行,享受一些美好的时光:)

技巧还是智慧?

原文:https://towardsdatascience.com/artifice-or-intelligence-993f6f400313?source=collection_archive---------17-----------------------

在看到任何数据之前,报告您的建模策略或统计分析计划

照片由Karen lark Boshoff在https://www . pexels . com/photo/black-red-and-white-round-decor-6758919/

如果你的模型在新数据上表现不佳,未跟踪的倾听可能是原因。

想象一下,在你成功之后,在台球上打你的球!这是一个坏的研究习惯。预注册是指你甚至在走到桌子前就开始打电话。你会赢一些,也会输一些,但你会公平地比赛——这就是你如何提高你的比赛。

技巧

在纽约州北部,我的大学室友在我们的宿舍房间里搭建了一个飞镖靶。一个好朋友——让我们称他们为“纽约的詹姆斯”——会经常过来。詹姆斯喜欢炫耀自己是未来的飞镖高手。

詹姆斯会在地板上的胶带前摆好姿势。他们会仔细评估镖靶,手中的飞镖,以及两者之间的轨迹。最后,随着戏剧性的结束,詹姆斯会开始,“看,当我灵巧地击中…

然后,詹姆斯会夸张地把飞镖抛向空中,甚至发出低沉的运动咕噜声。当看到它果断地落在从靶心延伸到标有“16”的外弧的三角形带内时,詹姆斯会胜利地总结道,“……六!”(这是飞镖游戏“板球”中“16”的俚语。)

如果你就在那时走进来,你可能会惊叹于詹姆斯投掷飞镖的高超技艺和准确性。我的意思是,他们称之为公平公正的拍摄,对不对?"看,我灵巧地击中了第六个!"

当你谈论一个新的见解时,好像你一直都在期待它,你移动了科学证实的目标来适应你的发现。

听着:德克萨斯神枪手

在科学、研究和统计领域,詹姆斯被称为德州神枪手。这位骗子以“结果已知后的假设”而闻名——同时声称假设是在结果已知前创造的(听)。这通常表现为“研究人员自由度”,通常用于 p-hacking 和数据钓鱼或窥探。

这很糟糕,因为这让你看起来像是在寻找支持你最初假设的证据,而事实上你在寻找一个新假设的可能证据——一个需要来自单独的额外研究新证据来进一步支持的假设:“我找到了六个。也许我擅长打六?让我再试一次。”

每次你听的时候,你都冒着宣称不可信的风险:你在实际上只有噪音的地方复制了一个真实的信号。

这种常见的混淆使得一项科学发现看起来比实际上更真实、更可复制。例如,每当你在之后写下你的建模策略、统计分析计划(SAP)或方法部分时,你可能会无意中这样做。

也就是说,即使在最好的情况下,也很容易忘记或没有注意到你是如何简单地通过检查你的初步发现,或通过查看工作图或数据可视化来改变你的初始假设或模型的。这种“假设蠕变”意味着你在缓慢但肯定地调整你的想法以适应你的研究数据,而不是用你的研究数据来测试或证实你的原始想法。

这些根据经验更新的假设就是你最终在 SAP 或方法部分呈现的初始假设!你试图“让数据自己说话”——但在你给了他们那一英寸后,他们又后退了一码。

样品内部性能

您错误地将您对模型性能的理解“颠倒”了,从样本内(真)到样本外(假)。

在机器学习中,HARKing 的一个版本可以产生一种微妙类型的统计过拟合(即在没有结构的变化中找到结构,或者在只有噪声的地方找到信号)。如果你的模型在新数据上表现不佳,未跟踪的倾听可能是原因。

  • ***“看着,我灵巧地打……”***假设你适合,交叉验证,用你的训练数据选择一个模型。然后,在维持数据上测试模型,并计算其维持性能。
  • 您觉得可以改进这种维持性能,并决定调整您最初的建模和交叉验证参数。然后,使用您的培训数据重新拟合、交叉验证并选择一个新模型。
  • 您在相同的维持数据上测试您的模型,注意到您的新模型的维持性能得到了改进,现在感到满意了。你报告这是它的样本外表现。“……第六!”

不幸的是,您只是优化了您的模型以适应您的定型数据和维持数据,从而恶化了它的真实维持性能(即,它归纳为新数据的能力)。你忘记了你做了这些,并且在总结你的结果时,你没有报告你“在已知维持拟合(结果)后调整了你的模型(假设)”。

通过倾听,您隐式地对样本内数据进行了重新分类,以包括您的训练数据维持数据。但随后你混淆了结果模型拟合反映出样本外的表现。也就是说,您错误地将您对模型性能的解释“颠倒”了,从样本内(真)到样本外(假)。

附录(2021 年 12 月 4 日星期六):事实上,Hastie 等人(2009 年)在他们的开创性文本统计学习的要素(第 7.2 节)中明确警告了这一点:

如果我们处于数据丰富的情况下,解决这两个问题的最佳方法是
将数据集随机分成三部分:训练集、验证集
和测试集。训练集用于拟合模型;验证
集用于估算模型选择的预测误差;测试集
用于评估最终选择模型的泛化误差。
理想情况下,测试集应该保存在一个“保险库”中,只有在数据分析结束时才拿出来
假设我们重复使用测试集
,选择测试集误差最小的模型。那么最终选择的模型的测试
设定误差会低估真实的测试误差,
有时会大大降低。

智力

Rodolfo Clix 在https://www.pexels.com/photo/five-bulb-lights-1036936/拍摄的照片

重复的想法,确认的发现,样本内的非样本表现。

詹姆斯显然是在夸大其词,实际上并没有声称自己在飞镖方面有不可思议的技能。但是,许多(如果不是大多数的话)研究人员通过倾听以这种方式玩科学板球,通常是无意识的。它非常普遍、自然且容易做到:在获得应用统计学硕士学位和生物统计学博士学位多年后,并且拥有 18 年以上的专业数据分析师经验后,我仍然发现自己在听!

重复的想法,确认的发现,样本内的非样本表现。每次你听的时候,你都冒着宣称不可信的风险:你复制了一个实际上只有噪音的真实信号。

这种说法令人不安地普遍存在,产生了真实而深远的后果;倾听是科学可修复但顽固的缺陷之一。因此,它是“生物医学和心理学复制危机的一个关键因素”,正如我在其他地方写的关于显著性谬误(呼应了研究界的一种普遍情绪)。

方法:预注册

所以在某个时候,你意识到你一直在用你的研究玩“詹姆斯在纽约板球”。你想改掉这个坏习惯。怎么会?

在 SAP 或方法部分:

  1. **预案。在收集和处理任何研究数据进行分析之前(即“先验”或“事前”),始终陈述您计划的分析和模型,即使这些分析和模型取决于出现的分析结果;预先存在)。
  2. **报告。**报告、发布或以其他方式标记该版本,以便于验证这些假设和模型确实是先验的。随着研究的进展,如果需要的话,报告带有时间戳的文本修改。

这个操作程序被称为预注册,正式或非正式都可以。对于美国的临床试验,你可以通过clinicaltrials.gov来完成,这有助于减少发表和结果报告偏差。

预先注册有助于你的观众(和你!)了解如何正确解释你的分析结果。

结果:发现还是证实?

一般来说,每个分析主要为两个互补的研究目标之一提供证据。两者都是正确的科学研究设计的基础。

  • **发现真知灼见:**使用你的研究数据构建新的假设或模型,这些假设或模型是在你评估结果时出现的(即事后分析,或“让数据说话”),如假设生成或探索性研究,或探索性数据分析(EDA) 。
  • **确认见解:**使用你的研究数据试图重现你的先验假设和模型,就像大多数临床随机对照试验和 A/B 测试中的假设检验或验证性研究。

当你谈论一个新的见解时,好像你一直都在期待它,你移动了科学证实的目标来适应你的发现。这给了你错误的信心,认为这些见解比实际情况更真实。

想象一下,在成功后,你在台球上打了分!这是一个坏的研究习惯。预注册是指在走上牌桌之前,你甚至要对每一个镜头都打电话*。你会赢一些,也会输一些,但你会公平地比赛——这就是你如何提高你的比赛。*

也就是说,预先注册有助于你的观众(和你!)了解如何正确解释你的分析结果。那么你应该如何报告你的结果呢?

  • **标签。**清楚地将每个分析结果标记为事后(探索性)或先验(证实性)发现。
  • 发表。至少,发布或提供一份预先注册的 SAP 或方法资料,让你的观众可以用来给自己的结果贴上标签。

这样做将使其他研究人员能够为规划他们自己的研究得出正确的结论。这种更强大的科学过程帮助你和其他人以你的发现为基础进行优化——为每个人优化科学。

参考

  • 统计学习的要素:数据挖掘、推理和预测。纽约:统计学中的斯普林格系列。2009.

关于作者

Eric J. Daza 是数字健康领域的数据科学统计学家。他获得了应用统计学硕士学位和生物统计学博士学位,在临床试验、公共卫生和行为改变研究方面拥有 18 年以上的工作经验。Daza 博士为用于个性化健康建议的个人内(即,n-of-1,单病例,独特的)数字健康研究开发因果推断方法。| ericjdaza.com🇺🇸🇵🇭@埃里克森 linkedin.com/in/ericjdaza|statsof1.org@ stats of@ fsbiostats

人工意识是不可能的

原文:https://towardsdatascience.com/artificial-consciousness-is-impossible-c1b2ab0bdc46?source=collection_archive---------3-----------------------

思想和理论

有意识的机器是科幻小说的主要内容,通常被认为是未来事实的必然产物,但这是不可能的。

许摄于 Unsplash

这篇文章试图解释为什么有意识的机器是不可能的。硬件和软件设计的行为本身是一种动力的传递,是设计者的延伸,而不是意识意志的灌输。文章的后半部分致力于解决反驳的论点。最后,列出了本论文的一些启示。

智力对意识

智能是一个实体执行任务的能力,而意识是指一种主观现象的存在。

智力[1]:

“……运用知识来控制环境的能力”

意识[2]:

“当我处于有意识的精神状态时,从主观或第一人称的角度来看,我就像是处于那种状态。”

意识要求

一个有意识的实体,即头脑,必须具备:

1.意向性[3]:

“意向性是心灵关于、代表或代表事物、属性和事态的力量。”

请注意,这不仅仅是一个象征性的表示。

2.感受性[4]:

“……我们精神生活中可内省的、非凡的方面。在这个术语的广义上,很难否认有感受性。”

含义和符号

意义是事物(具体的或抽象的)和意识体验之间的心理联系。心灵哲学家描述了使这些意向性联系成为可能的心灵力量。符号只对那些在他们的意识体验和符号之间建立了联系的实体有意义。

一面写有汉字的墙。照片由蒂莫西·吉登纳在 Unsplash 上拍摄

中国房间,重新设计

《中国房间》是约翰·塞尔于 1980 年出版的一部哲学论证和思想实验[5]:

塞尔想象自己独自一人在一个房间里,按照一个电脑程序对塞在门下的汉字做出反应。塞尔对中文一窍不通,但他却像电脑一样按照程序操作符号和数字,把适当的汉字串从门缝里送了出来,这让外面的人误以为房间里有一个说中文的人。

就目前情况而言,中国房间的论点需要重新构建。房间里的人从来没有把他或她的意识经验和汉字联系起来,因此这个人和这个房间都不懂中文。核心问题应该是缺乏连接的意识体验,而不是是否有一个适当的程序可以将任何东西变成思维(这就好比说,如果一个程序 X 足够好,它就会理解语句 s。一个程序永远不会“足够好”,因为它是一个程序,我将在后面的部分解释)。这种最初的模糊框架使争论脱轨,并使其更容易受到攻击。(出轨导致的此类攻击之一是斯洛曼的【6】)

中文房间的论点指出,符号处理的合法问题对于任何意义来说都是不充分的(语法对于语义来说是不够的),但是对于框架来说,这给反对留下了太多的回旋余地。我们不再关注一个程序是否可以被转化成一个大脑,而是深入研究程序本身的基本性质。

一系列形状。照片由在 Unsplash 上的魔术图案拍摄

符号操纵器,一个思维实验

程序的基本性质是它们没有构成意义的有意识的联想。编程代码之所以对人类有意义,仅仅是因为代码是以符号的形式存在的,这些符号包含了与读者的意识体验相关的内容。塞尔的中文房间论证的目的是将论证的读者置于与编程代码中的符号没有经验联系的人的位置。因此,中文教室是一个语言教室。房间内的人不理解编程代码背后的含义,而对外界来说,房间似乎理解特定的人类语言。

中国房间的争论伴随着另一个潜在的破坏性问题。中文房间里的人是作为一个可视化设备引入的,让读者从机器的角度“看”。然而,由于机器因为没有意识而不能有“观点”,房间里有一个人就产生了一个问题,可能会出现“房间里有一个有意识的人在做有意识的事情”的异议。

我将解决 POV 问题,并通过使用以下思维实验来阐明语法和语义的区别:

你记住了一大堆形状。然后,你记住这些形状的排列顺序,这样,如果你看到一堆形状是按一定的顺序排列的,你就会以另一个规定的顺序选择一堆形状来“回答”。现在,你有没有学到任何语言背后的意义?

所有程序都以这种方式操作符号。程序代码本身没有任何意义。对机器来说,它们是要和它们的有效载荷一起执行的序列,仅此而已,就像中文教室里的汉字是要根据给不识字的人的排序指令来处理的有效载荷一样。

它不仅概括了编程代码,符号操纵器思想实验及其序列和有效载荷也是一种算法的概括:“在计算或其他解决问题的操作中,尤其是由计算机遵循的一个过程或一组规则。【7】

形状和序列之间的关系是任意定义的,而不是因果确定的。操作规则是简单编程的东西,不一定与任何种类的世界因果关系相匹配,因为任何这样的链接将是程序的偶然特征,而不是本质特征(即,偶然而非必然)。)程序可以处理任何输入,而机器会跟着处理,这不是因为它“理解”了输入或输出的任何世界含义*,而仅仅是因为它遵循了程序的指示。*

一个非常粗略的伪代码示例来说明这种任意关系:

让 p=“夜”

输入 R

如果 R = day,则打印 p+"是"+R

现在,如果我输入“白天”,那么输出将是“夜晚就是白天”。太好了。绝对“正确输出”根据其编程。它不一定“有意义”,但也没有必要,因为这是编程!同样的道理也适用于任何输入到机器中产生输出的其他输入,例如,“nLc 是 auS”,“e8jey 是 3uD4”,等等。

对机器来说,代码和输入只不过是要执行的项目和序列。对机器来说,这种排序或执行活动没有任何意义。对程序员来说,有意义是因为他或她将变量概念化并理解为他们有意识体验的代表性占位符。机器不理解诸如“变量”、“占位符”、“项目”、“序列”、“执行”等概念。它只是不理解,句号。因此,机器永远不会真正“知道”它在做什么,只能表现出理解的操作外观。

理解房间——机器模仿理解

房间隐喻延伸到所有人工智能活动。机器似乎只处理意义,当它们最终将一切翻译成机器语言指令时,在执行之前和之后都没有意义,并且只关心执行本身(上面的形状记忆思维实验说明了所有机器程序执行的机制)。一个程序只包含对程序员的意义)。中文屋和符号操纵者思维实验表明,虽然我们的大脑能够理解和处理概念,但机器却不能,只能处理序列和有效载荷。因此,头脑不是机器,机器和机器模拟都不可能是头脑。 看似理解语言和意义的机器,本质上是“理解室”,只是在外表上表现出理解。

机器学习并不像许多人认为的那样。照片由布雷特·乔丹在 Unsplash 拍摄

学习室——机器实际上从不学习,部分原因是大脑不仅仅是一个物理信息处理器

机器完全缺乏任何可能的真正理解和认识的直接结果是,机器只能是看似学习但实际上从不学习的学习室。考虑到这一点,“机器学习”是一个被广泛误解和可能经常被滥用的术语。

人工智能教科书欣然承认“机器学习”中的“学习”并不是指通常意义上的学习[8]:

“例如,一个允许用户更新数据条目的数据库系统将符合我们对学习系统的定义:它根据从数据库更新中获得的经验来提高其回答数据库查询的性能。与其担心这种类型的活动是否属于“学习”一词通常的非正式会话含义,我们将简单地采用我们对通过经验改进的程序类的技术定义。

请注意,术语“经验”也不是在这个词的通常意义上使用的,因为经验不仅仅是数据收集。知识论证展示了大脑不仅仅是处理关于物理世界的信息。

机器只拥有物理信息,而且在没有理解能力的情况下这样做,它们通过无视活动的经验背景的方式参与学习活动。一个很好的例子是一台计算机如何用蛮力人工适应一个视频游戏,而不是学习任何东西【10】。

在“学习识别图片”的情况下,机器会看到几十万到几百万张图片,并通过多次失败看到成束的“非大猩猩”像素中的“大猩猩”,最终正确地将屏幕上的像素束与术语“大猩猩”匹配起来……除了它甚至不是一直都做得那么好 [11]。

不用说,通过智能“提高识别大猩猩像素的性能”与通过意识体验“了解大猩猩是什么”几乎不是一回事。减轻这种大锤策略包括人工刺激机器只尝试每件事的一个更小的子集而不是绝对的每件事【12】。

“学习机”是“学习室”,只是在学习的外表上。机器模仿学习的某些理论机制以及模拟学习的结果,但从不复制学习的经验活动。实际的学习需要将参照对象与有意识的经验联系起来。这就是为什么机器会将构成大猩猩图像的像素组与构成深色皮肤人类图像的像素组相混淆。机器不会学习——它们进行模式匹配,而且只有模式匹配。没有实际的个人经验把人的脸和大猩猩的脸联系起来。上一次一个人诚实地把动物的脸错当成人的脸是什么时候?当然,我们可能会看到相似之处,并认为这些动物的脸是人类的,但我们只承认它们是相似的,而不是真正的匹配。机器被“抽象伪装”愚弄,对抗性生成的图像出于同样的原因【13】。这些错误仅仅是缺乏真正学习的症状;即使机器给出完美的结果,它们也不会学习。从根本上来说,“机器学习”与实际学习的距离就像之前人工智能教科书中提到的简单的电子表格数据库更新一样遥远。

意志房间——机器只能表现为拥有内在动力

机器被编程的事实注定了它们是附属物,是程序员意志的延伸。一台机器的设计和它的编程约束和定义了它。没有“没有设计的设计”或“没有编程的编程”一台机器的操作已经被它的程序员和设计者从外部决定了,即使存在诸如“一个程序/机器进化了”(进化算法是谁设计的?)“没有人知道黑盒中的结果程序是如何产生的,”(谁编写了产生结果代码的程序?)“神经网络没有程序,”(神经网络的算法是谁写的?)“机器学习并适应了,”(它不会“学习……”谁决定它会如何适应?)和“有自我修改代码”(是什么决定了这种所谓的“自我修改”的行为,因为它不是“自我”)最终产生行为的是程序员的编程,这是无法逃避的。

让我们再来看看塞尔的中国室。中国房间里的人遵循的程序是谁或什么写的?肯定不是那个人,因为他不懂中文,当然也不是中文室本身。正如前面关于学习的文章所指出的,这个中文教室并不仅仅是通过在教室里放置说明来“学习中文”,就像一个电子表格“学习”写在上面的项目一样。这个人和中国房间都没有“说中文”他们只不过是按照中文教室里说中文的程序员的指示做的。

很容易看出,当程序员对他们的驾驶进行编程时,“自动驾驶汽车”这样的术语是多么不恰当。这意味着当涉及到编程时,人类设计师最终要为机器的失败负责;其他任何事情都是企图推卸责任。“自动驾驶汽车”很难做到自动驾驶。他们学不会开车或自己开车,就像一个中国人学中文或说中文一样。设计师和程序员是机器明显意志的来源。

它很可爱,令人想抱抱,它的眉毛可以形成看起来像皱眉的样子。梁杰森在 Unsplash 上的照片

意识房间——结论,机器只能看起来有意识

看起来有意识的人工智能是一个意识室,是一种成功程度不同的模仿。正如我所展示的,他们既不能理解也不能学习。不仅如此,他们没有能力拥有意志。人工意识是不可能的,因为编程的外在本质是与语法绑定的,没有任何意义。

对反驳的回应

下面的部分是对反对我的论文的特定类别的反驳的回应。请注意,这些回答并不独立,只能被视为支持我上面的主要论点。每个回应只适用于持有相应异议的人。

“你不能提供意向性和感受性的证据,因为它们是主观的”

如果你的意识不具备意向性,“意识关于、代表或代表事物、属性和事态的能力”,那么你将无法理解你面前这个屏幕上的任何单词,因为这些单词根本不涉及任何东西。如果感受性不存在,那么就没有主观感觉存在。没有寒冷的寒冷,没有怀疑的情绪,也没有任何事物的白色、金色、蓝色或黑色。现象的本质和现象存在的本质是有区别的,意向性和感受性的存在是不言而喻的。

“任何反对机器能够做人类能做的事情的可能性的论点都是特别的恳求!”

性能与智力有关,与意识无关——参见定义。为什么有人会假设意识是“完成”的东西?什么支持这一假设?意识作为行动的假设无论如何都不是公理,理论上 AGI 可以在没有意识的情况下完成任何和所有的任务。

从结论来看,超越语法的操作需要从有意识的经验中获得意义。当有意识的经验在论点的最开始被提到作为意义的定义成分时,这可能会使论点显得循环往复(假设它试图证明什么)。

然而,定义意义的最初命题(“意义是与意识经验的心理联系”)并没有因为结论或结论之后的任何事情而被赋予有效性;这是一个独立于结论的观察。

可能用图形表示足球比分与股票市场的相关性。由马克西姆·霍普曼在 Unsplash 上拍摄的照片

功能主义者的反对意见(我的回答是:他们没有考虑到欠确定性)

许多反对意见是以这样或那样的功能主义形式出现的。也就是说,它们都遵循一条或多条路线:

如果我们知道神经元做什么,那么我们就知道大脑做什么。

如果我们能复制一个大脑或复制一组神经元,那么我们就能制造出人工意识

如果我们能复制大脑的功能,我们就能制造人工意识

功能主义者的论点在这里不起作用,因为要复制任何功能,必须有办法确保所有功能及其依赖关系都是可见的和可测量的。没有“复制”未确定的东西。“如果我们知道/如果我们可以复制”的功能主义假设是无效的。

欠确定不需要对大脑进行如此详尽的建模是不可能的,正如 SEP (emphasis mine)[14]中的以下段落所解释的:

“……当牛顿的天体力学未能正确预测天王星的轨道时,当时的科学家并没有简单地放弃这一理论,而是保护这一理论免遭驳斥……

“……尽管牛顿的理论是错误的,这一策略还是取得了成果……

“……但是,同样的策略在试图通过假设存在另一颗行星“火神”来解释水星轨道近日点的推进时失败了……

“……迪昂正确地提出,不仅假设必须作为一个群体或一个集合进行测试,而且这绝不是一个预先确定的结论,即这样一个集合中的哪个成员应该被放弃或修改,以应对失败的经验测试或错误的暗示。

简而言之,当我们一开始就不能完全了解 X 的时候,我们就不能保证我们能设计出“像 X 一样”的东西。由于不确定性,不可能保证一个完整的模型。功能主义者的论点失败了,因为发现中的相关性并不意味着因果关系,这些相关性必须 100%可以发现,才能有一个详尽的模型。甚至在看像这样的实际实验之前,就有许多对功能主义立场的理论攻击:

重复刺激苍蝇大脑中相同的神经元群会产生随机的结果。这从物理上证明了欠定[15]:

“……一些神经元群可以引发跨动物的多种行为,有时甚至可以引发单个动物的多种行为。

刺激不同动物的一组神经元偶尔会导致不同的行为。Zlatic 说,这种差异可能是由多种因素造成的:“可能是以前的经历;可能是发育差异;这可能是动物的性格。动物在神经元激活时所处的不同状态。”

研究小组发现,刺激同一只动物的相同神经元偶尔会导致不同的行为。"

在上面引用的段落中,注意短语“可能是”和“可能是”的所有实例它们是不确定因素在起作用的迹象。当随机实验结果有多种可能的解释时,不可能进行详尽的建模。

功能主义者回答:“……但是我们不需要详尽的建模或功能复制”

是的,我们有,因为没有任何保证意识是以其他方式产生的。不引入意识就能产生过多的功能和行为;没有真正可衡量的外部成功指标。参见下面的“行为主义者的异议”一节。

伸出十个手指。一定是在想数字十。路易斯·金特罗在 Unsplash 上的照片

行为主义者的反对

这些反方一般说,如果我们能重现有意识的行为,那么我们已经产生了意识。例如,我完全不同意《科学美国人》的一篇文章声称存在检测机器意识的测试。

可观察到的行为并不意味着什么,正如最初的中文教室论证已经证明的那样。中文室貌似只懂中文。机器学习不等同于实际学习的事实也证明了这一点。

这是比蚯蚓更有意识,比蚯蚓更没有意识,还是根本没有意识?照片由特伦斯伯克在 Unsplash 上拍摄

通过机器复杂性的突现主义

复杂性突现论的反例包括电话处理器中晶体管的数量与果蝇大脑中神经元的数量。为什么智能手机没有果蝇有意识?拥有数百万倍晶体管的超级计算机呢?相比之下更加复杂的太空发射系统呢……它们是有意识的吗?意识不是从复杂性中产生的。

克隆羊不是人工智能。Benjamin Sander Bergum 在 Unsplash 上拍摄的照片

控制论与克隆

如果涉及到生命体,那么这个主题就不再是人工意识的主题了。那些将是操纵先天意识的例子,而不是任何人工意识的创造。

“最终,所有的东西都会在未来被发明出来”和“为什么大脑不能用另一种基质形成?”

基底与问题无关。所有人工智能系统都需要算法和代码。所有这些都以这样或那样的方式被编程。一个人在未来走多远,或者用什么衬底,都无关紧要;机器码的基本语法性质仍然存在。举出一个不涉及任何代码的人工智能项目。举出一个人工智能可以违反非冲突原则并拥有编程能力而不需要编程的方式(见上文“意志房间”一节)。)

“我们有 DNA,DNA 是程序代码”

DNA 不是程序代码。基因构成只影响而不决定行为。DNA 的功能也不像机器代码。DNA 测序携带了广泛的作用指令,如生长和繁殖,而机器代码的功能范围相对有限。观察表明,每一个基因影响每一个复杂的特征到一个不确切知道的程度【17】。这表明它们的工作是不确定的,而相比之下,编程代码在功能上是确定的(在不知道程序代码应该做什么的情况下,程序员没有办法设计行为,无论是适应性的还是“进化的”。参见讨论“意志房间”的部分),并且在比较中被严重划分(向我展示一个大型程序,其中每一行代码都影响所有行为)。DNA 编程类比是一个糟糕的类比,经不起科学观察。

“但是我们的大脑也操纵符号”

仅仅因为我们的大脑可以处理符号并不意味着它象征性地运作。我们可以体验和回忆那些我们还没有恰当描述的事情。换句话说,我们可以有难以形容的经历。我们从非象征性的经历开始,然后在我们试图理性地组织和交流这些经历的过程中,为它们炮制象征性的表现。

一个个人轶事的例子:我最早的童年记忆是躺在床上看着窗户上的排气扇。我记得当时我看到了什么,尽管当时我还太小,还没有学会诸如“床”、“窗户”、“风扇”、“电风扇”或“电动窗户排气扇”等单词和术语。感官和情感的回忆可以用符号来描述,但是回忆的经历本身并不是符号化的。

此外,失语症的医学现象表明视觉体验与对它们的描述是完全分开的【19】。

随机性和随机数生成器

当谈到作为意识的指标时,随机性是一个转移注意力的话题(更不用说所有外部指标的可疑性,如中国房间的论点所示)。机器内部的随机数发生器将简单地提供另一个输入,最终只会产生更多的符号来操作。

“我们已经构建了复杂的功能神经计算模型”

复杂功能模型的存在并不能帮助功能主义者摆脱功能主义陷阱。这些模型仍然严重欠定,正如最近的一个高级神经学习算法【20】的例子所示。

这个模型非常复杂,但是请注意它包含了多少不确定的表达:

“可能是不同的阈值”

“可能有共同的不应期”

“可能会用实验来回答”

模型远不能反映存在于活体大脑中的功能神经群;我非常怀疑任何研究人员会提出这样的主张,因为这不是他们的首要目标。模型能够并且确实产生有用的功能,并且实际上是“正确的”,即使那些模型实际上是“错误的”,因为它们不一定与功能上的现实相对应。换句话说,模型并不一定要 100%符合现实才能工作,因此它们的事实正确性永远无法保证。例如,轨道卫星仍然可以在不考虑相对论效应的情况下运行,因为大多数相对论效应太小,在卫星导航中不显著【21】。

照片由西格蒙德在 Unsplash 上拍摄

“你的论点只适用于冯·诺依曼机器”

它适用于任何机器。它适用于弹弓。为弹射器编程包括调整支点、张力和配重。弹射器的编程语言包含在枢轴的位置、张力的大小、配重的大小等等。如果你愿意的话,你甚至可以用水管造一台电脑;同样的原则也适用。一台机器不会“自己做事情”,就像一个弹弓不会自己投出去一样。

“你的思维实验是一个直觉泵”

为了采取这种批评的方式,一个人必须证明我所谓的滥用推理。爱因斯坦在他关于参考系的思想实验中也使用了“民间”概念[23],那么是思想实验在这里被集体怀疑,还是只有我怀疑?提出明确的批评是失败的,含糊地回答“思想实验可能被滥用”是徒劳的。人们是否认为我的类比比他们陈旧的战略更糟糕,他们把思维作为当时流行技术的类比——首先是水力,然后是电话,然后是电场,现在是计算机【24】?如果人们用可以拿在手里的带图案的索引卡来做我的实验,他们会感觉更好吗?批评需要具体。

缺乏解释力(我的回答是:证明现有理论的错误不需要另一个理论)

对人工意识的可能性的支持或反对并没有对意识的实际性质产生多大的影响,但这并没有偏离主题,因为这里的目标不是明确定义意识的性质。“意识是什么”(例如,它的性质)在这里没有像“意识不需要什么”一样被探索,这仍然可以通过它的要求来确定。围绕各种物理材料的不同“意识潜力”已经有了一些理论,但是这些理论已经在很大程度上证明了它们是一派胡言【25】。我的论文既不需要解释性理论,也不能证明或否定它。必要的基本原则已经提供了(见“意识的要求”一节))

泛灵论

(最近几年在 SA 上流行的一个话题 [26])

我不赞同泛灵论,但即使泛灵论是真的,随后可能的主张“所有事物都是有意识的”仍然是假的,因为它犯了分裂的谬误。每一件事物都有本质上的不同。泛灵论声称的普遍意识,如果存在的话,不会与在生命体中发现的普通意识是同一种类的。

这种分类差异的一些例子:约翰尼唱歌,但他的肾脏不唱歌。约翰尼看得见,但他的脚趾甲看不见。说一盏灯在这个词的一种意义上是有意识的,仅仅是因为它属于一个在另一个宇宙中是“有意识的”宇宙,这就犯了一个和说一个肾会唱歌或一个脚趾甲能看见一样大的范畴错误。

声称所有事物都是有意识的(包括人工智能)是宇宙意识的结果,仅仅因为缺乏区分它们的术语,这将会把两个范畴混为一谈。仅仅因为“意识”这个术语将所有事物与宇宙意识的追随者联系起来,并不意味着这个术语本身就应该被模棱两可地使用。泛灵学哲学家大卫·查尔默写道[27]:

“泛灵论,从字面上理解,是万物皆有灵的学说。实际上,自称泛灵论者的人并不致力于一个如此强大的学说。即使他们相信数字、塔和城市的存在,他们也不相信数字 2 有头脑,或者埃菲尔铁塔有头脑,或者堪培拉城有头脑。”

鸭子机器人。照片由 A. Konby 通过互联网档案,公共领域在维基媒体上拍摄。

“如果它看起来像一只鸭子……”这是对行为主义者半开玩笑的指责

如果它看起来像鸭子,游泳像鸭子,嘎嘎叫像鸭子,但你知道这只鸭子是人工智能鸭子,那么你就有了一个花式鸭子自动机。"但是等等,如果没人知道呢?"然后,这是一个奇特的自动鸭子,没有人能从一只真实的鸭子中分辨出来,可能是因为它的所有制造文件都被销毁了,程序员死了,不能告诉任何人这是一只人工智能鸭子……然而,它仍然不是一只真实的鸭子。暗示性的回答,比如“那我们就可以消除制造的所有证据”和其他我认为是抓住救命稻草和智力上不诚实的俏皮话。如果有人为了证明我是错的而建造了一只功能完美、视觉上无法区分的人造鸭子,那是白费力气;为了证明这一点,它的身份必须被揭露。在这一点上,启示将证明我是正确的。

“鸭子的回答”是另一个行为主义者的反对意见,被“中国房间”的论点弄得毫无意义(见上面“行为主义者的反对意见”一节)。)

你不确定你的朋友是有意识的实体吗?照片由纳松·阿泽维多在 Unsplash 上拍摄

“你不能向我证明你有意识”

这种否认和上面的非鸭子反对一样,是在玩弄同样的经验主义的不可论证的事实。我们谈论的是形而上学的事实,而不仅仅是获得它们的能力或能力。也就是说,无论是承认还是怀疑地否认意识,出发点都应该从“我否认我的意识的存在吗?”而不是“向我证明你的”

不可否认,一个人自己的意识是存在的,一旦我们承认自己是有意识的,就去质疑别人的意识是荒谬的。当我们每个人遇到另一个人时,我们是否首先假设我们遇到的可能只是一个人的复制品,然后检查那个人是否是一个人,最后才开始在满足时将实体视为一个人?不,以免有人患有妄想症。我们也不想创造一个让这种荒谬的偏执狂变得可行的世界。)

如果有人搞乱了它的程序,你最好小心。照片由阿瑟尼·托古列夫在 Unsplash 拍摄

人工意识不可能性的一些暗示

1.AI 永远不应该被赋予道德权利。因为它们永远不会有意识,所以它们比动物更不值得拥有这些权利。至少动物是有意识的,能感觉到疼痛【28】。

2.无论是外貌还是行为(如穿越恐怖谷)都与人类极其相似的 AI,在未来应该被严格禁止。允许他们存在只会创造一个沉浸在荒谬偏执中的世界。根据我的观察,许多人对机器意识这个主题感到非常困惑,因为我的一个同事称之为“糟糕的科幻小说”的例子太常见了。

3.意识永远不可能被“上传”到机器中。任何试图这样做,然后在它的自然寿命之前“退休”原来的身体将是一种自杀行为。任何完整的忒修斯式的一点一点的机器“替换”都会逐渐导致同样的结果。

4.任何灾难性的人工智能“灾难”都是由糟糕的设计/编程造成的,而且仅仅是糟糕的设计/编程。

5.人类对其创造的行为负有全部责任,公司应对其产品的不当行为负责。

6.我们不是生活在一个模拟的场景中。根据我的论文,这些推测是荒谬的:

鉴于人工意识是不可能的:

-模拟环境是人造的(根据定义。)

-如果我们存在于这样的环境中,我们就不能有意识。否则,我们的意识将是人工系统的一部分——由于人工意识的不可能性,这是不可能的。

-然而,我们是有意识的。

-因此,我们不是生活在模拟中。

参考

[1]【merriam-webster.com】【智力】(2021)

[2] 互联网哲学百科,《意识》(2021),https://iep.utm.edu/consciou/

[3] 斯坦福哲学百科全书,《意向性》(2019),https://plato.stanford.edu/entries/intentionality/,

[4] 斯坦福哲学百科全书,《克利》(2017),《T16》http://plato.stanford.edu/entries/qualia/

[5] 斯坦福哲学百科全书,《中国房间的争论》(2020 年),https://plato.stanford.edu/entries/chinese-room/

【6】a .斯洛曼, 塞尔攻击的是强强还是弱强 AI? (1985),人工智能及其应用,A.G .科恩和 J.R .托马斯(Eds。)约翰·威利父子 1986。

[7]牛津英语词典,《算法》(2021),https://www.lexico.com/en/definition/algorithm

[8] T .米切尔, 机器学习 (1997),麦格劳-希尔教育(第 1 版。)

[9] 斯坦福哲学百科全书,《感受性:知识的争论》(2019 年),https://plato.stanford.edu/entries/qualia-knowledge/

[10] V. Highfield, AI 在 QBert 学会以人类从未做过的方式作弊* (2018),https://www . ALP HR . com/artificial-intelligence/1008697/AI-learn-To-check-At-Q Bert-In-A-Way-No-Human-Ever-Done-Before

[11] J. Vincent,谷歌通过从其图像标记技术中删除大猩猩来“修复”其种族主义算法 (2018 年),https://www . the verge . com/2018/1/12/16882408/Google-racistic-gorillas-photo-recognition-algorithm-ai

[12] H. Sikchi,朝向安全强化学习 (2018),https://medium . com/@ harshitsikchi/朝向-安全-强化-学习-88b7caa5702e

[13] D. G. Smith,如何黑掉一台智能机器 (2018),https://www . scientific American . com/article/How-to-Hack-an-Intelligent-Machine/

[14] 斯坦福哲学百科全书《科学理论的欠定》(2017)https://Plato . Stanford . edu/entries/Scientific-under determination/

[15] L. Sanders,万个神经元与苍蝇的行为相联系 (2014),https://www . science news . org/article/万个神经元相联系的行为-苍蝇

[16] S .施耐德和 e .特纳,有人在家吗?一种确定人工智能是否有自我意识的方法 (2017),https://blogs . scientific American . com/observations/is-any one-home-a-Way-to-Find-Out-If-AI-have-been-Self-Aware/

[17] V. Greenwood,理论认为所有基因影响每一个复杂性状 (2018),https://www . quanta magazine . org/omnigenic-model-suggest-That-All-Genes-Affect-Every-Complex-Trait-2018 06 20/

[18] D .罗布森,你从未知道自己有过的‘不可翻译’的情绪 (2017),https://www . BBC . com/future/article/2017 01 26——你从未知道自己有过的‘不可翻译’的情绪

[19]齐默(C. Zimmer),图这个?有些就是不行 (2015),https://www . nytimes . com/2015/06/23/science/aphantasia-minds-eye-blind . html

[20] R. Urbanczik, 通过树突预测学习的体细胞锋电位 (2014),神经元。2014 年 2 月 5 日;81(3):521–8.

[21] Ž.Heć imović, 相对论对卫星导航的影响 (2013),Tehnicki Vjesnik 20(1):195–203

[22] K. Patowary,弗拉基米尔·卢克扬诺夫的水计算机 (2019),https://www . amusing planet . com/2019/12/Vladimir-lukyanovs-Water-Computer . html

[23]https://plato.stanford.edu/entries/thought-experiment/《思想实验》(2019 年)

[24] M. Cobb,为什么你的大脑不是一台计算机 (2020 年),https://www . the guardian . com/science/2020/feb/27/Why-your-brain-is-a-computer-neuroscience-neural-networks-awareness

[25] M. A. Cerullo,Phi 的问题:综合信息理论批判 (2015),PLoS Comput Biol。2015 年 9 月;11(9): e1004286。康拉德·p·科尔丁(编辑。)

[26]各种作者,出于说明目的检索到的scientificamerican.com泛灵论文章列表(2021 年 4 月 22 日)https://www.scientificamerican.com/search/?q=panpsychism

[27] D. J. Chalmers, 泛灵学与泛灵学阿默斯特哲学讲座8(2013):1–35

[28] M. Bekoff,动物意识:新报告将所有疑虑置于睡眠 (2018),https://www . psychologytoday . com/us/blog/Animal-emotions/201801/Animal-manual-New-Report-Puts-All-claudes-Sleep

人工智能和机器人技术将不可避免地融合

原文:https://towardsdatascience.com/artificial-intelligence-and-robotics-will-inevitably-merge-4d4cd64c3b02?source=collection_archive---------32-----------------------

人工智能|机器人技术

AGI 将有一个身体,并将生活在世界上

Alexus Goh 在 Unsplash 上的照片

人工智能研究不断达到新的里程碑。深度学习范式年复一年地不断重申其主导地位。假设神经网络将主宰人工智能的未来似乎是有把握的。然而,承诺总是落空。尽管一些声称,人工通用智能(AGI)似乎还不会到来。人工智能系统仍然非常笨拙和狭窄。人工智能在哪里和我们希望它在哪里之间似乎有一个缺失的差距。

今天的方法是找到并弥合这一差距的方法吗?在这篇文章中,我解释了为什么人工智能系统需要具体化,成长,并在世界上生活,以便有一天达到智能。尽情享受吧!

心灵需要身体吗?

勒内·笛卡尔在他 1641 年出版的《第一哲学沉思》一书中首次提出了思想和身体是分开的物质的观点——这被称为笛卡尔二元论或“脱离肉体的智慧”笛卡尔将心灵等同于我们对世界的有意识的主观体验和我们智力的来源。他认为,虽然我们不需要一个身体来智能,但我们的思想和身体是相互作用的;物理事件引起精神事件。

向前推 300 年,我们发现一个非常相似的想法:大脑是“一个由大脑中的神经活动物理实现的计算系统。”计算思维最初是由沃伦麦卡洛克和沃尔特皮茨在 1943 年提出的。杰里·福多尔和希拉里·普特南在接下来的几十年里将这个想法扩展到了今天所谓的大脑计算理论。

在此基础上,1976 年艾伦·纽厄尔和司马贺提出了物理符号系统假说https://dl.acm.org/doi/10.1145/360018.360022(PSS 假说)。它指出“一个物理符号系统具有一般智能行为的必要和充分的手段。”有了这个假设,我们就可以回到笛卡尔,正如艾米莉亚·布拉图所说,“人类的理解都是关于形成和操纵符号表征。”

将这些想法结合在一起,我们有:

  • 身体和精神是分离的。
  • 思维是通过计算性的大脑活动来实现的。
  • 智慧通过符号操作显现。

正是在这个框架下,人工智能在约翰·麦卡锡于 1956 年提出将它作为一个独立的研究领域后首次出现。

占统治地位的人工智能范式是无形的

在人工智能发展的过去 60 年中,符号人工智能(专家系统)和连接人工智能(神经网络)无可争议地占据了主导地位。首先,象征性的人工智能统治了 50-80 年代。然后,随着机器学习和深度学习的出现,神经网络取得了今天的地位。

**虽然在外表上非常不同,但这两种方法有一个重要的共同点:**它们都生活在笛卡尔二元论、心灵的计算理论和 PSS 假设的边界内。因此,两个都拒绝真正智能的人工智能需要一个身体的想法。

今天的人工智能,最好用深度学习来描述,已经忘记了身体。十年来最重要的进步依赖于基于软件的人工智能。能够在人类层面生成文本,在国际象棋或围棋中击败世界冠军,测试人类模仿莎翁或巴赫的创造力,或者在未来驾驶汽车的系统。所有这些都是生活在无形计算机虚拟世界中的系统。

大多数人的兴趣和努力都集中在人工智能(AGI)可以在计算机中基于软件的系统中实现的想法上。然而,这种方法有很大的局限性。

脱离实体的机器无法获得“专有技术”知识

哲学家休伯特·德雷福斯首先抨击了 PSS 假说背后的概念。在他 1972 年的著作《计算机不能做的事情》中,他强调了人类智能和早期象征性人工智能的一个关键区别。他认为,人类知识的很大一部分是隐性知识——经验知识,比如骑自行车或学习语言——这些知识无法充分传播,更不用说形式化或编纂了。Dreyfus 说,专业知识大多是隐性的,因此“专家”人工智能系统永远不可能是真正的专家。用迈克尔·波拉尼的话说,“我们知道的比我们能说的多。”

随着连接主义人工智能的出现和神经网络的繁荣,德雷福斯的论点显然已经过时。机器学习系统可以在没有被明确告知学习什么或如何学习的情况下进行学习。人脸识别,这是隐性知识的一个很好的例子,可以通过这些系统来完成。我们可以在一千张面孔中认出母亲的面孔,但我们不知道是怎么做到的。我们无法传递如何操作的知识,然而,机器学习系统可以比我们更好地识别人脸。

然而,Ragnar Fjelland,在为 Dreyfus 的论点辩护时,声明即使是连接主义的人工智能系统也不能获得实际的隐性知识。他解释说,体验真实世界是获得这类知识的必要条件。相比之下,人工智能系统最多只能体验我们喂给它们的过于简化的现实模型。机器可以在虚拟世界的边界内获得专业知识,但不能超过这个范围。用 Fjelland 的话来说:“只要计算机不成长,不属于一种文化,不在世界上活动,就永远不会获得类似人类的智能。”

体验世界的重要性

我们通过与周围环境的互动来加深对世界的理解。苹果不仅仅是发出绿光或红光,还有光滑的触觉和甜美的味觉。我们知道苹果是要花钱的。我们知道如果我们不吃它,它最终会腐烂。我们知道如果它从树上掉下来砸到我们的头上会很痛,即使它从未发生过。

我们理解苹果的所有形式,因为我们可以将信息与意义联系起来。一个人工智能系统可以对苹果进行分类,但它无法理解为什么有人宁愿吃巧克力。因为人工智能系统不生活在这个世界中,它们无法与这个世界互动,因此它们无法理解这个世界。热那亚大学生物工程教授朱利奥·桑蒂尼认为“为了在机器中开发类似人类智能的东西,机器必须能够获得自己的经验。”

德雷福斯认为,我们的智力来源于我们积极感知的感官信息和我们对世界的行动之间的复杂关系。我们不像人工智能系统那样被动地吸收世界,我们“制定我们的感知经验”阿尔瓦·诺伊在他的《感知中的 动作 一书中说得好,“感知不是大脑中的一个过程,而是身体作为一个整体的一种熟练活动。[……]世界不是一下子给意识的,而是通过积极的探究和探索逐渐获得的。”

总而言之,

  • 我们聪明是因为我们经历了这个世界。
  • 认知和感知是与行动相联系的主动过程。
  • 我们通过身体感知世界。

体验世界给了我们获得隐性知识的途径,这导致了专业知识,这是人类智慧的标志。似乎有理由假设,机器需要体验世界才能真正智能。显而易见的问题是:我们如何才能创造出满足这些要求的机器?

发展机器人的前景

这个最近的研究领域结合了机器人学、人工智能、发展心理学和神经科学的思想。Scholarpedia 将定义为建模“自然和人工系统中日益复杂的认知过程的发展,并理解这些过程如何通过物理和社会互动出现。”

发展机器人学融合了机器人学和人工智能,但在两个方面有所不同。首先,它强调了身体和环境作为导致认知出现的因果要素的作用。第二,人工认知系统不是程序化的。它们从一个发展过程的启动和维持中出现,在这个过程中,它们与物理的(无生命的)物体和社会环境(人或其他机器人)互动。

研究人员使用机器人来测试他们的认知模型,因为他们可以与世界互动。在这种范式下,发展机器人专家最终可以创造出一个像人类儿童一样在世界上成长的机器人。

艾伦·图灵早在 1950 年就已经提出构建儿童大脑并对其进行教育可能是比构建成人大脑更好的创造人工智能的方法。沿着这条通往 AGI 的道路走下去是有意义的,因为发育是我们所知道的生物体获得智力的唯一过程。这可能没有必要(正如连接主义者和象征主义者所辩护的那样),但有理由假设在机器中模仿类似人类的智能是“机械上至关重要的”。

通过给人工智能认知系统一个可以发展并与物理和社会世界互动的身体,我们正在将传统人工智能的努力与唯一已知的真正智能的实例相结合。正是在人工智能、机器人和认知科学的交汇处,我们将找到通往 AGI 的道路。

TL;速度三角形定位法(dead reckoning)

笛卡尔推广了一个关于心灵哲学的学派,这个学派的影响延续至今。在过去的 60 年里,人工智能的无实体方法取得了巨大的成功,但它们距离实现类似人类的智能还很远。发展中的机器人可能是其余问题的答案。

没有人可以声称找到了今天的人工智能和 AGI 之间缺失的联系,但融合人工智能、机器人和认知科学可以让我们更接近我们拥有的唯一真正智能的实例:我们。

人工智能的开端

原文:https://towardsdatascience.com/artificial-intelligence-beginnings-6f8937acdc6a?source=collection_archive---------39-----------------------

用 Python 从头开始构建神经网络

目标

这篇文章将解释如何使用 Python 语言从头开始创建一个神经网络,以及如何使用它来检查汽车并预测每加仑的里程数。

首先,需要解释一些概念:

网络

神经网络是将人工智能应用于现实世界问题的最常用的计算模型之一。它由一组称为神经元的单元组成,这些单元相互连接以传输和处理信号。

图片由 h3llkn 0 wz/CC BY-SA 3.0

每个神经元都通过链接与其他神经元相连。通过他们,他们接收信息,评估信息,并传播评估的结果,这可以是一个信号,突出一个功能或削弱它。

该网络还具有一个或多个最终神经元,其将从先前的神经元获取信号,并将产生可以是实数(对于回归问题)或一组值(对于分类问题)的信号。

结构

通常,神经网络以几个神经元层的形式实现。第一个图层称为输入图层或图层 0,表示要评估的不同对象要素。它不同于所有其他层,因为它不执行任何计算,只是表示提供给网络的数据。

在我们的示例中,第一层将保存将要检查的汽车的特征。例如缸数、重量、加速度、年份和制造产地等。

然后,模型将包含两个隐藏层。它们被称为隐藏的,因为它们不直接连接到输入或输出。他们将负责评估来自前一层的不同特征之间的关系,并将结果发布给下一层。

最后,我们将有一个输出层,它将获得最后一个隐藏层的结果,并将计算汽车用一加仑燃料可以行驶的距离。

下图是不同层神经元之间的连接示例:

版权所有 2021 Tensorflow:根据 Apache 许可证 2.0 授权使用

神经元

每一层都由几个神经元组成,除了最后一层,即输出层,在本例中,对于我们的问题,它只有一个神经元。

网络的每个神经元将由以下公式表示:

作者图片

其中 X 是一个向量(一维矩阵),信息来自上一层神经元。在第一个隐藏层的情况下,它将从输入层接收汽车的特征。

W 是一个向量,它将为前一层神经元的每个值分配一个权重。它们是将为网络优化以产生真实结果的主要组件之一。

b 是将偏移(偏差)应用于结果的值,也将被优化。

图片来自:www.MLinGIFS.aqeel-anwar.com作者:阿克尔瓦尔 用法授权

非线性激活

后一个函数是线性函数。如果所有的神经元都是线性函数,神经网络的结果也将是另一个线性函数。这将不允许网络识别特征之间存在的复杂关系。

为了解决这个问题,每个神经元都被添加了一个非线性成分,称为激活函数。在我们的例子中,我们将使用一个常用的激活函数 ReLU(来自整流线性单元),它无非是:

作者图片

因此,除了输出层之外,每个神经元的完整公式为:

作者图片

最终线性激活

由于目标是预测一个值(回归),而不是检测或分类一个对象(分类),输出层的神经元必须生成一个实值。因此它不会应用非线性激活。

这个神经元的公式就是:

作者图片

神经网络的优化:又名学习

网络学习过程将包括搜索权值 W 和偏移量 b 的值,当你向网络提供一辆汽车的数据时,它将产生我们想要估计的结果:那辆汽车每加仑的里程数。

逻辑:

为了找到 W 和 b 值,首先,我们用下面的等式对它们进行初始化:

  • W: 服从正态分布的随机值 0.01*
  • b: 正好用 0

然后,重复以下步骤几次(我们将这个循环的每次迭代称为一个时期):

  1. 向网络提供一辆车或几辆车的特征(以防我们的网络能够并行处理几个输入数据)。
  2. 执行神经网络的计算(称为前向传播),将权重乘以输入值,添加偏移,并逐层应用激活函数,直到我们获得最终值。
  3. 计算网络的估计值和汽车实际值之间的误差(或差异),我们将称之为**【J(W,b)*** ,并在我们的示例中表示均方误差。*
  4. 从后到开始(称为反向传播的过程),使用所获得的差,我们将使用以下公式来计算权重 W 和偏移 b 的导数:

作者图片

5.对于导数,我们继续修改权重,使它们更接近差值达到最小值的点。为此,我们将导数乘以一个 α 值(称为学习率),然后减去相应的权重:

作者图片

6.使用更新后的权重,我们重复前面的所有步骤,直到网络预测值和实际值之间的误差达到可接受的最小值。

代码

实际上,神经网络的优化不是一次一个例子地进行。有一些代码库利用现代 CPU、GPU 和 TPU 的能力对许多例子同时执行计算。

在我们的例子中,我们将使用 Python 语言和 Numpy 库同时对所有示例执行计算,并获得更好的性能。

模型

我们将定义结构(第一和第二隐藏层中的神经元数量)并创建我们的神经网络模型:

正向传播函数

它计算网络预测

成本函数

它测量网络估计值和实际值之间的差异:

反向传播函数

它计算网络函数的导数

更新权重函数

它让我们的网络更接近预期的结果

数据

定义了模型后,现在我们将使用经典的 Auto MPG 数据集来训练神经网络,以预测 20 世纪 70 年代末和 80 年代初汽车的燃油效率。该数据集提供了该时期许多汽车的描述。该描述包括气缸、排量、马力和重量等属性。

本文的目的不是详细介绍如何预处理要在网络中输入的数据。我们只说数据集被归一化并分成两部分,一个训练集用于网络优化,一个测试集用于验证训练好的网络:

最后,创建和训练网络并评估其预测的代码:

在训练网络完成后,我们用它来预测测试集中的汽车的 MPG,并将它们与它们的实际 MPG 值进行比较。

预测并不完美,但接近真实的 MPG 值。

预测: 29,26,30,32,25,28,42,34,29,28

真实值: 26,22,32,36,27,27,44,32,28,31

自己运行这个例子

为了看看这个例子是如何执行的,你可以打开这个谷歌合作笔记本,直接在你的浏览器中运行它。

结论

这是一个简化的回归问题,用 Python 编写的神经网络来解决,该神经网络呈现了所有网络的非常基本但基本的工作概念。

这个例子中故意省略了很多概念,因为它们可能会吓到一些人。在现实世界的项目中,它们将需要被考虑。其中一些是:

  • 数据的可用性、清洁度、类别之间的平衡、分布以及如何处理它。
  • 不同问题的不同网络模型(如用于回归和分类任务的模型、用于图像检测的卷积网络、用于序列(语言翻译、股票市场预测)的递归网络)等。).
  • 不同的优化方法(如本模型中的批量梯度下降、小批量 G.D .、Momentum、RMSProp、Adam 等)和超参数优化(层数量和大小、学习速率、动量参数、激活和使用的成本函数)。
  • 常见问题及解决方法(偏差和方差,爆炸或递减梯度,正则化,辍学等)。
  • 加速计算的专用硬件(如 CPU SIMD 指令、GPU 和 TPU)。

我们希望,已经看到有可能从一个真正简单的实现开始,而不需要专门的库或硬件,这将增加您对人工智能这一激动人心的领域的兴趣。

要了解这个领域的更多信息,两个共同的起点是 Michael Nielsen 的深度学习和神经网络书和 Ian Goodfellow 的深度学习书。

而且,如果你对视觉艺术感兴趣,这篇关于使用人工智能进行艺术风格转换的文章也值得一读。

金融中的人工智能:机遇与挑战

原文:https://towardsdatascience.com/artificial-intelligence-in-finance-opportunities-and-challenges-cee94f2f3858?source=collection_archive---------3-----------------------

杰弗里·布鲁姆在 Unsplash 上的照片

人工智能(AI)不再是一个新生事物,这个领域正在以不断加快的速度发展。几乎每天都有某种新的发展,无论是宣布新的或改进的机器学习算法的研究论文,还是最流行的编程语言之一(Python/R/Julia)的新库,等等。

在过去,这些进步中有许多没能进入主流媒体。但这种情况也在迅速改变。最近的一些例子包括 AlphaGo 击败了 18 次世界冠军[1],使用深度学习生成从未存在过的人类的逼真面孔[2],或者深度假像的传播——图像或视频将人们置于从未实际发生的情况中。

除了这些有新闻价值的成就,在过去的几十年里,人工智能已经被广泛应用于几乎每个行业。我们可以在周围看到它。我们在网飞得到的推荐,我们收到的关于我们最近没有使用的网上商店额外折扣的电子邮件,仅举几例。

企业采用人工智能来获得竞争优势:

  • 他们可以做出更好的、数据驱动的决策,
  • 通过有效的定位或准确的推荐直接增加他们的利润,
  • 通过尽早识别“犹豫不决”的客户来减少客户流失,
  • 自动化一些重复的任务,人工智能可以比人类员工做得更快,
  • 还有很多。

考虑到以上所有因素,难怪《哈佛商业评论》将数据科学家评为“21 世纪最性感的工作”[3]。

同样的“人工智能革命”正在影响金融行业。《福布斯》报道称,已经有“70%的金融服务公司正在使用机器学习来预测现金流事件、微调信用评分和检测欺诈”[4]。

在本文中,我们展示了人工智能在金融领域中影响最大的领域,以及使用了哪些技术来实现这一点。此外,我们还讨论了在金融领域进行数据科学研究时需要考虑的最重要的挑战。

人工智能在金融中的应用

我们首先提到金融行业中的一些关键领域,在这些领域中,人工智能产生了最大的影响,并提供了超过传统方法的附加价值。

信用评分

机器学习在金融行业的一个重要应用是信用评分。许多金融机构,无论是大型银行还是较小的金融科技公司,都在从事放贷业务。为此,他们需要准确评估个人或另一家公司的信誉。

传统上,这种决定是由分析师在与个人进行面谈并收集相关数据点后做出的。然而,与过去的评分系统相比,人工智能可以使用更复杂的方法来更快更准确地评估潜在的借款人。为此,高级分类算法使用各种解释变量(例如,人口统计数据、收入、储蓄、过去的信用历史、在同一机构的交易历史等等)来得出最终分数,该分数决定了该人是否会获得贷款。

基于人工智能的评分系统的另一个优势是做出公正决策的潜力——没有人为因素,如银行员工在某一天的情绪或其他一些影响决策的因素。此外,它可能有利于没有广泛信用历史的人,让他们证明自己的可信度和偿还贷款的能力。

欺诈防范

机器学习可以产生巨大影响的另一个关键领域是欺诈预防。对于欺诈,我们理解为任何欺诈活动,如信用卡欺诈、洗钱等。由于电子商务的日益普及、在线交易的数量以及第三方集成,前者近年来一直呈指数级增长。

尼尔森[5]的一份报告揭示了这种影响的潜在规模——“2019 年,全球基于卡的支付系统产生了 286.5 亿美元的总欺诈损失,相当于每 100 美元的总交易量中有 6.8 美元”。

过去,组织使用领域专家设计的硬编码规则来打击欺诈。然而,潜在的危险在于欺诈者发现了规则,然后能够利用该系统。基于人工智能的解决方案则不是这样,它可以随着时间的推移而进化,并适应数据中发现的新模式。

有许多机器学习算法专门从事异常检测,擅长发现欺诈性交易。这种算法可以筛选数以千计的交易相关特征(客户过去的行为、位置、消费模式等)。)并在出现故障时触发警告。

虽然许多传统的机器学习技术(如逻辑回归、支持向量机或决策树)已经可以达到合理的性能,但行业仍在不断推动改进。这是可能的,因为更复杂的算法可以更好地处理大量数据(包括观察数据和潜在特征)。除了 XGBoost 或 LightGBM 等 Kaggle 竞赛获胜者之外,欺诈检测是深度神经网络擅长的一个领域,因为它们能够处理非结构化数据并识别模式,而无需太多的特征工程。

行政长官在广场拍照

算法交易

“时间就是金钱”这句话在交易中最有意义,因为更快的分析意味着更快的模式识别,从而带来更好的决策和交易。当某种模式被发现,市场做出反应时,采取行动已经太晚,机会已经错过。

这就是为什么如此多的精力和金钱被投入到算法交易中,也就是说,复杂的系统在瞬间做出决定,并根据确定的模式自动执行交易。这样的系统可以大大超过人类交易者,也考虑到他们不受情绪的影响。Mordor Intelligence 的一份报告[6]指出,2020 年美国股票交易总量的大约 60%到 73%是由某种人工智能支持的系统处理的。

算法交易系统结合了机器和来自各个领域的深度学习的最新发展。虽然这些系统的某些部分可以专注于尝试预测资产回报(在合理的程度上),但其他组件可能会使用基于计量经济学和资产配置理论的更传统的方法。

最近获得大量关注的是使用替代数据源来获得对竞争对手的优势。对象识别的进步有助于分析卫星图像,而自然语言处理(NLP)的最新技术允许从新闻文章、Twitter、Reddit 等来源进行准确的情感识别。

算法交易在数据科学的个体从业者中也越来越受欢迎,他们试图在本地机器或云中建立自己的交易系统。随着最近开始交易的难易程度的变化以及各种经纪人 API 的可用性越来越多,愿意尝试的人越来越多。

或者,数据科学家可以参加 numeri[7]—一项类似 Kaggle 的数据科学挑战,目标是根据提供的数据(匿名)和潜在的外部替代数据来预测股市回报。该公司可以被描述为人工智能主导的对冲基金,它汇总了参与个人做出的预测,并允许他们以计价单位(该基金自己的加密货币)赚取他们的收益份额。

机器人顾问

鉴于通货膨胀对我们储蓄的影响,以及把钱存在储蓄账户中不再有利可图的事实,越来越多的人对被动投资感兴趣。这正是机器人顾问发挥作用的地方。它们是财富管理服务,AI 根据投资者的个人目标(包括短期和长期目标)、风险偏好和可支配收入,提出投资组合建议。投资者只需每月存入资金(或自动转账),其他一切都由他们来处理——从选择投资的资产、实际购买资产,然后可能在一段时间后重新平衡投资组合。所有这些都是为了确保客户能够以最佳方式实现他们的预期目标。

这种系统的主要优点是,它们对客户来说非常容易使用,并且不需要任何金融知识。自然,成本也起着重要作用——机器人顾问往往比人力资产管理公司的服务更便宜。

个性化银行体验

银行业试图利用人工智能的力量为每个人提供个性化的银行体验。一个例子可能是聊天机器人,它们越来越难以从真正的人类顾问中辨别出来。使用先进的自然语言处理技术,他们可以理解客户的意图,并试图为他们指出正确的方向。例如,他们可以帮助用户更改密码、检查当前余额、安排交易等。此外,这种聊天机器人通常可以识别客户的情绪,并在此基础上调整他们的反应。如果他们检测到消费者非常生气,可能有必要将他们与人类顾问联系起来,以尽快解决问题,避免进一步的挫折。智能聊天机器人不断增强的能力还可以通过减少呼叫中心的工作量来节省成本。

但聊天机器人并不是金融领域唯一的个性化体验。许多机构利用他们拥有的大量数据来分析消费者的消费行为,并提供量身定制的金融建议,帮助他们实现目标。这种服务可以包括如何减少每月开支的技巧,或者以简单和用户友好的方式向客户展示这些开支,例如,本月你花费最多的三个地方。这些机构也可以让你知道,一些经常性的转移将很快发生,你的帐户上没有足够的资金。所有这些只是现代金融公司能够为客户提供的服务的冰山一角。

过程自动化

最后,当谈到自动化时,人工智能提供了很多。使用高级光学字符识别(OCR)可以显著提高通常由员工处理的普通且耗时的任务的效率。例如,数字化文档、处理表单或从文档中提取相关信息。

许多金融机构要么使用专用软件,要么为 KYC(了解您的客户)流程构建内部解决方案。在金融领域,通常需要提供某种形式的 ID 以避免欺诈。许多新经纪人和金融科技公司让这个过程变得非常简单——你用手机扫描你的 ID,然后自拍以验证与 ID 匹配。在后台,一个基于人工智能的解决方案验证是否有匹配,但同时检查 ID 是否不是假的,以及图片是否没有什么值得警惕的。处理图像是深度学习和卷积神经网络(CNN)等架构显示出非常有前途的结果的领域。

人工智能在金融领域的挑战

描述了人工智能在金融领域产生影响的关键领域后,讨论与之相关的潜在挑战才是有意义的。

数据质量

数据科学领域有一句格言——“垃圾进,垃圾出”。虽然适用于任何与数据相关的工作,但它在金融行业中至关重要。一天的损坏数据,甚至是输入到交易算法中的几个错误的观察值,都会对整个系统产生可怕的后果,导致糟糕的交易和财务损失。

这就是为什么在金融领域的这些关键领域,拥有干净、有条理、维护良好的数据源作为机器学习模型的输入非常重要。如果数据发生了任何不希望的事情,或者引入了不合适的东西,必须有一种方法在整个管道中快速跟踪它,确定问题并修复它。一些公司基于这一概念开展业务,并为数据提供类似 git 的版本控制。

弗兰基·查马基在 Unsplash 上拍摄的照片

有偏差的数据

人工智能做出的决策会对金融机构的客户产生重大影响。一个被拒绝的贷款申请可以改变一个人的一生。这就是为什么需要特别注意消除数据中的任何偏差来源。凯茜·奥尼尔(Cathy O'Neil)的《数学毁灭的武器》(Weapons of Math Destruction)【8】(免责声明:参考链接)详细阐述了数据偏差的几个例子及其有形的后果。

降维

金融机构坐拥大量数据,因为一笔交易可能有数千个数据点。这也是为什么行业中的信噪比非常低,这使得数据科学家的工作同时非常具有挑战性和趣味性。

许多机器学习技术随着观察的数量而很好地扩展,但是当特征的数量爆炸时,它们会受到影响。也就是说,分析师必须要么执行某种特征选择(基于领域知识或自动进行),要么尝试降低数据的维度。对于后者,他们可以使用成熟的技术,如主成分分析(PCA)、线性判别分析(LDA)或更现代的技术,如 t 分布随机邻居嵌入(t-SNE)或均匀流形逼近和投影(UMAP)。

黑匣子

在许多行业中,数据科学家非常渴望使用最新、最先进的技术,这些技术可以在幕后执行大量复杂的计算,并提供非常准确的预测。尽管在许多情况下,这可能是一件合理的事情,但在金融领域,事情远不止如此。

金融行业受到严格监管(这是有充分理由的),算法做出的许多决定必须被该机构完全理解。想象一下,一个人的信用评分很低,贷款申请被拒绝了。然后,这样的人可以提出索赔,并要求详细解释导致这一决定的所有因素。

这就是为什么模型可解释性在金融行业中起着至关重要的作用。虽然使用最新和最棒的神经网络架构可能很有吸引力,并提供额外的几个百分点的准确性(或用于评估的其他性能指标),但它通常不是适合工作的正确工具,而是选择更简单的模型(如逻辑回归或决策树)。这是因为有了这样的模型,分析师总能解释是什么因素塑造了决策。

此外,可解释的人工智能领域发展非常迅速,研究人员致力于模型不可知的方法,允许解释相对简单和非常复杂的模型的决定。这种技术的例子包括 LIME(局部可解释模型不可知解释)或一种基于博弈论的方法,称为 SHAP (SHapley 加法解释)。

结论

在本文中,我们描述了金融行业中广泛理解的人工智能可以为公司及其客户提供大量增值的领域。我们还讨论了在实现这些技术时需要解决的一些关键挑战。这些列表绝不是详尽的,因为人工智能和金融领域都在不断变化,并适应每天的进步。可以肯定的一点是,我们生活在一场基于人工智能的革命的尖端,这场革命对企业和个人都产生了影响。

喜欢这篇文章吗?成为一个媒介成员,通过无限制的阅读继续学习。如果你使用这个链接成为会员,你将支持我,不需要额外的费用。提前感谢,再见!

您可能还会对以下内容感兴趣:

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

参考

[1]https://deep mind . com/research/case-studies/alpha go-the-story-迄今为止

[2]https://thispersondoesnotexist.com/

[3]https://HBR . org/2012/10/data-科学家-21 世纪最性感的工作

[4]AI 在金融服务中的采用状况—https://www . Forbes . com/sites/louiscolumbus/2020/10/31/The-State-Of-AI-Adoption-In-Financial-Services/?sh=42c39ad12aac

[5]卡及移动支付行业统计|尼尔森报告图表存档—https://Nilson Report . com/publication _ chart _ and _ Graphs _ Archive . PHP?1=1 &年=2020

[6]算法交易市场趋势、规模| 2021 年至 2026 年行业预测与 COVID 影响—Mordor Intelligence—https://www . Mordor Intelligence . com/Industry-reports/Algorithmic-Trading-Market

[7]数字—https://numer.ai/

[8]奥尼尔,凯茜。数学毁灭武器:大数据如何增加不平等并威胁民主。皇冠,2016。

人工智能在魔法聚会中

原文:https://towardsdatascience.com/artificial-intelligence-in-magic-the-gathering-4367e88aee11?source=collection_archive---------6-----------------------

实践教程

第一部分:数据科学之旅

这是一个一页的总结,应该有助于整体方法的解释。图片作者。

请允许我以结尾开始这篇文章**,以展示我最终能够开发的应用,来展示人工智能模型,这些模型被训练来预测(可以说是)有史以来最伟大的游戏的交易卡的属性。**

作为第一个最小可行产品,它是由正在进行的研究的第一组结果构建的,在任何意义上它肯定不是最终版本,但我计划继续改进。另一方面,我对它感到足够自豪,我很乐意与数据科学社区Magic The Gathering 社区分享它。

我相信,这种经验可以帮助数据科学家同事完成他们自己的项目,同时为卡片设计目的、卡片测试、创意、模拟和许多其他与新卡创建过程相关的任务提供一种有趣的工具。

这里是链接 和一个小视频教程,教你如何使用这个应用程序:

https://share . streamlit . io/gabrielpierobon/magic aimodels/main/app . py

作者的 Youtube 视频

动机

自从几年前我开始研究机器学习以来,最重要的是从我专攻自然语言处理的那一刻起,我就一直梦想着将这项技术应用于我在世界上最喜爱的游戏之一的可能性:

魔法:聚会

照片由 Ryan Quintal 在 Unsplash 上拍摄

这篇文章是我计划撰写的系列文章的第一篇**,我的目标是更深入地了解这个持续了大约六个月的过程中每一步的细节。不幸的是,如果我试图在一个镜头中彻底解释我自己,这将是一篇很长的文章。所以,如果我没有马上解释清楚,请不要担心,我会尽快解释清楚的。**

这篇文章的目标受众是谁?

首先也是最重要的,我不打算花时间来解释这个聚会是什么魔法以及它是如何玩的。不是因为我不想做,而是因为这可能会让我永远做不完。

我希望点击这篇文章并发现它很有趣的读者,对这个游戏有点熟悉,并且对于有几年游戏经验的人来说(无论是最近的经验还是几年前的经验)会更容易理解。

我还期望至少有一些关于机器学习数据科学过程的中级知识,尽管在本文的前半部分这不是必需的(直到检查点标题)。

快速介绍

作为一个快速介绍,以防你碰巧不知道这个游戏,但仍然想继续阅读:

魔术聚会是一种交易纸牌游戏,玩家在单人或多人比赛中制作纸牌并相互竞争。你只(大部分)使用你牌组中的牌,并试图通过召唤生物、施法和攻击对手致死来赢得游戏。

基本规则相当容易学习,然而掌握游戏甚至擅长游戏可能非常具有挑战性,但这正是游戏的魅力所在。你可以随意地玩,也可以激烈地玩。如果你还没有玩过一个魔术游戏,我鼓励你去玩。它需要统计思维、资源分配、不完全信息下的决策、优化和许多其他技能,作为一名数据科学家,你应该不断提高这些技能。如果你想学习基础知识,你可以观看这些视频:

YouTube 视频魔术聚会官方频道

Tolarian 社区学院频道的 YouTube 视频

开始玩和学习基础知识的一个好方法是安装数字客户端: Magic Arena 。这里是下载链接。

在这种情况下,人工智能面临的挑战是什么?

将人工智能引入这样一个游戏的一个主要挑战是,有一个不断增长的可用卡池,它每年只会变得越来越大。到今天为止,大约有三十张 和一千张不同的卡片,每一张都有独特的能力和效果。卡片之间的互动和协同作用几乎是无限的,而不完善的信息(不知道对手手中的卡片)使得游戏中的决策非常困难,以至于它被称为世界上最复杂的游戏,也是人工智能永远无法真正擅长的游戏。

这不应该阻止我们尝试,对不对?

我的研究重点

当然,这些前提在某种程度上仍然是正确的。我不会说现在我们还不能教人工智能如何玩好魔法,但是就像生活中的任何难题一样,我们需要把它分成更小的部分,并尝试一个接一个地解决它们。希望这项研究能帮助其他人解决下一步的问题,等等!有一件事对我来说是肯定的:

我无法想象一个没有人工智能在聚会上玩神奇游戏的未来

提到这一点,对于这个项目,我决定避免卡片之间的互动和游戏所需的决策顺序所带来的复杂性,而只关注对个别卡片的解释这意味着我们所做的就是处理我们能从单张牌中获得的最多数据,并对这些牌的其他重要属性做出预测(如其颜色,其稀有度,其法力值,其市场价格等属性)。)

带着这个目标,我们来谈谈魔法卡…

一张神奇的收集卡

这在我看来是一张非常好的魔术集结卡。一个 4/4 的飞行器花费 5 点法力是很合理的。匆忙让这张卡变得非常好,因为它可以在进入战场的同一个回合进行攻击。它真正的力量在于它的最后一个能力,该能力允许对手在攻击时对目标非龙生物造成 4 点伤害。对一个生物的移除总是很强的。在它的时间标准,这是一个惊人的终结者,它看到了其他格式的发挥,如先锋,历史和指挥官。对于更有效的格式,如现代或传统格式,这还不够好。**图片来自 Scryfall API。**作者:山姆伯利。2017 海岸巫师

每一张神奇的收集卡都是不言自明的。这意味着 读卡说明了卡。这句话很简单,但非常有力。

魔法卡就像一个独立的小程序,在游戏的语言(规则)下运行。它的作用和它对黑板的影响可以 100%从黑板上的内容中扣除。

一个经验丰富的玩家可能会阅读一张牌,并试图以较高的置信度预测其许多最重要的属性:

  1. 强/厉害的卡吗?
  2. 这可能是一张贵的卡吗?
  3. 这张卡能不能像现代或者指挥官一样成为某种格式的订书钉

你可以看看我对上图中我最喜欢的一张卡片的评价。不同意可以随意!

考虑这些例子:

有些牌被认为是好的,因为它们的效果在任何棋盘状态下都是有效的,并且通常能让你当场赢得游戏*。全知让你不用支付资源就能从你手里玩牌。它本身相当昂贵,但是一旦它进入战场,它通常就玩完了。**图片来自 Scryfall API。*作者:陈柏宇。2018 海岸巫师

有些牌很强,因为它们便宜(意味着它们使用的资源少),因此非常节省法力。剑转犁头是一个单法力移除法术,以瞬间速度放逐,唯一的缺点是对手赢得一些生命,使其效率极高。**图片来自 Scryfall API。**作者:杰斯珀·埃辛。2021 海岸巫师

一些生物卡比其他类似的卡更强,仅仅是因为它们的生物类型不同,因为它们可以适应已经存在的强大原型 / 部落(例如人类精灵巨人或狗拥有更多的支持)。你玩的人类越多,一个变得越来越大的人类对人类来说是非常好的,但是这张卡在其他缺乏和人类同等水平支持的部落中不起作用。**图片来自 Scryfall API。**作者:斯维特林·韦利诺夫。2016 海岸巫师

有些卡片非常强大,因为它们能做正常情况下这种颜色做不到的事情,而且它们在 Commander 这样的格式中成为主食。喂虫群是一个可以对付附魔的黑色法术,以前没有过。这张白色的牌没有那么强大,因为白色有更好的选择来达到同样的效果。**图片来自克里福尔 API。**作者:安德烈·库金斯基。2021 海岸巫师

我也许可以永远继续这些例子,但是正如你所看到的,一张牌是好还是坏贵还是便宜一种颜色还是另一种颜色,这是难以置信地变化着的,并且依赖于牌中的文字和符号的某种分布。

真正的智慧能用卡片做什么

想象一下这个子博弈。假设我是一名魔法采集设计师,我制作了一张新的卡,这张卡以前并不存在,所以我写下了它的卡类型,它的效果,能力等等。没有插图,没有参考具体的颜色,没有参考铸造成本

卡类型:即时

甲骨文:反击目标法术。如果某个非生物咒语以此方式被反击,则此咒语对任何目标造成 2 点伤害。

然后我把这张新卡给一个有经验的玩家看:

  • 他们能预测它应该是什么颜色吗?
  • 他们能预测卡片的铸造成本吗?
  • 他们能预测卡片的稀有度吗?是普通生僻稀有还是神话牌?
  • 他们能预测那张卡买起来会是还是便宜吗?

我的假设是是的绝对 他们可以那样做,而且他们往往是对的而不是错的。

如果你玩高水平游戏的时间够长,并且你非常熟悉池中的许多牌,那么:

  1. 你可以非常合理的区分五种颜色中每一种的不同属性所谓的颜色派 并且明白因为这是一个反法术,那么它肯定是蓝色,但是它也能造成伤害的事实表明这个法术也被认为是红色
  2. 你很可能推断出它的法力值(转换后的法力消耗),尽管在这里你可能还需要知道它的稀有度。我们制作的牌可能是普通稀有4 法力费用牌,但也可能是不普通稀有甚至稀有3 法力费用牌。
  3. 你大概明白,牌越强越有可能是稀有或者神话。知道这张卡可以对抗一个法术并且对任何只有 3 法力的目标造成 2 点伤害可能会让你认为它至少是稀有不常见
  4. 最后,你可能会熟悉如今推动卡片价格上涨的因素**,并预测有一种新的《指挥官》神话主食会非常受欢迎,供应量非常有限,因此非常昂贵。我们制作的卡不是这样,因为在任何构造的格式中,反击法术3 法力并不是非常有效地成为钉书钉(除非那张卡有很多优势,比如神秘命令)。**

无论如何,这些例子都不疯狂。有些人已经变得非常擅长这种类型的评估。以下是我最喜欢的一些:

下面是 MTGGoldfish 团队讨论一些最新卡的电量水平的视频

从某种意义上说,你的大脑会从经验和接触中了解到,每当在一张纸板上出现一定分布的字符、符号和单词时,那张纸板就会是一张好的或坏的纸板,一张更贵或更便宜的纸板等等。****

你的真实智能将帮助你发现并理解这些小模式**,这些隐藏的信息,你越多地接触它,并在评估中从失败和成功中学习,你最终会变得更好。**

这个有力的结论,让人工智能在我们的征途中光彩亮相!

AI 来了!

上述结论引发了一些有趣的机会:

  • 如果我们训练一个人工智能**(在这种情况下是一系列监督的机器学习模型)在上训练一张卡片中所有可能可用的 数据,以及我们有兴趣预测的那张卡片的所有属性(稀有度成本价格颜色等),会怎么样?)?**
  • 我们能否将卡片上的文字和符号转化为实际数据好到足以让机器学习模型接受训练?
  • 这些模型 能学习预测那些具有良好确定性**、准确性和总体表现良好的属性吗?**

接受挑战!

C 检查点

从现在开始,这篇文章变得更加专业,需要一些关于机器学习的知识。但是没有也不用担心。

现在你…

  • …已经了解研究的前提,
  • …已经介绍过这个应用程序,所以你可以清楚地了解我想要完成的任务及其结果。
  • …可以跳过文章的其余部分,阅读最后的结论。
  • …尽管如此,我还是很高兴被邀请继续这篇文章的讲座,因为你可能会觉得它足够有趣!

该过程

该项目的任务执行非常符合数据科学工作流程的标准,可以总结在下面的列表中。我计划写一篇关于他们每一个人的详细文章:

  1. 获取数据 (5%的工作量)
  2. 转换数据 (25%的工作量)
  3. 特征工程/特征选择 (35%的工作量)
  4. 多模型训练 (20%的努力)
  5. 模型评估 (5%的工作量)
  6. 用于演示目的的 Web 应用程序开发 (10%的工作量)

在接下来的完整详细文章之前,先简要介绍一下上面的每个任务

获取数据:注释

  • 我使用 Scryfall API 和库 scrython 收集了所有数据,并决定从 2004 年开始制作一个所有魔法卡的数据集。做出这一决定是为了确保有足够大的卡片样本,但同时避免书写古怪的非常旧的卡片**。我们不希望我们的模特从中吸取教训。**
  • 结果数据集包含 26,622 张卡(包括重印)。

下面是我们可以从 Scryfall API 获得的一张卡的数据示例:

****图片来自克里福尔 API。作者:基兰·扬纳。2019 海岸巫师

{'object': 'card',
...
 'name': '**Kenrith, the Returned King**',
 'lang': 'en',
 'released_at': '2019-10-04',
...
 'layout': 'normal',
...
 'image_uris': {'small': 'https://c1.scryfall.com/file/scryfall-cards/small/front/5/6/56c1227e-bea7-47cb-bbec-389a3d585af5.jpg?1637568481',...},
 'mana_cost': '**{4}{W}**',
 'cmc': **5.0**,
 'type_line': '**Legendary Creature — Human Noble**',
 'oracle_text': "**{R}: All creatures gain trample and haste until end of turn.\n{1}{G}: Put a +1/+1 counter on target creature.\n{2}{W}: Target player gains 5 life.\n{3}{U}: Target player draws a card.\n{4}{B}: Put target creature card from a graveyard onto the battlefield under its owner's control.**",
 'power': '**5**',
 'toughness': '**5**',
 'colors': **['W']**,
 'color_identity': **['B', 'G', 'R', 'U', 'W']**,
 'keywords': [],
 'legalities': {'standard': 'not_legal',...},
 'games': ['arena', 'paper', 'mtgo'],
...
 'reprint': False,
 'variation': False,
 'set_id': 'a90a7b2f-9dd8-4fc7-9f7d-8ea2797ec782',
 'set': 'eld',
 'set_name': 'Throne of Eldraine',
 'set_type': 'expansion',
...,
 'rarity': '**mythic**',
...
 'prices': {'usd': '**6.51**',
  'usd_foil': '**6.97**',
  'usd_etched': **None**,
  'eur': **None**,
  'eur_foil': **None**,
  'tix': '**0.17**'},
 'related_uris': {...}

转换数据:注释

  • 由于数据源是 JSON 格式,我不得不把它转换成一个 熊猫数据帧
  • 一个非常重要的转换是将来自单面卡的数据与来自双面卡的数据合并。魔术牌有时有两面,是 API 响应中的不同字段,需要大量的操作。
  • 关键字列转换为每个关键字的单列,如下所示。****

  • ****将卡类型分成不同的列,如下所示。

  • 固定劈开 。《奈斯特拉:深红誓言》中的系列介绍了具有*【括号内】能力的卡片,这些能力可能适用,也可能不适用,这取决于卡片是如何铸造的。我修好了那个,但是它很复杂。我会在一篇具体的文章中解释。*
  • 用标准化的“CARDNAME”令牌替换甲骨文中的卡名。这是最重要的转变之一。它包括用实际的令牌“ CARDNAME ”替换神谕文本(写有该卡能力的文本)中的卡名。卡片的名称应该与模型无关,但是标记 CARDNAME 的实际存在非常重要,特别是对于 CARDNAME 是句子主语的自然语言模型。

例如,卡片闪电的甲骨文文字由

"闪电箭对任何目标造成 3 点伤害."

"对任何目标造成 3 点伤害."

  • 对甲骨文进行分词。剧透警报!。稍后我会解释我是如何训练两组不同的模型的。一方面是典型的分类模型,另一方面是具有嵌入层深度学习 NLP** 模型。我用标记化的 oracle 文本(以 TF-IDF 的方式)填充了第一个模型,用标记序列填充了 NLP 模型。分别如下(1)和(2)。**

  • 移除土地。在这个项目中,我们不包括土地,所以我把它们从数据集中过滤掉了。
  • 一个热编码分类列。将所有分类列转换为单个二进制列。例如:

特征工程/特征选择:注释

  • 转载。计算一张卡片的重印数量。如果一张牌出现在 3 组不同的牌中,那么“印数”一栏将是 3。一张卡片重印的次数越多,市场上该卡片的供应量就越多,因此,它的价格就越便宜,这使它成为我们价格预测模型的一个非常有用的特征。
  • 计算一张卡中的能力。这意味着在神谕文本中计算一张卡中不同的能力块。例如,我们的朋友 Glorybringer 有 2 个能力。"飞行,急速"是它第一个能力的一部分,并且"你可以在它攻击时使用光明使者。当你如此做时,它对目标由对手操控的非龙生物造成 4 点伤害。“是第二种能力。卡片上的文字越多,卡片上的能力越多,卡片越强大的几率就越高(越稀有,越昂贵,等等。).作为一个规则,任何时候甲骨文有一个“\n”,我认为是一个能力的结束和下一个能力的开始。****
  • ****创建列“单色”、“单色”、“双色”、…、“五色”,根据卡片为 1 或 0。

  • 计算投入。这是一张牌的施放费用中有多少不同的实际魔法力符号。例如,一张施法成本为 {2} 的牌,因为有 2 个白色魔法符号,所以奉献为 2。我在另一个专栏中计算了甲骨文中的奉献。
  • X 咒。如果卡有一个包括 的施法成本,则此列为 1,否则为 0。
  • 清点甲骨文中的法力符号。除了甲骨文中的符号,与上面的奉献相同。****
  • 包括多选。对于像 Prismari 命令这样的卡,给你多种选择。如果该卡包含此选项,则此栏为 1。**

****图片来自 Scryfall API。作者:约翰内斯·沃斯。2021 海岸巫师

  • 包含攻技 。对于像法力愚人法力摇滚这样的牌,或任何横置以做某事的牌。**

****图片来自克里福尔 API。作者:马塞洛·维格纳利。2016 海岸巫师

  • 包括风味文本。风味文字本身是非常没用的,因为它对游戏没有任何影响,它只是故事。然而,还有另一种观点。一张有风味文字的牌是一张不太可能有很多能力的牌,因为风味文字(见上图中斜体部分)和能力文字占据相同的空间。
  • 风味文字长度。计算风味文本的实际字符长度。还是那句话,味文越长,能力空间越小。
  • 最重要也是最困难的部分:超类型卡片

我认为牌的超类型是玩家非正式分配给他们的任何一种牌。例如,一张卡片可以被认为是一个“移除咒语”,但那并没有写在卡片的任何地方。然而,我想捕捉所有的**【移除法术】以及许多其他超类型,因为它可以让模型受益匪浅。其他的例子还有:《魔法石》《魔法石》《愤怒》《坡道》《进入战场触发》等。**

我通过为每个超类型使用多个正则表达式来实现这一点,这是如此乏味、冗长和复杂,我甚至无法在这里开始展示。现在,您需要知道的是,这些是我包含的所有不同的超类型:

**'counterspell', 'manarock', 'manadork', 'removal', 'wrath', 'ramp', 'tutor', 'cardraw', 'burn', 'discard', 'enters_bf', 'die_trigger', 'attack_trigger', 'pseudo_ramp', 'static_ramp', 'creature_tokens', 'extra_turn', 'plus1_counters', 'graveyard_hate', 'free_spells', 'bounce_spell', 'sac_outlet', 'sac_payoff', 'cant_counter', 'costx_more', 'costx_moreactivate', 'costx_less', 'costx_lessacitivate', 'whenever_opp', 'returnfrom_gy', 'reanimation', 'castfrom_gy', 'lord', 'upkeep_trigger', 'endstep_trigger', 'landfall', 'combat_trigger', 'life_gain', 'treasure_tokens', 'protection', 'cost_reduction', 'mana_multipliers', 'card_selection', 'whenever_cast', 'gain_control', 'unblockeable', 'difficult_block', 'create_copy', 'milling', 'trigger_multiplier', 'untapper', 'static_effects', 'damage_multipliers', 'variable_pt', 'agressive', 'doublers', 'blinker', 'graveyard_tutor', 'play_toplibrary', 'life_lose', 'play_from_graveyard', 'infect', 'disenchant', 'venture', 'animator', 'wish', 'gy_synergies', 'looting_similar', 'cheatinto_play', 'pumped_foreach', 'ritual', 'no_maximum', 'wheel', 'extra_combat', 'ghostly_prison', 'land_destruction', 'win_game', 'lose_game', 'cant_lose'**

例如,我的孩子 Glorybringer 有 5 个超类型:

****移除=1,灼烧= 1,攻击触发= 1,困难格挡= 1,攻击性= 1,所有其他超类型= 0。图片来自 Scryfall API。作者:山姆·伯利。2017 海岸巫师

这种分配超类型的过程产生了一种惊人的将卡片聚集在一起的方式,它确实对模型有很大的帮助。

  • 创建价格箱。这是为了离散化连续价格变量(青铜:0–0.25,白银:0.25–1.00,黄金:1.00–5.00,铂金:5.00–10.00,钻石:10.00-)。价格预测既有回归模型的数值预测,也有分类模型的这 5 个类别的预测。

还有许多其他的转换和特性工程任务,但是由于文章的长度,我不能在这里包括它们。

训练数据集

在执行转换和特性工程步骤之后,我得到了一个由 25K+行和 1K+列组成的巨大数据集。

这意味着我能够将一张卡中的信息转换成数百个由 0 和 1 组成的数据点,这就为一些机器学习做好了充分的准备!

数据集本身就是一个瑰宝,它在 GitHub 中是开源的,请随意在您自己的模型上使用它!

它很大,可以在这里展示,但你可以在我的 GitHub 中找到它:

https://raw . githubusercontent . com/gabrielpierobon/magic aimodels/main/datasets/datasets _ vow _ 2021 12 20 _ full . CSV

模型训练:注释

  • 型号类型。我按照一个监督过程训练了二元分类多类分类回归模型。**
  • 算法。我主要使用了来自 scikit-learn Python 库的线性/逻辑回归梯度提升以及带有 Keras/Tensorflow深度学习**
  • 模型市场。这里有一个表格,列出了所有的模型和它们的作用。注意专栏模拟题

  • 降维。由于我们的数据集中有非常高的维数,所以我研究了 多重共线性 ,并在训练前删除了高度相关的特征。我还研究了 递归特征消除 算法,帮助去除一些无用变量。
  • 不平衡问题。大多数类别是不平衡的,这在机器学习的世界里总是有问题的。有更多的普通卡,例如神话,所以我不得不 每次都上采样 数据集,以便获得平衡的类。我只是重复了代表性不足的班级的样本。**
  • 超参数调谐。我为所有模型中的超参数调整设计了网格搜索空间,并使用了五重交叉验证**。****
  • 缩放。大多数变量是二进制的(1 和 0),但也有一些数字特征,所以我使用 MinMaxScaler 缩放所有数字特征。
  • 训练/测试/验证分割。出于评估目的,我将数据集分为训练集和测试集,并省略了最后一个魔术集“in nistrad:Crimson Vow”**
  • NLP 深度学习模型。对于深度学习模型,我对前面提到的甲骨文文本进行了标记化,将标记序列填充到最大长度,创建了一个具有 100 个维度的嵌入层,通过一个双向 LSTM 层对它们进行处理,然后通过全连接神经元的一些隐藏层,使用丢弃来避免过多的过拟合。如果测试设置精度没有提高,使用提前停止和耐心 3 对模型进行 100 个时期的训练。****

这是一个二元分类模型的模型摘要

模型评估:注释

模型评估总结。作者图片

  • ****试试 app,自己看!评估模型的最佳方式是进入应用并使用 Innistrad: Crimson Vow 集中的卡片进行尝试,这些卡片是训练和测试中遗漏的数据。选择不同的型号,看 app 怎么分类。
  • 报告的指标总是使用 setin nistrad:Crimson vout。评估模型的决定是在一组不用于训练也不用于测试的模型上进行。以下所有指标都应该是可靠的。**
  • 二元模型。对于二元模型,我计算了每个单独模型的精确度,还计算了三个模型的平均预测,在一种投票分类器中(见上图)。我的理由是,每个模型本身都是好的,应用程序可以受益于在他们三人之间进行投票的最终决定。结果:****

二元模型:我们可以看到,使用单词嵌入和来自数据集的所有特征的深度学习模型的表现优于逻辑回归和梯度增强模型。大多数模型在 Innistrad: Crimson Vow 上的得分都高于 90%,然而,该模型在预测稀有和神话卡片方面有更多的麻烦,准确率仅为约 70%。

  • 多类模型。这些模型给出了每一类的概率。因此,例如,颜色预测模型将给出每一类的概率:白色、蓝色、黑色、绿色、红色和无色。最终预测将永远是概率最高的那个。由于我对 3 种算法之间的投票感兴趣,我决定对 3 种算法(逻辑回归、梯度推进和深度学习)中每一种算法的每一类的概率进行求和,并从较高的预测概率到较低的预测概率对各类的求和概率进行排序。这给了我第一次选秀权,第二次选秀权和第三次选秀权。最后,我记录了模特的第一次选择和第二次选择是否正确(见上图)。我对结果非常满意,可以在这里找到:

多类模型:只有 multiclass_binusd 模型和 multiclass_colrs 预测模型在第一次挑选时效果不错,得分几乎达到 80%。然而,他们在第一次或第二次选股时都表现不错(见最后一栏)。

  • 回归模型。最后,对于这些数字预测模型,其中我们预测了转换的法力成本**(法力值)和美元/欧元/TIX 的价格,我计算了平均绝对误差(MAE) 。这些是结果:**

数字模型:欧元价格预测的 MAEs 最低,尽管欧元价格通常低于美元价格。每张卡小于 1.00 的平均偏差并不惊人,但可以接受。对于 CMC 来说,小于 1.00 法力值的偏差也不惊人,但可以接受。

有趣的发现

我选择了一些没有被模型正确分类的预测,试图解释它们,因为每次模型失败,都是评估模型被混淆的卡片发生了什么的机会。很多时候,它会导致有趣的解释:

**蓝色二元模型预测蓝色的概率为 0.55。我知道为什么它会是蓝色的,因为抽牌。**图片来自 Scryfall API。作者:山姆·瓜伊。2021 海岸巫师

**二元蓝色模型预测的蓝色概率仅为 0.17,而二元黑色模型预测的黑色概率为 0.67。需要从你的坟墓场驱逐一个生物的僵尸可能绝对是黑色的。**图片来自 Scryfall API。作者:伊戈尔·基里卢克。2021 海岸巫师。再来看看 app 里对同一张卡的另一个预测:

**其中两个模型预测这张卡片是黑色的,而另一个模型预测是绿色的。需要从你的坟墓场驱逐一个生物的僵尸可能绝对是黑色的。从你的坟墓场驱逐它的最后一个效果是让你抽一张牌,我明白为什么它会是一个绿色的效果了。**图片来自 Scryfall API。作者:Igor Kieryluk。2021 海岸巫师

**在这种情况下,我们的多类模型预测 Falkenrath 庆祝者首先是不常见的,然后是常见的。我认为这完全有道理,因为卡做了很多事情。4/4 换 5 点法力,带威胁,把 2 个血令牌放到战场上是惊人的价值。这是有限的最好的公地之一。**图片来自克里福尔 API。作者:安娜·斯坦鲍尔。2021 海岸巫师

还记得我们之前制作的卡片吗?让我们快速起草它,看看我们的应用程序预测什么颜色:

应用程序预测它首先是一个蓝色法术,其次是一个红色法术。这是非常准确的!来自 Scryfall API 的图像

同样,评估该型号的最佳方式是使用应用程序亲自动手!

再来看一下链接:

https://share . streamlit . io/gabrielpierobon/magic aimodels/main/app . py

Web 应用程序开发:注释

  • ****为胜利而简化!这个网络应用程序是使用 Streamlit 构建的,它功能强大却简单易用。我怎么推荐都不为过!
  • ****免费!我免费使用 Streamlit Cloud 托管应用程序!
  • ****开源!这个应用的代码在我这里的 GitHub 上:https://github.com/gabrielpierobon/magicaimodels

结论和后续步骤

我非常高兴和满意,尤其是对过程**,对结果和最终产品(应用程序)也是如此。我在一个个人项目上度过了一段美好的时光,这个项目涉及到我喜欢做的事情和我擅长做的事情。这真的很令人兴奋,也是一种惊人的成就感。**

事实上,我们可以将卡片上的信息转换成有用的数据,并训练一台机器来识别模式并做出预测,这太令人兴奋了!

我仍在计划如何在 2022 年发展这项技术,并与社区分享,看看它能产生多大的影响,能对未来的进一步研究产生多大的影响。

至于结果,我认为它们非常好,但我也能看到它们如何能变得更好。这里有一些关于这个主题的注释:

  • 更好的算法。我们可以使用更强大的算法,比如 XGBoost、LightGBM 等。
  • 更 tunning 。我们可以花更多的时间在模型调试阶段,我没有时间去做。
  • 变形金刚。我们可以通过使用 BERT 进行迁移学习来将 NLP 模型提升到下一个级别,并根据魔域对其进行定制。这太不可思议了。
  • 更多数据。我们可以得到更好的数据。我很想从其他网站上获得一些关于该卡可玩性的统计数据。这将允许我创建一个列,可以记录一张牌在特定格式下的播放次数。这将会改变一些结果,尤其是价格。

如果有人有兴趣讨论这项研究的内容和成果,你可以在 LinkedIn 上联系我:https://www.linkedin.com/in/gabrielpierobon/

人工智能不会很快取代你的编码工作

原文:https://towardsdatascience.com/artificial-intelligence-is-not-taking-your-coding-job-anytime-soon-5bf0df677ee8?source=collection_archive---------29-----------------------

为什么像 GitHub Copilot 这样的人工智能编码工具不能做你的工作

照片由this is 工程 发自 像素

我曾经担心人工智能(AI)会抢走我的工作,让我失业。

毫无疑问,围绕人工智能的恐惧正在逐年增加。

但是我写代码越久,对机器学习越深入,我就越不担心。

最近,OpenAI 和微软(拥有 GitHub)发布了 Copilot ,这是一个 AI 驱动的结对程序员。

来源:副驾驶

虽然令人印象深刻,但我们离能够自己编写代码的人工智能还很远。

但这并不意味着没有短期影响。

幸运的是,软件工程不仅仅是在电脑上打字。

大多数写人工智能的人都没有写过代码

如果你已经编写了任何一个适度复杂的软件,过时的开发者论点很快就会土崩瓦解。

你知道“写代码”不是开发人员真正的工作。

说“软件工程师的工作是写代码”就像说“作者的工作是写段落”虽然这是真的,但它没有抓住要点。不是任何作者都能写出《权力的游戏》。

编写代码是容易的部分。针对规模进行架构设计、满足客户需求以及处理现有的设计约束要复杂得多。

如今,软件开发人员是建筑师、工程师和建筑工人。但随着我们走向未来,我怀疑我们会更多地看到前者,而更少地看到后者。

繁重的工作正在消亡

像 Copilot 这样的 AI 驱动的编码工具在做什么?

智能生成样板代码。

他们正在移除我们价值最低的任务。比如编写代码来循环数据、创建单元测试以及查找堆栈溢出的答案。

作为开发人员,我们管理的是能源,而不是时间。每一个走神的想法和谷歌搜索都会消耗一点这种能量。优秀的开发人员希望通过解决具有挑战性的问题,而不是编写基本的代码来获得丰厚的报酬。副驾驶帮助他们做到这一点。

这对大多数开发者来说是个好消息。除非你花时间写垃圾应用程序…

我怀疑我们将在未来十年看到一个转变,随着低价值任务的枯竭,开发人员变得更像技术项目经理。

代码的价值会下降

正确生成的代码允许有能力的开发人员在更短的时间内构建更多的技术。

这种价值的大部分将被公司获取。

软件工程师的工资不会少,工作也不会多。他们只会在更短的时间内完成更多的工作。

随着软件开发成本的降低,需求也会增加。

在经济学中,“杰文斯悖论”……发生在技术进步或政府政策提高了资源的使用效率(减少了任何一次使用的必要数量),但由于需求增加,资源的消费率上升。

  • 杰文斯悖论,维基百科

我们可以看到公司用同样的资源解决更多的问题,或者更多的科技公司被创造出来。

成本下降带来新的机遇

您现在可能能够构建那些以前太耗时或太昂贵的辅助项目。

如果建造一件东西花费的时间更少,那么边际效益低的项目现在就变得可行。

以前过于昂贵的机会现在可以追求了。

也许你想构建一个简单的应用程序来聚合一些数据。金钱激励太低,不足以证明 40 小时的努力是值得的。但是现在只需要 20 个小时,你可能会重新考虑。

这同样适用于公司。他们不能在当前工作的基础上追求更低价值的机会。作为一名企业家和程序员,我喜欢这个。

人工智能驱动的编码给未来带来了一些风险

现在,Copilot 生成样板代码。它比现有的代码编辑器更智能。但这对任何人都没有风险。

也就是说,我们必须假设工具会继续改进。如果这是真的,我们可以想象一个有以下问题的未来。

高级开发人才渠道枯竭

我们都是大三学生,只能编写 CRUD 应用程序。但是,当我们不再需要人类来编写这些简单的应用程序时,会发生什么?新开发人员将如何学到足够的知识来提升价值链?

收益只属于最优秀的开发者

在任何职业中,前 1%的人都比其他人赚得多得多。如果顶级开发人员可以完成 10 倍的工作,它可能会消除对其他中等技能开发人员的需求。

无代码工具会把软件变成一个黑匣子

如果我们不再写代码,怎么能理解 AI 正在写的代码呢?我们对使用我们不了解的技术感到舒服吗?

这些是我们作为一个行业和社会在某个时候可能需要面对的长期问题。

最后的想法

这是我不担心 AI 抢走我工作的最大原因。

如果 AI 会写软件,那就已经结束了。所有人都过时了。不仅仅是开发商。

尽管媒体大肆宣传,但没有什么理由害怕人工智能取代你的编码工作。编码主要是一种创造性的职业。就目前的情况来看,神经网络从根本上来说不可能有新的想法。

此外,软件工程师是问题的解决者。我看不到问题的尽头。

因此,尽管技术性失业可能不可避免,但不会持续很长时间。

**剧情转折:**本文由 GPT-4 撰写……开个玩笑。

人工智能专利 101 项

原文:https://towardsdatascience.com/artificial-intelligence-patent-101-3eebf93f5297?source=collection_archive---------30-----------------------

谁在创造专利,你也应该获得专利吗?

天使的小号,作者

专利出版趋势

与人工智能和机器学习相关的专利出版物继续以惊人的速度增长,现在美国专利局每年的申请量接近 10 万件。仅在三年前,这个比率接近每年 7 万份申请。使用patentguru.com,我查看了美国专利出版物和专利申请出版物标题中的下列术语的出现频率:“机器学习”或“机器学习”或“数据分析”或“分析”或“计算机程序产品”或“人工智能”或“数据科学”或“神经网络”由于只审查了专利标题,而没有审查专利正文,所以包括了更一般的术语“分析”和“计算机程序产品”。

有可能包含少量非人工智能/人工智能专利,但人工检查产生的专利确定这些搜索词给出了良好的结果。专利的最大受让人是 IBM,其次是高通、三星、英特尔、微软、谷歌、华为和苹果。

专利是如何组织的?

专利需要被归入一个特定的类别。这些类别是很久以前创建的,那时计算机工作产品还不需要一个类别。出于这个原因,你会发现大多数美国专利局 ML/AI 类型的专利在类别 G:物理学中,但是它们可以在任何类别中找到,这取决于发明应用的领域。

答:人类的必需品

b:执行操作,运输

化学、冶金

d:纺织品、纸张

e:固定结构

机械工程,照明,供暖,武器

物理

h:电力

如何获得特定类别专利的更多信息

在每个类别中有子类,G06F 是美国专利局 ML/AI 专利中最常见的。

使用 www.patbase.com 的,我查看了类别 G06N 上的信息。这是我最近提交了机器学习专利申请的一个类别。这里的结果是针对该类中的所有专利和应用,而不仅仅是机器学习相关的专利和应用。

G06N 的 PatBase 分析结果

基于特定计算模型的计算机系统类别的最大受让人是 IBM,其专利数量是紧随其后的受让人微软、谷歌和三星的两倍。在这次评估中,我并不局限于美国专利,因此您将看到全球受让人的分布情况。

这些申请中有许多是中国的专利,其次是美国的专利。

在 2020 年和 2021 年,所有国家的 G06N 专利申请数量都在大幅增长。这只是机器学习和人工智能专利可以申请的多个类别之一。

我如何写我自己的专利?

你不知道。你的专利律师会帮你做的。只有专利律师或非常敬业的发明家才会尝试写专利。你的公司可以聘请专利律师来帮助你,如果他们致力于他们的知识产权专利的概念,并希望保护你的项目。成本不是微不足道的,而且完全有可能你的公司可能更愿意将你的工作作为“商业秘密”而不是申请专利。假设你的专利是与雇主相关的工作,你的名字会出现在专利上,但专利的“受让人”将是你的雇主。

出版你的作品,而不是追求专利,是另一条可以选择的道路。如果目标是建立作为专家的声誉,以及传播一般知识,而不是对作品的具体保护,这可能是更可取的。

为了继续为你的作品申请专利,你需要能够证明你的作品是新颖的、非显而易见的和有用的。你应该创建文档,用通俗的语言解释你的发明。它应该清楚地解释你的作品,以及你试图保护作品的哪一方面。你不能给抽象的概念申请专利,你的发明必须有实际应用。你的律师将能够搜索“现有艺术”来证实你的主张。虽然您也可以搜索“现有技术”,但请记住,您需要披露您在此类搜索中的任何发现。当专利被撰写时,它将包含确切的“权利要求”。这些权利要求准确地描述了你的发明是由什么组成的,是专利最重要的部分。他们还将决定你的专利应该提交给哪个类别和子类,以及你将提交的专利类型。

看到你的发明被解析成连你自己都难以理解的法律术语,并伴随着不熟悉的图表,你可能会有点迷惑。显然,这正是专利局正在寻找的,所以在这一点上,你需要相信你的律师。你还需要确保他们在撰写时已经清楚地理解了你的发明,并且权利要求确实代表了你试图申请专利的内容。不同的权利要求可以与不同的发明人相关联,因此您可以在这里指定哪个发明人对整个发明的各个方面做出了贡献。

我能从我的专利中赚钱吗?

大概不会。此外,你的雇主可能也不会从中赚钱。专利可以用来增加公司的内在价值,并证明其作为创新领导者的地位,即使具体专利没有实际的货币价值。此外,专利保护你的产品不被别人申请专利。许多专利申请都没有具体的计划来将受保护的发明货币化。

美国专利商标局的新人工智能数据

美国专利局最近发布了一个关于人工智能相关专利的数据集。该数据集是基于一种比本文所用的更全面的专利分类方法编制的。在下一篇文章中,我将讨论这个新数据和专利局发布的相关发现。

人工智能:人类的未来

原文:https://towardsdatascience.com/artificial-intelligence-the-future-of-mankind-46aaf6b4b87f?source=collection_archive---------17-----------------------

人工智能|未来|技术

为什么人类需要人工智能

安迪·凯利在 Unsplash 上的照片

据我们所知,世界上很少有行业能够改变世界。人工智能(AI)在这份名单中占据主导地位。人工智能在我们生活的几乎每个方面都有应用。它彻底改变了我们的生活方式,而我们中的大多数人甚至不知道它,而且它不会很快放缓!那么,为什么人工智能对我们变得如此重要?我们为什么需要 AI?

我们都看过好莱坞对人工智能的描述。好莱坞倾向于将 AI 戏剧化为邪恶或恶棍。总有某种邪恶的人工智能准备接管世界。这是我们注定的未来吗?是人类对抗机器吗?我不这么认为。

问一个 GPT 3 聊天机器人这个问题,我们得到如下回答:

[作者捕获的图像] GPT-3 人工智能对作者所提问题的答复

“AI 可以成为我们的朋友。”—比尔·盖茨

现实是人类需要 AI 才能生存,反之亦然。作为一个种族,我们已经取得了如此大的进步,以至于我们现在需要人工智能来扩展我们的智力,激发我们的创造力。我们已经能够建造巨大的东西。任何有电脑和互联网连接的人都可以阅读这篇文章。这多不可思议啊。

人工智能在学习模式和自动化任务方面非常出色。人类是有创造力的,并且拥有普通智力和情商——至少我们中的一些人是这样。两者都是任何 AI 都无法拥有的技能。这就是为什么人工智能将使我们能够达到更新的高度。已经发生了。我们有自动驾驶汽车和机器人制造。人工智能增强了人类的工作能力。这允许更大更快的创新。通过人工智能,人类将变得更聪明,更强大,甚至更有效率。人工智能会提升我们。人工智能将帮助我们维系生命。

马特·帕尔默在 Unsplash 上拍照

卡尔·本茨于 1886 年 7 月 3 日推出了第一辆汽车。它的最高时速高达 16 公里[1]。2020 Koenigsegg Jesko Absolut 的速度达到 531+km/h。这款车利用了先进的人工智能半导体和许多传感器[2]。100 年前,要给某人发信息,你必须写一封信并寄出去。今天吗?拿出手机,发送即时消息。技术激发创新。科技让我们从不同的角度重新发现我们周围的世界。

“人工智能的目的是重塑人类思维”——克里斯·达菲

到 20 世纪 90 年代初,百视达已经开了第 1000 家店[3]。2010 年,百视达宣布破产。为什么?因为有人试图重新设计电影租赁业务。现在,网飞的神经引擎每月处理超过 60 亿小时的观看时间[4]。亚马逊动摇了巴诺和优步与传统出租车服务的竞争。

即使是银行也面临来自 Revolut 等金融科技解决方案的竞争。为什么这些公司能够打败老牌巨头?简单。行业颠覆和创新。人工智能为终端用户定制产品提供了一系列数字机会。人工智能的优势不仅允许我们经济的自然进化,也允许我们生活质量的自然进化。这引出了我的下一点。人工智能提高了我们的生活质量。

扎卡里·尼尔森在 Unsplash 上的照片

人工智能在为我们实现自动化方面很棒。我们可以花更少的时间在单调上。人工智能也让复杂的任务变得不那么复杂。在制造业,工厂使用机器人机械来完成所有的重物提升。这为工厂工人节省了多年的健康时间。

此外,人工智能系统从来不会请病假。他们没有家庭或个人问题,他们总是表现出同样的水准。仍然需要维护干预;尽管如此,工厂工人承担的劳动密集程度较低的角色。这使得工作流程更加高效和一致。人类是大脑,人工智能是肌肉。人工智能为汽车提供动力并增强芯片组的性能。人工智能是许多改善我们生活状况的软件应用的核心。

一个很好的例子就是像 Alexa 和 Siri 这样的人工智能助手的概念。我们的愿望就是他们的命令。人工智能还应用于一些数据密集型应用,如打击金融犯罪[5]。在这里,我们可以利用人工智能的速度和模式识别技能来检测欺诈。

“我想象一个人工智能将使我们工作更有效率、寿命更长、能源更清洁的世界。”—费·

人工智能还揭示了日常偏见。人工智能系统通过处理几个数据示例来学习任务的解决方案。如果我们将有偏见的数据传递给 AI,那么 AI 将学习我们问题的有偏见的表示。人工智能将学习模仿传递给它的观察结果。这种人工智能偏见不幸进入现实世界的一个例子发生在 2019 年[6]。美国医院使用人工智能来预测哪些病人需要额外的医疗护理。人工智能系统后来被发现有种族偏见。不同的种族有不同的医疗费用,这导致了代表性不足的种族。

那么,AI 是如何挑战我们的?这种偏见引发了对医疗保健领域潜在种族歧视的调查。现实世界中偏见无处不在。特别是在社会应用中,人工智能有助于更好地理解当前的社会关系。人工智能可以揭示我们认为理所当然或忘记它们存在的观察结果。在构建 AI 解决方案的时候,我们也在挑战和提升自己。一步一步来。

“没有人这么说,但我认为人工智能几乎是一门人文学科。这真的是一种理解人类智能和人类认知的尝试。”巴斯蒂安·特龙

参考

[1]http://www . themotormuseumminiature . co . uk/inv-Karl-benz . PHP

[2]https://www.koenigsegg.com/car/jesko-absolut/

[3]https://www . history . com/this-day-in-history/first-blockbuster-store-opens

[4]https://www . pcmag . com/news/us-网飞-订户-观看-32 小时-每天使用-96 GB 数据

[5]d .法鲁吉亚、c .泽拉法、t .西尼等人一种用于网络游戏行业中可解释的网络欺诈检测的实时规定解决方案。 SN COMPUT。SCI。 2、 215 (2021)。https://doi.org/10.1007/s42979-021-00623-7

[6] Obermeyer,z .,Powers,b .,Vogeli,c .,和 Mullainathan,s .,2019 年。剖析用于管理人口健康的算法中的种族偏见。科学366 (6464),第 447–453 页。

想给我买杯咖啡吗?

*https://paypal.me/itsdavidfarrugia?country.x=MT&locale.x=en_US *

想联系吗?

我很想听听你对这个话题或任何人工智能的想法。如果你想联系我,请给我发电子邮件到 davidfarrugia53@gmail.com,或者通过下面的我的社交网站联系我。

Linkedin——Twitter

使用 PySpark 的人工神经网络

原文:https://towardsdatascience.com/artificial-neural-network-using-pyspark-324cf47e8d0a?source=collection_archive---------15-----------------------

使用 PySpark 实现用于二进制类预测用例的神经网络

简介 :
这是 Pyspark 博客系列的延续。之前我已经分享了使用 PySpark 实现一个基本的线性回归。在这篇博客中,我将展示另一个有趣的神经网络实现,它使用 PySpark 作为二进制类预测用例。这篇博客不会有很多预处理步骤,但是会给你一个实现分布式环境的想法,特别是当你在数据块中的集群中运行代码的时候。对于 Databricks 环境,如果您想利用 TensorFlow, horovod 对此太方便了,或者您也可以参考分布式 tensorflow 。但是如果你在业界工作的时候在 GPU 集群上面使用 Horovod 还是推荐的。然而,我将使这篇博客过于精确,以至于读者无法理解 pyspark 的神经网络实现方式。

欢迎,让我们深入主题。

我拍了一张钞票认证数据集。数据集中有 5 列,如 f1、F2、F3、F4 作为特征,Class 作为标签。

多层感知器分类器:

media.istockphoto

为了在 PySpark 中实现一个神经网络,我们可以使用多层感知器分类器。超级好用,从 pyspark.ml.classification 导入即可基于前馈人工神经网络。输入层中的节点表示输入数据。其余节点通过输入与节点权重**w**和偏差**b** 的线性组合以及应用激活函数,将输入映射到输出。这可以表示为:

具有 K+1 层的 MLPC 的矩阵形式

特点:

  1. 它基于多层感知器。

2.Sigmoid 激活函数用于每一层,Softmax 激活函数用于输出层。

N 表示类别的数量

3.它使用逻辑损失函数进行优化,使用求解器 L-BFGS 进行优化。但是你可以另一个像 gd 这样的求解器。

gd 代表梯度下降算法。

l-bdgs 代表有限内存 Broyden–Fletcher–gold farb–Shanno 算法

缺点:

当您使用 Tensorflow 或 PyTorch 定义 ann 时,它缺少定制功能。

阅读更多关于 scikit learn 实施的信息。

实施

加载数据集:

dataset = spark.read.csv(“data_banknote_authentication.csv”,header=True)

我的电脑

通常,当您使用 pyspark 导入数据时,如果模式不是预定义的,它将采用 string 类型。现在让我们将列类型转换为 double 类型。

for col in dataset.columns:
    dataset = dataset.withColumn(col,dataset[col].cast('double'))

有几个空值。所以让我们用平均值来估算。

imputed_col = ['f_{}'.format(i+1) for i in range(len(input_cols))]model = Imputer(strategy='mean',missingValue=None,inputCols=input_cols,outputCols=imputed_col).fit(dataset)
impute_data = model.transform(dataset)

我的电脑

在 PySpark 中,在将数据输入模型之前,我们用向量来表示数据。想法是以矩阵格式表示数据,并在 0,1 之间缩放数据。

assemble = VectorAssembler(inputCols=imputed_col, outputCol='assembled_features', handleInvalid='error')
a_data = assemble.transform(impute_data)scaler = MinMaxScaler(min=0.0, max=1.0, inputCol='assembled_features', outputCol='features')
s_data = scaler.fit(a_data).transform(a_data)

我的电脑

现在,让我们将数据分为训练和测试数据集,定义模型,并将训练数据放入模型中。我用过的网络层是 4,16,2

4 是因为有 4 个不同的输入要素,2 是输出图层,因为它是二元分类。

train_df,test_df = s_data.select('Class ','features').randomSplit([0.7,0.3],1213) mlpc=MultilayerPerceptronClassifier( featuresCol=’features’,labelCol=’Class ‘,layers = [4,16,2],\
 maxIter=1000,blockSize=8,seed=7,solver=’gd’)ann = mlpc.fit(train_df)

一旦完成。你可以检查一下准确性。使用方法 multiclasssclassificationevaluator()。

现在转换测试数据,并在 evaluator 方法中定义精度,如 f1、精度等等。

pred = ann.transform(test_df)
evaluator = MulticlassClassificationEvaluator(labelCol='Class ',predictionCol='prediction',metricName='f1')
ann_f1 = evaluator.evaluate(pred)
ann_f1

运行 1000 次迭代后,f1 值为 0.8309986610958963。

结论:

尝试使用不同的数据集,如带超参数调整的 mnist 数据集,并检查模型性能。请在评论区告诉我你的想法。你可以在这里访问代码和数据集。

我会带着另一个有趣的话题回来,在那之前祝你阅读愉快!

请在评论区分享你的想法。你可以在 Linkedln 、 Gmail 上帮我联系。

作为新手:我了解到在 Python 中使用配置文件可以使开发更高效

原文:https://towardsdatascience.com/as-a-novice-i-learned-that-using-configuration-files-in-python-makes-development-more-efficient-29c75b4eabd5?source=collection_archive---------10-----------------------

查看使用配置文件时的区别

费伦茨·阿尔马西拍摄于 Unsplash

介绍

在理解配置文件之前,我的脚本通常非常长,重复,低效。此外,每次变量发生变化时,我都会花大部分时间在脚本的不同部分进行更改,这非常耗时。然后我注意到其他人正在使用配置文件作为他们开发的一部分,我也开始探索和实现它们,我意识到当使用配置文件时,事情变得更加高效、灵活和有组织

那么什么是配置文件呢?

  • 配置文件允许我们配置参数和初始设置。
  • 配置文件的格式可以是— yaml ,ini,json,xml

配置文件通常用于存储敏感信息,如数据库凭证、密码、服务器主机名、管理参数等。

在本文中,我将分享在机器学习项目中使用配置文件与不使用配置文件的区别。我们将使用的配置文件格式是 YAML 格式。代表另一种标记语言的 YAML 被选中,因为它没有诸如大括号和方括号之类的格式,这使得它因可读性和易写性而受欢迎。

这个用例中的场景是基于不同的预建模型执行评分(预测)。每个模型需要不同的数据集来执行预测,但源表是相同的。下图说明了构建所需的过程:

用例场景说明

评分流程概述:

  • 有两个模型:Model_A 和 Model_B,它们已经基于不同的数据集预先构建,但是是从相同的 features 表中检索的。
  • 为模型 A 准备评分脚本,根据数据集 A 进行预测,并将预测结果推送到数据库中。
  • 为模型 B 准备评分脚本,根据数据集 B 进行预测,并将预测结果推送到数据库中。

(在这个用例中,开发的模型基于从 Kaggle:超市销售数据集)

现在,让我们来看看如何实现配置文件,以及不使用配置文件时的比较。

带有配置文件的评分脚本:

首先,让我们看看 YAML 的配置文件是什么样子的。下面是一个配置文件 (model_A.yml) 的示例,它指定了模型 A 执行模型预测所需的段、模型文件名和列。

然后,我们将加载并读取 YAML 文件,作为评分脚本的一部分。下面是一个使用 python 加载 YAML 文件并读取配置文件中的值的示例。注意,配置文件名是用变量***“+模型+”指定的。yml* 而不是*" model_A.yml "***因为我们有多个 YAML 文件要加载到脚本中(model _ a . yml,model_B.yml)。用这种方法指定允许我们为不同的模型重用相同的脚本。

*config_file = ""+model+".yml"with open(config_file, "rb") as file:
        config = yaml.load(file)segment = config['segment']
model_file_name = config['model_file_name']
columns = config['columns']*

在我们的评分脚本中,配置变量在两个不同的区域被调用:

*(1) **配置变量[' segment ']&[' columns ']*用于从 Google Big Query 中检索模型 A 所需的数据集

*client = bigquery.Client()
table_id = 'sales_data.superstore_sales_data_processed'
sql = "SELECT **{columns}** FROM `sue-gcp-learning-env.sales_data.superstore_sales_data_processed` where segment = ? and year_week = ?;".format(**columns**=",".join(**columns**))job_config = bigquery.QueryJobConfig(
        query_parameters = [
            bigquery.ScalarQueryParameter(None, "STRING" , **segment**),
            bigquery.ScalarQueryParameter(None, "INTEGER" , int(year_week))
        ]
    )*

(2) 配置变量['模型文件名称'] 用于调用加载模型的 pickle 文件

*pickle_file_name = **model_file_name**
with open(pickle_file_name,'rb') as pickle_model:
     model = pickle.load(pickle_model)*

现在让我们看看我们最终的评分脚本是什么样子的:

要为模型 A 或模型 B 运行我们的评分脚本,我们可以调用带有指定参数的函数。(型号 _A /型号 _B)。例如,在下图中,通过传递与 YAML 文件(model_A.yml,model_B.yml)同名的参数,可以使用相同的评分脚本为模型 A 和模型 B 运行。

调用评分脚本函数

没有配置文件的评分脚本:

现在让我们看看不使用配置文件时的区别。在下面的脚本中,请注意变量是基于模型 A 所需的细分值硬编码的— 细分=‘消费者’

*client = bigquery.Client()
    table_id = 'sales_data.superstore_sales_data_processed'
    sql = "SELECT * EXCEPT(total_sales) FROM `sue-gcp-learning-env.sales_data.superstore_sales_data_processed`  where **segment = 'Consumer'** and year_week =?"job_config = bigquery.QueryJobConfig(
        query_parameters = [
            bigquery.ScalarQueryParameter(None, "INTEGER" , int(year_week))
        ]
    )*

此外,模型 A 的模型文件名也是硬编码的

*pickle_file_name = **'model_A_consumer.pkl'**
with open(pickle_file_name,'rb') as pickle_model:
    model = pickle.load(pickle_model)*

下面是没有配置文件的最终脚本。现在,该脚本只显示了一个模型,如果我们将这种方法用于模型 B,它将是模型 B 变量被硬编码的脚本的副本。随着我们有越来越多的模型,脚本将继续复制。例如,如果我们有 10 个模型要执行评分,并且没有引入配置文件,那么我们的脚本将是下面脚本长度的 10 倍。

如果您想查看包括型号 B 的配置文件在内的完整代码,可在 Github 上找到。

结论:

将配置文件作为软件开发的一部分来添加,使事情更易于管理,并且无疑使我的生活更加轻松。在我目前的项目中,我们有数百个模型要开发和评分。如果我对所有东西都进行硬编码,将会花费大量的时间,并且可能会达到无法控制的程度。我很高兴我意识到了使用配置文件的重要性,并希望这篇文章可以帮助任何人在他们的下一个项目中开始使用配置文件。

引用&链接

[1]https://www . analyticsvidhya . com/blog/2021/05/reproducible-ml-reports-using-YAML-configs-with-codes/

[2]https://medium . com/analytics-vid hya/how-to-write-configuration-files-in-your-machine-learning-project-47bc 840 ACC 19

[3]https://www.kaggle.com/rohitsahoo/sales-forecasting

https://www.tutorialspoint.com/yaml/index.htm

AutoML 是不够的,最好的分析仍然需要人

原文:https://towardsdatascience.com/as-organizations-try-and-empower-democratized-analytics-they-must-consciously-recognize-where-3c73398a9065?source=collection_archive---------44-----------------------

减少对编码的需求和向更广泛的受众展示数据并没有使探索数据时对人类直觉的需求失效。

让我们从肯定 AutoML 工具的威力开始。任何用户,无论技术能力如何,现在都可以在几分钟内建立模型,而以前需要专家数据科学家使用数百行 Python。AutoML 加速了逐步完成特征工程的过程,尝试许多不同的算法,调整参数,并最终确定一个准确的模型。

因此,它已经成为数据科学民主化的重要支柱,因为它从可生产模型的奖励中抽象出编码和算法函数调用。在 Einblick,我们亲眼目睹了我们的 AutoML 工具如何让非技术分析师和运营经理开始用精确的模型取代“直觉”。

但是对我们来说,AutoML 代表了一种工具上的增强,以实现加速模型构建和数据科学民主化的目标。然而,它不是一根魔杖,一挥就能立刻创造出数据科学。一个更现实的类比可能是,自动化工具是电动开罐器。它们可以解放双手使用,比手动启动更快更干净地完成目标。

因此,对组织领导的一个重要提醒是,不要过度投资于技术自动化解决方案,而是应该更多地投资于人和过程。

1。领域知识提高了投入

基本的特征工程和数据清理工具已经融入了大多数 AI / ML 工具。领先的 AutoML 平台(简单而无耻地宣传我自己的产品, Einblick here ) 将包括一组类似的候选转换,包括一次性编码(分类变量到 1/0)、插补、缩放、比率、NLP 文本特征提取。然而,这些方法是一种“看棍子”的方法。

然而,基于人类的领域知识具有一些比较优势,这些优势增强了自动特征工程,包括以下内容:

  • 对模式的真实世界激励变化的检测:人类可能识别出数据集的变化,其代表发生的可命名事件。例如,组织启动了一项新计划、发生了战略转移、发生了自然灾害、发生了金融危机等。该模型只能从数据中的低级统计模式所揭示的信息中进行推断。而人类的直觉依赖于大量的额外知识来解释数据。
  • 基于期望值的异常值识别:AutoML 算法可能能够识别 3 个标准差之外的变量,并消除它们。然而,与上面类似,理解价值观是否合法是人类的任务。以一家零售银行为例:900 分的信用评分似乎是可行的,但不在标准评分 300-850 分的可能范围内。相比之下,100 万美元的支票账户很少,比平均水平高得多,但我们马上知道这是可能的。领域知识允许分析师对无关值是否合法进行分类。
  • 智能和可解释的数据转换:一个经典的例子是体重和心脏病发作之间的关系。虽然[体重与[心脏病发作正相关,但更好的预测可能是[体重/[身高],因为非常高和重的人可能仍然健康。更多的专业知识可以告诉你,分母的平方就是身体质量指数——这是一个常用的指标。

2。可解释性工具必须创建讨论,然后是迭代

模型只有在实现时才有帮助。通过能够清楚地传达模型正在做什么,解决问题,并解决关于输入驱动因素和输出影响的任何分歧点,可以赢得认同。

AutoML 确实有一系列可用的模型解释功能,从对变量重要性进行排序和让用户处理数据,到部分依赖图和独立条件期望的可视化。但这些是数据科学家的工具。它们没有帮助传播信息,也没有向与分析相关的广泛的利益相关者解释模型。团队和工具必须超越固定的包,以促进涉众更好地理解来驱动迭代:

  • 预测结果的描述性可视化:虽然有用,但代表最佳模型可解释性工具的预装箱输出需要对过程的信任而不需要理解,或者潜在地需要太多先前的数据科学知识。相反,实际的描述性分析应该在模型上运行。价值是否有意义,细分是否如我所料存在,当我可视化针对关键驱动因素的预测时,是否有任何无法解释的模式,等等?被确定为重要的变量可以通过驾驶员分解的目标响应变量的快速标准化直方图来确认。
  • 快速评估变更的影响:模型需要一次又一次的运行。基于这些结果,用户应该能够灵活地跳回到数据流任务来扩充数据集,转向描述性的视觉效果来检查假设,或者只是重新运行没有坏变量的模型。AutoML 工具是找到好模型的好方法,但这并不意味着它们足以一次性解决问题。

总之,不要只关注自动模型,而忽略了在模型创建后与数据进行人工交互的需要。许多 AutoML 工作流隐含地断言“信任我们”如果模型的统计数据看起来不错,并且是由智能工具生成的,那么实现它肯定是有意义的!数据科学的民主化并不意味着用户应该放弃创建易于理解和解释的模型。

原载于 https://einblick.ai/automl-not-enough-citizen-data-science/ Einblick:

尝试一种新的、更加动态的方式将 AutoML 集成到您的数据科学工作流中https://einblick.ai/try-einblick/

问我任何关于矢量搜索的问题

原文:https://towardsdatascience.com/ask-me-anything-about-vector-search-4252a01f3889?source=collection_archive---------20-----------------------

本杰明·苏特在 Unsplash 上拍摄的照片

今年的柏林流行语特别关注搜索的未来——向量搜索,以及其他真正酷的话题,如扩展卡夫卡,使用 Opentelemetry 的分布式系统跟踪以及提高工作满意度。一些致力于向量搜索主题的会议包括一些令人印象深刻的密集检索技术的演示,以支持在你的文本湖中回答问题。

在问我任何问题:矢量搜索!会议 Max Irwin 和我讨论了矢量搜索的主要话题,从它的适用性到它与优秀的 ol' sparse search (TF-IDF/BM25)的比较,到它在黄金时间的准备情况以及在向用户提供它之前哪些具体的工程元素需要进一步调整。如果你对矢量搜索感兴趣,你可以从阅读我写的关于这个主题的一系列博客文章开始:在 Solr 、 Lucene 和 Elasticsearch 中,跳转到 GitHub repo (在会议期间,我有与会者联系我,分享他们使用它运行内部演示——所以你也可以这样做)。

更新:AMA 会议的录音在这里:

链接:https://youtu.be/blFe2yOD1WA

https://www.youtube.com/watch?v=blFe2yOD1WA

对于这篇博文,我决定从友好的互联网观众中挑选 3 个最重要的问题(我们在活动前圈了一份在线表格,以收集一组关于矢量搜索的非常有趣和深刻的问题),并给出我的部分答案,稍微扩展一下(并在可能的情况下增加论文和代码)。

我们从研究和工业两方面看到了密集检索领域出现的一些模式。你对密集检索的下一步有什么想法?事情将走向何方,人们需要做些什么准备?

这里有一篇来自谷歌研究的最近的论文,关于在字节级上训练嵌入模型,这将有助于解决拼写错误查询的各种令人生畏的问题。另一篇论文应用傅立叶变换来提高 BERT 的速度:快 7 倍,准确率 92%。因此,社区正在解决嵌入带来的各种问题,这将推动密集检索/重新排序和矢量搜索的进一步发展。需要注意的一点是,这些模型是否通用化,根据 BEIR 的基准测试论文,密集检索方法不能很好地通用化。只有当模型已经为相同的领域训练时,它们才会击败 BM25。相比之下,最快的方法是基于重排序的,如 ColBERT,但有一个条件:准备多分配 10 倍的磁盘空间来存储索引,而不是 BM25 索引(具体数字:900 GB 对 18 GB)。当谈到将前沿研究产品化时,除了考虑神经搜索如何与当前的搜索解决方案共存之外,您还需要整体评估特定搜索方法对可伸缩性、搜索速度、索引足迹的影响。你还允许预过滤吗?用户对他们在屏幕上看到的结果有发言权吗?你的 UX 会平稳地支持这种搜索引擎模式的转变,并在转变过程中保持用户效率与当前水平相当吗?

此外,当您考虑为您的域构建矢量搜索块时,请仔细选择相似性度量:余弦度量在排名中倾向于较短的文档,而点积则倾向于较长的文档,因此可能需要这些度量的组合,甚至是动态度量选择过程。这可以追溯到仔细设计整个搜索栈和/或选择搜索供应商。矢量搜索的总体性能是一个尚未解决的问题,所以你需要寻找最适合你的搜索引擎的模型配置,不要太在意大玩家报告的误差幅度。我也可以推荐阅读一些好的调查论文,比如 https://arxiv.org/abs/2106.04554 的文章。对于那些想在十亿规模数据集上练习并了解现有人工神经网络算法的能力和局限性的人来说,作为 NeurIPS 2021 的一部分,有一个出色的大型人工神经网络竞赛宣布。

许多 ML 应用程序在简单的 web 服务后面使用 faiss/airy/NMS lib 进行人工神经网络检索,例如在推荐系统中。这对于简单的应用程序很有效,但是当需要有效的过滤时,你似乎需要跳跃到一个成熟的搜索系统(elastic,vespa 等)。你认为“faiss plus filter”工具有没有用武之地,或者你认为像 vespa 这样的搜索系统带来的额外好处能够弥补它带来的额外复杂性吗

D 不同的供应商提供了不同的构建人工神经网络指数的方法。在 Elasticsearch 世界里,你有两个选择:

  1. 实现 LSH 的 Elastiknn 插件。
  2. 用 HNSW 方法实现堆外图搜索。

Elastiknn 支持使用字段过滤器对结果进行预过滤,如颜色:蓝色。OpenDistro 通过重用 Elasticsearch 熟悉的功能来实现预过滤,比如脚本评分和无痛扩展。顺便说一句,我在以前的博客文章中试验了这两种方法(在开头提到过),并实现了索引和搜索组件来演示这两种实现。

无论您选择哪种方法,您都需要仔细选择超参数,以便在索引速度、召回率和消耗的内存方面获得最佳性能。HNSW 可以很好地扩展到多核架构,它有一系列启发式算法来避免局部极小值,并且它可以构建一个连接良好的图。但是在 Lucene 中为每个段构建一个图在 RAM 和磁盘使用方面可能会变得非常昂贵,所以您应该考虑在服务查询之前将段合并成一个(所以考虑一下为这样的优化分配比纯 BM25 索引更多的时间)。我认为将过滤和人工神经网络结合起来作为搜索的一个单一阶段是一个明智的决定,因为多步检索可能会遭遇速度慢或召回率低或两者兼而有之的问题。此外,当用户预先知道该特定搜索将可能产生非常大量的文档作为回报时,他们可能想要控制文档空间的边界(例如,像工业研究或专利现有技术调查)。

这是一个内容长度“最佳点”吗?密集向量比稀疏向量(普通 tf*idf)有明显优势。

在你的领域专家团队的帮助下,你可以通过更加关注长文档中的内容来解决这个问题。第一段和第二段最重要吗?文档中的特定章节对于特定的信息需求是否重要?如果是的话,让它们被注释掉重要性和语义角色,并加载到多字段倒排索引中,使用 BM25 作为基线。顺便说一下,在衡量搜索质量时,你可以重复使用行业标准,如 DCG@P、NDCG@P、AP @ T——选择合适的评分者来优化搜索质量本身就是一门艺术,但如果你想开始,请前往 Quepid(使用托管的或本地部署——纯开源),将其连接到 Solr / Elasticsearch,并开始使用评分查询来了解你当前的搜索质量。相信我,这项投资将会有回报,并产生大量改进的想法,从而使你的搜索引擎更具结构性。这是我今年用 Quepid 为学生做的电影搜索的现场演示:https://www.youtube.com/watch?v=OOYsWn3LWsM&t = 1068s

密集检索有一个 512 个单词的自然限制,超过这个限制,无论是在索引速度方面,还是在一个长文本可以压缩成什么语义方面,该模型的性能都不会很好。"所有的神经方法都有文档长度的限制,因为它们有 512 个单词的限制."——来自 BEIR 纸业。

在 AMA 会议期间,观众提出了更多的问题。请观看录像,了解更多信息,享受矢量搜索的乐趣!

使用 Haystack 上的长格式问题回答来问维基百科 ELI5 类的问题

原文:https://towardsdatascience.com/ask-wikipedia-eli5-like-questions-using-long-form-question-answering-on-haystack-32cf1ca6c00e?source=collection_archive---------18-----------------------

使用你的文档和 26 行 Python 代码构建一个长形式的问题回答平台

基于自然语言处理的问答系统的最新进展是惊人的。QA 系统建立在最新的语言模型(BERT,RoBERTa 等)之上。)可以相对轻松且精确地回答基于仿真陈述的问题。该任务包括找到包含答案的相关文档段落,并通过扫描正确的单词标记范围来提取答案。

更具挑战性的问答系统涉及所谓的“生成性问答”。这些系统关注于处理这样的问题,其中所提供的上下文段落不仅仅是所提取答案的源标记,而是提供更大的上下文来合成原始答案。

长篇问答动机

就在上周,我在复习度量学习,突然想到它和对比学习有一些相似之处。我当时没有时间去做一次深潜来满足我的好奇心,尽管我很想这样做。一个问答平台,我可以问,“度量学习和对比学习的主要区别是什么?”通过迅速提供一个可靠的、详细的答案,会使这个话题变得迅速而富有成效。

还记得上一次你在谷歌上研究一个特定的主题,进行了几十次查询来寻找相关的网页结果,随后,自己煞费苦心地合成了一个长达一段的答案吗?如果 QA 系统能自动为你做这件事会怎么样?

长格式问题回答(LFQA)系统试图复制和自动化这一艰巨的活动。由于这些 QA 系统相对较新,研究人员在一个公开可用的数据集上为它们训练模型——Eli 5(解释一下,就像我五岁一样)。ELI5 来源于 subred dit/r/explain like im five/,它抓住了综合来自多个网络来源的信息并生成五岁儿童能够理解的答案的挑战。

那么,ELI5 数据集中有哪些问题和答案呢?你可以随意看看 r/explainlikeimfive/ subreddit,或者更好的是,在展会上查看 ELI5 专用的网站。

尽管由 Angela Fan、Yacine Jernite 和 Micheal Auli 领导的脸书人工智能研究团队公开发布了 ELI5 数据集和附带的语言模型,但还没有现成的 QA 平台允许用户轻松定制这样的 LFQA 系统。直到现在。

干草堆里的 LFQA

Haystack 是一个端到端的开源框架,使用户能够为各种问答和语义搜索案例构建健壮的生产就绪管道。从 0.9.0 版本开始,Haystack 支持 LFQA 以及之前支持的 QA 和语义搜索场景。

使用 Haystack 创建自己的端到端 LFQA 管道非常简单。Haystack 上的 LFQA 由三个主要模块组成:文档存储、检索器和生成器。让我们更深入地了解这三个模块,以及它们如何适应 LFQA 平台。

Haystack 中的 LFQA 组件和问答流程。图片由作者提供。

文档存储

顾名思义,DocumentStore 保存您的文档。Haystack 有几种文档存储解决方案可用于不同的用例。对于 LFQA,我们需要使用一个向量优化的文档存储,其中嵌入的文档向量表示我们的文档。因此,在我们的演示中,我们将使用 FAISSDocumentStore,但我们也可以很容易地使用 Haystack 平台上的任何其他向量优化文档存储,如 Milvus 或最近添加的 Weaviate。

取回的人

在为给定的查询生成答案之前,我们的 QA 系统需要找到支持文档。检索器模块的工作是通过计算查询和文档向量之间的相似性来找到最佳候选文档。为了找到与我们的查询最匹配的文档,我们将使用 Haystack 的密集检索器之一 EmbeddingRetriever。检索器首先通过它的语言模型传递查询,以获得查询嵌入。然后,通过比较嵌入查询和文档存储中嵌入文档向量的点积,我们可以快速找到正确的文档并检索它们。

我们将使用已经可用的名为 Retribert 的 BERT 变体,它专门针对这个查询/文档匹配任务进行了优化。Retribert 语言模型在 HuggingFace 模型中心公开可用,其训练的细节可在这里获得。

发电机

在检索器返回与我们的查询最相关的文档之后,我们就可以将选择的文档输入到基于 ELI5 BART 的模型中,为给定的查询生成答案。ELI5 BART 语言模型也可以在 HuggingFace hub 上使用,它具有由 Haystack 的 Seq2SeqGenerator 实现的 seq2seq(例如机器翻译)架构。

为了从检索器找到的支持文档中生成一个很长的答案,我们将查询和支持文档连接起来,并将其作为输入通过 ELI5 BART 模型。模型的输出是我们生成的答案。关于如何训练 ELI5 模型的更多细节,请参考此文档。

LFQA 演示

现在,我们对构建 LFQA 系统所必需的重要组件有了更好的理解,让我们使用 Haystack 来构建和测试它吧!

在本文的其余部分,我们将向您展示如何使用上面提到的现成组件快速创建 LFQA 部署场景。我们将使用 HuggingFace Wiki 片段数据集(来自 100k 维基百科文档的 100 个单词的段落)作为我们 LFQA 系统的源文档。然后我们将使用类似于 ELI5 的问题来查询系统,看看我们会得到什么样的答案。

为了遵循这一部署场景,您可以使用谷歌的合作实验室笔记本进行免费的 GPU 访问。

搭建干草堆

我们将从所需库的 pip 安装开始。在我们的例子中,我们需要的只是草堆和拥抱脸数据集。

初始化文档存储

现在我们已经安装了所需的库及其依赖项,包括 HuggingFace transformers 等等,我们准备初始化我们的 QA 管道。我们将从 FAISSDocumentStore 开始存储我们的文档。

这个一行程序几乎不需要额外的解释。我们将使用 FAISSDocumentStore 的默认风格和“平面”索引。我们需要将 vector_dim 参数初始化为 128,因为我们的 Retribert 语言模型将查询和文档编码成一个 128 维的向量。

将维基百科文档添加到文档存储

在 FAISSDocumentStore 初始化之后,我们将加载并存储我们的维基百科段落。HuggingFace 数据集库提供了一种简单方便的方法来加载像 Wiki 片段这样的大型数据集。例如,Wiki snippets 数据集有超过 1700 万个 Wikipedia 段落,但是我们将流式传输前十万个段落,并将它们存储在 FAISSDocumentStore 中。

现在,让我们对前 100k 个 Wiki 片段进行编写迭代,并将它们保存到我们的 DocumentStore:

现在我们所有的文档都在 FAISSDocumentStore 中,我们需要初始化第二个 Haystack 组件——检索器。对于 LFQA,我们将使用 EmbeddingRetriever,它是用我们简单讨论过的 retriebert-base-un cased 语言模型初始化的。在检索器初始化之后,我们准备计算每个文档的嵌入,并将它们存储在文档存储中。

喝杯咖啡,因为更新 FAISSDocumentStore 中所有维基百科文档的嵌入大约需要 15 分钟。我们可以通过使用专用的 GPU 实例来加速文档嵌入过程,但是,为了演示的目的,即使是 Colab 的 GPU 也可以做得很好。

测试寻回犬

在我们盲目地使用 EmbeddingRetriever 获取文档并将其传递给答案生成器之前,让我们首先对其进行经验测试,以确保示例查询找到相关的文档。我们将使用 Haystack 的预制组件进行文档搜索 DocumentSearchPipeline。当你尝试类似 ELI5 的问题时,不要忘记你只是使用了十万个维基片段中的一小部分。在提问之前,使用下面的管道来确保您想要的主题和文档已经在数据库中。

事实上,DocumentSearchPipeline 确实找到了相关文档:

发电机

LFQA 堆栈中的最后一个组件是生成器。我们将使用 LFQA 的特定模型初始化 Haystack 的通用 seq 2 seq generator——Bart _ Eli 5 模型除了这个模型,我们将使用其他参数的默认初始化值。您可以使用其他 Seq2SeqGenerator 构造函数参数微调文本生成的各个方面。更多细节请参考 Haystack 文档。我们需要做的最后一件事是在一个预定义的 Haystack 管道中连接检索器和生成器 GenerativeQAPipeline。

正如您可能已经猜到的那样,GenerativeQAPipeline 结合了检索器和生成器来为我们的查询生成答案。它代表了与我们构建的 LFQA 系统交互的主要 API。

运行查询

我们将与 GenerativeQAPipeline 进行交互,以获得我们的查询的答案。除了指定查询本身,我们还将对检索器传递给生成器的匹配文档的数量进行限制。这可以是任何数字,但是对于本演示,我们选择将源限制为 4。让我们先问一个类似于 ELI5 的查询:

我们得到以下答案:

🚀🎇这个答案简直令人震惊。它从百慕大单桅帆船的简要说明开始,并继续阐述使其在帆船类别中广受赞誉的特征。

让我们试试另一个:

答案是:

简明扼要。答案不像上一个例子那样详细。但是,我们可以强制模型生成更长的答案。我们需要在 Seq2SeqGenerator 构造函数中传递可选参数 min_length (字数)。

同一问题的新答案是:

太好了,这是我们想要的更详细的答案。随意试验,尝试不同的问题,但不要忘记答案来自我们使用的维基百科的小样本。

ASMNet:一种用于人脸对齐和姿态估计的轻量级深度神经网络

原文:https://towardsdatascience.com/asmnet-a-lightweight-deep-neural-network-for-face-alignment-and-pose-estimation-9e9dfac07094?source=collection_archive---------23-----------------------

本文解释了 ASMNet,这是一个轻量级卷积神经网络(CNN ),用于面部标志点检测(也称为面部对齐)和野外面部姿态估计。

代码和预先训练好的模型可以在 Github 这里获得。你也可以在这里阅读原文。

介绍

面部标志点检测是许多面部图像分析和应用中的基本任务。它对于人脸图像对齐、人脸识别、姿态估计和表情识别至关重要。已经提出了几种方法用于面部标志点检测,例如基于约束局部模型的方法[1,2],AAM [3,4],部分模型[5],以及基于深度学习(DL)的方法[6,7]。尽管基于 DL 的方法被认为是最先进的方法,但是对于具有大姿态变化的人脸,人脸标志点检测仍然具有挑战性。因此,实现高精度的代价是计算复杂性的增加和效率的下降。

此外,包含在特征中的信息分层地分布在整个深度神经网络中。更具体地,虽然较低层包含关于边缘和角的信息,因此更适合于定位任务,例如面部标志点检测和姿态估计,但是较深层包含更适合于分类任务的更抽象的信息。受多任务学习思想的启发,我们设计了我们的 CNN 模型以及相关的损失函数来同时学习多个相关的任务。

最近的方法集中于提高精确度,这通常通过引入新的层、增加参数的数量和更长的推断时间来实现。这些方法在桌面和服务器应用中是准确和成功的,但随着物联网、移动设备和机器人技术的发展,人们越来越需要更准确和高效的算法。

我们提出了一种新的网络结构,它受 MobileNetV2 的启发,专门设计用于面部标志点检测,重点是在不损失太多准确性的情况下使网络变得浅而小。为了实现这个目标,我们提出了一个新的损失函数,它使用 ASM 作为辅助损失,并使用多任务学习来提高准确率。图 1 描绘了我们提出的想法的一般框架。我们用具有挑战性的 300W [8]数据集和野外更宽的面部标志(WFLW) [9]数据集测试了我们提出的方法。我们的实验结果表明,在网络规模比 MobileNetV2 小 2 倍的情况下,面部标志点检测和姿态估计的精度与最先进的方法相当。

ASM 网络

图 1: ASM 网络(图片来自作者)

我们设计了一个比 MobileNetV2 [33]小两倍的网络,在参数和 FLOPs 数量方面都是如此。在设计 ASMNet 时,我们只使用 MobileNetV2 [33]的前 15 个块,而主架构有 16 个块。然而,创建一个浅层网络最终会降低系统的最终精度。为了避免这个问题,我们有目的地添加了一些新的层。图 1 显示了 ASMNet 的架构。

除此之外,在 CNN 中,较低层具有诸如边缘和角之类的特征,这些特征更适合于诸如地标定位和姿态估计之类的任务,而较深层包含更适合于诸如图像分类和图像检测之类的任务的更抽象的特征。因此,为相关任务训练网络同时建立了可以提高每个任务的性能的协同作用。

因此,我们设计了一个多任务 CNN 来检测面部标志,同时估计面部的姿态(俯仰、滚动和偏航)。为了使用不同图层的功能,我们创建了块 1-批量-归一化、块 3-批量-归一化、块 6-批量-归一化、块 10-批量-归一化以及最后块 13-批量-归一化的快捷方式。我们使用全局平均池层将这些快捷方式中的每一个连接到 MobileNetV2 的块 15 的输出,块 15-add。最后,我们连接所有的全局平均池层。这种架构使我们能够使用网络不同层中可用的功能,同时保持触发器的数量较少。换句话说,由于最初的 MobileNetV2 是为图像分类任务而设计的,其中需要更抽象的特征,因此它可能不适合面部对齐任务,因为面部对齐任务既需要在较深层中可用的抽象特征,也需要在较低层中可用的特征,例如边缘和拐角。

此外,我们向网络中添加了另一个相关的任务。如图 1 所示,所提出的网络预测 2 个不同的输出:面部标志点(网络的主要输出),以及面部姿态。虽然这两个任务之间的相关性和协同作用可以产生更准确的结果,但我们也希望我们的轻量级 ASMNet 能够预测人脸姿态,以便它可以用于更多的应用程序。

ASM 辅助损失函数

我们首先回顾主动形状模型(ASM)算法,然后解释我们基于 ASM 定制的损失函数,它提高了网络的准确性。

活动形状模型检查

活动形状模型是形状对象的统计模型。每个形状被表示为 n 个点以及 S 集合在等式中定义。1 在以下:

为了简化问题和学习形状分量,将主分量分析(PCA)应用于从一组 K 个训练形状样本计算的协方差矩阵。一旦建立了模型,任何训练样本的近似值都可以使用等式计算。2:

因此,可变形模型的一组参数由向量 b 定义,从而通过改变向量的元素,改变模型的形状。考虑 b 的第 I 个参数的统计方差(即本征值)为λi,为了保证应用 ASM 后生成的图像与地面真实情况比较接近,通常将向量 b 的参数 bi 限定为 3√λi [7]。此约束确保生成的形状与原始训练集中的形状相似。因此,在应用了这个约束后,我们根据等式创建了一个新的形状
。3:

其中 b̃是受约束的 b。我们还根据等式定义 ASM 算子。4:

ASM 使用等式将每个输入点(Px i,Py i)转换为新点(Aix,Aiy)。1、2 和 3。

图 2:asmlos(图片由作者提供)

ASM 辅助损失

我们描述了两种不同任务的损失函数。这些任务负责面部标志点检测和姿态估计。

人脸标志点检测任务:人脸标志点检测常用的损失函数是均方误差(MSE)。我们提出了一个新的损失函数,它包括 MSE 作为主要损失,以及利用 ASM 提高网络精度的辅助损失,称为 ASM-LOSS。

所提出的 ASM 损失指导网络首先学习面部标志点的平滑分布。换句话说,在训练过程中,损失函数将预测的面部标志点与它们相应的地面实况以及使用 ASM 生成的地面实况的平滑版本进行比较。考虑到这一点,在训练的早期阶段,与主要损失(即 MSE)相比,我们为 ASM 损失设置了更大的权重,因为平滑的面部标志点的变化比原始标志点低得多,并且作为经验法则,更容易被 CNN 学习。然后,通过逐渐降低 ASM-LOSS 的权重,我们引导网络更多地关注原始标志点。在实践中,我们发现这种方法,也可以被认为是迁移学习,效果很好,可以得到更准确的模型。

我们还发现,虽然人脸姿态估计严重依赖于人脸对齐,但它也可以在平滑的人脸标志点的帮助下获得良好的精度。换句话说,如果面部标志点检测任务的性能是可接受的,这意味着网络可以预测面部标志,使得面部的整个形状是正确的,则姿态估计可以达到良好的精度。因此,使用平滑的标志点和使用 ASM-LOSS 的训练网络将导致姿态估计任务的更高精度。

考虑对于训练集中的每个图像,在称为 G 的集合中存在 n 个标志点,使得(Gxi,Gyi)是第 I 个标志点的坐标。类似地,预测集 P 包含 n 个点,使得(Px i,Py i)是第 I 个标志点的预测坐标。

我们对训练集应用 PCA 并计算特征向量和特征值。然后,我们计算集合 A,它包含 n 个点,每个点都是 G 中对应点的变换,根据等式应用 ASM 运算符
。4:

我们定义主要的面部标志点损失,Eq。7、作为
地面实况(G)和
预测标志点(P)之间的均方差

其中 N 是训练集中图像的总数,Gij = (Gix,Giy)表示训练集中第 j 个样本的第 I 个界标。我们将 ASM 损失计算为 ASM 点(Aset)和预测标志点(Pset)之间的误差,使用等式。8:

最后,我们根据等式计算面部标志任务的总损失。9:

主成分分析的准确性严重依赖于 ASM 点(Aset),这意味着主成分分析越准确,地面实况(G)和 ASM 点(Aset)之间的差异就越小。更详细地说,通过降低 PCA 的准确度,生成的 ASM 点(Aset)将更类似于平均点集,平均点集是训练集中所有地面真实人脸对象的平均值。因此,预测 Aset 中的点比 Gset 中的点更容易,因为后者的变化低于前者的变化。我们使用这个特征来设计我们的损失函数,使得我们首先引导网络学习平滑的标志点的分布——这更容易学习——并且通过降低 ASM 损失的权重来逐渐硬化问题。我们使用等式将α定义为 ASM-减重。10:

其中 I 是历元数,l 是训练历元的总数。如等式所示。9,在训练开始时,α的值较高,这意味着我们更加重视 ASM-LOSS。因此,网络更关注于预测更简单的任务,并且收敛得更快。然后,在总周期的三分之一之后,我们将α减少到 1,并同等重视主要 MSE 损失 ASM 损失。最后,在总时期的三分之二之后,通过将
α减小到 0.5,我们将网络导向预测主要地面事实,同时考虑使用 ASM 作为辅助生成的平滑点。

**姿态估计任务:**我们使用均方差来计算头部姿态估计任务的损失。情商。11 定义了损失函数 Lpose ,其中偏航(yp)、俯仰(pp)和滚转(rp)是预测姿态,而 ytptrt 是相应的地面实况。

实施细节

代码可以在 Github 上找到。关于代码的所有文档也是可用的。

安装需求

为了运行代码,您需要安装 python >= 3.5。可以使用以下命令安装运行代码所需的要求和库:

pip install -r requirements.txt

使用预先训练好的模型

您可以使用以下文件中的代码测试和使用预训练模型:https://github.com/aliprf/ASMNet/blob/master/main.py

tester = Test()
  tester.test_model(ds_name=DatasetName.w300,
                     pretrained_model_path='./pre_trained_models/ASMNet/ASM_loss/ASMNet_300W_ASMLoss.h5')

从零开始的培训网络

准备数据

数据需要规范化,以 npy 格式保存。

常设仲裁法院的创建

您可以使用 pca_utility.py 类来创建特征值、特征向量和均值向量:

pca_calc = PCAUtility()
    pca_calc.create_pca_from_npy(dataset_name=DatasetName.w300,
                                 labels_npy_path='./data/w300/normalized_labels/',
                                 pca_percentages=90)

培训

培训实现位于 train.py 类中。您可以使用以下代码开始培训:

trainer = Train(arch=ModelArch.ASMNet,
                    dataset_name=DatasetName.w300,
                    save_path='./',
                    asm_accuracy=90)

结果

ASMNet 可以以非常高的视觉精度执行人脸对齐和姿态估计。样本图片请访问我的 GitHub 或原始论文。

结论

我们提出了 ASMNet,一种轻量级的 CNN 架构,具有多任务学习功能,用于面部标志点检测和姿态估计。我们提出了使用 ASM 辅助的损失函数来提高网络精度。我们使用 MobileNetV2 的一小部分构建了我们的网络(称为 ASMNet)。所提出的 ASMNet 架构比 MobileNetV2 小大约 2 倍,而精度保持在相同的 rat

请将此作品引用为:

@inproceedings{fard2021asmnet,
        title={ASMNet: A Lightweight Deep Neural Network for Face Alignment and Pose Estimation},
        author={Fard, Ali Pourramezan and Abdollahi, Hojjat and Mahoor, Mohammad},
        booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},
        pages={1521--1530},
        year={2021}
  }

参考

[1] A. Asthana、S. Zafeiriou、S. Cheng 和 M. Pantic。约束局部模型的鲁棒判别响应图拟合。IEEE 计算机视觉和模式识别会议论文集,第 3444–3451 页,2013 年。

[2] D. Cristinacce 和 T. F. Cootes。约束局部模型下的特征检测和跟踪。在 Bmvc,第 1 卷,第 3 页。Citeseer,2006 年。

[3]库茨、爱德华兹和泰勒。主动外观模型。在欧洲计算机视觉会议上,第 484-498 页。斯普林格,1998 年。

[4]马丁斯、卡塞罗和巴蒂斯塔。通过 2.5 维主动外观模型的生成式人脸对齐。计算机视觉和图像理解,117(3):250–268,2013。

[5] X .朱和 d .拉马南。人脸检测、姿态估计、
和野外地标定位。2012 年 IEEE 计算机视觉和模式识别会议,2879-2886 页,2012 年 6 月。

[6]张俊杰、单绍良、简明和陈。用于实时人脸对齐的粗到细自动编码器网络(cfan)。在欧洲计算机视觉会议上,第 1-16 页。斯普林格,2014。

[7]张志军、罗培平、李春春和唐晓明。基于深度多任务学习的人脸标志点检测。在欧洲计算机视觉会议上,第 94-108 页。斯普林格,2014。

[8] C .萨戈纳斯、G. Tzimiropoulos、S. Zafeiriou 和 M. Pantic。野外 300 张脸挑战:第一次面部标志定位挑战。IEEE 计算机视觉研讨会国际会议论文集,397–403 页,2013 年。

[9]吴文伟、钱春弦、杨树国、王庆、蔡玉英和周庆。一种边界感知的人脸对齐算法。IEEE 计算机视觉和模式识别会议论文集,第 2129-2138 页,2018 年。

基于特征的文档相似度的变换器

原文:https://towardsdatascience.com/aspect-based-document-similarity-using-transformers-8a2f820e5692?source=collection_archive---------22-----------------------

NLP 研究论文解释

在这篇博客中,我试图根据我的理解,使用变形金刚 来总结论文 中基于方面的文档相似度。请随时评论你的想法!

问题陈述

当前的文档相似性技术主要集中在比较文档,而没有考虑它们固有的文档结构。这种相似性技术被称为方面无关的相似性。这里,similarity 函数只返回一个介于 0–1 之间的值,用来衡量两个文档之间的相似程度,这多少有点像一个无法解释的相似性黑盒。此外,这可能会限制像推荐系统这样的应用程序的性能,这些应用程序主要依赖于文档相似性作为基础。例如,您可能希望设计一个推荐系统,仅基于“方法论”或“数据集”部分返回与现有论文相似的论文,这里的相似性通常被认为是多方面的,而当前的相似性系统无法捕捉这种粒度。

本文正是以此为目标,将与方面无关的相似性扩展到基于方面的相似性。为了结合方面的概念,他们将测量相似性的任务建模为成对的文档分类任务。此外,他们使用 Transformer 模型,如 RoBERTa 和 BERT 变体,在来自 ACL 和 CORD-19 的研究论文数据集上执行和评估他们的方法。

下图显示了与方面无关和基于方面的相似性的图示视图—

图片来自来源

在上图中,给定一个种子文档,基于某些距离度量,如欧几里德距离、余弦距离等,无特征相似性返回 k 近邻。然而,基于方面的相似性方法将只返回那些对于某些方面 (a1) 相似的文档,导致低假阳性。

如果你想继续享受阅读与数据科学和机器学习相关的精彩文章的乐趣,你可以通过我的推荐链接:)购买中级会员资格

提议的方法

他们将整个问题建模为多类多标签分类问题。在本节中,我们将介绍数据集准备和模型训练方面——

数据集准备

在这项任务中,从研究论文中获取人工注释的数据成本很高,如果可能的话,可能仅限于少量数据。因此,作者通过将引用视为训练信号来继续并自动化这一过程,即如果任何两篇论文之间存在引用,我们认为这些论文是相似的。此外,为了合并节级别信息*(方面),他们选择引用其他文档的种子文档的节的标题作为类标签。例如,在下图中,种子文档引用了介绍和讨论部分下的目标文档。因此,我们将种子和目标作为带有标签介绍和讨论的文档对。因此,分类类型在本质上将是**多类(因为多个标题)以及多标签(同一篇论文在不同章节下的多次引用)*** 。

使用引用信号的数据注释|图片来自来源

现在,由于对一个章节可以采用什么样的标题没有特定的标准,作者有意识地对某些章节标题进行标准化、分组和划分,以获得所有论文的固定标题集,他们还将离群值或无法识别的章节放在“其他”类别中。下图显示了 ACL *(左)CORD-19(右)*纸张的标签分布-

ACL 和 CORD-19 数据集的标签分布|图片来自来源

此外,除了只有正信号样本之外,他们还引入了一个名为“ None 的新类,它在相同的比例下充当我们正样本的负对应 。他们将一组论文归入这一类别的一般经验法则是,论文首先不应该是正对的,不应该一起被共同引用,不应该共享任何作者,并且不应该在同一地点发表

在所有这些步骤和转换之后,我们已经准备好了数据集!

模特培训

为了训练相似性模型,作者从 seed 和其他研究论文中提取论文标题和摘要,并将其视为整个文档的代理。提取后,它们用 cls分隔符标记连接这些片段,形成一个大序列。这然后被馈送到变换器模型,并且在输出端,它们在 CLS 表示法上堆叠一个分类层,并且用交叉熵损失 作为罚信号来对照地面真相中存在的标签训练模型。下图显示的是同一— 的图示

模型训练|图片来自来源

如果你愿意,你也可以查看我写的其他研究论文摘要。

所以,是的,这就是我的博客。我有一个同样的多语种字幕视频漫游,如果你喜欢消费视频内容而不是文本(就像我一样:D),一定要看看—

多看看这样的视频

请随意阅读整篇论文,并向作者问好,感谢他们的贡献。

论文标题: 基于方面的文档相似度使用变形金刚

论文链接:https://www.aclweb.org/anthology/2020.coling-main.545.pdf

作者: 马尔特·奥斯坦多夫、特里·鲁斯、蒂尔·布卢姆、贝拉·吉普、格奥尔格·雷姆

我希望你喜欢读这篇文章。如果你愿意支持我成为一名作家,可以考虑注册成为一名媒体成员。每月只需 5 美元,你就可以无限制地使用 Medium。

感谢您的宝贵时间!❤

使用 Spacy & TextBlob 的基于方面的情感分析

原文:https://towardsdatascience.com/aspect-based-sentiment-analysis-using-spacy-textblob-4c8de3e0d2b9?source=collection_archive---------1-----------------------

评估特定主题或属性的情感

NLP 最常见的目标之一是分析文本和提取见解。你可以找到无数关于如何进行情感分析的教程,但是通常使用的方法并不总是足够的。

当你说出这样一句话时。

We had some amazing food yesterday. But the next day was very boring.

一个逐句的情感分析算法会产生类似这样的结果。

但是有时候你希望你的情感分析是基于方面的,或者叫做基于主题的。

在本文中,我们将构建一个非常简单的基于方面的情感分析,它能够提取一般概念并理解它们周围的情感。在我们之前的示例中,这意味着类似于:

在这种情况下,方面或主题是食物。通过执行基于方面的情感分析,我们分析大量文本并提取见解。

例如,如果您监控客户评论或电话记录,您可以寻找附加了一些情感的方面,并提取关于如何改进的见解。

对于本文,我们将使用 spacy(Python 中的自然语言处理库)和 Textblob,text blob 提供了用于情感分析和文本处理的简单工具。

# We get started by importing spacy
**import** spacy
nlp = spacy.load("en_core_web_sm")

如果你还没有,你需要通过执行python -m spacy download en_core_web_sm来下载en_core_web_sm

我们也来定义几个简单的测试句子。

sentences = [
  'The food we had yesterday was delicious',
  'My time in Italy was very enjoyable',
  'I found the meal to be tasty',
  'The internet was slow.',
  'Our experience was suboptimal'
]

我们的第一个目标是以某种方式拆分我们的句子,以便我们有目标方面(例如,食物)和他们的情感描述(例如,美味)。

**for** sentence **in** sentences:
  doc = nlp(sentence)
  **for** token **in** doc:
    print(token.text, token.dep_, token.head.text, token.head.pos_,
      token.pos_,[child for child in token.children])

由于 spacy 的依存解析和 POS(词性)标签,我们可以看到句子中每个标记的依存关系。我们也注意到了孩子的标记,这样我们就可以选择像“非常”、“相当”等强化词。

**免责声明:**我们目前过于简单的算法可能无法提取语义上的重要信息,如“不太好”中的“不”。这在实际应用中至关重要。

让我们先看看如何挑选情感描述。

**for** sentence **in** sentences:
  doc = nlp(sentence)
  descriptive_term = ''
  **for** token **in** doc:
    **if** token.pos_ == 'ADJ':
      descriptive_term = token
  print(sentence)
  print(descriptive_term)

你可以看到,我们的简单算法选择了所有的描述性形容词,如美味、愉快和可口。但是现在缺少的是强化词,比如“very”。

**for** sentence **in** sentences:
  doc = nlp(sentence)
  descriptive_term = ''
  **for** token **in** doc:
    **if** token.pos_ == 'ADJ':
      prepend = ''
      **for** child **in** token.children:
        **if** child.pos_ != 'ADV':
          **continue** prepend += child.text + ' '
      descriptive_term = prepend + token.text
  print(sentence)
  print(descriptive_term)

正如你所看到的,这一次我们也非常愉快地学习了。我们的简单算法能够识别副词。它检查每个形容词的子代标记,并挑选出诸如“非常”、“相当”等副词。

在常规场景中,我们还需要捕捉诸如“不”之类的否定,但这超出了本文的范围。但是如果你愿意的话,我们鼓励你练习并在之后做得更好。

我们现在准备识别被描述的目标。

aspects = []
**for** sentence **in** sentences:
  doc = nlp(sentence)
  descriptive_term = ''
  target = ''
  **for** token **in** doc:
    **if** token.dep_ == 'nsubj' **and** token.pos_ == 'NOUN':
      target = token.text
    **if** token.pos_ == 'ADJ':
      prepend = ''
      **for** child **in** token.children:
        **if** child.pos_ != 'ADV':
          **continue** prepend += child.text + ' '
      descriptive_term = prepend + token.text aspects.append({'aspect': target,
    'description': descriptive_term})
print(aspects)

现在我们的解决方案开始看起来更完整了。我们能够挑选方面,即使我们的应用程序事先不“知道”任何事情。我们还没有对“食物”、“时间”或“用餐”等方面进行硬编码。我们也没有硬编码诸如“美味”、“缓慢”或“愉快”这样的形容词。

我们的应用程序根据我们设置的简单规则来选择它们。

有时候,你可能想先找到主题,然后在文本中识别它们,而忽略那些不常见的主题或方面。为此,在进入解决方案的情感分析部分之前,你需要在主题建模上工作。有一个关于数据科学的很好的指南,解释了潜在的狄利克雷分配,你可以用它来进行主题建模。

既然我们成功地提取了方面和描述,是时候将它们分类为正面或负面了。这里的目标是帮助计算机理解美味的食物是积极的,而慢速互联网是消极的。计算机不懂英语,所以在我们找到可行的解决方案之前,我们需要做一些尝试。

我们将从使用默认的 TextBlob 情感分析开始。

**from** textblob **import** TextBlob
**for** aspect **in** aspects:
  aspect['sentiment'] = TextBlob(aspect['description']).sentiment
print(aspects)

TextBlob 是一个提供开箱即用的情感分析的库。它有一个单词袋方法,这意味着它有一个单词列表,如“好”、“坏”和“很好”,这些单词都附有一个情感分数。它还能够挑选出影响情绪得分的修饰语(如“不”)和强化词(如“非常”)。

如果我们看看我们的结果,我可以说它看起来绝对不差!我同意他们所有人的观点,但唯一的问题是美味和次优被认为是中性的。似乎它们不是 TextBlob 的字典的一部分,因此,它们没有被选中。

另一个潜在的问题是,一些描述性术语或形容词在某些情况下可能是正面的,而在其他情况下可能是负面的,这取决于它们所描述的单词。TextBlob 使用的默认算法无法知道寒冷的天气可以是中性的,冷食可以是阴性的,而冷饮可以是阳性的。

好的一面是,TextBlob 允许你使用一个非常简单的语法来训练一个 NaiveBayesClassifier,这个语法对任何人来说都很容易理解,我们将使用它来改进我们的情感分析。

为了能够使用它,您需要执行以下命令来下载所需的语料库:python -m textblob.download_corpora

**from** textblob.classifiers **import** NaiveBayesClassifier
# We train the NaivesBayesClassifier
train = [
  ('Slow internet.', 'negative'),
  ('Delicious food', 'positive'),
  ('Suboptimal experience', 'negative'),
  ('Very enjoyable time', 'positive'),
  ('delicious food.', 'neg')
]cl = NaiveBayesClassifier(train)# And then we try to classify some sample sentences.
blob = TextBlob("Delicious food. Very Slow internet. Suboptimal experience. Enjoyable food.", classifier=cl)**for** s **in** blob.sentences:
  print(s)
  print(s.classify())

正如你所看到的,我们传递的句子并不完全是我们在训练示例中使用的,但它仍然能够正确地预测所有短语的情绪。

您可以使用这个解决方案作为更复杂的基于方面的情感分析解决方案的起点。要做到这一点,您需要改进依赖项解析过程,以提取更准确的信息和更多类型的数据。一个很好的方法是使用 spacy 的 DependencyMatcher ,它允许你使用自定义规则匹配模式。

至于情感分析部分,理想情况下,您希望标记大量数据,以便可以创建更高级的分类器,具有更高的准确度。你可以使用 keras 、 TensorFlow 或其他机器学习库和工具来执行大量的二元(或分类)分类。

如果你有预先标记的数据,那会很有帮助。如果你不同意,你可以使用 TextBlob 这样的简单工具创建一个初始分析,然后你可以选择是否同意 TextBlob,而不是决定每个短语的情感,这比从头开始决定情感要快得多。

我真的很感激任何进一步的评论,因为它可以帮助我创建一个更先进的后续文章。感谢您阅读至此!

按比例评估图像美学质量

原文:https://towardsdatascience.com/assessing-image-aesthetic-quality-at-scale-d7c834fd22de?source=collection_archive---------35-----------------------

或者,如何一次使用一个深度学习模型来改进搜索算法

迈尔斯·范德鲁文在 Unsplash 上的照片

问自己这样一个问题:“*你多久检查一次谷歌搜索的第二页?”。*我猜答案在 20%左右。在 HousingAnywhere ,我们也注意到同样的模式,84% 的搜索在第一页停止。这意味着成千上万的公寓和房间不会被用户看到。这就是为什么,作为一个中期住宿市场的核心,改进搜索算法是改善任何地方住房用户体验的关键。

问题是

在 HousingAnywhere 上,我们的用户首先从登录页面开始,在那里他们会看到一个搜索框,输入他们正在寻找的住宿地点和住宿日期。从那里,他们被定向到搜索页面,在那里他们可以根据更多要求进一步细化他们的搜索。点击任何搜索结果都会将用户引导至该住宿的列表页面。

搜索页面(图片作者提供)

列表页面(图片由作者提供)

我们在搜索页面上注意到的一个主要问题是,由于搜索算法没有考虑这一因素,图像质量差的列表经常出现在结果的顶部。这是不可取的,因为 HousingAnywhere 的主要使命之一是奖励“好”广告商,即那些提供详细信息、具有吸引力的广告客户。在我们的平台上,房客不需要进行现场查看就可以预订,这使得住宿照片成为决定房间是否被预订的主要因素之一。因此,需要一种模型来评估图像的质量,以便具有高质量图像的列表可以在搜索页面上获得提升。因此,为了获得更多的用户曝光率,图片质量差的列表需要增强它们的图片。

在处理画质的时候,我们衡量画质的方式主要有两个方面:技术美学。前者处理像噪声、模糊、压缩这样的退化,而后者处理图片的吸引力图像是否看起来令人愉快并显示房间的清晰概观。

但是你如何创建一个模型来决定一个图像在美学上是有吸引力的呢?幸运的是,有相当多的研究做了这个主题。最值得注意的是,这项由谷歌完成的研究。在研究中,引入了实现深度学习的解决方案来解决该问题。

https://ai.googleblog.com/2017/12/introducing-nima-neural-image-assessment.html

解决方案

总之,所提出的架构本身非常简单,我们有一个基线 CNN (MobileNet、Inception 等),其最后一层被大小为 10 的密集层所取代,之后是 Softmax 激活函数。主要成分是建议的损失函数,地球移动距离:

在统计学中,运土机的距离(EMD)是区域 D 上两个概率分布之间的距离的度量。非正式地,如果分布被解释为在区域 D 上堆积一定量的泥土的两种不同方式,EMD 是将一堆变成另一堆的最小成本;其中成本假定为移动的灰尘量乘以移动的距离。

该论文在美学视觉分析(AVA)数据集上展示了有希望的结果,但由于该数据集包含非常普通的图片(从风景到动物图片到不同物体的图片),它在只有房间图像的数据集上表现不佳。然后我们决定收集我们自己的数据集来执行迁移学习。

我们创建了一个由 5 名注释者组成的团队,每个人负责注释一个包含 1500 张图片的数据集。为了简单起见,我们决定将分数范围从 1-10 降低到 1-5。通过让多个注释者处理同一个数据集,我们试图减少在这个过程中产生的错误数量。例如,对于一个 5 分的图像,如果 4 个人记下了 5,但 1 个人错误地填了 1,则平均分数仍然很高(4.2),而不是 1。

我们提出了这些评定图像的标准,作为所有注释者遵循的通用指南:

The photo quality of the image (i.e. clear and not blurry)
The attractiveness of the room (aesthetic wise)
The relevance of the image (i.e. does it show a good overview of the room)
Try to relate yourself to the tenants, how likely would you book this room if the listing has that image

由于 MobileNet 的轻量级架构,我们决定将其作为基线 CNN,并以 90:10 的比例分割训练/测试集。该模型输出一个概率分布,从中计算平均分数。为了评估模型的质量,我们选择使用一个对利益相关者更直观的简单指标(平均绝对误差)。结果是非常有希望的,最好的 epoch 获得了 0.519 的 MAE。所以平均来说,这个模型与真实标签相差大约 0.5 分。

模型架构(图片由作者提供)

以下是模型输出的一些示例:

比分: 4.97 / 5 (来源:HousingAnywhere.com)

比分:【HousingAnywhere.com】4.71/5(来源:中国)

得分: 2.02 / 5 (来源:HousingAnywhere.com)

比分: 1.94 / 5 (来源:HousingAnywhere.com)

结果呢

在我们最初的 A/B 测试后,我们发现使用考虑了质量分数的搜索算法,治疗组从搜索页面到列表页面的转化率有了 5% 的提高。我们对结果非常满意,因为这是我们对搜索算法进行的为数不多的实验之一,达到了统计学意义。

建筑

为了生产模型,我们使用 FlaskGunicorn 构建了一个 RESTful API。这种架构设置简单,性能相当好。发送给我们的服务的请求将包含图像 URL,然后服务将提取并发送给这些模型。该服务作为一个容器部署在谷歌云平台 Kubernetes Engine 上。这种架构虽然非常简单,但仍然允许我们根据需要进行扩展,以处理来自平台的流量。

应用架构(图片由作者提供)

为了让我们晚上睡得安稳,我们使用 Bugsnag 进行错误监控,使用 Prometheus 跟踪指标。当服务失败太多请求或请求处理时间超过阈值时,我们会设置警报。

Bugsnag 为 Flask 提供了本地支持,这使得调试错误变得非常简单。跟踪有关错误的详细信息,包括代码失败的位置和请求包含的内容。

从普罗米修斯收集到的数据会显示在 Grafana 上(图片由作者提供)

结论

就这样,我希望我已经成功地展示了如何在 HousingAnywhere 使用数据科学智能地解决一个复杂的业务用例。该模型的性能非常有前途,它有助于我们完成我们的使命,帮助租户找到最适合他们的住所。

最后,我要特别感谢 BI 团队和 Simone Pouw 校对了这篇文章,感谢 Idealo 团队展示了迁移学习是解决这个问题的关键。

使用 Inception V3 和 FID 评分评估图像相似性

原文:https://towardsdatascience.com/assessing-similarity-between-two-images-groups-using-inception-v3-and-fid-score-4b0367a74e67?source=collection_archive---------10-----------------------

衡量人工智能生成的图像与训练图像相似性的最佳方法是什么?

在过去的几年中,生成敌对网络或 gan 被广泛用于生成类似于训练集中给出的新图像(你可以使用动漫或自行车和许多 其他来查看一些很酷的例子)。根据生成图像的数量及其用途,对生成图像的质量进行视觉评估可能并不充分,并且单独的 FID 分数可能并不充分。在这里,我将尝试说明一种方法,以便更深入地分析生成的结果。

照片由现代灵感的灰烬在 Unsplash 上拍摄

例如,考虑一个应用程序,其中为过采样生成新图像,以帮助从不平衡数据开始训练分类模型。在这种情况下,我们希望能够评估过采样图像和原始训练数据之间的相似性。理想情况下,它们应该与训练集足够相似,但也足够多样,覆盖原始数据集的整个领域,以便真正有助于模型训练。

在这个例子中,我不会训练任何模型,我将使用现有的图像集来说明该方法。为了简单起见,我将评估从 Kaggle fruits 数据集中提取的几种苹果之间的相似性。数据集包含在白色背景下的 100×100 像素的水果图像

我考虑了 7 类苹果,总共 1173 张图片:

数据集中每个苹果类别的图片数量(图片由作者提供)

数据集中的样本图像:

作者图片

为了评估图像之间的相似性,我将从计算苹果参考类别(例如红苹果 1 号)和所有其他类别之间的 FID 分数开始。FID 或弗雷歇初始距离是在训练生成模型(如 StyleGAN)时可以使用的度量之一。它是基于使用在 ImageNet 数据集上训练的 Inception V3 模型从每个图像提取的特征来计算的。

1.图像准备

在计算 FID 分数之前,输入图像需要经历一些转换,以使它们达到预训练的 Inception V3 模型所期望的良好格式:

  1. 大小为 299x299px 像素的 RGB 图像。简单地调整原始图像的大小会使它们变得太模糊,所以我选择用白色填充每个图像,直到达到预期的大小
  2. 将图像转换为张量(将像素值从 0–255 缩放到 0–1)
  3. 使用 ImageNet 训练集的平均值和标准偏差标准化图像

2.预训练的 Inception V3 模型和特征提取

首先实例化一个 inception v3 模型,并加载在 ImageNet 数据集上训练的现有模型的权重(它可以作为 pth 文件直接从 p ytorch 下载) :

Inception V3 模型已经被训练来执行分类,但是因为我们只对使用它来从我们的图像中提取特征感兴趣,所以我们需要移除计算分类概率的最后一层:

Inception V3 网络中的层(图片由作者提供)

为了访问中间层的输出,我们可以使用 torch vision 的特征提取模块:

现在,我们可以简单地使用特征提取器从任何批量图像中获取特征。结果应该是一个大小为 2048 的向量。

3.FID 计算

在这篇文章中已经介绍了计算弗雷谢特初始距离的公式。对于我的 Python 实现,我使用了这个教程作为灵感

我评估了 7 组水果和我的参考类别苹果红 1 之间的 FID 距离。红苹果 1 及其本身的 FID 为零,我们可以看到,除了蛇果看起来更不一样之外,其他类型苹果的得分非常相似:

苹果红 1 和其他类型苹果之间的 FID(图片由作者提供)

对于未受过训练的眼睛来说,所获得的结果不容易解释,因为在视觉上,蛇果和红色 1 之间的差异对我来说似乎不如红色、黄色 2 和红色 1 之间的差异重要。

作者图片

4.主成分分析和 TSNE 投影

为了进一步深入分析提取的特征,我们可以执行主成分分析或 PCA 来获得降维数据集。主成分分析表明,我们可以从 2048 个特征传递到 60 个特征,同时仍然保持数据集中 95%以上的方差。

累积解释差异(作者图片)

通过在 PCA 降维数据集上使用 TSNE,可以获得数据的 2D 可视化。

作者图片

我们可以看到,在每个类别中没有太多的可变性,但每个类别似乎都由 3-4 个子组组成。这并不奇怪,因为考虑的数据集包含从不同角度拍摄的苹果图像,可以解释观察到的行为。

作者图片

基于使用 Inception V3 模型提取的特征,苹果的每个类别似乎也可以与其他类型区分开来。

理想情况下,在我们分析由训练模型生成的合成图像的情况下,我们应该以生成的图像为目标,这些图像的特征实际上与训练集中的图像的特征没有区别:

作者图片

我希望这篇文章给你一些关于如何分析图像组之间的相似性和使用生成模型评估图像质量的想法。

评估森林火灾严重程度和范围绘图的准确性

原文:https://towardsdatascience.com/assessing-the-accuracy-of-bushfire-severity-and-extent-mapping-ce18215f4f42?source=collection_archive---------41-----------------------

使用 Python 3、GeoPandas 和“正常”Pandas 评估火灾严重程度和范围分类的准确性,数据来自 Planet,分析就绪数据来自 Sentinel-2,通过开放数据立方体。

使用 matplotlib 生成的火灾严重程度和范围直方图显示了类别可分性。图片作者。

在我的上一篇文章“用开放数据立方体绘制 2019-2020 年澳大利亚森林火灾”中,我介绍了使用 Sentinel-2 分析就绪数据生成差分标准化燃烧比(dNBR)的过程。dNBR 是一种非常有用且简单的算法,仅需要两个波段(红色和近红外),因此降低了计算资源方面的处理成本,进而降低了时间成本。有关 dNBR 算法的更多信息,请参见我以前的文章。

然而,如果没有某种形式的准确性评估来提供所生成结果的置信度,则任何结果都是无用的。下面是一个高层次的工作流程图,显示了我的结果的整个过程。在左侧,您可以看到创建 dNBR 栅格图层的 Sentinel-2 影像的处理过程。右侧是使用 Planet Dove 影像生成精确数据的过程(根据 Planet Education and Research 许可证)。

整个流程的高级工作流程。图片作者。

Gibson 等人在 2020 年对 dNBR 结果的准确性评估方法进行了描述[1]。该方法在图像上随机采样 n 个点,并基于错误彩色图像的特定视觉问题将它们视觉地解释为火灾严重程度等级:

图片作者。

设置准确度数据时要记住的是,要确保所有图像都可以进行分析,包括但不限于:

  • 在相同的坐标系和数据中进行空间校正和投影,最好 RSME 小于 0.5 像素
  • 随机样本的最小间隔或间距至少为 15 米(Sentinel-2 图像的空间分辨率为 15 米)
  • 每节课至少 50 分,以尽可能减少统计偏差(或在合理范围内尽可能多)
  • 随机采样您的坐标-选择“易于分类”的区域可能会导致错误的评估
  • 我将结果 dNBR 值附加到实际分类观察的形状文件中。你可以选择把它们分开,但是我个人觉得这样更容易。

Python、GeoPandas 和普通熊猫的美妙之处在于,一旦汇编了准确的数据,我们就可以重复且超快速地运行这一过程。但是你为什么会问?我们不是只生成一个准确度值(例如,所有类别的准确度为 60%),而是可以通过随机抽取 n 个准确度点并将它们与实际结果交叉列表,基于多次运行该过程来提供一个范围。让我们看一下代码:

步骤 1 —加载必要的模块并读入数据

步骤 2-分离并绘制实际的课堂观察

步骤 3-将 dNBR 值映射到分类值

步骤 4 —随机抽取每个班级的 n=40 名学生

步骤 5-生成实际火灾严重程度与测量的分类火灾严重程度结果的交叉表格

步骤 6-计算火灾范围精确度

同样,这种方法的优点是可重复的随机抽样,以产生一个精度范围。该过程的准确性被评估为火灾严重性结果的 60-64%(分为未燃烧、低、中、高和极端的严重性类别)和火灾范围的 88-92%(分为未燃烧和燃烧的类别)。如果你想找到完整的笔记本,请访问位于https://github.com/yobimania/dea-notebooks的仓库。有关我如何生成原始结果的更多信息,请访问我的文章‘用开放数据立方体绘制 2019-2020 澳大利亚森林火灾’。

参考资料:

[1]:吉布森,R 等。艾尔(2020)。*使用 sentinel 2 和 random forest 绘制澳大利亚东南部火灾严重程度的遥感方法。*环境遥感 240,111702。

评估机器学习模型的可行性

原文:https://towardsdatascience.com/assessing-the-feasibility-of-a-machine-learning-model-ae36f4180f8?source=collection_archive---------17-----------------------

在编写任何代码之前需要回答的问题

在开始新的建模任务之前,考虑进行可行性研究。预测模型的可行性研究将回答一些关键问题,这些问题可以帮助您和企业决定建模任务是否可能成功。

由 Unsplash 上的 krakenimages 拍摄的照片

机器学习的可行性研究

一个可行性研究是对一个提议的项目或系统的实用性的评估。

——维基百科

可行性研究在各个行业和学科中都很常见。它们是一种重要的项目规划工具,可以帮助您在投入资金或时间之前识别项目中的失败点。

我认为可行性研究对机器学习项目特别有用,因为 ML 项目通常是实验性的。它们失败的原因有很多,其中一些可以通过可行性研究提前确定。

可行性研究期间要问的问题

在对预测模型进行可行性研究时,我喜欢使用以下模板。

  1. 培训数据 —是否需要收集培训数据?如果是,需要花费多少时间和金钱?
  2. 预测特征— 根据领域专家的说法,哪些因素有可能预测目标变量?您可以访问这些数据吗?
  3. 数据源— 您需要访问哪些数据源?如果是内部的,你有数据工程师的支持吗?如果是外部的,供应商数据的成本是多少?
  4. 生产— 在生产中开发、部署和维护您的模型的努力程度如何?

培训用数据

乔纳森·博尔巴在 Unsplash 上拍摄的照片

让我们假设你的建模任务受到监督(因为如果没有,你的可行性研究的结论几乎总是“不可能成功”😅).

如果你没有训练数据,你应该尽早制定一个计划,知道如何获取数据,以及获取数据的成本。

你将需要在某个时候提出预算请求,并且你会很高兴手头有你的可行性研究。这是建立商业案例和证明预算要求的完美文件。

预测功能

蓝水环球在 Unsplash 上拍摄的照片

用厨房水槽砸你的模特可不是个好主意。但是,你如何在可行性研究中提前缩小可能的预测特征呢?

理想情况下,你将有机会接触到主题专家,他们可以建议通常会导致你试图预测的结果的场景或风险因素。

您还可以研究一小部分数据样本,以加深对驱动目标结果的因素的理解。你可能需要在网上做一些研究,或者与客户交谈,以便了解你的数据点的背景。我发现这样做的收获总是值得投入时间的。

一旦您对驱动目标结果的因素有了定性的了解,您就可以更清楚地阐明您需要什么数据以及为什么需要。这有助于在提出数据请求时构建业务案例。

数据源

克里斯托弗·伯恩斯在 Unsplash 上拍摄的照片

完成上一步后,您应该很好地掌握了构建成功模型所需的数据。

在这一步中,您需要确定每个预测特征的数据将来自哪里。我认为数据访问的层次结构是这样的。

  1. 你已经可以访问的内部数据是最好的。
  2. 需要开发运营部门或数据工程部门的工作才能提供给您的内部数据是次佳选择。
  3. 内部无法获得的数据可以从客户、合作伙伴或政府那里免费获得。
  4. 供应商或数据集成商可能有你需要的数据。这种数据从来都不便宜,需要长时间的合同谈判和内部集成/消化时间,并且经常遭受销售过程中隐藏的数据质量问题。
  5. 网络抓取可能值得考虑,但有许多挑战。请记住,抓取是违反大多数大型网站的使用条款的。因此,即使你建造了一座精致的攻城塔来穿过他们的防御墙,法律上也不允许你使用你掠夺的数据。
  6. 如果你已经做到这一步,假设数据是不可用的。评估缺乏数据对项目整体的影响。没有这些数据,项目有可能成功吗?

生产

克里斯·莫瑞在 Unsplash 上拍照

努力程度

对于数据科学项目来说,评估工作水平 (LOE)可能很难,因为它们通常包含实验或迭代阶段。根据实验和探索的结果,整个项目的时间表可以缩短或延长。

所以我更喜欢将 ML 项目分解成相当精细的步骤,每个步骤都有自己的爱好。这样,不确定性小的步骤(比如工程化一个特定的特性)可以得到一个可靠的 LOE,而不确定性大的步骤(比如在业务用户反馈后迭代一个模型原型)可以得到一个 LOE 范围。

我发现这种方法有助于产品经理对将您的模型集成到产品路线图中更有信心。

速赢

当把项目分解成步骤时,我也喜欢在早期加入一些快速见效的东西。对于企业来说,交付增量价值的项目计划比最终只交付价值的项目计划更容易接受。

车型生命周期

请务必考虑整个型号生命周期。即使您的团队不直接负责部署和维护的所有方面,您也需要确信项目不会遇到任何障碍。记住,可行性研究的目的是评估成功的可能性;如果没有生产的途径(即使你能开发出一个模型),你可能应该终止这个项目,继续前进。

人数和时间表

您详细的 LOE 评估是提出员工请求的重要工具。比如说,你可以展示一个有 3 个头的时间线和一个有 4 个头的时间线。如果你是一个需要从零开始建立数据科学团队的团队,你也可以展示一个时间表。

https://skillenai.com/2020/12/09/build-a-data-science-team-from-scratch/

结论

对您的数据科学项目进行可行性研究是实现以下目标的好方法:

  1. 在编写任何代码之前,尽早捕捉故障点。
  2. 构建业务案例,并为数据和人员编制提出资源请求。
  3. 增加您的项目进入产品路线图的机会。

评估研究和数据科学项目的可行性

原文:https://towardsdatascience.com/assessing-the-feasibility-of-research-and-data-science-projects-dcd8fe3215ae?source=collection_archive---------24-----------------------

客观项目评估—得出 ORA 分数

阿迪·戈尔茨坦的照片

第 1 部分—技术成功的概率

你正在提议一个项目,该项目具有有希望的投资回报、对业务的积极影响以及可以使公司在竞争中脱颖而出的营销潜力。目前为止还不错。你继续澄清,在项目完成之前,不知道哪些技术障碍可能会破坏项目。而且即使完成了,你也明白你的公司可能不会选择采用。但是不管后一种可能性,你能在预算中增加几十万美元来完成这个项目吗?嗯?一个和善的老板可能会让你回到办公桌前做些功课。典型的老板可能只是困惑地盯着你。但是他们会吗?事实证明,许多数据科学、人工智能、物联网和其他“性感”的技术项目都是在这些情况下获得批准的。

有序科学已经走进了一些这样的项目。他们的领导者从健康的乐观和被过度的“内部观点”驱动的高期望值开始(参见丹尼尔·卡内曼,思考,快与慢)。但他们的愿景最终无法在糟糕的数据、不成熟的先驱技术、专业知识不足以及抵制创新的公司文化的严酷现实中存活下来。

最初为什么要启动这些项目?答案并不简单。我们遇到的大多数公司都进行了评估,试图量化和衡量风险。但这种评估无法评估最近才出现的人工智能和数据科学技术。这些公司缺乏客观的措施和机制来阻止低成功概率的项目。最终,他们被竞争对手被夸大的成功所诱惑,尽管有时是可疑的。由于害怕被落在后面,这些公司不顾谨慎,蹒跚着走向发展。

在这篇文章的剩余部分,我将讨论序数科学用来评估技术和商业成功概率的客观标准。我将介绍由此产生的 ORA 分数,该分数旨在为启动或放弃一个项目的决策插入一个客观性的度量。这涉及到一些数学问题,但这没有发挥作用的思想和原则重要。数据科学、人工智能和应用数学带来了丰厚的回报,但你选择做什么项目,在什么章程下决定了它们为你的公司做了多少。

可行性研究。

可行性研究决定了项目成功的可能性。它提供了这种概率的单一测量,但包括两个独立的评估。第一个是技术成功的概率——P(T)。它侧重于项目原型或概念证明。第二个因素决定了商业成功的可能性——P(C)。它评估的可能性,原型可以扩大到生产和采用的公司或其客户。这两个度量的乘积就是成功的概率:P(S) = P(T)P(C)。我们将每个测量值视为一个独立变量。当评估商业成功的可能性时,我们假设原型已经被成功开发。

在解开每个分数的推导之前,我应该澄清我们的方法很少是静态的。大多数数据科学和研究项目都有共同的特征,并受益于一致的风险评估方法。然而,通常有必要使评估的细节适应项目的组织特性,并考虑行业垂直市场的细微差别。请考虑,就像我们必须考虑每个项目一样,什么适合您的需求。这样做的目的是保持客观,并避免调整评估参数的诱惑,以便您最喜欢的项目返回一个更好的,但膨胀的分数。

技术成功评估。

估计技术成功的概率(从现在开始指定为 P(T ))是一种识别突出风险因素的练习,然后在将值代入数学函数之前,以一致的尺度对每个因素进行单独评分。简单。但究竟什么是“技术成功”?

P(T)的定义如下:在给定现有数据、可用技术、所需研究和开发的情况下,原型将完成并在精心设计的实验室或受限生产环境中执行规定功能的可能性。P(T)以百分数给出。

定义很重要,因为它设定了对可交付成果的期望。我们将 P(T)的范围限制在为测试技术而设计的原型上,并让一个温和的怀疑者相信这种方法是可行的。测试应该在有限但有代表性的情况下运行,并使用经过审查的数据集。为什么会有限制?它们减少了开发原型所需的时间,而不影响评估。它们通过促进微小的、持续的调整来减少与最终目标不一致的机会。它们降低了投资风险。同时,该过程仍然验证生产解决方案所需的困难组件和算法。

我们在前期的项目阶段定义了原型的细节:概念开发。这是另一篇文章的主题,我们将假设我们的原型有明确的目的、相关的用户角色、功能定义和不可接受的故障模式。

现在,我们评估构建原型需要什么。我将把这个过程压缩成一系列的问题,这些问题引出调查,并给出一个从 1 到 10 的分数,其中 1 是绝对否定,10 是绝对肯定。我们将评估分为四个同等权重的类别:数据、技术、业务和专业知识。

数据:

1.我们拥有所有必需的数据特征

2.每个特征的数据都是完整的

3.每个特征的数据都清晰而准确

4.我们有能力综合模拟样本数据

5.我们可以在没有官僚障碍的情况下访问数据

技术:

6.大多数所需技术的技术准备水平(TRL)。(见 NASAhttps://www . NASA . gov/directorates/heo/scan/engineering/technology/technology _ readiness _ level)

7.单个必需组件的最低 TRL

8.我们可以访问相关解决方案的源代码或库

9.我们可以获得低 TRL 成分的综合文件。

10.我们有计算能力来获得足够的结果

11.我们有一个清晰的路径来验证结果的正确性

业务:

12.这个项目有一个强大的内部拥护者

13.这个项目有很高的内部投资回报率

14.项目团队有明确的章程

15.该项目有充足的预算

专长:

16.客户有一名内部主题专家

17.该团队(序数科学)的专业知识与低 TRL 成分完全一致

18.该团队已经成功地完成了在概念上相似的空间中的研究和原型开发

19.该团队可以利用外部资源,就低 TRL 组件进行咨询

20.在最初的研究阶段,该团队被授予一定程度的独立性

我们给 20 个参数中的每一个赋值,然后把数字代入我们开发的公式。我们将得出的数字称为“ORA 得分”——有序风险评估得分。

ORA 评分

S 是单个参数分数的数组,其中 s 是 1 到 10 之间的整数

N 是一组参数,在我们的例子中 N = 20

C 是压缩系数, C = aN ,其中 a = 3(凭经验选择)

W 是确定每个参数关键程度的参数权重数组,其中 s 是 1 到 6 之间的整数。 w = 6 对于单个参数当 s = 1 时会有将 P(T) 压制在 0.5 以下的效果。

w 对于所有的 W 是最安全的,除非特别权重的原因很好理解。

如果你说“啊?”对于以上所述,不要担心——给我们打电话,我们会为您做可行性评估。这是我们的职责。如果你跟着走,那么在重量上要小心。它们非常重要,必须在您的业务环境中有意义。对于所有特征,它们始终不等于 1。我们如何得到我们的权重向量是一个商业秘密,但是通过大量的实验,你可以得到一个适合你的环境的合理的集合。

定义 P(T)的主要目的是决定是否继续下一阶段。前进的正确门槛是什么?我不知道。我们通常以 70%的技术成功可能性来启动我们的项目,但是环境和客户的风险承受能力同样重要。应该通过与利益相关者的业务讨论来确定适当的阈值。

我将在这里结束可行性文章的第一部分,在下一篇文章中继续“第二部分——商业成功的可能性”。

最初发表在我们的序数科学博客上:https://www . Ordinal Science . com/post/assessing-the-probability-of-research-and-data-Science-projects

例如,评估数据流的质量对于数字化至关重要

原文:https://towardsdatascience.com/assessing-the-quality-of-data-in-streams-2c6352bcbb5b?source=collection_archive---------29-----------------------

意见

为了方便企业客户,我们必须不断将客户旅程数字化。因此,从客户渠道和服务接触点产生了大量数据。这些数据要么是客户自愿提供的信息,要么是从系统及其处理过程中作为日志生成的大量数据。

逐渐地,在物联网世界中,我们看到机器做出决策。这些决策要么让客户对什么更好产生深刻的认识,要么减少他们对服务关系的焦虑。为了使机器模型产生可操作的见解,需要实时获得各种高质量的数据。

管理数据质量的经典模型

1960 年代的数据被认为是在孤岛中管理的,通常是物理上的,同时也有有限的技能组合来产生见解。然而,投资于管理高质量信息的人获得了更好的收入。

然后是商业智能解决方案的出现,它可以被称为今天的复古功能。然而,是一种为报告和分析模型使用数据的有效方式。多年来,组织一直专注于将数据移动到单个参考存储中,如具有提取-转换-加载(ETL)功能的仓库。这是公司普遍采用的第一代数据质量模型。

在将数据加载到仓库中之前,会针对质量的上下文维度(如有效性)对数据质量进行评估。这种模型可以称为第一代数据质量管理模型。

图 1:EDW 或仓库的第一代数据质量管理

由于需要处理往往过于庞大且结构多样的数据集,大数据作为一种能力已经发展起来。虽然 lake 使用提取、加载和转换的概念,但是在提取数据并将其加载到登陆存储时,会对数据的质量进行评估。

物联网数据质量管理高级模型

我们不能不强调运动数据的质量,这些数据经常被用于实时人工智能模型,包括欺诈检测和其他消费活动和分析过程。第一个数据质量挑战通常是为机器学习企业用例获取正确的数据。

错误数据即使业务目标明确,数据科学家也可能无法找到正确的数据作为 ML 服务/算法的输入,以实现预期的结果。

正如任何数据科学家都会告诉你的,开发模型没有理解和以正确的方式处理问题/用例复杂。确定适当的数据可能是一个巨大的挑战。你必须有“正确的数据”

作为数据质量维度的数据覆盖率,用于 ML 用例

术语“覆盖”用于描述是否包含所有正确的数据。例如,在一家投资管理公司中,可能存在不同的客户群以及与这些客户相关联的不同子产品。如果不包括描述客户和相关产品的所有交易(行),您的机器学习结果可能会有偏见或完全误导。众所周知,收集所有数据(通常来自不同的子实体、销售点系统、合作伙伴等。)可能很难,但它对你的结果至关重要。

流媒体数据质量管理的新生模型——第二代

当务之急是查看由外部参与者(包括客户、外部合作伙伴和传感器等)流入环境的数据的质量。发现数据质量问题的方法可能与某些维度特别相关。

  1. 完整性—数据是否符合您对完整性的预期?
  2. 一致性—确保结构、语义的一致性并实施业务策略
  3. 及时性—数据是系统滞后还是手动滞后?
  4. 有效性—数据是否以指定的格式传输,是否符合标准
  5. 唯一性——相似的数据是否已经作为实例存在于生态系统中?

流数据质量架构是什么样的?

让我们来看一个甚至在数据落地之前就自动处理数据以保证质量的架构。这与数据通过管道传输到着陆区并按传统方式进行质量评估的选择截然不同。通常数据以更高的速度进入,因为它需要实时处理。同时,高速度的特征可以与质量管理相结合。

  • 创建一个捕获客户人口统计详细信息的客户应用程序
  • 声明两个消费应用程序——一个用于 MDM,另一个用于分析沙箱。
  • 对从客户注册产品的在线门户获得的数据进行增量质量分析
  • 使用一致性和有效性数据质量规则,使用 ksql 对到达的数据运行数据质量测试
  • 根据验证结果向客户发回通知
  • 捕捉仪表板中的指标以便可视化

注意—堆栈的选择是本机的,而不是使用 Kafkaconnect。

图 2:评估流中的数据质量。礼貌:Tejasvi Addagada

  1. 使用 Python 实例化客户数据流

我使用 Faker 生成客户数据,同时也使用属性姓名、地址、电话号码、工作、电子邮件、出生日期。我使用 IntelliJ 来运行脚本。

注意:在项目结构中,将项目 SDK 修改为 Python 3.6。还要安装软件包——Faker 5 . 8 . 0,coverage 5.4,kafka-python 2.0.2,pip 21.0.1,pymongo 3.11.2,python-dateutil 2.8.1,setuptools 52.0.0,six 1.15.0,text-unidecode 1.3 1.3

启动一个名为 data.py 的新 Python 脚本,并导入 Faker

from faker import Faker

fake = Faker()

def get_registered_user():
    return {
        "name": fake.name(),
        "address": fake.address(),
        "phone": fake.phone_number(),
        "job": fake.job(),
        "email": fake.email(),
        "dob": fake.date(),
        "created_at": fake.year()
    }

if __name__ == "__main__":
    print(get_registered_user())

2 。安装汇流卡夫卡&创建主题

融合平台试用版可从链接下载—https://docs . confluent . io/platform/current/quick start/ce-quick start . html

confluent local services start

您的输出应该如下所示

Starting Zookeeper
Zookeeper **is** [UP]
Starting Kafka
Kafka **is** [UP]
Starting Schema Registry
Schema Registry **is** [UP]
Starting Kafka REST
Kafka REST **is** [UP]
Starting Connect
Connect **is** [UP]
Starting KSQL Server
KSQL Server **is** [UP]
Starting Control Center
Control Center **is** [UP]

启动服务的第一步是创建一个主题 custchannel。

kafka-topics — bootstrap-server localhost:9092 — topic custchannel — create

3.使用 Python 创建一个生产者,持续发送数据

创建一个名为 producer_cust_ch.py 的新 Python 脚本,并从我们全新的 Kafka-Python 库中导入 JSON 、 *time.sleep、*和 KafkaProducer

from time import sleep
from json import dumps
from kafka import KafkaProducer

然后初始化一个卡夫卡制作人

  • bootstrap _ servers =[' localhost:9092 ']:设置生成器应该联系的主机和端口,以引导初始集群元数据。
  • value _ serializer = lambda x:dumps(x)。encode('utf-8') :声明数据在发送到代理之前序列化方式的函数。这里,我们将数据转换为 JSON 文件,并将其编码为 utf-8。
producer = KafkaProducer(bootstrap_servers=['localhost:9092'],
                         value_serializer=lambda x: 
                         dumps(x).encode('utf-8'))

下面的代码将使用 Faker 在步骤 1 中定义的方法创建客户记录。让我们在一个无限循环中生成客户记录,而您可以随时从 UI 中终止生成器。在同一个循环中,数据将使用 send 方法通过管道传输到生成器

if __name__ == "__main__":
    while 1 == 1:
        registered_user = get_registered_user()
        print(registered_user)
        producer.send("custchannel", registered_user)
        time.sleep(10)

图 3:生产者使用 python,在 IntelliJ。礼貌:Tejasvi Addagada

在屏幕底部,由 Faker 功能创建并发送给生产者的客户记录被打印出来,正如我在向生产者发送数据的循环中所指示的那样。

4.拥有一个包含数据库和集合的名称空间,用于在 MongoDB 上存储传入的客户记录

MongoDB 进入这个行业才 5 年,但是它的能力可以很好地与 OLTP 和 OLAP 一起工作。对于这个例子,我将它用作客户数据存储。这将是与第一个消费应用程序相关联的数据库。

命令使用将创建一个新的数据库,如果它不存在

>use custchannel
switched to db custchannel

我将创建一个具有相同名称 custchannel 的集合,并插入示例记录。

图 4: Mongo,创建数据库,收集和插入样本记录。礼貌:Tejasvi Addagada

5。为消费者数据创建 2 个消费者群体(应用程序)

我使用 Python 实例化了第一个消费应用程序和相关的消费者以及 Kafka 中的一个组。

现在,让我们创建一个新文件 consumer_cust_ch.py 并从 pymongo 导入 JSON.loadsKafkaConsumer 类和 MongoClient

from kafka import KafkaConsumer
from pymongo import MongoClient
from json import loads

作为下一个逻辑片段,我将创建一个 KafkaConsumer 并使用下面的参数

  • 第一个参数是题目, custchannel
  • bootstrap _ servers =[' localhost:9092 ']
  • auto _ offset _ reset = ' earliest ':该参数处理用户在集群关闭后重新开始读取,可以设置为 earliestlatest 。当设置为 latest 时,消费者接收在订阅主题之后或从最后提交的偏移量到达主题的消息。如果您想从头重新阅读所有消息,请选择最早的*。*
  • enable _ auto _ commit = True:确保消费者提交其读取以补偿每个间隔。
  • auto _ commit _ interval _ ms = 1000 ms:设置两次提交的时间间隔。
  • group_id='custdq' :一个重要的方面是,我们需要定义一个组,因为我们有多个消费应用程序接收相同的流。
  • 值反序列化器将数据反序列化为 JSON 格式,这与值序列化器执行的功能相反。
*consumer = KafkaConsumer(
    'custchannel',
    bootstrap_servers=['localhost:9092'],
    auto_offset_reset='latest',
    enable_auto_commit=True,
    group_id='custdq',
    value_deserializer=lambda x: loads(x.decode('utf-8')))*

在相同的消费者代码中,我们将连接到一个名为 custchannel 的 MongoDB。我已经用一个示例文档创建了一个集合,并将该集合命名为 custchannel。

*client = MongoClient('localhost:27017')
collection = client.custchannel.custchannel*

消费者会一直听经纪人的话。可以使用 value 属性访问消息的值。然后,我们将数据插入到集合 custchannel 中,同时当值作为文档插入到集合中时,我们还打印一个确认

*for message in consumer:
    message = message.value
    collection.insert_one(message)
    print('{} added to {}'.format(message, collection))*

*当您运行消费者组 *custdq,*时,消息将被存储到 Mongo 数据库 *custchannel 中。在运行窗口中,我们可以看到存储的消息。

图 5:消费者,在 Intellij 中使用 Python。礼貌:Tejasvi Addagada

在图 2 中,我们可以看到记录计数随着消息被插入到集合 custchannel 中而增加。

6.创建另一个消费者群体来阅读相同的信息

我们可以让多个消费者读取来自同一个生产者的消息,只要它们与不同的组相关联。属于同一个群体的消费者将不能整体消费同一个话题。

由于汇合服务已经启动,下面的代码将创建一个消费者组 mdm

*kafka-consumer-groups.sh --bootstrap-server localhost:9092 --topic custchannel --group mdm*

我们可以看到这个消费群体 mdm 订阅了同一个话题 custchannel。生产者生成的信息现在显示在终端上。为了会话的目的,您可以将偏移设置为最早的

图 6:创造第二个消费群体。礼貌:Tejasvi Addagada

7。让我们来看看 KSQL,从主题中声明一个流

*我已经定义了一个流 *custdqdemo,来自步骤 2,custchannel 中创建的主题。消息的格式可以在参数 VALUE_FORMAT 中指定为 JSON。客户记录 name、address、job、email dob 中的属性用它们的数据类型指定给 KSQL。

*ksql> CREATE STREAM custdqdemo (name VARCHAR, address VARCHAR, phone VARCHAR, job VARCHAR, email VARCHAR, dob VARCHAR, created_at VARCHAR) \>>WITH (VALUE_FORMAT = 'JSON', KAFKA_TOPIC = 'custchannel');*

在执行上述语句时,流 custdqdemo 被创建,如下面的屏幕截图所示

图 7: Ksql 流创建。礼貌:Tejasvi Addagada

我们可以查看来自主题 custchannel 的消息,这些消息在我们查询流时显示。

图 8:查询来自主题的消息流。礼貌:Tejasvi Addagada

8。通过数据质量验证评估流并创建异常流

当我们到达模拟的最后一站时,我们将查看针对流中的每个消息验证的两个数据质量规则。这些规则将以查询的形式持续运行。

*CREATE STREAM custexcep AS
SELECT name,
       CASE
         WHEN dob < '1980-01-01'      THEN 'Policyexception'
         WHEN job = 'Arboriculturist' THEN 'Not standard profession'
         ELSE                                      'Correct'
       END AS Quality
  FROM CUSTDQDEMO;*

图 9:在流上使用 Ksql 脚本评估异常。礼貌:Tejasvi Addagada

在 ksql 脚本中,我使用一个简单的 case 语句来检查

a.如果客户的出生日期在 1980 年之后,政策例外。

b.有效的职业/工作名称。

*有一个新的属性 quality,它在运行数据质量规则时捕获预定义的异常消息,如上面的屏幕截图所示。一个名为 *custexcep 的新流被创建。该持久性源可用于监控动态数据的数据质量问题。

Ksql 中有更成熟的功能来减轻监控开销,我们可以在接下来的博客中看到。

来源

Kafka-Python 文档

阿帕奇卡夫卡文献

介绍 KSQL

使用 Apache Kafka:构建流媒体平台实用指南

介绍 Kafka 消费者:开始使用新的 Apache Kafka 0.9 消费者客户端

MongoDB 命令

Asset2Vec:将 3D 对象转化为矢量,然后再转化回来

原文:https://towardsdatascience.com/asset2vec-turning-3d-objects-into-vectors-and-back-8335496b756d?source=collection_archive---------5-----------------------

行业笔记

我们如何使用 NeRF 将我们的整个 3D 对象目录嵌入到一个共享的潜在空间中,这对图形的未来意味着什么

在我目前担任人工智能研究主管的 Datagen ,我们创建常见 3D 环境的合成照片级真实感图像,用于训练计算机视觉算法。例如,如果你想教一个房屋机器人在一个脏乱的卧室中导航,就像下面这样,这将花费你相当多的时间来收集足够大的训练集的真实图像[人们通常不喜欢外人进入他们的卧室,他们肯定不会喜欢给他们的混乱拍照]。

凌乱卧室的合成图像(图片由作者提供)。

我们使用图形软件生成了上面的图像。一旦我们(在软件中)建立了环境和其中所有东西的 3D 模型,我们就可以使用它的光线跟踪渲染器在我们想要的任何光照条件下,从我们喜欢的任何相机视点生成场景的图像。我们已经完全控制了。

现在,如果你认为收集真实图像很难,那么等到你尝试标记这些图像。你需要启动一个漫长而昂贵的标记操作,教人类如何根据你的标准标记这些像素。当然,使用合成图像,我们可以轻松地为图像的任何方面生成像素完美的标签,包括人类无法评估的东西,如深度和表面法线贴图。

从左上顺时针方向:不同光照条件下渲染的场景,表面法线贴图,深度贴图,对象类标签(图片由作者提供)。

收集资产

为了帮助我们的用户训练她的机器人,我们需要生成成千上万个像上面这样的卧室,我们需要用东西填满它们:家具、布、书、用过的杯子、遥控器等等。因此,我们维护了一个艺术家制作的 3D 对象的大型目录(我们称之为资产 ) *。*我们的产品目录涵盖 100 多万件商品,我们对此深感自豪。

每个资产对象由一个详细的 3D 网格(由三角形组成的多边形结构,它定义了对象的形状)和一个纹理贴图(一个图像,它定义了对象的外观,就好像它是一个用来覆盖网格表面的毯子)。

资源(左)由网格结构(中)和纹理贴图(右)表示。图片作者。

除了在视觉上定义对象的网格和纹理贴图之外,为每个资产存储的其余信息是 3D 艺术家决定放入文本元数据文件中的任何内容,如对象的类型(“餐椅”),以及当时似乎相关的任何标签。

因此,在目录中搜索(例如,“给我所有有三条腿的表”)只能使用它们的元数据属性来完成。如果艺术家没有写下每张桌子的腿数,那么要知道哪些桌子是三条腿的,唯一的方法就是一个一个地打开它们的 3D 模型文件去看。

资产-2-Vec

相反,我们建议在嵌入空间中编码每个资产,这将封装整个资产的形状和外观。与 Word2Vec 非常相似,它为字典中的每个单词提供一个“代码”向量,该向量对应于一个 n 维空间中的一个位置,这样语义相似的单词就彼此靠近,我们希望为我们的每个资产分配一个向量,这样我们就可以通过查看向量来判断资产的所有视觉属性。

将我们所有的 3D 资产编码成向量。图片作者。

理想情况下,我们还希望将形状属性(例如,腿的数量)与外观属性(如颜色或材料)分离开来。我们怎么知道向量确实抓住了物体的全部本质?最终的方法是能够从向量回到资产的 3D 模型。

您可以想象一个神经网络,它将学习读取向量作为输入,并输出资源的原始网格和纹理贴图。然而,这将是困难的。每个资源的网格都有完全不同的拓扑:不同数量的三角形,每个节点的不同含义,纹理贴图和网格之间不同的映射格式。我们还需要其他东西,一种适合所有资产的替代 3D 表示。

NeRF 来救援了

这就是 NeRF 的用武之地。正如你所记得的,在我之前的文章中,我展示了如何使用大约 40 张从不同角度拍摄的物体图像,我们可以训练一个神经网络来学习物体周围的整个空间。经过训练的神经网络将空间中的点 (x,y,z) 作为输入,并返回该点中材质的颜色 (r,g,b) 和不透明度(α)。网络对空间了解得如此之好,以至于渲染器可以拍摄对象的“照片”,只需通过沿着来自模拟“相机”的光线的点查询该网络。

NeRF 中心的神经网络(图片由作者提供)。

我们可以轻松获得 40 张图片,涵盖我们目录中的每项资产。我们简单地使用图形软件从它们的原始网格模型渲染它们(所以我们也可以渲染 80)。然后,我们可以使用这些图像来训练 NeRF 网络,以对物体周围的空间进行编码。网络训练完成后,我们可以生成一个短片,从各种新的角度展示物体,其中每一帧都是通过查询训练好的 NeRF 网络来渲染的。

左图:来自图形软件 Blender 的截图,其中我们从各个方向渲染了该资产的 80 幅合成图像(每个金字塔是一个模拟相机),用于训练 NeRF 网络。右图:通过查询训练好的 NeRF 网络,从 80 个视点渲染的对象,跨越 360 度。作者图片。

我们接下来要做的是,使用单个 NeRF 网络,不仅对单个资产进行编码(就像上面的椅子),而且对我们目录中的所有椅子进行编码**。这个单一网络将拥有与 NeRF 网络完全相同的架构。唯一的区别是它将有一个额外的输入:分配给每把椅子的(潜在)向量,它将在训练期间学习。我们将像训练 NeRF 网络一样训练这个网络,除了我们将使用从我们目录中的所有**椅子上拍摄的照片。****

NeRF 网络,以潜在向量作为附加输入。在训练期间,资产的潜在向量也与全连接层的权重一起被学习(图片由作者提供)。

这种训练不同于普通训练,在某种意义上,除了其自身的权重之外,网络还学习与每把椅子相关联的一组特殊变量——其潜在向量(类似于嵌入层的学习方式)。当我们反向传播从渲染椅子图像获得的误差时,不仅更新了 NeRF 网络的权重,而且更新了分配给特定椅子的的潜在向量中的值(例如 vec 输入)。****

一旦我们训练了这个网络,我们就可以用它来制作产品目录中所有椅子的电影!要渲染任何特定的椅子,我们只需要在查询时将椅子的潜在代码作为输入提供给 NeRF 网络。

通过查询一个单个** NeRF 网络呈现的椅子资产示例。图片作者。**

潜在探索

我们不需要将自己局限于为当前目录中的资产学习的向量。我们还可以探索当我们任意改变潜在向量,或者混合和匹配来自两个不同资产的潜在向量时会发生什么。或许在不久的将来,我们能够通过以下方式用新资产丰富我们的产品目录:

混合潜在向量:当 NeRF 网络的输入将椅子 i 的潜在向量的 形状部分与椅子 j外观部分组合时,产生位置(I,j)的椅子。图片由作者提供。

为了直观地了解资产潜在空间的样子,我们可以使用 TSNE 算法将我们的资产放置在 2D 平面上(根据它们的潜在向量):

我们 522 个资产的向量的 T-SNE 图。对象类和子类之间的清晰分离。图片由作者提供。

我们可以看到,椅子的不同子类之间的区别是明显的,即使在一个子类中(即扶手椅),我们也可以很容易地找到椅子共享视觉属性的区域(即带木质扶手的扶手椅与带软垫扶手的扶手椅)。

这就是重点,不是吗?因为这意味着我们可以很容易地训练一个线性分类器(像 SVM 一样)来识别我们关心的任何视觉属性,只需给它提供少数正面和负面资产的向量,然后用它来标记其余的 100 万资产目录,而无需加载这些资产。这种特别的分类可以节省我们大量的时间!

潜伏是未来

最后,这种分析不仅适用于椅子,也适用于我们产品目录中的所有其他资产系列。我们可以想象一个未来,我们渲染的每个场景都将被这些潜影完全描述:每个资产的潜影,背景的潜影,姿势的潜影,相机角度,灯光。如果我们敢,我们可以想象一个未来,传统的网格和纹理贴图将不再被用来渲染合成但逼真的图像,就像上图中凌乱的卧室场景。

通过查询一个单个** NeRF 网络,我们的资产的一个示例。图片作者。**

附录:解耦形状和外观

NeRF 网络有两个分支,一个用于不透明度(α),另一个用于颜色。为了分离潜在向量中的形状和外观部分,我们将输入的潜在代码分成两部分,并且仅向颜色分支显示外观部分,如下所示。这个技巧来自最近的 GIRRAFE 论文(尼迈耶和盖格,CVPR 2021)。

我们修改后的 NeRF 网络架构(图片由作者提供)。

为了更好地理解形状和外观子空间,我们对潜在向量的相关部分进行了 PCA 分析:

****

形状空间(上)和外观空间(下)的前 10 个 PCA 组件的图示。作者图片。

我们可以看到这些是如何控制椅子的各个方面的,如座位的大小,宽度,靠背的高度等。在外观空间中,我们可以看到 PCA 方向如何控制颜色,以及它们的饱和度、亮度和光照条件。

线性回归的假设

原文:https://towardsdatascience.com/assumptions-of-linear-regression-fdb71ebeaa8b?source=collection_archive---------1-----------------------

用 R 和 Python 实现

线性回归的假设—照片由陈丹妮在 Unsplash 上拍摄

线性回归是一种统计模型,允许根据一个或多个独立变量(标为 x )的变化来解释因变量 y 。这是基于自变量和因变量之间的线性关系。

在本文中,我将快速浏览一遍线性回归模型,并涵盖进行线性回归时需要检查的五个假设。我将用 R 和 Python 讲述理论和实现。

线性回归基础—示例

让我们从描述线性回归的一个常见用例开始。我们将研究一个模型,在这个模型中,我们根据房屋的一些物理标准来解释和预测未来房屋销售的价格。

数据

我制作了一个模拟数据集,对这个练习非常有用。当然,既然数据不真实,解读就不会有价值。数据如下所示:

我们线性回归的数据

您可以使用 R 或 Python 通过以下代码片段从 S3 导入数据。

用 Python 从 S3 导入 CSV 文件:

使用 Python 从 S3 导入 CSV

从 S3 导入带有 R: 的 CSV 文件

从 S3 用 R 导入 CSV

线性回归模型

现在,我们感兴趣的是解释房价和其他变量之间的关系。为了对此进行建模,我们将进行线性回归,对以下公式进行建模:

在这个等式中,我们有:

  • β0,截距系数,给出所有解释变量都为 0 的假设情况下的卖出价格值。
  • 贝塔系数的 1 到 4,即斜率系数,给出了特定变量增加 1 步时的销售价格的增加。
  • ε:模型无法解释的销售价格变化(这可能是随机变化或由于一些解释变量引起的变化)

拟合线性回归模型

进入假设之前的最后一步是拟合模型。对于 R 代码,我们将使用lm函数,它是线性模型的定位函数。在 Python 实现中,我们将使用statsmodels库。

用 Python 拟合线性回归

用 R 拟合线性回归

线性回归假设

因为本文的重点是涵盖假设检查,所以让我们跳过模型解释,直接进入您需要检查的假设,以确保您的模型构建良好。

线性回归假设 1 —观察值的独立性

线性回归的第一个假设是观测值的独立性。独立性意味着不同的例子之间没有关系。这不是看数据就能推断出来的:数据收集过程更有可能对此给出答案。

一个明显的依赖观察 (这是我们不想要的!) 可以在使用时间序列时发生。想象一下某个值的日常数据测量。在这种情况下,今天的价值比很久以前的价值更接近昨天的价值。

一个清晰的独立观测 *(这正是我们想要的!)*是实验研究,参与者被随机分配到治疗组。在这种情况下,分配是随机和强制的这一事实确保了观察值之间没有隐藏的关系。

线性回归假设 2 —没有隐藏或缺失的变量

线性回归模型的第二个假设是,你已经在你的模型中使用了所有相关的解释变量。如果你不这样做,你最终会得到一个错误的模型,因为模型会试图将系数赋给数据集中确实存在的变量。这通常被称为模型的错误设定

如果在模型中加入一个变量会有很大的不同,那就意味着没有这个变量,模型是不正确的,没有用的。在这种情况下,你唯一能做的就是回到你的数据收集中去寻找必要的数据。

线性回归假设 3 —线性关系

线性回归的第三个假设是自变量和因变量之间的关系必须是线性的。

尽管这一假设并不总是在文献中被引用,但是检查它是合乎逻辑的并且是重要的。毕竟,如果你的关系不是线性的,你不应该使用线性模型,而应该使用大量存在的非线性模型。

您可以通过绘制每个自变量和因变量的散点图来轻松检查线性关系。您可以使用下面的 R 和 Python 代码来做到这一点。

使用 Python 检查线性关系

线性回归的假设-线性关系 Python

检查与 R 的线性关系

线性回归的假设—线性关系— R

虽然有许多其他方法来做散点图,这种方法是简单的,足够好地检查假设。

Python 代码生成的散点图

要搞清楚 1 对 1 的关系是否是线性的,需要判断数据点是或多或少在一条直线上,还是在一条直线周围。清晰的反模式是当你看到曲线、抛物线、指数或者基本上任何可以识别为非直线的形状时。

这些图没有显示完美的直线,但这不是问题。也没有任何明确的非线性模式,线性模型可能在这方面工作得很好。

线性回归假设 4 —残差的正态性

线性回归的第四个假设是残差应该遵循正态分布。从模型中获得残差后,使用直方图或 QQ 图进行测试相对容易。QQ 图有点难读,但解释起来更精确,所以让我们看看如何使用 R 和 Python 制作残差的 QQ 图。

使用 Python 检查残差的正态性:

线性回归的假设-残差中的正态分布 Python

使用 R 检查残差的正态性:

线性回归假设—残差中的正态分布— R

由 R 代码产生的 QQ 图

在 QQ 图中,您需要查看的是这些点是否在从左下方到右上方的直线上。当偏差发生时,它们通常位于线的低端或高端,而中间的偏差不太可能发生。

如果您看到任何类型的 S 形、指数曲线或直线以外的其他形状,这意味着您有问题:您的模型可能没有正确指定。可能你遗漏了一些变量,或者你的关系实际上不是线性的!您可能想要尝试非线性模型或线性模型的其他规格(使用不同的变量或变量的不同准备)。

在当前的例子中,显然有一个倒置的 S 形,这意味着模型可能有问题。

线性回归假设 5-没有或很少多重共线性

线性回归的第五个假设是不存在或很少存在多重共线性。多重共线性是指多个解释变量高度相关的现象。

那么为什么我们希望每个自变量和因变量之间有很强的相关性,而自变量之间没有相关性呢?原因是,如果两个独立变量相关,它们解释了相同的信息。该模型将无法知道两个变量中的哪一个实际上对因变量的变化负责。

您可以使用方差膨胀因子(简称 VIF)来测试多重共线性问题。VIF 表示一个自变量与其他自变量的相关程度。您可以使用以下代码在 R 和 Python 中计算 VIF。

使用 R 检查多重共线性:

线性回归的假设—使用 VIF 检验多重共线性

使用 Python 检查多重共线性:

线性回归的假设-使用 VIF-Python 检查多重共线性

Python 生成的 VIFs

VIF 从 1 开始,没有上限。VIF 为 1 是最佳值,因为这表示该变量不存在多重共线性。高于 5 或 10 的 VIF 表明模型中的自变量有问题。

在当前的模型中,浴室、卧室和平方米屋这些变量肯定有问题。它们之间似乎非常相关,因此有必要考察这些变量中的哪一个是解释销售价格所真正需要的。

线性回归假设 6 —同方差

线性回归的第六个假设是同方差。模型中的同方差意味着误差沿着因变量的值是恒定的。检验同方差的最好方法是用残差对因变量做一个散点图。您可以使用下面的 R 和 Python 代码来实现这一点。

使用 R 检查同质性:

线性回归的假设—同方差— R

使用 Python 检查同质性:

线性回归的假设-同方差 Python

线性回归的假设—同方差图

同方差意味着一个恒定的误差,你在寻找点与零线的恒定偏差。在当前情况下,您可以在右上角清楚地看到两个异常值。在其余的点中,你也看到顶部的点多,底部的点少。这显然不像零线附近的恒定方差。

如果你违反了同质异方差,这意味着你有异方差。您可能希望对输入数据做一些工作:可能需要添加或删除一些变量。另一个解决方案是进行转换,比如对因变量应用逻辑或平方根转换。

如果这不能改变什么,你也可以切换到**加权最小二乘模型。**加权最小二乘法是一种模型,c 可以处理非恒定方差,因此异方差不是问题。

线性回归假设 7 —所有独立变量与误差项不相关

线性回归模型的第七个诊断检查用于检查任何自变量和误差项之间是否存在相关性。如果发生这种情况,很可能是型号指定错误。你可能忘记了一个重要的解释变量。

您可以使用以下 R 和 Python 代码获得散点图:

在 Python 中检查 IVs 和残差之间的相关性:

线性回归的假设-独立变量和残差之间没有相关性 Python

检查 iv 和 R 中残差之间的相关性:

线性回归的假设—独立变量和残差之间没有相关性— R

线性回归的假设—独立变量和残差之间没有相关性

在这些散点图中,我们看不到任何明显的相关性。右下图可能是一个有争议的案例,但它也不是一个非常清晰和令人信服的问题。

线性回归假设 8 —误差项的观测值彼此不相关

我们要看的最后一个模型诊断是,误差项的观测值内部是否存在相关性。如果发生这种情况,您肯定违反了假设 1:观察值不是随机抽取的。

您可以通过绘制残差与残差阶数的关系来进行直观检查。以下代码片段允许您这样做:

在 Python 中检查残差自相关:

线性回归的假设-残差中的自相关 Python

检查 R 中的剩余自相关:

线性回归假设—残差中的自相关— R

线性回归假设-残差中没有自相关

如果出现一个模式,很可能是一个错误指定的模型。你可能忘记了一个重要的解释变量。或者您可能更适合使用另一系列模型。如果你有自相关,你可能想看看时间序列模型,如自回归移动平均或 ARMA。

如果你的线性回归假设被违反了怎么办?

下一个大问题当然是,如果你发现你的一个假设不成立,该怎么办?!不要担心:对于大多数无效假设的情况,你都可以做一些事情。以下概述了在假设无效的情况下可以采用的替代方法:

  • 通过转换或添加缺失变量来处理输入数据可以解决许多问题
  • 当你发现你有一个错误的设定时,非线性回归是一个很好的方法
  • 如果观察到多重共线性,您可能希望在模型中使用较少的变量。你有强相关的解释变量,最好在它们之间进行选择。一种替代方法是使用例如主成分分析将它们制成一个复合变量。
  • 如果您观察到同方差,您可以转向加权最小二乘模型,这是 OLS 的替代方案,可以处理
  • 如果你的自变量与误差相关,你很可能处于一个错误指定的模型中,你应该选择正确的变量来包含在你的研究中
  • 如果误差项彼此相关,您可能处于自相关存在的情况下,并且您可能擅长使用时间序列模型。

我希望这篇文章对你有用。感谢阅读,不要犹豫,继续关注更多!

逻辑回归的假设,解释清楚

原文:https://towardsdatascience.com/assumptions-of-logistic-regression-clearly-explained-44d85a22b290?source=collection_archive---------0-----------------------

理解并实现假设检验(用 Python ),这是最重要的数据科学建模技术之一

塞巴斯蒂安·斯坦尼斯在 Unsplash 上的照片

逻辑回归是一种非常有效的建模技术,自 20 世纪 40 年代发展以来,一直是统计学中的主流。

考虑到它的普及性和实用性,数据从业者应该在使用它处理数据和业务问题之前理解逻辑回归的基本原理。

在本文中,我们将通过理论解释和实践假设检验的 Python 实现来探索逻辑回归的关键假设。

内容

(1)理论概念&实践检验 (2)与线性回归 (3)总结与 GitHub 回购链接

照片由格伦·卡斯滕斯-彼得斯在 Unsplash 拍摄

理论概念&实践检验

为了在 Python 中实现假设检查,我们将使用经典的 泰坦尼克号数据集。完整的代码请看一下这个项目 GitHub repo。

假设 1—适当的结果类型

逻辑回归通常用作分类器,因此所用的逻辑回归类型(二元、多项式或有序)必须与数据集中的结果(因变量)相匹配。

默认情况下,逻辑回归假设结果变量为二元,其中结果的数量为两个(例如,是/否)。

如果因变量有三个或更多结果,则应使用多项式或顺序逻辑回归。

如何检查?

我们可以通过获得因变量中不同结果的数量来检验这一假设。如果我们要使用二元逻辑回归,那么在结果变量中应该只有两个唯一结果。

假设 2 —独立变量和对数优势的线性

逻辑回归的一个关键假设是,结果的 logit (又名 log-odds )与每个连续自变量之间的关系是线性*。*

logit比值比的对数,其中 p =积极结果的概率(例如,在泰坦尼克号沉没中幸存)

怎么查?

(一)Box-Tidwell 测试

盒形井 测试是用于检查预测值和逻辑值之间的线性。这是通过将连续独立变量与其对应的自然对数之间的对数转换交互 添加到模型中来实现的。

例如,如果你的一个连续自变量是**Age**,那么作为新变量添加的交互项将是**Age * ln(Age)**

作为 Box-Tidwell 测试的一部分,我们对数据集进行过滤,只保留连续的独立变量。

注意:虽然 R 有 *car* 库来用一行代码执行 Box-Tidwell,但我找不到任何可以做类似事情的 Python 包。

如果你有一个以上的连续变量,你应该在模型中包括相同数量的相互作用项。包含交互项后,我们可以重新运行逻辑回归并查看结果。

涉及 Box-Tidwell 变换的 Logit 回归结果示例|图片由作者提供

我们需要做的是根据它们的 p 值检查交互项年龄:Log_Age* 和费用:Log_Fare统计显著性。*

年龄:Log_Age 交互项的 p 值为 0.101 ( 不是统计显著,因为 p >为 0.05),这意味着自变量年龄与结果变量的 logit 线性相关**,并且假设得到满足。**

相反, Fare:Log_Fare统计显著(即 p≤0.05),表明 Fare 与 logit 之间存在非线性

一种解决方案是通过结合高阶多项式项来执行变换,以捕捉非线性(例如, Fare )。

(二)目测

我们可以检查 logit 线性的另一种方法是通过目视检查每个预测值和 logit 值之间的散点图。

**费用变量与结果的对数概率的散点图|图片由作者提供

上述散点图显示了费用与对数优势比的清晰非线性模式,从而暗示违反了logit 线性假设

假设 3—没有强烈影响的异常值

逻辑回归假设不存在具有高度影响力的异常数据点,因为它们会扭曲模型的结果和准确性。

请注意,并非所有异常值都是有影响的观察值。相反,离群值有潜在的影响力。为了评估这一假设,我们需要检查是否满足两个标准,即有影响的异常值。

怎么查?

(一)影响

我们可以用库克距离来确定一个数据点的影响,它是根据它的残差和杠杆来计算的。它总结了当特定的( i th)观察值被移除时回归模型中的变化。

关于使用什么截止值,有不同的意见。一个标准阈值是 4/N (其中 N =观察次数),意味着具有库克距离> 4/N 的观察被认为是有影响的。

statsmodel包还允许我们可视化 GLMs 的影响图,例如影响属性的指数图([influence.plot_index](https://www.statsmodels.org/stable/generated/statsmodels.genmod.generalized_linear_model.GLMResults.get_influence.html)):

库克距离的指数图示例。红色虚线表示厨师的距离界限,上面是作者认为有影响的点|图片

(二)离群值

我们使用标准化残差来确定一个数据点是否是异常值。绝对标准化残差值大于 3 的数据点代表可能的极端异常值。

(三)把两者放在一起

我们可以根据之前为库克距离和标准化残差定义的阈值,通过查找顶部观察值来识别具有强烈影响的异常值数据点。

当检测到异常值时,应该对它们进行相应的处理,例如删除或转换它们。

前 5 名最具影响力的异常值(以及相应的指数)|作者图片

假设 4-不存在多重共线性

多重共线性对应于数据包含高度相关的独立变量的情况。这是一个问题,因为它降低了估计系数的精度,削弱了逻辑回归模型的统计能力。

如何检查?

方差膨胀因子(VIF) 测量一组独立变量中多重共线性的程度。

从数学上来说,等于整个模型方差与一个只包含单个自变量的模型的方差之比。

VIF 的最小可能值是 1(即完全没有共线性)。根据经验,超过 5 或 10 的 VIF 值表示多重共线性的数量有问题。

以下是计算出的 VIF 值的示例。由于没有 VIF 值超过 5 ,假设成立。

VIF 价值观|作者图片

另一种检查方法是生成关联矩阵热图:

相关矩阵|作者图片

这种方法的问题是,当存在许多独立变量时,热图可能难以解释。

更重要的是,三个或更多变量之间可能存在共线性,即使没有一对变量被视为具有异常高的相关性。因此, VIF 是评估多重共线性的更好方法。

*https://kennethleungty.medium.com/membership *

假设 5——观察的独立性

观察值必须彼此独立,也就是说,它们不应该来自重复或成对的数据。这意味着每个观察不受其余观察的影响或与之相关。

怎么查?

对于我们的 Titanic 示例数据集来说,这种独立性假设是自动满足的,因为数据由单个乘客记录组成。

在处理时间序列数据时,这种假设更值得关注,因为时序观测值之间的相关性(自相关)可能是一个问题。

尽管如此,仍然有方法来检查非时间序列数据的观测值的独立性。在这种情况下,“时间变量”是观察的顺序(即指数)。

特别是,我们可以创建残差序列图,其中我们绘制了 logit 模型的偏差残差与观察值的指数。

剩余系列图|作者图片

由于上图中的残差似乎随机分布在零点的中心线周围,我们可以(直观地)推断该假设得到满足。

注:如果您希望了解更多关于逻辑回归中传统残差 vs .fit图的解释,请查看文章 此处 此处

假设 6 —足够大的样本量

对于数据集中的每个独立变量,应该有足够数量的观察值,以避免创建过度拟合的模型。

怎么查?

像库克的距离一样,有许多关于经验法则的观点来确定“足够大”的数量。

一个经验法则是,对于每个独立变量,至少应该有 10 个观察值,且结果最不频繁。我们可以通过检索每个变量的值计数来检查这一点。

另一种确定大样本量的方法是,的总观测数应大于 500 。我们可以通过获得整个数据帧的长度来检查这一点。**

与线性回归的比较

尽管逻辑回归的假设不同于线性回归,但这两种技术都有几个假设。

差异

  • 逻辑回归要求因变量和自变量之间存在线性关系。然而,它仍然需要独立变量与结果的对数概率线性相关。
  • 线性回归需要同方差(常方差),但逻辑回归不需要。
  • 误差项(残差)必须为正态分布,用于线性回归,但在逻辑回归中不需要。

类似

  • 多重共线性缺失
  • 观察是相互独立的

罗伯特·阿纳施在 Unsplash 上拍摄的照片

摘要

以下是我们已经讨论过的假设的回顾:

  1. 适当的结果类型
  2. 自变量的线性对数比
  3. 无强烈影响的异常值
  4. 缺少多重共线性
  5. 观察值的独立性
  6. 足够大的样本量

我还推荐探索附带的GitHub repo查看这六个假设检查的完整 Python 实现

如果你对这个话题有任何反馈或建议,我期待在评论区听到你的意见。

在你走之前

*欢迎您**加入我的数据科学学习之旅!*点击此媒体页面,查看我的 GitHub ,了解更多精彩的教育数据科学内容。同时,享受运行逻辑回归的乐趣!

* [## 垂死的雷鲁问题,解释得很清楚

通过理解 ReLU 的缺点来保持你的神经网络的活力。](/the-dying-relu-problem-clearly-explained-42d0c54e0d24)

参考

GitHub repo 自述文件 中整理的参考资料完整列表*

亚述人还是巴比伦人?楔形文字中的语言识别

原文:https://towardsdatascience.com/assyrian-or-babylonian-language-identification-in-cuneiform-texts-4f15a14a5d70?source=collection_archive---------21-----------------------

实践教程

古代美索不达米亚方言的语言模型

楔形文字泥板。来源: Rama ,维基共享

美索不达米亚是幼发拉底河和底格里斯河之间地区的一个古老名称,位于今天的伊拉克和土耳其、叙利亚和伊朗的部分地区。现代社会的“现代性”很大程度上归功于美索不达米亚人在农业、数学或冶金等领域的发明。在这些发明中,古代美索不达米亚人最伟大的成就之一是发展了 楔形文字手稿,并由此发展出最早的书写系统之一。这是公元前第三个千年,历史才刚刚开始。

楔形文字由印在新鲜泥板上的楔形符号组成。粘土是一种可以抵抗时间流逝而不会显著退化的材料。因此,考古学家设法找到了大量保存完好的石碑。该地区的粘土也非常便宜和丰富。这使得这种形式的经文非常受欢迎,不同的民族在很长一段时间里根据他们的语言改编了这种文字。因此,我们对美索不达米亚几千年来(书面)语言的演变有一个很好的记录。事实上,我们有这么多的记录跨越了这么长的时间,它们几乎是无法管理的。这就是数据科学的用武之地。

古代美索不达米亚地图。来源: Goran tek-en ,维基共享

本文的目的是展示如何编写一个简单的定制语言模型来识别楔形文字文本中的美索不达米亚语言和方言。为此,我们使用来自 Kaggle data challenge 的数据集https://www.kaggle.com/wilstrup/cuneiform-language-identification**识别楔形文字。该数据集包含大约 139,000 个楔形文字片段,还提供了语言或方言标签。有七个标签,包括夏季语 (SUX),一种孤立的语言,以及阿卡德语的六种方言:新亚述语(NEA),标准巴比伦语(STB),晚期巴比伦语(LTB),新巴比伦语(NEB),中巴比伦外围语(MPB),以及旧巴比伦语(OLB)。

如果你想知道这些字符的样子,下面的图片显示了我们的数据集的一个样本。很漂亮,对吧?

我们数据的子集。来源:作者对 Kaggle 数据集的分析

接下来,如果您想在本地机器上复制这个分析,我建议您下载这些字体中的一种。虽然这不会影响您复制分析的能力,但否则文本将无法正确呈现。

语言模型

一般来说,语言模型是单词序列的概率分布。在这个宽泛的定义中,我们可以找到不同类型的模型。一些最常见的使用 n-gram 的概念,即 n 个连续字符(单词)的序列,我们在其中分割文本。N-gram 模型在 NLP 文献中相当常见。它们的应用包括语音和手写识别以及机器翻译。因此,Python 中有一些众所周知的包,比如 NLTK ,用它们我们可以很容易地构建一个 N 元模型。

对于这项任务,我使用一个 N-gram 模型来预测楔形文字 N-gram 序列属于特定的古代美索不达米亚语言或方言的概率。在这个实现中,我们假设每个字符是一个单字。从技术上讲,楔形文字可以是一个完整的单词,也可以只是一个声音,但是我们会忽略这个事实。现在,你可能已经猜到了,如果我遵循这个挑战的简单路径,我就不会写这篇文章。相反,在这里我将向您展示如何从零开始构建一个 N 元模型。事实上,我在代码中使用的唯一 Python 库是numpypandas。我决定这样做有两个原因:首先,标准的 NLP 库是为处理拉丁字符而设计的,所以让它们适应楔形文字有点痛苦。第二,好玩!我坚信测试你在一个主题上的知识的最好方法是从基础开始,看看你是否能用尽可能少的专业库来编码它。**

我提出的 N-gram 模型实现受到了使用概率链规则和马尔可夫假设的经典 N-gram 模型的启发。简单来说,这个假设说明了一个 n 元文法在位置 t 的概率只取决于前面的 k n 元文法(其中 k 通常为 1)。因此,可以通过取其 n 元文法的条件概率的乘积来计算序列的概率,直到 t-k

嗯,我的代码并没有完全做到这一点,而是更接近和更简单。它实际上是计算每种语言的训练集中所有 n 元语法的无条件概率。然后,它通过乘以序列中出现的所有 n 元语法的无条件概率来估计观察到的序列属于每种语言的概率。选择概率最高的语言作为预测标签。

显然,可以开发更复杂的方法。然而,我发现这个非常简单的模型在测试集上已经表现得非常好了。

履行

现在我们对语言模型有了更好的理解,让我们看看如何为楔形文字编写自定义实现。就代码而言,这一部分有点重,但是请相信我:付出的努力是值得的!或者,您可以转到结果部分,了解故事的结局。

我们从一些辅助函数开始。第一个,我们称之为preprocess,将楔形文字的字符串转换成对我们来说更方便的格式。它执行两个操作:首先,它添加一个句子开头和结尾的标记(我们分别称之为 B 和 E),然后它在字符之间添加一个空格。b 和 E 是有用的标记:它们帮助我们计算一个句子以给定字符开始和结束的概率。

预处理功能。来源:作者

现在,我们需要计算 n-grams!下面的两个函数是我们实现的核心,因为它们将文本分割成 n 个字母,并计算每个字母在我们的示例中出现的次数。

N-gram 计数函数。来源:作者

我们的最后一个帮助函数logprob,将用于计算 n 元文法的整个序列的对数概率。在这种类型的问题中,我们通常处理非常小的概率,所以取对数通常是跟踪我们的数字的好主意。这里我们有另一个关于经典语言模型的简化。通常,N-gram 模型会在其词汇表中包含一个“未知”单词标记,以估计找到真正不常见单词的概率。然而,在我们的例子中,我们将简单地假设找到这样的字符的概率是 0.00001(比我们最稀有的一些字符低大约 10 倍)。

计算一个序列的对数概率。来源:作者

就是这样!这些都是我们需要的辅助函数。现在轮到定义一个类来包装我们的模型,您可以在下面的代码片段中看到。因为没有更好的名字,就叫它CuneiPy吧。我们的包装类遵循经典的 Scikit-Learn 结构,包含两个方法:.fit().predict().fit()方法计算每个 n 元语法和语言的无条件概率(记住,我们有七个)。这就是 n 元语法在 n 元语法总数中出现的次数。.predict()方法获取楔形文字字符序列,并计算该序列属于我们的一种语言的概率。然后,它取概率最高的语言,选择它作为预测标签。

CuneiPy —模型的包装类。来源:作者

结果

如果你现在还和我在一起,你可能会想这个东西到底有没有用。你可能已经猜到了答案:是的!虽然肯定有改进的空间,但我们的简单模型在 1000 个观察值的测试集上表现得非常好,加权 f 1 分数约为 0.8(取决于训练-测试划分)。

测试CuneiPy就像这样简单:

测试 CuneiPy。来源:作者

正如我们在.fit()部分看到的,我们使用的是二元模型(因此 n = 2 )。列“楔形文字”是我们语言模型的输入,我们的目标列由数据集中的“lang”定义。下面的分类报告为我们提供了一个模型性能最佳的细分。也许不足为奇的是,该模型更善于识别新亚述语(NEA)和索姆利语(SUX),这两种最常见的语言。该模型也很好地识别了晚期巴比伦语(LTB ),尽管只有 11%的文本属于这种阿卡德方言。中巴比伦周边语(MPB)是我们的模型最难对付的方言。这与我们在样本中对这种语言的表述是如此之少(占所有观察结果的 3.9%)是一致的。

分类报告。来源:作者对 Kaggle 数据集的分析

主要外卖

在本文中,我们看到了如何创建一个定制的 N-gram 语言模型来预测古代美索不达米亚楔形文字的方言或语言。该模型是经典 N 元模型的一个版本,利用了概率链规则和马尔可夫假设。虽然简单,但该模型实现了 0.8 的 F1 分数。

我希望你喜欢这篇文章。如果你喜欢,你可以访问这个 Github 库中的代码。

如有任何反馈,请通过 LinkedIn或电子邮件联系我!

其核心是:图形数据库与关系数据库有什么不同?

原文:https://towardsdatascience.com/at-its-core-hows-a-graph-database-different-from-a-relational-8297ca99cb8f?source=collection_archive---------2-----------------------

通过谷歌搜索这个话题很容易找到一些答案,然而,正如我发现的,大多数答案只是简单地列出了好处

在当今永不停息的世界中,新数据不断产生,是大多数企业的基本资产。系统全天候可用,并且每天每秒都在生成数据。此外,数据生成和处理系统的复杂组合协作向用户提供服务。我最近多次遇到的一个问题——也是我仔细思考的结果——是:图形数据库有什么问题,它们有什么不同?通过谷歌搜索这个话题很容易得到一些答案,然而,正如我发现的,大多数答案只是简单地列出了好处。在这篇文章中,我想简单描述一下我对它们真正价值的理解——独立于大公司和技术影响者的营销幻灯片。

数据库维护和保存所有进入我们系统的先前处理过的事件的物化状态。

事件是进入我们系统的一个独立的、不变的信息。当我们建立一个数据库来处理和存储这样的事件时,我们必须做出各种设计决策:

  • 我们想要存储什么数据?
  • 是如何表现的?
  • 我们在哪个抽象层存储数据?
  • 我们希望处理哪些事件,以及如何将它们应用到我们的数据中?

例如:我们可以存储进入系统的原始事件,或者应用它们来更新我们的数据。

数据库有以特定方式存储数据的目的和原因。

例如,如果数据库充当面向用户的应用程序的持久层,以实时服务于用户请求,那么它应该包含一个表示,该表示保存可被特定请求集快速访问的数据。相反,对于需要考虑大量历史数据的统计业务问题,这可能不是最佳方法。

那么,图数据库和关系数据库有什么区别呢?随着图形数据库越来越受到许多公司的关注,并且大多数公司也有传统的关系数据库,我想在这里重点介绍这两个。

作者图片

关系数据库是实体优先的。

让我们从关系模型开始。关系数据库将数据存储在表中。表格代表一个实体。我称之为实体优先。方法是为一个表定义一个模式,然后在该表中只存储该特定类型的对象。因此,结构相似的数据存储在一起。

关系模型将关系存储为用户域中的数据。

在关系模型中,数据之间没有关系的概念。也就是说,您不能定义表之间的关系。为了在关系模型中链接数据,您必须显式地将关系建模到您的数据中。您无法区分实际数据和仅用于表示关系的数据。对关系建模的唯一方法是将其建模为表中的外键——作为实体的属性(一对一、多对一)或与附加表一起(一对多、多对多)。可以将映射表视为关系表,因此将关系视为实体。然而,它并不隐含在支持关系的技术中,而是我们在创造新的数据。这导致了一个基本的含义:关系数据库将外键存储为用户数据,即引用实体表中的另一个条目。因为引用是用户域中的数据,所以数据库不能有自动机制来管理它们——它们受制于用户逻辑。

作者图片

图形数据库是关系优先的。

相比之下,图模型对于实体(节点)和关系(边)有一个明确的概念,这使得它与众不同。因为我们可以直接定义实体之间的关系,所以我们不需要关心如何在我们的模式中显式地对它们建模。我们不需要了解外键,也不必编写如何存储它们的逻辑。我们定义一个实体和关系的模式,系统会处理它。如果我们想要对高度关联的数据建模,这有一个巨大的好处:实现可以有效地处理引用。图形数据库系统可以存储指向下一个相关实体的真实内存指针,而不是将额外的数据(引用)作为属性显式地存储在我们的数据表中。大多数图形数据库系统以类似于链表的结构存储数据。它们存储的是与相关数据的直接链接,而不是相似的对象。我会说他们是关系第一。

这两种方法中的上述差异导致了关于每一种都可以很好服务的用例的一些暗示。

图形数据库像面向对象语言一样存储数据。

由于关系数据库不包含关系的概念,我们需要将它们作为数据显式地建模到我们的模式中。这导致了与我们在大多数编程语言中使用的面向对象建模的差异。每个对象可以维护与其相关的其他对象的集合。这些引用通常是指向内存中对象的指针,我们不必显式地存储它们。我们也不需要在内存中找到具有外键属性的对象。因此,进行所谓的对象关系映射需要相当大的开销。

图形数据库像面向对象的语言一样存储数据——我们有指向相关对象的直接指针。因此,对象关系映射更加简单。

单个关系的遍历可以在恒定的时间内完成。

由于图数据库可以通过跟随内存指针从一个实体跳到一个相关的实体,我们称之为无索引邻接。我们不必在不同的表中查找外键(使用索引),或者更糟的是,在映射表中查找一个键,然后在第三个表中查找结果外键来跟踪关系。因此,单个关系的遍历可以在恒定的时间内完成。也就是说,它与存储在图形数据库中的数据大小无关。而我们必须扫描关系型索引中的一个——可能是多个——索引,而关系型索引随着数据的增长而增长。

就是感觉用 SQL 写多跳查询不对。

虽然确实可以在关系模型中对连接的数据和关系进行建模,但是一旦我们尝试使用 SQL 查询语言沿着多跳的路径前进,我们可能会觉得我们写下的东西并不是我们想要完成的事情。我们必须在某些条件下连接表,我们必须手动指定这些条件来查找相邻的数据——可能需要多次连接,因此会编写难看的嵌套查询。感觉很大,好像有很多开销正在发生。如果发生这样的事情,这通常是一个强烈的信号,表明我们正在使用一种不完全符合其设计的技术。我们不想连接整个表—我们想查找一个特定的数据点。

在图形数据库中,这看起来不同。因为它们被设计成基于连接结构来查询相关数据,所以它们提供了一种简洁而直观的语法来做到这一点。我们可以准确地指定我们想要查找的路径。没有连接条件或复杂的嵌套查询,没有映射表——只是我们想要找到的最简单的描述。

结论

图形和关系数据库在一个基本设计原则上是不同的:图形有关系的概念,而关系数据库没有。这就是为什么图形数据库可以更有效地管理相互关联的数据。尽管如此,两者都有其存在的理由:当分析接近单个数据点的整个上下文时,图形表现更好,使用起来更直观——可能有多次跳跃。但是,如果不需要探索高度连接和紧密连接的数据,关系模型可能同样可以很好地满足需求。

执掌数据科学、认识论和可知事物

原文:https://towardsdatascience.com/at-the-helm-of-data-science-epistemology-and-what-is-knowable-a-primer-on-the-prevalence-d52da5452aa5?source=collection_archive---------30-----------------------

流行阈值和贝叶斯定理入门

作者图片

  • 宇宙是一个巨大而充满敌意的地方。作为人类,我们只能在这个无限小的空间中生存。我们的生存在一定程度上依赖于我们运用自己的智慧,做出理性选择以最好地适应环境的能力。
  • 在很大程度上,智力是分类的自觉实践。
  • 我们对事物、人、想法、感觉和实体进行分类,以避免危险,最大化我们的幸福,从而提高我们的生存能力。
  • 我们的分类能力是归纳性的,因此受到贝叶斯定理的限制,这就造成了一个生存困境。
  • 因此,鉴于我们对支配我们宇宙的规则的有限知识,当我们探索自然时,我们应该问这个问题:“我们所看到的,到底是什么?”

上面的序言,虽然过于简单和简化,但说明了一个无可争议的事实,即我们茁壮成长和生存的能力至少部分取决于我们的智力。尽管根植于我们的遗传密码及其在进化过程中提炼的潜力,我们的智力主要是通过对我们的世界进行推断并得出让我们能够最有效地导航的结论而获得的。但是这种推理过程有多准确和精确呢?事实证明——这取决于我们使用的推理类型。一方面,演绎推理声称,基于遵循明确定义和详尽的逻辑规则的前提,得出必然为真的结论。这种“自上而下”的推理在纯科学和应用科学中有许多应用——特别是逻辑和数学——从一系列基本原理中发展出一个完整的领域,并以绝对确定性得出内在一致的结论。虽然哥德尔的不完全性定理限制了第一性原理集的完备性、一致性和可判定性,但演绎推理中得到的结论是确定的。不幸的是,鉴于我们对支配我们宇宙和我们存在经验的基本原则的有限知识,生活很少是演绎的。相反,归纳推理是我们得出关于世界的结论的方法。归纳逻辑是一种推理方法,通过这种方法,一组观察结果被综合起来,得出一个普遍的原则——在这种情况下,结论是可能的——甚至经常是可能的——尽管确定。这些结论的不确定程度取决于几个因素——但考虑到它们固有的不确定性——描述它们的语言本质上是统计的和概率的。将这一论点引向其逻辑结论——我们推测,我们绝对确定地了解任何事物的能力很可能是无法达到的。

贝叶斯定理

条件概率的贝叶斯定理方程。图片作者。

贝叶斯定理描述了基于与特定事件或观察相关的条件的先验知识的事件或观察发生的概率。贝叶斯方法的本质是提供一个数学模型,解释现有的信念如何根据新的证据而改变。值得注意的是,贝叶斯定理在生活的无数领域和方面都有应用,它是我们如何观察和与我们的世界互动的核心。

贝叶斯定理通过引入归纳逻辑的形式框架彻底改变了现代哲学,归纳逻辑是一种认知合理性的实用方法,作为一种扩展演绎逻辑定律的证明的方式,包括对归纳逻辑定律的证明。形式结构本身有两个主要元素:使用概率法则作为对理性信任度(或置信度)的约束,以及引入概率推理规则,即所谓的条件概率。

从数学上来说,贝叶斯定理的等式转化为给定事件或状态 B 时事件 A 的条件概率。上述关系等于给定事件 A 时事件 B 的概率乘以事件 A 与事件 B 的独立概率之比。虽然上述概念有些抽象,但应用于日常生活情况的具体示例可能有助于说明这一概念。

例如:

  • 假设今天是九月的一个普通的星期二。在不知道其他情况下,今天下雨的概率有多大?你可以大胆猜测。就保证精度而言,这将是最糟糕的情况。同样,您可以根据您所在地理区域过去(比如说 10 年)的平均降雨天数来推断降雨的基准风险,然后根据今年迄今为止的降雨天数以及今年的剩余天数来推断今天的降雨可能性。现在——估计可能会非常不精确,因为有许多自由度我们没有考虑——但它仍然比猜测要好。毕竟,我们正在使用一些数据来获取知识。现在让我们通过引入新的“证据”或新的“数据”来“更新”我们的估计。说外面是阴天。今天下雨的可能性有多大*?当然,知道今天多云会增加下雨的可能性。使用贝叶斯方法,评估进一步的改进,直到我们能够获得更准确的信息,做出更精确的预测。这是贝叶斯方法的精髓——更多的信息等于更多(或更好、更精确)的知识。正如我们马上会看到的,流行阈值[1]限制了得出准确结论所需的必要证据数量——因此检索信息和新数据的过程不必是无限的。*

我们还可以描述一个医学筛查的常见例子:

  • 根据居住国家的不同,女性从 40 岁或 50 岁开始接受乳房 x 光片和/或乳房超声波的定期乳腺癌筛查。乳房 x 光检查发现疑似乳腺癌病变的可能性有多大?在没有任何进一步信息的情况下,我们可以说,乳房 x 光片被解读为乳腺癌阳性的几率等于人群中乳腺癌的患病率。但是这种方法并没有考虑到女性的个体风险因素或症状。如果接受乳房 x 光检查的人有乳腺癌家族史怎么办?如果她感觉乳房或腋下有肿块怎么办?乳房 x 光片显示病变的机会随之增加。它增加的数量可以使用贝叶斯定理来计算。在这里,我们也观察到,当我们获得更多信息时,我们会更新我们的先验概率以检索新的风险估计,这无非是通过获得更准确的知识来完善我们的理解和更新我们的信念。

分类和混淆矩阵

混淆矩阵是一种总结分类算法性能的技术。它最基本的形式是画出一张 2x2 的表格,将我们试图了解的事物的真实状态/性质与我们观察到的预测进行比较。

混淆矩阵或 2x2 表。图片作者。

我们估计的“预测值”或“精确度”取决于几个变量:我们用来观察和预测的工具有多好,但更重要的是,我们试图了解的东西有多普遍。后一点就是所谓的基础利率谬误,它直接来自贝叶斯统计。

观察工具

我们用来探索世界的观察工具是无限的。给定适当的上下文,任何东西都可以用作获取知识的工具。比方说,你发现自己在一片土地上——一眼望不到边,空无一物。你会被问到这样一个问题:在过去的某个时候,你站的地方附近有一栋建筑的可能性有多大?甚至尝试一个猜测可能看起来令人生畏。如果在第二种情况下,除了你面前有一堵砖墙之外,一切都是一样的,那会怎么样呢?这能保证那里曾经有过建筑吗?不。这是否增加了曾经有过的可能性?是的,它确实如此,尽管砖墙在阐明建筑物的存在方面缺乏敏感性和特异性。从这个意义上说,这堵墙是一种观察工具,尽管它提供的信息质量很差,但它增加了人们了解世界的潜力。

从逻辑上讲,并不是每个工具都能有效地提供有用或准确的信息。这些工具的特征可以最好地描述为它们区分真实情况和虚假情况的能力,以及它们在预测中在各组之间产生多少重叠。他们的表现最好通过混淆矩阵来观察。

下面给出一个混淆矩阵的例子。尽管这个例子试图在医学筛查的背景下对疾病状态进行分类,但是对任何个人、概念、想法、主题或物理实体的任何分类都遵循相同的规则。用于观察的工具的灵敏度或“真阳性率”(在信息检索中也称为回忆*)被定义为总阳性(真预测和假预测)中真阳性的数量,而特异性或“真阴性率”(在信息检索中称为选择性)被定义为总阴性(真预测和假预测)中真阴性的数量。作为一个工具,混淆矩阵作为一个二元分类系统,允许我们计算上述参数。*

混淆矩阵中灵敏度(真阳性率)和特异性(真阴性率)参数的方程式。图片作者。

一个极限问题

在评估分类工具的有效性时,如果我们只考虑其敏感性和特异性参数,就会出现一个重大问题,因为这必然要求您在参与分类过程之前了解您试图分类的任何内容的真实状态。这种障碍在机器学习(ML)和人工智能(AI)中经常观察到。例如,你向计算机提供一组不同颜色的圆形水果的图像。你试图开发一个神经算法,在这个场景中的分类工具,来识别这个数据集中的苹果。即使算法非常优秀,它也需要一个黄金标准来比较它的发现。这产生了两个问题——首先,如上所述,您需要提前知道哪些水果是真正的苹果,以确定算法是否得出了正确的结论,这逆转了分类过程,并使其变得没有意义(如果您已经知道哪些是真正的苹果,为什么需要对它们进行分类?).但是第二,也许更重要的是,这些参数没有解释基本利率谬误。因此,我们需要其他参数来进行正确的认知归纳推理,并获得关于世界的更准确的知识。

精度/预测值

*基本比率谬误被定义为在主观判断事件的条件概率时,没有考虑事件的基本比率或先验概率的认知失误,为了解释基本比率谬误,需要不同的参数。这里是阳性和阴性预测值进入等式的地方。这些新的参数是流行率相关的,并通过以下问题在其适当的年表中处理分类过程:*在预测观察值的数量中,有多少对那些观察值的确认将被证明是正确的?不要问敏感度问的是什么:在确认的观察结果中,有多少是首先被正确预测的?前一个问题的答案是所谓的正预测值,或精度。观察工具的精度取决于它试图观察的事物有多普通。

混淆矩阵中阳性(精确度)和阴性(选择性)预测值参数的方程式。图片作者。

我们试图观察的事物的普遍性与其观察工具的精确度(阳性预测值)之间的比例由以下等式给出——贝叶斯定理的另一个直接结果:

其中ρ(ϕ)is 是精确度,a 是灵敏度,b 是特异性,ϕ是流行率。图片作者。

很容易观察到,上述比例不是线性的。换句话说,普及率的提高并不意味着精确度的同等提高。也许用不同的灵敏度和特异性值来图示这种关系更有用。

作为患病率函数的分类工具的精确度或阳性预测值。曲线下的面积越大,工具的性能越好。在这种情况下,红色的工具比蓝色的好,而蓝色本身又比黄色的工具好。图片由尼尔·d·戈尔茨坦提供。许可用于商业用途。(https://www . goldsteinepi . com/blog/relationships-between-observed-outcomes-and-true-prevention/)。

上述曲线的一个显著特征是,每条曲线上都有一个拐点,在拐点以下,精度下降最快。在这些低流行水平下,该测试可能并不那么可靠——在其预测中产生更多的假阳性而不是真阳性。我们把这个拐点称为“流行阈值”,它在决定世界上什么是可知的方面起着至关重要的作用。

流行阈值

如上所述,流行阈值[1]指的是流行水平,低于该水平时,测试的精确度下降得更快。从认知的角度来看,这意味着什么?这意味着,在这种情况下,对于一个真实的信号,我们会得到大量的噪声,或者假阳性预测。根据我们试图观察或分类的东西的流行程度,我们不会获得主要是纯信号——因此不可避免的问题是:鉴于贝叶斯限制将流行程度与我们的预测能力联系起来,以及鉴于我们试图观察的东西的低流行程度而做出的错误观察的数量——我们能够绝对确定地真正知道任何事情吗?答案很可能是否定的——除非在一个非常特殊的情况下,观察工具的特异性是 100%,在这种情况下,根据上面的等式,精度将等于 1。有多少观察工具的特异性是 100%?考虑到口译翻译过程中工具功能的自然变化、人为错误和信号丢失(机器的输出需要由得出这些结论的人来解释——这个过程也容易出错),很可能没有。上述事实很有趣,并且对我们观察可知世界的确定性有重要的哲学和认识论意义。然而,硬币的另一面(或在这种情况下,阈值)同样有趣。注意第一条红色曲线中超过患病率阈值的几乎水平的红线。图表的这一部分是什么意思?超过流行阈值,对于具有足够好的灵敏度和特异性参数的工具来说,增加流行对提高精确度只有很小的影响。也就是说,当我们已经收集了足够的信息来做出准确的预测时,增加信息量可能不会以显著的方式增加精确度。针对流行阈值校正信息检索的过程可以减少计算时间并减少不必要的资源使用。有鉴于此,计算工具流行阈值的等式如下,其中 a 是灵敏度, b 是特异性:

患病率阈值的等式(a =敏感性,b =特异性)。图片作者。

从图形上看,流行阈值可描述如下:

流行阈值线(绿色)将图形分为两个区域。在它之下,精确度水平随着流行程度的降低而下降。它上面的区域表明,添加额外的信息可能不会显著提高精度。图片作者。

请注意绿色垂直线是如何在图形的拐点或最大曲率点处截取图形的。这是流行阈值。在它之下,精确度水平随着流行程度的降低而下降。上面的区域表明,添加额外的信息可能不会显著提高精度[2]。

结论

哲学、认识论和贝叶斯理论之间的关系提供了一个奇妙的——也是令人谦卑的——工具来最好地理解我们对世界的推理理解的局限性。基于数学,我们得出一个不可避免的事实:我们不可能绝对确定地知道任何事情。也就是说,尽管有巨大的影响,流行阈值是一个简单的指标,它决定了工具的精确度以及我们对现实的理解开始失效的流行水平。开发更好的观察工具并获得足够的信息以保持在流行阈值以上,对于我们在世界上的观察得出更可靠的结论是必要的。

参考文献

  1. Balayla,2020。患病率阈值(ϕ e)和筛查曲线的几何形状。 Plos one15 (10),p.e0240215
  2. 巴拉伊拉,j . 2021。论筛选悖论的形式主义。 Plos one16 (9),p.e0256645。

ATOM:一个用于快速探索机器学习管道的 Python 包

原文:https://towardsdatascience.com/atom-a-python-package-for-fast-exploration-of-machine-learning-pipelines-653956a16e7b?source=collection_archive---------12-----------------------

照片由迈克·本纳在 Unsplash 上拍摄

优化建模自动化工具(ATOM)是一个开源的 Python 包,旨在帮助数据科学家对受监督的机器学习管道进行快速探索和实验。

介绍

在项目的探索阶段,数据科学家试图为他的特定用例找到最佳的管道。这通常包括应用标准的数据清理步骤、创建或选择有用的特性、尝试不同的模型等。测试多个管道需要许多行代码,将所有代码都写在同一个笔记本上通常会使代码变得冗长而混乱。另一方面,使用多台笔记本电脑会增加比较结果和保持概览的难度。最重要的是,为每个测试重构代码可能会很耗时。您执行过多少次相同的操作来预处理原始数据集?有多少次你从一个旧的存储库中复制并粘贴代码,以便在一个新的用例中重用它?

ATOM 旨在帮助解决这些常见问题。该包充当整个机器学习管道的包装器,帮助数据科学家快速找到解决其问题的好模型。避免无休止的导入和文档查找。避免反复重写相同的代码。只需几行代码,现在就可以执行基本的数据清理步骤,选择相关功能,并在给定数据集上比较多个模型的性能,从而快速了解哪种管道最适合当前任务。

原子可能采取的步骤示意图。

装置

通过pip轻松安装 ATOM 的最新版本:

$ pip install -U atom-ml

或者通过conda:

$ conda install -c conda-forge atom-ml

使用

理解软件包能为您做什么的最简单的方法是通过一个例子。在本例中,我们将:

  • 加载数据集。我们将要使用的数据是来自 Kaggle 的澳大利亚天气数据集的变体。可以从这里下载。这个数据集的目标是预测明天是否会下雨,在目标列RainTomorrow上训练一个二元分类器。
  • 分析要素的分布
  • 估算缺失值
  • 对分类列进行编码
  • 对数据进行逻辑回归和随机森林模型拟合
  • 比较两种模型的性能

我们将用不到 15 行代码完成所有这些工作!让我们开始吧。

加载数据集

我们开始从 csv 文件加载数据。

import pandas as pdX = pd.read_csv("weatherAUS.csv")
X.head()

ATOM 有两个主要的类,用于初始化管道:

  • ATOMClassifier:用于二进制或多类分类任务。
  • ATOMRegressor:用于回归任务。

对于这个例子,我们使用 ATOMClassifier。这里,我们用加载的数据集初始化一个 atom 实例。

from atom import ATOMClassifieratom = ATOMClassifier(X, y="RainTomorrow", test_size=0.3, verbose=2)

此外,我们指定 atom 应该以 70%-30%的比率分离训练和测试集中的数据集。

<< ================== ATOM ================== >>
Algorithm task: binary classification.

Dataset stats ====================== >>
Shape: (142193, 22)
Scaled: False
Missing values: 316559 (10.1%)
Categorical features: 5 (23.8%)
Duplicate samples: 45 (0.0%)
---------------------------------------
Train set size: 99536
Test set size: 42657
---------------------------------------
|    | dataset      | train       | test        |
|---:|:-------------|:------------|:------------|
|  0 | 110316 (3.5) | 77205 (3.5) | 33111 (3.5) |
|  1 | 31877 (1.0)  | 22331 (1.0) | 9546 (1.0)  |

我们收到的输出是数据集的简短摘要。我们可以立即看到数据集中缺少值和分类列。

分析数据集

将数据集加载到 atom 实例后,我们就可以开始分析它了。ATOM 为此提供了各种情节和方法。例如,为了绘制特征相关矩阵,我们可以键入。

atom.plot_correlation()

请注意,该图会自动忽略分类列。我们还可以使用Kolmogorov–Smirnov测试来调查特性的分布。

atom.distribution("Temp3pm")

 ks  p_value
weibull_max  0.0173   0.0053
beta         0.0178   0.0036
pearson3     0.0215   0.0002
gamma        0.0216   0.0002
lognorm      0.0217   0.0002
norm         0.0230   0.0001
invgauss     0.0649   0.0000
triang       0.0696   0.0000
uniform      0.1943   0.0000
expon        0.3376   0.0000
weibull_min  0.7675   0.0000

让我们绘制特征分布图,看看它是否确实符合威布尔 _ 最大值分布。

atom.plot_distribution("Temp3pm", distribution="weibull_max")

数据清理

既然我们已经了解了如何使用包来快速分析数据集,我们可以继续清理它。既然 sklearn 模型不接受缺失值,我们就应该去掉它们。我们可以使用 atom 的 impute 方法做到这一点。

atom.impute(strat_num="median", strat_cat="most_frequent")

所选择的参数规定,对于数字特征,我们用列的中位数进行估算,对于分类特征,我们用列的最频繁值(众数)进行估算。将数据集作为实例的一部分的好处之一是,我们不需要调用 fit 或 transform。基础转换器将自动适应定型集,并转换整个数据集。

Fitting Imputer...
Imputing missing values...
 --> Dropping 702 samples for containing less than 50% non-missing values.
 --> Imputing 351 missing values with median (12.0) in feature MinTemp.
 --> Imputing 169 missing values with median (22.6) in feature MaxTemp.
 --> Imputing 1285 missing values with median (0.0) in feature Rainfall.
 --> Imputing 60160 missing values with median (4.8) in feature Evaporation.
 --> Imputing 67131 missing values with median (8.5) in feature Sunshine.
 --> Imputing 8667 missing values with most_frequent (W) in feature WindGustDir.
 --> Imputing 8609 missing values with median (39.0) in feature WindGustSpeed.
 --> Imputing 9402 missing values with most_frequent (N) in feature WindDir9am.
 --> Imputing 3106 missing values with most_frequent (SE) in feature WindDir3pm.
 --> Imputing 2096 missing values with median (21.1) in feature Temp3pm.
 --> Imputing 1285 missing values with most_frequent (No) in feature RainToday.

为了对分类列进行编码,我们使用 atom 的编码方法。我们可以从类别编码器包中选择任何估计器来进行转换。

atom.encode(strategy="LeaveOneOut")

Fitting Encoder...
Encoding categorical columns...
 --> LeaveOneOut-encoding feature Location. Contains 49 classes.
 --> LeaveOneOut-encoding feature WindGustDir. Contains 16 classes.
 --> LeaveOneOut-encoding feature WindDir9am. Contains 16 classes.
 --> LeaveOneOut-encoding feature WindDir3pm. Contains 16 classes.
 --> Ordinal-encoding feature RainToday. Contains 2 classes.

就这样,所有缺失值都被估算,分类特征用数值编码。atom 管道中的数据可以通过dataset属性随时访问。

atom.dataset.head()

模特培训

既然数据集已经清理完毕,我们就可以开始拟合模型了。在这个例子中,我们将评估一个逻辑回归和一个随机森林模型在分类问题上的表现。所有可用的型号及其相应的缩写可在文档中找到。同样,一个简单的命令就足够了。

atom.run(models=["LR", "RF"], metric="f1")

**注意:**这是一个极简的例子。此外,还可以指定模型参数、使用多个指标、执行超参数调整和训练定制模型。详见文件。

Training ===================================== >>
Models: LR, RF
Metric: f1 Results for Logistic Regression:         
Fit ---------------------------------------------
Train evaluation --> f1: 0.4716
Test evaluation --> f1: 0.4658
Time elapsed: 0.201s
-------------------------------------------------
Total time: 0.201s Results for Random Forest:         
Fit ---------------------------------------------
Train evaluation --> f1: 0.9999
Test evaluation --> f1: 0.5434
Time elapsed: 14.976s
-------------------------------------------------
Total time: 14.976s Final results ========================= >>
Duration: 15.177s
------------------------------------------
Logistic Regression --> f1: 0.4658
Random Forest       --> f1: 0.5434

这里发生了几件事。使用所提供的度量,在训练集上训练这两个模型,并在测试集上评估这两个模型。然后,为每个模型创建一个对象,并作为属性附加到atom实例。它们通过模型的首字母缩略词(如随机森林模型的atom.RF)来调用,并可用于进一步分析结果。

评估结果

最后,我们想要比较模型的性能。为了分析单个模型,我们使用前面提到的 model 子类。例如,为了检查随机森林的特征重要性,我们键入。

atom.RF.plot_feature_importance(show=10)

用于拟合数据的实际估算器(来自 scikit-learn 包),可通过模型的estimator属性访问。

atom.RF.estimator

RandomForestClassifier(n_jobs=1)

但 ATOM 的真正强大之处在于,我们可以轻松地比较其管道中所有模型的性能。例如,通过绘制 ROC 曲线。

atom.plot_roc()

或者评估他们在多个指标上的表现。

atom.evaluate()

结论

ATOM 在机器学习项目的探索阶段协助数据科学家。它能够分析数据,应用标准的数据清理步骤,并在几行代码中比较多个模型的性能。但这还不是全部!ATOM 还可以帮助机器学习中的其他常见任务,例如:

  • 检测并移除异常值
  • 处理不平衡的数据集
  • 比较在不同管道上训练的模型
  • 执行超参数调谐
  • 使用集成技术组合模型
  • 还有更多…

欲了解更多信息,请查看该项目的 GitHub 或文档页面。对于 bug 或特性请求,请不要犹豫,在 GitHub 上打开问题或给我发电子邮件。

原子神经网络、计算的未来、量子过程和意识——伯特·卡彭教授深度访谈

原文:https://towardsdatascience.com/atomic-neural-networks-the-future-of-computing-quantum-processes-and-consciousness-an-in-depth-9d40be276376?source=collection_archive---------28-----------------------

马库斯·斯皮斯克在 Unsplash 上的照片

1987 年,卡彭教授获得了洛克斐勒大学的理论物理学博士学位。在飞利浦进行了两年的研究后,他于 1989 年回到学术界。为了更好地了解人类,他将研究领域转向了神经网络和机器学习。

Kappen 教授的研究兴趣在于统计物理学、计算机科学、计算生物学、控制理论和人工智能之间的接口。多年来,他一直认为计算、内存和能耗将是人工智能未来发展的主要挑战。Kappen 教授没有被这些挑战限制他的研究,而是最近在《自然》杂志上发表了一篇革命性的文章,题为“能够自适应的原子玻尔兹曼机器”。在这项工作中,他展示了在核水平上训练神经网络的可能性。这一发现可能是新一代算法的先驱,只消耗当前模型能量吸收的一小部分。在这次采访中,我们将讨论 Kappen 教授的发现,他的发现的潜在影响,以及我们是否可以在他的发现和人类之间建立联系。

Kappen 教授,您主要认为自己是物理学家还是计算机科学家?

那是一个困难的问题。我的大部分出版物都在机器学习期刊和会议上。从这个意义上说,我是一名计算机科学家。然而,我最常用的方法和方法论源于物理学。所以,我最终认为自己主要是一个物理学家。

例如,我的大部分工作是在近似推理上,它有效地近似了在非常大的概率模型中低阶统计的计算。这个问题由变分法和蒙特卡罗采样等各种技术主导,都植根于物理学。在我的大部分工作中,我将这些技术从物理学界转移到机器学习和人工智能领域。

你为什么决定从物理学转到计算机科学?

我攻读了理论高能粒子物理学的博士学位,并一直对该领域复杂的数学着迷。它有令人难以置信的美丽,我们有令人难以置信的成就,了解它是一种特权。

同时,我觉得它离我个人的日常生活很遥远。

在攻读博士学位期间,我一直对我的大脑是如何工作的非常感兴趣。“我”的概念和问题“我是谁?”一直让我着迷。这个问题可以用大脑、神经科学、AI、哲学的知识来回答。

我从粒子物理学转向人工神经网络,主要是受这种魅力的驱使。我发现这是一个美丽的领域,因为你正在以某种有限的方式模拟模仿人类的系统。因此,这是一种了解你自己的尝试。

人工智能的未来是否在物理学和计算机科学的交叉点上?

很难预测未来。例如,我没有看到深度学习的成功,尽管这些技术从 80 年代就已经存在了。令人惊讶的是,我们使用大量数据和计算能力获得了如此惊人的性能。也就是说,我认为这两个领域的交叉有着巨大的潜力。但是利润也可以来自其他各种各样的学科。

许多人声称,我们应该利用大脑的知识来帮助人工智能进步。这是一个令人信服的想法,但在实践中很难做到。对人工智能和新技术做出贡献的新颖大脑机制的数量非常少,如果不是没有的话。尽管如此,神经科学将激励我们进行这项研究,因此仍然与人工智能的未来相关,工程学和物理学的新见解也是如此。

总之,我认为有许多成功的道路和许多重要的贡献。当然,我特别感兴趣的是机器学习和物理学之间的接口。

我最近的工作就是这种界面的一个例子,在这里我们让物理学处理大量的计算问题。我们可以利用物理学来识别你基本上免费获得的属性,并将其用于我们的目的。

让我们谈谈你最近的工作。你在《自然》杂志上的论文有什么发现?

这是与来自奈梅亨(IMN)凝聚态物理研究组的 Alexander A. Khajetoorians 教授的合作。

他是世界上操纵表面单个原子的领导者之一。你知道 IBM 用 35 个原子写名字的老照片吗?他也可以做这样的事情。最近,他发现某些原子(在这种情况下是钴)在黑磷衬底的表面上可以有两种状态。本质上,这意味着这些原子与它们的基质相互作用;当电子云在原子表面机械移动时,原子周围的电子云可以有两种形态。你可以把这些原子想象成在两种状态下实现一个随机比特,原子的这种'舞蹈 s '可以作为电压来测量。

早些时候,IMN 发现,如果你把许多原子放在表面上,它们会以不同的时标跳舞,一些跳得很慢,而另一些跳得很快,并且是一种复杂的模式。这一发现激励我们与学习建立联系。

大脑可以被建模为一个由神经元和连接组成的神经网络,你们称之为突触。对于人脑中给定的突触连接,神经元实现某些功能,如感知或运动控制。本质上,当突触改变到其他状态时,学习就发生了。虽然神经元在很短的时间尺度(毫秒)内发生变化,但突触的变化要慢得多。后者可能需要几分钟、几小时、几天或更长时间(想想婴儿走路需要的时间)。

就像跳舞的原子一样,你可以把神经网络想象成由两种类型的变量组成的网络:一些移动得非常快,一些移动得非常慢。

在我们的工作中,我们在这个材料上展示了这两种类型的时标。时间尺度的分离是巨大的:快速变量在毫秒内变化,而慢速变量可能需要几秒、几分钟甚至更长时间才能变化,就像大脑一样。这种时标分离可以被认为是实现了一种记忆形式:慢变量随着时间的推移而改变,并改变了自旋阵列中快变量之间的连接性。

我们在一个简单的装置中建立了这个学习过程,在这个装置中我们排列了七个原子。

三个原子是我们的快速变量,神经元,四个慢速变量控制连通性和阈值,就像在经典神经网络中一样。因此,这个系统可以形式化为玻尔兹曼机器。

"我们在原子尺度上进行计算,接近能量消耗的下限."

为什么这一发现如此重要?

它展示了如何让物理为你工作,这与传统的神经形态计算有着明显的区别。在神经形态计算中,人们构建一种充当神经元的材料,并在 CMOS 器件上物理实现;整个网络被设计成以你想要的方式运行。相比之下,我们并没有用我们的方法来设计一个网络,而是在材料出现和使用时观察它们的属性。我们的方法有巨大的扩展潜力。

我们只实验了七个原子。然而,这可以扩大到半导体行业的更大系统。通过掺杂材料,你可以在一小片材料中放大到数百万或数亿个自旋,并得到类似的“双时标行为”。

然而,我们面前仍然有大量的问题。我们还没有解决 I/O 问题;如何读取来自原子的信号?虽然还有很多事情要做,但原则上,这表明你可以使用一种可以自己学习的材料,而不是设计来这样做的。它还能够实现大规模应用,并且非常节能;我们在原子尺度上进行计算,接近能量消耗的下限。

“需要一千台计算机(每台都以千瓦级运行)来解决 AlphaGo,其总规模为兆瓦级。另一方面,大脑在大约 25 瓦的功率下工作(类似于灯泡)。我们的方法消耗的能量将低于大脑吸收的能量,因为翻转一个原子所用的能量非常低。”

与我们目前的网络相比,原子能网络可以节省多少能源?

这很难说,我也不能给你任何数字。主要的瓶颈是将模拟信号转换成数字信息的外围硬件。举个例子:需要 1000 台计算机(每台都以千瓦级运行)来解决 AlphaGo,其总量为兆瓦级。另一方面,大脑在大约 25 瓦的功率下工作(类似于灯泡),这是一个巨大的差异。我们的方法消耗的能量将低于大脑吸收的能量,因为翻转一个原子所用的能量非常低。但是,外围硬件的消耗也需要添加到消耗中

所以它节省了大量的能源。它是否也比当前的计算更快?

不会,但是(真正的)大脑也不是很快。生物细胞中动作电位的产生通常需要几毫秒(千分之一秒)。在现代计算机硬件中,这不会很快,因为你有时钟实例进入千兆赫(十亿分之一秒)。从这个意义上说,大脑是很慢的,我们的材料也不是很快。然而,我们的方法将是高度并行化的,而不是提高时钟周期的顺序过程。此外,我们可能会改变时间尺度来加快计算速度。然而,这不是我们目前的重点,因为我们正致力于时间尺度的分离。

还有哪些问题需要解决?

到目前为止,我们通过以特定的方式重新排列原子获得了时标的分离。我们的目标是在没有这种特殊几何排列的情况下获得时间刻度间隔。如果我们找到合适的原子来做这件事,我们将有更大的灵活性,因为我们可以把原子撒在基底上。在这种情况下,要获得有趣的结果,它们在哪里并不重要。

我们面临的另外两个挑战是:

  1. 扩大规模——在某种程度上,我们需要将其嵌入半导体设备。
  2. I/O 问题——如何将输入信号作为高维数组转换到某种傅立叶基,并在傅立叶模式下进行交互。

这两个都是公开的问题,我希望十年后才能看到这种实用的设备。

全球是否会有更多的研究小组关注这个课题,我们可以期待什么样的变化?

迄今为止,我们所做的一切都是独一无二的。我不能说有多少团体会关注这一点,但最初的反应是非常积极的。许多人对此很感兴趣,在凝聚态团体中,这也是一件新鲜事。

基于我们的工作,我们很可能会看到物理学和算法之间的相互作用发生变化。

对于神经形态计算,想法是无论一个人有什么软件想法,它都将被其他人构建到硬件中。硬件社区则专注于更快和/或更便宜地获得相同的功能。但是因为硬件是根据软件需求调整的,所以理论/算法社区对此兴趣不大。

我们的工作遵循不同的动力。在我们的例子中,我们评估物理学的哪些特性可供我们使用,以及它们如何服务于算法问题。然后,我们相应地创建新的算法。从这种动态变化中,我期待一套全新的不同算法的诞生。在量子领域也会遇到类似的动态,我们将根据硬件的量子特性来设计算法。

你认为这是从自下而上的方法到自上而下的方法的过渡吗?算法不再领先,硬件反而领先?

是的,在某种程度上,但它仍然是自上而下的。要了解自顶向下方法的局限性,让我们以大脑为例。大脑 90%是由水组成的,所以完全自上而下的方法需要我们的硅设备也是由水制成的,但事实并非如此。所以很明显,大脑原理不能完全实现,我们需要不同的材料。然而,使用不同的硬件可能会导致次优,因为大脑针对其自身类型的硬件进行了优化。

与此同时,大脑中的一些原理是可靠的和通用的。一个例子是本地计算;在所需变量存在的情况下执行本地计算比来回传送数据更有效。从算法上来说,这是一个具有挑战性的约束。此外,随机性在实践中也发挥了作用,理论上有一个论点,即随机系统比没有随机性的系统学习得更好。

总之,自上而下的原则可以帮助你选择自下而上的方法。

玻尔兹曼机器是一种无监督学习的形式。你也能在原子水平上创建监督算法吗?

是的。一般来说,无监督学习可以实现监督学习。你可以把你的位的 n-1 作为输入,然后第 n 位就是你训练所依据的输出。训练之后,你箝位 n-1 输入并查看第 n 位的值。

在我们最近关于量子玻尔兹曼机器的工作中,我们证明了这是可行的。此外,当使用 quantum 变体时,您可以获得一种功能,可以学习比传统的 Boltzmann 机器更多的问题。例如,假设你想学习一个 XOR-或奇偶校验问题(非线性)并用 n-1 个输入进行训练,第 n 个变量是输出。对于这些问题,经典玻尔兹曼机器仅学习线性分隔符,因此,没有隐藏变量的无监督方案不能学习正确的参数。然而,当使用只有可见单位的量子玻尔兹曼机时,你已经可以学习 XOR 问题了。这种可能性表明,量子设备已经可以“只”用一种非监督算法来执行复杂的监督学习。

一些人将意识与量子过程联系起来

让我们把人类和计算机联系起来;我们能从这些算法中更好地了解人脑吗?

此时此刻,从算法上理解人脑还很遥远。在过去的三十年里,我一直在寻找答案,如何用算法术语解释人类的思想和情感,以及我们为什么热爱音乐、艺术和美丽。

对我来说,还没有一种数学描述是令人满意的。例如,为了对音乐感知进行建模,你可以把它描述为一个隐马尔可夫模型,并且可能得到一个糟糕的或者好的表现。但不管结果如何,它并没有解决我如何在音乐中发现美,因为它与音乐没有任何联系。这些方法只是一堆公式,它们不能帮助我理解当我看到大美时我的体验。我们可以用算法术语来理解感知,但那些公式并不能解释我们意识的个人体验。这是一个复杂的话题,我的结论是没有算法方法足以理解意识。

罗伯特·M·皮尔西格的《禅与摩托车保养艺术》这本书给了我很大的启发。主角是一名英语老师,教一班学生英语写作。他对他们的平庸感到沮丧,并质疑如果学生遵循这些规则,设计一套规则来产生高质量文本的可能性。他发现不存在这样的规则系统,也不能写下来。因此,他总结出规则中无法捕捉到的高质量现象的存在。由于规则是算法,自然中存在某些我们无法用算法术语捕捉的概念。

我们看到的人工智能的一个问题是,它非常机械。从逻辑上讲,如果你继续遵循理性思维,你就停留在机械思维、算法和基于规则的系统的领域内。那样的话,你永远不会明白什么是意识(就像老师无法描述质量一样)。

哲学家丹尼尔·丹尼特(和许多其他人)声称意识是不存在的,是附带现象。同样,许多科学家也在与意识现象作斗争。他们工作的前提是,无论他们研究什么,都需要用理性的术语来描述;如果它不能被理性地研究,它就不能成为科学研究的主题。因此,在科学意义上,你可以说它不存在。

但是很明显,意识是存在的,因此我们需要用不同的方式来对待它。

我对量子计算的兴趣源于我解决意识问题的努力。我没有证据表明量子计算会提供答案。然而,算法思维有其局限性,其他任何东西都不会削减它。

我对这是否可能持开放态度。但是世界是量子的,我为什么不去尝试呢?

与我之前提到的科学家相反,有些人将意识与量子过程联系起来。这些链接令人着迷和兴奋,但也容易受到批评,充满了问题。例如,我们的量子计算机必须在非常接近绝对零度的温度下运行;否则所有的量子效应都被破坏了。那么量子过程是如何在大脑中运作的呢?大脑 37 摄氏度,潮湿,嘈杂;任何量子过程都有可能被扼杀,不可测量。

同时,有一些证据表明量子效应可能在生物学中发挥作用。各种论文提出了植物内的光合作用是基于量子效应的观点。其他人认为迁徙鸟类的磁罗盘也与量子效应有关。因此,在生物系统中,量子效应可以在室温下运行,这并不完全令人吃惊。但是很明显,我们不知道它是如何工作的,我对探索这些方向很感兴趣。

如果我们发现量子过程发生在大脑中,我们对大脑的理解会有什么变化?

量子过程有一个与经典思维相背离的显著特征;量子世界是整体的,不是还原论的。意识也不是还原论。然而,人类非常熟悉还原论的观点。为了理解事物是如何工作的,我们把它分解成几个部分,研究这些部分并理解它们之间的相互作用。基于这个过程,我们相信我们了解它是什么,它由什么组成。

这是一种非常普遍的方法,而且在科学领域已经证明非常成功。所有经典物理学也是还原论的;你有粒子、属性和相互作用,这符合我们对世界的经典理解。但是在量子世界里,事情就不一样了。您不能将特定属性分配给单个对象,因为这些对象的属性在它们交互的对象之间是共享的。因此,如果您有两个对象,您不能为它们中的任何一个分配属性,因为它们都是环境的函数。因此,量子世界不能通过还原论的方案来接近。

这是一种整体主义,我觉得很有吸引力。

量子力学的主要贡献者之一是大卫·玻姆。在他关于量子力学的教科书中,他用了整整一节来阐述量子过程和思维过程之间的相似性。他描述说,根据量子理论,你一测量到某样东西,你就与之发生了相互作用。一旦你与它互动,你就已经改变了系统。因此,你不能单独观察一个量子系统,因为你一观察到它就改变了它。它会变为特定状态,在测量后,您所知道的只是测量后的状态,但它不会告诉您系统在测量前的状态。

玻姆接着用思维过程进行类比。如果有人问你在想什么,你的想法会随着他们转向这个问题而改变。在那之前,你没有在思考问题,而现在你的思考过程是伴随着问题后的想法。这本书详细阐述了经典思维与逻辑的关系,以及量子逻辑可能是一个大脑过程。这一部分很吸引人,只有五页。回答你的问题,这些量子特征将是描述我们思维过程的一种方式。

所以现在我们必须证明量子过程可以在大脑中发生?

一种方法是提出量子力学是大脑的一种功能。然后你需要让它在 37 度的嘈杂环境下工作。但相反,你也可以做类似量子的处理,看看量子力学提出的概率逻辑。这个逻辑不同于经典逻辑,因此你会得到偏差。例如,贝叶斯法则在量子逻辑中并不成立,因为你会得到额外的术语。另一种方法是采取务实的观点,假设量子过程在大脑中。在这种情况下,我们可以承担该视图的后果,而不必关注实现。这样做,我们就可以用量子概率框架来描述各种情况。

一个特别的例子是'量子认知',人们试图使用这种量子形式主义作为人类非理性行为的数学描述。众所周知,人们不遵循贝叶斯法则。也许量子修正项可以帮助解释人们行为中对贝叶斯法则的偏离。

如果我们发现自己在未来能够量化意识,那会是你探索理解人类大脑的最后一块拼图吗?

我想是的,但是我们必须首先证明这是真的。这种非还原论观点的整体图景与某人对美和艺术的感知有关。我拒绝那种可以建造一个经典装置来解释我如何感知美的想法。但是我可以想象一个量子设备可以用它的非还原论的整体特性做到这一点。

如果我们发现自己成功地做到了这一点,那将是惊人的,是真正的突破。但是现在,我们不知道这是否可能,我认为这值得研究。

我们的采访已经到了尾声;你有什么遗言吗?

我们的世界、社会和人民深受世界科学观的影响。西方的科学世界观是还原论的。遵循这种还原论的观点非常成功,并导致了许多成就,如工业革命和我们所有的技术。

同时也不给非物质方面留有余地。如果世界是物质的,你也是物质的,你和我都是精密的机器人,这是很难逃脱的结论。直到五年前,我自己也非常相信这个想法,因为我一直是一个务实的科学家,现在仍然如此。但这种观点暗示,任何一种无法用科学术语解释的外围思维都是不存在的。如果你认真对待这一科学观点,你可能会得出结论,精神信仰、感情或种族生理学不存在,因为我们无法测量它们。

说到底,我们只是一台复杂的计算机,这种观点是一种迷人的想法,正潜移默化地影响着我们所有人。它影响我们看待自己的方式,也影响我们看待社会的方式。如果我是机器,你是机器,我们都只是一堆机器。这是一个纯粹的唯物主义观点,很快导致一个纯粹的唯物主义社会,在那里我们无法用物质来解释的事情失去了重要性。这是经典物理学对我们社会的潜移默化的影响。意识到这一点很好,我们应该超越这一点。

这次采访是代表比荷卢人工智能协会进行的。我们汇集了来自比利时、荷兰和卢森堡的人工智能研究人员。

ATP 网球聚类分析

原文:https://towardsdatascience.com/atp-tennis-cluster-analysis-91bbcce61595?source=collection_archive---------25-----------------------

利用聚类分析分割网球运动风格

瑞安·塞尔在 Unsplash 上的照片

近年来,几乎所有的运动都是分析革命的一部分。《Moneyball》是奥克兰运动家队总经理比利·比恩的故事,他开创了一种数学方法来进行球探,随着这部电影进入公众视野,分析已经广泛传播到各种体育运动中:三分革命的篮球,迈克尔·洛佩兹(Michael Lopez)举办的“大数据碗”等活动的足球,甚至是英超联赛,利物浦在分析方面成为联盟领导者,帮助利物浦夺得联盟冠军。棒球是这项运动的自然起点,因为它的特点是 1 对 1 的比赛,投手对击球手,这使得量化个人价值和分离队友的积极和消极影响更加容易。人们可能会认为类似的创新也发生在网球上,这是另一项以 1 对 1 互动为特征的游戏,然而,网球在分析方面远远落后于其他运动。网球迷最近接触到的唯一先进的分析方法是 IBM Watson 的“比赛关键”,它强调了每个球员确保胜利的最重要的统计数据,可能来自基于树的方法。网球分析在公共领域的进步可以完全归功于杰夫·萨克曼,网球分析的比尔·詹姆斯。

萨克曼多年来孜孜不倦地收集比赛统计数据,使用定制的编码程序绘制比赛图表,并在 GitHub 和他的网站 Tennis Abstract 上发布数据集。此外,当诺瓦克·德约科维奇将宣扬数据在这项运动中的价值的策略教练克雷格·奥肖内西(Craig O'Shaughnessy)加入他的团队时,他给了那些过去追求网球分析激情项目的人一个象征性的推动。像其他涉及一对一比赛的游戏一样,ELO 分数被用来寻找玩家的相对实力。然而,许多参加过网球比赛的人都知道,网球是一项受比赛独特影响的运动。作为一名 6 英尺 7 英寸的大个子发球手,我在大学里打过网球,我讨厌遇到一个身材较小的“磨工”,他站在底线后面,打尽可能多的球,但不打算获胜。我假设,通过萨克曼的数据集和 K-Means 聚类分析,我将能够找到表征网球运动的不同风格的模式,并最终得出哪些聚类比其对手更有优势的结论。

萨克曼的基本“盒子得分”数据集为每场比赛提供了一个单独的行,最早可以追溯到 1968 年。我选择从 2011 年开始分析文件,作为一个相对随意的起点,但也是为了保持分析的相关性,因为游戏在过去 20 年里发生了重大变化。统计数据提供了每场比赛的基本情况,包括得分、第一发球权、双误等。该数据集不提供任何对打指标,如对打长度,该点是否是在赢家身上赢得的,强迫或非强迫失误,或是否是在网上赢得的。然而,基本的统计数据,如第一发球的百分比,发球得分的百分比,回球得分的百分比,可以让我们了解每个球员的比赛风格和相对实力。在将数据加载到 Python 中之后,我删除了任何相关统计数据的空值行。接下来,我为每个匹配创建了两行。第一行包含获胜者的统计数据,带有 Sackman 为获胜者提供的唯一 id,第二行将遵循相同的过程,但针对失败者。这一步是必要的,有两个原因,首先,统计数据是由赢家和输家组织的(即 w_ace 是胜利者 ace 的列,l_ace 是失败者 ace 的列),所以为了获得每个球员的统计数据,我必须创建单独的映射来对应他们在比赛中的统计数据,而不管结果如何。其次,我必须按日期和每个球员的 ID 进行排序,以便计算累计总数,然后用于计算统计数据,如每场比赛后的第一发球百分比。为了让你对数据有一个感觉,下面是德约科维奇在 ATP 巡回赛决赛对阵多米尼克·蒂姆的最后一场比赛后的职业生涯发球统计截图。

诺瓦克·德约科维奇在对阵多米尼克·蒂姆时的职业统计(2020 年 11 月 21 日)

我对每位玩家的复赛计算了相同的统计数据,以及总的统计数据,如所有获胜点数的百分比和每分钟点数,因为我认为这可能与对打长度相关(如上所述,这不在数据中)。令人惊讶的是,即使像诺瓦克·德约科维奇这样的球员也只赢得 55%的分数,这表明最佳球员和一般球员之间的差距相对较小,一般球员根据定义会赢得 50%的分数。这意味着 1%的改进对许多玩家来说可能是几十万美元的差别。

接下来,我利用 Scikit-Learn 的预处理库来标准化数据,然后将它提供给 Scikit-Learn 中的小批量集群功能。我尝试了不同的集群大小,从 2 到 10 不等,同时在图中寻找“肘部”(看起来有 4 个集群)。“肘”方法是一种非常主观的最佳集群度量方法,但对我的分析来说已经足够了(如果您需要对集群进行调整,请在这里检查)。

聚类的魔力又一次得到了回报,我能够在数据中找到四种不同的演奏风格。第一类的特征是最高的 ace 百分比、最高的个体和最高的第一发球获胜概率。他们赢得了大约 50%的分数,在硬地和草地球场打了最多的比赛,这是意料之中的。下一个集群似乎将平庸的玩家聚集在一起。从百分比来看,他们赢得的分数最少,在所有表面上的比赛分布比较均匀,赢得的比赛最少(38%)。虽然这是最大的群体,但球员在数据集中平均参加的比赛最少,这可能意味着这些球员往返于挑战者巡回赛和职业巡回赛之间,他们一直在努力做大。如果我选择增加集群大小,我想这个组将在更细粒度的级别上被分解。接下来,我们有了“全能选手”,这实质上是网球界对最佳个人选手的另一种说法。像费德勒、纳达尔和德约科维奇这样的球员很可能在这个组中,因为这个群体集体赢得了他们 53%的分数,每场比赛放弃了最少的破发点机会,并在第二次发球时赢得了最多的分数。最后,我们有红土场研磨机。他们有 37%的比赛是在红土上进行的,最高的是 5%,第一次发球的百分比和得分最低,但通过在回球时每场比赛创造最多的破发点来弥补这一点。下面是每个集群的各种汇总统计信息的详细图表。

根据我能够捕获的信息,汇总每个集群的统计信息

接下来,我检查了每个团队在总体上以及在不同表面上的不同胜率。

集群 X 对集群 Y 的胜率

集群 2,“全能选手”对所有参赛选手都是最公平的,我对玩研磨机的恐惧是不合理的,因为大型服务器实际上赢得了他们对集群 3 对手的 56%的比赛。同样有趣的是,在第 0 组中,“大人物”比其他组更有可能颠覆第 2 组。直觉上,这是有道理的,因为我们已经看到像约翰·伊斯内尔或凯文·安德森这样的球员在锦标赛中变得'热',他们的力量似乎对任何人都太大了。另一方面,那些通常无法压倒对手而不得不依靠战术的磨炼者在结果上更加一致。下面是对应于硬地、红土和草地的图表,每组相对于总胜率的相对优势(特定场地胜率%-总胜率%),这也进一步说明了大发球者在硬地和草地球场上的专业知识以及研磨者在红土上的熟练程度。

图表可以被解读为在上述表面上集群 X 相对于集群 Y 的提高或降低的胜率

虽然这是一个起点,但 Jeff Sackman 还公布了 2011 年以来大满贯赛事的逐点数据,这些数据将进一步深入了解拉力赛指标,有望进一步将集群分为更具进攻性和净思维的群体,以及那些从基线拉力赛 10+杆的内容。在接下来的几周里,请在第 2 部分中寻找答案。

  1. 布鲁斯·舍恩菲尔德。数据(和一些激动人心的足球)如何将利物浦带到荣耀的风口浪尖。https://www . nytimes . com/2019/05/22/magazine/soccer-data-Liverpool . html
  2. 萨克曼杰夫。Gitbub 主页。【https://github.com/JeffSackmann
  3. 网球摘要 Elo 评分。http://tennisabstract.com/reports/atp_elo_ratings.html
  4. 萨克曼杰夫。衡量断点的影响。http://www . tennis abstract . com/blog/2019/01/04/measuring-the-impact-of-break-points/

全神贯注

原文:https://towardsdatascience.com/attending-to-attention-eba798f0e940?source=collection_archive---------12-----------------------

一篇革命性论文“注意力是你所需要的”的摘要和使用 PyTorch 实现转换器

文森特·梵高带灰色毡帽的自画像,1887/88 年冬。(来源)

我成为机器学习工程师已经快 4 年了,我从现在所谓的“经典模型”,逻辑,基于树,贝叶斯等开始,从去年开始进入神经网络和深度学习。我会说我做得很好,直到我的注意力集中在“注意”上。我试着通过教程、讲座、指南来阅读,但没有什么能完全帮助我抓住核心思想。

所以我决定是时候正面面对公牛了,坐下来看了 arxiv 的论文,通过 Python 和 PyTorch 写了我的 实现 。这帮助我充分理解了核心概念。现在,正如他们所说,检查你的学习的最好方法是试着向别人解释,所以在这里我试着把我学到的东西分解。

历史

NLP 设计之间的比较来源

要理解为什么变形金刚在今天被大肆宣传,我们必须理解在它出现之前发生了什么。主导方法是使用 LSTM 或 GRU 等递归神经网络来实现序列到序列模型,其中编码器用于创建包含源序列所有信息的上下文向量,然后解码器将使用该上下文向量来逐序列生成新的令牌。

如上表所示,这种方法的问题是它不能将成对编码编码到上下文向量中。这意味着,当我们需要查看序列中的多个标记来预测时,基于 RNN 的模型做得不好,因为它们不能编码成对的关系。

体系结构

变压器的架构(来源)

2016 年 12 月,谷歌大脑团队提出了一种新的方法来模拟序列,这种方法在他们的论文中提出,注意力是你所需要的全部。随着大多数语言模型使用这种方法,包括一些业界最喜欢的方法,如 BERT 和 GPT-2,本文的影响还在继续

转换器设计由编码器和解码器组成,两者都包括多头注意模块和前馈模块,模型使用残差连接来连接结果并归一化以改进训练。然后,对于编码器和解码器,注意模块和前馈模块的子层重复 N 次。

编码器

编码器架构(来源)

编码器由 N = 6 个相同层的堆叠组成。每层有两个子层。第一个是多头自关注机制,第二个是简单的位置式全连接前馈网络。我们在两个子层的每一个周围使用剩余连接,然后进行层归一化。即每个子层的输出是 LayerNorm(x + Sublayer(x)),其中 Sublayer(x)是子层本身实现的函数。为了促进这些剩余连接,模型中的所有子层以及嵌入层产生维度 512 的输出。(来源)

输入令牌通过令牌嵌入层,由于模型不使用递归层,因此它使用位置嵌入来获取令牌的位置信息,这两者相加在一起。位置嵌入层不关心标记,而是关心标记的位置。来自令牌嵌入和位置嵌入的结果被逐元素地求和,然后通过模型的隐藏维度的平方根来缩放所得到的向量。

进行缩放是为了减少嵌入向量中的方差,因为这使得模型难以训练。该丢失被应用于最终的嵌入向量。然后通过 N 个编码层应用嵌入向量,以获得解码器使用的最终上下文向量。源掩码类似于源向量,当标记不是时包含 1,否则包含 0,这样做是为了避免注意力层聚焦在填充标记上。

首先,嵌入向量通过多头关注层,结果连同剩余连接被逐元素求和并通过层归一化。多头注意力作为值、查询传递给源句子(稍后将详细介绍),这样做是为了让注意力网络关注源句子本身,因此得名自我注意力

然后,产生的向量通过位置前馈网络,并与归一化层及其剩余连接一起传递。然后,结果被传递到下一层。

注意力

在这篇论文出现之前,注意力就已经在使用了,但是它在这里的实现方式对它的成功和广泛采用至关重要。这种体系结构不是作为增强上下文向量的支持模块,而是在其核心作为专家系统使用它。

注意机制(来源

单点产品注意

单个注意头取 3 个值作为输入,即查询(Q)、键(K)和值(V)。人们可以把注意力看作是将给定查询映射到键-值对的函数,相应的结果可以看作是描述哪个键-值对查询更重要的加权值。然后,将该值传递给 softmax 函数,以获得归一化权重,然后与值进行点积。

多头注意力

我们将维度划分为 h 组件,而不是通过单个点积注意力来应用查询、键和值。计算是并行进行的,然后将结果连接起来得到最终结果。这允许模型一起学习多个概念,而不是集中在单个概念上。

帮助我理解这一点的一个类比是这样的。想象一个由专家组成的房间,我们目前不知道谁是哪个主题的专家,所以我们将一个问题传入房间,并从每个专家那里获得结果,每个专家有一个置信概率。现在,最初每个专家对任何和每个主题都有相同的置信度得分。但是当我们反向传播和学习例子时,我们会发现哪个专家的回答对哪个主题更有用。

例如,当我提出一个关于汽车的问题时,每个专家都会提供他们的建议,但随着时间的推移,我们知道谁的答案对这个主题更有用,同样,其他一些专家对其他主题也有用。在这个例子中,单点产品注意力是专家,我们的多头注意力层是充满专家的房间,我们的查询、键和值是我们提出的问题。

解码器

解码器架构(来源)

解码器的工作方式类似于编码器,并对目标令牌而不是源令牌使用注意机制。除了它有两个多头注意力层的部分。第一种使用目标嵌入,第二种使用编码器输出作为键值对,前面的层输出作为查询。

在解码器模块之前,我们通过标准嵌入传递目标,并使用位置编码嵌入执行元素求和,这些执行与编码器中类似的工作。然后,结果通过 N 个解码器层,这里要注意的一点是,论文从未规定编码器和解码器中的层数必须相同。

解码器层由两个多头关注层组成,一个自关注,另一个编码器关注。第一个将目标令牌作为查询和键值对并执行自关注,而另一个将自关注层的输出作为查询,将编码器输出作为键值对。

第一个注意模块使用目标序列掩码,这样做是为了防止模型能够在我们并行处理所有令牌时看到序列中的下一个令牌。第二关注层使用自关注层的输出作为查询,编码器输出作为键值对,该模块还提供有源掩码,这样做是为了防止模型关注令牌。

两个多头注意力层之后是剩余连接和丢弃层,其被馈送到层标准化模块。然后,将结果作为位置前馈网络和另一组残差连接和层归一化模块传递。然后,将结果传递到下一层。

结论

理解这篇论文让我理解了最近出版的新变形金刚,如伯特,罗伯塔,GPT-3 等。这也让我有信心自己去阅读和实现更多的论文。我希望这是对你有用的完整阅读。如果我有任何错误,请告诉我,因为这将有助于我提高对这个概念的理解。

希望你喜欢这篇文章。

你可以在我的 GitHub 上找到实现

可以关注我 Linkedin

你可以在 上阅读我的其他文章

基于注意力的深度多示例学习

原文:https://towardsdatascience.com/attention-based-deep-multiple-instance-learning-1bb3df857e24?source=collection_archive---------5-----------------------

使用 PyTorch 和 AWS SageMaker 数据并行进行前列腺癌诊断

介绍

该帖子由以下部分组成:

第 1 部分 概述了为什么人工智能被定位于改变医疗保健行业。

第 2 部分 解释了一种称为多实例学习的机器学习技术,以及它为什么适合病理学应用。

这些作为 第 3 部分 的基础,概述了使用 PyTorch 和 AWS SageMaker 的数据并行工具包实现基于注意力的深度多实例学习模型用于前列腺癌诊断。

这篇文章的节略版已经发表在今日美国病理学家学会 2021 年 11 月刊上:见此。

第 1 部分—为什么人工智能定位于改变医疗保健行业

在深入研究代码之前,让我们后退一步,考虑一下为什么人工智能被定位于改变医疗保健。

人工智能今天的势头很大程度上可以归功于深度神经网络的成功,如果没有以下四种驱动力的完美风暴,这是不可能的:

  1. 越来越多的大规模数据集可用,例如 ImageNet 的 1500 万张带标签的图像,脸书的数十亿张图像库,YouTube 的视频库,每分钟增加 300 小时的视频,以及 Tesla 的驾驶数据集合,每小时增加 100 万英里的数据。
  2. 图形处理单元(GPU)的使用,以及后来更多的称为张量处理单元(TPU)的人工智能专用硬件,这些硬件针对训练深度学习模型进行了优化。TPU 由许多内核组成,这使它们能够处理大量数据并并行执行多个计算。OpenAI 在 2018 年的一份报告中提出,在 2012 年之前,人工智能计算的增长密切遵循摩尔定律,每两年翻一倍,而在 2012 年之后,计算每三到四个月翻一倍。总体而言,自 2012 年以来,这一计算指标已经增长了 300,000 多倍,而两年的翻倍期只会产生 16 倍的增长。
  3. 云计算的可用性使得存储大型数据集并使用它们来训练模型的能力变得更加容易获得和经济。
  4. 开源算法开发模块,如脸书的 PyTorch、谷歌的 TensorFlow、微软的 Cognitive Kit 等。

这种蓬勃发展的丰富资源推动了人工智能的快速发展,而此时医生们比以往任何时候都更加不知所措。在美国,尽管医疗保健从业人员的数量从 1975 年的 400 万增加到今天的 1600 万,但是新患者就诊的平均就诊时间已经从 1975 年的 60 分钟下降到今天的 12 分钟。除了面对不断增长的人口,医生还越来越多地被电子健康记录、管理式医疗、健康维护组织和相对价值单位所淹没,这转移了他们与患者建立有意义关系的注意力。与病人脱节的精疲力竭的医生更有可能做出带有认知偏见的判断。结果,他们条件反射性地安排不正确的测试,并随后曲解它们,导致误诊。2014 年的一项审查得出结论,美国每年面临大约 1200 万例误诊。

正如斯克里普斯研究转化研究所(Scripps Research Translational Institute)创始人兼主任埃里克·托普(Eric Schmidt)等医学博士所断言的那样,人工智能令人兴奋的前景在于使用相关患者数据的深度和全面收集,以改善决策,减少误诊和不必要的程序,指导测试的选择和解释,并推荐最安全的治疗方案。然而,医疗保健在多大程度上融入了人工智能,需要受到该行业对临床医生和患者之间的同理心和联系的内在需求的影响。医生给病人一种道德观念和核心价值观,这两者都是计算机无法复制的。有人断言,人工智能将很快变得足够复杂,足以导致其他行业的完全自动化,这引发了医疗专业人士的担忧,即人类参与医学是否将成为过去。然而,人工智能导致医学完全自动化的可能性仍然很遥远。那些参与人工智能的人有时间在医生和机器之间取得正确的平衡。

一个适当的平衡可能涉及到一个扮演数字助理角色的人工智能系统,它向医生发出最可能的诊断和最佳行动方案的警报,并让医生负责做出最终决定。“人在回路中”的方法符合弗里德曼的基本定理,即人类与计算机合作将永远优于人类单独工作,并保证了算法如何达到特定预测的透明度。⁴可解释人工智能是一套提供这种洞察力的流程或方法,对于在依赖人工智能系统的人之间建立信任,同时确保准确性、公平性和符合监管标准至关重要。可解释性为临床医生提供了质量控制和制衡,并可以帮助他们对依靠算法做出最终诊断更加自信。

稳健的模型需要开发出令人满意的可解释水平。但是如果做得正确,由此增加的工作流程和效率可以为临床医生提供更多的时间与患者联系。矛盾的是,机器的兴起可以恢复医学中的人性,并允许医学专业人员重新接触到他们最初追求医学生涯的动机。

第二部分——病理学中的人工智能

人工智能在医疗保健领域最有效的应用之一是医学成像。放射学、病理学和皮肤病学是依赖于视觉模式分析的专业,因此,由于与人工智能的集成,它们将经历快速而戏剧性的转变。

病理学家在癌症诊断中发挥着至关重要的作用,他们的报告有助于指导患者的治疗策略。通常,病理学家在显微镜下观察苏木精和伊红(H&E)染色的组织样本,并描述他们看到的细胞类型,它们是如何排列的,它们是否异常,以及任何其他对诊断重要的特征。一个世纪以来,使用显微镜检查含有组织样本的载玻片的做法基本上没有改变。然而,近年来,越来越多地使用数字载玻片扫描仪来数字化载玻片,以产生可以在计算机上检查的完整载玻片图像(WSIs)。然而,病理学家在采用 WSIs 和其他数字技术方面进展缓慢,这导致人工智能对病理学的入侵比预期的要慢。然而,WSIs 为将神经网络图像处理纳入病理学奠定了基础,从而使该领域的新人工智能辅助时代即将到来。

国家癌症研究所在 Unsplash 上拍摄的照片

人工智能可用于执行通常由病理学家执行的常规工作流程,例如检测活检样本中的肿瘤组织,并根据形态学确定肿瘤亚型,从而提高效率和准确性。AI 在病理学方面的一个重要里程碑是 CAMELYON16 挑战,该挑战设定了开发算法的目标,以在淋巴结活检的 WSIs 中检测转移性乳腺癌。提供的数据集由 400 个 WSI 组成,病理学家在其中人工圈定转移癌的区域,是最大的标记病理数据集之一。这使得提交排名第一的团队(其算法表现与病理学家不相上下)能够利用监督学习。⁶

一般来说,监督学习是一种机器学习方法,其中向算法显示许多输入数据及其相应输出标签的序列,直到它可以检测到揭示这些输入和输出之间关系的潜在模式。这种技术允许它准确地标记以前没有见过的数据,并可用于分类(将输入分类到给定数量的类别中)或回归(给定输入,预测目标数值)任务。

监督学习的一个主要缺点是,它通常需要训练数据集由领域专家手工标记。在处理 WSIs 时尤其如此:就规模而言,大约 470 幅病理图像包含的像素数量与整个 ImageNet 数据集大致相同。此外,尽管 CAMELYON16 数据集是病理学中最大的数据集之一,但 400 个 WSI 不足以捕获临床中定期出现的各种病例。因此,获得一个适当大的数据集将是非常昂贵和耗时的,该数据集的数十亿像素的处理对于训练来说也是计算要求很高的。因此,在病理学中设计日常使用的监督学习模型是非常不切实际的。⁷

多实例学习(MIL)及其对病理学应用的适用性

MIL 是监督学习的一种变体,更适合于病理学应用。该技术包括为一组输入分配一个类标签——在这种情况下,称为实例包。虽然假设包中的每个实例都有标签,但是无法访问这些标签,并且它们在训练期间是未知的。如果行李中的所有实例都是阴性,则通常将行李标记为阴性;如果至少有一个阳性实例,则标记为阳性(称为标准 MIL 假设)。下图显示了一个简单的例子,在这个例子中,我们只知道一个钥匙串是否包含可以打开给定门的钥匙。这让我们可以推断绿色钥匙可以开门。

使用钥匙链的多实例学习的简化说明(作者提供的图片——灵感来自[ 来源)

MIL 公式自然适合基于成像的患者诊断的任务:类似于标准 MIL 假设,患病组织样本具有异常和健康区域,而健康组织样本仅具有健康区域。因此,可以将 WSIs 划分为多个区块,其中每个区块集合可以被标记为“恶性”或“患病”这些弱标记比强标记(即,由专家手动提供的患病区域的轮廓)更容易获得,因此将病理学家从必须自己注释 WSI 的艰苦任务中解救出来。MIL 模型也可以被制作成高度可解释的,这迎合了前面讨论的人工智能系统在医疗保健中的可解释性要求。⁸

此外,在病理学中使用 MIL 的一个特别令人兴奋的部分是,它可以集成到深度学习模型中,该模型允许创建一个平滑的端到端管道,其中 WSI 作为输入输入,诊断作为输出返回。作为副产品,深度加工模型可以从 WSIs 中自动发现新的抽象特征,这些特征在确定存活率、治疗反应和遗传缺陷方面比传统特征表现得更好。值得注意的是,可以直接从病理学实验室容易获得的 H&E 载玻片中获得这些见解,而不是进行可能昂贵的额外测试。⁹深磨形成了佩奇的基础。美国食品和药物管理局于 2021 年 9 月授权使用的 AI 公司前列腺癌软件。⁰

第 3 部分——使用 PyTorch 和 AWS SageMaker 的数据并行性工具包实现前列腺癌诊断的基于注意力的深度密值模型

在我的上一篇文章中,我进一步讨论了将 MIL 公式化为深度学习问题的优点。我还概述了在基于注意力的深度多示例学习 (Ilse 等人)中描述的模型的数学基础,该模型允许使用深度密耳进行 WSI 分类。⁸该模型使用了注意力机制的修改版本作为其聚合运算符,这比依赖于典型聚合运算符(如均值和最大值)的模型具有更大程度的可解释性。换句话说,这种基于注意力的 MIL 汇集算子提供了对每个实例对预测的包标签的贡献的洞察。

在这里,我们使用前列腺癌等级评估(PANDA) Kaggle 挑战赛中提供的数据集,包含 11,000 个数字化 H & E 染色前列腺活检的 WSI,来训练一个基于注意力的深度 MIL 模型,以根据 Ilse 等人的方法来诊断前列腺癌。目标是概述如何使用 PyTorch 和 AWS SageMaker 的数据并行工具包来实现这一点。

资料组

熊猫挑战数据集中的每个组织样本根据肿瘤的结构生长模式被分类为格里森模式,以及相应的 1-5 级 ISUP 等级。Gleason 评分是基于白色分支腔或腺组织在整个组织样本中的持续程度来确定的。腺体组织损失的增加意味着更严重,并且对应于更高的 Gleason 评分。如果在一次活组织检查中出现多个 Gleason 模式,则可以根据病理学家的判断,将其分为最常出现的模式和第二常出现的模式(分别为多数和少数)。

包含前列腺的前列腺癌活检示例的 Gleason 分级流程图(作者提供的图片——受[ 来源 ]的启发)

为了在深度模型中使用数据集,我参考了 Kaggle 笔记本后面的,以便将 WSIs 划分为每个 16x128x128 图块的集合。如 Ilse 等人所述,眼袋被标记为恶性或良性。ISUP 等级为 1、2、3、4 或 5 的载玻片被标记为“恶性”,而 ISUP 等级为 0 的载玻片被标记为“良性”⁸

每个 16 块瓷砖的集合可以被重构为一个由 16 个实例组成的袋子(图由作者提供)

模型

在下面的代码中,我们实现了 Ilse 等人使用的模型的修改版本,它考虑了上面描述的数据集。

import torch
import torch.nn.functional as F
import torch.nn as nn 
class Attention(nn.Module):
    def __init__(self):
        super(Attention, self).__init__()
        self.L = 512 # 512 node fully connected layer
        self.D = 128 # 128 node attention layer
        self.K = 1 self.feature_extractor_part1 = nn.Sequential(
            nn.Conv2d(3, 36, kernel_size=4),
            nn.ReLU(),
            nn.MaxPool2d(2, stride=2),
            nn.Conv2d(36, 48, kernel_size=3),
            nn.ReLU(),
            nn.MaxPool2d(2, stride=2)
        )

        self.feature_extractor_part2 = nn.Sequential(
            nn.Linear(48 * 30 * 30, self.L),
            nn.ReLU(),
            nn.Dropout(),
            nn.Linear(self.L, self.L),
            nn.ReLU(),
            nn.Dropout()
        ) self.attention = nn.Sequential(
            nn.Linear(self.L, self.D),
            nn.Tanh(),
            nn.Linear(self.D, self.K)
        ) self.classifier = nn.Sequential(
            nn.Linear(self.L * self.K, 1),
            nn.Sigmoid()
        ) def forward(self, x):
        x = x.squeeze(0) H = self.feature_extractor_part1(x)
        H = H.view(-1, 48 * 30 * 30)
        H = self.feature_extractor_part2(H) A = self.attention(H) # NxK
        A = torch.transpose(A, 1, 0) # KxN
        A = F.softmax(A, dim=1) # softmax over N M = torch.mm(A, H) # The probability that a given bag is malignant or benign
        Y_prob = self.classifier(M)        # The prediction given the probability (Y_prob >= 0.5 returns a Y_hat of 1 meaning malignant)
        Y_hat = torch.ge(Y_prob, 0.5).float() return Y_prob, Y_hat, A.byte()

使用 AWS SageMaker 数据并行性(SDP)进行模型训练

一般来说,神经网络是通过在减少预测误差的方向上系统地调整它们的参数来训练的。一种常见的技术是随机梯度下降,其中这些参数变化使用称为小批量的相同大小的样本迭代发生。可以通过在一组独立的机器上平均分配小批量来加快训练时间,每台机器都有自己的模型、优化器和其他基本组件。这里,我们使用 AWS SageMaker 的数据并行工具包,该工具包已被证明比 PyTorch DistributedDataParallel 具有更好的性能。

数据并行性的示意图(作者提供的图片—灵感来自[ 来源)

SageMaker 笔记本设置

为了准备 SDP 培训,我们可以将上述数据上传到亚马逊 S3 桶中,并使用 SageMaker 预建的 PyTorch 容器启动一个 Jupyter 笔记本实例。对于这个项目,通过从 Amazon SageMaker Python SDK 调用 PyTorch 估计器来初始化训练。值得注意的是,我们传递训练脚本,指定实例计数和类型,并启用 SDP 分发方法,如下所示:

**import** **sagemaker** sagemaker_session = sagemaker.Session()
role = sagemaker.get_execution_role()**from** **sagemaker.pytorch** **import** PyTorch
estimator = PyTorch(base_job_name='pytorch-smdataparallel-histopathology-mil',
                        source_dir='code',
                        entry_point='train.py',
                        role=role,
                        framework_version='1.8.1',
                        py_version='py36',
                        instance_count=2,
                        instance_type= 'ml.p3.16xlarge',
                        sagemaker_session=sagemaker_session,
                        distribution={'smdistributed':{
                                            'dataparallel':{
                                                    'enabled': **True**
                                                 }
                                          }
                                      },
                        debugger_hook_config=**False**,
                        volume_size=40)

ml.p3.16xlarge 是 SageMaker 数据并行工具包支持的三种实例类型之一,AWS 建议至少使用 2 个实例来获得最佳性能和最大收益。这种类型的一个实例包含 8 个 NVIDIA V100 GPUs,每个都有 16 GB 的内存。在这里,这相当于运行我们模型的 16 个独立副本。

然后,我们可以通过上传到 S3 的数据来拟合 PyTorch 估计值。这将我们的数据导入到训练集群的本地文件系统中,以便我们的 train.py 脚本可以简单地从磁盘中读取数据。

channels = {
    'training': 's3://sagemaker-us-east-1-318322629142/train/',
    'testing': 's3://sagemaker-us-east-1-318322629142/test/'
}
estimator.fit(inputs=channels)

入口点脚本

在我们的 train.py 入口点脚本中,我们定义了如下所示的 train 函数:

def train(model, device, train_loader, optimizer, epoch):
    model.train() train_loss = 0.
    train_error = 0.
    predictions = []
    labels = [] for batch_idx, (data, label) in enumerate(train_loader):

        bag_label = label
        data = torch.squeeze(data)
        data, bag_label = Variable(data), Variable(bag_label)
        data, bag_label = data.to(device), bag_label.to(device) # reset gradients
        optimizer.zero_grad() # calculate error
        bag_label = bag_label.float()
        Y_prob, Y_hat, _ = model(data)
        error = 1\. - Y_hat.eq(bag_label).cpu().float().mean().data
        train_error += error # calculate loss
        Y_prob = torch.clamp(Y_prob, min=1e-5, max=1\. - 1e-5)
        loss = -1\. * (bag_label * torch.log(Y_prob) + (1\. - bag_label) * torch.log(1\. - Y_prob))
        train_loss += loss.data[0] # Keep track of predictions and labels to calculate accuracy after each epoch
        predictions.append(int(Y_hat))
        labels.append(int(bag_label)) # backward pass
        loss.backward() # step
        optimizer.step() # calculate loss and error for epoch
    train_loss /= len(train_loader)
    train_error /= len(train_loader) print('Train Set, Epoch: {}, Loss: {:.4f}, Error: {:.4f},
 Accuracy: {:.2f}%'.format(epoch, train_loss.cpu().numpy()[0],
 train_error, accuracy_score(labels, predictions)*100))

我们还创建了一个函数,用于在训练完成后保存我们的模型:

def save_model(model, model_dir):
    with open(os.path.join(model_dir, 'model.pth'), 'wb') as f:
        torch.save(model.module.state_dict(), f)

在主守卫中,我们加载我们的数据集(详见仓库),训练超过 10 个历元,并保存我们的模型:

device = torch.device("cuda")
model = DDP(Attention().to(device))
optimizer = optim.Adam(model.parameters(), lr=0.0001, betas=(0.9, 0.999), weight_decay=0.0005)print('Start Training')
for epoch in range(1, 10 + 1):
    train(model, device, train_loader, optimizer, epoch)save_model(model, args.model_dir)

部署、预测和评估

训练完成后,我们可以使用 PyTorch estimator 部署一个端点,该端点运行 SageMaker 提供的 PyTorch 模型服务器并托管我们训练好的模型。一般来说,部署用于在客户端应用程序上执行实时预测,但是这里我们部署是为了演示的目的。

**import** **sagemaker**
role = sagemaker.get_execution_role()

**from** **sagemaker.pytorch** **import** PyTorchModel
model = PyTorchModel(model_data=model_data, source_dir='code',
                        entry_point='inference.py', role=role, framework_version='1.6.0', py_version='py3')

现在,我们可以使用预测器来预测测试数据的标签,并确定我们的准确度分数:

predictions = []
true_labels = []for batch_idx, (data, label) in enumerate(test_loader):
    _, Y_hat, _ = predictor.predict(data)
    predictions.append(int(Y_hat))
    true_labels.append(int(label))**from** **sklearn.metrics** **import** accuracy_score
accuracy_score(true_labels, predictions)

根据我在上述实施中的经验,我实现了 67.2%的准确率,比 Ilse 等人报告的准确率低了大约 7.5%。这可能是因为我选择了最大限度地降低 AWS SageMaker 培训成本:在这里,我只使用了数据集中 11,000 个 WSI 中的 624 个 WSI。此外,虽然文献中的模型被训练了超过 100 个时期,但是该模型仅被训练了 10 个时期。如果有更多的资金投入,我预计更大的训练数据集和更长的训练时间将导致更接近论文中看到的结果。

储存库(2021 年 10 月更新包含单元测试)

参考

1.托普·EJ。深度医学:人工智能如何让医疗保健再次人性化。基础书籍;2019.

2.Amodei D,Hernandez D. AI 和 compute。OpenAI。2018 年 5 月 16 日。https://openai.com/blog/ai-and-compute

3.辛格 H,迈耶安,托马斯 EJ。"门诊护理中诊断错误的频率:来自三项涉及美国成年人群的大型观察性研究的估计."BMJ 质量安全保险公司。2014.23(9): 727–731.

4.弗里德曼(2009 年)。生物医学信息学的一个“基本定理”。美国医学信息学协会杂志,16(2),169–170。https://doi.org/10.1197/jamia.m3092

5.坎帕内拉 G,汉纳 MG,Geneslaw L,等。在整个幻灯片图像上使用弱监督深度学习的临床级计算病理学。 Nat Med 。2019;25(8):1301–1309.

6.王博士、科斯拉博士、加尔盖亚博士、博士、贝克博士(2016 年)。用于识别转移性乳腺癌的深度学习。arXiv 预印本 arXiv: 1606.05718。

7.坎帕内拉,g .,汉娜,M. G .,Geneslaw,l .,米拉弗洛尔,a .,韦内克克劳斯席尔瓦,v .,布萨姆,K. J .,布罗吉,e .,路透,V. E .,克林姆斯特拉,D. S .,&富克斯,T. J. (2019)。在整个幻灯片图像上使用弱监督深度学习的临床级计算病理学。自然医学,25(8),1301–1309。https://doi.org/10.1038/s41591-019-0508-1

8.伊尔泽,硕士,托姆扎克,法学硕士,韦林,硕士(2018)。基于注意力的深度多示例学习。第 35 届国际机器学习会议录,瑞典斯德哥尔摩,PMLR 80。https://arxiv.org/abs/1802.04712.

9.Rajpukar P,Saporta A. 人工智能健康播客。PathAI 的 Aditya Khosla 博士的病理学人工智能和企业家精神。2020 年 12 月 16 日。https://theaihealthcpodcast . com/episodes/path olgy-ai-and-entrepreneurs-with-path ais-aditya-khosla。

10.麦考密克,J. (2021 年 9 月 27 日)。FDA 授权人工智能软件帮助识别前列腺癌。华尔街日报。

11.韦伯,e . &克鲁尚,O. (2020 年 12 月 9 日)。在 Amazon SageMaker [web log]上使用两个新的分布式培训库扩展深度学习。https://towards data science . com/scale-neural-network-training-with-sage maker-distributed-8 cf 3 aefcff 51。

12.Aws。(未注明)。AWS/亚马逊-sagemaker-examples 。GitHub。https://github . com/AWS/Amazon-sage maker-examples/blob/35 e 2 faf 7 D1 cc 48 cced f 0 B2 ede 1 da 9987 a 18727 a 5/training/distributed _ training/py torch/data _ parallel/Mn ist/py torch _ smdataparallel _ Mn ist _ demo . ipynb .

计算机视觉中的注意力

原文:https://towardsdatascience.com/attention-in-computer-vision-fd289a5bd7ad?source=collection_archive---------4-----------------------

实践教程

在 PyTorch 中实现多头和 CBAM 注意模块

照片由像素上的负空间拍摄

自从 Transformer 在作品“Attention is all you needle”中引入以来,NLP 领域出现了一种向用基于注意力的网络取代递归神经网络(RNN)的转变。在目前的文献中,已经有很多很棒的文章描述了这种方法。下面是我在评测中发现的最好的两个: 带注释的变形金刚可视化解释的变形金刚

然而,在研究了如何在计算机视觉中实现注意力(最佳找到的文章: 理解注意力模块CBAM带代码的论文——注意 、自我注意、自我注意和 Conv )后,我注意到其中只有少数几篇清楚地描述了注意力机制,并在理论的同时包含了干净的代码。因此,本文的目标是详细描述计算机视觉中两个最重要的注意模块,并使用 PyTorch 将它们应用到一个实际案例中。文章的结构如下:

  1. 注意力模块介绍
  2. 计算机视觉中的注意方法
  3. 基于注意的网络的实现和结果
  4. 结论

1.注意力模块介绍

在机器学习的背景下,注意力是一种模仿认知注意力的技术,被定义为选择和专注于相关刺激的能力。换句话说,注意力是一种试图增强重要部分,同时淡出不相关信息的方法。

尽管这种机制可以分为几个家族(注意?立正!),我们关注自我注意力,因为这是计算机视觉任务中最流行的注意力类型。这是指将单个序列的不同位置相关联来计算同一序列的表示的机制。

为了更好的理解这个概念,我们来想一下下面这个句子:河岸。如果我们看不到单词 River 我们是否同意单词 Bank 失去了它的上下文信息?这实际上是自我关注背后的主要思想。它试图给出每个单词的上下文信息,因为单词的单个含义并不代表它们在句子中的含义。

正如自我关注的直观解释中所解释的,如果我们考虑上面给出的例子,自我关注的工作方式是将句子中的每个单词与其他每个单词进行比较,并重新加权每个单词的单词嵌入,以包括上下文相关性。输出模块的输入是没有上下文信息的每个单词的嵌入,而输出是具有上下文信息的类似嵌入。

2.计算机视觉中的注意方法

此处列出了持续更新的关注模块列表。从列出的几个中,我们重点介绍两个最受计算机视觉任务欢迎的:多头注意力和卷积块注意力模块(CBAM) 。

2.1。多头关注

多头注意力是注意力机制的一个模块,它并行运行一个注意力模块若干次。因此,要理解它的逻辑,首先需要理解注意力模块。两个最常用的注意力函数是https://paperswithcode.com/method/additive-attention点积注意力 ,后者是本工作感兴趣的一个。

关注模块的基本结构是有两个向量列表 x1x2 ,一个是关注的,另一个是出席的。向量 x2 生成“查询”,而向量 x1 创建“键”和“值”。关注函数背后的思想是将查询和设置的键值对映射到输出。输出计算为值的加权和,其中分配给每个值的权重由查询与相应关键字的兼容性函数计算"T17 注意是您所需要的全部 T18"。输出计算如下:

正如在本讨论中提到的,键/值/查询概念来自检索系统。例如,当在 Youtube 上键入一个查询来搜索一些视频时,搜索引擎会将您的查询映射到一组(视频标题、描述等)。)与数据库中的候选视频链接。然后,它会为您呈现最匹配的视频()。

在进入多头注意力之前,让我们运行这个点积注意力,多头注意力是本模块的一个扩展。下面是 PyTorch 中的实现。输入是[128, 32, 1, 256],其中 128 对应的是批次,32 对应的是序列长度,1 对应的是头数(对于多个关注头我们会增加),256 是特征数。

输出是:

*attn_output: [128, 32, 1, 256], attn_weights: [128, 1, 32, 32]
attn_output: [128, 32, 1, 256], attn_weights: [128, 1, 32, 16]*

从这个基本实现中可以得到一些启示:

  • 输出将具有与查询输入大小相同的形状。
  • 每个数据的注意力权重必须是一个矩阵,其中行数对应于查询的序列长度,列数对应于键的序列长度。
  • 点积注意力中没有可学习的参数。

所以,回到多头注意力,这个人并行运行这个解释过的注意力模块几次。独立的注意力输出然后被连接并线性转换成期望的维度。下面是实现过程:

输出是:

*attn_output: [128, 32, 256], attn_weights: [128, 8, 32, 32]
attn_output: [128, 32, 256], attn_weights: [128, 8, 32, 32]*

从代码中可以看出:

  • 例如,查询的线性层的输入是[128, 32, 256]。然而,正如在这篇文章中提到的,Linear层接受任意形状的张量,其中只有最后一个维度必须与你在构造函数中指定的in_features参数相匹配。输出将具有与输入完全相同的形状,只有最后一个维度将改变为您在构造函数中指定的out_features。对于我们的例子,输入形状是一组128 * 32 = 4096256特征。因此,我们将密集网络应用于序列长度的每个元素和批次的每个数据。
  • 此外,我们添加了残余连接和层规范化,因为它是在变压器神经网络中实现的。但是,如果你只是想实现多头注意力模块,这些应该被排除在外。

因此,在这一点上你可能会疑惑,为什么我们要实现多头注意力而不是一个简单的注意力模块?根据论文注意力是你所需要的全部,“多头注意力允许模型共同注意来自不同位置的不同表征* 子空间 *的信息。用单一的注意力头,平均化抑制了这一点。”换句话说,将特征划分为头部允许每个注意力模块仅关注一组特征,从而提供更大的能力来编码每个单词的多种关系和细微差别。

如果在这一点上你还想深入了解这种类型的注意力,我鼓励你阅读这篇文章,它用很棒的插图详细解释了所有这个模块。

在结束之前,我只想提一下,我们已经使用了这个注意力模块,就好像我们在处理序列一样,但是这篇文章是关于图像的。如果你理解了这一点,序列和图像之间唯一的区别就是输入向量。对于图像来说,与序列长度相对应的是像素。因此,如果输入是[batch=128, no_channels=256, height=24, width=24],一个可能的实现可能是:

输出是:

*attn_output: [128, 256, 24, 24], attn_weights: [128, 8, 576, 576]*

2.2。卷积块注意模块(CBAM)

在 2018 年, S. Woo 等人(2018) 发表了一个新的注意力模块,名为卷积块注意力模块(CBAM),它和卷积运算一样,强调了沿通道和空间轴的有意义的特征。与多头注意力相比,这种类型的注意力是针对前馈卷积神经网络有意制造的,并且可以应用于深度网络中的每个卷积块。

CBAM 包含两个连续的子模块,称为通道注意模块(CAM)和空间注意模块(SAM)。这两个概念可能是谈论卷积时最重要的两个概念。通道是指每个像素的特征或通道的数量,而空间是指维度(h x w)的特征图。

  • 空间注意模块(SAM) :该模块由三重顺序操作组成。它的第一部分称为通道池,它包括对输入(c×h×w*)应用跨通道的最大池和平均池,以生成具有 shape (2 × h × w )的输出。这是卷积层的输入,卷积层输出一个单通道特征图(1 × h × w )。在通过 BatchNorm 和可选的 ReLU 传递这个输出之后,数据进入 Sigmoid 激活层。*
  • 通道注意模块(CAM) :该模块首先将输入张量分解成由全局平均池(GAP)和全局最大池(GMP)生成的 2 个后续维度向量( c × 1 × 1)。此后,输出通过完全连接层,然后是 ReLu 激活层。

想了解更多关于 CBAM 的信息,我推荐阅读这篇伟大的帖子,里面有很棒的解释图片。

下面是实现过程:

输出是:

*attn_output: [128, 256, 24, 24]*

3.基于注意的网络的实现和结果

在上述理论部分之后,本节将重点介绍两个注意层在一个实际案例中的实现。

具体来说,我们选择了 STL 数据集,并在一些图像中添加了白色补丁,如下图所示。任务是创建一个神经网络来分类这两种类型的图像。

STL 图像。那些标记为 1 的图像属于其图像具有白色斑块的类别,而那些标记为 0 的图像是没有白色斑块的图像。

然后,我们创建了三个类。第一个只是一个 CNN,而第二个包含多头注意力层,第三个包括 CBAM 模块。

下面是运行培训的代码。

这些是输出结果:

  • *CNN 😗
*Min train error: 0.0011167450276843738
Min test error: 0.05411996720208516*

  • CNN +多头关注:添加关注层后性能有所提高,但关注图没有突出显示图像中带有白色斑块的部分。
*Min train error: 9.811600781858942e-06
Min test error: 0.04209221125441423*

**

由于有一些过度拟合和注意力层没有做它应该做的,我用卷积层重新实现了这一层。如果有人有什么建议,请在评论中留下。

  • 基于 CNN + 1DConv 的多头关注:这一次稳定性和性能明显提高。此外,还可以观察到注意力层的输出是如何为包含它的图像高亮显示白色斑块的。
*Min train error: 0.00025470180017873645
Min test error: 0.014278276459193759*

**

  • CNN + CBAM 注意:这一个呈现了最好的结果。显然可以在注意力层的输出中观察到白色斑块,并且训练非常稳定,实现了所有模型中最低的验证损失。
*Min train error: 2.786791462858673e-05
Min test error: 0.028047989653949175*

**

4.结论

总之,本文介绍了多头注意力和 CBAM 模块,这是计算机视觉中最流行的两个注意力模块。此外,它还包括 PyTorch 中的一个实现,其中我们对包含白色补丁(手动添加)的 CIFAR 数据集中的图像进行分类。

对于未来的工作,我认为将位置编码和注意力结合起来是很有趣的。在这里,我为感兴趣的人留下了一个链接。

如果你喜欢这篇文章,请考虑 订阅 。你将获得我所有的内容+所有其他来自牛逼创作者的文章!

你需要的只是关注

原文:https://towardsdatascience.com/attention-please-85bd0abac41?source=collection_archive---------4-----------------------

解释机器翻译的变压器架构

动机

假设我们想把英语翻译成德语。

(图片由作者提供)

我们可以清楚地看到,我们不能通过单独翻译每个单词来翻译这个句子。例如,英语单词“the”可以翻译成“der”或“die ”,这取决于与其相关的名词的性别。同样,单词“to”根本没有被翻译成德语,因为在德语句子中没有不定式。还有更多例子可以说明一个单词的上下文是如何影响其翻译的。

我们需要将整个输入句子的信息输入到我们的机器翻译模型中,这样它才能理解单词的上下文。

由于大多数机器翻译模型一次输出一个单词,我们也要给模型关于它已经翻译了哪些部分的信息

过去,机器翻译主要是通过使用 LSTM 或 GRU 这样的递归神经网络来完成的。然而,他们很难学习单词之间的依赖关系,因为单词之间的计算步骤数随着距离的增加而增加,所以单词在句子中距离很远。

为了解决这个问题,引入了变形金刚,它消除了重复现象,代之以注意机制。我将介绍著名论文“你所需要的只是注意力”中提出的架构的内部运作。

编码器解码器

transformer 模型可以一次预测一个单词/单词。它将我们想要翻译的源句子和它已经翻译的句子部分作为输入。然后,变压器输出下一个字。

变压器有两个不同的部分,称为“编码器”和“解码器”。输入的句子被输入编码器,而已经翻译的部分被输入解码器,解码器也产生输出。

注意机制

注意力机制是 Transformer 架构的核心,其灵感来自于人脑中的注意力。想象你在一个聚会上。即使你的名字被淹没在其他的噪音中,你也能听出在房间的另一边有人在喊你的名字。你的大脑可以专注于它认为重要的事情,过滤掉所有不必要的信息。

在查询、键和值的帮助下,变压器中的注意力变得更加容易。

**Key:**Key 是一个单词的标签,用来区分不同的单词。

**查询:**检查所有可用的键,并选择最匹配的一个。所以它代表了对特定信息的主动请求。

**值:**键和值总是成对出现。当查询匹配一个键时,不是键本身,而是单词的值被进一步传播。值是一个单词包含的信息。

在 Transformer 架构中有三种不同的注意机制。一个是编码器和解码器之间的 T2。这种类型的关注被称为交叉关注,因为键和值是由不同于查询的序列生成的。

(图片作者

如果键、值和查询是从相同的序列中生成的,那么我们称之为自关注。在编码器和解码器中各有一种自我关注机制。

自我注意在下图中用紫色表示,交叉注意用红色表示。

(图片由作者提供)

"那么,在数字上是如何做到的呢?",你可能会问。一种方法是使用成比例的点积注意力。

比例点产品关注度

首先,我们必须注意,我们通过使用嵌入层将单词表示为向量。这个向量的维数可以变化。例如,小型的 GPT-2 记号赋予器使用每个单词/记号 768 的嵌入大小。

(图片由作者提供)

从这些单词向量中,查询( q )、键( k )和值( v )向量通过矩阵乘以学习矩阵来计算。我们把这些矩阵叫做 M

在以下示例中,矩阵的形状为(3,2)。3 是单词向量的长度,2 是一个查询、键或值向量的长度。

(图片由作者提供)

我们将查询放在矩阵 Q 中,将键放在矩阵 K 中,将值放在矩阵 V 中。

注意力是这样计算的:

(图片由作者提供)

为了简化,我们考虑 3 个键、3 个值和 1 个查询。当在 Q 和转置的 **K,**之间取点积时,这与在每个键和查询之间取标量积是一样的。标量积越大,键和查询之间的角度越小。

(图片由作者提供)

然后,softmax 函数缩放分数向量,使其总和等于 1。然后分数向量乘以值向量。

(图片由作者提供)

使用这个过程,我们从值中选择更多的信息,其中键和查询更相似。

为了提高变压器的性能,我们可以引入多头关注。

多头注意力

多头注意力意味着我们有多个并行运行的点积注意力机制。这有助于网络同时处理多条信息。

摘自论文“注意力是你所需要的一切”

线性层是简单的学习权重矩阵。对于每个头部,我们通过不同的学习权重矩阵 W 来缩放 VKQ 。并且对于整个多头也有一个输出权重矩阵。

(图片由作者提供)

位置编码

因为转换器没有循环元素,所以当我们输入一个完整的句子时,转换器没有办法知道哪个单词在哪个位置。因此,我们必须对位置进行编码。一种方法是将不同频率的正弦波和余弦波附加到字向量上。

(图片由作者提供)

由于每个位置都有唯一的值组合,因此变压器能够准确地学习位置。

(图片由作者提供)

假设通过使用正弦波和余弦波作为位置编码,变换器应该能够知道超出训练样本大小的位置。

剩余连接和图层标准化

我们还在我们的架构中引入了剩余连接。这是通过在图层之后将输入添加到输出来完成的。

(图片由作者提供)

它们用于允许梯度直接流经网络,因此也被称为跳过连接。

执行层标准化以保持每个训练样本的平均值接近 0,标准偏差接近 1 。这有助于稳定训练,从而减少训练时间。

(图片由作者提供)

整体架构

下图是变压器的整体架构。编码器和解码器可以重复 N 次。

(图片由作者提供)

我们还没有提到架构的前馈部分。这是一个点式前馈网络。它是一个简单的神经网络,具有相同的输入和输出维度。

(图片由作者提供)

摘要

Transformer architecture 去掉了递归,代之以一种关注机制,这种机制使用查询来选择它需要的信息(值),基于键提供的标签。如果键、值和查询是从同一个序列中生成的,就叫自注意。在交叉注意中,查询是由不同于键值对的序列生成的。多头注意力有助于变形金刚同时处理多件事情。

关于源文本的信息被提供给编码器,关于目标句子的已翻译部分的信息被提供给解码器,解码器还输出下一个单词/单词。网络从以不同频率的正弦波和余弦波的形式提供的位置编码中学习句子中单词的顺序。

作者相关文章

作者撰写的其他文章

想联系支持我?

领英
https://www.linkedin.com/in/vincent-m%C3%BCller-6b3542214/
脸书
https://www.facebook.com/profile.php?id=100072095823739
推特
https://twitter.com/Vincent02770108
中等
https://medium.com/@Vincent.Mueller
成为中等会员并支持我(你的部分会员费直接归我)
https://medium.com/@Vincent.Mueller/membership

参考

图文并茂的 GPT-2

人脑中的注意力

《注意力是你所需要的全部》论文

Yannik Kilchers 关于“关注是你所需要的一切”的视频

谷歌的变形金刚代码库

py torch 中的变压器

解释的键、查询和值

关键字、查询和值的数学运算

Tensor2Tensor 笔记本

剩余连接上的堆栈溢出

变压器架构中的层标准化

K 纪元层归一化

Python 中吸引人的、有效的和描述性的图像可视化

原文:https://towardsdatascience.com/attractive-effective-descriptive-image-visualization-in-python-aa6831d716dc?source=collection_archive---------32-----------------------

添加比例尺、可视化图像分布、纠正异常值等。

作者图片

Seaborn-image 是一个基于 matplotlib 的开源 Python 可视化图像库。它旨在提供一个高级 API 来可视化图像数据,类似于 seaborn 提供高级 API 来可视化表格数据。顾名思义,seaborn-image很大程度上受到了seaborn库的启发。

装置

让我们从安装seaborn-image开始

$ pip install --upgrade seaborn-image

然后将seaborn-image导入为isns

*import* seaborn_image *as* isns*# set context* isns.set_context("notebook")*# set global image settings* isns.set_image(*cmap*="deep", *origin*="lower")*# load sample dataset* polymer = isns.load_image("polymer")

seaborn-image中的所有函数都在一个平面名称空间中可用。

isns.set_context()帮助我们全局改变显示上下文(类似于seaborn.set_context())。

除了上下文,我们还使用isns.set_image()全局设置绘制图像的属性。稍后,我们还将看看如何使用isns.set_scalebar()来全局设置图像比例尺属性。

这些功能使用 matplotlib rcParams 定制显示。关于seaborn-image中设置的更多细节,您可以参考文档。

最后,我们从seaborn-image加载一个样本聚合物数据集。

在这篇文章中,我们将使用这个聚合物图像数据集进行可视化。

二维图像

可视化图像就像用我们的聚合物图像数据调用imgplot()函数一样简单。imgplot()在幕后使用 matplotlib imshow ,但是提供了对许多定制的简单访问。我们将在这篇博文中看看一些定制。

默认情况下,它会添加一个colorbar并关闭轴记号。然而,这仅仅是开始触及表面!

我们可以通过设置describe=True得到一些关于我们图像数据的基本描述性统计。

ax = isns.imgplot(polymer, *describe*=True)  *# default is False*No. of Obs. : 65536
Min. Value : -8.2457214
Max. Value : 43.714034999999996
Mean : 7.456410761947062
Variance : 92.02680396572863
Skewness : 0.47745180538933696

作者图片

也可以使用 *imshow* *,*的别名*imgplot*

画一个比例尺

虽然我们知道一些关于我们的聚合物图像数据的基本信息,但是我们仍然没有关于图像中特征的物理尺寸的任何信息。我们可以画一个比例尺来校正它。

要添加比例尺,我们可以指定单个像素的大小dx和物理的units。这里,单个像素的物理尺寸是 15 纳米。所以,我们设置dx=15units="nm"

ax = isns.imgplot(
    polymer,
    *dx*=15,  *# physical size of the pixel
    units*="nm",  *# units
    cbar_label*="Height (nm)"  *# add colorbar label to our image* )

作者图片

注意:我们仅指定了单个像素的大小和单位,并绘制了适当大小的比例尺。

提示:您可以更改比例尺属性,如比例尺位置、标签位置、颜色等。全局使用 [*isns.set_scalebar()*](https://seaborn-image.readthedocs.io/en/latest/api/_context.html#seaborn_image.set_scalebar)

异常值校正

真实的数据从来都不是完美的。它通常充满了异常值,这些异常值会影响图像显示。

# sample data with outliers  
pol_outliers = isns.load_image("polymer outliers")ax = isns.imgplot(pol_outliers, cbar_label= "Height (nm)")

作者图片

上述示例数据集有一个影响图像显示的异常像素。我们可以使用所有seaborn-image 函数中的robust参数来校正异常值。

ax = isns.imgplot(
    pol_outliers,
    *robust*=True,  *# set robust plotting
    perc*=(0.5, 99.5),  *# set the percentile of the data to view
    cbar_label*="Height (nm)"
)

作者图片

这里,我们设置robust=True并绘制 0.5 到 99.5%的数据(使用perc参数指定)。这样做可以根据指定的健壮百分比适当地缩放色彩映射表,还可以在没有任何附加代码的情况下绘制色彩条扩展。

注意:您可以指定 *vmin* *vmax* 参数来覆盖 *robust* 参数。详见 *imgplot* 文档示例

图像数据分发

图像可视化的一个最重要的方面是知道底层图像数据的分布。在这里,我们使用imghist绘制一个直方图以及我们的聚合物图像。

*fig = isns.imghist(polymer, *dx*=15, *units*="nm", *cbar_label*="Height (nm)")*

作者图片

注意:不需要新的参数。

使用直方图和适当的色彩映射表提供了关于图像数据的附加信息。例如,从上面的直方图中,我们可以看到大部分数据的值小于 30 纳米,只有极少数值接近 40 纳米,如果我们不看直方图,这一点可能不明显。

提示:您可以使用 *bins* 参数更改条柱的数量,使用 *orientation* 参数更改彩条和直方图的方向。详见 *imghist* 文档示例

重要的是,生成完整的图形,包括与颜色条级别匹配的直方图、描述图像中要素物理大小的比例尺、颜色条标签、隐藏轴刻度等。—只用了一行代码。本质上,这就是seaborn-image的目标——为 吸引人的、描述性的和有效的图像可视化 提供一个高级 API。

最后,这篇文章只介绍了seaborn-image为图像可视化提供的一些高级 API。更多细节可以查看详细的文档和教程以及 GitHub 上的项目。

感谢阅读!

原载于 2021 年 2 月 26 日https://sarthakjariwala . github . io。**

音频深度学习变得简单:自动语音识别(ASR),它是如何工作的

原文:https://towardsdatascience.com/audio-deep-learning-made-simple-automatic-speech-recognition-asr-how-it-works-716cfce4c706?source=collection_archive---------0-----------------------

动手教程,直观音频深度学习系列

语音到文本的算法和架构,包括 Mel 频谱图,MFCCs,CTC 损失和解码器,在平原英语

由拍摄的照片在 Unsplash 上

在过去的几年里,随着 Google Home、Amazon Echo、Siri、Cortana 等的流行,语音助手变得无处不在。这些是自动语音识别(ASR)最著名的例子。这类应用程序从某种语言的语音片段开始,并提取所说的单词作为文本。因此,它们也被称为语音转文本算法。

当然,像 Siri 和上面提到的其他应用程序走得更远。他们不仅提取文本,而且还解释和理解所说内容的语义,以便他们可以根据用户的命令做出响应或采取行动。

在这篇文章中,我将重点关注使用深度学习的语音到文本的核心功能。我的目标是不仅要理解事物是如何工作的,还要理解它为什么会这样工作。

我的音频深度学习系列中还有几篇文章,你可能会觉得有用。他们探索了这一领域的其他有趣主题,包括我们如何为深度学习准备音频数据,为什么我们将 Mel 光谱图用于深度学习模型,以及它们是如何生成和优化的。

  1. 最先进的技术 (什么是声音,它是如何数字化的。音频深度学习在解决我们日常生活中的哪些问题。什么是光谱图,为什么它们都很重要。)
  2. 为什么 Mel Spectrograms 表现更好 (用 Python 处理音频数据。什么是 Mel 光谱图以及如何生成它们)
  3. 数据准备和扩充 (通过超参数调整和数据扩充增强光谱图特征以获得最佳性能)
  4. 声音分类 (端到端的例子和架构对普通声音进行分类。一系列场景的基础应用。)
  5. 波束搜索 (语音到文本和 NLP 应用程序常用的增强预测的算法)

语音转文本

我们可以想象,人类的语音是我们日常个人和商业生活的基础,语音到文本的功能有大量的应用。人们可以用它来记录面向语音的聊天机器人的客户支持或销售电话的内容,或者记录会议和其他讨论的内容。

基本音频数据由声音和噪声组成。人类语言是一个特例。因此,我在文章中谈到的概念,如我们如何将声音数字化,以及为什么我们要将音频转换成频谱图,也适用于理解语音。然而,语音更复杂,因为它对语言进行编码。

像音频分类这样的问题从一个声音片段开始,并从一组给定的类别中预测该声音属于哪个类别。对于语音转文本问题,您的训练数据包括:

  • 输入特征( X ):口语的音频剪辑
  • 目标标签( y ):所说内容的文本副本

自动语音识别使用音频波作为输入特征,使用文本抄本作为目标标签(图片由作者提供)

该模型的目标是学习如何获取输入音频并预测说出的单词和句子的文本内容。

数据预处理

在声音分类文章中,我一步一步地解释了用于处理深度学习模型的音频数据的转换。对于人类语言,我们也遵循类似的方法。有几个 Python 库提供了这样的功能,librosa 是最流行的一个。

将原始音频波转换为频谱图图像,以输入到深度学习模型(图片由作者提供)

加载音频文件

  • 从输入数据开始,输入数据由音频格式的口语语音的音频文件组成。wav”或“. mp3”。
  • 从文件中读取音频数据,并将其加载到 2D Numpy 数组中。这个数组由一系列数字组成,每个数字代表特定时刻声音的强度或振幅。这种测量的次数由采样率决定。例如,如果采样速率为 44.1kHz,则 Numpy 数组对于 1 秒钟的音频将具有单行 44,100 个数字。
  • 音频可以有一个或两个通道,俗称单声道或立体声。对于双声道音频,第二个声道会有另一个类似的幅度数字序列。换句话说,我们的 Numpy 数组将是 3D 的,深度为 2。

转换为统一维度:采样率、通道和持续时间

  • 我们的音频数据项可能会有很多变化。片段可能以不同的速率采样,或者具有不同数量的通道。剪辑很可能具有不同的持续时间。如上所述,这意味着每个音频项的尺寸将是不同的。
  • 由于我们的深度学习模型期望我们所有的输入项都具有相似的大小,因此我们现在执行一些数据清理步骤来标准化我们的音频数据的维度。我们对音频进行重新采样,以便每个项目都具有相同的采样率。我们将所有项目转换到相同数量的频道。所有项目也必须转换为相同的音频持续时间。这包括填充较短的序列或截断较长的序列。
  • 如果音频质量很差,我们可以通过应用噪声去除算法来消除背景噪声,以便我们可以专注于语音音频。

原始音频的数据扩充

  • 我们可以应用一些数据扩充技术来增加输入数据的多样性,并帮助模型学习概括更广泛的输入。我们可以随机地将音频向左或向右移动一个小的百分比,或者少量地改变音频的音高或速度。

梅尔光谱图

  • 这个原始音频现在被转换成 Mel 光谱图。频谱图通过将音频分解为包含在其中的一组频率,将音频的本质捕捉为图像。

MFCC

  • 特别是对于人类语音,有时采取一个额外的步骤并将梅尔频谱图转换成 MFCC(梅尔频率倒谱系数)会有所帮助。MFCCs 通过仅提取最基本的频率系数来产生 Mel 频谱图的压缩表示,这些频率系数对应于人类说话的频率范围。

光谱图的数据扩充

  • 我们现在可以使用一种称为 SpecAugment 的技术,对 Mel 光谱图图像应用另一个数据扩充步骤。这包括随机屏蔽掉垂直(即时间掩模)或水平(即频率屏蔽)来自频谱图的信息频带。注:我不确定这是否也适用于 MFCCs,是否会产生好的结果。

经过数据清理和扩充,我们现在已经将原始音频文件转换为 Mel 声谱图(或 MFCC)图像。

我们还需要从抄本中准备目标标签。这只是由单词的句子组成的常规文本,所以我们从脚本中的每个字符构建一个词汇表,并将它们转换成字符 id。

这给了我们输入特征和目标标签。这些数据已经准备好输入到我们的深度学习模型中。

体系结构

ASR 的深度学习架构有很多变体。两种常用的方法是:

  • 一种基于 CNN(卷积神经网络)和 RNN(递归神经网络)的架构,使用 CTC Loss 算法来区分语音中单词的每个字符。百度的深度语音模型。
  • 基于 RNN 的序列到序列网络,将声谱图的每个“切片”视为序列中的一个元素,例如 Google 的 Listen Attend Spell (LAS)模型。

让我们选择上面的第一种方法,并更详细地探讨它是如何工作的。概括地说,该模型由以下模块组成:

  • 由几个残余 CNN 层组成的常规卷积网络,处理输入频谱图图像并输出这些图像的特征图。

光谱图由卷积网络处理以生成特征图(图片由作者提供)

  • 由几个双向 LSTM 层组成的规则循环网络,将特征地图作为一系列不同的时间步长或“帧”进行处理,这些时间步长或“帧”与我们所需的输出字符序列相对应。(LSTM 是一种非常常用的循环层,它的完整形式是长短期记忆)。换句话说,它采用连续表示音频的特征图,并将它们转换成离散表示。

递归网络处理来自特征图的帧(图片由作者提供)

  • 带有 softmax 的线性图层,使用 LSTM 输出为输出的每个时间步长生成字符概率。

线性层为每个时间步长生成字符概率(图片由作者提供)

  • 我们还有位于卷积和递归网络之间的线性层,有助于将一个网络的输出整形为另一个网络的输入。

因此,我们的模型获取频谱图图像,并输出该频谱图中每个时间步长或“帧”的特征概率。

对齐序列

如果你稍微思考一下这个问题,你会意识到我们的拼图中还缺少一个重要的部分。我们的最终目标是将这些时间步或“框架”映射到我们的目标脚本中的单个字符。

该模型解码字符概率以产生最终输出(作者的图像)

但是对于一个特定的声谱图,我们怎么知道应该有多少帧呢?我们如何确切地知道每一帧的边界在哪里?我们如何将音频与文本脚本中的每个字符对齐?

左边是我们需要的排列。但是我们如何得到它呢??(图片由作者提供)

音频和声谱图图像没有被预先分割以给我们这个信息。

  • 在口语音频中,因此在声谱图中,每个字符的声音可以具有不同的持续时间。
  • 这些字符之间可能会有间隔和停顿。
  • 几个字符可以合并在一起。
  • 有些字符可以重复。例如,在单词“apple”中,我们如何知道音频中的“p”实际上是否对应于文字记录中的一个或两个“p”?

事实上,口语对我们来说并不整齐一致(图片由作者提供)

这实际上是一个非常具有挑战性的问题,也是为什么 ASR 如此难以正确解决的原因。这是 ASR 区别于分类等其他音频应用的显著特征。

我们解决这个问题的方法是使用一种巧妙的算法,它有一个听起来很好听的名字,叫做连接主义时间分类,简称 CTC。由于我不是“喜欢幻想的人”,而且很难记住这个长名字,我就用反恐委员会这个名字来指代它😃。

CTC 算法——训练和推理

当输入是连续的而输出是离散的,并且没有清晰的元素边界可用于将输入映射到输出序列的元素时,CTC 用于对齐输入和输出序列。

它的特别之处在于它会自动执行这种对齐,而不需要您手动提供这种对齐作为标记的训练数据的一部分。这将使创建训练数据集变得极其昂贵。

如上所述,在我们的模型中,卷积网络输出的特征映射被分割成单独的帧,并输入到递归网络。每一帧对应于原始音频波的某个时间步长。但是,在设计模型时,帧数和每帧的持续时间是由您选择作为超参数的。对于每一帧,线性分类器后面的递归网络预测词汇表中每个字符的概率。

连续的音频被分割成离散的帧并输入到 RNN(图片由作者提供)

CTC 算法的工作就是获取这些字符概率并导出正确的字符序列。

为了帮助它处理我们刚刚讨论过的对齐和重复字符的挑战,它在词汇表中引入了“空白”伪字符(用“-”表示)的概念。因此,网络输出的字符概率也包括每帧空白字符的概率。

请注意,空白与“空格”不同。空格是一个真正的字符,而空白意味着没有任何字符,有点像大多数编程语言中的“null”。它仅用于划分两个字符之间的界限。

CTC 以两种模式工作:

  • CTC 丢失(在训练期间):它有一个地面真实目标抄本,并试图训练网络以最大化输出那个正确抄本的概率。
  • CTC 解码(推断中):这里我们没有目标抄本可以参考,必须预测最可能的字符序列。

让我们更深入地研究一下,以理解算法的作用。我们将从 CTC 解码开始,因为它稍微简单一些。

CTC 解码

  • 使用字符概率为每一帧选择最可能的字符,包括空格。例如," -G-o-ood "

CTC 解码算法(图片作者提供)

  • 合并任何重复的字符,并且不用空格分隔。例如,我们可以将“ oo ”合并成一个“ o ”,但是我们不能合并“ o-oo ”。这就是 CTC 能够区分有两个单独的“o”并产生由重复字符拼写的单词的方式。例如," -G-o-od "
  • 最后,因为空格已经达到了它们的目的,所以它删除了所有的空格字符。例如“好的”。

CTC 损失

损失被计算为网络预测正确序列的概率。为此,该算法列出了网络可以预测的所有可能的序列,并从中选择与目标转录本匹配的子集。

为了从可能序列的全集中识别该子集,该算法如下缩小可能性:

  • 只保留出现在目标脚本中的字符的概率,而丢弃其余的。它只保留“G”、“o”、“d”和“-”的概率。
  • 使用过滤的字符子集,对于每一帧,只选择那些以与目标抄本相同的顺序出现的字符。尽管“G”和“o”都是有效字符,但“Go”的顺序是有效序列,而“oG”是无效序列。

CTC 丢失算法(图片由作者提供)

有了这些约束,算法现在有了一组有效的字符序列,所有这些都将产生正确的目标转录本。例如,使用推理过程中使用的相同步骤,“-G-o-ood”和“-Go-od-”都将导致“好”的最终输出。

然后,它使用每一帧的单个字符概率来计算生成所有这些有效序列的总概率。网络的目标是学习如何最大化该概率,并因此降低产生任何无效序列的概率。

严格地说,由于神经网络使损失最小化,所以 CTC 损失被计算为所有有效序列的对数概率。由于网络在训练期间通过反向传播最小化了这种损失,所以它调整其所有的权重以产生正确的序列。

然而,实际做到这一点比我在这里描述的要复杂得多。挑战在于有大量可能的字符组合来产生一个序列。就我们这个简单的例子来说,每帧可以有 4 个字符。有 8 个帧,所以我们有 4 * 8 个组合(= 65536)。对于任何有更多角色和更多画面的真实剧本,这个数字会呈指数增长。这使得简单地穷尽列出有效组合并计算它们的概率在计算上是不切实际的。

高效地解决这个问题是 CTC 如此创新的原因。这是一个迷人的算法,非常值得理解它如何实现这一点的细微差别。这本身就值得一篇完整的文章,我打算很快就写出来。但是现在,我们已经把重点放在建立对 CTC 做什么的直觉上,而不是深入它是如何工作的。

指标—单词错误率(WER)

在训练我们的网络之后,我们必须评估它的表现如何。语音到文本问题的一个常用度量是单词错误率(和字符错误率)。它一个字一个字地(或一个字符一个字符地)比较预测的输出和目标抄本,以计算出它们之间的差异。

差异可以是存在于转录本中但在预测中缺失的单词(被计为删除)、不在转录本中但已被添加到预测中的单词(插入)、或者在预测和转录本之间改变的单词(替换)。

统计转录本和预测之间的插入、删除和替换(图片由作者提供)

度量公式相当简单。它是差异相对于总字数的百分比。

单词错误率计算(图片由作者提供)

语言模型

到目前为止,我们的算法只把语音当作某种语言的字符序列。但是当把这些字符组合成单词和句子时,它们真的有意义吗?

自然语言处理(NLP)中的一个常见应用是建立语言模型。它捕捉了在一种语言中如何使用单词来构建句子、段落和文档。它可以是关于语言(如英语或韩语)的通用模型,也可以是特定于特定领域(如医学或法律)的模型。

一旦有了语言模型,它就可以成为其他应用程序的基础。例如,它可以用来预测句子中的下一个单词,辨别一些文本的情绪(例如,这是一篇积极的书评吗),通过聊天机器人回答问题,等等。

因此,当然,它也可以用于通过引导模型生成更有可能符合语言模型的预测来选择性地提高我们的 ASR 输出的质量。

波束搜索

当在推理过程中描述 CTC 解码器时,我们隐含地假设它总是在每个时间步长选择一个概率最高的单个字符。这就是所谓的贪婪搜索。

然而,我们知道使用一种叫做波束搜索的替代方法可以得到更好的结果。

虽然波束搜索通常用于 NLP 问题,但它并不是特定于 ASR 的,所以我在这里提到它只是为了完整。如果你想知道更多,请看看我的文章,其中详细描述了波束搜索。

结论

希望这能让您对用于解决 ASR 问题的构建模块和技术有所了解。

在早期的深度学习之前,通过经典方法解决这类问题需要理解音素等概念,以及大量特定领域的数据准备和算法。

然而,正如我们刚刚看到的深度学习,我们几乎不需要任何涉及音频和语音知识的功能工程。然而,它能够产生出色的结果,不断给我们带来惊喜!

最后,如果你喜欢这篇文章,你可能也会喜欢我关于变形金刚、地理定位机器学习和图像字幕架构的其他系列。

让我们继续学习吧!

音频深度学习变得简单(第一部分):最新技术

原文:https://towardsdatascience.com/audio-deep-learning-made-simple-part-1-state-of-the-art-techniques-da1d3dff2504?source=collection_archive---------0-----------------------

直观音频深度学习系列

颠覆性深度学习音频应用和架构世界的温和指南。以及为什么我们都需要了解光谱图,用简单的英语。

杰森·罗斯韦尔在 Unsplash 上的照片

尽管计算机视觉和 NLP 应用获得了最多的关注,但也有许多突破性的音频数据深度学习用例正在改变我们的日常生活。在接下来的几篇文章中,我的目标是探索音频深度学习的迷人世界。

下面是我计划在这个系列中发表的文章的简要概述。我的目标是不仅要理解事物是如何工作的,还要理解它为什么会这样工作。

  1. 最先进的技术——本文 (什么是声音,它是如何数字化的。音频深度学习在解决我们日常生活中的哪些问题。什么是光谱图,为什么它们都很重要。)
  2. 为什么 Mel Spectrograms 表现更好 (用 Python 处理音频数据。什么是 Mel 光谱图以及如何生成它们)
  3. 特性优化和增强 (通过超参数调整和数据增强增强光谱图特性以获得最佳性能)
  4. 音频分类 (端到端例子和架构对普通声音进行分类。一系列场景的基础应用。)
  5. 自动语音识别 (语音转文本算法和架构,使用 CTC 丢失和解码进行序列对齐。)
  6. 波束搜索

在这第一篇文章中,由于这一领域可能不为人们所熟悉,我将介绍这个主题,并概述音频应用的深度学习前景。我们将了解什么是音频,以及它是如何以数字形式呈现的。我将讨论音频应用对我们日常生活的广泛影响,并探索它们使用的架构和建模技术。

什么是声音?

我们都记得在学校时,声音信号是由气压的变化产生的。我们可以测量压力变化的强度,并随时间绘制这些测量值。

声音信号经常以规则的间隔重复,因此每个波都具有相同的形状。高度表示声音的强度,称为振幅。

显示振幅对时间的简单重复信号(经马克·利伯曼教授许可)

信号完成一个完整波所用的时间就是周期。信号在一秒钟内产生的波数称为频率。频率是周期的倒数。频率的单位是赫兹。

我们遇到的大多数声音可能不遵循这样简单而有规律的周期模式。但是不同频率的信号可以被加在一起以创建具有更复杂重复模式的复合信号。我们听到的所有声音,包括我们人类的声音,都是由这样的波形组成的。例如,这可能是乐器的声音。

带有复杂重复信号的音乐波形(来源,经乔治·吉布森教授许可)

人耳能够根据声音的“质量”(也称为音色)来区分不同的声音。

我们如何用数字方式表现声音?

为了将声波数字化,我们必须将信号转换成一系列数字,这样我们就可以将它输入到我们的模型中。这是通过在固定的时间间隔测量声音的振幅来实现的。

定期进行样本测量(来源

每个这样的测量称为一个样本,采样率是每秒的样本数。例如,常见的采样率大约是每秒 44,100 个样本。这意味着一个 10 秒钟的音乐片段将有 441,000 个样本!

为深度学习模型准备音频数据

直到几年前,在深度学习出现之前,计算机视觉的机器学习应用曾经依赖于传统的图像处理技术来进行特征工程。例如,我们会使用算法来检测角、边和面,从而生成手工制作的特征。对于 NLP 应用程序,我们也将依赖于诸如提取 N 元语法和计算词频之类的技术。

类似地,音频机器学习应用过去依赖于传统的数字信号处理技术来提取特征。例如,为了理解人类语音,可以使用语音学概念来分析音频信号,以提取像音素这样的元素。所有这些都需要大量特定领域的专业知识来解决这些问题,并调整系统以获得更好的性能。

然而,近年来,随着深度学习变得越来越普遍,它在处理音频方面也取得了巨大的成功。有了深度学习,不再需要传统的音频处理技术,我们可以依赖标准的数据准备,而不需要大量的手动和自定义生成特征。

更有趣的是,通过深度学习,我们实际上不会处理原始形式的音频数据。相反,常用的方法是将音频数据转换成图像,然后使用标准的 CNN 架构来处理这些图像!真的吗?把声音转换成图片?这听起来像科幻小说。😄

答案当然是相当普通和平凡的。这是通过从音频生成频谱图来完成的。首先让我们了解什么是光谱,并用它来理解光谱图。

范围

如前所述,不同频率的信号可以叠加在一起,形成复合信号,代表现实世界中出现的任何声音。这意味着任何信号都由许多不同的频率组成,可以表示为这些频率的总和。

频谱是组合在一起产生信号的一组频率。这幅图显示了一段音乐的频谱。

该频谱描绘了信号中存在的所有频率以及每个频率的强度或振幅。

频谱显示了构成声音信号的频率(来源,经 Barry Truax 教授许可)

信号中的最低频率称为基频。基频的整数倍频率称为谐波。

例如,如果基频为 200 赫兹,那么其谐波频率为 400 赫兹、600 赫兹等等。

时域与频域

我们之前看到的显示振幅与时间关系的波形是表示声音信号的一种方式。由于 x 轴显示了信号的时间值范围,因此我们是在时域中查看信号。

频谱是表示同一信号的另一种方式。它显示的是幅度与频率的关系,由于 x 轴显示的是信号的频率值范围,时刻,我们看到的是频域中的信号。

时域和频域(来源

光谱图

由于信号随时间变化会产生不同的声音,因此其组成频率也随时间变化。换句话说,它的光谱随时间而变化。

信号的频谱图绘制了其随时间变化的频谱,就像信号的“照片”。它在 x 轴上绘制时间,在 y 轴上绘制频率。这就好像我们在不同的时间点一次又一次地获取光谱,然后将它们全部结合成一个单一的图。

它用不同的颜色来表示每个频率的幅度或强度。颜色越亮,信号的能量越高。频谱图的每个垂直“切片”实质上是该时刻信号的频谱,并显示了信号强度在该时刻信号中的每个频率上的分布。

在下面的例子中,第一张图片显示的是时域信号。幅度与时间的关系它让我们知道在任何时间点一个剪辑有多大声或安静,但它给我们提供的关于存在哪些频率的信息很少。

声音信号及其声谱图(图片由作者提供)

第二张图是频谱图,显示频域中的信号。

生成光谱图

频谱图是利用傅里叶变换将任何信号分解成其组成频率而产生的。如果这让你有点紧张,因为我们现在已经忘记了大学期间学过的傅立叶变换,不要担心😄!我们实际上不需要回忆所有的数学,有非常方便的 Python 库函数可以在一个步骤中为我们生成光谱图。我们将在下一篇文章中看到这些。

音频深度学习模型

现在我们知道了什么是频谱图,我们意识到它是音频信号的等效紧凑表示,有点像信号的“指纹”。这是一种将音频数据的基本特征捕捉为图像的优雅方式。

音频深度学习模型使用的典型管道(图片由作者提供)

所以大多数深度学习音频应用使用频谱图来表示音频。他们通常遵循这样的程序:

  • 从波形文件形式的原始音频数据开始。
  • 将音频数据转换成相应的声谱图。
  • 可选地,使用简单的音频处理技术来扩充谱图数据。(在谱图转换之前,也可以对原始音频数据进行一些扩充或清理)
  • 现在我们有了图像数据,我们可以使用标准的 CNN 架构来处理它们,并提取特征图,这些特征图是光谱图图像的编码表示。

下一步是根据您试图解决的问题,从这种编码表示中生成输出预测。

  • 例如,对于一个音频分类问题,你可以通过一个通常由一些完全连接的线性层组成的分类器。
  • 对于语音到文本的问题,你可以让它通过一些 RNN 层,从这个编码的表示中提取文本句子。

当然,我们跳过了许多细节,做了一些概括,但在这篇文章中,我们停留在一个相当高的水平。在接下来的文章中,我们将更详细地讨论所有这些步骤和所使用的架构。

音频深度学习解决了哪些问题?

日常生活中的音频数据可以以无数种形式出现,例如人类语音、音乐、动物声音和其他自然声音,以及来自人类活动(如汽车和机械)的人造声音。

鉴于声音在我们生活中的普遍存在和声音类型的多样性,有大量的使用场景需要我们处理和分析音频就不足为奇了。现在深度学习已经成熟,可以应用它来解决许多用例。

音频分类

这是最常见的用例之一,涉及到获取一个声音并将其分配给几个类中的一个。例如,任务可以是识别声音的类型或来源。这是汽车启动声,这是锤子声,哨声,还是狗叫声。

普通声音的分类(图片由作者提供)

显然,可能的应用是巨大的。这可以应用于根据机器或设备产生的声音来检测其故障,或者在监控系统中检测安全入侵。

音频分离和分段

音频分离包括从混合信号中分离出感兴趣的信号,以便可以用于进一步处理。例如,您可能想要从大量背景噪音中分离出个人的声音,或者从音乐表演的其余部分中分离出小提琴的声音。

从视频中分离单个发言人(来源,经 Ariel Ephrat 许可)

音频分段用于突出显示音频流中的相关部分。例如,它可以用于诊断目的,以检测人类心脏的不同声音和检测异常。

音乐流派分类和标记

随着音乐流媒体服务的流行,我们大多数人都熟悉的另一个常见应用是根据音频对音乐进行识别和分类。对音乐的内容进行分析,以找出它所属的流派。这是一个多标签分类问题,因为一首给定的音乐可能属于一个以上的流派。例如,摇滚、流行、爵士、萨尔萨、器乐以及其他方面,如“老歌”、“女歌手”、“快乐”、“派对音乐”等等。

音乐流派分类和标记(作者图片)

当然,除了音频本身,还有关于音乐的元数据,如歌手、发行日期、作曲家、歌词等,这些都可以用来为音乐添加丰富的标签。

这可以用于根据音乐收藏的音频特征对其进行索引,根据用户的偏好提供音乐推荐,或者用于搜索和检索与您正在收听的歌曲相似的歌曲。

音乐生成和音乐转录

这些天我们看到了很多关于深度学习被用于以编程方式生成看起来非常真实的人脸和其他场景的图片,以及能够编写语法正确和智能的信件或新闻文章的新闻。

音乐生成(作者图片)

类似地,我们现在能够生成与特定流派、乐器甚至特定作曲家风格相匹配的合成音乐。

在某种程度上,音乐改编反过来应用了这种能力。它需要一些声学效果并对其进行注释,以创建一个包含音乐中存在的音符的乐谱。

声音识别

从技术上讲,这也是一个分类问题,但处理的是语音识别。它可以用来识别说话者的性别,或者他们的名字(例如,这是比尔·盖茨还是汤姆·汉克斯,或者这是柯坦的声音还是入侵者的声音)

用于入侵检测的语音识别(图片由作者提供)

我们可能想检测人类的情绪,并从他们的语调中识别出这个人的情绪,例如,这个人是高兴、悲伤、生气还是有压力。

我们可以将此应用于动物的声音,以识别发出声音的动物的类型,或者潜在地识别这是一种温柔深情的咕噜声,一种威胁的吠叫,还是一种害怕的嚎叫。

语音到文本和文本到语音

在处理人类语言时,我们可以更进一步,不仅仅是识别说话者,而是理解他们在说什么。这包括从音频中提取单词,用说的语言,并转录成文本句子。

这是最具挑战性的应用之一,因为它不仅处理音频分析,还处理 NLP,并需要开发一些基本的语言能力来从发出的声音中破译不同的单词。

语音转文本(图片由作者提供)

相反,使用语音合成,人们可以走另一个方向,使用书面文本并从中生成语音,例如,使用人工语音作为会话代理。

显然,能够理解人类语言能够在我们的商业和个人生活中实现大量有用的应用,而我们只是刚刚开始触及表面。

已经实现广泛使用的最知名的例子是虚拟助手,如 Alexa、Siri、Cortana 和 Google Home,这些都是围绕这一功能构建的消费者友好型产品。

结论

在本文中,我们停留在一个相当高的水平,探索了音频应用的广度,并涵盖了用于解决这些问题的一般技术。

在下一篇文章中,我们将深入探讨预处理音频数据和生成频谱图的更多技术细节。我们将看看用于优化性能的超参数。

这将为我们更深入地研究几个端到端的例子做好准备,从普通声音的分类开始,到更具挑战性的自动语音识别,我们还将讨论有趣的 CTC 算法。

最后,如果你喜欢这篇文章,你可能也会喜欢我关于变形金刚、地理定位机器学习和图像字幕架构的其他系列。

让我们继续学习吧!

音频深度学习变得简单(第二部分):为什么 Mel 频谱图表现更好

原文:https://towardsdatascience.com/audio-deep-learning-made-simple-part-2-why-mel-spectrograms-perform-better-aad889a93505?source=collection_archive---------1-----------------------

直观音频深度学习系列

用 Python 处理音频的简明指南。什么是 Mel 光谱图以及如何用简单的英语生成它们。

乔丹在 Unsplash 上的照片

这是我关于音频深度学习系列的第二篇文章。现在,我们知道了声音是如何以数字形式表示的,我们需要将其转换为声谱图以用于深度学习架构,让我们更详细地了解这是如何完成的,以及我们如何调整转换以获得更好的性能。

由于数据准备非常关键,尤其是在音频深度学习模型的情况下,这将是接下来两篇文章的重点。

下面是我计划在这个系列中发表的文章的简要总结。我的目标是不仅要理解事物是如何工作的,还要理解它为什么会这样工作。

  1. 最先进的技术 (什么是声音,它是如何数字化的。音频深度学习在解决我们日常生活中的哪些问题。什么是光谱图,为什么它们都很重要。)
  2. 为什么 Mel Spectrograms 性能更好—本文 (用 Python 处理音频数据。什么是 Mel 光谱图以及如何生成它们)
  3. 特性优化和增强 (通过超参数调整和数据增强增强光谱图特性以获得最佳性能)
  4. 声音分类 (端到端的例子和架构对普通声音进行分类。一系列场景的基础应用。)
  5. 自动语音识别 (语音转文本算法和架构,使用 CTC 丢失和解码进行序列对齐。)
  6. 波束搜索

音频文件格式和 Python 库

深度学习模型的音频数据通常会以数字音频文件的形式开始。通过听录音和音乐,我们都知道这些文件是根据声音的压缩方式以各种格式存储的。这些格式的例子有。wav、. mp3、。wma,。aac,。flac 等等。

Python 有一些很棒的音频处理库。Librosa 是最受欢迎的软件之一,拥有广泛的功能。scipy 也常用。如果您使用 Pytorch,它有一个名为 torchaudio 的配套库,与 Pytorch 紧密集成。它没有 Librosa 那么多的功能,但它是专门为深度学习而构建的。

它们都可以让你阅读不同格式的音频文件。第一步是加载文件。使用 librosa:

或者,您也可以使用 scipy 做同样的事情:

然后你可以想象声波:

将声波可视化(图片由作者提供)

听听吧。如果您使用的是 Jupyter 笔记本,您可以直接在单元格中播放音频。

在笔记本单元格中播放音频(图片由作者提供)

音频信号数据

正如我们在上一篇文章中看到的,音频数据是通过以固定的时间间隔对声波进行采样,并测量每个样本的声波强度或振幅而获得的。该音频的元数据告诉我们采样率,即每秒的样本数。

当音频以压缩格式保存在文件中时。当文件被加载时,它被解压缩并转换成一个 Numpy 数组。无论您从哪种文件格式开始,这个数组看起来都是一样的。

在内存中,音频以数字的时间序列表示,代表每个时间步长的幅度。例如,如果采样率是 16800,一秒钟的音频片段将有 16800 个数字。因为测量是以固定的时间间隔进行的,所以数据只包含振幅数字,而不包含时间值。给定采样速率,我们可以计算出每个幅度数测量是在哪个时刻进行的。

比特深度告诉我们每个样本的幅度测量可以取多少个可能值。例如,位深度为 16 意味着振幅数可以在 0 到 65535(2⁶-1)之间。位深度影响音频测量的分辨率,位深度越高,音频保真度越好。

位深度和采样率决定了音频分辨率(源)

光谱图

深度学习模型很少直接把这个原始音频作为输入。正如我们在第 1 部分中了解到的,通常的做法是将音频转换成声谱图。声谱图是声波的简明“快照”,因为它是图像,所以非常适合输入到为处理图像而开发的基于 CNN 的架构中。

频谱图是使用傅立叶变换从声音信号生成的。傅立叶变换将信号分解成其组成频率,并显示信号中每个频率的振幅。

声谱图将声音信号的持续时间分割成更小的时间片段,然后对每个片段进行傅立叶变换,以确定该片段中包含的频率。然后,它将所有这些部分的傅立叶变换组合成一个单一的图。

它绘制了频率(y 轴)与时间(x 轴)的关系,并使用不同的颜色来表示每个频率的幅度。颜色越亮,信号的能量越高。

简单的频谱图(图片由作者提供)

不幸的是,当我们展示这个光谱图时,没有太多的信息让我们看到。我们以前在科学课上看到的那些彩色光谱图都去哪了?

这是因为人类感知声音的方式。我们能够听到的大部分声音都集中在一个狭窄的频率和振幅范围内。让我们先探索一下,这样我们就能知道如何产生这些可爱的光谱图。

人类是如何听到频率的?

我们听到声音频率的方式被称为“音高”。这是对频率的主观印象。所以高音的频率比低音高。人类不会线性地感知频率。我们对低频之间的差异比对高频更敏感。

例如,如果你听不同的声音对,如下所示:

  • 100 赫兹和 200 赫兹
  • 1000 赫兹和 1100 赫兹
  • 10000 赫兹和 10100 赫兹

你对每对声音之间的“距离”的感知是什么?你能区分每一对声音吗?

尽管在所有情况下,每对之间的实际频率差在 100 Hz 时完全相同,但 100Hz 和 200Hz 的那对听起来比 1000Hz 和 1100Hz 的那对更远。你很难区分 10000 赫兹和 10100 赫兹的频率对。

然而,如果我们认识到 200Hz 的频率实际上是 100Hz 的两倍,而 10100Hz 的频率只比 10000Hz 的频率高 1%,这似乎就不那么令人惊讶了。

这是人类感知频率的方式。我们听到的是对数标度,而不是线性标度。我们如何在数据中说明这一点?

梅尔标度

Mel 量表是通过对大量听众进行实验来考虑这一点的。这是一种音高标准,听众可以据此判断每个单元与下一个单元的音高距离相等。

梅尔标度测量人对音高的感知(来源,经 Barry Truax 教授许可)

人类是如何听到振幅的?

人类对声音振幅的感知是声音的响度。类似于频率,我们听到的响度是对数的,而不是线性的。我们用分贝标度来说明这一点。

分贝标度

在这个范围内,0 dB 代表完全静音。从那里开始,测量单位呈指数增长。10 dB 比 0 dB 大 10 倍,20 dB 大 100 倍,30 dB 大 1000 倍。在这个范围内,超过 100 分贝的声音开始变得难以忍受。

常见声音的分贝水平(改编自来源

我们可以看到,为了以现实的方式处理声音,在处理数据中的频率和振幅时,通过 Mel 标度和分贝标度使用对数标度是很重要的。

这正是 Mel 光谱图的目的。

梅尔光谱图

Mel 频谱图相对于绘制频率与时间关系的常规频谱图有两个重要变化。

  • 它使用 Mel 标度,而不是 y 轴上的频率。
  • 它使用分贝标度而不是振幅来表示颜色。

对于深度学习模型,我们通常使用这个而不是简单的声谱图。

让我们修改上面的谱图代码,用 Mel 标度代替频率。

使用 Mel 标度的光谱图(图片由作者提供)

这比以前好,但大多数光谱图仍然是暗的,没有携带足够的有用信息。所以我们修改一下,用分贝标度代替振幅。

梅尔光谱图(图片由作者提供)

终于!这是我们真正在寻找的东西😃。

结论

我们现在已经了解了如何预处理音频数据和准备 Mel 光谱图。但是在我们可以将它们输入深度学习模型之前,我们必须优化它们以获得最佳性能。

在下一篇文章中,我们将看看如何通过调整 Mel 光谱图来增强模型的数据,以及增加我们的音频数据来帮助我们的模型推广到更广泛的输入。

最后,如果你喜欢这篇文章,你可能也会喜欢我关于变形金刚、地理定位机器学习和图像字幕架构的其他系列。

让我们继续学习吧!

音频深度学习变得简单(第三部分):数据准备和增强

原文:https://towardsdatascience.com/audio-deep-learning-made-simple-part-3-data-preparation-and-augmentation-24c6e1f6b52?source=collection_archive---------1-----------------------

直观音频深度学习系列

增强声谱图特性以获得最佳性能的简明指南。还有数据扩充,用简单的英语说

由维达尔·诺德里-马西森在 Unsplash 上拍摄的照片

这是我关于音频深度学习系列的第三篇文章。到目前为止,我们已经了解了声音是如何数字化表示的,深度学习架构通常使用声音的声谱图。我们还看到了如何在 Python 中预处理音频数据以生成 Mel 光谱图。

在本文中,我们将更进一步,通过调整其超参数来增强我们的 Mel 谱图。我们还将研究音频数据的增强技术。这两者都是数据准备的重要方面,以便从我们的音频深度学习模型中获得更好的性能。

下面是我计划在这个系列中发表的文章的简要概述。我的目标是不仅要理解事物是如何工作的,还要理解它为什么会这样工作。

  1. 最先进的技术 (什么是声音,它是如何数字化的。音频深度学习在解决我们日常生活中的哪些问题。什么是光谱图,为什么它们都很重要。)
  2. 为什么 Mel Spectrograms 表现更好 (用 Python 处理音频数据。什么是 Mel 光谱图以及如何生成它们)
  3. 数据准备和扩充——本文 (通过超参数调整和数据扩充增强光谱图特性以获得最佳性能)
  4. 声音分类 (端到端的例子和架构来分类普通的声音。一系列场景的基础应用。)
  5. 自动语音识别 (语音转文本算法和架构,使用 CTC 丢失和解码进行序列对齐。)
  6. 波束搜索 (语音到文本和 NLP 应用程序常用的增强预测的算法)

超参数调谐光谱图优化

在第 2 部分中,我们学习了什么是 Mel 光谱图,以及如何使用一些方便的库函数来创建一个。但是为了真正获得我们深度学习模型的最佳性能,我们应该针对我们试图解决的问题优化 Mel 光谱图。

我们可以使用许多超参数来调整声谱图的生成方式。为此,我们需要理解一些关于光谱图是如何构建的概念。(我会尽量保持简单直观!)

快速傅立叶变换

计算傅立叶变换的一种方法是使用一种称为 DFT(离散傅立叶变换)的技术。DFT 的计算非常昂贵,因此在实践中,使用 FFT(快速傅立叶变换)算法,这是实现 DFT 的有效方式。

然而,FFT 将给出音频信号整个时间序列的整体频率分量。它不会告诉您音频信号中的这些频率成分是如何随时间变化的。例如,您将看不到音频的第一部分具有高频率,而第二部分具有低频率,等等。

短时傅立叶变换(STFT)

为了获得更精细的视图并查看频率随时间的变化,我们使用 STFT 算法(短时傅立叶变换)。STFT 是傅立叶变换的另一种变体,它通过使用滑动时间窗口将音频信号分解成更小的部分。它对每个部分进行 FFT,然后将它们合并。因此,它能够捕捉频率随时间的变化。

STFT 沿着信号滑动一个重叠窗口,并对每个片段进行傅立叶变换(源

这将沿着时间轴将信号分成多个部分。其次,它还将信号沿频率轴分成几个部分。它获取整个频率范围,并将其划分为等间距的频段(在 Mel 音阶中)。然后,对于每个时间段,它计算每个频带的振幅或能量。

让我们用一个例子来说明这一点。我们有一个 1 分钟的音频剪辑,包含 0Hz 到 10000 Hz 之间的频率(在 Mel 范围内)。假设梅尔谱图算法:

  • 选择窗口,以便将我们的音频信号分成 20 个时间段。
  • 决定将我们的频率范围分成 10 个频段(即 0–1000 赫兹、1000–2000 赫兹、…9000–10000 赫兹)。

该算法的最终输出是形状为(10,20)的 2D Numpy 数组,其中:

  • 20 列中的每一列代表一个时间段的 FFT。
  • 10 行中的每一行代表一个频带的幅度值。

我们来看第一列,这是第一时间段的 FFT。它有 10 行。

  • 第一行是 0–1000Hz 之间第一个频带的振幅。
  • 第二行是 1000–2000Hz 之间第二频带的振幅。
  • …等等。

阵列中的每一列都成为 Mel 光谱图图像中的一个“列”。

Mel 光谱图超参数

这为我们调谐 Mel 谱图提供了超参数。我们将使用 Librosa 使用的参数名。(其他库将具有等效的参数)

频段

  • fmin —最小频率
  • fmax —显示的最大频率
  • n_mels —频带的数量(即梅尔箱柜)。这是声谱图的高度

时间段

  • n_fft —每个时间段的窗口长度
  • hop_length —每步滑动窗口的样本数。因此,声谱图的宽度=样本总数/跳跃长度

您可以根据您拥有的音频数据类型和您正在解决的问题来调整这些超参数。

MFCC(人类语言)

Mel Spectrograms 对于大多数音频深度学习应用来说效果很好。然而,对于处理人类语音的问题,如自动语音识别,您可能会发现 MFCC(梅尔频率倒谱系数)有时工作得更好。

这些基本上采用 Mel 光谱图并应用几个进一步的处理步骤。这从 Mel 频谱图中选择对应于人类说话的最常见频率的频带的压缩表示。

由音频生成的 MFCC(图片由作者提供)

上面,我们已经看到相同音频的梅尔频谱图具有形状(128,134),而 MFCC 具有形状(20,134)。MFCC 从音频中提取与捕捉声音的基本质量最相关的小得多的特征集。

数据扩充

增加数据集多样性的一种常用方法是人工增加数据,尤其是在数据不足的情况下。我们通过小幅修改现有的数据样本来做到这一点。

例如,对于图像,我们可能会做一些事情,如稍微旋转图像,裁剪或缩放图像,修改颜色或光照,或者给图像添加一些噪声。由于图像的语义没有发生实质性的变化,因此来自原始样本的相同目标标签仍然适用于增强样本。例如,如果图像被标记为“猫”,则增强图像也将是“猫”。

但是,从模型的角度来看,这感觉像是一个新的数据样本。这有助于您的模型推广到更大范围的图像输入。

就像图像一样,也有几种技术来增强音频数据。这种增强既可以在产生声谱图之前对原始音频进行,也可以在生成的声谱图上进行。扩充频谱图通常会产生更好的结果。

光谱图增强

用于图像的常规变换不适用于光谱图。例如,水平翻转或旋转会显著改变声谱图及其代表的声音。

相反,我们使用一种称为 SpecAugment 的方法,在这种方法中,我们将声谱图的某些部分分离出来。有两种口味:

  • 频率屏蔽—通过在谱图上添加水平条,随机屏蔽一系列连续频率。
  • 时间掩码—类似于频率掩码,不同之处在于我们使用竖条随机从谱图中划出时间范围。

(图片由作者提供)

原始音频增强

有几个选项:

时移—将音频向左或向右移动一个随机量。

  • 对于没有特定顺序的声音,如交通或海浪,音频可以环绕。

通过时移增强(图片由作者提供)

  • 另一方面,对于像人类说话这种顺序很重要的声音,间隙可以用沉默来填充。

音高移位—随机修改声音各部分的频率。

通过音高变换增强(图片由作者提供)

时间延伸—随机减慢或加快声音。

通过时间拉伸增强(图片由作者提供)

添加噪声—向声音添加一些随机值。

通过添加噪声进行增强(图片由作者提供)

结论

我们现在已经看到了我们如何预处理和准备音频数据以输入到深度学习模型。这些方法通常应用于大多数音频应用。

我们现在准备探索一些真正的深度学习应用,并将在下一篇文章中涵盖一个音频分类示例,在那里我们将看到这些技术的实际应用。

最后,如果你喜欢这篇文章,你可能也会喜欢我关于变形金刚、地理定位机器学习和图像字幕架构的其他系列。

让我们继续学习吧!

音频深度学习变得简单:声音分类,循序渐进

原文:https://towardsdatascience.com/audio-deep-learning-made-simple-sound-classification-step-by-step-cebc936bbe5?source=collection_archive---------0-----------------------

动手教程,直观音频深度学习系列

音频深度学习基础应用场景的端到端示例和架构,用简单的英语讲述。

照片由布鲁斯·马尔斯在 Unsplash 上拍摄

声音分类是音频深度学习中使用最广泛的应用之一。它包括学习对声音进行分类和预测声音的类别。这种类型的问题可以应用于许多实际场景,例如对音乐剪辑进行分类以识别音乐的流派,或者对一组说话者的简短话语进行分类以基于语音识别说话者。

在本文中,我们将通过一个简单的演示应用程序来理解用于解决此类音频分类问题的方法。我的目标是不仅要理解事物是如何工作的,还要理解它为什么会这样工作。

我的音频深度学习系列中还有几篇文章,你可能会觉得有用。他们探索了这一领域的其他有趣主题,包括我们如何为深度学习准备音频数据,为什么我们将 Mel 光谱图用于深度学习模型,以及它们是如何生成和优化的。

  1. 最先进的技术 (什么是声音,它是如何数字化的。音频深度学习在解决我们日常生活中的哪些问题。什么是光谱图,为什么它们都很重要。)
  2. 为什么 Mel Spectrograms 表现更好 (用 Python 处理音频数据。什么是 Mel 光谱图以及如何生成它们)
  3. 数据准备和扩充 (通过超参数调整和数据扩充增强光谱图特征以获得最佳性能)
  4. 自动语音识别 (语音转文本算法和架构,使用 CTC 丢失和解码进行序列对齐。)
  5. 波束搜索 (语音到文本和 NLP 应用程序常用的增强预测的算法)

音频分类

就像使用 MNIST 数据集对手写数字进行分类被认为是计算机视觉的“Hello World”类型的问题一样,我们可以将这一应用视为音频深度学习的入门问题。

我们将从声音文件开始,将它们转换成频谱图,将它们输入到 CNN plus 线性分类器模型中,并对声音所属的类别进行预测。

音频分类应用程序(图片由作者提供)

有许多合适的数据集可用于不同类型的声音。这些数据集包含大量音频样本,每个样本都有一个类别标签,根据您要解决的问题来识别声音的类型。

这些类别标签通常可以从音频样本的文件名的某个部分或者从文件所在的子文件夹名称中获得。或者,类标签在单独的元数据文件中指定,通常是 TXT、JSON 或 CSV 格式。

示例问题—对普通城市声音进行分类

在我们的演示中,我们将使用城市声音 8K 数据集,它包含了从日常城市生活中记录的普通声音的语料库。这些声音取自 10 个类别,如钻井、狗叫和警笛声。每个声音样本都标有其所属的类别。

下载数据集后,我们看到它由两部分组成:

  • audio 文件夹中的音频文件:它有 10 个子文件夹,分别命名为“ fold1 ”到“ fold10 ”。每个子文件夹包含多个'。wav '音频样本等'fold 1/103074–7–1–0 . wav
  • “元数据”文件夹中的元数据:它有一个文件“ UrbanSound8K.csv ”,该文件包含关于数据集中每个音频样本的信息,例如其文件名、其类别标签、“文件夹”子文件夹位置等等。对于这 10 个类别中的每一个,类别标签是一个从 0 到 9 的数字类别 ID。数字 0 代表空调,1 代表汽车喇叭,等等。

样本长度约为 4 秒。这是一个样本的样子:

演习的音频样本(图片由作者提供)

采样速率、通道数量、位数和音频编码

数据集创建者的建议是使用折叠进行 10 重交叉验证,以报告指标并评估模型的性能。然而,由于本文中我们的目标主要是作为音频深度学习示例的演示,而不是获得最佳指标,因此我们将忽略折叠,并将所有样本简单地视为一个大型数据集。

准备培训数据

至于大多数深度学习问题,我们会按照以下步骤:

深度学习工作流程(图片由作者提供)

这个问题的训练数据相当简单:

  • 特征(X)是音频文件路径
  • 目标标签(y)是类名

因为数据集有一个包含这些信息的元数据文件,所以我们可以直接使用它。元数据包含关于每个音频文件的信息。

既然是 CSV 文件,我们可以用熊猫来读。我们可以从元数据中准备要素和标签数据。

这为我们提供了训练数据所需的信息。

带有音频文件路径和类别 id 的训练数据

元数据不可用时扫描音频文件目录

拥有元数据文件对我们来说很容易。我们如何为不包含元数据文件的数据集准备数据?

许多数据集仅由排列在文件夹结构中的音频文件组成,从该文件夹结构中可以导出类别标签。为了以这种格式准备我们的训练数据,我们将执行以下操作:

元数据不可用时准备训练数据(图片由作者提供)

  • 扫描目录并准备好所有音频文件路径的列表。
  • 从每个文件名或父子文件夹的名称中提取类别标签
  • 将每个类名从文本映射到数字类 ID

不管有没有元数据,结果都是一样的——特征由一列音频文件名组成,目标标签由类 id 组成。

音频预处理:定义变换

这种带有音频文件路径的训练数据不能直接输入到模型中。我们必须从文件中加载音频数据,并对其进行处理,以便它是模型所期望的格式。

当我们读取和加载音频文件时,这种音频预处理将在运行时动态完成。这种方法类似于我们对图像文件所做的。由于音频数据和图像数据一样,可能相当大且占用大量内存,所以我们不想提前一次将整个数据集读入内存。因此,我们在训练数据中只保留音频文件名(或图像文件名)。

然后,在运行时,当我们一次训练一批模型时,我们将加载该批的音频数据,并通过对音频应用一系列转换来处理它。这样,我们一次只能在内存中保存一批音频数据。

对于图像数据,我们可能有一个转换管道,首先将图像文件作为像素读取并加载。然后,我们可能会应用一些图像处理步骤来调整数据的形状和大小,将它们裁剪为固定的大小,并将它们从 RGB 转换为灰度。我们可能还会应用一些图像增强步骤,如旋转、翻转等。

音频数据的处理非常相似。现在我们只是在定义函数,稍后当我们在训练期间向模型提供数据时,它们将会运行。

预处理输入到我们模型的训练数据(图片由作者提供)

从文件中读取音频

我们需要做的第一件事是读取并加载音频文件。wav”格式。因为我们在这个例子中使用 Pytorch,下面的实现使用 torchaudio 进行音频处理,但是 librosa 也可以。

从文件加载的音频波(图片由作者提供)

转换到两个频道

一些声音文件是单声道的(即 1 个音频通道),而它们中的大多数是立体声的(即 2 个音频通道)。由于我们的模型期望所有项目具有相同的尺寸,我们将通过将第一个通道复制到第二个通道来将单声道文件转换为立体声。

标准化采样率

一些声音文件以 48000Hz 的采样率进行采样,而大多数以 44100Hz 的采样率进行采样。这意味着对于一些声音文件,1 秒钟的音频将具有 48000 的数组大小,而对于其他声音文件,它将具有 44100 的较小数组大小。同样,我们必须将所有音频标准化并转换为相同的采样速率,以便所有阵列具有相同的维度。

调整到相同的长度

然后,我们调整所有音频样本的大小,使其具有相同的长度,方法是通过用静音填充来延长其持续时间,或者将其截断。我们将该方法添加到我们的 AudioUtil 类中。

数据扩充:时移

接下来,我们可以对原始音频信号进行数据扩充,方法是应用时移,将音频向左或向右移动一个随机量。在这篇文章中,我将更详细地介绍这种和其他数据增强技术。

声波的时移(图片由作者提供)

梅尔光谱图

然后,我们将增强的音频转换为 Mel 声谱图。它们捕捉音频的基本特征,通常是将音频数据输入深度学习模型的最合适的方式。为了获得更多关于这方面的背景知识,你可能想阅读我的文章(这里和这里),这些文章用简单的语言解释了什么是 Mel 频谱图,为什么它们对音频深度学习至关重要,以及它们是如何生成的,以及如何调整它们以从你的模型中获得最佳性能。

一个声波的 Mel 声谱图(图片由作者提供)

数据扩充:时间和频率屏蔽

现在,我们可以进行另一轮增强,这次是在 Mel 声谱图上,而不是在原始音频上。我们将使用一种称为 SpecAugment 的技术,它使用这两种方法:

  • 频率屏蔽—通过在谱图上添加水平条,随机屏蔽一系列连续频率。
  • 时间掩码—类似于频率掩码,不同之处在于我们使用竖条随机从谱图中划出时间范围。

光谱增强后的 Mel 光谱图。请注意水平和垂直蒙版带(图片由作者提供)

定义自定义数据加载器

既然我们已经定义了所有预处理转换函数,我们将定义一个自定义 Pytorch 数据集对象。

要使用 Pytorch 将数据提供给模型,我们需要两个对象:

  • 使用所有音频转换来预处理音频文件并一次准备一个数据项的自定数据集对象。
  • 一个内置的 DataLoader 对象,它使用 Dataset 对象提取单个数据项并将它们打包成一批数据。

使用数据加载器准备批量数据

我们需要将数据输入到模型中的所有函数现在都已经定义好了。

我们使用自定义数据集从 Pandas 数据框架中加载要素和标签,并以 80:20 的比例将该数据随机分为训练集和验证集。然后,我们使用它们来创建我们的训练和验证数据加载器。

分割我们的数据用于训练和验证(图片由作者提供)

当我们开始训练时,数据加载器将随机获取一批包含音频文件名列表的输入特征,并对每个音频文件运行预处理音频转换。它还将获取一批包含类 id 的相应目标标签。因此,它将一次输出一批训练数据,这些数据可以直接作为输入输入到我们的深度学习模型中。

数据加载器应用转换并一次准备一批数据(图片由作者提供)

让我们从一个音频文件开始,逐步了解数据转换的步骤:

  • 文件中的音频被加载到 shape 的 Numpy 数组中(num_channels,num_samples)。大多数音频以 44.1kHz 采样,持续时间约为 4 秒,结果是 44,100 * 4 = 176,400 个样本。如果音频有一个声道,数组的形状将是(1,176,400)。类似地,持续时间为 4 秒、具有 2 个声道并以 48kHz 采样的音频将具有 192,000 个样本和(2,192,000)的形状。
  • 由于每个音频的通道和采样速率不同,接下来的两个转换会将音频重新采样为标准的 44.1kHz 和标准的 2 通道。
  • 由于一些音频剪辑可能多于或少于 4 秒,我们也将音频持续时间标准化为 4 秒的固定长度。现在,所有项目的数组都具有相同的形状(2,176,400)
  • 时移数据扩充现在随机地向前或向后移动每个音频样本。形状没有改变。
  • 增强的音频现在被转换成 Mel 频谱图,产生(num_channels,Mel freq _ bands,time_steps) = (2,64,344)的形状
  • SpecAugment 数据增强现在可以将时间和频率遮罩随机应用于 Mel 光谱图。形状没有改变。

因此,每个批次将有两个张量,一个用于包含 Mel 光谱图的 X 特征数据,另一个用于包含数字类 id 的 y 目标标签。这些批次是从每个训练时期的训练数据中随机选取的。

每个批次都有一个形状(批次 _sz,数量 _ 通道,Mel 频率 _ 波段,时间 _ 步骤)

一批(X,y)数据

我们可以看到一批中的一个项目。我们看到带有垂直和水平条纹的 Mel 谱图,显示了频率和时间掩蔽数据增强。

数据现在可以输入到模型中了。

创建模型

我们刚刚完成的数据处理步骤是我们的音频分类问题中最独特的方面。从这里开始,模型和训练过程与标准图像分类问题中通常使用的非常相似,并且不特定于音频深度学习。

由于我们的数据现在由光谱图图像组成,我们构建了一个 CNN 分类架构来处理它们。它有四个卷积块来生成特征图。然后,这些数据被重新调整为我们需要的格式,以便可以输入到线性分类器层,最终输出 10 个类别的预测。

该模型采用一批预处理数据并输出类别预测(图片由作者提供)

关于模型如何处理一批数据的更多细节:

  • 将一批图像输入到具有 shape (batch_sz,num_channels,Mel freq_bands,time_steps) ie 的模型中。(16, 2, 64, 344).
  • 每个 CNN 层应用其过滤器来增加图像深度。频道数量。随着内核和步长的应用,图像的宽度和高度会减小。最后,经过四个 CNN 层,我们得到输出的特征地图 ie。(16, 64, 4, 22).
  • 这将汇集并展平为(16,64)的形状,然后输入到线性层。
  • 线性层为每个类别 ie 输出一个预测分数。(16, 10)

培养

我们现在准备创建训练循环来训练模型。

我们为优化器、损失和调度器定义函数,以随着训练的进行动态地改变我们的学习率,这通常允许训练在更少的时期内收敛。

我们为几个时期训练模型,在每次迭代中处理一批数据。我们跟踪一个简单的准确性度量,它测量正确预测的百分比。

推理

通常,作为训练循环的一部分,我们还会评估验证数据的度量。然后,我们将对看不见的数据进行推断,也许是通过从原始数据中保留一个测试数据集。但是,出于本演示的目的,我们将使用验证数据。

我们运行一个推理循环,小心禁用梯度更新。通过模型执行正向传递来获得预测,但是我们不需要反向传递或运行优化器。

结论

我们现在已经看到了声音分类的端到端示例,这是音频深度学习中最基础的问题之一。这不仅在广泛的应用中使用,而且我们在这里讨论的许多概念和技术将与更复杂的音频问题相关,例如自动语音识别,我们从人类语音开始,理解人们在说什么,并将其转换为文本。

最后,如果你喜欢这篇文章,你可能也会喜欢我关于变形金刚、地理定位机器学习和图像字幕架构的其他系列。

让我们继续学习吧!

用雪花增强您的数据湖分析

原文:https://towardsdatascience.com/augment-your-data-lake-analytics-with-snowflake-b417f1186615?source=collection_archive---------13-----------------------

凯利·西克玛在 Unsplash 上的照片

对雪花供电的数据湖的建议

M 如今,现代企业需要处理各种大规模、快速移动的数据源,这给数据团队带来了巨大的压力,他们需要持续提取、转换和加载数据以获得有意义的见解。除非出于分析目的对数据和信息进行战略性管理,否则它们不会提供切实的价值。

什么是数据湖?

虽然这是一个众所周知的概念,但对于门外汉来说,“数据湖”最简单的形式就是存储所有原始数据的仓库。

让我们更进一步;对于现代分析需求,数据湖是一个中央存储库,用于存储结构化数据(如本地或云数据库)、半结构化数据(如 json、avro、parquet、xml 和其他原始文件)以及非结构化数据(如从几个(甚至数百万个)批处理或连续数据流中获取的音频、视频和二进制文件)。

数据湖,作者图片

为什么是数据湖?

每个组织都以这样或那样的方式处理 SaaS(软件即服务)数据,因为 SaaS 应用程序易于配置和使用。因此,每秒钟都会产生指数级的数据量,这使得实时保护和存储数据变得非常困难。此外,如果不处理这些指数数据,就有可能失去从中获得的价值。

这就是数据湖出现的原因。数据湖平台强健、灵活且易于扩展,可为各种使用情形下的用户提供海量数据集的快速分析,包括维护单一真实来源。

让我们看看理想的数据湖需要解决的一些挑战:

挑战,作者图片

具有数据湖工作负载的雪花云数据平台

雪花——理想的数据湖,作者图片

雪花通过原生 SQL 支持实现快速数据访问、查询性能和复杂转换。它内置了数据访问控制和基于角色的访问控制(RBAC)来管理和监控数据访问安全性。

雪花为数据湖工作负载提供了灵活、弹性、健壮的大规模并行处理(MPP)架构,能够在单个 SQL 查询中加入各种数据格式(结构化和半结构化)。

*(注:对非结构化数据的支持目前在 数据湖工作量 处于私下预览)

  1. 用例: 增强现有云数据湖功能

企业在构建、设计和实现基于 S3、Blob 或 GCP 存储的数据湖方面花费了大量精力。为了实现简单性并利用雪花数据湖工作负载的高性能,企业应该扩大现有的数据湖。

如何?

外部表和简单的 SELECT 语句,按作者分类的图像

“雪花存储集成”功能将 AWS S3、Azure BLOB 或 GCP 存储上的云存储作为外部表(本质上是雪花生态系统之外的数据文件中的表)集成到雪花数据湖。

通过创建一个存储集成和一种文件格式(可以把它想象成一个决定文件格式配置的雪花对象),来自雪花的查询可以使用简单和标准的 ANSI SQL(如 select 语句)直接选择数据。这并不需要先将数据从它的云位置文件加载到雪花中。此外,这有助于确定相关数据是否是分析所必需的,以及是否应该存储在数据湖中。

另一方面,为了提高查询性能,可以在外部表之上使用带有“部分”选项的物化视图。物化视图中的这些数据可以在“云通知服务”的基础上自动刷新,该服务在外部“阶段”创建新数据文件时通知雪花。

优点?

实体化视图和外部表,按作者排序的图像

以下优势直接取自雪花——此处:

  • 雪花支持对数据湖执行并发查询,而不会影响性能。
  • 使用外部表直接查询数据湖中的数据,而不必移动数据。
  • 通过对外部表使用物化视图来提高查询性能。
  • 将外部表与 Apache Hive metastore 同步。
  • 使用分区自动刷新功能,从您的数据湖中自动注册新文件。
  • 借助 Snowsight(雪花的内置可视化用户界面)加速数据探索。

2.用例: 雪花表(原始数据湖+数据管道上的自动化)

雪花和数据管道,作者图片

使用雪花作为数据湖工作负载,从所有来源将所有数据按原样接收到雪花数据湖表中。轻松地同时对结构化和半结构化数据执行 SQL 操作。

矢量化拼花扫描仪的最新 GA 功能将拼花文件的性能提高了 8 倍。

利用雪花作为数据湖有助于使数据存储更便宜、压缩和高度安全。

使用外部表格的自动化数据管道

使用外部表格的自动化数据管道,按作者分类的图像

“流”、“数据共享”的可用性以及半结构化数据文件(如 parquet、avro 等)的增强性能。,您可以为云存储中的外部数据构建自动化的数据管道。

如何自动化?

当一个新文件进入云存储时,一个通知会在外部表上触发一个流。流和“任务”执行加载(通过转换)到雪花表格中。最后,通过外部(现在可能)和内部表的数据共享可以用来共享数据。或者我们可以简单地将内部表中的数据(丰富的数据)卸载到云存储中。这里的亮点是,加载- >转换- >卸载过程不需要人工干预

优点?

以下优势直接取自雪花— 此处:

  • 我们应该用雪花来扩充现有的数据湖,以提供免维护的自动化。
  • 通过使用云通知和“Snowpipe”的连续数据管道,自动接收数据并支持变更数据捕获(CDC)。
  • 我们使用标准的 ANSI SQL 高效地转换数据,并通过利用雪花的自动扩展、缩小、内扩或外扩计算将丰富的数据加载到雪花中。
  • 我们使用针对“变体”数据类型和不同摄取风格的流和任务来构建和编排数据管道。
  • 使用 RBAC 模型实现粒度访问控制。
  • 轻松实现数据屏蔽、行列级过滤访问,增强数据安全性。
  • 使用扩展功能,如数据共享和市场。
  • 利用雪花压缩数据存储来减少数据量并最终降低成本。
  • 使用单一云数据平台满足您的所有数据需求,加快数据接收、转换和消费。
  • 向所有数据用户提供您的数据的一个副本—真实的单一来源。
  • 通过将所有数据放入雪花中,最大限度地减少外部数据湖管理、调优和优化的任务。

总而言之,考虑使用雪花数据湖工作负载进行高效的数据接收、转换和编排。

如果您想要更多信息或帮助扩充或迁移您现有的数据湖,或者完全在雪花上构建一个新的数据湖,请随时联系我们。

https://www.indigochart.com/

或者发送电子邮件至hello@indigochart.com并在 LinkedIn 上关注我们:

https://www.linkedin.com/company/indigochart/

参考文献:

[1] 雪花文件,雪花公司。

[2] 雪花为数据湖,雪花公司。

[3] 自动化数据管道,雪花公司。

[4] 雪花数据湖,雪花公司。

使用情感分析的转换器和同义词替换来扩充您的小型数据集(第 1 部分)

原文:https://towardsdatascience.com/augment-your-small-dataset-using-transformers-synonym-replacement-for-sentiment-analysis-part-1-87a838cd0baa?source=collection_archive---------11-----------------------

如何增加数据集的大小,以便稍后用于 NLP 分类任务。

作家创造的形象。

现在是 2021 年 1 月,一场风暴正在 Reddit 上酝酿。一群个人投资者,即 sub Reddit 'wall street bets的成员,开始谈论一家公司,行业专业人士和机构投资者认为这家公司正在走下坡路。而且理由很充分——他们的业务正在被在线零售商侵蚀。

但这些“流氓”个人投资者并不认同业内专业人士的观点。许多人用有意义的分析支持的金融术语来表达他们的观点。散户投资者对机构投资者前所未有的异议,以及 Reddit 用户的集体交易行为,导致 GameStop 股票暴涨。短短几天内,股价从 17.25 美元飙升至 500 多美元,创造了历史上最大的“空头挤压”之一。

为什么个人投资者战胜了大机构,为什么没有人预见到这一天的到来?

因为没人在听。

输入情感分析:

情感分析是自然语言处理(*)的一种形式。它识别和量化文本数据、情感状态以及其中的主题、人物和实体的主观信息。情感分析使用 NLP 方法和算法,这些方法和算法或者是基于规则的,或者是混合的,或者是依靠机器学习技术从**数据集中学习数据。*因此,it 最具挑战性的一个方面是在大规模范围内寻找并标记有意义的数据。

回到我们最初的案子。如果机构将人气作为分析指标,GameStop 的反弹不会让任何人感到意外。但是,要实现这一目标,还需要克服一些挑战。

魔鬼就在数据中:

首先,存在金融术语独特的问题。这个行业充满了术语,大多数情绪分析工具训练的数据不一定能够理解。然后是它的领域限制的本质和整体缺乏可用的结构化数据(分类)的问题。让我们现实一点,用 IMDb 电影评论或推特数据集的公共数据来训练 NLP 模型是不会成功的。综上所述,这些挑战导致大多数用于金融的现成 NLP 工具表现参差不齐。

我们需要的是来自声誉良好的金融领域来源的标记数据。尽管有大量的非结构化数据,但没有足够多的标记源来训练一个监督模型,以解决植根于金融情绪分析的内在挑战。

传统上,解决这一需求意味着手动通读成千上万的文档,对它们进行分类并相应地进行标记。这将是一个漫长而痛苦的过程,并不能保证很快给我们想要的结果。

幸运的是变形金刚及其通过迁移学习执行数据扩充和分类的能力可以改变这一切。

在这篇文章中,我们将基于我从网上收集和标记的金融文章的小样本建立一个大型数据集,我们随后将使用它来建立一个情感分析模型,该模型可以测量金融数据的情感。

照片由罗文·辛普森在 Unsplash 上拍摄

什么是变形金刚和迁移学习?

简而言之 Transformers 是预先训练好的机器学习模型,主要用于文本数据。谷歌在 2017 年的论文'中首次介绍了注意力是你所需要的',它们已经取代了 NLP 任务中的其他神经网络框架。

变形金刚的性能远远超过其他型号,这正是我们手头任务所需要的。在这个练习中,我们将使用 HuggingFace (一个提供用于下载预训练模型的 API 的包)。

迁移学习是一种监督学习,将为特定任务训练的现有模型应用于一组不同的类别,这些类别中的数据要少得多。理论上,原始模型已经从原始数据中学到了足够的东西,通过重新训练它的一部分,它可以应用于我们的新任务。迁移学习是通过用与我们的任务相关的新数据训练所述模型的最终层来完成的,从而使模型适应新的领域。

挑战:

对金融新闻等领域进行情感分析面临多重挑战。在金融领域可能有负面含义的词在其他领域不一定被认为是不好的。

处理财务数据时需要注意的另一个因素是在一个句子中处理多个身份。例如,常见的句子有‘在该机构的历史性裁决中,X 机构对 Y 公司罚款数百万美元’。这使得任何对情绪进行分类的尝试都变得困难,因为这取决于我们关注的是哪个实体。**

这个问题有很多有趣的解决方法;然而,在这篇文章中,我已经精心挑选了数据来避免这个问题,所以我们不会涉及它。如果你想了解更多如何处理这个问题,可以在这里找到一个方法。

在这个练习中,我使用了手动标记的 352 条财经新闻,我将它加载到一个熊猫数据框架中,删除了所有数字字符,单词被压缩(“s to is”),每篇文章的情绪要么被标记为积极,要么被标记为消极。

数据视图

我们写点代码吧!

数据扩充是一种创建新数据的方法,方法是对原始源进行多处小的更改,从而扩展可用于训练模型的数据。它广泛应用于图像分类任务,也已经成功地应用于文本分类任务。

在我们能够扩充数据之前,我们需要解决使用转换器的分类任务的一个主要瓶颈,它对可以训练的文本大小的限制,一些文章和金融文档可能有多页长,试图对它们训练模型可能会导致内存问题。为了解决这个问题,我们将使用名为 T5 的 transformer 模型来总结我们的文本数据。T5 是在非监督和监督任务的多任务混合上预先训练的编码器-解码器模型,并且对于该模型,每个任务被转换成文本到文本格式。T5 是开箱即用的总结任务的最佳表现者之一(无需对我们的数据进行训练),因此我们将在这里使用它。

函数'summary _ article'将我们的文章编码、汇总并解码回比源材料小得多的人类可读文本,超参数' min_length '和' max_length '将确保摘要的大小在标准阈值之间,同时保持其信息完整。一旦完成,输出将被传递到我们的增强管道的下一个步骤。

****Before Summarization:***
*len(data_source['text'].max().lower().split()) =* ***520***
***After Summarization:***
*len(data_source['text'].max().lower().split()) =* ***60****

有多种方法来为 NLP 执行数据扩充。有些技术比其他技术更复杂,而且都有优缺点。NLP 绝不是一门精确的科学,当涉及到扩充数据时,理解你的领域和任务是至关重要的。

“简约是极致世故*——老子:***

我发现关于数据增强的一篇论文很有趣,是的 Jason Wei 的【EDA:提高文本分类任务性能的简单数据增强技术】

在这篇文章中,Jason 和 Kai 探讨了同义词替换 (SR) 、随机插入 (RI) 、随机交换 (RS) 和随机删除 (RD) 如何成为轻量级且高效的数据扩充方式,何时以及如何实现,以及与其他方法相比,它们在 NLP 任务中的表现如何。

来自 Jason Wei 论文的子集。

飞马座的飞行;

**“用提取的间隙句进行抽象概括的预训练”,又名 飞马 。它的独特性在于它的“自我监督”,预训练目标架构。与其他通过提取句子的小部分来推断句子意思的模型不同,Pegasus 完全“屏蔽”了句子,并试图通过阅读句子前后的文本来找到它。

Pegasus 确实擅长数据总结,但也非常擅长转述句子。该模型非常易于使用,不需要很多依赖关系,只需几行代码,我们就可以为训练准备好我们的扩充数据集。

任务:

为了能够有效地利用我们的小数据集,我们将执行文本释义和同义词替换,以获得足够大和唯一的数据集来训练我们的情感分析模型。

型号名称为' pegasus_paraphrase ',更多信息请点击此处。首先,我们将获得我们的依赖项,并下载模型和‘tokenizer’。记号赋予器将句子分解成更小的块,这些块的大小和形状取决于任务和模型。

我们需要做的就是编写一个方法,使用我们的记号化器将我们的文本转换为一个序列,它将截断长句,填充小句,并返回一个张量结构,模型将使用它来生成释义的句子。

每个句子都将通过模型,超参数值是通过试错法选择的。这里看到的超参数是:

  • 【num _ beam】,模型将在一个序列中搜索最优后续词的次数
  • ****‘num _ return _ sequences’**模型将生成的句子数量(我们将超过 50)
  • 【温度】 调节高概率词出现的机会,减少低概率词在世代中出现的机会。

Pegasus 将生成新的句子,这些句子将作为新的系列返回到我们的数据帧中,其中每一行都是生成的文本列表。然后,我们将通过使用 Pandas 的“explode”功能将列表中的每个元素变成一行来使它们变平。

在模型遍历了每个句子之后,我们最终得到了一个比源材料大 11 倍的新数据集。然而,这个数据有一个问题。每一行中大约有一半(见下图)以非常相似的文本开始,忽略这一点可能会导致我们稍后付出代价,因为我们可能会过度拟合模型,破坏我们的努力。

项目中间输出:大多数作品都以非常相似的措辞开始

因此,我们将执行数据扩充任务的第二部分。同义词替换。这个过程将扩展文本,并进一步推广它。

首先,扩充的数据通过一个名为' find_synonym 的方法传递,在这个方法中,在前半部分文本中找到的任何停用词和数值都被过滤掉。

然后把剩下的单词一分为二地分组。每一个新句子将会把每一组中的两个单词替换成它们各自的同义词。为了找到同义词,我们将利用一个名为自然语言工具包的包,更好的说法是'【nltk ',* 一套用于符号和统计自然语言处理的库和程序。具体来说它的语料库阅读器' wordnet '包含了浩如烟海的词汇信息和同义词。*

最后,在函数遍历了数据集的每一行之后,我们将确保没有任何重复或空值,新的语料库将被保存以备后用。

在模型遍历了每个句子并且数据被正确格式化之后,我们最终得到了一个比源材料大 50 多倍的新数据集,它仍然保留了原始数据的含义、风格和上下文。

项目最终产出

结论:

在本文中,我们介绍了如何使用转换器和同义词替换技术来执行数据扩充,使用少量数据带来的挑战以及如何克服这些挑战,以及如何创建一个由足够大的带标签的金融文章组成的数据集来执行有意义的分析。

如果你好奇如何使用这些数据进行情感分析,点击这里跳转到本系列的第二部分: 如何使用变形金刚进行情感分析&迁移学习

来源:

  • 本项目回购:https://github.com/cmazzoni87/ComputerVisionRegression
  • 【EDA:提升文本分类任务性能的简易数据增强技术】 贾森·魏,。
  • 飞马变形金刚文档:https://huggingface.co/transformers/model_doc/pegasus.html
  • T5 变压器文档:https://huggingface.co/transformers/model_doc/t5.html

使用白蛋白和 PyTorch 的扩增方法

原文:https://towardsdatascience.com/augmentation-methods-using-albumentations-and-pytorch-35cd135382f8?source=collection_archive---------21-----------------------

增强管道

讨论最新的增强研究和使用所讨论的方法的新颖实现

作者图片

自从深度神经网络在 20 世纪 90 年代末成名以来,有限的数据一直是一块绊脚石。缺少数据会导致*过拟合,*尤其是对于具有大量参数的架构。幸运的是,增强对于数据有限的机器学习任务来说是一个启示。它提供了两个主要优势。

首先,您可以通过创建原始数据集的多个扩充副本来增加数据量,这些副本也可用于平衡倾斜的数据集。

第二,它迫使模型对于样本中的不相关特征是不变的,例如,人脸检测任务中的背景。这有助于模型更好地概括。

在本帖中,我们将探索最新的数据扩充方法,以及使用所讨论方法的新颖实现。我们将主要讨论两种方法,自动增强和随机增强。所以,让我们从简单介绍这两种方法开始,然后继续讨论实现。

自动增强

在“ 中介绍的自动增强:从数据中学习增强策略 ”试图自动选择应用于样本的变换的类型和幅度。他们提出了一种强化学习方法,通过离散化搜索问题来找到有效的数据扩充策略。所提出的方法找到增强策略 S ,其具有关于变换、变换的幅度以及使用这些变换的概率的信息。

让我们看看算法的一些细节。

搜索空间

策略 S 包含五个子策略,每个子策略有两个变换,每个变换有一个幅度和一个概率参数。

注意这里的子策略对转换的顺序很敏感,如果应用程序的顺序颠倒了,则被视为不同的子策略。

有 16 种增强转换可供控制器选择(将在实现部分讨论)。每个变换的幅度和应用概率的范围分别被离散成 10 和 11 个均匀间隔的值。

搜索算法

搜索算法有两个组成部分:一个控制器,这是一个递归神经网络(RNN),和训练算法,这是最接近的政策优化算法。

来源:自动增强纸

控制器(RNN)从搜索空间预测增强策略 S ,然后预测的策略用于训练小得多的子模型。子模型在通过对训练集应用 5 个预测子策略而生成的扩充数据上被训练。对于小批量中的每个示例,随机选择 5 个子策略中的一个来扩充图像。然后,子模型在一个单独的保留验证集上进行评估,以测量精确度 R ,它被用作训练 RNN 控制器的奖励信号。

你可以在这里阅读全文了解所有细节。

AutoAugment 是第一批有效实现数据扩充自动化方法的论文之一,并显示出比以前的自动化方法好得多的结果。然而,单独的优化过程和非常大的搜索空间具有很高的计算成本。此外,该方法作出了一个强有力的假设,即来自一个较小网络的结果可以转移到一个大得多的网络。事实证明,这一假设并不完全正确,RandAugment 论文中指出,该论文提出了一种更快且在某些情况下性能更好的数据扩充方法,我们将在接下来讨论该方法。

随机扩增

像 AutoAugment 这样的大多数已学习的增强算法创建一个代理任务,该代理任务在较小的网络上为最佳增强策略进行优化,如前一部分所述。这种方法有一些需要解决的基本缺陷。在“ RandAugment:具有减少的搜索空间的实用自动数据扩充 ”中介绍的 RandAugment 试图绕过这种代理任务,并且还极大地减少了搜索空间,以减轻训练过程的计算负荷。该方法将参数的数量减少到两个, NM (将在随后的小节中详细讨论),并在训练过程中将它们视为超参数。

搜索空间

RandAugment 不是学习策略,而是以 1/ K 的统一概率从一组 K 转换中随机挑选一个转换。要挑选的转换数量由超参数 N 给出,这将搜索空间中的总策略减少到 K pow N 。学习增强方法的主要好处来自增加样本的多样性,RandAugment 采用的均匀概率方法保持了样本的多样性,但搜索空间显著减小。

资料来源:RandAugment Paper

最后,类似于自动增强的每个变换的幅度范围被离散成由 M 给出的 10 个均匀间隔的值,然而,与已知的方法相反,所有的变换都遵循用于 M 的相同的时间表,这将幅度的搜索空间减少到仅仅一个。这是因为增强的最佳幅度取决于模型和训练集的大小,更大的网络需要更大的数据失真(请参考上图),这在直觉上是有意义的。该论文还指出,更大的数据集需要更大的数据失真,这似乎很奇怪,作者提出的一个假设是,小数据集的激进增强可能会导致低信噪比。在任何情况下,基于模型大小和训练集大小,所有变换都遵循最佳幅度的明确模式,这暴露了使用较小网络来估计所有任务的变换幅度的已有增强方法中的基本缺陷。

搜索算法

RandAugment 使用简单的网格搜索来寻找 NM 的最优值,这是通过为两个超参数选择一组值并在单独的验证集上测试这些组的所有排列来完成的。最后,选择对验证集有最佳改进的组合。可以对每个样品、每个批次或每个时期执行该程序。

现在,我们已经对算法有了相当好的理解,让我们向实现前进。如前所述,RandAugment 是一种更好的算法,但是,AutoAugment 论文中的一些关键发现可以与 RandAugment 结合使用,以进一步降低计算成本。

你可以从这里下载这篇文章的笔记本,笔记本上有所有必要的代码来设置增强算法,并在 fastai 提供的一小部分 Imagenet 数据集上用 Resnet50 进行测试。然而,在这篇文章中,我们将只关注笔记本中与增强相关的部分。

履行

让我们从笔记本上的自定义 RandAugment 函数开始,然后对其进行分解。

def randAugment(N, M, p, mode="all", cut_out = False): **# Magnitude(M) search space**  shift_x = np.linspace(0,150,10)
  shift_y = np.linspace(0,150,10)
  rot = np.linspace(0,30,10)
  shear = np.linspace(0,10,10)
  sola = np.linspace(0,256,10)
  post = [4,4,5,5,6,6,7,7,8,8]
  cont = [np.linspace(-0.8,-0.1,10),np.linspace(0.1,2,10)]
  bright = np.linspace(0.1,0.7,10)
  shar = np.linspace(0.1,0.9,10)
  cut = np.linspace(0,60,10) **# Transformation search space** Aug =[#0 - geometrical
        A.ShiftScaleRotate(shift_limit_x=shift_x[M], rotate_limit=0,   shift_limit_y=0, shift_limit=shift_x[M], p=p),
        A.ShiftScaleRotate(shift_limit_y=shift_y[M], rotate_limit=0, shift_limit_x=0, shift_limit=shift_y[M], p=p),
        A.IAAAffine(rotate=rot[M], p=p),
        A.IAAAffine(shear=shear[M], p=p),
        A.InvertImg(p=p),
        #5 - Color Based
        A.Equalize(p=p),
        A.Solarize(threshold=sola[M], p=p),
        A.Posterize(num_bits=post[M], p=p),
        A.RandomContrast(limit=[cont[0][M], cont[1][M]], p=p),
        A.RandomBrightness(limit=bright[M], p=p),
        A.IAASharpen(alpha=shar[M], lightness=shar[M], p=p)] **# Sampling from the Transformation search space** if mode == "geo": 
    ops = np.random.choice(Aug[0:5], N)
  elif mode == "color": 
    ops = np.random.choice(Aug[5:], N)
  else:
    ops = np.random.choice(Aug, N)

  if cut_out:
    ops.append(A.Cutout(num_holes=8, max_h_size=int(cut[M]),   max_w_size=int(cut[M]), p=p)) transforms = A.Compose(ops)
  return transforms, ops

该功能大致可分为以下两部分。

量值搜索空间

本节将星等范围离散为 10 个均匀分布的值。

变换搜索空间

" Aug "是变换搜索空间,算法可以从中以均匀的概率挑选出 N 个变换。请花点时间看看这些单独的转换做了什么,以便更好地创建这个搜索空间。

注意该功能有三种模式“地理”、颜色全部”。“地理”模式适用于基于颜色的特征定义图像中感兴趣对象的任务,例如火灾探测。类似地,“颜色”模式适用于形状定义感兴趣对象的任务,例如人脸检测、汽车检测等。然而,“全部”模式使用所有的转换。

AutoAugment 论文中的作者表明,不同的数据集对正向和负向的不同变换都很敏感。因此,“没有免费的午餐”定理也适用于数据扩充,你需要为每个项目调整算法。

来源:自动增强纸

注意上表中给出的幅度范围是针对 PIL 库中的函数,然而,我们在 randAugment()函数中使用白蛋白,主要是因为白蛋白库使用的 open cv 比 PIL 快。您必须进行实验,并为您喜欢使用的库计算出每个变换的幅度范围。

现在让我们来看看训练期间的转变幅度的时间表。

def train_model(model, criterion, optimizer, scheduler, **aug_mode="all"**, **cut_out=False**, **max_M=9**, num_epochs=25): best_model_wts = copy.deepcopy(model.state_dict())
  best_acc = 0.0 **N=2;M=0;p=0.5** for epoch in range(num_epochs):
        print('Epoch {}/{}'.format(epoch, num_epochs - 1))
        print('-' * 10)

        **transforms, ops = randAugment(N=N, M=M, p=p, mode=aug_mode, cut_out=cut_out)**
        dataloaders, dataset_sizes = create_dataloaders(root, train_df, valid_df, label_dict, bs=32, **transforms=transforms**) # Each epoch has a training and validation phase
        for phase in ['train', 'val']:
            if phase == 'train':
                model.train()  # Set model to training mode
            else:
                model.eval()   # Set model to evaluate mode running_loss = 0.0
            running_corrects = 0 # Iterate over data.
            for inputs, labels in dataloaders[phase]:
                inputs = inputs.to(device)
                labels = labels.to(device) # zero the parameter gradients
                optimizer.zero_grad() # forward
                # track history if only in train
                with torch.set_grad_enabled(phase == 'train'):
                    outputs = model(inputs)
                    preds = torch.argmax(input = outputs, dim = 1)
                    loss = criterion(outputs, labels) # backward + optimize only if in training phase
                    if phase == 'train':
                        loss.backward()
                        optimizer.step() # statistics
                running_loss += loss.item() * inputs.size(0)
                running_corrects += torch.sum(preds ==          torch.argmax(input = labels, dim = 1))
            if phase == 'train':
                scheduler.step() epoch_loss = running_loss / dataset_sizes[phase]
            epoch_acc = running_corrects.double() /  dataset_sizes[phase] print('{} Loss: {:.4f} Acc: {:.4f}'.format(
                phase, epoch_loss, epoch_acc)) # deep copy the model
            if phase == 'val' and epoch_acc > best_acc:
                best_acc = epoch_acc
                best_model_wts = copy.deepcopy(model.state_dict())
            **elif phase == 'val' and epoch_acc < best_acc:
                stp = int((9-M)*((best_acc-epoch_acc)/best_acc))
                M += max(1,stp)
                M = min(M, max_M)
                if M < max_M:
                  print("Augmentaion Magnitude Changed To : {}\n".format(M))** print('Best val Acc: {:4f}'.format(best_acc)) # load best model weights
    model.load_state_dict(best_model_wts)
    return model

在上面的代码块中,与时间表相关的代码行被加粗。

在这个示例中,我为 M 使用了预定的时间表,每当历元精度低于验证集上的最佳精度时, M 就递增。根据最大可能值(9)和当前值 M 之间的差值计算出 M 将增加的数量,当前值由两个精度和最佳精度之间的差值的比率缩放。

注意该时间表不会产生额外成本,但是非常严格,RandAugment paper 在每批之后对 N 和 M 进行网格搜索,以找到它们的最佳值。然而,即使与自动增强相比计算成本大幅降低,对于大多数机器学习项目来说,网格搜索对于具有适度设置和单个 gpu 的人来说仍然是不可行的。

此实现中使用的时间表不是唯一可用的时间表,您可以试验每个子策略的转换数量 N 以及这些转换的概率 p. 增强不是一门精确的科学,每个锁都有不同的密钥,您需要通过试验和创造性思维来找到匹配的密钥。

参考

自动增强纸:https://arxiv.org/abs/1805.09501

RandAugment 论文:https://arxiv.org/abs/1909.13719

Python 中的增广赋值表达式 Walrus 运算符:=及其他

原文:https://towardsdatascience.com/augmented-assignment-expression-in-python-the-walrus-operator-and-beyond-9db36a219df3?source=collection_archive---------26-----------------------

不仅仅是关于海象算子,还有很多相关的概念

汤米·克兰巴赫在 Unsplash 上拍摄的照片

从 3.8 版本开始,Python 中就包含了新的特征增强赋值表达式。特别是,结果出现了一个新的操作符——内联赋值操作符:=。因为它的外观,这个操作符通常被称为海象操作符。在本文中,我将讨论这个操作符的关键方面,以帮助您理解这项技术。

事不宜迟,让我们开始吧。

表达式和语句的区别

在 Python 或一般的编程语言中,有两个密切相关的概念:表达式和语句。让我们看两行简单的代码,如下所示。

>>> 5 + 3    #A
8
>>> a = 5 + 3    #B

#A 是一个表达式,因为它的计算结果是一个整数。相比之下,#B 是一个语句,确切地说是一个赋值语句。更一般地说,表达式是计算值或 Python 中的对象的代码(Python 中的值都是对象)。例如,当你调用一个函数时(如abs(-5)),它是一个表达式。

语句是不计算任何值的代码。简而言之,他们执行一个动作,或者做一些事情。例如,赋值语句创建一个变量。with语句建立了一个上下文管理器。if…else…语句创建逻辑分支。

如您所见,表达式和语句的最大区别在于代码是否计算为对象。

你可能想知道为什么我们在这里关心这种区别。我们继续吧。

扩充赋值是一个语句

许多人熟悉的最常见的扩充任务形式是+=。下面的代码向您展示了一个示例。

>>> num = 5
>>> num += 4

判断一行代码是否是表达式的一个简单方法是简单地将它发送给内置的print函数,该函数应该接受任何对象。当您发送一个要打印的语句时,它会引发一个SyntaxError。让我们来试试:

>>> print(num += 4)
  File "<input>", line 1
    print(num += 4)
              ^
SyntaxError: invalid syntax

事实上,我们不能在print函数中使用增强赋值。或者,为了确定某些代码是否是表达式,有另一个内置函数eval,它计算一个表达式。当代码不能被求值时,比如一个语句,就会发生错误,如下所示。

>>> eval("num += 4")
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "<string>", line 1
    num += 4
        ^
SyntaxError: invalid syntax

事实上,x += y 是语句x = x + y的简写,这是一个设计好的赋值。因为产生的变量与用于增量(y)的变量同名(即 x),所以它也被称为就地加法运算。

同样的就地分配也适用于其他的扩充分配,例如-=*=/=

扩充赋值表达式是一个表达式

与这些扩充赋值语句不同,新的扩充赋值表达式是一个表达式。让我们从一个简单的例子开始。

>>> (another_num := 15)
15

如上图,因为我们使用的是交互式 Python 控制台,所以如果该行代码的求值结果是任何对象(除了None,控制台在输出时会忽略它),那么求值结果会自动显示。因此,上面的扩充赋值表达式确实是一个表达式。请注意,这里使用的一对括号是出于语法原因,因为这样一个增强的赋值表达式本身没有任何实际用途,因此不推荐使用。

我们可以证明扩充赋值表达式的本质是一个带有printeval函数的表达式,如下所示。

>>> print(another_num := 15)
15
>>> eval("(another_num := 15)")
15

实际用例是什么?

扩充赋值表达式也称为内联扩充赋值。正如它的行所示,这是一个内联操作,因此我们在刚刚求值的地方定义一个变量——本质上,我们将求值和赋值合并到一个步骤中。

也许这有点太专业,难以理解,但让我给出一个看似合理的用例。在一个典型的 if…else…语句中,if 或 else 子句只能接受表达式,这样子句就可以对运算的表达式求值为 true 或 falsy。显然,在从句中,你不能使用陈述句。考虑下面这个看似合理的用例。

def withdraw_money(account_number):
    if account := locate_account(account_number):
        take_money_from(account)
    else:
        found_no_account()

如上所示,locate_account函数返回使用account_number找到的账户。如果找到,从赋值表达式中创建的变量account将进一步用于if子句的主体中。否则,使用顺序方式,这里有一个可能的解决方案:

def withdraw_money(account_number):
    account = locate_account(account_number)
    if account:
        take_money_from(account)
    else:
        found_no_account()

这两种实现之间的差异可能微不足道。然而,实际的用例可能更复杂,涉及更多的分支,这证明了使用赋值表达式技术的合理性。考虑以下使用案例:

def withdraw_money(account_number):
    if account := locate_account_in_saving(account_number):
        take_money_from_saving(account)
    elif account := locate_account_in_checking(account_number):
        take_money_from_checking(account)
    elif account := locate_account_in_retirement(account_number):
        take_money_from_retirement(account)
    else:
        pass

正如你所看到的,有了更多的分支,如果你选择分成两个独立的步骤:函数调用,然后赋值,上面的代码会变得复杂得多。不信的话,请自行尝试:)

结论

在本文中,我们回顾了 Python 3.8 中增加的扩充赋值表达式技术。我们不仅研究了这项技术本身,还回顾了与这项技术相关的关键概念。我希望您对这种技术及其正确的用例有更好的理解。

感谢阅读这篇文章。通过注册我的简讯保持联系。还不是中等会员?通过使用我的会员链接支持我的写作(对你没有额外的费用,但是你的一部分会费作为奖励由 Medium 重新分配给我)。

Python 中的扩充赋值

原文:https://towardsdatascience.com/augmented-assignments-python-caa4990811a0?source=collection_archive---------25-----------------------

理解增强赋值表达式在 Python 中是如何工作的,以及为什么在可变对象中使用它们时要小心

由凯利·西克玛在 Unsplash 上拍摄的照片

介绍

Python 从 C 语言中借用的一个概念是扩充赋值,本质上是标准赋值的简称。

在今天的简短指南中,我们将讨论什么是扩充赋值,以及为什么在对可变数据类型使用它们时要格外小心。

Python 中的扩充赋值

扩充赋值创建了一种速记法,将二进制表达式合并到实际的赋值中。例如,以下两个语句是等效的:

a = a + b
a +=  b  # augmented assignment

在下面的代码片段中,我们展示了 Python 语言中允许的所有扩充赋值

a += b
a -= b
a *= b
a /= b
a //= ba &= b
a |= b
a ^= ba >>= b
a <<= b
a %= b
a **= b

扩充赋值适用于任何支持隐含二进制表达式的数据类型。

>>> a = 1
>>> a = a + 2
>>> a
3
>>> a += 1
>>> a
4>>> s = 'Hello'
>>> s = s + ' '
>>> s 
'Hello '
>>> s += 'World'
>>> s
'Hello World'

扩充赋值如何处理可变对象

当使用扩充赋值表达式时,将自动选取最佳操作。这意味着对于支持就地修改的特定对象类型,将应用就地操作,因为它比先创建副本再进行分配要快。如果你想添加一个条目到一个列表中,通常使用append()方法比使用连接更快:

>>> my_lst = [1, 2, 3]
>>> my_lst.append(4)  # This is faster 
>>> my_lst = my_lst + [4]  # This is slower

由于就地操作速度更快,它们将被自动选择用于扩充任务。为了弄清楚这些表达式是如何处理可变对象类型的,让我们考虑下面的例子。

如果我们使用串联,那么将会创建一个新的列表对象。这意味着,如果另一个名称共享同一引用,它将不受新对象列表中任何未来更新的影响:

>>> lst_1 = [1, 2, 3]
>>> lst_2 = lst_1
>>> lst_1 = lst_1 + [4, 5]
>>> lst_1
[1, 2, 3, 4, 5]
>>> lst_2
[1, 2, 3]

现在,如果我们使用增强赋值表达式,这意味着表达式将使用extend()方法来执行更新,而不是连接,那么我们也将影响所有其他拥有共享引用的名称:

>>> lst_1 = [1, 2, 3]
>>> lst_2 = lst_1
>>> lst2 += [4, 5]
>>> lst_1
[1, 2, 3, 4, 5]
>>> lst_2
[1, 2, 3, 4, 5]

扩充赋值的三个优点

总而言之,扩充赋值表达式提供了以下三个优点:

  1. 它们需要更少的击键,而且更干净
  2. 它们速度更快,因为表达式的左边只需要计算一次。在大多数情况下,这可能不是一个巨大的优势,但当左侧是一个复杂的表达式时,它肯定是。
x += y  # x is evaluated only once
x = x + y  # x is evaluated twice

3.将选择最佳操作,这意味着如果对象支持就地更改,则就地操作将应用于串联。但是,您应该非常小心,因为有时这可能不是您想要的,因为在应用就地操作区域时,名称共享引用可能会相互影响。

最后的想法

在今天的文章中,我们讨论了 Python 中的增强赋值表达式,以及它们如何帮助您编写更 Python 化、更清晰甚至更快的代码。

此外,我们强调了这种类型的表达式如何应用于可变数据类型,这可能会给我们带来共享引用的麻烦。

成为会员 阅读介质上的每一个故事。你的会员费直接支持我和你看的其他作家。你也可以在媒体上看到所有的故事。

https://gmyrianthous.medium.com/membership

你可能也会喜欢

https://codecrunch.org/what-does-if-name-main-do-e357dd61be1a

使用 AugLy 扩充数据

原文:https://towardsdatascience.com/augmenting-data-using-augly-a5c275bfa6ce?source=collection_archive---------30-----------------------

使用 AugLy 增强文本、图像、音频和视频

马库斯·斯皮斯克在 Unsplash 上的照片

当我们使用的数据集不包含太多信息时,数据扩充是一个重要的部分,因此我们不能单独使用这些数据来建立模型,因为模型不会因训练数据中缺乏信息而被一般化。让我们试着通过一个例子来理解这一点。

假设我们正在尝试建立一个图像分类模型。我们使用的数据集包含 10 个类和每个类的 100 幅图像。现在我们可以构建模型了,但问题是它是否能被泛化和优化到足以用于新数据集的预测。这个问题可能会出现,因为一个类中仅有 100 个图像可能无法捕获该类的所有信息。所以,我们能做的就是克服这一点,我们需要每一个类有更多的图像。

数据扩充通过处理图像来帮助生成数据。现在我们可以在训练本身中使用这些数据,或者用它来检查模型的稳健性。数据扩充通过稍微修改数据集影像的副本来创建更多影像。

AugLy 是由脸书研究团队创建的开源 python 库,它有助于数据扩充,并支持不同类型的数据,如音频、视频、图像和文本。它包含 100 多种可以相应使用的增强功能。

在本文中,我们将使用 AugLy 探索一些数据扩充技术。

安装所需的库

我们将从使用 pip 安装 AugLy 开始。下面给出的命令可以做到这一点。

!pip install augly
!sudo apt-get install python3-magic

导入所需的库

在这一步中,我们将导入加载图像和执行数据扩充所需的库。

import augly.image as imaugs
import augly.utils as utils
from IPython.display import display

导入库后,下一步是加载映像。

正在加载图像

对于本文,我们可以采用任何图像或图像数据集。我拍了自己的照片来进行数据扩充。为了使图像看起来更清晰而不覆盖所有屏幕,我们将使用 AugLy Scaler 缩放它。

input_img_path = "/content/img1.jpg"
input_img = imaugs.scale(input_img_path, factor=0.2)

执行增强

现在,我们将开始放大过程,并应用不同的图像放大。

  1. 模因格式
display(
    imaugs.meme_format(
        input_img,
        text="LOL",
        caption_height=70,
        meme_bg_color=(0, 0, 0),
        text_color=(250, 200, 150),
    )
)

迷因(来源:作者)

在这里,您可以使用不同类型的文本并设置它们的颜色,您选择的文本将显示在您正在使用的图像上。

2。饱和度

display(
    imaugs.saturation(
        input_img,
        factor=1.5
    )
)

饱和度(来源:作者)

这里你可以看到饱和度是如何使图像变亮的,因子变量是可以改变的,你可以使用不同的饱和度值。

3。透视变换

aug = imaugs.PerspectiveTransform(sigma=200.0)
display(aug(input_img, metadata=meta))

观点(来源:作者)

西格玛值决定标准差的值,西格玛值越大,转换越剧烈。

类似地,AugLy 中提供了大量不同的增强功能,您可以使用下面的命令查看所有这些功能,并阅读它们,然后在您的图像中使用它们。

help(imaugs)

转换(来源:作者)

继续尝试不同的图像/图像数据集。如果您发现任何困难,请在回复部分告诉我。

本文是与 Piyush Ingale 合作完成的。

在你走之前

感谢 的阅读!如果你想与我取得联系,请随时联系我在 hmix13@gmail.com 或我的 LinkedIn 简介 。可以查看我的Github简介针对不同的数据科学项目和包教程。还有,随意探索 我的简介 ,阅读我写过的与数据科学相关的不同文章。

八月版:走向货币化

原文:https://towardsdatascience.com/august-edition-towards-monetization-7ae1c8f72876?source=collection_archive---------26-----------------------

月刊

探索数据科学领域以创造财务价值

照片由苏西·黑兹伍德从派克斯拍摄

数据科学是一个快速发展的领域。新的工具、技术和经验正在各种平台上被开发、应用、收获和分享,包括本出版物。由于飞速的进步、不断增长的应用和简化的协作机制,信息过载很容易成为一种自然的结果。非常坦率地说(也是矛盾地说),关于我们提议简化的科学的数据的激增可能是压倒性的。

在许多行业中,数据科学的主要资助目的是产生商业价值。例如,即使数据项目的最初目的可能是更好地了解人口的社会方面,其结果通常会导致一个或多个价值驱动的货币化机会。不幸的是,其中一些好处最终实现了,而另一些根本没有实现。以浓缩的方式提取这些机会可能有助于我们从树木中看到森林,并激发更多关于从个人和组织的角度创造价值的想法。

在本月的新闻简报中,我们认为突出强调一些作者的工作重点是货币化的重要观点可能会有所帮助。我们希望您喜欢浏览该系列,这样做可能会激发您探索更多,点燃火花,并与 TDS 社区分享您自己的贡献。我们迫不及待地想看看你想出了什么!

TDS 志愿编辑助理 John Jagtiani 博士

产品分析推动免费增值转化——在移动游戏及其他领域

细分和查询客户数据将照亮增加货币化的道路

杰里米·利维 — 6 分钟

数据科学家的商业战略

在开始机器学习之前,先学习商业策略的基础知识

到饶彤彤 — 11 分钟

数据科学……没有任何数据?!

为什么尽早聘用数据工程师很重要

由凯西·科济尔科夫 — 6 分钟

建模:教授机器学习算法以交付商业价值

如何训练、调整和验证机器学习模型

到威尔·科尔森 — 9 分钟

insta cart 如何利用数据科学解决复杂的商业问题

买杂货从来没有这么复杂

安德烈·叶 — 11 分钟

企业难以采用深度学习的 5 个原因

当巨大的潜力不能转化为商业利益时

由 Ganes Kesari — 6 分钟

通过机器学习为您的企业创造价值的 6 个步骤

企业高管实现机器学习操作化和货币化的战略路线图

由毗瑟摩德—5 分钟

嘎吱嘎吱的数字。建立模型。预测未来。现在怎么办?

菜鸟数据科学家,还是顶级美元价值创造者?你想成为谁?

尼克·卡拉斯——4 分钟

数据科学家的业务基础知识

使用你的机器学习能力来影响基本的商业方程式。

简·扎瓦日基 — 7 分钟

数据驱动还没死

问题不在于术语;而是我们不是真心的。

由法布里吉奥·范蒂尼 —6 分钟

新播客专题节目

  • 彼得·高— 自动驾驶汽车:过去、现在和未来
  • 丹尼尔·菲兰— 探究人工智能安全的神经网络
  • 2021 年:人工智能的一年(迄今为止)——与我们的朋友一起在《让我们谈谈人工智能》播客上回顾 2021 年最大的人工智能故事
  • Divya Siddarth — 我们对人工智能的看法是错误的吗?

我们还要感谢最近加入我们的所有伟大的新作家:贾姆沙伊德·沙希尔,加尔·沈,布拉克·阿克布卢特,普哈·帕沙克,罗伯特·戴尔,巴维克·帕特尔,若昂·莫拉,杰米·温格,阿雷巴·梅里亚姆 米亚·罗姆、丹尼尔·梅尔乔尔、蒂亚戈·马丁斯、罗霍拉·赞迪、辛迪·霍西亚、阿比奥顿·奥劳耶、马里奥·迈克尔·克雷尔博士、乔尔·施瓦茨曼、拉斯·罗姆霍尔德、特万 埃里克·格林,洛夫库什·阿加瓦尔,阿比德·阿里·阿万,阿希什·比斯瓦斯,普拉纳夫·塔恩拉杰,卡西索,萨拉·加莱比克萨比,弗拉基米尔·布拉戈耶维奇, https://medium.com/u/c5e721e0bfda?source=post_page-----7ae1c8f72876-------------------------------- 迈克尔·甘斯梅尔、阿贾伊·埃德、西楚·张、阿克希尔·普拉卡什、艾丹·佩平、胡安·路易斯·鲁伊斯-塔格尔、莱安德罗·g·阿尔梅达、凯特·加洛等众多。 我们邀请你看看他们的简介,看看他们的工作。

AUK——AUC 的简单替代品

原文:https://towardsdatascience.com/auk-a-simple-alternative-to-auc-800e61945be5?source=collection_archive---------35-----------------------

对于不平衡数据,比 AUC 更好的性能指标

由 Javier Quesada 在 Unsplash 上拍摄的照片

二进制分类和评价指标

分类问题在数据科学中普遍存在。通过分类,模型被训练来标注来自固定标签集的输入数据。当这个固定集合的长度为二时,那么这个问题就叫做二元分类

通常,经过训练的二元分类模型为每个输入返回一个实数值 r 。如果实数值高于设定的阈值 t ,则为输入分配一个正标签,否则,将为输入分配一个负标签。

为二元分类问题计算的评估指标通常基于混淆矩阵。

为了评估分类模型的性能或对不同的模型进行排序,可以选择选取一个阈值 t 并基于它计算精度、召回率、F(1)分数精度。此外,可以通过关注所有阈值(测试集中唯一的 r 分数的数量)来评估模型的性能,而不是选择一个阈值。基于后一种方法的一个常用图表是 ROC 曲线,它描绘了真实正比率(TP / TP + FN)与真实负比率(TN / TN + FP)的关系。然后,该曲线下的面积(AUC,0 到 1 之间的值)用于评估模型的质量,并将其与其他模型进行比较。

联合自卫军的缺点

AUC 是用于对模型性能进行排名的最常用的标量之一。然而,AUC 的缺点鲜为人知;Hand (2009)已经表明 AUC 对不同的分类器使用不同的分类成本分布(在这种情况下;对于不同的阈值 t ),并且它不考虑数据中的类偏度。然而,误分类损失应该取决于属于每个类别的对象的相对比例;AUC 不考虑这些前科。这相当于说,使用一个分类器,错误分类类别 1 是错误分类类别 0 的倍。但是,使用另一个分类器,误分类类 1 是 P 倍严重,其中PP*。这是无意义的,因为单个点的不同种类的错误分类的相对严重性是问题的属性,而不是碰巧被选择的分类器。*

海雀

为了克服这些缺点,Kaymak、Ben-David 和 Potharst (2012)提出了一个相关但不同的指标;Kappa 曲线下的面积(AUK),这是基于被称为 Cohen 的 Kappa 的公认指标。它测量绘制 Kappa 对假阳性率的图形下的面积。就像 AUC 可以被视为整体性能的指标一样,海雀也可以。然而,Kappa 由于偶然性而导致正确的分类。因此,它固有地解释了类偏度。

在本文中,作者展示了海雀的一些特征和优点:

  • Kappa 是真阳性率和假阳性率之差的非线性变换。
  • 凸 Kappa 曲线具有唯一的最大值,可用于选择最佳模型。

此外,如果数据集是平衡的:

  • 科恩的 Kappa 提供了与 ROC 曲线完全相同的信息。
  • AUK = AUC — 0.5 (AUK 和 AUC 仅相差一个常数)。
  • AUK = 0.5 基尼(当数据集中没有偏斜时,AUK 等于基尼系数的一半)
  • 当 ROC 曲线的梯度等于 1 时,Kappa 值最大。因此,通过 Kappa 找到最优模型没有任何附加价值。

结论

也就是说,如果数据集是平衡的。然而,AUC 和 AUK 可能对不平衡数据集有不同的模型排名(请阅读论文中的示例),这在投入生产时会产生巨大的影响。由于 AUK 解释了类偏度,而 AUC 没有,AUK 似乎是更好的选择,应该成为任何数据科学家工具箱的一部分。

代码

假设您有:

  • *概率:*你的分类模型的输出;一个长度为 k 的实数列表。
  • *标签:*分类模型的实际标签;一个由 0 和 1 组成的 k 长度列表。

然后,可以调用下面的类来计算 AUK 和/或得到 Kappa 曲线。

class AUK:
    def __init__(self, probabilities, labels, integral='trapezoid'):
        self.probabilities = probabilities
        self.labels = labels
        self.integral = integral
        if integral not in ['trapezoid','max','min']:
            raise ValueError('"'+str(integral)+'"'+ ' is not a valid integral value. Choose between "trapezoid", "min" or "max"')
        self.probabilities_set = sorted(list(set(probabilities)))

    #make predictions based on the threshold value and self.probabilities
    def _make_predictions(self, threshold):
        predictions = []
        for prob in self.probabilities:
            if prob >= threshold:
                predictions.append(1)
            else: 
                predictions.append(0)
        return predictions

    #make list with kappa scores for each threshold
    def kappa_curve(self):
        kappa_list = []

        for thres in self.probabilities_set:
            preds = self._make_predictions(thres)
            tp, tn, fp, fn = self.confusion_matrix(preds)
            k = self.calculate_kappa(tp, tn, fp, fn)
            kappa_list.append(k)
        return self._add_zero_to_curve(kappa_list)

    #make list with fpr scores for each threshold
    def fpr_curve(self):
        fpr_list = []

        for thres in self.probabilities_set:
            preds = self._make_predictions(thres)
            tp, tn, fp, fn = self.confusion_matrix(preds)
            fpr = self.calculate_fpr(fp, tn)
            fpr_list.append(fpr)
        return self._add_zero_to_curve(fpr_list)

    #calculate confusion matrix
    def confusion_matrix(self, predictions):
        tp = 0
        tn = 0
        fp = 0
        fn = 0
        for i, pred in enumerate(predictions):
            if pred == self.labels[i]:
                if pred == 1:
                    tp += 1
                else: 
                    tn += 1
            elif pred == 1:
                fp += 1
            else: fn += 1
            tot = tp + tn + fp + fn
        return tp/tot, tn/tot, fp/tot, fn/tot

    #Calculate AUK
    def calculate_auk(self):        
        auk=0
        fpr_list = self.fpr_curve()

        for i, prob in enumerate(self.probabilities_set[:-1]):
            x_dist = abs(fpr_list[i+1] - fpr_list[i])

            preds = self._make_predictions(prob) 
            tp, tn, fp, fn = self.confusion_matrix(preds)
            kapp1 = self.calculate_kappa(tp, tn, fp, fn)

            preds = self._make_predictions(self.probabilities_set[i+1]) 
            tp, tn, fp, fn = self.confusion_matrix(preds)
            kapp2 = self.calculate_kappa(tp, tn, fp, fn)

            y_dist = abs(kapp2-kapp1)
            bottom = min(kapp1, kapp2)*x_dist
            auk += bottom
            if self.integral == 'trapezoid':
                top = (y_dist * x_dist)/2
                auk += top
            elif self.integral == 'max':
                top = (y_dist * x_dist)
                auk += top
            else:
                continue
        return auk

    #Calculate the false-positive rate
    def calculate_fpr(self, fp, tn):
        return fp/(fp+tn)

    #Calculate kappa score
    def calculate_kappa(self, tp, tn, fp, fn):
        acc = tp + tn
        p = tp + fn
        p_hat = tp + fp
        n = fp + tn
        n_hat = fn + tn
        p_c = p * p_hat + n * n_hat
        return (acc - p_c) / (1 - p_c)

    #Add zero to appropriate position in list
    def _add_zero_to_curve(self, curve):
        min_index = curve.index(min(curve)) 
        if min_index> 0:
            curve.append(0)
        else: curve.insert(0,0)
        return curve #Add zero to appropriate position in list
    def _add_zero_to_curve(self, curve):
        min_index = curve.index(min(curve)) 
        if min_index> 0:
            curve.append(0)
        else: curve.insert(0,0)
        return curve

要计算 AUK,请使用以下步骤:

auk_class = AUK(probabilities, labels)auk_score = auk_class.calculate_auk()kappa_curve = auk_class.kappa_curve()

最后,我强烈建议只在计算积分时使用梯形,因为这也是 sklearn 计算 AUC 积分的方式。

参考

Hand,D. J. (2009)。测量分类器性能:ROC 曲线下面积的一致替代方法。机器学习77 (1),103–123。

凯马克,u .,本大卫,a .,,波塔斯特,R. (2012)。海雀:AUC 的简单替代。人工智能的工程应用25 (5),1082–1089。

厌倦了棋盘游戏中的失败?如果你是一名数据科学家,你不必这样做。

原文:https://towardsdatascience.com/author-spotlight-7b86e0c683b9?source=collection_archive---------17-----------------------

作者聚焦

通过模拟大量的大富翁游戏、井字游戏和掷骰子游戏,我们能学到什么?

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

杰克 是一名机械工程专业的学生,对数据科学感兴趣。他喜欢在空闲时间模拟棋盘游戏和进行体育分析。我们最近采访了他,聊了聊他在棋盘游戏和统计方面的热门系列,以及其他话题。

作为一名工程专业的学生,最初是什么吸引你进入数据科学领域的?

我的数据科学之旅始于我高中低年级的时候,当时有一门新的计算机科学课程可供选修。在很快看到编程的好处和用处后,我认为这只是我大学申请上的一个额外的复选框变成了真正的热情。

大概就是在这个时候,我发现了FiveThirtyEight这个网站。他们使用数据和统计分析来写关于体育和政治的文章,但是他们题为《谜语者 T21》的系列真正引起了我的兴趣。谜语者每周发出挑战,这些挑战大多需要编码来回答。我将我新发现的数据科学技能用于测试,并以解答每周谜语为乐,同时也学到了更多关于编码的知识。这些谜语向我展示了如何将编码应用到几乎任何事情上,这将激发我对数据科学文章的兴趣。

哪种以数据为中心的项目最吸引你?

数据科学中我更感兴趣的领域是那些需要模拟的领域。因为我有数学和统计学的背景,我喜欢寻找没有固定公式的问题的答案。没有一个公式可以像掷 10 次硬币的结果一样计算出赢得垄断的几率。这些因其复杂性而需要模拟的问题在我看来有最令人满意的结果,这可能是我觉得它们最有趣的原因。

你的数据科学和棋盘游戏系列的创意来自哪里?

我将数据科学与桌游结合的想法是在我被弟弟妹妹们在“大富翁”中击败太多次后开始的。这是我考虑写我的项目之前的几年,所以我的主要目标是利用数据科学来赢得更多与我家人的棋盘游戏。快进 4-5 年,我在卡坦输给了我的室友。不是这个又是

我决定打开 MATLAB,开始再次策划我的复仇。结果真的很有趣,我开始想知道其他人是否也会对这些结果感兴趣。终于,我的数据科学和桌游系列诞生了。

你是如何计划这个系列的?

当我在设计这些项目时,我希望所有背景的人都能够享受这些成果,并在他们的下一个游戏之夜使用它们。有些人真的很喜欢看到项目背后的代码,这就是为什么我要确保在我的代码中包含一部分解释。有些人希望看到大量代表数据的图表和数字(我也是其中之一),所以我也确保用图形来表示我的发现。我还希望那些没有数学或统计学背景的人能够从这些文章中获得一些东西,所以我确保在最后用易于理解的术语总结所有内容。

对你来说,这个项目最意想不到的收获是什么?

在制作这个系列的过程中,有几件事真的让我很惊讶。第一个肯定是看似随机的游戏中有这些真正有趣的模式。当着眼于 1 个游戏的范围时,涉及掷骰子的游戏似乎是随机的,但是扩展到 50,000 个游戏,一些重要的优势就暴露出来了。我发现,把一个本质上涉及到随机数生成器的游戏,变成一篇文章,展示即使是最简单、最随机的游戏也有玩起来的优势,真的很令人满意。

第二个收获是这个系列获得的兴趣。当我第一次发布一篇关于桌游的文章时,我想我可能会从一些人那里得到一些意见,他们也认为这是一个好主意。我没想到的是,在过去的一个月里,我收到了大量的兴趣和反馈。相当多的人真正喜欢阅读这个系列,这促使我寻找新的棋盘游戏来写。

您是否发现了这个系列(这似乎是一个有趣的附带项目)与您的其他数据科学和工程兴趣之间的任何联系?

桌游和工程学之间的联系起初可能看起来模糊不清,但是从我制作这个系列的经验来看,有很多点需要考虑。工程师是专业的问题解决者,将复杂的棋盘游戏转化为计算机可以理解的算法是一个巨大的问题。我已经看到了编码的好处,无论是机器设计(随机模拟轴组件以找到最佳设计)还是机器人技术(预测机器人肢体的电机角度)。虽然在棋盘游戏优势方面获得的知识可能不会在我的其他数据科学或工程兴趣中发挥巨大作用,但在此过程中获得的经验和解决问题的技能是无价的。

说到你的工作和其他项目,你的下一步是什么?

我即将进入机械工程项目的高年级,我开始思考我毕业后想做什么。我将努力专注于机器人技术,希望在该领域运用我的数据科学经验。在公共写作方面,我将继续写我的副业,无论是我现有的系列还是新的系列。我对我的文章的未来感到兴奋,我希望继续增加我对媒体和数据科学的关注。

通过在 Medium 和 LinkedIn 上关注杰克的最新作品,如果你还没有阅读它们,这里是他最近的一些 TDS 帖子,主题从棋盘游戏到迪士尼世界:

  • 杰克的棋盘游戏系列揭示了一些最受欢迎的游戏中的模式和违反直觉的见解——他已经探索了连接 4 、垄断、井字游戏、滑道&梯子和曼卡拉。
  • 如果你计划有一天参观迪士尼公园,你会想看看这个三 - 部分 系列,它使用可用的数据和统计数据来优化最短的等待时间和最多的乘坐次数。
  • 杰克还在他的作品中探索了体育分析,从用蒙特卡洛方法模拟 NFL和对当前 NBA 赛季进行预测,到展望未来 50 年的棒球。

权威情报:数据标签如何提高人工智能模型的准确性

原文:https://towardsdatascience.com/authoritative-intelligence-how-data-labelling-increases-the-accuracy-of-ai-models-ca7d58ec8fdc?source=collection_archive---------15-----------------------

今天,机器学习的方法可以分为两大阵营:以模型为中心和以数据为中心

弗兰基·查马基在 Unsplash 上拍摄的照片

尽管许多人仍然坚持前者,但包括人工智能(AI)杰出人物吴恩达在内的一些人热切地认为,数据,而不是模型,必须是人工智能进步的核心。事实证明他说得有道理。事实上,不止一个。但是让我们从头开始。

虽然所有的 ML 模型本质上都试图做出预测,但标签的准确性决定了这些预测在现实生活中是否成立。换句话说,数据的标记方面需要始终与“外部世界”一致,即模型设计的实际条件。正因为如此,就模型而言,数据标签比其他任何东西都重要。除非数据被正确标注,否则没有任何模型能够达到合理的实际精确度,即使它声称在理论上达到 99%的精确度。

照片由 Alicia Gauthier 在 Unsplash 上拍摄

一个以迷因形式出现的众所周知的例子来自计算机视觉领域:虽然一般人区分不同的吉娃娃和松饼没有问题,但这个看似基本的任务对机器来说非常具有挑战性,该模型的成功不可否认地依赖于干净、完美的标签数据。

因此,数据准确性是迄今为止数据质量最具决定性的组成部分。它必须存在于整个数据集中,ML 模型才能对任何人真正有用。这就是为什么我们可以认为,今天专注于数据标签的准确性可以成为提高所有人工智能模型准确性的主要途径。

今年 6 月,曾担任谷歌大脑(Google Brain)负责人、百度首席科学家的吴教授发起了一项活动,鼓励人工智能开发人员这样做:将他们的注意力从模型和算法转移到提高用于训练这些模型的数据质量上来。根据 ng 的说法,已建立的以模型为中心的方法在开发人员改进模型时保持数据不变,直到他们获得合适的结果。这需要一个极其敏捷的模型,能够以某种方式解决所有与数据质量相关的问题,这些问题可能会在未来某个时间点出现。唉,大多数模型完全没有做到这一点。直截了当地说,你的最终结果只会和你使用的数据一样好,但很少会更好。以数据为中心的方法翻转脚本并保持模型或代码不变,而人工智能从业者迭代地努力提高数据质量。Ng 认为这是前进的方向。我们也这么认为。

以模型为中心与以数据为中心

Ng 的积极探索再次证明了数据在现代人工智能发展中的重要作用。当然,数据质量对于人工智能行业来说并不是一个新话题——的研究一致显示80%的人工智能项目时间都花在了数据准备上。因此,随着人工智能的发展变得越来越以数据为中心,最基本的是,ML 科学家应该敏锐地理解如何通过过程中的数据标记部分来提高他们模型的准确性。

说实话,以模型为中心的方法确实有一些好处;毕竟这样更便宜,更省时,一看就没那么麻烦。作为一名计算机科学家,你可以完全控制正在发生的事情——模型就在你的手中,你可以随心所欲地调整和扭曲。因此,这本质上归结为从那些处理数据的人的角度去了解你所知道的。

一般来说,科学家会尽量避免他们无法直接影响的因素。数据科学家不是贴标签的人,所以通常情况下,他们对数据如何贴标签或由谁贴标签没有发言权。由于这个原因,对于许多 ML 研究者来说,淡化标签的重要性,转而关注模型是有意义的;换句话说,在他们的工作上。

Pablo Merchán Montes 在 Unsplash 上拍摄的照片

打个粗略的比方,作为一个糖果商,你会尽最大努力用你手头的原料做出高质量的巧克力,但你很少自己种植可可豆。

这取决于世界另一端的树农。这种情况下的可可豆就是贴了标签的数据,农民就是贴标签的人。就像糖果制造商一样,数据科学家只是利用提交给他们的东西来制作他们的产品,无论是巧克力还是 ML 模型。

但是,尽管这看似合理并且很有吸引力,但是采用以模型为中心的方法肯定会遇到严重的问题,因为:

💡根据定义,您的输出只能接受您使用的数据。如果数据有噪声,那么再好的模型也只能到此为止。比方说,你正在开发一款帮助用户保持健康饮食的应用。如果你的数据集包含标签错误的项目,比如看起来相似的欧洲萝卜和胡萝卜,那么这个应用注定会表现不佳。因此,如果没有正确的数据,即使您改进了您的模型,整个企业也无法正常工作。不这样想基本上等同于声称新的油漆工作会以某种方式提高你的汽车的性能,更不用说腐烂的发动机了。

💡如果数据是固定的,就不能更新或更改。灵活性是一个好的科学模型(在任何领域)都应该考虑的因素。同样,如果你的第一步是说你永远不会改变你的数据,这是不可能的。换个角度来看,如果你正在开发一个交通控制解决方案,而另一种基本颜色突然必须添加到交通灯的任意红黄绿中,那么你的模型就会过时。为了使您的解决方案有效,您必须重新标记数据以适应这种变化。

💡现在,假设你正在做一个项目,这个项目使用持续更新的数据,比如面部识别软件(新面孔)或语音助手(新口音/方言)。为了保持竞争优势,以模型为中心的方法很可能要么停滞不前,要么彻底改造自己,成为以数据为中心的方法。

💡如果确实需要在以模型为中心的框架内进行更改,那么与简单地更新您的集合相比,任何操作都将花费更长的时间,这是拥有永远无法调整的固定数据的结果。因此,那些在模型上工作的人经常不得不寻找规避问题的方法。回到交通灯的例子,为了适应这种新的变化,而不是更新你的数据集,你必须想出一个巧妙的方法来提高你的模型。这将意味着教会机器识别新颜色,而实际上并没有把它作为集合中的标记颜色。这可能行得通,也可能行不通,而且无论如何都是具有挑战性的。

💡实际上,这意味着以模型为中心的方法是最初采取的较短的道路——假设一切保持不变——但是当需要与模型的初始参数不一致的变化时,这条道路很快变成之字形。

💡因此,可伸缩性也成为一个真正的问题——如果事情在微观层面不稳定,你就无法在宏观层面保持稳定。这就是为什么当原始参数的任何重大变化都可能意味着回到绘图板去思考一种新的方法来解决问题而不接触您的数据时,可伸缩性变得几乎不可能。将它与当今最常见的数据标记方法结合起来——内部途径(当团队使用自己的员工而不是外包来从头开始学习标记数据)——在你能够交付任何可靠的东西之前,你会经历相当长的等待。当你这样做的时候,可能不会持续太久。

同时,以数据为中心的方法具有许多巨大的优势:

💡您的数据可以不断更新和快速验证。这是唯一可能的,因为这种方法是纯数据驱动的。

💡这种方法为您的整个管道带来了相当程度的灵活性和可伸缩性(通常还有弹性)。这是因为你拥有理论上可以无限操纵的数据。自然,在大规模处理人为标注的数据时,这是一项无价的资产。例如,你可能正在处理音频注释,以便训练语音激活的人工智能。如果您已经有 50,000 个记录(这也可以通过以模型为中心的方法实现),这可能足以发布一个基本产品。但是使用数据驱动的方法,您总是可以向同一个数据集添加另一种口音或方言,甚至包括不同的语言。从质量上来说,这改变了一切。

💡另一方面,在以模型为中心的场景中,您要么必须保持现状(即接受产品的局限性),要么考虑精心设计的方法来调整您的模型而不触及数据(这在自然语言处理中很少起作用),或者——可能不承认这一点——切换到以数据为中心的方法,即使是暂时的。

💡普遍性是另一大好处。标签员,特别是在众包的背景下,可以处理几乎每一项任务,并在任务之间切换,为训练模型提供有价值的甚至罕见的数据。比方说,您正在处理地图/导航,以获取最新的商业信息。使用基于模型的固定数据方法,您基本上只能使用当时拥有的数据。但是如果事情已经改变了呢?例如,现在有新的街道标志或一些企业已经搬迁。这可能是一个真正的问题,但如果您的方法是数据驱动的,就不是问题了。特别是如果你使用的是人群工作者:简单地要求他们重新考虑问题点,你就有了一个更新的数据集。

💡如果足够的质量控制机制到位,并且项目得到适当的管理(例如,使用 CSA ),输入数据质量的提高可以极大地促进培训模型的整体结果。

那还有什么可耽搁的?

公平地说,以数据为中心的方法也有一些缺点。也就是说,如果您的团队预算紧张,并且您使用现成的数据集试图完全绕过任何人工处理的标记,那么以模型为中心的方法是唯一的选择。同时,当涉及到您的贴标选择时,上述内部路线可能非常昂贵和耗时,而外包有时可能是一场赌博,通常也花费很多。另一种被称为合成标记的方法需要为 ML 生成人造数据,但需要大量的计算能力,许多较小的公司无法获得。因此,许多团队认为以数据为中心的方法不值得麻烦,主要是因为,事实证明,他们消息不灵通。

以数据为中心的方法会让你走得更远,但前提是你准备好投入时间和/或金钱来处理数据。好消息是,有了众包等方法,数据标注不再需要花费很高的成本,也不再需要几个月才能完成。问题是许多人不知道这些方法的存在,也不知道它们已经变得有效。研究表明几乎 80%的 ML 从业者选择了内部途径,尽管知道它的缺点。这些练习者这样做并不是因为他们特别喜欢这种方法,而是因为他们不知道更好的方法,正如最近的调查所揭示的。

我们只能假设剩下的 20%熟悉一些较新的标记方法,但他们可能对走出熟悉的以模型为中心的方法的舒适区感到不确定和警惕。原因是他们一想到必须处理任何形式的讨厌的数据标签就紧张。因此,这不仅仅是一个转向数据导向方法的完全意识形态的问题,而是实际上学会认识到这种转变并不一定意味着走向绞刑架——它实际上是可以忍受的,甚至是无痛的。

标准化是关键

标准化是我们所追求的。当谈到标准化时,Ng 从行业角度出发,认为所有人工智能项目应该有一个单一的系统来标记数据。但在行业标准建立之前,人工智能开发人员今天已经可以做某些事情来确保他们项目中标签数据的一致性。

首先,我们需要使用一种或多种标准质量保证方法来测量标签的准确性,如黄金标准、共识或样品审查。一个好的开始是为贴标机提供坚实的指导和丰富的例子。重要的是,这些例子不仅要包括要做什么,还要包括要做什么。它们必须足够详细,以指定什么被认为是可接受的或适当的,从而避免常见的问题 混乱的观察 。例如,当贴标机必须标记人脸时,他们是否也被期望标记真实的卡通人物来代表人?这一点必须在贴标签者开始任务之前向他们说明,因为正如大量研究表明的那样,贴标签者通常会避免问澄清性的问题,而会简单地以他们自己的方式解释任务。

其次,标记过程应该在领域知识和背景的设定框架内进行。这一点至关重要,因为如果贴标签的人了解标签的设置,他们就能更好地在使用具有多重含义的词时正确地贴标签,如“手臂”、“日期”或“起重机”词汇、格式和文本风格可以根据行业的不同而有很大的不同,并且应该始终包含在为特定的 ML 项目建立的上下文中。

这些巩固一致性的步骤有助于防止可能出现的准确性问题,特别是当标记 主观数据 时。这种类型的数据没有真理的黄金标准,这经常使过程暴露于不一致的标签,源于每个贴标签者的经验和对任务的理解。这就是所谓的 标记偏差 ,它不同于犯下个体错误甚至混淆观察结果,因为这种情况下的标记不一致有时可能会遵循特定的群体趋势,往往与个人的文化背景有关。例如,“在照片中认出一个亚洲人”对来自美国和英国的人来说意味着不同的事情,例如,对美国人来说是来自中国或日本这样的远东地区的人,对英国人来说是来自印度或尼泊尔这样的南亚地区的人。

最后,虽然标准可能导致笨拙或未解决的不规则性,但重要的是要记住 ML 本质上是迭代的。随着各种模型的测试及其结果的评估,应该不断引入新的数据集来改进模型。因此,数据标注过程和工作团队都应该保持敏捷和灵活,以结合任何必要的更改来微调 ML 模型。

这些变化可能涉及修改数据的某些方面,如数据量或复杂性。它们还可能涉及到基于来自模型测试和验证的任何相关见解来改变过程本身。这种灵活性应始终使表演者能够在必要时通过在持续的任务中提供见解来做出超出实际标签的贡献,这在众包的背景下可能意味着多数投票。

保持控制

总之,数据驱动的方法有很多优点。数据标注的准确性是它的核心。为了确保这种准确性,人工智能从业者必须规划和配置一个质量控制系统。这个多阶段的过程包括分解数据标注任务、编写说明、设计清晰的界面以及与标注团队建立双向沟通渠道。此外,为了从贴标签者的见解中获得价值,数据贴标签过程涉及一个封闭的反馈回路是至关重要的,这基本上意味着在一个开放的对话中无限地来回,即,直到实现一个期望的目标。

让我们想象一下,你正在开发一个交互式机器人,它与购买电子产品的客户交谈,向他们提问,澄清他们的偏好或发货日期,并结束销售。这种类型的人工智能不是静态的。它不仅像每个 AI 应该的那样训练自己,而且还需要客户反馈来操作和改进。基于此,可能需要对模型或贴标机进行一些调整。在这种情况下,这可能意味着识别新的送货地址,并考虑不同的卸货点来规划最快的路线,或者交叉引用同一客户购买的任何其他产品来解决兼容性问题。只有数据驱动的方法才能完全考虑到这一点。在 Toloka 的案例中,数据驱动的跟踪采取与全球无数贴标机众包的形式,每一步都使用自动化质量控制工具和在 Toloka 学院教授的现代人群科学方法进行监控。

主要外卖

足够数量的高质量数据的可用性仍然是人工智能发展的一个障碍。随着以 Ng 为风向标的运动获得势头,对准确标记的数据的需求预计将大幅上升。因此,前瞻性的人工智能从业者现在开始重新评估他们如何给自己的数据贴标签。由于其非常高的成本以及它提供的可扩展性非常少,他们可能会超越内部标记,或者发现自己的价格超出了外部来源,例如预打包数据、抓取或与数据丰富的实体建立关系。

这为众包数据标签的持续崛起奠定了基础,众包数据标签是一种具有成本/时间效益和可伸缩性的替代方案,具有集成的质量控制和微调的、高度自动化的交付管道。2019 年,分析公司cognelytica 报告称,到 2023 年,第三方数据标签市场将从 2018 年的 1.5 亿美元扩大到 10 亿美元以上。其他研究预测了类似的趋势,包括一些来源,如 Grand View Research 估计到 2028 年数据标签市场价值超过 80 亿美元。

底线是,如果人工智能项目要在现实世界中取得成功,它们必须得到高质量的投入。提高数据的质量,进而提高数据所支持的模型的质量,需要精确,也就是准确的标签。幸运的是,合适的数据标签技术和现成的解决方案是可用的:阿彭,Toloka 和 Scale AI 等等。现在,由人工智能从业者来决定如何有效地将这些解决方案集成到他们现有和未来的 ML 项目中,这归结为朝着数据驱动的方法迈出决定性的一步。这一面向目标的先决条件应该得到满足,以确保无错误标签的存在,从而提高 ML 数据的质量,产生更强大的训练模型,并最终实现成功的人工智能创新,从而改善我们未来的生活。

如何在 Pandas 中读取 CSV 文件时自动检测日期/日期时间列并设置它们的数据类型

原文:https://towardsdatascience.com/auto-detect-and-set-the-date-datetime-datatypes-when-reading-csv-into-pandas-261746095361?source=collection_archive---------15-----------------------

小窍门

例如,当 read_csv()将“2021-03-04”和“2021-03-04 21:37:01.123”读取为单纯的“对象”数据类型时,通常可以简单地将它们一次性自动转换为真正的日期时间数据类型,如下所示:

假设我有一个 CSV 数据文件,我想将它读入 Pandas 数据帧,它的一些列是日期或日期时间,但是我不想预先识别/指定这些列的名称。相反,我想自动获取上面图中*、df.info()输出中显示的数据类型,其中适当的列已经被自动*给定了日期时间数据类型(绿色轮廓框)。以下是实现这一点的方法:

from dt_auto import read_csv
df=read_csv('myfile.csv')

注意,我没有而不是直接调用上面的 PD . read _ CSV(read _ CSV 的熊猫版本)。我的 dt_auto.read_csv 函数(参见下面的代码)调用了 pd.read_csv()本身,然后自动检测并转换两个检测到的 datetime 列的数据类型。(此 df 的内容将在下面显示。)

如果我使用了常规的 Pandas pd.read_csv(),那么默认情况下,我将只获得通用的对象数据类型,如下所示(红色外框):

from pandas import read_csv
df=read_csv('myfile.csv')
df.info()

请注意,与原始代码的唯一区别是在导入语句中,我将“from dt_auto”改为“from pandas”。只要您始终只使用“=read_csv()”,而不是将其限定为“=pd.read_csv()”或“=dt_auto.read_csv()”,这就足够了。

下面是我的dt_auto.py(“日期时间自动”)的内容:

import pandas as pd
def dt_inplace(df):
    """Automatically detect and convert (in place!) each
    dataframe column of datatype 'object' to a datetime just
    when ALL of its non-NaN values can be successfully parsed
    by pd.to_datetime().  Also returns a ref. to df for
    convenient use in an expression.
    """
    from pandas.errors import ParserError
    for c in df.columns[df.dtypes=='object']: #don't cnvt num
        try:
            df[c]=pd.to_datetime(df[c])
        except (ParserError,ValueError): #Can't cnvrt some
            pass # ...so leave whole column as-is unconverted
    return df
def read_csv(*args, **kwargs):
    """Drop-in replacement for Pandas pd.read_csv. It invokes
    pd.read_csv() (passing its arguments) and then auto-
    matically detects and converts each column whose datatype
    is 'object' to a datetime just when ALL of the column's
    non-NaN values can be successfully parsed by
    pd.to_datetime(), and returns the resulting dataframe.
    """
    return dt_inplace(pd.read_csv(*args, **kwargs))

但是这不是很冒险吗?如果其中一个列不完全是日期时间列,会怎么样?当然,您可能会有一些看起来像日期但实际上不是日期的模糊字符串,但是这段代码不会盲目转换或丢失非日期时间字符串,原因有二:

  1. 除非 pd.to_datetime 可以成功地解析该列中的每个非 NaN 值并将其转换为日期时间,否则该代码不会转换该列中的任何值。换句话说,我们不会让它将字符串转换成 pd。NaT(“失败”结果),因为它不能将其理解为日期时间。
  2. 它将而不是尝试转换已经被解释为除 object 以外的任何类型的列,即任何特定类型,如 int64 或 float64,即使 pd.to_datetime 会很乐意(但很可能不希望)将类似 2000 的数字转换为日期 2000-01-01。

根据我目前的经验,dt_auto.read_csv 函数在典型的数据帧上运行并不需要很长时间。即使有许多非 datetime 对象(字符串)列,它几乎总是很快遇到每个此类列顶部附近的一个值,它无法将其解析为 datetime,因此放弃并继续处理下一列,而不尝试解析该列的其余值。

下面是 dt_auto.read_csv()产生的 dataframe 的外观,尽管您不一定能通过查看它来判断这两个适当的列是否确实是 datetime 数据类型。碰巧的是,CSV 文件在 Update_Timestamp 中的秒有不同的小数位数(三位、零位和九位),但是 datetime 数据类型本身显示了九位这样的数字。csv 文件中的 Birthdate 实际上只有日期(没有时间),但存储为完整的日期时间,小时、分钟和秒都是零(包括小数部分的零),但是列中的所有时间部分都是零导致 Pandas 只显示该列的日期(年-月-日)。

当然,pd.to_datetime 以及 dt_auto.read_csv 在默认情况下不能处理所有可能的日期和日期时间格式,但它可以处理许多常见的明确(通常是年、月、日)格式,例如 dataframe.to_csv 方法和许多其他工具编写的格式,包括许多 ISO 日期时间格式(通常用“T”而不是空格来分隔日期和时间)。我没有试验过包含时区信息的 datetimes,因为我通常不会看到这样的数据,但是请在回复评论中让我知道是否可以通过进一步修改代码来更好地处理这些数据。

你怎么想呢?你觉得这篇小文章有用吗?Pandas 本身是否应该添加(例如 pd.read_csv 函数本身?)为我们选择这样做的能力,这样你就不需要复制/导入我上面的 dt_auto.py 代码了?我很乐意在这里看到你的评论和问题作为回应。

用 Python 中的百里香 Boost 实现自动预测

原文:https://towardsdatascience.com/auto-forecasting-in-python-with-thymeboost-8bc9bd466998?source=collection_archive---------10-----------------------

比较百里香增强剂、Pmdarima 和 Prophet

图片由皮埃特罗·马蒂亚在 Unsplash 上拍摄

TLDR: 当我们将百里香与其他一些流行的时间序列方法进行比较时,我们发现它可以生成非常有竞争力的预测。 剧透警告: 百里助推胜。但除了胜利,我们看到了百里香框架的许多好处,即使在它失败的情况下。

更多例子你可以查看百里香增强 Github 。

系列第一帖:用百里香 Boost 进行时间序列预测。如果你还没有看过,那就去看看吧!

介绍

本次竞赛中使用的示例相当流行,但是用于数据争论的一些代码摘自本文(感谢 Tomonori Masui!).您应该看看这篇文章,看看其他一些模型在这些数据集上的表现如何。

第一个例子是一个相当著名的时间序列:航空乘客数据集。这些数据来源广泛,其中一个来源来自 Kaggle 或 Github 。确保你有最新的百里香增强包,可以通过 pip 安装:

pip install ThymeBoost --upgrade

既然是最新的,那就来看看吧!

航空乘客数据集

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from ThymeBoost import ThymeBoost as tb
import seaborn as sns
sns.set_style("darkgrid")#Airlines Data, if your csv is in a different filepath adjust this
df = pd.read_csv('AirPassengers.csv')
df.index = pd.to_datetime(df['Month'])
y = df['#Passengers']
plt.plot(y)
plt.show()

作者图片

这个时间序列挺有意思的!明显的趋势和倍增的季节性。绝对是任何预测方法的好基准。

为了判断预测方法,我们将把数据分割成标准的训练/测试分割,其中保留最后 30%的数据。测试程序的结果可能会因这种分裂而改变。为了保持不偏不倚,将使用上述文章中的训练/测试分割。

任何调整或模型选择都将在训练集上完成,而测试集将用于判断方法。目标(至少对我来说)是看看百里香增强疗法是否能与其他经过审查的方法竞争。如果您要在生产中实现一个预测模型,那么您可能想要使用一个更健壮的方法来判断模型,例如时间序列交叉验证。

test_len = int(len(y) * 0.3)
al_train, al_test = y.iloc[:-test_len], y.iloc[-test_len:]

首先,让我们尝试一个自动 Arima 实现: Pmdarima 。

import pmdarima as pm
# Fit a simple auto_arima model
arima = pm.auto_arima(al_train,
                      seasonal=True,
                      m=12,
                      trace=True,
                      error_action='warn',
                      n_fits=50)pmd_predictions = arima.predict(n_periods=len(al_test))
arima_mae = np.mean(np.abs(al_test - pmd_predictions))
arima_rmse = (np.mean((al_test - pmd_predictions)**2))**.5
arima_mape = np.sum(np.abs(pmd_predictions - al_test)) / (np.sum((np.abs(al_test))))

接下来,我们会给先知一个机会。

from fbprophet import Prophetprophet_train_df = al_train.reset_index()
prophet_train_df.columns = ['ds', 'y']prophet = Prophet(seasonality_mode='multiplicative')
prophet.fit(prophet_train_df)
future_df = prophet.make_future_dataframe(periods=len(al_test), freq='M')
prophet_forecast = prophet.predict(future_df)
prophet_predictions = prophet_forecast['yhat'].iloc[-len(al_test):]prophet_mae = np.mean(np.abs(al_test - prophet_predictions.values))
prophet_rmse = (np.mean((al_test - prophet_predictions.values)**2))**.5
prophet_mape = np.sum(np.abs(prophet_predictions.values - al_test)) / (np.sum((np.abs(al_test))))

最后,实现百里香增强。这里我们使用了一种新的方法:从最新版本的包中“自动调整”。考虑到可能的季节性,该方法将尝试几种简单的实现。这是一个实验性的特性,只适用于传统的时间序列。当前的一个问题是,它尝试了几个冗余的参数设置,这将在未来的版本中得到解决,以加快进程!此外,如果您打算传递外部因素,我们建议使用在自述文件中找到的优化方法。

boosted_model = tb.ThymeBoost(verbose=0)output = boosted_model.autofit(al_train,
                               seasonal_period=12)
predicted_output = boosted_model.predict(output, len(al_test))
tb_mae = np.mean(np.abs(al_test - predicted_output['predictions']))
tb_rmse = (np.mean((al_test - predicted_output['predictions'])**2))**.5
tb_mape = np.sum(np.abs(predicted_output['predictions'] - al_test)) / (np.sum((np.abs(al_test))))

通过在构建该类时设置 verbose=0,它将每个单独模型的日志记录静音。相反,将显示一个进度条,指示不同参数设置以及找到的“最佳”设置的进度。默认情况下,百里香的自动拟合方法将进行 3 轮拟合和预测。该过程遍历训练集的最后 6 个值,以选择“最佳”设置。对于该数据,找到的最佳设置是:

Optimal model configuration: {'trend_estimator': 'linear', 'fit_type': 'local', 'seasonal_period': [12, 0], 'seasonal_estimator': 'fourier', 'connectivity_constraint': True, 'global_cost': 'maicc', 'additive': False, 'seasonality_weights': array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
       1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
       1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
       1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
       1., 1., 1., 1., 1., 1., 1., 1., 1., 5., 5., 5., 5., 5., 5., 5., 5.,
       5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5., 5.]), 'exogenous': None}
Params ensembled: False

一些需要注意的重要事项:

  1. “加法”设置为 false,这意味着整个过程是“乘法”,即从输入序列中提取对数。正常的“倍增”季节性尚未实现。
  2. 有一个“季节性权重”数组,其中最后两个“季节性周期”被设置为 5,这意味着这些周期对季节性成分的影响是其他周期的 5 倍。
  3. “季节性周期”是[12,0],因此它在衡量季节性和不衡量季节性之间来回循环。这是一个有趣的行为,但它本质上给季节性因素增加了一些规律性。

说到组件,我们来看看:

boosted_model.plot_components(output, predicted_output)

作者图片

总而言之,ThymeBoost 决定采用输入序列的对数,拟合一个线性变点模型,并在季节性成分中添加一个“变点”。

这些决定是正确的吗?让我们来看看误差指标:

作者图片

这些误差指标不言自明,百里香增强优于其他方法全面。但是预测实际上是什么样的呢?

plt.plot(pmd_predictions, label='Pmdarima')
plt.plot(al_test.values, label='Actuals')
plt.plot(prophet_predictions.values, label='Prophet')
plt.plot(predicted_output['predictions'].values, label='ThymeBoost')
plt.legend()
plt.show()

作者图片

显然,所有的方法都获得了非常相似的信号。就季节形状而言,百里香似乎略胜一筹,这可能是因为它决定使用季节权重。

WPI 数据集

下一个数据集是从 1960 年到 1990 年的美国批发价格指数(WPI ),这个例子再次取自前面提到的文章。

不幸的是,这个数据集没有附带百里香增强,但我们可以通过 Statsmodels 访问它:

from  statsmodels.datasets import webusedta = webuse('wpi1')
ts_wpi = dta['wpi']
ts_wpi.index = pd.to_datetime(dta['t'])
test_len = int(len(ts_wpi) * 0.25)
ts_wpi = ts_wpi.astype(float)
wpi_train, wpi_test = ts_wpi.iloc[:-test_len], ts_wpi.iloc[-test_len:]
plt.plot(ts_wpi)
plt.show()

作者图片

这个时间序列与以前的有很大不同。它似乎缺乏任何季节性,因此这些设置将被禁用(尽管如果我们不小心将季节性设置添加到百里香增强中,它不会发生太大变化)。

让我们按照与之前相同的过程,首先安装 Pmdarima:

import pmdarima as pm
# Fit a simple auto_arima model
arima = pm.auto_arima(wpi_train,
                      seasonal=False,
                      trace=True,
                      error_action='warn',
                      n_fits=50)
pmd_predictions = arima.predict(n_periods=len(wpi_test))
arima_mae = np.mean(np.abs(wpi_test - pmd_predictions))
arima_rmse = (np.mean((wpi_test - pmd_predictions)**2))**.5
arima_mape = np.sum(np.abs(pmd_predictions - wpi_test)) / (np.sum((np.abs(wpi_test))))

接下来,先知:

from fbprophet import Prophetprophet_train_df = wpi_train.reset_index()
prophet_train_df.columns = ['ds', 'y']prophet = Prophet(yearly_seasonality=False)
prophet.fit(prophet_train_df)
future_df = prophet.make_future_dataframe(periods=len(wpi_test))
prophet_forecast = prophet.predict(future_df)
prophet_predictions = prophet_forecast['yhat'].iloc[-len(wpi_test):]prophet_mae = np.mean(np.abs(wpi_test - prophet_predictions.values))
prophet_rmse = (np.mean((wpi_test - prophet_predictions.values)**2))**.5
prophet_mape = np.sum(np.abs(prophet_predictions.values - wpi_test)) / (np.sum((np.abs(wpi_test))))

最后,百里香增强剂:

boosted_model = tb.ThymeBoost(verbose=0)output = boosted_model.autofit(wpi_train,
                               seasonal_period=0)predicted_output = boosted_model.predict(output, forecast_horizon=len(wpi_test))
tb_mae = np.mean(np.abs((wpi_test.values) - predicted_output['predictions']))
tb_rmse = (np.mean((wpi_test.values - predicted_output['predictions'].values)**2))**.5
tb_mape = np.sum(np.abs(predicted_output['predictions'].values - wpi_test.values)) / (np.sum((np.abs(wpi_test.values))))

最佳设置,也可以通过以下方式直接访问:

print(boosted_model.optimized_params)

它返回:

{'trend_estimator': 'linear', 'fit_type': 'local', 'seasonal_period': 0, 'seasonal_estimator': 'fourier', 'connectivity_constraint': False, 'global_cost': 'mse', 'additive': True, 'exogenous': None}

像上次一样,百里香选择了一个局部拟合的线性模型,也就是趋势分量的线性变点模型。除了这次‘connectivity _ constraint’被设置为 False,这放松了趋势线在变点的连接。

让我们来看看误差指标:

作者图片

百里香增强再次胜过其他两种方法。

预测是:

plt.plot(pmd_predictions, label='Pmdarima')
plt.plot(wpi_test.values, label='Actuals')
plt.plot(prophet_predictions.values, label='Prophet')
plt.plot(predicted_output['predictions'].values, label='ThymeBoost')
plt.legend()
plt.show()

作者图片

结论

这篇文章的目的是看看百里香是否能与其他流行的方法竞争,在这些例子中它显然可以。但是不要被骗以为百里香是万能药(虽然我也希望是!).它有很多次被超越,然而,一个主要的好处是任何超越百里香增强的方法都有可能被添加到框架中。一旦添加了一个方法,它就可以通过提升过程访问一些有趣的特性。

这方面的一个例子可以在已经引用的文章中找到。对于太阳黑子数据集,ThymeBoost 的 autofit 没有做任何 ARIMA 建模,因此与 sktime 发现的 ARIMA(8,0,1)相比,它的结果很差。然而,如果我们使用标准拟合方法,并通过局部拟合传递 ARIMA 订单(因此我们允许变点),我们会优于 sktime 的自动 ARIMA。

我将把它作为一个练习留给您来尝试,只需使用这些设置:

output = boosted_model.fit(sun_train.values,
                           trend_estimator='arima',
                           arima_order=(8, 0, 1),
                           global_cost='maicc',
                           seasonal_period=0,
                           fit_type='local'
                           )

如前所述,这个包仍处于早期开发阶段。大量可能的配置使得调试成为一个复杂的过程,所以使用时风险自担。但是,请在 GitHub 上讨论和公开你遇到的任何问题!

Python 中的自动 HMM

原文:https://towardsdatascience.com/auto-hmm-in-python-254bc937cbf6?source=collection_archive---------5-----------------------

隐马尔可夫模型的自动模型选择、训练和测试

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

在加州大学洛杉矶分校攻读博士期间,我开发了各种序列和时间序列数据模型。隐马尔可夫模型(HMM)是我最早使用的模型之一,效果相当好。我在 Python/MATLAB/R 中找不到任何关于 HMM 的教程或工作代码。我正在发布 Auto-HMM,这是一个 Python 包,使用 AIC/BIC 为监督和非监督 HMM 执行自动模型选择。

该软件包使用 hmmlearn 进行隐马尔可夫模型训练和解码,并且它包括用于最佳参数数量(混合成分数量、隐藏状态数量等)的模型选择。我用 MATLAB 和 r 实现了一个类似的包。

如果你想看同一个模型的 R 和 MATLAB 实现,请在这篇文章下评论。

HMM 中的训练是通过 Baum-Welch 完成的,这是 EM 算法的特例。解码是通过维特比算法完成的。我猜除了 ML(维特比)解码器之外,hmmlearn 包还支持 MAP 解码器。

模型选择是通过 AIC 和 BIC 完成的,它们通过惩罚似然函数来运行。这是通过指定您喜欢的隐藏状态的最大数量来自动完成的,并且该算法为离散 HMM 找到隐藏状态的最佳数量、最佳数量混合分量以及为连续 HMM 找到隐藏状态的最佳数量。

要访问代码,请访问我的 GitHub

https://github.com/manitadayon/Auto_HMM

请仔细阅读 DHMM 测试和嗯测试 Python 文件中的例子。它们要求您提供 CSV 文件地址、HMM 模型的迭代次数、训练规模、特征数量(时间序列的维度)。

例如,以下代码对 2000 个观察值执行离散 HMM,每个观察值有 50 个时间点,最多有 3 个隐藏状态。训练大小设置为 0.8 (0.8 * 2000 = 1600)。该功能决定了时间序列的维数(1 表示单变量时间序列)。该标志决定了您是希望按降序还是升序对隐藏状态进行排序。

from Hidden_Markov_Model import *
from Hidden_Markov_Model.DHMM import *
Train_ratio=0.8
Max_state=3
Iter=1000
Feat=1
N=2000
T=50
flag=0
N_symb=3
Path= 'Path to CSV file'
Data=pd.read_csv(Path)
Data=Data.astype(int)
First_DHMM=Supervised_DHMM(Train_ratio,Max_state,Iter,Feat,N,T,Data,N_symb)
First_DHMM.Best_States()

关于我最近的活动和任何问题的更多信息,请访问我的 YouTube 页面。我还编写了 tsBNgen,这是用于生成合成时间序列数据的 Python 包,可以用作 Auto-HMM 模型的输入。要了解更多关于 tsBNgen 的信息,请访问下面我的 YouTube 页面。

https://www.youtube.com/channel/UCjNDIlqrFdKUgSeN9wV-OzQ

如果您有任何问题或疑虑,可以访问我的个人页面

要了解有关 HMM 建模和实现的更多信息,请参考以下视频:

自动导入 Python 库

原文:https://towardsdatascience.com/auto-import-python-libraries-d095a11b4cca?source=collection_archive---------14-----------------------

使用 Pyforest 导入重要的 python 库

克里斯里德在 Unsplash 上的照片

在用 python 编码时,你是否也陷入了导入库的困境?我们中的大多数人都会在编码时忘记导入我们将使用的库,我们陷入了导入不同库的困境,这很令人沮丧,而且我必须说,作为一个懒惰的程序员,我想一劳永逸地解决这个导入问题。

PyForest 是一个开源的 python 库,对于像我这样懒惰的程序员来说真的很有帮助,因为它导入了 python 编程所需的所有主要库,包括机器学习和深度学习。

在本文中,我们将探索 PyForest,看看我们如何使用它。

让我们开始吧…

安装所需的库

我们将从使用 pip 安装 PyForest 开始。下面给出的命令可以做到这一点。

!pip install pyforest

导入所需的库

在这一步中,我们将只导入 PyForest,这是唯一需要的库。

from pyforest import *

探索 PyForest

神奇的事情开始了,让我们看看我们在一行代码中导入了多少 python 库。

lazy_imports()

来源:作者

你可以看到我们多么容易地导入了所有主要的 python 库,包括深度学习、机器学习、图像处理等库。如果你像我一样是一个懒惰的程序员,这些库真的很有帮助。

在本文中,我们看到了 PyForest 对于导入重要的库是多么有用。继续尝试在一行中导入库,并让我知道您在回复部分的评论。

本文是与皮尤什·英格尔合作完成的。

在你走之前

感谢 的阅读!如果你想与我取得联系,请随时通过 hmix13@gmail.com 联系我或我的 LinkedIn 个人资料 。可以查看我的Github简介针对不同的数据科学项目和包教程。还有,随意探索 我的简介 ,阅读我写过的与数据科学相关的不同文章。

Power BI 中的自动页面刷新—您需要知道的一切

原文:https://towardsdatascience.com/auto-page-refresh-in-power-bi-everything-you-need-to-know-a6e7bd9d0444?source=collection_archive---------26-----------------------

您知道 Power BI 可以自动刷新您的报告页面吗?您知道有两种不同类型的自动刷新吗?

由 Sigmund 在 Unsplash 上拍摄的图像

自动化任务——这是我们都喜欢的东西!而 Power BI 在这方面做得很出色。尽管其中一些自动化的东西可能会回来困扰你,比如自动日期/时间选项,幸运的是还有更多让我们的生活变得更容易。

我最近研究了自动页面刷新特性,在这篇文章中,我想更多地介绍这个功能——特别是关于特定用例的最佳实践和限制。

什么是自动页面刷新?

简而言之,顾名思义,自动页面刷新功能可以让您设置报告中特定页面的计划刷新!因此,不要将此功能与报告计划刷新混淆,因为自动页面刷新是一个完全不同的故事。第一个至关重要的区别是,自动页面功能仅适用于 DirectQuery 存储模式(以及某种程度上的实时连接)。 不支持导入模式 ,切记!

作者图片

下一个重要的考虑是使用哪种类型的自动页面刷新…哦,是的,有两种不同的类型,所以让我们更深入地研究它们。

固定间隔

这是安排页面自动刷新的基本方式。您可以设置所需的时间间隔(范围从 1 秒到 X 天),当时间间隔到达时,所有的视觉效果都将被刷新。这意味着,每个单独的可视化将生成一个单独的(直接的)查询,并将其发送到底层数据源。但是,在文章的后面会有更多的介绍。

变化检测

本质上,它在某种程度上类似于固定间隔类型。您将再次设置间隔,但这一次,不同的事情在后台发生。与固定时间间隔相比,关键的区别在于,您必须指定一个将要被监控的度量(就像检查底层表中是否有新记录一样),在定义的固定时间间隔之后,Power BI 将生成一个单独的查询来检查指定的度量是否发生了变化,如果发生了变化,它将执行剩余的查询来刷新所有的视图…如果没有发生变化,报表页面不会发生任何变化!

现在,让我们来看看在使用这些类型的每一种时会发生什么。

在 Power BI Desktop 中配置自动页面刷新

进入 Power BI Desktop 并使用 DirectQuery 存储模式后,我可以配置页面刷新属性:

作者图片

我使用的是 Contoso 数据库,为了简单起见,我只连接到 DimCustomer 表。如您所见,我在报告页面上放置了三个视觉效果,并设置了自动页面刷新类型(固定间隔),刷新间隔为 2 秒。

有了这个设置,Power BI Desktop 应该每两秒钟触发三个独立的查询(每个可视化一个)!让我们打开 SQL Server Profiler,并检查后台的运行情况:

作者图片

正如预期的那样,对 DimCustomer 表运行了三个查询,并且每两秒钟重复一次。

让我们切换到 Power BI Desktop 中的性能分析器,并检查该设置背后的具体指标:

作者图片

我已经按照行动顺序对结果进行了分类,以便能够区分不同的行动。而且,您可能会看到我们的表格可视化每次都需要 2 秒多的时间来呈现(为了清楚起见,Performance analyzer 中的值是以毫秒为单位的)!这给我们带来了一个重要的启示:

如果您注意到渲染视觉所需的时间比您在自动页面刷新设置中指定的时间长,您应该增加刷新间隔的值! 老实说,如果视觉需要比这更多的时间在报表中渲染,那么每两秒刷新一次数据又有什么意义呢?!

Power BI 桌面中的变化检测

现在让我们设置变更检测类型。它比固定时间间隔稍微复杂一些,因为您需要应用一些额外的配置步骤。

我创建了一个非常基本的方法来计算客户总数:

Total Customers = COUNT(DimCustomer[CustomerKey])

作者图片

本质上,一旦我们以这种方式设置了自动刷新,接下来将会发生的是,每隔 2 秒,Power BI 将触发一个查询来检查总客户度量的值。如果 measure 的值改变了,视觉效果将会刷新,否则什么也不会发生!让我们确认我们的假设:

作者图片

正如我们所想的那样:每 2 秒钟,在数据源端执行一次查询来检查总客户度量的值,由于没有检测到任何变化,所以没有刷新报告页面。现在,让我们通过在 DimCustomer 表中插入一个新行来更改度量值:

USE [Contoso]
GO

INSERT INTO [dbo].[DimCustomer]
           ([FirstName]
           ,[LastName]
           ,[Gender]
           ,[GeographyKey]
       ,[CustomerLabel]
           )
     VALUES
           ('Power'
           ,'BI'
       ,'?'
           ,1
           ,112233
           )
GO

这是用于在表中填充新行的 T-SQL 代码。现在,我将检查一旦底层数据发生更改,更改检测将如何表现:

作者插图

是啊!仔细看看上面的动画:查询检查了又检查,什么也没发生。然后,我在 DimCustomer 表中插入一行,变更检测捕捉到了这一修改,然后执行所有三个查询来填充我们的视觉效果。之后,再次执行一个查询来检查度量中是否有新的变化。

本测试的一个要点: 如果您预计源数据的变化频率低于您在变化检测中指定的值,您应该增加变化检测的间隔。

电源 BI 服务中的配置

现在,我将在 Power BI 服务中将此报告发布到我的工作区。

作者图片

等等,什么?!这是行不通的!正如你在最上面的消息中看到的, 改变检测类型 ,与固定间隔不同,它将在所有容量下工作, 需要高级许可

总则

根据上面执行的测试得出的结论,下面列出了在使用自动页面刷新功能时应该记住的一般规则:

  • 如果您希望基础表中的数据每 5 分钟更改一次,请不要将自动页面刷新间隔设置为低于 5 分钟
  • 当您将刷新间隔设置为较低的值时,例如我们示例中的 2 秒,请考虑您的查询将会产生的工作负载,尤其是使用固定间隔类型时。举例来说,如果有 20 个并发用户运行这个报告,并且我们在报告页面上有 3 个视觉效果,那么每 2 秒钟就有 20×3 = 60 个查询!现在,想象一下如果页面上有 10 个以上的视觉效果会有什么影响…
  • 只有在 DirectQuery 存储模式或包含至少一个 DirectQuery 数据源的混合模式下,才支持自动页面刷新。在实时连接模式下,您也可以使用固定时间间隔,但有一些限制
  • 变更检测类型需要高级容量
  • 对于每个数据集,只能对一个度量设置更改检测类型
  • 在 Power BI 租户中,最多可以使用 10 个具有更改检测类型的数据模型

现在,如果您想知道如果您的自动页面刷新工作负载干扰常规工作负载会发生什么——根据微软的官方文档,自动页面刷新查询具有较低的优先级。

另一个合理的问题是:如果执行该查询需要 5 秒,并且我已经将刷新间隔设置为 2 秒,那么会发生什么情况?在前一个周期完成之前,Power BI 不会运行下一个周期。简单地说,Power BI 将等待 5 秒钟来完成查询,然后执行下一次运行。

最后,我很想知道自动页面刷新查询是否可以利用来自缓存的结果。答案是否定的,因为这些查询不是由缓存提供的。

结论

当您需要实时监控一些关键事件并根据 Power BI 报告提供的快速洞察力做出决策时,自动页面刷新是一项非常强大的功能。但是,在什么时候使用这个特性以及使用到什么程度都要非常小心。

感谢阅读!

成为会员,阅读 Medium 上的每一个故事!

自动解析任何文档

原文:https://towardsdatascience.com/auto-parse-and-understand-any-document-5d72e81b0be9?source=collection_archive---------17-----------------------

用于文档布局解析的基于 Train Detectron2 的定制模型

图片由 GitHub 上的布局解析器解析

自从人类首次开发出书面文字以来,文档就无处不在。杂志、协议、历史档案、当地商店的小册子、税单、房契、大学申请表等等。到目前为止,处理这些文档一直是一项相当手工的任务,自动化只是在最近几十年才开始接管。这一自动化之旅在很大程度上受到了一个致命缺陷的阻碍——计算机无法像人类那样直观地理解布局。

随着现代计算机视觉的出现,这一切都改变了。我们现在有了模型,它可以准确地定位、表示和理解文档布局的组件。但是对于一般的自动化爱好者来说,这些模型相当抽象,通常需要全面的 Python 知识才能理解文档,更不用说在项目中使用它了。

学分:布局解析器

在这种程度上,布局解析器,正如在他们非常酷的论文中所解释的,通过一个干净的 API 减轻了这种复杂性,该 API 允许并实现完整的端到端布局检测、解析和理解,只需要几行代码(我的意思是非常少,比如 5 行)。他们有一堆可以直接开箱使用的型号。总之是一个超级酷的工具。

现在,除了预训练模型的功能之外,如何使用该工具来理解和处理定制布局?

作者图片

显而易见的想法是在您的定制布局上微调现有的布局模型。

你是对的,这是最好的办法,特别是考虑到我们并不是所有人都有从头开始训练这种模型所需的硬件火力。

虽然微调过程比仅仅使用预先训练的模型在技术上更复杂一些,但是由布局解析器的作者创建的一个方便的库,通过大量处理训练/微调活动中不合理的部分,有助于缓解这些问题。

Gareth Fowler 在 Tumblr上发布的 GIF

在接下来的章节中,我们将通过一个全面的教程来使用 这个库 来训练你自己的定制模型。

先决条件

图片由纳万舒·阿加瓦尔

  1. Python ≥ 3.6
  2. 探测器 2 从主分支分叉或克隆而来。*
  3. 最新版本的布局解析器及其依赖项。
  4. Pytorch (Linux: 1.6+或 Windows: 1.6)**
  5. CUDA 工具包:10+(与 Pytorch 兼容)***
  6. 数据集:以 COCO 格式标注。

警告

  • Detectron2 不容易安装在 Windows 系统上,请参考 ivanapp 的这篇精彩帖子以获得基于 Windows 的安装过程的指导。

  • *尽管官方文档中推荐使用 1.8,但 Windows 用户应该坚持使用 1.6。

***CUDA 不是强制性的,理论上也可以在 CPU 上训练。尽管如此,这样的训练尝试将会非常缓慢。

步骤 1:基本设置

  • 将布局模型训练库克隆或分支到您的系统中。
  • 打开命令/anaconda 提示符并激活环境,其中安装了布局解析器和检测器 2 。
  • 将工作目录更改为保存布局-模型-训练报告的位置。

步骤 2:拆分数据集(可选)

  • 打包在布局-模型-训练 repo 中的是一个内置脚本(utils\cocosplit.py),用于将数据集分割成测试和训练子集。
  • 该脚本确保在数据集中不存在标记区域的图像的情况下,训练和测试子集中标记图像与未标记图像的比率将是相等的。
  • 使用以下命令分割数据集(假设工作目录与上一步中的指示一致)。

请注意,以上命令是在基于 Windows 10 的系统上执行的,请根据操作系统更改路径分隔符。

论据解释

  • annotation_path :合并数据集所在的路径。
  • 训练测试:训练/测试数据集应该保存的路径。
  • 分割比:分配给训练的合并数据集的分数。

步骤 3:下载预训练模型

  • 从布局解析器的 模型动物园 下载一个预先训练好的模型及其相关配置文件。
  • 下载包含两个文件:
  1. model_final.pth :这是预训练模型的权重。
  2. config.yaml :这是预训练模型的配置。有关配置文件的信息,请参考 检测器 2 文档

步骤 4:训练模型

既然数据集已被分割,预训练的模型权重也已下载,让我们进入有趣的部分: 模型训练 (或者更确切地说是微调)。

  • 使用tools\train_net.py处的训练脚本完成训练
  • 使用下面的命令来训练模型。

请注意,以上命令是在基于 Windows 10 的系统上执行的,请根据操作系统更改路径分隔符。

论据解释

  • dataset_name :自定义数据集的名称(可以随意命名)。
  • json_annotation_train :训练标注的路径。
  • json_annotation_val :测试注释的路径。
  • 图像 _ 路径 _ 训练:训练图像的路径。
  • image_path_val :测试图像的路径。
  • config-file :步骤 3 下载的模型配置文件的路径。

注意,其余的参数-值对实际上是配置修改,并且特定于用例(有时)。为了清楚地了解如何使用和设置它们,请参考 检测器 2 文档

  • 微调后的模型及其配置文件、训练指标和日志将保存在输出路径中,如上面命令中的OUTPUT_DIR所示。

第五步:推理

有了 finetuned 模型,使用它来解析文档就成了一项简单的任务。

  • 在布局解析器的演示中,用以下代码替换模型初始化。

请注意,以上路径基于基于 Windows 10 的系统,请根据操作系统更改路径分隔符。

  • custom_label_mapint_label -> text_label的映射。这种映射是根据训练数据的 COCO Json 中存在的'categories'字段以如下方式进行的:每个category对应{'id': 'name'}。例如:

custom_label_map = {0: "layout_class_1", 1: "layout_class_2"}

结论

总而言之,可以使用布局-模型-训练 repo 轻松训练任何数据集上的定制模型。这种模型可以用于解析和理解各种各样的文档,并且在训练后相对容易。

参考

[1] Y. Wu,a . a .,F. Massa,W. Y. Lo 和 R. Girshick, Detectron2 :提供最先进的检测和分割算法的人工智能研究的下一代库(2019), GitHub Repo

[2]沈,张,戴尔,李,卡尔森和李,【LayoutParser:一个基于深度学习的文档图像分析的统一工具包】(T5)(2021),arXiv 预印本 arXiv:2103.15348

[3] T. S. Lin,M. Maire,S. Belongie,L. Bourdev,R. Girshick,J. Hays,p .佩罗娜,D. Ramanan,C. L. Zitnick 和 P. Dollár,微软 COCO:上下文中的共同对象 (2015),arXiv 预印本 arXiv:1405.0312v3

自动 Sklearn:sci kit-学习类固醇

原文:https://towardsdatascience.com/auto-sklearn-scikit-learn-on-steroids-42abd4680e94?source=collection_archive---------11-----------------------

自动化“无聊”的东西。加速您的模型开发生命周期。

亚历山大·雷德尔在 Unsplash 上拍摄的照片

动机

典型的机器学习工作流是数据处理、特征处理、模型训练和评估的迭代循环。想象一下,在我们获得令人满意的模型性能之前,必须试验数据处理方法、模型算法和超参数的不同组合。这项费力费时的任务通常在超参数优化过程中执行。

模型开发生命周期。图片作者。

超参数优化

超参数优化的目标是找到最佳模型管线组件及其相关的超参数。让我们假设一个简单的模型管道,它有两个模型管道组件:一个估算步骤,后面跟着一个随机森林分类器。

作者图片

插补步骤有一个名为“策略”的超参数,用于确定如何进行插补,例如使用均值、中值或众数。随机森林分类器有一个称为“深度”的超参数,它确定森林中单个决策树的最大深度。我们的目标是找到跨模型管道组件的超参数的哪个组合提供最佳结果。进行超参数调整的两种常见方法是使用网格搜索或随机搜索。

网格搜索

对于每个超参数,我们列出一个可能值的列表,并尝试所有可能的值组合。在我们的简单例子中,我们有 3 种估算策略和 3 种不同的随机森林分类器深度可以尝试,因此总共有 9 种不同的组合。

网格搜索。图片作者。

随机搜索

在随机搜索中,我们定义每个超参数的范围和选择,并且在这些边界内随机选择超参数集。在我们的简单示例中,深度的范围在 2 到 6 之间,估算策略的选择有均值、中值或众数。

随机搜索。图片作者。

请注意,网格和随机搜索中的超参数集是彼此独立选择的。这两种方法都不使用先前训练和评估试验的结果来改进下一次试验的结果。进行超参数优化的一个更有效的方法是利用先前试验的结果来改进下一次试验的超参数选择。这种方法被用于贝叶斯优化。

贝叶斯优化

贝叶斯优化存储先前搜索的超参数和预定义目标函数的结果(例如,二进制交叉熵损失),并使用它来创建代理模型。代理模型的目的是在给定一组特定的候选超参数的情况下,快速估计实际模型的性能。这允许我们决定是否应该使用候选超参数集来训练实际模型。随着试验次数的增加,用附加试验结果更新的替代模型得到改进,并开始推荐更好的候选超参数。

贝叶斯优化存在冷启动问题,因为它需要试验数据来建立替代模型,然后才能为下一次试验推荐好的候选超参数。代理模型在开始时没有要学习的历史试验,因此候选超参数是随机选择的,这导致在寻找性能良好的超参数时启动缓慢。

为了克服冷启动问题,Auto-Sklearn,一个开源的 AutoML 库,通过一个称为元学习的过程,将热启动合并到贝叶斯优化中,以获得比随机更好的超参数的实例化。

自动 Sklearn

自动机器学习(AutoML)是机器学习管道中自动化任务的过程,例如数据预处理、特征预处理、超参数优化、模型选择和评估。Auto-Sklearn 使用流行的 Scikit-Learn 机器学习框架自动执行上述任务。下图简单展示了 Auto-Sklearn 的工作原理。

自动 Sklearn。图片来自[1]。

Auto-Sklearn 使用带有热启动(元学习)的贝叶斯优化来寻找最佳模型管道,并在最后从各个模型管道构建集成。让我们检查一下 Auto-Sklearn 框架中的不同组件。

元学习

元学习的目的是为贝叶斯优化找到好的超参数实例,以便它在开始时比随机的表现更好。元学习背后的直觉很简单:具有相似元特征的数据集在同一组超参数上表现相似。Auto-Sklearn 作者定义的元特征是*“可以有效计算的数据集特征,有助于确定对新数据集使用哪种算法”。*

在离线训练期间,对来自 OpenML 的 140 个参考数据集,共列出了 38 个元特征,如偏度、峰度、特征数、类别数等。使用贝叶斯优化过程训练每个参考数据集,并对结果进行评估。为每个参考数据集给出最佳结果的超参数被存储,并且这些超参数充当具有相似元特征的新数据集的贝叶斯优化器的实例。

在新数据集的模型训练期间,新数据集的元特征被制成表格,并且根据元特征空间中到新数据集的 L1 距离对参考数据集进行排序。来自前 25 个最接近的参考数据集的存储的超参数被用于实例化贝叶斯优化器。

作者在参考数据集上实验了 Auto-Sklearn 的不同变体,并使用不同训练持续时间的平均排名对它们进行了比较。等级越低表示性能越好。由于贝叶斯优化器的良好初始化,元学习的变体(蓝色和绿色)在开始时显示排名急剧下降。

图 1:不同 Auto-Sklearn 变体的比较。图片来自[1]。

数据预处理程序

Auto-Sklearn 按以下顺序预处理数据[2]。

  1. 分类特征的一种热编码
  2. 使用平均数、中位数或众数的插补
  3. 重新缩放要素
  4. 使用类权重平衡数据集

特色预处理器

在数据预处理之后,可以选择使用一个或多个以下类别的特征预处理程序对特征进行预处理[2]。

  1. 使用 PCA、截断 SCV、核 PCA 或 ICA 的矩阵分解
  2. 单变量特征选择
  3. 基于分类的特征选择
  4. 特征聚类
  5. 核近似
  6. 多项式特征扩展
  7. 特征嵌入
  8. 稀疏表示和变换

全体

在训练过程中,Auto-Sklearn 训练多个单独的模型,这些模型可用于构建集合模型。集成模型组合多个训练模型的加权输出,以提供最终预测。众所周知,它们不容易过度拟合,并且通常优于单个模型。

从图 1 中,作者显示了使用集成的变体比没有集成的变体性能更好(黑色对红色和绿色对蓝色)。具有元学习和集成的变体(绿色)表现最好。

密码

让我们来看看 Auto-Sklearn 的一些实际例子。

安装包

pip install auto-sklearn==0.13

进口包装

import pandas as pd
import sklearn.metrics
from sklearn.model_selection import train_test_split, StratifiedKFoldfrom autosklearn.classification import AutoSklearnClassifierfrom autosklearn.metrics import (accuracy,
                                 f1,
                                 roc_auc,
                                 precision,
                                 average_precision,
                                 recall,
                                 log_loss)

加载数据集

我们将使用来自 UCI 的数据集,该数据集描述了一家银行向客户提供定期存款的营销活动。如果客户同意,目标变量为是;如果客户决定不定期存款,目标变量为否。你可以在这里找到原始数据集。

我们将数据集作为熊猫数据帧来读取。

df = pd.read_csv('bank-additional-full.csv', sep = ';')

准备数据

Auto-Sklearn 要求我们在 pandas 数据帧中识别一个列是否是数字分类的,或者我们可以稍后在fit函数中完成。让我们现在转换它。

num_cols = ['ge', 'duration', 'campaign', 'pdays', 'previous', 'emp.var.rate', 'cons.price.idx', 'cons.conf.idx', 'euribor3m', 'nr.employed']
cat_cols = ['job', 'marital', 'education', 'default', 'housing', 'loan', 'contact', 'month', 'day_of_week', 'poutcome']df[num_cols] = df[num_cols].apply(pd.to_numeric)
df[cat_cols] = df[cat_cols].apply(pd.Categorical)y = df.pop('y')
X = df.copy()X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state=1, stratify=y)

实例化分类器

skf = StratifiedKFold(n_splits=5)

clf = AutoSklearnClassifier(time_left_for_this_task=600,
                            max_models_on_disc=5,
                            memory_limit = 10240,
                            resampling_strategy=skf,
                            ensemble_size = 3,
                            metric = average_precision,
                            scoring_functions=[roc_auc, average_precision, accuracy, f1, precision, recall, log_loss])

以下是AutoSklearnClassifier中使用的一些参数。

time_left_for_this_task:限制总训练时间(秒)

max_models_on_disc:限制保留的型号数量

memory_limit:我们想要使用的内存量(MB)

resampling_strategy:维持或不同种类的交叉验证。请参考本文档。

ensemble_size:服装系列中包含的模特数量。Auto-Sklearn 提供了一个选项,通过以加权方式取最大的ensemble_size个模型,在创建单个模型后创建集合。

metric:我们想要优化的指标

scoring_function:我们想要评估模型的一个或多个指标

安装分类器

clf.fit(X = X_train, y = y_train)

在引擎盖下,Auto-Sklearn 在每次试验期间都构建了一个 Scikit-Learn 管道。Scikit-Learn 管道用于组装一系列执行数据处理、特征处理和估计器(分类器或回归器)的步骤。fit函数触发整个 Auto-Sklearn 构建、拟合和评估多个 Scikit-Learn 流水线,直到满足停止标准time_left_for_this_task

结果

我们可以查看结果和选择的超参数。

df_cv_results = pd.DataFrame(clf.cv_results_).sort_values(by = 'mean_test_score', ascending = False)
df_cv_results

交叉验证结果和参数。图片作者。

我们还可以在排行榜上查看所有试验之间的比较

clf.leaderboard(detailed = True, ensemble_only=False)

排行榜。图片作者。

我们可以使用以下命令查看哪些管道被选择用于集合

clf.get_models_with_weights()

该方法返回元组列表[(weight_1, model_1), …, (weight_n, model_n)]weight表示它给每个模型的输出多少权重。所有weight值的总和将为 1。

我们还可以查看其他培训统计数据。

clf.sprint_statistics()

用所有训练数据改装

在 k-fold 交叉验证期间,Auto-Sklearn 在数据集上拟合每个模型管道 k 次,仅用于评估,它不保留任何已训练的模型。因此,我们需要调用refit方法,用所有的训练数据来拟合交叉验证期间找到的模型管道。

clf.refit(X = X_train, y = y_train)

保存模型

dump(clf, 'model.joblib')

负荷模型和预测

让我们加载保存的模型管道进行推理。

clf = load('model.joblib')
y_probas = clf.predict_proba(X_test)
pos_label = 'yes'
y_proba = y_probas[:, clf.classes_.tolist().index(pos_label)]

结论

搜索最佳模型管线组件和超参数是一项重要的任务。幸运的是,有 AutoML 解决方案,如 Auto-Sklearn,可以帮助自动化这个过程。在本文中,我们研究了 Auto-Sklearn 如何使用元学习和贝叶斯优化来找到最佳模型管道并构建模型集成。Auto-Sklearn 是众多 AutoML 软件包中的一个。查看其他备选方案,如 H2O 汽车。

你可以在这里找到本文中使用的演示代码。

参考

[1] 高效而健壮的自动化机器学习

[2] 高效稳健的自动化机器学习补充材料

[3] Auto-Sklearn API 文档

汽车 911:让我们用人工智能自动化 2.4 亿次 911 查询

原文:https://towardsdatascience.com/auto911-lets-automate-240-million-911-queries-using-ai-b4e92010a68e?source=collection_archive---------18-----------------------

革新传统 911 紧急响应的一步

由法斯汗在 Unsplash 拍摄的照片

平均每年,仅在美国就有大约 2.4 亿个 911 呼叫,全国平均每天超过 60 万个呼叫;由于新冠肺炎,911 紧急响应呼叫中心人手不足,导致紧急情况下等待时间更长。【1】现在,想象一下,如果我们利用人工智能的力量自动化呼叫响应,并允许人们对他们的问题做出自由、直接和即时的响应,会怎么样?

这就是 Auto911 闪耀的地方🌟

📑目录

1\. [🚑 What is Auto911?](#c3ae)2\. [😍 How does it look?](#cf5e)3\. [❓ How does it Work?](#43ca) 3.1 [🎰 Exploring GPT-J API](#92fb) 3.2 [📃 Making requirements.txt](#65d7) 3.3 [🐍 Creating streamlit_app.py](#aed4) 3.4 [🍎 Check the output!](#e3d5)4\. [💡 Other Use Cases](#d0df)5\. [👊 Limitations and Considerations](#5328)6\. [🎆 Conclusion](#1a88)7\. [✏️ About Author](#be77)8\. [✅ References](#826f)

现在,在投入工作之前,我们先简单了解一下这个项目和这个 app 的用途。

🚑什么是 Auto911?

Auto911 是一个 AI for Good solution,旨在通过使用尖端开源 GPT-J 这一 60 亿参数的人工智能模型和 Streamlit Sharing 这一部署、管理和共享应用程序的平台来自动化 911 紧急响应,从而通过提供直接、免费和即时的支持来帮助处于紧急情况下的人们。

😍看起来怎么样?

厉害!既然现在您已经熟悉了什么是 Auto911 及其目标,我相信这也是一个了解应用程序的好时机。这是应用程序的链接:

https://share.streamlit.io/alihussainia/auto_911/main

作者截图

❓:它是如何工作的?

🎰探索 GPT-J API

如上所述,它使用了两个东西:1.GPT J 模型和 2。简化共享。所以让我们从 GPT-J 模型开始。承蒙维克多·加莱戈的好意,我使用了 GPT J 的免费公共 API。现在,如果您想自己探索这个 API,请随意访问GPT-j-APIGithub repository【2】或者如果您喜欢简单的方法,下面是在您自己的项目中使用它的 Pythonic 方法:

作者代码示例

让我们一个变量一个变量地分解它😅

  1. 上下文:描述对话的字符串
  2. payload :以模型参数为关键字,自变量为值的字典
    + context : Context 变量将作为值
    + token_max_length :输出响应的最大长度
    +Temperature:Temperature 控制模型的随机性
    +Top _ p:Top probability 是控制模型随机性的另一种方法
  3. 响应:模型生成输出文本

有关每个参数的更多信息,请查看 GPT-J API 文档【3】。

📃制作要求. txt

从上面这段代码中,你可以看到该应用程序需要请求 python 包,因为我们即将在 Streamlit 上部署该应用程序,我们也将需要它。

在云实例上运行我们的应用程序之前,让 Streamlit Sharing 知道我们想要安装哪些库的一个简单方法是创建一个 requirements.txt 文件。所以,下面是如何做到这一点:

  1. 创建一个简单的文本文件,并将其命名为 requirements.txt
  2. 将下面提到的两个库名复制并粘贴到 requirements.txt 文件中

作者代码示例

现在就到此为止,让我们进入下一个任务!

🐍正在创建 streamlit_app.py

现在这是你的应用程序布局和逻辑将驻留在。Streamlit Sharing 将使用这个 python 脚本来创建您在上面看到的漂亮的应用程序布局。好的,所以我当然不想让你因为阅读这篇文章而感到遗憾,所以让我们避免像如何放置按钮或制作标题这样的微小的前端细节😅为此,您可以阅读我的 streamlit101 文章

https://medium.com/omdena/streamlit101-deploying-an-automl-model-using-streamlit-e86c6508b5c2

好了,开始说主要的吧!

下面是我创建 streamlit_app.py 文件的步骤:

  1. 创建一个名为 streamlit_app having 的文件。py 扩展。
  2. 像这样在文件中导入 streamlit 库:

作者代码示例

3.在文件中定义一些上下文、有效负载和响应请求,如下所示:

由 Víctor Gallego 编写的代码示例

5.使用以下内容打印出上述回复:

作者代码示例

🍎检查输出!

太棒了!现在,让我们自己尝试一下这个应用程序,看看输出结果。所以,我在输入提示中输入了一条随机的 911 紧急短信,然后按下*帮助!*按钮。以下是输出结果:

作者截图

可以说,结果对我来说非常直观!😎

💡其他使用案例

由于 GPT-J 是一种语言模型,它的应用仅限于我们的想象。它可以用于从给定的要点生成文本,如电子邮件,或从一些角色对话中生成电影脚本,或根据一些标签对情感进行分类,等等。我个人对使用 GPT-J 感兴趣的是创建一个基于开源人工智能的代码完成引擎,就像 Github 的 Copilot 或 OpenAI 的 Codex 的替代品一样。就像我说的,唯一的限制是你的想象力,尽情发挥吧!

但是就像人类和所有与他们相关的事物一样,它也有自己的局限性,所以为什么不在下一个标题中讨论它们呢😅

👊限制和注意事项

GPT J 的第一个问题是,除了 Eleuther 之外,它没有其他组织的支持,这在资源方面特别是计算、数据和专业人力资源方面严重限制了它。由于没有重要的财政支持,它在 60 亿个参数上进行训练,比 GPT-3 少得多,但看看其他可用的选项。

公开可用的 GPT-2 在 15 亿个参数上进行训练,这大大少于 GPT-J 的 60 亿个参数。此外,拥有 60 亿个参数有助于它的性能与 GPT-3 相当,后者是在 67 亿个参数上训练的。因此,由于这些因素,它可以被认为是迄今为止最准确的公开可用模型。

GPT J 也是像 GPT 3 一样基于大型变压器的模型,这就是为什么它没有长期记忆。因此,它不像人那样从长期的互动中学习。

GPT J 也不例外,所有的模型都是由用来训练它们的数据决定的。本文举例说明,反穆斯林偏见存在于 GPT-3 和其他大的语言模型中。[ 4

在这方面,伊柳瑟在 GPT J 号中做得很好,试图消除 GPT 3 号中存在的偏见。Eleuther 的数据集比 GPT-3 更加多样化,它避免了一些像 Reddit 这样的网站,这些网站更有可能包含有问题的内容。[ 5

最后,关于我们是否应该或可以依靠让人工智能完全处理紧急反应是一个进一步研究和广泛测试的问题。但就目前而言,我可以说,人工智能像其他任何工具一样,可以帮助人类处理紧急响应等情况,提供应该做什么的即时指导,但同样,这是基于人类的判断力,以验证和确认响应对他们来说是否足够,或者他们应该进一步寻求人类的支持。汽车 911 是漫长旅程的第一步,但我希望最终结果会值得努力😇

🎆结论

恭喜你!您刚刚不仅了解了 Auto911,还了解了 GPT-J 和 Streamlit 共享,以及如何使用它们来创建和部署一个使用最复杂和公开可用的 transformer 模型之一的全功能 AI 应用程序。我希望这篇文章能给你必要的知识来理解、创建和部署你自己的基于 GPT-J 模型的应用程序。

如果你想更多地了解 911,这里有一个很好的简短总结。

我还建议查看 GPT-J 的文档,以了解更多关于 GPT-J 的其他应用

您可以在 Victor 的官方 GPT-J-API github 存储库中随意查看样本 streamlit_app 示例

✏️关于作者

穆罕默德·阿里是欧洲最大的创业中心数字产品学校的人工智能工程师。他喜欢学习、教授和撰写关于数据科学和机器学习现实世界的应用和项目。他的主要爱好是玩很酷的开源工具,并用它们来解决现实世界的问题。也可以在 LinkedIn 上和他联系。

通过 Medium 关注他,了解他最新的最先进和最前沿的技术文章,就像你上面读到的那篇。

✅参考

[1]Jiovanni lie ggi911 呼叫中心人手不足导致紧急情况下等待时间延长 (2021),福克斯新闻频道警察和执法科

[2]维克多·加莱戈 gpt-j-api (2021),Github

[3]维克多·加莱戈 gpt-j-api 文件 (2021),Github

[4] Abubakar Abid,Maheen Farooqi,James Zou 大型语言模型中持续的反穆斯林偏见 (2021),Arxiv

[5]赫里蒂克·罗伊 GPT-J: GPT-3 民主化 (2021),P3r

[6] Elana Pearl Ben-Joseph 如何使用 911 (2018),KidsHealth,Nemours 基金会

用于图像去噪的自动编码器

原文:https://towardsdatascience.com/autoencoder-for-denoising-images-7d63a0831bfd?source=collection_archive---------4-----------------------

包含动手 Python 代码的实施指南

图片由 Cara Shelton 在 Unsplash 上拍摄

在这篇文章中,你将了解到自动编码器是如何工作的,以及为什么它们被用于医学图像去噪。

正确理解图像信息在医学等领域至关重要。去噪可以专注于清理旧的扫描图像,或者有助于癌症生物学中的特征选择工作。噪音的存在可能会干扰疾病的识别和分析,从而导致不必要的死亡。因此,医学图像去噪是一项必不可少的预处理技术。

所谓的自动编码器技术已经被证明对图像去噪非常有用。

自动编码器由一对两个相连的人工神经网络组成:一个编码器模型和一个解码器模型。自动编码器的目标是找到一种将输入图像编码成压缩形式(也称为潜在空间)的方法,使得解码图像版本尽可能接近输入图像。

自动编码器如何工作

网络提供原始图像 x ,以及它们的嘈杂版本 x~ 。网络试图重建其输出*x’*以尽可能接近原始图像 x 。通过这样做,它学会了如何去噪图像。

来源

如图所示,编码器模型将输入转换为小型密集表示。解码器模型可以被视为能够生成特定特征的生成模型。

编码器和解码器网络通常作为一个整体来训练。损失函数惩罚网络产生不同于原始输入 x 的输出x’

通过这样做,编码器学会在潜在空间的限制中保留尽可能多的相关信息,并巧妙地丢弃不相关的部分,例如噪声。解码器学习获取压缩的潜在信息,并将其重构为完全无错误的输入。

如何实现自动编码器

让我们实现一个自动编码器来消除手写数字的噪声。输入是 28x28 灰度图像,构建 784 元素向量。

编码器网络是具有 64 个神经元的单一密集层。因此,潜在空间将具有尺寸 64。整流单元(ReLu)激活函数被附加到该层中的每个神经元,并且基于每个神经元的输入是否与自动编码器的预测相关来确定它是否应该被激活(“激发”)。激活函数还有助于将每个神经元的输出标准化到 1 到 0 之间的范围。

解码器网络是具有 784 个神经元的单个密集层,对应于 28×28 灰度输出图像。sigmoid 激活函数用于比较编码器输入和解码器输出。

二进制交叉熵用作损失函数,Adadelta 用作最小化损失函数的优化器。

MNIST 数据集是一个著名的手写数字数据库,广泛用于机器学习领域的训练和测试。我们在这里使用它,通过应用高斯噪声矩阵并在 0 和 1 之间裁剪图像来生成合成噪声数字。

你仍然可以识别数字,但是很难。因此,我们想使用我们的自动编码器来学习恢复原始数字。我们通过在 100 个时期内拟合自动编码器来实现这一点,同时使用有噪声的数字作为输入,并将原始去噪的数字作为目标。

因此,自动编码器将最小化噪声图像和干净图像之间的差异。通过这样做,它将学习如何从任何看不见的手写数字中去除噪声,这些数字是由类似的噪声产生的。

如何用自动编码器去噪

现在,我们可以使用经过训练的 autoencoder 来清理看不见的噪声输入图像,并根据清理后的图像绘制它们。

  • 总的来说,噪音消除得非常好。在输入图像上人为引入的白点已经从清洗后的图像中消失。数字可以被视觉识别。例如,有噪声的数字“4”根本不可读,现在,我们可以读取它的干净版本。
  • 去噪对信息质量有负面影响。重建的数字有些模糊。解码器添加了一些原始图像中不存在的特征,例如,下面的第 8 位和第 9 位数字几乎无法识别。

图片由印第安纳大学(开放访问)

在本文中,我描述了一种图像去噪技术,并提供了如何用 Python 构建自动编码器的实用指南。放射科医生通常使用自动编码器对 MRI、US、X 射线或皮肤病变图像进行去噪。这些自动编码器在大型数据集上接受训练,例如由 7470 张胸部 x 光图像组成的印第安纳大学的胸部 x 光数据库。降噪自动编码器可以用卷积层来增强,以产生更有效的结果。

感谢阅读。

用于降维的自动编码器网络优化

原文:https://towardsdatascience.com/autoencoder-network-optimization-for-dimensionality-reduction-67922ccc6889?source=collection_archive---------21-----------------------

如何优化隐藏层数和大小?

在之前的文章中,我们看到了如何通过使用线性激活函数和“mse”作为损失度量,利用自动编码器网络(AE)模拟 PCA 降维。

在一个合成数据集上,我们比较了基于分类分数和潜在变量的降维性能。我们看到了如何通过修改网络(添加更多层,堆叠自动编码器)或最终允许激活函数为非线性来改善结果。然而,这些变化是任意的。在这篇文章中,我想进行同样的基本分析,但这一次使用一种随机搜索的方法来寻找最佳的网络结构。我们将通过使用方便的 KerasRegressor 包装器来实现这一点

from tensorflow.keras.wrappers.scikit_learn import KerasRegressor

与前一篇文章不同的是,我们将从一个新的数据集开始:我们将使用一个严格非线性的数据集,它由来自 sk learn . datasets:make _ friendman 2 的 4 个变量组成。为了增加维度,我们也将使用 sklearn 的多项式特征(order=2,interactions_only=True)。这可能会稍微减轻主成分分析的工作,但我们会将 11 个变量的系统减少到 3 个。

在第一部分中,我们将使用浅网络的性能作为起点,就像我们在上一篇文章中所做的那样。在第二部分,我们将优化参数。第一个尝试是优化隐藏层的数量和形状(最多 4 层)。

自动编码器网络结构。图片作者。

基线性能

为了理解优化效果如何,我们将比较自动编码器和 PCA(主成分分析)的维数减少。
我们建立了包含 4 个特征的数据集。我们引入了多项式特征来增加维数,然后我们对所有这些特征应用标准缩放。最后,我们将把数据集的维数减少到 3。

主成分分析解释了该数据集约 77%的方差。

PCA 和编码器前 3 个组件。颜色显示要预测的值。

使用具有最大深度 3RandomForestRegressor ,我们在具有原始 4 个特征的数据集上获得了 0.92 的回归分数。在具有多项式和缩放要素的数据集上为 0.98。
使用具有 3 个成分的 PCA,我们得到 0.67 的回归分数。使用简单的线性自动编码器,1 级 a 分数约为 0.7。使用简单的堆叠 AE:10–10–3,我们可以达到 0.77。

从这些数据中我们已经了解到,构成结果 y 的非线性特征强烈地影响着潜在变量的预测能力。自动编码器已经比 PCA 执行得更好,我们仍然使用线性激活函数。

对不同结构的回归结果进行评分。

优化层数

我们现在要优化堆栈编码器。我们通过导入一个新的库来实现:KerasRegressor。它将允许我们使用 scikit-learn 中的 RandomizedSearchCV。

from tensorflow.keras.wrappers.scikit_learn import KerasRegressor

要生成层的组合,有几种方法。直截了当的方法是用简单的列表理解一些条件句。最终我们可以决定定义一个函数,它的形状与我们数据的输入形状相关联。

output_dim = 3
sizes = [10,10,5,5,0]
shapes = [(i,j,k,q,output_dim) for i in sizes for j in sizes for k in sizes for q in sizes if (i>=j>=2*k>=output_dim)]

以下是从前面的列表理解中输出的一些形状:正如你在代码中注意到的,我们确保最终的维度总是我们的潜在空间维度。

(10, 10, 5, 10, 3),
 (10, 10, 5, 10, 3),
 (10, 10, 5, 5, 3),
 (10, 10, 5, 5, 3),
 (10, 10, 5, 0, 3),
 (10, 10, 5, 10, 3),
 (10, 10, 5, 10, 3),
 (10, 10, 5, 5, 3),
 (10, 10, 5, 5, 3),
 (10, 10, 5, 0, 3),
 (10, 10, 5, 10, 3),
 (10, 10, 5, 10, 3), ... ]

层结构现在变成如下图所示:

将被优化的堆叠编码器结构。图片作者。

我们定义一个函数,它将使用我们刚刚定义的图层大小作为参数。我们将像上一篇文章一样构建编码器,但这次我们也将解码器的重量与编码器的重量联系起来。这样,我们将减少可训练参数,搜索将会更快。最后,它将连接两个模型,就像我们之前在堆栈自动编码器中所做的那样。

既然我们已经定义了构建自动编码器的函数,我们就定义了参数搜索网格,并利用 RandomizedSearchCV 功能来执行搜索。

请注意,我们正在寻找最能减少重建损失的网络结构。我们不是在寻找最佳的网络参数来改善我们的回归得分问题!

经过一番搜索,最佳结果似乎是(8,8,5,3)层网络。尽管如此,分数都是可比的。看起来至少有一些额外的层会有所帮助,但不会太复杂。

不同网络的平均测试分数。

结果报告如下。左边是到目前为止我们考虑的所有结果。右边是从 0.6 开始的(奇怪的)柱状图。即使在这种规模下,搜索的好处也不明显。

结论

在这篇短文中,我们看到了如何构建一个用于降维的自动编码器,并将其与上一篇文章中的 PCA 等标准算法进行比较,但使用的是强非线性数据集。在这种情况下,我们做了一个回归问题。

我们试图通过使用多项式特征来帮助 PCA 更好地执行,但是与原始数据集结果相比,信息损失仍然很大。一个简单的欠完整自动编码器已经开始比 PCA 表现得更好,增加层数和将解码器的权重与编码器的权重联系起来会使它甚至更好。

我们在 scikit-learn RandomizedSearchCV 和 GridSearchCV 中使用了 Keras 序列模型的包装器。在这个数据集上没有观察到更大的改进。很可能,由于原始维度只有 11,搜索效率并不高。

文献学

[1] A. Géron,用 Scikit-Learn 进行机器学习的实践,Keras & TensorFlow(第二版)。真的吗?
[2] A. Gulli,A. Kapoor,S. Pal,深度学习用 TensorFlow 2 和 Keras。(第二版)。打包。
【3】sk learn . datasets . make _ Friedman 1—scikit-learn 0 . 24 . 1 文档(scikit-learn.org)
【4】用自动编码器降维

使用 JavaScript 自动化和增强 Google Colab

原文:https://towardsdatascience.com/automate-and-supercharge-google-colab-with-javascript-9f494d98489d?source=collection_archive---------15-----------------------

在 Colab 上运行预先安排的 Python 脚本,并在您自己的驱动器上访问结果

Jean-Philippe Delberghe 在 Unsplash 上拍摄的照片

介绍

云计算正迅速成为数据科学家和公司的首选武器,这也是有充分理由的。有了提供给你的资源和与之相关的极小的费用,辨别云和本地计算实际上只是一个基本的算术问题。多年来,像亚马逊网络服务、微软 Azure、谷歌云平台和其他平台都竞相向客户提供最复杂、最先进、但最实惠的服务。具有讽刺意味的是,谷歌作为科技行业的先驱之一,在这场游戏中姗姗来迟,他们仍在弥补失去的时间。但是随着几年前 Google Colab 的推出,他们已经向全世界提供了一种服务,这种服务是无与伦比的,因为你没有为它付费。

可比虚拟机—每小时定价。图片作者。

从资源分配的角度快速查看一下最近的产品,就会发现使用 Colab 每一小时平均可以节省 16.3 美分。事实上,如果您自己进行调配,为每个 Colab 会话调配的实际虚拟机本身每小时会花费您 0.16 美元。下表显示了 Amazon Web Services、Microsoft Azure 和 Google Cloud Platform 提供的与 Colab 最具可比性的虚拟机及其各自的规格和价格。

换句话说,Colab 是一个不花钱的好东西。更不用说 Colab 还为您提供了对 GPU 和 TPU 的访问,这意味着您实际上每小时节省了 16 美分以上。最棒的是,实际上,世界上任何地方的任何人都可以按需访问它。请注意,这种善良也有局限性。您最多可以运行 12 个小时的会话,空闲超时大约为半小时。此外,如果您被发现过度使用 Colab 的一些资源,如 GPU 和 TPU,您可能会面临编程瓶颈。尽管如此,这样的限制还是过于宽松了。然而,为了更好地衡量,我们鼓励您有效地使用资源,不要过度使用,以避免任何服务中断。

Colab 自动化

人们想要自动化 Colab 的原因有很多:

  • 运行 Python 脚本时要留出时间间隔,以避免过度利用可用资源。
  • 您的脚本是一个时间关键的程序,需要在预先安排的时间运行。
  • 确保您的程序在完成时或系统超时/关闭前关闭。

不管有什么原因,您确实可以通过编写 JavaScript 的小片段来自动化 Colab,这些小片段将在您的浏览器控制台上运行,以在 Colab 界面上交互和模拟按钮按压,从而在特定时间或通过特定触发来启动和/或停止您的会话。

要插入并运行 JavaScript 代码片段,请在您选择的浏览器上按 F12 打开控制台。然后将 JavaScript 片段粘贴到命令窗口中,并按 enter 键。随后,浏览器将运行代码,通过模拟按钮点击来自动化 Google Colab。要查找需要点击的按钮的 JavaScript 路径,请右键单击按钮并选择“检查”,或者使用浏览器控制台中的“选择一个元素”光标查找相关路径,如下所示。请注意,Google 可能会动态更改这些路径。

使用“选择一个元素”光标定位按钮元素。图片作者。

右键单击按钮元素复制 JavaScript 路径。图片作者。

场景 1: 在预先安排的时间运行/终止会话

对于我们的第一个场景,我们将立即运行我们的 Python 脚本(或者如果需要,在一定的秒数之后),然后我们将在指定的秒数之后终止会话。为此,我们将实施以下步骤:

  1. 激活 Colab 会话
  2. 运行脚本(在预先安排的时间)
  3. 终止会话(在预先安排的时间)

下面的视频展示了自动化 Google Colab 的 JavaScript 代码。

作者视频。

请在下面找到该场景的 JavaScript 代码:

场景 2: 迭代地运行/终止会话

对于我们的第二个场景,我们将使用以下步骤根据需要多次迭代运行 Python 脚本:

  1. 激活 Colab 会话
  2. 如果迭代次数小于指定次数,则运行脚本
  3. 终止会话

请在下面找到该场景的 JavaScript 代码:

场景 3: 动态运行/终止会话

对于最后一个场景,我们将动态运行 Python 脚本,直到它提示我们终止它。这对于具有动态或未知运行时的脚本很有用。将为此用例实施以下步骤:

  1. 激活 Colab 会话
  2. 运行脚本,直到执行完成
  3. 向控制台日志发送消息以触发终止
  4. 终止会话

为了提示我们的 JavaScript 程序终止会话,我们将在 Python 脚本的末尾添加一行,这将产生一个错误。例如,我们可以尝试除以 0,这将提示 Colab 显示一条错误消息,该消息也将记录在浏览器的控制台中。然后,我们可以使用相同的 JavaScript 程序不断检查日志的长度是否超过 0,一旦超过,就会终止会话。

空日志允许程序无限期运行。图片作者。

完整日志将触发 JavaScript 终止会话。图片作者。

请在下面找到该场景的 JavaScript 代码:

持久保存结果

Google Colab 无缝连接到 Google Drive,这使我们能够将执行结果持久保存到我们自己的驱动器中。此外,您可以通过从 Google Drive 中的 csv 文件读取 Python 脚本来进一步自动化您的程序,该文件可以指导您的程序执行某些操作。例如,每次运行脚本时,它将首先检查 Google Drive 电子表格中的第一行,告诉它要操作数据帧中的哪一列,一旦执行完成,Python 脚本将删除第一行并重新保存电子表格,以便下次运行时将移动到数据帧中的下一列。

将 Google Drive 连接到 Colab。图片作者。

使用以下代码从您的 Google Drive 访问“指南”文件。

guide = pd.read_csv('drive/MyDrive/ColabNotebooks/guide.csv')
column_to_manipulate = guide.iloc[0][0]

执行完成后,只需忽略第一行,将文件重新保存到 Google Drive:

guide = guide.iloc[1:]
guide.to_csv('drive/MyDrive/ColabNotebooks/guide.csv',index=False)

结论

Google Colab 和云计算总体上提供了对大量计算资源的无与伦比的访问,直到最近许多人还无法访问这些资源。这样的功能加上一些使用 JavaScript 的自动化可以创造无限的机会,同时以更有效的方式利用资源。具体来说,在 Colab 的情况下,这样一种优秀的产品最好不要过量使用,以使社区中的每个人都能平等地受益于这样一包好东西。

https://github.com/mkhorasani/colab_automation

新到中?您可以在此订阅和解锁无限文章。

使用 Apache Spark 实现阿拉伯语自然语言处理自动化

原文:https://towardsdatascience.com/automate-arabic-nlp-with-apache-spark-fdcc2eedade5?source=collection_archive---------50-----------------------

带代码的教程,使用 Apache Spark 和 Spark NLP 将大数据与阿拉伯语自然语言处理结合起来进行分布式计算

杰瑞米·托马斯在 Unsplash 上拍照

很难概念化“大数据”实际上有多大,以及它对试图利用大数定律进行社会研究的数据科学家来说意味着什么。在《反乌托邦 2020》开始的时候,世界经济论坛估计全世界的数据量是 44 zettabytes(一个 zettabyte 有 21 个零);这个数字大约是可观测宇宙中恒星数量的 40 倍。在全球范围内,到 2025 年,估计每天将产生 463 艾字节(一个艾字节有 18 个零)。对社会研究感兴趣的数据科学家应该为这一现实做好计划;目前专注于使用大数据工具应对未来是一个务实的决定。

在这个关于阿拉伯语 NLP 的三部分系列的第一篇文章中,我提到了对阿拉伯语特定语言资源日益增长的需求,并介绍了一些可用的前沿工具。这第二部分重点关注在使用像阿拉伯语这样的低资源语言时所必需的创造性,特别是因为最有前途的大数据工具都是为英语构建的。目前, Apache Spark 显然是大数据领域的领跑者,John Snow Labs 的流行开源项目 Spark NLP 提供了构建自动化大数据管道所需的免费 NLP 工具。此外, Apache Spark MLib 提供了可扩展的机器学习算法,可以无缝融入 Spark 的 API,为 Spark NLP 提供了必要的扩展。

在本文中,我将探讨如何使用这些大数据工具来创建 NLP 管道,以实现阿拉伯语 NLP 的自动化。具体来说,我比较了来自 Spark NLP 的三个预训练嵌入,它们与深度学习文本分类器结合使用,创建了一个阿拉伯语情感分析管道,可以在 Spark 集群中运行,用于分布式计算。

面向大数据的 Apache Spark】

Spark 将自己定位为“大规模数据处理的统一分析引擎”。关键卖点是速度(内存比 Apache Hadoop 快 100 倍)以及与其他数据需求的广泛集成,如 SQL、流、机器学习和图形。实际上,Spark 作为数据处理框架的强大之处在于可伸缩性和并行性。Spark 可以在大数据集上快速执行处理任务,重要的是将这些数据处理任务分布在多台计算机上。这种批处理并行化可以通过 Spark 单独完成,也可以与其他分布式计算工具协同完成。例如,它可以与谷歌开发的 kubernetes 和其他 Apache 产品集成,如 Hadoop 、 Cassandra 、 Mesos 和 HBase 。

Medium 上有几个有用的快速入门指南,用于设置 Spark 集群:与 Kubernetes 一起使用,与 Databricks 一起使用,与 Hadoop 一起使用,与 PySpark 和 Spark-submit 一起使用。Spark 框架的核心构建块是弹性分布式数据集 (RDD),本质上是一个可以并行操作的数据集。Spark 在 RDD 编程指南中提供了大量利用 RDD 的文档。当使用 Python 时,我使用 PySpark,这本全面的指南对于 PySpark 和 RDD 初学者来说是一个很好的起点。对于一个更短的、专注于代码的教程,我建议在 Neptune.ai 博客上发布这个可访问的帖子。

Spark 是用 Scala 编写的,它有一个 Java 虚拟机(JVM)运行时,运行速度比 Python 快 10 倍。此外,Scala 作为静态类型语言还有额外的运行时优势,这意味着代码是在运行时之前编译的,而 Python 是动态类型语言,因此速度较慢,因为代码必须在运行时进行解释。由于速度的原因,Spark 最好与 Scala 一起使用,但是我建议在选择一种语言之前,先阅读这篇比较 Scala 和 Python for Spark 的文章。出于本教程的目的,我将利用 Python 例子来提高可访问性,但是我建议在为生产编写管道时使用 Scala。

Spark NLP for Arabic NLP

Spark NLP 是 John Snow Labs 的一个开源项目,作为第三方产品,成功地将 NLP 集成到 Spark 生态系统中。这是一个很好的做法,以简化效率和质量保证的共同进程,和火花 NLP 的管道,使这成为可能,为经常性的 NLP 任务。Spark NLP 有许多预训练的管道、模型和嵌入,可用于几种不同的语言,用于命名实体识别、依存解析和情感分类等任务。

特别是对于阿拉伯语,Spark NLP 提供了一个阿拉伯语分类器,一个停用字词清洁器和字词嵌入。不幸的是,在撰写本文时(2021 年 1 月), lemmatizer 和单词嵌入是错误的和不可靠的。就个人而言,我发现在使用阿拉伯语时,最有用的 Spark NLP 工具是多语言工具。对于本文,我构建了几个深度学习阿拉伯情感分类器,测试了两种类型的多语言句子嵌入和一种多语言单词嵌入。

阿拉伯情感分类

为了判断前述多语言嵌入的质量,我使用阿拉伯语约旦语通用推文(AJGT)语料库进行二元情感分类。这允许与 AraBERT 情感分类器的结果进行直接比较,我在我的上一篇阿拉伯语 NLP 文章中介绍了该分类器。提醒一下,AJGT 数据集由 1800 条现代标准阿拉伯语或约旦方言的推文组成,标注为正面或负面。当用于训练 AraBERT 模型时,该数据集产生 93.8%的准确率。我测试的三个嵌入包括如下:通用句子编码器句子嵌入(USE) ,语言不可知的 BERT 句子嵌入(LaBSE) 和多语言 BERT 单词嵌入(M-BERT) 。

句子嵌入

句子嵌入是一种将句子映射到向量的文本处理方法,作为一种用适合机器学习的实数表示文本的方法。关于如何训练和部署基于 Transformer 的句子嵌入(如 LaBSE)的更多细节,我建议阅读我关于基于 Transformer 的句子嵌入的文章。

https://medium.com/swlh/transformer-based-sentence-embeddings-cd0935b3b1e0

Spark NLP 提供了两个 Tensorflow Hub 的通用句子编码器模型,默认选项是用深度平均网络(DAN)编码器训练的模型,这是最初使用论文的研究人员提供的两个选项中最受欢迎的一个。关于如何实现 USE 语句嵌入的更多细节,我推荐这篇讨论生产选项的中型文章。

多语言 BERT 单词嵌入

根据我的经验,句子嵌入的主要优势是速度和适合语义文本相似性任务。然而,对于文本分类任务,例如情感分析,BERT 型单词嵌入通常产生更好的结果。Spark NLP 没有用于多语言或阿拉伯语情感分析的预训练管道,用于文本分类的管道组件需要句子嵌入。因此,为了比较 M-BERT 嵌入,我决定修改单词 embedding,以便它们可以以类似于多语言句子嵌入的方式使用。明确地说,我怀疑这种非常规的方法不如预先训练的句子嵌入,因为研究表明这对于语义相似性任务来说是正确的。然而,据我所知,这种比较还没有用于文本分类任务,因此我很好奇。

【Spark NLP 入门

首先,要使用 Spark NLP for Python,需要安装 Spark NLP 和 PySpark。这是通过以下代码行完成的:

pip install spark-nlp==2.6.5 pyspark==2.4.4

下一个需求是为 Spark NLP 安装正确的 Java 环境。这一步可能比较棘手,所以如果在设置 Java 8 运行时环境时遇到困难,我建议使用 Google Colab 而不是本地 IDE。

成功安装后,输出应为:

最后,必须初始化一个 Spark NLP 会话,只需使用下面的代码片段即可完成。

import sparknlpspark = sparknlp.start()

检查是否使用了正确版本的 Spark 和 Spark NLP 是可行的,因此我建议运行以下两个命令作为健全性检查。

Spark.versionsparknlp.version()

最后一步,从 Spark NLP 和 Spark MLib 导入必要的模块。

from pyspark.ml import Pipeline
from sparknlp.annotator import *
from sparknlp.common import *
from sparknlp.base import *
from sparknlp.embeddings import *
from pyspark.sql.functions import *

在 Spark NLP 中使用 rdd

Spark NLP 会话运行后,可以将不同类型的数据加载到 Spark 数据帧(RDD)中。以下命令用于将 json 读入 PySpark RDD:

df_spark = spark.read.option("header",True).json("AJGT_labels.json")

AJGT 数据集中的前五个条目读作 RDD。图片作者。

快速分组命令显示二进制标签的分布。

df_spark.groupBy("label").count().show()

来自 AJGT 数据集的标签计数显示了平衡分布。图片作者。

在准备训练时,有必要分割数据集,对于 RDDs,可以使用以下命令:

df_train, df_test = df_spark.randomSplit([0.8, 0.2], seed=42)

构建 Spark NLP 管道

如前所述,Spark NLP 提供了一个深度学习文本分类器,需要句子嵌入作为输入。对于两个多语言句子嵌入,通过简单地切换出嵌入,可以使用相同的 NLP 管道。我为 M-BERT 单词嵌入构建了一个单独的 NLP 管道,它基于平均池策略产生句子嵌入。管道构建组件包括转换器(不要与转换器架构混淆)和注释器,其细节在 Spark NLP 文档和这篇文章的第三部分中讨论。

如下面的代码片段所示,要构建一个阿拉伯情感分类器,第一步是使用一个名为 DocumentAssembler()的转换器。接下来,标记化和清理(删除停用词)的基本预处理步骤由标记化器()和停用词清理器()注释器处理。请注意,清洁工使用了阿拉伯停用词。

对于 LaBSE 句子嵌入,使用 BERTSentenceEmbeddings()注释器,而一个单独的注释器 UniversalSentenceEncoder()用于使用嵌入。两种嵌入都显示在下面的代码片段中,只需根据所需的管道注释掉不需要的代码块。

对于 M-BERT 单词嵌入,BERTEmbeddings()注释器用于创建单词嵌入,然后用 sentence embeddings()注释器将单词嵌入转换成句子嵌入。

当使用 ClassiferDLApproach()设置文本分类深度学习方法时,可以为深度神经网络的训练分配参数。在下面的代码片段中,我将最大历元数设置为 6,验证拆分为 50%,丢弃为 20%,学习率设置为 5^-4.我选择这些参数是为了避免由于小数据集而导致的过度拟合,并希望提高泛化能力。根据所使用的数据集,可能有必要调整这些参数。

构建管道的最后一步是按照指定的顺序组装组件,用分类器打包预处理步骤。在下面的代码片段中,我展示了两条管道,第一条管道用于 USE 和 LaBSE 嵌入,第二条管道用于 M-BERT 嵌入。如图所示,对于 M-BERT,唯一的区别是将单词嵌入和句子嵌入放在一起。

NLP 管道培训

为了用 NLP 管道训练分类器,我使用了下面的单行代码:

classification_model = nlp_pipeline.fit(df_train)

下面的代码片段显示了访问培训日志和显示培训报告所需的两个命令。培训日志中的每个报告条目都将打上时间戳,并可通过十二位字母数字代码进行识别。

!cd ~/annotator_logs && ls -l# select a report log from output of previous command 
!cat ~/annotator_logs/ClassifierDLApproach_xxxxxxxxxxxx.log

最后,为了评估结果,在拆分数据集时,有必要在搁置维持数据的情况下测试模型。下面的代码片段显示了如何在测试 Spark 数据帧上运行预测,将其转换为 Pandas 数据帧,然后使用 Scikit-Learn 构建一个简单的分类报告。

当使用 AJGT 数据集来训练阿拉伯情感分类器时,Spark NLP 提供的预训练嵌入都没有 AraBERT 模型的准确度高。对于 USE、LaBSE 和 M-BERT 嵌入,如下所示的结果分别为 65%、87%和 77%。

使用通用语句编码器 嵌入训练的阿拉伯情感分类器的分类报告。

使用语言不可知的 BERT 句子嵌入训练的阿拉伯情感分类器的分类报告。

使用多语言 BERT 单词嵌入训练的阿拉伯情感分类器的分类报告。

有趣的是,观察到与使用嵌入相比,M-BERT 嵌入导致显著更高的准确度,假定 M-BERT 嵌入旨在作为单词嵌入而不是句子嵌入。对于 LaBSE 嵌入,测试嵌入实现的最高准确度是 87%。然而,正如之前证明的,直接在阿拉伯语上训练的 AraBERT 模型表现得非常好,对于这个特定的情感分类任务,报告的准确率为 93.8%。

此外,从上述结果中可以看出,三种分类报告的计算墙时间存在明显差异。使用报告耗时 3.24 秒,而 LaBSE 和 M-BERT 报告分别耗时 38.1 秒和 48.4 秒。虽然使用嵌入产生了最差的准确度分数,但是使用管道比其他两个管道快 10 倍以上。

最终想法

本教程中的实验允许在 AraBERT 和 Spark NLP 已经采用的最先进的句子嵌入之间进行比较。看起来特定于阿拉伯语的语言模型比 Spark-NLP 提供的多语言选项表现得更好。事实上,AraBERT 背后的研究人员已经针对 M-BERT 单词嵌入对他们的模型进行了基准测试,结果显示 AraBERT 的准确率更高。不幸的是,Spark NLP 尚未将 AraBERT 添加到其预训练模型的阵容中。因此,根据我的结果,最好的选择是保存 LaBSE 管道和经过训练的分类器,以便部署在自动化 Spark 工作流中,用于可扩展和可并行的阿拉伯情感分类。准确性的牺牲将得到可靠而高效地处理大数据的能力的回报。我的希望是 Spark NLP 将为低资源语言添加额外的预训练模型,不仅仅是多语言模型或双语翻译模型,而是针对像阿拉伯语这样学习不足的语言的特定语言模型。

使用 BigQuery 或 Google Sheets 自动生成 BigQuery 数据集和表大小报告

原文:https://towardsdatascience.com/automate-bigquery-dataset-table-size-reporting-using-bigquery-or-google-sheets-c0d43c3db30?source=collection_archive---------23-----------------------

从 BigQuery 项目中自动收集表格大小和行数,并将其全部存储在 BigQuery 和/或 Google Sheets 中。

多说说…?

2021 年 1 月 18 日更新:更新了流程和回购代码,因此您只需指定您的 GCP 项目 id,而无需手动输入您的所有项目和数据集 id。所以…现在更容易了!

我想看看是否有可能轻松地自动化跟踪不同的 BigQuery 数据集和表如何随时间变化的过程。在某个时候,我还会添加在阈值被突破时接收电子邮件或 Google Chat 通知的功能(表格在两次检查之间增加/减少太多),但那是另外一天的事了。今天,我们只是收集关于表的信息,以便于报告和可视化。

显然有很多不同的方法可以做到这一点,包括 BigQuery 本身的预定查询,但这也不能处理将数据自动推入 Google Sheet 的过程。另外…我想看看这在 AppScript 中是否可行,因为现在我可以重新调整查询函数的用途,以便在将来执行其他事情。

以下是我们要用到的所有东西:

  1. BigQuery 数据集/表—跨多个项目检查它们的大小
  2. AppScript —处理代码并安排检查自动运行
  3. BigQuery 表——存储我们收集的数据,如果我们不想使用工作表
  4. Google Sheet——存储我们收集的信息,如果我们不想使用 BQ 的话

让我们开始吧。

创建 appscript 项目

  • 去 script.google.com创建一个新项目
  • 因为没有与 appscript 的 git 集成,所以您只需要手动复制文件(文件的内容)
  • 从这里分享的 github 库复制文件内容:【https://github.com/usaussie/appscript-bigquery-reporter
  • 您应该得到 3 个文件——jobs . GS、Helpers.gs、Config.gs(根据提供的示例重命名)

更新项目以使用您的 BigQuery / Sheet 信息

  • 更新 Config.gs 文件以指向您自己的 BQ 项目和您想要跟踪的数据集,然后还提供一个 BQ 表来存储结果=,最后是一个 google sheet url。
// BigQuery Project ID - all lowercase
const BQ_PROJECT_ID = 'your-gcp-project-id';// Create a dataset in the BigQuery UI (https://bigquery.cloud.google.com)
const BQ_DATASET_ID = 'your-gcp-dataset-id';// Table ID to store the collected stats
const BQ_TABLE_ID = 'your-gcp-table-id';// for storing the metrics in google sheets tooconst SHEET_URL = "https://docs.google.com/spreadsheets/d/your-google-sheet/edit";const MAIN_SHEET_TAB_NAME = "Sheet1";// these are the tables & datasets that you
function project_dataset_list() {  
    return [    
        ['gcp-project-id-a', 'dataset_one'],
        ['gcp-project-id-a', 'dataset_two'],
        ['gcp-project-id-b', 'dataset_one'],
        ['gcp-project-id-c', 'dataset_one']
    ];
}
  • 就是这样…这就是你要自己编码的所有东西…它甚至真的没有编码…它只是指向您已经管理的 id。
  • 如果您还没有 BQ 表来存储结果,不要担心,您也可以从这个项目中这样做。

设置完毕,让我们开始吧…

  • 首先,让我们创建 BQ 表—打开 Jobs.gs 文件,运行一次 create_tables_one_time()函数和 set_sheet_headers()函数。
/**
 * Only run this once to create the initial tables to hold the collected data.
 */

**function create_tables_one_time() {**

  var my_tables = tables_to_create();

  for (i = 0; i < my_tables.length; i++) {

    // generate correct function / table info from detected string
    var tableFunction;
    tableFunction = new Function('return ' + my_tables[i]);
    var thisTable = tableFunction()();

    var tableJson = constructTableJson(thisTable, BQ_PROJECT_ID, BQ_DATASET_ID);
    createTable(thisTable.tableId, BQ_PROJECT_ID, BQ_DATASET_ID, tableJson);

  }

**}**/*
*
* ONLY RUN THIS ONCE TO SET THE HEADER ROWS FOR THE GOOGLE SHEETS
*/
**function set_sheet_headers() {**

  var sheet = SpreadsheetApp.openByUrl(SHEET_URL).getSheetByName(MAIN_SHEET_TAB_NAME);
  sheet.appendRow(["timestamp","project","dataset","table", "size_bytes", "row_count"]);

**}**
  • 这将使 Google 弹出并提示允许您的新 appscript 项目代表您连接到 BigQuery,并写入 Google Drive/Sheets。注意,这是你的项目…所以你只是授予许可给…你自己:-)

授予自我许可!

  • 运行 job_get_bq_stats()函数,并等待几秒钟(取决于您正在检查多少个表)。
**function job_get_bq_stats() {** 
  var this_timestamp = Utilities.formatDate(new Date(), "UTC", "yyyy-MM-dd'T'HH:mm:ss'Z'");

  var projects = project_dataset_list();

  // loop the outer array
  var stats_array = []
  for (let i = 0; i < projects.length; i++) {

      var my_query = construct_select_query(projects[i][1]);
      var query_data = runQuery(projects[i][0], my_query);

      // if there are results, add the extra info (timestamp, project etc) ready for storage/insert into our sheet/bq table
      if(query_data.length > 0) {

        for (let q = 0; q < query_data.length; q++) {

          stats_array.push([
            this_timestamp,
            projects[i][0],
            projects[i][1],
            query_data[q][0],
            query_data[q][1],
            query_data[q][2],
          ]);

        }

      }

  }

  // write to bigquery
  var insert_query = construct_insert_query(stats_array);
  runQuery(BQ_PROJECT_ID, insert_query);

  //write to google sheet now
  // write collected rows arrays to the sheet in one operation (quicker than individual appends)
  var ss = SpreadsheetApp.openByUrl(SHEET_URL).getSheetByName(MAIN_SHEET_TAB_NAME);
  ss.getRange(ss.getLastRow() + 1, 1, stats_array.length, stats_array[0].length).setValues(stats_array);

**}**
  • 函数执行完毕后,您可以检查 BigQuery 表或 google sheet 来查看结果。

带有收集的 BQ 数据的 Google Sheets 截图

  • 现在您应该看到包含项目 ID、数据集 ID、表 ID 的行,然后是表大小(字节)和行数。

我有数据!

安排它自动运行

  • 单击 appscript 项目中的 triggers 部分,按照提示每天(或根据需要每小时)运行 job_get_bq_stats()函数。

在 appscript 中设置触发器以自动运行此作业的屏幕截图

我被触发了!

就是这样!

详述一下…

我想补充的下一点是,当数据集在两次检查之间增长/变化“太多”时会发出警报。

请注意,您显然可以将它连接到 Google Datastudio 仪表板,以绘制一段时间内的表格数据,并识别异常值等。

最后…这是代码的 git repo 的另一个链接……您可以根据自己的需要随意使用、增强、扩充。

https://github.com/usaussie/appscript-bigquery-reporter

我喜欢分享:-)

📧使用 Python 自动发送电子邮件

原文:https://towardsdatascience.com/automate-email-sending-with-python-74128c7ca89a?source=collection_archive---------4-----------------------

ETL 管道的权威代码片断集合

作者图片[A.Vaccaro]

0.介绍

通常,当执行复杂的 ETL 管道或简单的脚本时,我们需要从邮箱甚至 中读取,自动发送带有任何类型附件( CSV、PDF、JPEG 等)的 。)图一

图 1——一个简单的 ETL 管道可能以给涉众的电子邮件通知结束。[图片由作者 A.Vaccaro 提供]

正如我们可以想象的, Python 是在有或没有我们监督的情况下自动发送任何种类电子邮件的理想伴侣

问题是,尽管有一个简单的 包来处理这一切 ,但我们在网络上找到的指南往往是支离破碎、不完整的。

有了这篇文章我想 收集并展示 你一劳永逸的 最简单的方法 自动发送邮件 ( HTML 或不 ) 带或不带附件

🔖所以…请随意将这篇文章添加到您的 书签中,以备将来使用

1.在后台

我们当中有谁从未需要配置自己的邮箱来阅读电脑/智能手机上的电子邮件?

在那一刻,我们当然意识到发送、接收和存储电子邮件需要使用服务提供商 。其中最常见的当然是谷歌邮件、微软 Outlook 和苹果 iTunes。

因此,不可避免地要谈一下描述电子邮件服务提供商特征的 3 个著名协议 :

  • SMTP :是用于发送邮件的 协议。 其首字母缩写代表简单邮件传输协议。这就是我们将在本文中使用的。
  • 另一方面, IMAPPOP 是另外两个流行的协议,分别用于从/在我们的客户端中 读取下载 电子邮件。

2.流动

图 2 —电子邮件生命周期。[图片由作者 A.Vaccaro 提供]

我们即将实施的流程非常简单:

  1. 使用 Python,我们将实例化一个与服务提供商的 加密连接(STARTTLS);
  2. 收到我们的邮件后,我们的服务商(发件人服务器)会通过 SMTP 发送 给收件人服务商(收件人服务器);
  3. 收件人的客户端可以使用收件人的服务器 通过 IMAP 或 POP 阅读电子邮件

3.我们需要什么

这就是我们所需要的:

  • smtplib:Python 的标准库包之一,用很少几行代码发送电子邮件。我们不需要安装这个软件包。
  • SMTP 设置:让我们看看我们的服务提供商(,我们打算从那里发送邮件)的文档,寻找 SMTP 主机名SMTP 主机端口 。下面我给你留了一个表格,总结了最常见的设置:

图 3 — TODO ( 谷歌邮箱、微软 Outlook 、苹果 iCloud e 雅虎邮箱)【图片由作者提供— A.Vaccaro】

在继续之前,让 定义参数 :

注意:收件人和发件人是一样的,因为就本文的目的而言,我们最好给自己发邮件😅*。*

让我们从 代码片段 开始吧!

4.如何发送不带附件的电子邮件

让我们从最简单的例子开始:发送一封没有附件的文本邮件。

在这个例子中,像在其他例子中一样,我们将使用MIME Multipart格式,这将允许我们一次组合电子邮件的一部分。

图 4-带有 MIMEText 对象的简单电子邮件。[图片由作者 A.Vaccaro 提供]

让我们从导入smptlib包以及MIMEMultipartMIMEText模块开始。然后,我们可以通过输入我们的凭证来实例化与服务提供者的连接。

在创建 MIMEMultipart()对象之后,我们用关于发送者、接收者和主题的数据填充它的头部。

最后,让我们定义并填充 MIMEText()和 发送消息

搞定了。极其简单!

5.如何发送不带附件的 HTML 电子邮件

这与前面的例子非常相似。

唯一的区别?MIMEText 对象类型必须是“html ”, mime multipart 必须是“alternative”。

图 5-用 MIMEText 对象实现的 HTML 电子邮件。[图片由作者 A.Vaccaro 提供]

让我们像以前一样重写所有内容,插入刚才提到的两个属性。

超级简单。让我们继续附件…

6.如何发送带附件的电子邮件

MIMEMultipart 的 模块化 终将浮出水面。

图 6 —包含文本和附件的电子邮件。[图片由作者 A.Vaccaro 提供]

在这种情况下,实际上,为文本组件实例化一个 MIMEText 和为附件实例化一个(或多个)mime application就足够了。

我们最后将 把它们放在一起 在一个 MIMEMultipart 对象中。

我们可以看到,要将文件正确地附加到文件中,就必须以“字节格式打开它。因此在open()函数中需要“ rb ”。

最后,为了正确地构造 MIME 对象,我们还向 MIMEApplication 对象添加了“Content-Disposition”属性,以指示附件的名称。

7.结论

IT 工具发展非常迅速。尽管如此,电子邮件仍然是任何一种交流方式的基础(或多或少有些复杂)。

此外,正如我们在本文中看到的,使用 Python 自动发送电子邮件极其简单。

我希望已经阐明了你的想法,并能够适当地综合任何需要。

为了其他的一切…让我们保持联系吧!

🤝 如有任何疑问、反馈或协作要求,请随时 联系我Linkedin。我会很高兴和你聊天!

👉要获得更多像这样的内容,并保持对即将到来的文章的更新,不要忘记 在 Medium 上关注我。

🙏如需参考本文,请联系我。谢谢你。

使用 Python 自动化 Excel

原文:https://towardsdatascience.com/automate-excel-with-python-7c0e8c7c6256?source=collection_archive---------0-----------------------

使用 PyWin32 实现自动化

用 Python 自动处理无聊的事情,腾出手来喝咖啡

照片由布里吉特·托姆在 Unsplash 上拍摄

大多数情况下,一个组织会有多个数据源,数据科学家或数据分析师必须在执行分析或创建模型之前,将不同数据源中的数据提取并编译到一个 Excel 文件中。如果我们手动执行,这将是一项复杂且耗时的任务。

用最著名的 Python 库pandas来做这件事会缩短时间,但是硬编码的 Excel 文件可能不会受到直接访问 Excel 文件的其他领域用户的青睐。因此,创建一个格式良好的交互式 Excel 文件将减轻领域用户的工作,并启发他们。

Excel 允许您以透明的方式处理数据,这意味着当打开 Excel 文件时,数据立即可见,并且数据处理的每个步骤也可见。—周红[1]

此外,Excel 很棒,因为我们可以看到报告是如何生成的,以及各列之间的关系。Excel 文件本身是不言自明的。而pandas生成的硬编码 Excel 文件不具备这些特性。

所以,这就是pywin32的用武之地。Pywin32 允许我们从 Python 访问 Microsoft Excel。我们可以通过pywin32访问 Excel 中的所有对象、方法和属性。(在此查看所有 Excel 对象、方法和属性。)

Excel VBA 参考

pywin32没有官方文档,所以我必须参考 Excel VBA 的官方文档来了解可用的对象、属性和方法。

截图来自微软文档

Excel 对象模型

对象、属性、方法和事件包含在 Excel 对象模型中*(我现在不处理事件,所以在本文中,我将只关注对象、属性和方法)*。下面的流程图说明了它们之间的关系。

作者创建的图像

我经常使用的一个对象是范围对象。区域是指 Excel 工作表中的单元格。Range 对象包含如下图所示的方法和属性。

截图来自微软文档

该文档包含 Excel VBA 的基本语法。幸运的是,将 Excel VBA 中的语法翻译成 Python 是很容易的。在我们进入示例之前,我们需要了解五个项目:

  • Excel 对象
  • Excel 对象方法
  • Excel 对象属性
  • Excel 常量
  • Excel 宏

Excel 对象

Excel 对象类似于 Python 类模块。

当我们想调用一个定义在类模块中的函数时,我们会调用类模块,后跟一个点,然后是函数名。我们需要导入 class 模块来使用它的函数,但是对于pywin32 模块来说,它已经导入了一切,所以我们可以直接调用任何 Excel 对象、方法和属性。

以下部分是对 Excel 对象、方法和属性的详细解释,并附有示例。为了提供更清晰的信息,该示例将使用由下面的脚本生成的 Excel 文件来运行。

  1. 定义创建 Excel 文件的函数
def create_test_excel_file(f_path: Path, f_name: str, sheet_name: str):

    filename = f_path / f_name
    random.seed(365)
    np.random.seed(365)
    number_of_data_rows = 1000

    # create list of 31 dates
    dates = pd.bdate_range(datetime(2019, 9, 1), freq='1d', periods=31).tolist()data = {'Date': [random.choice(dates) for _ in range(number_of_data_rows)],
            'Gender': [random.choice(['Female', 'Male']) for _ in range(number_of_data_rows)],
            'Products': [random.choice(['Shirts', 'Pants', 'Caps', 'Socks']) for _ in range(number_of_data_rows)],
            'Price': np.random.normal(15, 5, size=(1, number_of_data_rows))[0]}# create the dataframe and save it to Excel
    pd.DataFrame(data).to_excel(filename, index=False, sheet_name=sheet_name, float_format='%.2f')

2.定义参数并执行功能

# sheet name 
sheet_name = 'example'  # update with sheet name from your file
# file path
f_path = Path.cwd()  # file in current working directory
# f_path = Path(r'c:\...\Documents')  # file located somewhere else
# excel file name
f_name = 'example.xlsx'
create_test_excel_file(f_path, f_name, sheet_name)

为您创建的 Excel 文件的屏幕截图。

作者创建的图像

Excel 对象方法

Excel 对象模型中的方法与 Python 中的函数相同,都是可调用的,执行任务。用 python 编写函数应该总是以一对包含关键字参数的括号结束,如下面的 Python 脚本所示,函数greet以一对包含名为“name”的参数的括号结束。

# Python Functions:
# create a function
def greet(name):
    print(f"Hello {name}")greet(name = "Alisa")

下面的脚本显示了如何在 Excel 中使用一种方法,通过使用pywin32自动筛选。它与 Python 函数语法非常相似,除了我们不需要定义方法,我们将对象放在方法的前面,就像我们将类模块名称放在我们在类模块中定义的函数之前一样。(这里使用的 Excel 文件是前面章节创建的 Excel 文件。)

import pandas as pd
from pathlib import Path
import win32com.client as win32

f_path = Path.cwd() # change to the path to the Excel file
f_name = 'example.xlsx' # Excel File name
filename = f_path/f_name
sheetname = 'example' # change to the name of the worksheet

# create Excel object
excel = win32.gencache.EnsureDispatch('Excel.Application')
# excel can be visible or not
excel.Visible = True 
# open Excel Workbook   
wb = excel.Workbooks.Open(filename)# create filter in Excel Worksheet
wb.Sheets(sheetname).Range("A1").AutoFilter(Field = 2, Criteria1="Female", VisibleDropDown=False)

在上面的例子中,wb.Sheets(sheetname).Range(“A1”)是指对象,AutoFilter()是方法,Field = 2, Criteria1="Female", VisibleDropDown=False是参数。字段是指要筛选的列。Field = 2指左数第二列,即 B 列['性别']。该脚本的结果如下图所示,数据根据“性别”过滤,当我们将标准设置为女性时,仅显示“女性”记录。

作者创建的图像

将 Excel VBA 写入 Python 的标准语法是以这种方式组织代码:

对象。方法(参数=参数)

当您查看 Excel VBA 文档时,总会有一些如下的脚本示例(下面的脚本是根据上面提到的 Excel VBA 参考中的示例修改的)。

Worksheets("Sheet1").Range("A1").AutoFilter _
 Field:=2, _
 Criteria1:="Female", _
 VisibleDropDown:=False

Excel VBA 和 Python 的语法只有微小的区别,其中 Excel VBA 不保存括号中的参数,而在 Python 中,我们必须创建 Excel 对象并显式定义工作簿路径和名称。因此,从 Excel VBA 转换到 Python 是可能且容易的。

Excel 对象属性

Excel 对象模型中的属性与 Python 中的变量相同,不可调用,只返回赋值。例如,Excel 表中某列的列宽是用来存储该列的列宽的属性。另一个例子,Excel 表中单元格的值。你可以把它想象成一个变量,你可以改变它的值,就像你在 python 中改变变量的值一样。

# Python Variable: 
# assign a value to a variable
x = 5
# change the value assigned to the variable
x = 6

上面显示了如何在 Python 中更新变量值的简单示例。下面的脚本展示了如何使用pywin32来更新 Excel 中单元格的值。

import pandas as pd
from pathlib import Path
import win32com.client as win32
import datetime
today = datetime.date.today()f_path = Path.cwd() # change to the path to the Excel file
f_name = 'example.xlsx' # Excel File name
filename = f_path/f_name
sheetname = 'example' # change to the name of the worksheet

# create Excel object
excel = win32.gencache.EnsureDispatch('Excel.Application')
# excel can be visible or not
excel.Visible = True 
# open Excel Workbook   
wb = excel.Workbooks.Open(filename)# update value in Excel Worksheet
wb.Sheets(sheetname).Range("F1").Value = f"Today date: {today}"

在上面的例子中,wb.Sheets(sheetname).Range(“F1”)指的是对象,Value是属性,而f”Today date: {today}”是分配给对象的值。简而言之,我们将一个值放入一个单元格中。当我们用 Python 编写脚本时,我们可以应用一些 Python 脚本。在这种情况下,使用 f 字符串。下图显示了脚本的结果。

作者创建的图像

当我运行这个脚本时,从前面的脚本创建的过滤器没有被清除,所以过滤器仍然在文件中。清除过滤器的方法将在下一节中解释。

将 Excel VBA 写入 Python 的标准语法是以这种方式组织代码:

对象。属性=值

下面是根据 Excel VBA 参考修改的脚本。

Worksheets("Sheet1").Range("F1").Value = "2021-05-13"

对于属性,Excel VBA 中的语法在大多数情况下与 Python 中的语法相同。当要分配的值是 Excel 常量时,语法会稍有不同。

Excel 常数

一些对象方法和属性只接受常量列表作为它们的参数。Excel 常量通常以“xl”开头。在这种情况下,我们必须在使用 Python 时导入常量(在使用 Excel VBA 时这是不必要的)。

import pandas as pd
from pathlib import Path
import win32com.client as win32
**win32c = win32.constants**f_path = Path.cwd() # change to the path to the Excel file
f_name = 'example.xlsx' # Excel File name
filename = f_path/f_name
sheetname = 'example' # change to the name of the worksheet

# create Excel object
excel = win32.gencache.EnsureDispatch('Excel.Application')
# excel can be visible or not
excel.Visible = True 
# open Excel Workbook   
wb = excel.Workbooks.Open(filename)# set cell horizontal alignment
wb.Worksheets("example").Columns("A:D").HorizontalAlignment = **win32c**.xlLeft

在上面的例子中,赋值为xlLeft,因为它是 Excel 常量,我们必须在常量前面添加 win32c (因为我将win32.constants保存为 win32c)。上面脚本的结果如下图所示。

作者创建的图像

标题的水平对齐方式是居中,现在向左对齐。

将 Excel VBA 写入 Python 的标准语法是以这种方式组织代码:

对象。Property = win32c。ExcelConstant

Excel 宏

pywin32 的语法类似于将 Excel VBA 翻译成 Python 语法。因此,您可以随时参考 Excel VBA 文档,了解 Excel 中可用的对象、方法和属性。当文档不够时,您可以简单地记录特定过程的宏并参考步骤信息。

在我的工作中,我使用 Excel 宏来获取特定列的字体颜色(*expression*.Columns.Font.Color)和单元格填充颜色(*expression*.Columns.Interior.Color)的颜色代码。

作者创建的 GIF

在上面的 GIF 中,255 代表红色的颜色代码,我们可以在 Python 脚本中使用它来改变单元格的颜色。

当我们不确定在某种情况下使用哪些方法或属性时,我们总是可以记录 Excel 宏。

例子

在这一节中,我将分享我经常使用的方法和属性。与上面的例子一样,在运行任何执行 excel 方法或修改 Excel 属性的脚本之前,我们需要导入库并创建 Excel 对象。以下示例中使用的 Excel 文件仍然是我们在前面部分创建的文件。

import pandas as pd
from pathlib import Path
import win32com.client as win32
win32c = win32.constantsf_path = Path.cwd() # change to the path to the Excel file
f_name = 'example.xlsx' # Excel File name
filename = f_path/f_name
sheetname = 'example' # change to the name of the worksheet

# create Excel object
excel = win32.gencache.EnsureDispatch('Excel.Application')
# excel can be visible or not
excel.Visible = True 
# open Excel Workbook   
wb = excel.Workbooks.Open(filename)

方法

  1. 自动滤镜

向每列添加筛选器。

wb.Sheets(sheetname).Range("A1").AutoFilter(Field = 1)

2。自动调整

根据单词长度调整列宽。

wb.Sheets(sheetname).Columns("A:I").AutoFit()

3。复制

将单元格区域的值复制到另一个位置。

wb.Sheets(sheetname2).Range("A1:E10").Copy(Destination = wb.Sheets(sheetname).Range("F1"))

4。复制+选择性粘贴

将一个工作表的格式复制到另一个工作表。

# copy paste FORMAT only, which include font colour, fill colour, and border
wb2.Sheets(sheetname).Range("A:D").Copy()
wb.Sheets(sheetname).Range("A1").PasteSpecial(Paste=win32c.xlPasteFormats)

5。向下填充(向左填充、向右填充、向上填充)

将公式填入单元格区域。例如,从单元格 A2 填充到 A1000,如下面的脚本所示。

wb.Sheets(sheetname).Range("A2:A1000").FillDown()

6。插入

通过向下移动原始列*(到后面的索引,例如,从 C 列到 D 列)*插入新列。

# insert a new row by shifting the original row down
wb.Sheets(sheetname).Rows("1:2").Insert(win32c.xlShiftDown)

性能

  1. 列宽

调整列宽。

wb.Sheets(sheetname).Columns("A").ColumnWidth = 10

2。字体/内部颜色

字体包含更多属性,例如字体颜色、字体大小和字体名称。

分配颜色有两种方法,颜色代码和颜色索引。对于颜色代码,它是一个很长的数字,只能通过查阅 Excel 宏步骤信息来获得。而对于颜色索引,您可以在 Excel 中创建一个颜色表,并找到您想要的颜色索引。

wb.Worksheets(sheetname).Columns("K:K").Font.Color = -4165632
wb.Worksheets("sheetname").Columns("K:K").Interior.Color = 10092492

3。公式

将公式分配给单元格。

wb.Sheets(sheetname).Range(f"{column_insert}2").Formula = "=A2+B2"# if you wish to create a function
column1 = "A"
column2 = "B"
operation = "+" # math operation to perform between 2 columnsdef math_op(column1, column2, operation):
  wb.Sheets(sheetname).Range(f"{column_insert}2").Formula =   f"={column1}2{operation}{column2}2"math_op(column1, column2, operation)

{column1}{operation}之间的‘2’,{column2}后的‘2’表示第 2 行。

4。水平对齐

调整单元格水平对齐。对准有三种类型,分别是xlLeftxlCenterxlRight

wb.Worksheets("sheetname").Rows("1:1").HorizontalAlignment = win32c.xlLeft

5。数字格式

设置数值的格式。对于NumberFormat值,可以通过 Excel 宏获取。

wb.Worksheets("sheetname").Columns("O:O").NumberFormat= '_("$"* #,##0_);_("$"* (#,##0);_("$"* "-"_);_([@_](http://twitter.com/_))'

结论

Pywin32 允许我们像手工一样设置 Excel 报表。我们可以用引用单元格设置公式(例如:O2 = P2+Q2),创建数据透视表,设置单元格格式(例如:单元格颜色、字体颜色、列宽等)。),设置滤镜等等。

我们可以通过pywin32自动生成定期生成的格式报告。我们只需在 Python 脚本中创建所有方法或设置属性一次。

此外,我们可以扩大这种自动化。例如,我们可能需要在完成后通过电子邮件发送这份 Excel 报告。我们可以简单地添加脚本的另一行来发送报告。

最后,每当你进退两难时,记住 Python pywin32 的标准语法如下。

对象。方法(参数= 参数

对象。属性=值

对象。Property = win32c。ExcelConstant

如果您是一个视频爱好者,这里有一个视频,介绍了您应该知道的使用 PyWin32 库自动生成 Excel 报表的关键概念。

保持联系

在 YouTube 上订阅

一些旁注

如果您有兴趣了解如何自动化创建数据透视表并从数据透视表中提取过滤后的数据到 pandas DataFrame ,用 Python 自动化数据透视表(创建、过滤和提取)。

如果你有兴趣用 Python 创建图表或数据透视图,并自动导出为图像,那么用 Python 自动化 Excel 图表。

如果你的工作使用的是 Google Sheet 而不是 Microsoft Excel,你可以参考这篇文章,“自动化 Google Sheet Report ”来了解可能的自动化。

如果你有兴趣知道如何使用pywin32访问 Microsoft Outlook 邮件和下载附件,你可以参考这篇文章“用 Python 自动下载邮件附件”。

文献学

[1] H .周,通过 Excel 学习数据挖掘:理解机器学习方法的逐步方法,纽约:新闻媒体,2020 .

[2] 如何用 Python win32com 模块在 Excel 中创建数据透视表 —用 Python 在 Excel 中创建数据透视表的完整示例。

[3] Excel VBA 参考 —关于 Microsoft Excel 中的对象、方法、属性和事件的完整参考。

祝贺并感谢你阅读到最后。希望你喜欢这篇文章。 ☺️

Caleb Chen 在 Unsplash 上拍摄的照片

使用 Python 自动化数据透视表(创建、过滤和提取)

原文:https://towardsdatascience.com/automate-excel-with-python-pivot-table-899eab993966?source=collection_archive---------1-----------------------

使用 PyWin32 实现自动化

自动化数据透视表并从过滤后的数据透视表中提取数据。省点时间喝杯茶吧。

黄茉莉在 Unsplash 上的照片

在使用 Python 自动化 Excel中,包含对象、属性、方法和事件的 Excel 对象模型的概念是共享的。用 Python pywin32 库访问 Excel 中的对象、属性和方法的技巧也用例子进行了解释。

现在,让我们用透视表来利用 Excel 报表的自动化,这是 Excel 中最精彩的功能之一!

为什么选择 PyWin32?

你可能会好奇为什么我们不用pandas 库中的pandas.DataFrame.pivotpandas.DataFrame.pivot_table来代替呢?这是一个内置的库,我们甚至不需要安装它。

嗯,上面提到的两个pandas函数可以很容易地创建数据透视表,但是如果你正在准备一个其他域用户可以访问的 Excel 报表,创建的硬编码数据透视表可能不适合他们,因为他们不能修改数据透视表字段。

数据透视表字段。图片作者。

上图显示了 Excel 中数据透视表的数据透视表字段,数据透视表根据游戏类型显示了不同地区的视频游戏销售额。使用交互式 Excel 数据透视表,领域用户可以自由选择任意数量的国家显示在数据透视表中,而由pandas创建的硬编码数据透视表不能这样做。

在下面的例子中,使用的数据集是来自 Kaggle 的 PS4 游戏销售数据。那么,用来创建数据透视表的脚本就是参考 Trenton McKinney 创建的笔记本,如何用 Python win32com 模块在 Excel 中创建数据透视表。在 McKinney 的笔记本中,他定义了用 Python 创建综合数据、数据透视表和 Excel com 对象的函数(他还展示了如何用 Excel VBA 实现)。

他很好地优化了脚本,因此,在下面的例子中,McKinney 的脚本将用于在 Excel 中创建数据透视表。然后,我将解释如何访问数据透视表的组件,修改数据透视表的过滤器,并使用 Python 提取过滤后的数据以供进一步分析。

为了更清楚地描述我们在下面的例子中要做的事情,让我解释一下这个例子的输入和输出。输入是 CSV 格式的 PS4 游戏销售额,如下图所示。

数据快照。作者创建的图像。

这些属性包括游戏的名称、出版年份、游戏类型、出版商以及游戏在北美、欧洲、日本、世界其他地区的销量和全球销量。基于这些数据,我们将创建一个数据透视表,根据游戏类型来展示 PS4 游戏在每个地区的总销售额。下图显示了我们将使用 Python pywin32库创建的数据透视表。

在 Excel 中创建的数据透视表。作者创建的图像。

创建数据透视表并用 pywin32 操作它

以下部分有五个部分:

  1. 导入库
  2. 读取和处理数据集
  3. 创建数据透视表
  4. 访问数据透视表的方法和属性
  5. 修改数据透视表的过滤器并提取过滤后的数据

导入库

import win32com.client as win32
import pandas as pd
import numpy as np
from pathlib import Path
import re
import sys
win32c = win32.constants

读取和处理数据集

df = pd.read_csv("PS4_GamesSales.csv", encoding = 'unicode_escape', engine ='python')# remove null values
df = df.dropna()# write the csv file to xlsx File to create Pivot Table
df.to_excel("PS4_GamesSales.xlsx", sheet_name = 'Sales', index = False)

由于数据集中存在特殊字符,在读取 CSV 文件时需要定义encoding 。有兴趣的话,这里有编码的参考。

需要注意的一点是,当我们导出以后要用来创建透视表的数据时,我们必须设置index = False。如果没有,我们可能会在创建数据透视表时遇到问题,因为该函数无法判断哪一行是标签行还是标题行。

创建数据透视表

创建数据透视表的脚本修改自 McKinney 的笔记本。脚本包含三个函数,分别是 pivot_table()run_excel()main()

pivot_table()函数用于将数据字段分配到各自的透视表字段中(过滤器、列、行和值)。

该函数的最后一部分用于修改 Excel 对象模型的透视表对象的属性“行总计”和“列总计”值的可见性,其他属性请参见此处的。

下一个功能是run_excel()。该函数用于创建 Excel 对象,然后为透视表创建新的工作表。将添加到数据透视表字段的数据字段(筛选器、列、行和值)将在此定义。

透视表创建后,wb.Save()将保存 Excel 文件。如果不包含这一行,创建的数据透视表将会丢失。如果您正在运行此脚本以在后台或计划的作业中创建数据透视表,您可能希望分别通过wb.Close(True)excel.Quit()关闭 Excel 文件并退出 Excel 对象。这样,您就不需要在作业完成后手动关闭 Excel 文件。或者,您可以设置excel.Visible = False,那么 Excel 文件将不会从头开始打开。

main()函数为主函数,它会调用run_excel()函数,然后run_excel()函数会执行pivot_table()函数。

如果您运行该函数两次,将会出现错误,因为数据透视表被编程为在名为“pivot_table”的工作表中创建,而该工作表已在第一次运行中创建,您可以更改 pt_name 或删除在第一次执行中创建的工作表。

错误消息。作者创建的图像。

访问数据透视表的属性

可以通过操作数据透视表对象(数据透视表对象引用)的两个方法和五个属性来研究或修改数据透视表:

方法

  1. 清除所有过滤器
  2. 透视项目

性能

  1. 当前页面(分组在数据透视字段对象下)
  2. 页面范围
  3. 行字段
  4. 列字段
  5. 表格范围 1

数据透视表的属性。作者创建的图像。

上图显示了数据透视表的 CurrentPage、PageRange 和 TableRange1。数据透视表字段的行字段和列字段如下图所示。

数据透视表属性。作者创建的图像。

上面提到的数据透视表方法和属性将在示例中使用,以提取过滤后的数据透视表的数据并保存到 DataFrame 中。

首先,创建 Excel 对象。虽然 Excel 对象是在创建数据透视表的过程中创建的,但我们仍然需要再次创建它,因为 Excel 对象是在函数中创建的,不能结转。

f_path = Path.cwd()
f_name = 'PS4_GamesSales.xlsx'
filename = f_path / f_name
# create excel object
excel = win32.gencache.EnsureDispatch('Excel.Application')# excel can be visible or not
excel.Visible = True  # False
wb = excel.Workbooks.Open(filename)  
pvtTable = wb.Sheets("pivot_table").Range("A3").PivotTable

页面范围和当前页面属性,清除所有过滤器方法

页范围指的是透视表的筛选字段(字段名和值),如下图所示。

PageRange 和 CurrentPage。作者创建的图像。

CurrentPage 是指过滤器的值,用于设置一个过滤器的值,而 Page Range 返回当前过滤器及其值。

下面的脚本打印页面范围,然后清除所有过滤器。

page_range_item = []
for i in pvtTable.PageRange:
    page_range_item.append(str(i))

print(page_range_item)pvtTable.PivotFields("Year").ClearAllFilters()

为了提供更清晰的信息,下面的 GIF 显示了运行上面脚本的结果。我在开始时手动设置过滤器,然后打印页面范围。之后,脚本清除了所有过滤器,然后再次打印页面范围。GIF 还展示了pywin32有多棒,因为我们可以立即看到对 Excel 的更改

作者创建的 GIF。

pvtTable.PivotFields("Year").CurrentPage = "2020"
page_range_item = []
for i in pvtTable.PageRange:
    page_range_item.append(str(i))

print(page_range_item)

现在,让我们使用当前页面的透视字段属性来修改过滤器。

作者创建的 GIF。

因为我们必须在修改当前页面时指定 Pivot 字段,所以它只能用于一次修改一个过滤器的值。

在本例中,我们仅使用一个值进行过滤。过滤多个值的方法显示在最后一个示例中,这也是修改数据透视表过滤器然后提取过滤数据的完整示例。

行字段/列字段

行字段和列字段将列出创建透视表时透视表字段中添加到行字段或列字段的所有字段。

row_fields_item = []
for i in pvtTable.RowFields:
    row_fields_item.append(str(i))

print(row_fields_item)column_fields_item = []
for i in pvtTable.ColumnFields:
    column_fields_item.append(str(i))

print(column_fields_item)

在我们的例子中,行字段是“类型”,而列字段是自动生成的“值”。但是,我们可以用下面的脚本禁用它。

wb.Sheets("pivot_table").PivotTables("example").DisplayFieldCaptions = False

下面的 GIF 说明了上面脚本的结果。

作者创建的 GIF。

“值”和“行标签”是字段标题,而不是数据字段。脚本与下面的操作相同。

作者创建的 GIF。

表格范围 1

TableRange1 打印不带页范围的数据,如果还想打印页字段,可以参考透视表的 TableRange2 属性。

table_data = []
for i in pvtTable.TableRange1:
    #print(i)
    table_data.append(str(i))

print(table_data)

表区域 1 属性以列表形式返回结果。

要将列表转换成数据帧,我们需要知道数据透视表的实际维度。通过在创建透视表的脚本中添加pt_fields并为行项目的列添加 1,可以很容易地确定列的数量。在本例中,pt_fields中有五个项目,“北美总销售额”、“欧洲总销售额”、“日本总销售额”、“世界其他地区总销售额”、“全球总销售额”。所以有了number of columns = 5 + 1 = 6

复杂的部分是确定行数。在本文的示例中,有三行是根据列字段标题(“值”)、数据透视表字段行(“北美总销售额”、“欧洲总销售额”、“日本总销售额”、“世界其他地区总销售额”、“全球总销售额”)和列的总计构建的。其他行是经过过滤后的行字段中的项。****

我通过使用 RegEx 删除列字段(" Values ")和pt_fields项、其他标签(如"行标签"、"列标签"、"总计"和"无")以及数据透视表中的所有数值,获得了行字段中的项数。

在获得数据透视表的列数和行数之后,可以将表范围 1 中的列表整形为 DataFrame。

将列表重塑为作者创建的数据帧图像。

在这个阶段,数据帧不能检测到正确的标题,即表格的第二行。因此,我们将第二行(row index = 1)设置为 header,然后删除前两行。有多种方法可以做到这一点,您可以重命名该列,然后删除前两行。

df.columns=df.iloc[1]
df = df.drop(index = 0)
df = df.drop(index = 1)

修改数据透视表的过滤器并提取过滤后的数据

现在,让我们将所有内容结合起来,根据条目列表修改过滤器,然后提取过滤后的数据透视表数据并将其保存为 DataFrame。

# Find all items in Year
year_items = []
for item in pvtTable.PivotFields("Year").PivotItems():
    year = str(item)
    year_items.append(year)year_to_include = ['2013','2014','2015']
year_to_exclude = [x for x in year_items if x not in year_to_include]

在我们修改过滤器之前,知道过滤器中包含的项目的确切数量是很重要的。在我们的例子中,过滤器是“年”。这一步可以通过使用 Pivot Table 方法来完成,Pivot Items()如上面的脚本所示。

下面是修改过滤器的完整函数,然后将过滤后的数据透视表提取为 DataFrame。

让我们在下面的 GIF 中见证这一点。

作者创建的 GIF

额外收获:创建不同数据透视表的多个工作表

收到关于如何创建不同数据透视表的多个工作表的询问。我们可以修改run_excel()函数来实现。

我们只需要复制脚本中设置和调用pivot_table()函数的部分。记得根据需要修改细节。最重要的是,我们需要更改保存新工作表标题和新工作表对象的变量名。如果没有,您可能想知道为什么在工作簿中只创建了一个数据透视表。😂我在下面的代码中加粗了您可能需要注意的变量名。

# Setup second pivot table and call pivot_table**ws3_name** = 'pivot_table_2'
wb.Sheets.Add().Name = **ws3_name**
**ws3** = wb.Sheets(**ws3_name**)pt_name = 'example'  # must be a string
pt_rows = ['expense']  # must be a list
pt_cols = ['products']  # must be a list
pt_filters = ['date']  # must be a list# [0]: field name [1]: pivot table column name [3]: calulation method [4]: number format
pt_fields = [['price', 'price: mean', win32c.xlAverage, '$#,##0.00']]  # must be a list of listspivot_table(wb, ws1, **ws3**, **ws3_name**, pt_name, pt_rows, pt_cols, pt_filters, pt_fields)

谢谢你读到这里,这是我知道的一篇长文。这之后还有一点,如果你想在工作中使用pywin32,这是必不可少的。

你可能面临的错误

错误。作者图片

在执行创建数据透视表的脚本时,我遇到过几次这样的错误。幸运的是,我在栈溢出上找到了解决方案。解决办法很简单。我们只需要删除下面脚本返回的路径中的文件夹标题“00020813–0000–0000–C000–00000000046 x 0x 1 x 9”。

import win32com
print(win32com.__gen_path__)

由于这是一个周期性(不是每天)出现的重复问题,我建议您运行以下脚本,在显示错误时直接删除文件夹。

import win32com
import shutil
path = win32com.__gen_path__
shutil.rmtree(path)

边注

如果你对 Excel 对象模型的对象、方法和属性感到困惑,或者想知道如何将 Excel VBA 的脚本翻译成 Python,可以看看用 Python 自动化 Excel。

如果您有兴趣使用 Python 创建图表或数据透视图,并将其自动导出为图像,请使用 Python 自动制作 Excel 图表。

如果你有兴趣知道如何使用pywin32访问 Microsoft Outlook 邮件和下载附件,你可以参考这篇文章“用 Python 自动下载邮件附件”。

如果您的工作使用 Google Sheet 而不是 Microsoft Excel,您可以参考这篇文章“自动化 Google Sheet Report”以了解可能的自动化。

保持联系

在 YouTube上订阅

参考

  1. 如何用 Python win32com 模块在 Excel 中创建透视表
  2. Excel VBA 参考

祝贺并感谢你阅读到最后。希望你喜欢这篇文章。 ☺️

亚历山大·莱多戈罗夫在 Unsplash 上的照片

5 分钟内自动完成谷歌表单报告

原文:https://towardsdatascience.com/automate-google-sheet-reporting-in-5-minutes-8bbdc1f8e293?source=collection_archive---------6-----------------------

每月自动将报告发送给你的老板,无需担心

照片由来自佩克斯的塔林·埃利奥特拍摄

您是否曾经使用 google sheets 收集数据,与您组织中的每个人共享这些数据,以便输入他们的每周、每月数据,如绩效报告、库存报告或 KPI 数据报告?之后,你将不得不每月提取数据来进行编译。

如果这些重复的行为可以自动化,并且最终报告可以每月通过电子邮件发送给相关人员(比如你的老板),那该有多好?是的,这篇文章可以帮助你实现这个目标!

自动化流程的图示。作者图片

场景:贵公司希望每月有一定数量的客户在贵公司的 40 多家零售店中查询特定产品的信息。

1.数据收集和报告生成

根据您的偏好设置您的数据收集表,例如,下图:

数据收集电子表格。作者图片

注意,最后一行是用户输入的最新数据,它是使用 google sheet 公式捕获的,如下所示:

=INDEX(B1:B13,Max(MATCH("zzz",B1:B13),Match(143^143,B1:B13)))

此公式自动捕获用户在特定区域(在本例中为列)的最新输入,公式中的数据用于绘制下图:

报告中所需的图表。作者图片

在这一步结束时,您已经有了最新的报告和每月报告的图表。

2.设置 Google 应用程序脚本

设置 Google 企业应用套件脚本。作者图片

进入工具脚本编辑器打开并授权 Google Apps 脚本,你会注意到一个名为 Code.gs 的文件在你屏幕的左侧,代码区在你屏幕的右侧。

Google Apps 脚本的接口。作者图片

将以下代码粘贴到内部:

function sendEmails() {// Get the sheet where the data is, in sheet 'system'
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1")// Get the data of particular cell, in this case, i need only the total cell (F14)
var data = sheet.getRange('F14').getValues();// Get all the chart in the sheets
const chartBlobs = new Array();
const emailImages = {};
const charts = sheet.getCharts();
charts.forEach(function(chart, i){
chartBlobs[i] = chart.getAs("image/png");
emailImages["chart"+i] = chartBlobs[i];
});// Send email
MailApp.sendEmail({
to: "you@gmail.com,"yourboss@gmail.com"",
subject: "Customer Enquiries as of " + new Date(),
htmlBody: "Customer Enquiries Data: <br>" +
"Total: " + data + "<br>",
inlineImages:emailImages
});
}

通过保存并单击顶部的 Run 按钮来测试代码。您将收到一封电子邮件,如下所示:

电子邮件报告。作者图片

根据您的偏好定制您的报告,并使其符合您组织的格式。

3.安排每月电子邮件

太好了,现在你有一个很好的报告生成功能,可以在你按下时触发。接下来,我们将设置爆破功能的触发器。Google App Script 根据用户需求提供了几种类型的触发器,分别是:

  • 事件驱动,如表单被编辑、打开或表单提交
  • 时间驱动、每小时、每周或每月
  • 按日期排列的日历

功能触发。作者图片

在我的情况下,我希望有一个每月计时器,它将在每月 6 日自动触发该功能(如下图),因为我已经告诉所有分行经理在每月 4 日前更新信息。

设置我的每月功能触发器。作者图片

最后,保存触发器,你就有了你的自动邮件报告系统,它将在 5 分钟内每月发送给你的老板,而不需要任何额外的步骤!

https://medium . com/geek culture/never-miss-your-customers-birthday-email-with Google-sheets-d64e 75372341

最后的话:

我经常发现,由于缺乏知识,在大多数组织中,资源被花费在可以自动化的任务上。因此,我决定在接下来的文章中写更多对组织有益的生产力技巧,这将包括使用多种编码语言,如 pythons 和 Google Apps 脚本。

我的其他生产力文章:

https://medium.com/geekculture/never-miss-your-customers-birthday-email-with-google-sheets-d64e75372341

最后,感谢您花时间阅读我的文章!

参考资料:

[## 使用 Python 自动化 Excel

towardsdatascience.com](/automate-excel-with-python-7c0e8c7c6256) https://aryanirani123.medium.com/send-charts-in-email-using-google-apps-script-d652dc752468 https://www.benlcollins.com/apps-script/google-apps-script-beginner-guide/

针对具有远视的多个模型的自动超参数调整

原文:https://towardsdatascience.com/automate-hyperparameter-tuning-with-hyperopts-for-multiple-models-22b499298a8a?source=collection_archive---------18-----------------------

犯错是人之常情,随机犯错在统计学上是神圣的

由 Unsplash 上的 Katarzyna Pe 拍摄

在我以前的博客中,我讨论了如何创建一个定制的 sklearn 转换器来自动化数据处理。如果你还没看过那篇文章,你可以在这里看看。让我们向前行驶吧!

本文将创建一个自动化的超参数调优模块,它与 sklearn 的 transformer 管道协同工作。我将在这个过程中使用远视。

Hyperopt 被设计为适应基于高斯过程和回归树的贝叶斯优化算法。

总之是一定要比 Sklearn 的原生版 GridSearchCV 快。

资料组

如果我的第一篇文章是 TL;博士,我找到你了!

数据帧头

我实现的转换后的管道会处理丢失的值、异常值整理任务和规范化。简而言之,一旦您 fit_transform ,您的数据就为模型训练做好了准备!

定义搜索空间

现在,你知道超参数(你当然知道!这就是你在这里的原因!).任何最大似然优化函数将试图最小化在某些模型参数上定义的损失函数。但是,这并没有改变算法本身的框架。我们在超参数的帮助下实现了这一点!简单。

第一步是定义一个 搜索空间 。简单地说,列出你的模型应该迭代的所有可能的超参数范围。例如,我已经为我将要考虑的 6 种不同算法定义了搜索空间。它们是:

  • KNearestNeighbors 基于实例
  • 逻辑回归—线性算法
  • SVC —基于内核
  • XGBClassifier —增强集成
  • QDA:基于歧视

同样,你可以插入任何与 sklearn API :p 兼容的型号

搜索空间定义

我选择了这些算法来涵盖主要类型。他们不打算赢得卡格尔比赛!

如何选择包含哪个参数?

答案是,这完全取决于您和您的用例。所以,我建议你了解这些算法是如何工作的,以及它们重要的可控参数。

注意:有一个特定的符号来定义搜索空间。它应该解决管道中步骤的顺序问题。例如,我们的模型管道(见下文)被标记为'模型,'制作我们的符号'模型 _ _ 参数名称。'同样,如果您将管道命名为'clf,'它将是'clf _ _ param _ name'

远视者的骨骼

远视有两个基本组成部分:

  1. 我们有一个试图优化的 optimize()函数:P

定义目标函数

2.我们有 fmin 函数,它将使用搜索空间中定义的一组超参数迭代调用优化函数。

定义控制器功能

这是仅有的两个基本步骤。如果你想了解更多关于远视,请随时查看他们的网页。(或者,谷歌一下)

就差一句台词了!

我们通过这个简单的访问从我们的小实验中获得了最好的模型:

best_params['model']SVC(C=0.15499999999999997, degree=2, gamma=391.91004869541047)

最后,我们检查我们的分类报告。

模型验证

就是这样!!现在,为您的用例即插即用您的模型。建议广泛研究你的超参数!!

结论

本文粗略浏览了使用超点为多个模型创建自动化超参数调优。我们已经使用 Sklearn 的 transformer 管道在一个步骤中预处理数据。由于 hyperopts 是模型不可知的,我们可以通过定义目标函数和控制器 fmin 函数来即插即用任何具有交叉验证和参数装饰的模型。很简单!

点击 可以访问 的完整代码。

布雷特·乔丹在 Unsplash 上拍摄的照片

作者不是蝙蝠侠!

感谢您的支持!希望有帮助:)

如果你想得到一些想法,你可以通过 Linkedin 联系我!

使用 Python 自动化 Microsoft Excel 和 Word

原文:https://towardsdatascience.com/automate-microsoft-excel-and-word-using-python-4244c613f818?source=collection_archive---------1-----------------------

将 Excel 与 Word 集成,无缝生成自动化报告

艾萨克·史密斯在 Unsplash 上拍摄的照片

毫无疑问,微软的 Excel 和 Word 是公司和非公司领域使用最广泛的两个软件。它们实际上是“工作”这个术语本身的同义词。通常,没有一个星期我们不把这两者结合起来,并以这样或那样的方式利用它们的优点。虽然对于一般的日常目的来说,不会要求自动化,但有时自动化是必要的。也就是说,当您有大量的图表、数字、表格和报告要生成时,如果您选择手动方式,这可能会成为一项非常乏味的工作。嗯,不一定非要那样。事实上,有一种方法可以在 Python 中创建一个管道,您可以无缝地将两者集成在一起,在 Excel 中生成电子表格,然后将结果传输到 Word 中,几乎即时生成报告。

Openpyxl

认识一下 Openpyxl,它可以说是 Python 中最通用的绑定之一,它使得与 Excel 的交互简直就像在公园里散步。有了它,您可以读写所有当前和传统的 excel 格式,即 xlsx 和 xls。Openpyxl 允许你填充行和列,执行公式,创建 2D 和 3D 图表,标记轴和标题,以及大量其他可以派上用场的功能。然而,最重要的是,这个包使您能够在 Excel 中迭代无数的行和列,从而将您从以前必须做的所有讨厌的数字计算和绘图中解救出来。

Python-docx

然后出现了 Python-docx——这个包对于 Word 就像 Openpyxl 对于 Excel 一样。如果你还没有研究过他们的文档,那么你或许应该看一看。毫不夸张地说,自从我开始使用 Python 以来,Python-docx 是我使用过的最简单、最容易理解的工具包之一。它允许您通过自动插入文本、填写表格和将图像渲染到您的报告中来自动生成文档,而没有任何开销。

事不宜迟,让我们创建自己的自动化管道。继续启动 Anaconda(或您选择的任何其他 IDE)并安装以下软件包:

pip install openpyxlpip install python-docx

Microsoft Excel 自动化

首先,我们将加载一个已经创建的 Excel 工作簿(如下所示):

workbook = xl.load_workbook('Book1.xlsx')
sheet_1 = workbook['Sheet1']

图片由作者提供。

随后,我们将迭代电子表格中的所有行,通过将电流乘以电压来计算并插入功率值:

for row in range(2, sheet_1.max_row + 1):
    current = sheet_1.cell(row, 2)
    voltage = sheet_1.cell(row, 3)
    power = float(current.value) * float(voltage.value)
    power_cell = sheet_1.cell(row, 1)
    power_cell.value = power

完成后,我们将使用功率的计算值来生成一个折线图,该折线图将插入到指定的单元格中,如下所示:

values = Reference(sheet_1, min_row = 2, max_row = sheet_1.max_row, min_col = 1, max_col = 1)
chart = LineChart()
chart.y_axis.title = 'Power'
chart.x_axis.title = 'Index'
chart.add_data(values)
sheet_1.add_chart(chart, 'e2') 
workbook.save('Book1.xlsx')

自动生成的 Excel 电子表格。图片由作者提供。

提取图表

现在我们已经生成了图表,我们需要将其提取为图像,以便在 Word 报告中使用。首先,我们将声明 Excel 文件的确切位置,以及输出图表图像应该保存的位置:

input_file = "C:/Users/.../Book1.xlsx"
output_image = "C:/Users/.../chart.png"

然后使用以下方法访问电子表格:

operation = win32com.client.Dispatch("Excel.Application")
operation.Visible = 0
operation.DisplayAlerts = 0
workbook_2 = operation.Workbooks.Open(input_file)
sheet_2 = operation.Sheets(1)

随后,您可以迭代电子表格中的所有图表对象(如果有多个图表对象),并将它们保存在指定位置,如下所示:

for x, chart in enumerate(sheet_2.Shapes):
    chart.Copy()
    image = ImageGrab.grabclipboard()
    image.save(output_image, 'png')
    passworkbook_2.Close(True)
operation.Quit()

Microsoft Word 自动化

现在我们已经生成了图表图像,我们必须创建一个模板文档,它基本上是一个普通的 Microsoft Word 文档。docx)完全按照我们希望的方式来制定我们的报告,包括字体、字体大小、格式和页面结构。然后,我们需要做的就是为我们的自动化内容创建占位符,即表格值和图像,并用变量名声明它们,如下所示。

Microsoft Word 文档模板。图片由作者提供。

任何自动化内容都可以在一对双花括号{{ variable_name }}中声明,包括文本和图像。对于表,您需要创建一个包含所有列的带有模板行的表,然后您需要用下面的符号在上面和下面各添加一行:

第一排:

{%tr for item in *variable_name* %}

最后一排:

{%tr endfor %}

在上图中,变量名为

  • table_contents 用于存储表格数据的 Python 字典
  • 字典关键字的索引(第一列)
  • 字典值的功率、电流和电压(第二、第三和第四列)

然后,我们将模板文档导入 Python,并创建一个存储表值的字典:

template = DocxTemplate('template.docx')
table_contents = []for i in range(2, sheet_1.max_row + 1):
    table_contents.append({
        'Index': i-1,
        'Power': sheet_1.cell(i, 1).value,
        'Current': sheet_1.cell(i, 2).value,
        'Voltage': sheet_1.cell(i, 3).value
        })

接下来,我们将导入之前由 Excel 生成的图表图像,并创建另一个字典来实例化模板文档中声明的所有占位符变量:

image = InlineImage(template,'chart.png',Cm(10))context = {
    'title': 'Automated Report',
    'day': datetime.datetime.now().strftime('%d'),
    'month': datetime.datetime.now().strftime('%b'),
    'year': datetime.datetime.now().strftime('%Y'),
    'table_contents': table_contents,
    'image': image
    }

最后,我们将呈现带有值表和图表图像的报告:

template.render(context)
template.save('Automated_report.docx')

结果

这就是自动生成的 Microsoft Word 报表,其中包含在 Microsoft Excel 中创建的数字和图表。这样,您就有了一个完全自动化的管道,可以根据您的需要创建尽可能多的表格、图表和文档。

自动生成的报告。图片由作者提供。

源代码

如果您想了解更多关于数据可视化和 Python 的知识,请随时查看以下(附属链接)课程:

使用 Streamlit 开发 Web 应用程序:

https://www.amazon.com/Web-Application-Development-Streamlit-Applications/dp/1484281101?&linkCode=ll1&tag=mkhorasani09-20&linkId=a0cb2bc17df598006fd9029c58792a6b&language=en_US&ref_=as_li_ss_tl

使用 Python 实现数据可视化:

https://www.coursera.org/learn/python-for-data-visualization?irclickid=xgMQ4KWb%3AxyIWO7Uo7Vva0OcUkGQgW2aEwvr1c0&irgwc=1&utm_medium=partners&utm_source=impact&utm_campaign=3308031&utm_content=b2c

面向所有人的 Python 专业化:

https://www.coursera.org/specializations/python?irclickid=xgMQ4KWb%3AxyIWO7Uo7Vva0OcUkGQgW16Ewvr1c0&irgwc=1&utm_medium=partners&utm_source=impact&utm_campaign=3308031&utm_content=b2c

GitHub 资源库:

https://github.com/mkhorasani/excel_word_automation

☕喜欢这个教程?在这里随意给我捐一杯咖啡。

新到中?您可以在此订阅并解锁无限文章。

使用 Google Sheets 和 Apps 脚本将多个 CSV 文件自动转换为 BigQuery 管道

原文:https://towardsdatascience.com/automate-multiple-csv-to-bigquery-pipelines-with-google-sheets-apps-script-3ff05f535a09?source=collection_archive---------29-----------------------

将一些简单的数据放入 BigQuery,而不必使用大量工具或复杂的工作流

https://unsplash.com/photos/JKUTrJ4vK00

想要将 CSV 文件的多个管道自动加载到不同的 BigQuery 项目/数据集/表,并从单个 Google Sheet 控制它们吗?什么事?那么这篇文章就送给你了。

这个过程甚至允许您配置是否希望自动化在每次向 BigQuery 表中截断或追加数据。不错吧?

背景

不久前,我写了一个使用 Google Apps 脚本将 CSV 文件加载到 BigQuery 的过程。这个过程在代码中使用了检测到的 CSV 文件类型的定义、BigQuery 的加载模式以及其他一些东西。我意识到对于入门者来说,这可能是多余的,需要他们自己写太多的代码。因此,我重写了这个过程,使之更加简单,使用一个 Google Sheet 作为管道管理器。

先决条件

  • 谷歌账户
  • 谷歌应用程序脚本—【script.google.com
  • 谷歌大查询项目、数据集、表—console.cloud.google.com
  • 此谷歌表单的副本
  • 要加载到 BigQuery 的 CSV 文件
  • 来自这个仓库的代码

Google 工作表和驱动设置

首先,将 google sheet 复制到你自己的 google 账户中。然后创建一些 Google Drive 文件夹来存放您的 CSV 文件。

您将需要一个谷歌驱动器“源”文件夹为每一个不同类型的 CSV。如果你愿意,你可以有多个“已处理”文件夹,或者如果你希望所有的东西都在同一个地方,你可以有同一个“已处理”文件夹。这真的取决于你。

然后,您将在适当的列中用 Google Drive ID 更新 Google 工作表。在浏览器中使用 Google Drive 时,ID 位于 URL 的末尾。例如:如果 Google Drive 文件夹的 URL 是https://Drive . Google . com/Drive/u/0/folders/1-zfa 8 svucirp xf J2 Cun 31 a,那么 Drive 文件夹的 ID 就是“1-zfa 8 svucirp xf J2 Cun 31 a”,这就是你要放入 Google Sheet 的列中的内容。

BigQuery 设置

对于要加载的每种 CSV 类型,您都需要一个 BigQuery 表。如果你有 4 种不同的 CSV 文件,那么你需要 4 个不同的表格。这些可以跨任意数量的 BigQuery 项目和数据集进行拆分,但是最终每个 CSV 类型都需要一个表。

如果您已经设置了 BigQuery 表,那么您需要做的就是用适当的信息(项目 ID、数据集 ID、表 ID)更新 Google 工作表

如果您需要创建一个新的 BigQuery 表,最简单的方法(无需编写任何代码)是通过 BigQuery 控制台上传一个 CSV,并使用 Autodetect 为您设置模式。然后,该类型 CSV 的每个后续加载将保证工作。

上传 CSV 以创建 BigQuery 表:

  1. 【https://console.cloud.google.com/bigquery 号
  2. 单击左侧导航栏上的项目名称
  3. 单击 3 点菜单并创建一个新数据集
  4. 点击数据集名称,然后点击创建表

当您的表被创建时,将它的 ID 与项目 ID 和数据集 ID 一起放入 Google Sheet。

创建您的应用程序脚本项目并配置代码

到目前为止,您应该已经有了一个 Google Sheet,其中填充了许多关于您的 Google Drive 文件夹、您的 BigQuery 项目/数据集/表的详细信息,现在剩下要做的就是将代码放入适当的位置,使它们一起工作。

在 Google 表单中,打开脚本编辑器。在撰写本文时,如果你使用的是个人 gmail.com 账户,这将通过工具- >脚本编辑器菜单项实现。如果您使用的是组织/学校帐户,这将通过扩展- >应用程序脚本菜单项实现。

这将打开应用程序脚本编辑器。

从这个 github 存储库中复制 code.gs 文件内容,并粘贴到现有的 Code.gs 文件中。

单击+图标添加一个新的 HTML 文件,并将其命名为“email ”,这样您的文件列表如下所示:

从同一个 github 存储库中复制 email.html 文件内容,并将其粘贴到 Apps 脚本中的 email.html 文件中。

使用左侧服务菜单旁边的+图标添加 BigQuery 和 Drive 服务(因此您的服务列表看起来也像上面的截图)。

打开 Code.gs 文件并更新文件顶部的变量。您可以在这里设置诸如工作表标签名称(如果您已经从原始模板中更改了它们)以及该流程也可以发送的电子邮件通知中的信息。

就是这样。这就是你需要做的所有设置。

让这东西跑起来,好吗?

  • 将适当类型的 CSV 文件放入 Google 工作表指定的 Google Drive 文件夹中
  • 在应用程序脚本中,单击顶部的运行按钮,运行列出的唯一函数
  • 当你第一次运行这个程序时,谷歌会询问你是否确定,以一些安全/批准提示的形式。这是正常的…这是您授权访问您的应用程序脚本项目,以便能够使用您的 Google Drive、BigQuery 和 Gmail 内容/服务。这是不允许谷歌或其他任何人对你的帐户做事情。只要确保你不与其他人分享谷歌表单,他们可能会用它来做一些邪恶的事情(因为他们也可以看到和编辑这些代码)。
  • 这些提示看起来有点像这样:
  • 之后…脚本将第一次运行。
  • 检查 Google Sheet 的日志选项卡,看看它是否做了什么。
  • 现在,为了好玩,再放几个 CSV 到文件夹中,然后再次运行该函数。看…成功了!
  • 接下来,您将希望设置一个触发器来按计划自动运行该功能。只需使用应用程序脚本项目左侧的触发器菜单来设置触发器,如下所示:

现在…真的是这样。简单吧?

您可以在 BigQuery 控制台中看到自动化作业的结果——在 BigQuery 中查看作业,然后查看数据集和表,您应该会很快看到表中的数据。如果你改变了这个网址中的 id…这就是你应该去查看的地方:https://console.cloud.google.com/bigquery?project=id&page =乔布斯(这也在谷歌表单日志中)。

万岁!

希望这比的原始文章/方法更容易理解,并且不需要使用很多工具或复杂的工作流程就可以将一些简单的数据导入 BigQuery。

我知道这个过程可以通过从 CSV 文件中自动检测模式来改进,以创建初始表,并且应该有更多的错误处理…但是…这是为了后面的提交和拉请求:-)

下面是代码:https://github . com/usaussie/app script-multiple-big query-pipelines-Google-sheet

这篇文章大概贴在techupover.com和techupover.medium.com上。也可以在 Twitter 上关注我 @techupover

原载于 2021 年 10 月 28 日【https://www.techupover.com】

使用 Python 自动重命名和组织文件

原文:https://towardsdatascience.com/automate-renaming-and-organizing-files-with-python-89da6560fe42?source=collection_archive---------6-----------------------

学习使用 Python 重命名和自动化您的文件组织!

使用 Python 自动重命名和组织文件!(来源:Nik Piepenbreier)

你知道你每天收到的那些销售报告吗?标有East-Sales-01Jan2021.xlsxEast-Sales-01Jan2021.xlsx等的?说你希望他们被称为2021–01–01 — East Sales

您可以手动逐个重命名它们。或者您可以使用 Python 的魔力!

在本文中,您将学习如何使用pathlib库来:

  1. 根据模式重命名文件,以及
  2. 将文件组织到逻辑文件夹中

如果你想跟随视频教程,请点击这里查看我的视频:

我们开始吧!

要加载我将在本教程中使用的示例文件,您可以从这个链接下载它们。只要解压它们,把文件夹放在你喜欢的任何地方。

现在,让我们加载我们将使用的两个库:

我们将使用datetime来捕获和转换文件名中的日期。我们还将使用pathlib来重命名文件并将其移动到逻辑文件夹中。

Python 的 pathlib 是如何工作的?

Python 的pathlib是一个面向对象的框架,用于处理和操作文件路径。它是在 Python 3.4 中引入的,因此任何 3.4 或更高版本都可以使用本教程。

Pathlib 允许我们创建具有许多不同属性和方法的 path 对象,我们可以使用它们来深入了解我们的文件或操纵它们。

让我们创建一个 path 对象,并检查该路径的一些属性。将你保存文件夹的目录加载到our_files变量中。(注意:如果你正在使用 Windows,通过在你的字符串前面放置一个r,把你的字符串变成一个原始字符串以防止转义反斜杠。)

我们在上面的代码中所做的是创建一个Path对象,并将其赋给一个名为our_files的变量。这样做的好处是,我们现在可以访问这两个属性,并对该对象应用方法。

例如,我们已经检查了路径代表的是文件(False)还是目录(True)。我们还打印出了父路径、路径的词干和后缀(在本例中是空白的)。

用 Pathlib 重命名文件

使用 Pathlib 提供的面向对象的方法,我们可以轻松地访问路径的元素并进行修改。

.iterdir()方法返回存储在该目录中的所有项目的生成器对象。让我们打印出这些项目,以确保它正确地捕获了我们的文件:

这样做的好处是,我们现在可以对目录中的每个文件进行迭代和操作!解决了这个问题,让我们开始修改文件名结构。

这里还有一点要解开,让我们一步步来看:

  • 我们使用.iterdir()方法遍历目录中的每个文件
  • 然后,我们创建两个有用的变量来存储每个文件的目录和扩展名
  • 我们将旧文件名(使用.stem属性创建的)解包成有意义的名称(区域、报告类型和旧日期)
  • 因为我们想要更改日期格式,所以我们将日期字符串转换成 datetime 对象,然后再转换回具有我们想要的输出格式的字符串。(注:我们先用.strptime(),再用.strftime()
  • 最后,我们创建一个 new_name 变量,它使用 f 字符串将其他字符串连接成一个文件名。(如果您要打印出一个新的 _name,它会是这样的:/Users/nikpi/Desktop/Files/2021–01–01 — East — Sales.xlsx)
  • 要重命名文件,我们调用文件本身的.rename()方法,传入目录和新名称的连接。

唷!好的,太棒了!你已经走到这一步了。如果您满足于仅仅重命名文件,现在可以自由运行您的代码了。它会立即做出改变(Mac OS 和 Windows 不允许你点击“撤销”——所以要小心!).

如果你也想把每个月的文件组织到文件夹中,请继续阅读。

用 Pathlib 移动文件

因为我们可以访问 Pathlib 对象的许多不同元素,所以我们可以使用这些元素将我们的文件组织到有意义的文件夹中。

自动移动文件到不同的文件夹!资料来源:Nik Piepenbreier

例如,如果您想将您的文件组织到它们所属的每个月的文件夹中,我们可以使用 Pathlib 来自动完成这项工作。

我将在这里重复一些早期的代码,以便当您想要立即运行它时,它们都在那里:

让我们一点一点地分解我们在这里所做的事情。我为您提供了步骤编号,以便于您更容易地理解,因为一些代码已经更改:

  1. 我们添加了一个条件来检查文件是否实际上是一个文件(而不是一个目录)。(提示:如果你运行的是 Mac,有时讨厌的文件叫做“.DS_Store”获得添加。条件的第二部分针对这些进行检查)
  2. 我们创造了和以前一样有用的变量。
  3. 我们将日期转换成更有用和可排序的格式。
  4. 我们将月份以字符串格式存储在month变量中。然后我们使用.joinpath()方法通过插入一个字符串作为参数来创建一个新路径。
  5. 然后我们使用.exists()方法检查文件夹是否存在,该方法返回一个布尔值。如果文件夹不存在,那么我们创建文件夹。
  6. 这里,我们创建了一个新的 path 对象,它将新文件名加入到新文件夹中。
  7. 最后,我们使用.replace()方法,将文件移动到那个路径。需要注意的是,如果该文件已经存在,它将被覆盖。为了避免这种情况,您可以编写一个条件来首先检查这一点。

现在剩下的就是点击运行!这将更改所有文件名,并将它们移动到新创建的文件夹中。

结论—自动化很有趣!

感谢阅读本教程!我希望你发现它在管理你的文件方面是有用的,并且看看你如何能更进一步。

例如,您可以添加条件以仅修改某些文件类型,并且您可以设置自动清理混乱的下载文件夹的方式。

想要更多这样的教程,可以考虑订阅我的 YouTube 频道,我经常在那里发布像这样的教程。点击下面的按钮订阅!

点击此处订阅。图片由 stickpng.com 提供)

使用 Faker 和 PostgreSQL 为 Django 项目自动生成样本大数据

原文:https://towardsdatascience.com/automate-sample-big-data-generation-with-faker-and-postgresql-for-django-projects-e95343ae93e?source=collection_archive---------20-----------------------

为您的数据密集型项目在几秒钟内生成可重复使用的大型模拟数据集

unsplash.com

在处理数据密集型应用程序时,总是需要生成大量模拟数据,以便在多种场景中进行测试。在大多数情况下,我们需要在几分钟内(如果不是几秒钟)生成大型数据集的方法。在我的例子中,我们需要一个模拟数据集用于我们的 UAT 环境 IoT,并验证 API 和查询的性能。我曾经在 CSV 中生成数据,并将数据移动到数据库中。但这似乎效率低下。如果数据集尚未保存,则必须生成,然后我们需要维护、集成和运行一个独立的 python 脚本。

我以前在一些情况下使用过 Django 管理命令。由于我们当前的一些后端运行在 Django 中,并且是用 ORM 管理的,我认为有一个生成模拟数据集的管理命令会很好。事实证明,这不仅对我,而且对整个团队和管理人员都非常有益。

如果你没有编写过定制管理命令,或者需要一份编写定制管理命令的参考资料,试试这个。尽可能地使用它。它不仅可以与您的 Django 应用程序很好地集成,而且您还可以充分利用 Django 的 ORM,从使用对象到运行聚合策略。

我非常依赖的一个软件包是 Faker ,用于生成虚假数据集,如用户名、电子邮件、公司名称。但是还有最后一个缺失的部分——时间序列数据的生成。这就是 PostgreSQL 生成系列的用武之地。它提供了创建时间序列等系列数据的有效方法。

我为一个物联网应用程序创建了一个包含三个模型的 Django 项目样本,安装了 Faker 库,并将其连接到本地 Postgres 数据库。

  • 应用程序用户注册用户数据
  • 用户设备为用户添加传感器设备
  • 设备数据按时间顺序捕获新增用户设备的温度和湿度。

数据库模式和模型:

现在将模型映射到相应的 admin.py。我喜欢 Django 的一点是管理页面。

我通常设计模式,并用 Django-admin 创建数据层的快速模型,包括过滤器、搜索、数据导出、只读字段。

在我的组织中有一个需求,我们需要从 excel(一个计数表)中提取数据。有多个表,每个表都有很多信息,有些单元格有基于月份的财务数据,如 account_no、credit、debit、closing-balance 和 opening-balance,有些表有非每月的非结构化数据。所有这些数据集都按类别存储。我想到了一个关于表单类型的可配置模型层的小点子。

根据类别数据类型的配置,在理货数据页面上输入的数据将应用该公式并计算最终金额。

不仅如此,它的编码方式是,当计数表被上传到一个类别时,提取和计算也会基于配置发生。这是在很短的时间内完成的,结果证明它非常有活力,非常有用。

如果您是 Pythonista,只要知道如何将设计好的模式转换成模型并创建管理页面映射,就可以为您节省大量创建数据层的时间。它还会为您的数据层提供一个漂亮、时尚的 UI。

是的,我明白了,这和这篇文章没有关系。但是如果你是 python 开发人员、数据分析师或科学家,Django 管理层会给你很多支持和帮助。我总是用 Django admin 来原型化我的数据层。

关于 Django admin 已经说得够多了。现在你可以在 Django-admin 中创建一个用户和一些与用户相关的设备。我已经创建了一个用户和一个设备。现在让我们使用原始 SQL 为设备生成数据。

PostgreSQL generate-series 是一个非常强大的系列数据生成函数,可以在几分钟内创建数百万条记录。

让我们为我们创建的 ID 尝试一个示例生成系列函数

插入到设备数据(日期时间,用户设备 id,温度,湿度)
选择
日期时间,
用户设备 id,
random()*100 作为温度,
random()*100 作为湿度
从 generate_series(now() —间隔' 3 年',now(),间隔' 1 小时')作为 g1(日期时间),
generate_series(1,1)作为 g2(用户设备 id)

我们正在为我们创建的设备插入 3 年的每小时数据

你可以看到快速的数据生成与 Postgres 生成系列。现在将它与 Faker 和 Django ORM 结合起来,您就可以将任何 Django 应用程序的样本数据生成脚本集成到您的代码库中。

这些是我遵循的步骤:

  1. 从用户处获取总用户和相关设备的数量作为输入。
  2. User Faker(faker.name())来创建模拟用户名。
  3. 然后用 Django bulk_create 批量插入那些用户数据和设备数据
  4. 然后用上面的原始 SQL 传递必要的参数,迭代地为设备生成数据。

通过这种方式,我们现在可以将样本数据集生成作为代码与 Django 中的 MVT 一起维护。

以下是输出:

或者,您仍然可以在 psycopg2 中使用等效的 SQLAlchemy ORM 或纯 python 本身。随意发挥你的想法。我之前用过 python,CSV,还有 pandas_to_sql 。虽然这很快,但与生成系列相比,它差远了。在我的一个示例项目中,我能够在 20 分钟内生成 2100 万条包含相关数据的记录。但要警惕的是,随着数据的增加,插入速度往往会变得缓慢。

完整的代码在 GitHub 中。

模拟数据——一种生成可预测数据并测试不可测试数据的方法

开心嘲讽和数据叠加!!

使用 Pyautogui 自动提取 SAP 报告

原文:https://towardsdatascience.com/automate-sap-report-extraction-with-pyautogui-f115ae19b653?source=collection_archive---------11-----------------------

从世界上最乏味的任务中节省时间的指南。

温德米亚酒庄在 Unsplash 拍摄的照片

介绍

报告是任何业务的基础。在日常生活中,你必须以某种方式从报告中吸收新数据,以决定每天的下一步。该报告可以采用各种格式,如 Microsoft Excel、Web 应用程序或从企业资源规划系统(ERP)导出。

我最近收到一个请求,要求我构建一个仪表板,在精心制作的报告中复制业务编号。财务团队每月手动创建此报告。最繁琐的过程是从 SAP 系统中导出源文件,并手动将其放入 excel 中。之后,他们必须调整一些数字,因为这是用户定义的公式无法计算的边缘情况。

在我看来,如果我们以相同的逻辑从 SAP 表的源表开始,我们可以不用做很多手工任务就可以导出报表。我第一次也是这么想的。

复制这些数字将是一项简单的任务。逻辑似乎很简单。但是,当我深入研究细节时,我发现所有这些数字都经过了许多底层 SAP 业务规则的处理。此外,业务规则是如此的动态,对于一个不完全理解整个流程的人来说,很难复制它。

经过一段时间的反复试验,我决定不再继续复制过程。我要花一个多月的时间才能理解所有内容,并将 SAP ABAP 语言转换成另一种我可以使用的语言。有时候,我们需要让一些事情保持原样。不要碰它,即使你认为它会是一个伟大的方式在未来这样做。

然后,我该怎么办?

照片由哈德逊·辛慈在 Unsplash 上拍摄

下面我们来看今天的主要话题。我没有接受源数据并自己计算数字,而是跳过了所有的过程,接受了最终的报告结果。我该怎么做?答案是用一个pyautogui模块。你可以在这个 Github 里找到。

简而言之,pyautogui帮助你完成基本的自动化任务,例如移动鼠标,点击按钮,键入一些单词。通过引用鼠标要移动到的像素,你可以在桌面上做任何你想做的事情。此外,它还附加了计算机视觉功能,可以根据提供的图片识别屏幕上的位置。太棒了。

今天,我将引导您浏览这个库,并添加一些其他有用的功能来帮助您自动化桌面上的任何事情。今天,我不会为一个pyautogui能做什么写一个教程,因为无论如何你能在文档中找到它。我会向你展示这个过程,以及你可以在哪里应用这个东西。

这是我们今天要讲的步骤。

由 Roman Synkevych 在 Unsplash 上拍摄的照片

  1. 打开 SAP GUI 并登录到服务器。
  2. 输入用于提取报告的 SAP 程序名称和参数。
  3. 执行报告并将其导出到 Microsoft Excel 电子表格。
  4. 将其上传到 AWS S3,以进行进一步的 ETL 流程。

因此,让我们打开 SAP,以便从中提取报告。这是你怎么做的。

import subprocesssap_gui = subprocess.Popen("path/to/saplogon.exe")

首先,我们用subprocess模块打开程序。你打开任何exe文件都很方便。你用参数sap_gui存储program对象。在脚本的最后,您可以像这样终止 SAP。

sap_gui.terminate()

当 SAP 登录打开时。您将看到这样的屏幕。

作者的 SAP 登录屏幕截图

使用pyautogui时要小心的一件事是,如果桌面处理不正确。我的意思是,假设你在屏幕上选择了某个选项,程序需要一些时间来处理它。如果您不在脚本中添加任何等待时间,所有后续步骤都可能出错。

为了让上面的例子更好。

import pyautogui
import subprocess
import timesap_gui = subprocess.Popen("path/to/saplogon.exe")# wait 3 seconds for the program to load
time.sleep(3)# assume that we move to input username fieldsusername_field_location = pyautogui.locateOnScreen('username_field.png')
pyautogui.moveTo(username_field_location) 
pyautogui.click()# type the username in the field that we just clicked
pyautogui.typewrite(username)# move (relative from the current cursor position) to below 50 pixel
pyautogui.moveRel(0, 50)
pyautogui.click()# type the password
pyautogui.typewrite(password)
pyautogui.press('enter')

通过下面的代码,我们向您展示如何使用pyautogui函数登录到 SAP 系统。上面的代码片段包含了我在摄取脚本中使用的几乎所有函数。我们同时使用参考运动和计算机视觉运动。现在你会在这里如下图。

作者的 SAP 主页截图

此时,您将输入报告所需的所有参数,然后执行它。我们可以使用上述所有功能来完成这项任务。让我只指出我先前没有提到的功能。

# Other functions that I used to assign the value to get the report# double click
pyautogui.doubleClick()# right click
pyautogui.click(button='right')# hot key with ctrl + f9 (shortcut for SAP command)
pyautogui.hotkey('ctrl', 'f9')# press tab to shift to the next input field
pyautogui.press('tab')

单击 SAP 导出过程的导出按钮后,它会自动为您打开 excel 文件。这种行为有时很烦人,因为在关闭 excel 文件之前,您不能对结果文件做任何事情。

这就是另一个有用的功能出现的地方。我们可以检查该进程(MS Excel)是否正在运行。之后,我们可以将它们作为一个触发点,进入下一步。如果 SAP 系统能够正确保存 excel,我们可以毫不犹豫地关闭 excel 结果文件。我们将使用下面的函数来做到这一点。

import osdef process_exists(process_name): # Thanks to [ewerybody](https://stackoverflow.com/users/469322/ewerybody) for providing this useful snippet code [https://stackoverflow.com/questions/7787120/check-if-a-process-is-running-or-not-on-windows-with-python](https://stackoverflow.com/questions/7787120/check-if-a-process-is-running-or-not-on-windows-with-python) # This function will return true if the process is running.
      It's compatible only in MS Window. try:
        call = 'TASKLIST', '/FI', 'imagename eq %s' % process_name        # use buildin check_output right away    
        output =  subprocess.check_output(call).decode()    

        # check in last line for process name    
        last_line = output.strip().split('\r\n')[-1]            # because Fail message could be translated    
       return last_line.lower().startswith(process_name.lower()) except Exception as e:
        print(e)def close_process(process_name): # This function will return true if the process is running.
      It's compatible only in MS Window. try:
        os.system('TASKKILL /F /IM {}'.format(process_name))
    except Exception as e:
        print(e)

这里我们检查微软是否存在。如果存在,我们就关闭它们。

# Let's wait untill the program is exists and close it.retry = 0
while not is_process_exists('path/to/excel.exe'):time.sleep(10) # may be we need more time for saving
    retry += 1
    if retry > threshold:
        raise ValueError("Excel cannot be saved")close_process('path/to/excel.exe')

我们将对导出的文件进行后处理,将其放在应该放的地方。

local_file = path/to/export.xlsx
target_dir = path/to/{load_date}
file_name = {business_key_parameter}.xlsx
absolute_file_name = os.path.join(target_dir, file_name)if os.path.exist(target_dir): # if the target dir doesn't exist, create one.
    os.mkdir(target_dir)if os.path.isfile(absolute_file_name): # if there is a file in the target folder, replace with new one.
    os.remove(absolute_file_name)# rename and move export file to the target dir
os.rename(local_file, absolute_file_name)

现在我们想要的报告已经放在目标目录中。我们将循环访问所有业务部门以获取所有报告。

要小心的事情pyautogui

pyautogui模块的一个缺点是,如果前一条指令的输出结果不符合预期(网页无法加载),那么这个错误将导致后面的所有步骤彻底失败。要解决这个问题,我能想到两个选择

  1. 为每个pyautogui阶段找一个可靠的参照物。如果那个可靠的引用不存在,我们将等待它被加载。请注意,如果您使用while循环而不重试,可能会导致无限循环。
  2. 引发错误并跳过当前错误。之后,您可以稍后重试。这假设问题是由于暂时不可靠的参考而发生的。我们可以创建一个函数来检查导出文件的数量。然后,对于丢失的文件,我们再次重新运行脚本。

在你得到你想要的所有报告后,让我们把目标文件上传到 AWS S3 公司做进一步的处理。

**import** **logging**
**from** **botocore.config** **import** Config

*# Intial S3 client* s3_config = Config(region_name = <<YOUR AWS REGION NAME>>)
s3_client = boto3.client(
    "s3", config=s3_config,
    aws_access_key_id = config["CREDENTIALS"]["AWS_ACCESS_ID"],
    aws_secret_access_key = config["CREDENTIALS"]["AWS_SECRET_KEY"]
            )
**try**:
    response = s3_client.upload_file(
               file_name, bucket, object_name
               )
**except** Exception **as** e:
    print(e)

瞧啊。我们已经自动提取了报告,并将其上传到 S3 自动气象站,无需人工协助。剩下的就是安排这个任务每天运行。

该休息了

照片由德鲁·科夫曼在 Unsplash 拍摄

我们今天浏览了几个有用的图书馆。如你所见,我们可以用 python 自动完成所有繁琐的任务。

我花了大约半天的时间来编写这个任务的动作代码。但是我能节省的时间更多。

假设您必须每天导出一次,提取时间为 1 小时,并每天输入相同的参数。这将是世界上最无聊的任务。现在我有一个脚本来处理所有这些事情。

起初,我认为自动化会有一些成本。在网上看到一些很优雅的 RPA 应用。如果我必须花钱购买这些应用程序,那么通过概念验证和采购流程将会花费大量时间。有了它,我们可以在一天之内在当地完成所有事情。

然而,正如我前面提到的,您必须自己处理边缘案例。如果它是一个简单的应用程序,我鼓励你自己尝试自动化它。但是对于复杂的流程,您可以选择获得完整的优雅 RPA 应用程序。这可能是一个更好的选择。

不要让你自己在单调乏味的任务中毫无收获。让我们实现自动化吧!

帕泰鲁什·西达

如果你喜欢这篇文章,并希望看到更多这样的东西。

  • 跟着我上媒
  • 其他渠道? LinkedIn , Twitter ,以及脸书

使用 Cookiecutter 自动化数据科学项目的结构

原文:https://towardsdatascience.com/automate-the-structure-of-your-data-science-projects-with-cookiecutter-937b244114d8?source=collection_archive---------13-----------------------

停止手工操作,重新使用项目模板

列宁·艾斯特拉达在 Unsplash 上的照片

这是很多数据科学家都熟悉的情况。

每当您开始一个新项目时,您都要重用旧项目的结构。您浏览它们的文件夹并复制粘贴它们,删除不必要的文件,用新项目的细节重命名剩余的文件,进入每个配置文件并替换旧的环境变量(URL、API 键、主机、端口等)。)与新的。

也许,谁知道呢,在这个过程中,您会创建新的配置和新的文件夹。

❌:我们都同意这是一项相当乏味和重复的任务。更不用说它很容易出错。

✅从一个主模板开始每个新项目不是更方便吗?你可以从终端克隆并填充特定的信息?让这个模板自动为您构建一个完整的文件夹结构,并用您定义的正确名称和变量填充文件,这不是很好吗?

Cookiecutter 才是解决这个问题的正确方法。

在本帖中,我们来看看 cookiecutter。
我们将了解它是如何工作的,以及您如何使用它来为您的项目构建定制的和可重用的模板。
然后,我们将介绍
Cookiecutter 数据科学 开源模板,以启动遵循行业最佳标准的数据科学项目。

事不宜迟,我们来看看🔍

什么是 cookiecutter?

" Cookiecutter 从项目模板创建项目."—官方文件

  • 项目可以是 python 包、web 应用程序、具有复杂工作流的机器学习应用程序或任何你能想到的东西
  • 模板是 cookiecutter 用来创建项目的。他们依赖于 Jinja2 的语法

cookiecutter 做的事情非常简单:它克隆一个目录并将其放入新项目中。然后,它用在cookiecutter.json文件中找到的名字替换在{{}} (Jinja2 语法)之间的所有名字。(我们将在下一节看到如何构建 cookiecutter 模板的示例)

要开始使用 cookiecutter,您可以使用 pip 安装它:

**pip install cookiecutter**

或康达:

**conda install -c conda-forge cookiecutter**

👉你可以在所有平台上使用 cookiecutter:Windows、Mac 和 Linux
👉它适用于 Python 2.7+和 3.5+(尽管更喜欢 Python 3.5+,因为 Python 2.7 不再维护 )
👉您可以使用 Cookiecutter 创建一种或多种语言的模板

如何为您的 Streamlit 项目创建自定义 cookiecutter 模板?

在这一节中,我将向您展示如何为 kickstart Streamlit 项目创建一个 cookiecutter 模板。

如果你不熟悉 Streamlit ,它是一个用于构建 web 应用程序的 Python 库。它使用起来非常简单,并且提供了很多功能。我每天都用它来与我的团队分享实验和结果,并制作机器学习应用的原型。

目标结构

我的基于 Streamlit 的项目往往具有以下结构:

作者截图

  • 一个包含应用程序(app.py)主脚本的src文件夹,以及一个包含两个脚本的utils模块:ui.py用于放置布局函数,而common.py用于保存其他用于数据处理或远程数据库连接的实用函数
  • 一个.gitignore文件,用于防止 git 对不必要的文件(例如 env 文件,或。pyc 文件)
  • Procfilesetup.sh:处理 Heroku 上的部署
  • requirements.txt:列出项目依赖关系
  • 一个.env文件,用于存储项目的环境变量
  • A README.md分享项目详情

创建一个 cookiecutter 模板以匹配目标结构

要创建一个生成这个结构的 cookiecutter 模板,让我们首先为这个模板创建一个文件夹。

**mkdir streamlit-cookiecutter
cd streamlit-cookiecutter**

在这个文件夹中,创建cookiecutter.json文件:

关于这个文件的一些事情:

  • 当 cookiecutter 从模板中启动一个项目时,每个键都是它需要的一个项目
  • 每个值对应于每个项目的默认值
  • 项目的值按顺序设置。例如,repo_name设置在project_name之后(因为它的值取决于project_name的值)

当您使用 cookiecutter 克隆模板时,会设置这些项的值:我们将在下一步中看到这是如何完成的。

现在创建文件夹,并将所需的目标结构放入其中。我们将根据repo_name项来命名该文件夹。
在 cookiecutter 语法中:{{cookiecutter.repo_name}}

{{cookiecutter.repo_name}}文件夹中,将您想要的结构放到您的项目中:

这些文件中的每一个都可以访问您传递给 cookie-cutter 的项目的值:您所要做的就是使用{{}}

让我们看看如何利用这一点。

👉生成 README.md 我们可以通过在其中插入project_namedescriptionopen_source_license项来自动生成 README.md。

👉设置环境变量 我们可以自动填写s3_bucketaws_profileporthostapi_key在。环境文件。

👉重复数据删除代码 如果您的 Streamlit 应用程序遵循相同的结构,并且都以项目名称作为标题,则没有必要每次都重复此代码。

一旦你完成了你的模板代码,把它推给 Github。我已经做了,你可以在这里查看。

测试模板!🚀

现在模板已经在 Github 上了,让我们用它来开始一个项目。

假设我想在 Streamlit 中创建一个情绪分析 app

我需要做的就是用模板的 URL 调用 cookiecutter。

**cookiecutter** [**git@github.com**](mailto:git@github.com)**:ahmedbesbes/streamlit-cookiecutter.git**

一旦执行该命令,Cookiecutter 将要求您设置您在cookiecutter.json文件中定义的项目的值(注意,每个项目的默认值都放在括号中)。

为每个项目输入特定值后,项目就创建好了。

让我们检查一下它的README.md

作者截图

.env文件✅

作者截图

app.py文件✅

作者截图

一切都好。项目具有所需的结构,文件中填充了正确的数据。

现在我们可以开始开发这个应用程序了。

库克数据科学

cookiecutter 的一大优点是充满活力的社区。现在有很多不同风格的开源模板(Django、Flask、FastAPI,随便你怎么说)。你可以很容易地在 Github 上找到它们并开始使用它们。

一个引起我注意的模板是 Cookiecutter 数据科学。

作者截图

正如作者所说,这个模板是:

一个逻辑合理、标准化但灵活的项目结构,用于进行和共享数据科学工作。

实际上,这个模板提供了一组目录来更好地组织您的工作。这有点固执己见,但它遵循了该领域公认的良好实践。

在我看来,它有助于:

  • 按职责组织模块:数据集创建、特征工程、建模、可视化
  • 按流水线阶段组织数据
  • 强制单元测试
  • 创建文档

您可以开始使用此模板,如下所示:

作者在碳上制作的图像。嘘

一旦您完成了对每一项的值的设置,您将得到以下结构:

来源:http://drivendata.github.io/cookiecutter-data-science/

您不必坚持这种结构:如果您对它不满意,您可以派生模板并修改它以满足您的需要。

资源

Cookiecutter 是一个神奇的图书馆。它有助于自动创建项目,并防止您重复自己。作为一名数据科学家,它必须是你工具箱的一部分。

为了了解更多关于 Cookiecutter 的信息,我挑选了一些你可以轻松浏览的好资源:

  • https://github.com/cookiecutter/cookiecutter
  • https://drivendata.github.io/cookiecutter-data-science/
  • https://dev . to/azure/10-top-tips-for-reproducible-machine-learning-36g 0
  • https://towards data science . com/template-your-data-science-projects-with-cookiecutter-754 d3c 584d 13
  • https://youtu.be/nExL0SgKsDY(一段优秀的 Youtube 视频)

感谢阅读🙏

如果你坚持到最后,我真的感谢你的时间,并希望你学到了一些关于 cookiecutter 和项目模板。

今天就这些了。直到下一次更多的编程技巧和教程。👋

由卡斯滕·怀恩格特在 Unsplash 上拍摄的照片

新到中?您可以每月订阅 5 美元,并解锁无限的文章— 单击此处。

用 Python 自动化 WhatsApp 消息

原文:https://towardsdatascience.com/automate-whatsapp-messages-with-python-6c1d71444ffa?source=collection_archive---------0-----------------------

只用了两行代码

附身摄影在 Unsplash 上拍照

用 Python 自动化 WhatsApp 消息?

Python 是一门令人惊叹的语言。你不一定要成为专业人士才能用它做令人兴奋的事情。

这种语言非常适合自动化。我尝试的第一个自动化是电子邮件自动化。然后是网页抓取,现在是 WhatsApp 消息。

也许你想让 WhatsApp 在某个特定的时间发送消息,但那个时候你可能很忙,甚至在睡觉。或者你可能想知道如何自动化 WhatsApp 信息,只是为了好玩。

在本文中,您将学习如何用两行 Python 代码自动处理 WhatsApp 消息。

安装 Python 、 Pycharm 和 Pywhatkit 如果你还没有的话。

如何用 Python 自动化 WhatsApp 消息

在编写代码的过程中,您可能会遇到错误,但不要担心。我将在下面介绍如何解决可能出现的 bug。如果你看到的 bug 这里没有提到,在 Google 上搜索解决方案。

bug 是编程的一部分。我无法克服在尝试自动化我的 WhatsApp 信息时遇到的一个错误。在我能解决它之前,我不得不考虑它。睡在虫子旁边总是好的。第二天早上你精神焕发,准备解决那些该死的 bug。

现在让我们开始吧。

  • 打开 Pycharm 并创建一个新项目。给新项目起一个名字——Whatsautomation 或任何您喜欢的名字。然后选择 python 文件。此外,给 python 文件取一个您想要的名称。
  • 谷歌 Pywhatkit 或者去网站这里。复制 Pywhatkit 安装链接。您将看到下图中红色箭头所指的链接。点击它,链接将被复制。

  • 回到皮查姆。记住你已经打开了 Pycharm。点击 Pycharm 左下角的终端。将您复制的 Pywhatkit 安装链接粘贴到终端中,然后按 enter 键。安装 Pywhatkit 需要几分钟时间。
  • 现在,在 Pycharm IDE(终端上方的大空间)中编写以下代码。

注:在括号内,写下您要发送自动消息的国家的国际代码(+……)。然后,写下你的信息。现在写下你希望信息传递的时间。这里的时间使用 24 小时制。因此,不是写 1,00 表示下午 1 点,而是写 13,00。另外,请注意引号。

  • 运行代码。代码成功运行后,您将收到以下类型的消息:

110 秒后,web.WhatsApp.com 将打开,20 秒后,一条信息将被传递。

在你设定的时间,WhatsApp 会自动在你用来访问 WhatsApp 的浏览器中打开。你写的信息会出现在文本框中,并在 20 秒后自动发送。如果您的互联网连接速度很慢,您的邮件将无法发送。它将保留在文本框内。

您可能会遇到的错误消息

在尝试自动处理 WhatsApp 信息时,你可能会看到我在下面列出的错误信息。我已经包括了你如何解决每个错误。

  • 安装 Pywhatkit 时,您可能会看到以下错误消息:

找不到 zlib 的头文件或库文件,这是从源代码编译 Pillow 时所需的依赖项。

解决方案

升级 pip 和枕头。分别运行以下代码:

  • 从 0 开始计时。例如,9,06。您将得到语法错误:

语法错误:十进制整数文本中不允许前导零;对八进制整数使用 0o 前缀。

解决方案

用 0 以外的数字开始计时。

  • 如果您要发送消息的电话号码没有国家代码。您将得到以下错误:

引发 CountryCodeException("电话号码中缺少国家代码")

pywhatkit . main functions . Country code exception:电话号码中缺少国家代码

解决方案

包括每个电话号码的国家代码。例如+234、+44、+1。

  • 当您的网络速度慢时,您的信息将不会被发送。您将收到以下错误消息:

发出警告(“互联网速度慢,提取信息可能需要更长时间”)

警告:互联网速度较慢,提取信息可能需要较长时间

解决方案

使用强大的互联网连接。

结论

你可以用两行 python 代码实现 WhatsApp 消息的自动化。使用 Pycharm 或任何你觉得舒服的 IDE。安装 Pywhatkit。导入 Pywhatkit。写下你的信息,包括你想发送自动信息的电话号码和你想发送信息的时间。

唷,消息是这样的。

自动化 WhatsApp 信息快乐。

“Python 就像许多优秀的技术一样,很快就像病毒一样在你的开发团队中传播开来,并找到了进入各种应用程序和工具的途径……”——Mustafa Thamer

P.S 作家面临的挑战可能会阻止他们终身写作……久坐导致的慢性背痛、长时间盯着屏幕导致的眼睛问题、写作时手指窒息等等。如果你想继续得到这种类型的文章,你可以通过成为 媒体订户来支持我。每月花费 5 美元。你的一部分订阅费归我

使用 Python 自动生成枯燥的 Excel 报表!

原文:https://towardsdatascience.com/automate-your-boring-excel-reporting-with-python-cb18d1ecce14?source=collection_archive---------21-----------------------

将多个 Excel 文件合并成一个可操作的报告,而无需接触 Excel!

学会自动化你重复、枯燥的 Excel 工作。图片作者:Nik Piepenbreier

Excel 是我们又爱又恨的工具。它擅长做的事情很棒,但不擅长它不该做的事情。在这个数据越来越重要的时代,你经常会收到来自不同来源的工作簿,并被要求用它们创造奇迹。

在这篇文章中,你将确切地了解到这一点——如何用简单的 Python 脚本的力量来施展 Excel 的魔法。

你会学到什么!

假设您收到一堆 Excel 文件,其中包含不同销售人员的销售数据。问题是这些文件除了文件名之外,没有告诉你谁是谁。你被要求找出一些关于销售的高级统计数据!

你将学习如何:

  1. 将多个工作簿合并成一个数据帧,
  2. 创建一个数据透视表,
  3. 用您的所有工作生成最终的 Excel 工作簿。

您将无需实际接触 Excel 就能完成所有工作。

将一堆松散的文件转换成可操作的报告,准备好 Excel 图表!图片作者:Nik Piepenbreier

更喜欢看教程?

我把整篇文章放在一个简单易懂的 YouTube 视频中:

在 YouTube 上看看这个教程吧!资料来源:Nik Piepenbreier

我们开始吧!

让我们从加载我们需要的库开始。在本教程中,您将使用pandasopenpyxlglob。Pandas 是 Python 的精华数据分析库;openpyxl 让我们做一些有趣的 Excel 工作来保存我们的数据(比如创建图表);glob 允许您仔细阅读目录中的不同文件。

如果你想跟着做,可以从这里的我的 GitHub 下载文件。

让我们看看如何使用 glob 来解析不同的文件。出于本教程的目的,我将文件保存在下面的目录中:/Users/nik/Desktop/ExcelMagic。让我们将修改后的文件路径保存到一个变量中。

Glob 允许您查找找到某个模式的文件路径。因为我们在 ExcelMagic 文件夹中寻找 Excel 文件,所以我们可以简单地使用通配符。因此,我们可以使用 glob 来查找所有匹配模式的文件路径:

最棒的是,我们现在有了一个我们想要迭代的所有文件的列表。

提示! 如果你使用的是 Windows,你可能需要通过在你的左引号前加上r来将你的路径字符串转换成原始字符串。

合并我们的文件

获取文件名

当我们查看这些文件时,我们会发现除了文件名之外,没有其他方法可以区分它们。我们要做的是获取文件名

要合并所有这些文件,让我们:

  1. 创建一个空的数据帧,
  2. 遍历列表并创建一个临时数据帧,
  3. 将临时数据帧添加到更大的数据帧中。

我们现在有了一个数据框架,其中添加了一个新列,其中包含雇员的姓名!

汇总数据

现在我们已经在一个数据框架中获得了数据,让我们按销售人员和季度汇总数据,看看谁的销售额最高。

让我们通过编写以下代码来创建一个熊猫数据透视表:

要了解更多关于熊猫的数据透视表,请查看我在这里的帖子。简而言之,以下是主要观点的概述:

  • 数据:您要透视的数据
  • 索引:数据透视表的“行”
  • :数据透视表的“列”
  • :您要使用哪一列进行汇总
  • aggfunc :您希望如何聚合您的数据

当我们使用print(pivot)打印数据透视表时,我们返回以下内容:

最后,让我们将数据保存到 Excel 工作簿中:

我们在这里创建了一个新的变量save_file_path,这样我们以后可以更容易地加载工作簿来格式化数据和添加 Excel 图表。

让我们创建一个 Excel 图表

现在我们有了数据摘要,我们可以使用这个数据框架直接在 Excel 文件中创建一个图表。

为此,我们将使用 openpyxl。让我们开始吧!

让我们看看我们在这里做了什么:

  • 我们已经将工作簿和工作表作为 openpyxl 对象加载,
  • 我们循环了包含我们的值的数据,并将它们格式化为货币,
  • 然后,我们创建了一个条形图对象并插入了数据,并指示 openpyxl 在一个特定的位置(G2)用一个标题保存它
  • 最后,我们将文件保存在同一个位置。

结论

我们在本教程中已经做了很多!我们遍历了许多不同的 Excel 工作簿来合并数据,生成了一个数据透视表和一个 Excel 图表— 所有这些都没有用到 Excel

有问题就留言评论,我会尽力解答。

点击此处订阅(图片由 stickpng.com 提供)

如果你想订阅我的 YouTube 频道,可以看看这里,我经常在这里发布 Python 和熊猫教程。

通过三个简单的步骤自动化您的数据科学项目结构

原文:https://towardsdatascience.com/automate-your-data-science-project-structure-in-three-easy-steps-277c92328d24?source=collection_archive---------13-----------------------

实践教程

快速高效地简化您的数据科学代码库和工具

免费矢量插图来自比例尺

好的代码是它自己最好的文档

Rachael tat man博士在她的演讲中,以一种非常微妙的方式强调了代码可再现性的重要性:

“你为什么要关心再现性呢?因为最有可能需要复制你作品的人……就是你。”

在很多层面上都是如此。你有没有发现自己处于一种很难破译你的代码库的情况?你是否经常以类似于untitled1.pyuntitled2.ipynb的多个文件结束?好吧,如果不是所有人,我们中的一些人无疑在一些场合面临过糟糕的编码实践的冲击。这种情况在数据科学中更为常见。通常,我们限制了对分析和最终产品的关注,而忽略了负责分析的代码的质量。

为什么再现性是数据科学管道中的重要组成部分?我在的另一篇博文中提到了这个话题,我将从那里借用几行文字。一个可重复的例子允许其他人使用相同的数据重新创建您的分析。这很有意义,因为你把你的作品公之于众,让他们使用。如果别人不能复制你的作品,这个目的就失败了。在本文中,让我们看看三个有用的工具,它们可以简化并帮助您创建结构化的、可重复的项目。

创建良好的项目结构

假设您想要创建一个包含代码的项目来分析电影评论的观点。创建良好的项目结构有三个基本步骤:

作者创建项目模板|图像的管道

1.使用 Cookiecutter 数据科学自动创建项目模板

@NounProject 的图标| CC: Creative Commons

在组织机器学习项目的最佳实践方面,社区中没有明确的共识。这就是为什么他们有太多的选择,而这种不明确会导致混乱。幸运的是,有一个变通办法,这要感谢 DrivenData 的人们。他们创建了一个名为 Cookiecutter 数据科学的工具,这是一个标准化但灵活的项目结构,用于进行和共享数据科学工作。几行代码就建立了一系列子目录,使得启动、构建和共享分析变得更加容易。你可以在他们的项目主页上阅读关于该工具的更多信息。让我们进入有趣的部分,看看它是如何工作的。

装置

pip install cookiecutterorconda config --add channels conda-forge
conda install cookiecutter

开始一个新项目

在您的终端上运行以下命令。它会自动用所需的文件填充一个目录。

cookiecutter [https://github.com/drivendata/cookiecutter-data-science](https://github.com/drivendata/cookiecutter-data-science)

使用 Cookiecutter 数据科学|作者图片

在指定的路径上创建一个情感分析项目目录,在上面的例子中是桌面。

新创建项目的目录结构|作者图片

注意 : Cookiecutter data science 将很快迁移到版本 2,因此该命令在未来的使用方式上会有细微的变化。这意味着你必须在上面的命令中使用*ccds ...*而不是*cookiecutter ...* 。根据 Github 库,这个版本的模板仍然可用,但是你必须显式地使用*-c v1*来选择它。当变更发生时,请留意文档。

用 readme.so 创建一个好的 Readme

@NounProject 的图标| CC: Creative Commons

接下来创建项目的框架后,您需要填充它。但在此之前,有一个重要的文件需要更新——README。自述文件是一个减价文件,传达有关项目的基本信息。它告诉其他人项目是关于什么的,项目的许可,其他人如何为项目做贡献,等等。我见过许多人在他们的项目上投入了巨大的努力,但却没能创造出像样的读物。如果你是其中之一,有一些好消息以一个项目的形式出现,这个项目叫做 readme.so

一个善良的人刚刚结束了手动写阅读材料的时代。Katherine Peterson 最近创建了一个简单的编辑器,允许您快速创建和定制项目的自述文件。

Github 甚至转发了凯瑟琳的推文。

编辑器非常直观。您只需单击一个部分来编辑内容,该部分就会添加到您的自述文件中。从大量的收藏品中选择你喜欢的。您也可以根据您希望它们在页面上的位置来移动这些部分。一旦一切就绪,继续复制内容或下载文件并将其添加到现有项目中。

使用 readme.so |图像按作者生成自动阅读材料

将您的代码推送到 Github

@NounProject 的图标| CC: Creative Commons

我们差不多完成了。剩下唯一的事情就是把代码推送到 Github(或者你选择的任何版本控制平台)。您可以通过 Git 轻松做到这一点。这里有一个方便的备忘单,包含了最重要和最常用的 Git 命令,便于参考。

资料来源:https://education.github.com/git-cheat-sheet-education.pdf

或者,如果你用的是 Visual Studio 代码 (VS 代码),像我一样,就已经搞定了。VS 代码使得直接向 GitHub 发布任何项目成为可能,而不必先创建一个存储库。VS 代码将为您创建存储库,并控制它是公共的还是私有的。您唯一需要做的就是通过 VS 代码向 GitHub 提供认证。

通过 Visual Studio 代码将代码推送到 Github 作者图片

这就是建立一个健壮的结构化的项目库所需要的一切。如果您想同步查看所有步骤,下面的视频总结了上述所有步骤。

展示文章中使用的工具的端到端视频

结论

创建结构化的和可重复的项目在开始时可能看起来很困难,但从长远来看却有好处。在本文中,我们看了三个有用的工具,它们可以帮助我们完成这项任务。虽然 cookiecutter data science 给出了一个干净的项目模板, readme.so 会自动填充一个 readme 文件。最后,VS 代码可以帮助我们将项目推到 web 上进行源代码控制和协作。这为一个好的数据科学项目创造了必要的基础。现在,您可以开始处理您的数据,并从中获得见解,与各种利益相关者共享。

👉有兴趣看我写的其他文章。这个 repo 包含了我分类写的所有文章。

在云中自动化您的数据科学项目—第 1 部分,共 2 部分

原文:https://towardsdatascience.com/automate-your-data-science-projects-in-the-cloud-884120a97718?source=collection_archive---------40-----------------------

使用 Azure 功能在云中实现无服务器代码自动化

有一个工作笔记本,里面有一个有趣的案例,理想情况下有一些有意义的结果,这对一个人来说是非常好的。但是,当涉及到向他人展示你的作品时,无论是同事、未来可能的雇主还是仅仅是互联网,一个全自动运行的展示台比通过邮件给某人发送笔记本要“性感”得多。

除了额外的外在好处(更容易的反馈、与结果的交互性、留下印象)之外,在将您的概念证明级别的项目提升为完全可操作的产品时,还会有惊人的内在满足感。

本文包含这个自动化系列的第 1 部分,并阐述了 Azure 函数的概念。

云有时也是美丽的东西,图片来自 pexels

Azure 函数

Azure Functions 是来自微软 Azure 的低成本服务,它可以用来在云中无服务器地执行你的代码——每次执行不到一美分。您可以将这些函数视为一个框架,让您的代码在云中运行。可以通过在浏览器中输入 HTTP 地址或计时器来触发执行。更多关于 Azure 功能的详细信息可以在这里找到。

为了使这个概念更加具体,请查看下面的用例。你拥有一个网站,有人在那里注册。这会向您的 Azure 函数发送一个 HTTP 请求,其中包含人员别名、电子邮件和其他有趣的参数。您的函数从这个请求开始,用这些参数做一些有趣的分类,查询一些信息,生成一封个性化的欢迎邮件并发送给这个人。所有这些都发生在你的网站之外。

低价格是有代价的:在最便宜的级别运行时间被限制在最长 10 分钟,默认设置为大约 5 分钟。为了获得更高的 60 分钟最大运行时间,必须额外付费购买高级计划。在设计管道时,请记住这一点。

这当然使得 Azure 函数很难适合处理大数据或企业级案例,但 Azure 为这些提供了自己的工具套件:Databricks、Synapse、Azure Data Factory 等等。

持久函数的概念是对函数框架的扩展。单个函数可以被自动发布和执行,但是为了创建一个管道,其中一个函数开始一个函数,然后开始第三个函数,发明了持久函数来编排这个过程。

设置您的环境

由于我们将使用 Azure Cloud,我强烈推荐使用微软的 Visual Studio 代码。有了原生 Azure 集成和许多模板,这个编辑器是这项任务的最佳选择。当然,您可以使用您选择的编辑器将您的模型开发成一个整洁的 python 包,然后只使用 VS 代码进行云编排。你可以在这里免费得到编辑器。

VS 代码扩展经理,作者图片

安装后,你有一个有点裸露的编辑器,左边有一个块状图标,让你安装扩展。用它来安装 **Azure 功能,**这个助手将大大减少我们要做的手工工作量。在编辑器的这个部分,你可以找到各种有用的扩展。去狂野和个性化吧——毕竟,是你要和它一起工作。此外,确保从这里安装 Azure 核心工具。

Azure 函数入门

创建新项目

使用命令面板⇧⌘P (Windows: Ctrl+Alt+P)在你喜欢的地方创建一个项目:输入“azure functions:create new project”并点击 enter。这是编辑器所有功能的主要枢纽。从设置、代码模板到 GitHub 版本控制,一切都可以在这里完成。

你可以从命令面板执行几乎每一个动作

选择一个路径(稍后会详细介绍),选择 python 作为一种语言,选择一个 Python 解释器,选择 HTTP Trigger 作为模板,给你的函数起一个名字(我把它命名为 MyTrigger)并选择 anonymous。您为新项目选择的文件夹必须是包含所有应该在云中运行的代码的路径。我找不到从高于 Azure Function Projects 基本路径的文件夹级别导入代码的方法。

文件结构

从这些模板创建项目和函数也创建了大量新文件。乍一看,这似乎让人不知所措,但是下面的列表包含了对重要文件的解释以及您可以用它们做什么。

创建项目和 Azure 函数后的文件结构,作者图片

  • host.json
    这个文件包含了一些关于项目的元信息,尤其是扩展包的版本号。这意味着我们用于数据科学项目自动化的 Azure 核心工具的版本。您可以将 Azure 函数与默认版本[1]一起使用。,2.0.0),但是因为我们想在以后使用持久函数来实现自动化,所以将版本设置为[2。,3.0.0)并重新启动编辑器。
  • requirements.txt
    这听起来应该很熟悉。无论您使用 Conda、pip 还是任何其他适合您的解决方案,在某种程度上,您都创建了一个包含所有使用过的包的 Python 环境。Azure 函数不使用这些环境。相反,在部署到云的过程中,环境是根据给定的 requirements.txt 创建的。
    幸运的是,有一些方法可以自动生成这个文件,
    pip freeze > requirements.txt
    就是这样一个解决方案。随着代码的增长,记得在这个文件中添加新的包。
    还要确保azure-functionsazure-functions-durable>=1.0.0b12已列出。
  • 。这个文件夹包含调试 Azure 函数时使用的 Python 环境。
  • MyTrigger/function.json
    这个文件包含了关于你的函数的元信息,它是什么类型,它是如何被触发的等等。它还可以用来设置可以从代码中读取的全局参数。
  • My_Trigger/init。py
    这个文件现在包含了主函数中的实际代码。这是你可以剪切掉中间部分,导入你的包并在主区域执行它的地方。但稍后会详细介绍。预先配置的功能。HttpResponse 由 main 函数返回,这是您的函数完成后将显示的消息。

排除故障

设置完成后,我们现在可以开始执行新创建的函数 MyTrigger。首先,打开命令面板(⇧⌘P),输入“查看:切换集成终端命令”。在编辑器的底部,应该会打开一个外壳。执行以下语句来更新中的 python 环境。venv 文件夹:

source .venv/bin/activate (Windows: .venv\scripts\activate)
python -m pip install -r requirements.txt

现在按 F5 键或打开 Run 并选择 Start Debugging 来启动主机。请注意,一旦设置好主机并且准备好执行您的函数,编辑器底部的蓝色条就会变成橙色。

这是你的函数准备好启动时的样子,作者图片

你的函数是用黄色和绿色写的,一个触发它的链接。按住 Command 键并单击链接,会打开一个浏览器窗口,执行您的功能。注意,在成功执行代码后,返回的 func。HttpResponse(来自 init。py 文件)。在编辑器的底部,错误消息或日志以蓝色显示。

有时你必须忽略编辑器突出显示的一些错误,因为它并不总是完全理解 Azure 函数的架构,并且可能对导入的处理方式很不满意。

另一方面,注意:我强烈推荐使用“logging.info”进行日志记录,就像模板中一样。这些消息在调试过程的执行过程中显示,并且一旦部署了该过程,也可以在云中轻松地免费阅读。如果您的代码中有一些自定义日志记录,将它切换到这种日志记录风格或者添加一个参数并使它自己相应地切换是一个好主意。

在代码中使用 azure 函数

在一些前期工作之后,我们来到了有趣的部分:添加你的定制代码,你的酷模型,你的价值生成脚本。

现有代码的示例导入,作者的图片

确保您的自定义代码在上面创建的项目文件夹中,并测试它以确保它可以顺利运行。现在剩下的就是导入代码并调用函数了。如果您已经将所有代码合并到一个 main 函数中,事情就变得简单了,因为现在您只需在 init 中调用它。py 和你玩完了。

就这么简单。

使用 F5 键调试您的代码,并使其在 Azure Functions 框架内运行。如果你想要一个例子作为参考,你可以从我的 repo 中这个文件,在那里我自动将数据从 Azure SQL DB 加载到 tableau 仪表板的 google sheets 文档。如果你想了解更多细节,你可以访问我关于这个话题的文章这里,在我的主页这里查看结果。

部署和无服务器执行

既然你的 Azure 功能已经完全开发好了,剩下的最后一步就是让奇迹发生:部署。

为了部署到 Azure,您必须已经创建了一个 Azure 帐户(显然)。点击左侧的 Azure 图标并连接到您的帐户。一旦建立了连接,你必须点击向上的蓝色小箭头。这将启动 Azure 功能的部署过程。

VS Studio 代码中的 Azure 窗口,圈起来的是部署按钮,作者图片

首先,它要求你创建一个新的“功能应用”或部署到一个已经存在的应用。据我所知,创建和拥有这样的 anApp 是完全免费的,所以继续创建一个新的吧。它基本上是你各种功能的管理工具:你可以查看日志,检查性能,并在一些语言中直接在你的 Azure 门户中从功能应用程序中编辑功能 coce(Python 不是这些语言中的一种)。

部署完成后,打开 azure 门户并检查你的功能应用。通过点击功能菜单,你可以访问所有已部署的功能,当你点击一个功能时,还可以看到一些不错的元信息。

对示例性 Azure 功能的概述,作者的图片

在功能概述中,实际的 URL 可以在“获取功能 URL”按钮下获取。复制 URL 并将其粘贴到您的浏览器中—您的功能将被执行。延迟一段时间后,您可以进入 Monitor 选项卡并检查执行情况:您可以查看函数执行的时间,它是否成功执行,并检查每次执行的日志(只需单击蓝色时间戳)。有关日志的更详细分析,请单击“在应用洞察中运行查询”按钮。但是我不会在我的文章中对此进行更详细的描述。

现在,您可以随时随地在云中执行您的代码。哦,我提到过你可以在 URL 中添加参数并在你的代码中读出它们吗?来自任何进程的完全参数化的函数调用。粘贴 URL,从您最喜欢的管道中呼叫。看看这提供的所有可能性。

发挥创意,尽情奔跑!

摘要

放弃控制并开始依赖一些模糊的框架让人感到不安。开发人员尤其习惯于对他们的代码拥有最终的控制权,可能会感到不止一盎司的怀疑。但是在前置设置之后,Azure 函数变得非常容易操作,并开启了一系列全新的可能性。

随着经验的积累,你将开始理解这个 Azure Functions 框架的内部运作,从而使它不再模糊不清,而是成为你不断发展的数据科学工具箱中一个新的强大的前沿工具。

将您的数据科学工作从笔记本电脑中的概念验证提升到完全可用的微型产品。超越你的竞争对手。带着对云的一点信任。

有时候真的就是这么简单。

下一篇文章:构建管道

请继续关注我的自动化系列的第 2 部分,在那里我将解释我们如何使用持久函数将 Azure 函数链接在一起,并从一个简单的触发器协调整个执行管道。

无耻的自我推销

在此之前,请阅读我的其他文章,访问我的投资组合网站,并在 Twitter 上关注我,关注@88Andreasd。

通过使用 Python 创建摘要表来自动化您的 Excel 报表

原文:https://towardsdatascience.com/automate-your-excel-report-by-creating-a-summary-sheet-using-python-6fdb26480c3b?source=collection_archive---------2-----------------------

Python + Excel

如何协调 Python 和 Excel,用一种像样的、专业的格式来总结你的数据?改进 Excel 报表的一种方法。

卢卡·布拉沃在 Unsplash 上的照片

简介

创建一个独特的和可展示的摘要页面是任何基于 Excel 的报告工作的最后一步。没有这些,你只能得到一张张的数字和公式,很难从你的基础数据中得出结论。通过创建摘要表,工作簿的查看者将能够立即以美观的格式理解数据。

在这个 Python + Excel 系列的前面,您学习了如何使用 Python 格式化 Excel 电子表格。这次我们将看看如何使用格式化代码在 Excel 中制作一个汇总表/仪表板。

在我的上一篇文章中,我写了一些推理,解释了为什么你想将 Excel 与 python 一起使用,python 与 pandas 和 xlwings 如何能极大地改善你的 Excel 繁重的工作流程,并包括一个简短的教程,其中有一些例子,让你开始对你的 Excel 电子表格进行样式化。

您可以在下面的链接中找到所有这些信息;这可能是一个很好的起点,因为本文不会详细讨论相同的主题。

我这篇文章的目标是帮助你在使用我上一篇文章中学到的 Excel/python 格式化技巧的同时总结你的数据。我们将对数据进行旋转、分组和排序。然后制作图表、设计风格并向摘要页面添加徽标。这些技能相结合将使您能够在一个简单的 python 脚本中对数据进行汇总和格式化。希望这篇文章和上一篇一样有用!

汇总数据

如果您的工作流程是 Excel 繁重的,我敢肯定您有跨越多个选项卡的工作簿、许多数据透视表和更多交叉引用每张工作表的公式。这很好…如果你的目标是迷惑所有试图理解你的电子表格的人。

使用 Python 汇总数据的一个好处是能够将数据透视表和其他数据存储为单个变量中的数据帧。以这种方式引用更容易调试,而不是试图通过电子表格中的多个选项卡来跟踪数字。

pandas —本模块对于成功总结您的数据至关重要。

根据熊猫网站:

pandas 是一个快速、强大、灵活且易于使用的开源数据分析和处理工具

简而言之,pandas 包含的功能可以完成你通常在 Excel 中所做的所有数据分析。以下是一些您会对基于 Excel 的背景感兴趣的函数,如果您想了解更多信息,每个函数的文档都有超链接:

  • value_counts()
  • drop_duplicates()
  • groupby()
  • 形容()
  • 【pivot _ table()(每个 Excel 用户的最爱)
  • 剧情()
  • 数据类型
  • loc
  • 国际劳工组织理事会

这些是 pandas 众多功能中的几个例子,可以用来操作或快速总结你的数据。

创建汇总表的步骤

如前所述,本教程中格式化电子表格的代码已经在我的上一篇文章“用 Python 格式化和自动化 Excel 文件”中详细解释过了。本教程将在前面的基础上增加一些新的功能来创建一个快速、美观和全面的汇总表。

我创建了一个 csv 格式的水果和蔬菜销售测试数据集,用于本教程和上一教程。

可以从 Github 下载数据:链接

  1. 第一步是导入我们将使用的模块。几乎所有的教程都将使用熊猫和 xlwings 来完成。
import pandas as pd
import numpy as np
import xlwings as xw
import matplotlib.pyplot as plt

2.使用 Pandas 将 csv 数据导入数据框架。有两种方法可以做到这一点,直接从 Github 读取或下载到您的本地驱动器并引用。两者在完整的剧本中都有提及。下面的片段将直接从 Github 中读取。

df = pd.read_csv(r”[https://raw.githubusercontent.com/Nishan-Pradhan/xlwings_dashboard/master/fruit_and_veg_sales.csv](https://raw.githubusercontent.com/Nishan-Pradhan/xlwings_dashboard/master/fruit_and_veg_sales.csv)")

3.下面的步骤初始化一个 Excel 工作簿,重命名 Sheet1 并将我们的 DataFrame 复制到 Excel。

wb = xw.Book()
sht = wb.sheets["Sheet1"]
sht.name = "fruit_and_veg_sales"
sht.range("A1").options(index=False).value = df

4.接下来,我们想创建一个名为“Dashboard”的新工作表,并引用该工作表。

wb.sheets.add('Dashboard')
sht_dashboard = wb.sheets('Dashboard')

我们现在有一个包含两张工作表的 Excel 工作簿。“水果蔬菜销售”有我们的数据,而“仪表板”是空白的。

5.我们现在将开始使用 pandas 来处理我们的数据,并生成我们的数据摘要,以包括在我们的空白表上。第一步是检查数据集中的列名。在 Python 中查看所有列名的快捷方式是运行下面一行:print(df.columns)

df.columns |作者图片

从这里我们可以看到,许多列名包含空格、括号、美元符号、大写字母和括号,很不方便。

为了防止我们犯小错误并节省大量调试时间,在用 pandas 引用这些列名时,复制并粘贴它们是明智的。(在较大规模的项目中,重命名列可能更好)

6.我们将为仪表板表创建的第一个摘要将是显示每件售出商品的总利润的数据的枢纽。为此,我们将利用 pandas 的pd.pivot_table()功能。

pv_total_profit = pd.pivot_table(df, index='Item', values='Total Profit ($)', aggfunc='sum')

这里我们创建了一个新的数据帧,名为pv_total_profit。这个数据帧有一个索引,包含我们的 Item 列中的每个值。显示的值来自我们数据中的“总利润(\()”列,我们指定的函数的最终输入是`aggfunc='sum'`,这告诉 Pandas 我们希望通过对`values`列求和来汇总我们的数据,在本例中是“总利润(\))”。

pv_total_profit 数据框架透视|作者图片

7.我们现在再次执行相同的步骤,只是这一次我们希望透视我们的数据,以显示每件售出商品的数量。

pv_quantity_sold = pd.pivot_table(df,index='Item',values='Quantity Sold',aggfunc='sum')

8.你可以制作一个简单枢纽的整个仪表板或报告,这将看起来很棒,然而,为了使本教程更有趣,我们将使用一个分组函数:df.groupby()将你的数据按你指定的方式分组。

由于我们的数据与过去一年的销售数字有关,因此查看按月而不是按天分组的数据可能会有用。我们会做到这一点,但首先我们需要确保我们的“售出日期”栏确实被熊猫作为日期读取。****

检查该运行print(df.dtypes)

您应该能够从这里看到,我们的“售出日期”列被作为一个对象读取,而不是日期时间格式。这意味着我们还不能很容易地按月对数据帧进行分组。

我们可以将该列的数据类型更改为 datetime,如下所示:

df[“Date Sold”] = pd.to_datetime(df[“Date Sold”], format=’%d/%m/%Y’)

这里,pd.to_datetime()格式化我们的列,我们指定原始数据的格式,以确保它被正确地从对象转换成日期时间。如果你再次运行df.dtypes,你会看到“销售日期”是datetime64[ns]的格式,这是我们分组工作所需要的。

******

数据类型:转换前(左)、转换后(右)|按作者分类的图像**

9.现在我们的数据有了正确的格式,我们可以使用下面的代码行来合计和聚合我们的数据,并显示相关的列。

gb_date_sold = df.groupby(df["Date Sold"].dt.to_period('m')).sum()[["Quantity Sold",'Total Revenue ($)',  'Total Cost ($)',"Total Profit ($)"]]

我们按月分组的数据现在看起来像这样:

gb_date_sold |作者图片

10.最后一个 groupby 将为我们的仪表板提供第四个数据集。

gb_top_revenue = (df.groupby(df["Date Sold"]).sum().sort_values('Total Revenue ($)',ascending=False).head(8))[["Quantity Sold",'Total Revenue ($)','Total Cost ($)',"Total Profit ($)"]]

这个 groupby 向我们展示了总收入排名前 8 位的。我们通过按“总收入”降序(最高收入在顶部)对数据框架进行排序来实现这一点,然后我们使用head(8)给出排序后数据的前 8 行。****

11.现在我们已经有了 4 个数据摘要,我们可以继续创建报告了。首先,我们从一些静态格式开始。

**# Background
sht_dashboard.range('A1:Z1000').color = (198,224,180)# A:B column width
sht_dashboard.range('A:B').column_width = 2.22# Title
sht_dashboard.range('B2').value = 'Sales Dashboard'
sht_dashboard.range('B2').api.Font.Name = 'Arial'
sht_dashboard.range('B2').api.Font.Size = 48
sht_dashboard.range('B2').api.Font.Bold = True
sht_dashboard.range('B2').api.Font.Color = 0x000000
sht_dashboard.range('B2').row_height = 61.2# Underline Title
sht_dashboard.range('B2:W2').api.Borders(9).Weight = 4
sht_dashboard.range('B2:W2').api.Borders(9).Color = 0x00B050# Subtitle
sht_dashboard.range('M2').value = 'Total Profit Per Item Chart'
sht_dashboard.range('M2').api.Font.Name = 'Arial'
sht_dashboard.range('M2').api.Font.Size = 20
sht_dashboard.range('M2').api.Font.Bold = True
sht_dashboard.range('M2').api.Font.Color = 0x000000# Line dividing Title and Subtitle
sht_dashboard.range('L2').api.Borders(7).Weight = 3
sht_dashboard.range('L2').api.Borders(7).Color = 0x00B050
sht_dashboard.range('L2').api.Borders(7).LineStyle = -4115**

上面代码片段中的副标题应该解释代码的每一部分是做什么的。

12.我创建了以下函数来手动创建特定的表格格式。这是相当长的,所以我将打破它在这一步做什么。

上面的函数有 4 个输入,header_cell, title, df_summary, color

  • header_cell 是一个字符串,表示您要放置数据帧摘要的右上角单元格(例如“B5”)。
  • 标题是您希望为摘要命名的字符串(例如,“前 8 天的收入”)。
  • df_summary 是您希望格式化并放在 Excel 仪表板页面上的 Pandas 数据框架。
  • color 是引用函数中预定义颜色的字符串(例如“蓝色”)。

在函数中,我们首先定义一个颜色字典。

**colors = {“purple”:[(112,48,160),(161,98,208)],
“blue”:[(0,112,192),(155,194,230)],
“green”:[(0,176,80),(169,208,142)],
“yellow”:[(255,192,0),(255,217,102)]}**

这里我们命名了 4 种颜色,紫色、蓝色、绿色和黄色。对于每种颜色,在元组中有两种色调,一种较暗的色调和一种较亮的色调,两者都是 RGB 格式。任何颜色都可以添加到这里,如果你想扩大这个范围!

其余的格式化是动态引用我们在函数输入中指定的 header_cell,并自动为您格式化表格的其余部分。

13.接下来,我们调用该函数 4 次,为我们创建的每个数据帧摘要调用一次。

**create_formatted_summary('B5','Total Profit per Item', pv_total_profit, 'green')create_formatted_summary('B17','Total Iteams Sold', pv_quantity_sold, 'purple')create_formatted_summary('F17','Sales by Month', gb_date_sold, 'blue')create_formatted_summary('F5','Top 5 Days by Revenue ', gb_top_revenue, 'yellow')**

14.最后,我们使用 Matplotlib 和 pandas .plot()函数(调用 Matplotlib)制作一个图表

**# Makes a chart using Matplotlib
fig, ax = plt.subplots(figsize=(6,3))
pv_total_profit.plot(color='g',kind='bar',ax=ax)# Add Chart to Dashboard Sheet
sht_dashboard.pictures.add(fig,name='ItemsChart',
    left=sht_dashboard.range("M5").left,
    top=sht_dashboard.range("M5").top,
    update = True)**

上面的第一部分创建了一个条形图,带有绿色的条形颜色。

然后sht_dashboard.pictures.add() xlwings 函数允许我们在 Excel 仪表板上放置该图表的图像。我们用lefttop参数指定我们想把它放在哪里。name也会在 Excel 中给我们的形象起一个名字。

奖金

为了让你的 Excel 仪表盘看起来更专业,我们甚至可以添加一个 logo 。下面的代码将从 Github 资源库下载一个 png 格式的小示例徽标,保存它,将其添加到我们的 Excel 仪表板,然后调整其大小。确保你已经在 FOLDER_PATH 变量中指定了保存 png 图像的位置。(Github 上的脚本顶部)

**import requestsFOLDER_PATH = r"path_to_save_folder" # r"C:\Users\Name\Downloads"image_url = r”[https://github.com/Nishan-Pradhan/xlwings_dashboard/blob/master/pie_logo.png?raw=true](https://github.com/Nishan-Pradhan/xlwings_dashboard/blob/master/pie_logo.png?raw=true)”r = requests.get(image_url, stream = True)
image_path = rf"{FOLDER_PATH}\logo.png"# Saves image to image_path above
file = open(image_path, "wb")
file.write(r.content)
file.close()# Adds image to Excel Dashboard
logo = sht_dashboard.pictures.add(image=image_path,
    name='PC_3',
    left=sht_dashboard.range("J2").left,
    top=sht_dashboard.range("J2").top+5,
    update=True)# Resizes image
logo.width = 54
logo.height = 54**

我们现在已经为数据集创建了仪表板摘要!不要忘记通过运行以下命令来保存它:

**wb.save(rf”{FOLDER_PATH}\fruit_and_veg_dashboard.xlsx”)**

作者使用 xlwings | GIF 格式的摘要表

结论

用不多的代码,我们创建了一个美观的仪表板,可以快速汇总我们的数据。用 Python 来做这件事的优点是易于阅读的语法、相对较少的代码行和使用第三方模块的组合,这可以节省我们总结数据的大量时间。

使用 Python 格式化 Excel 报表可以是手动创建 Excel 报表(或使用 VBA)和用替代报表软件完全替换 Excel 之间的中间步骤。能够以这种粒度级别与 Excel 进行交互使您能够加快工作流程、自动化报告并提高 Python 编码技能,同时为最终用户提供熟悉的输出。

这段代码应该足以让您入门;你可以随意定制。尝试改变颜色,边框,标题,背景色,标志,这里提到的几乎任何东西都可以改变,以符合你想要的风格。

任何创建函数以编程方式排列这些格式化摘要的人都会得到加分!

本教程中使用的代码可从 Github 这里 获得

如果你被卡住了,检查 xlwings 文档 这里

如果你还有任何问题,请在下面的评论区留言。

注:本文仅代表个人观点和经验。

**** ****

使用 Python 自动化您的 Excel

原文:https://towardsdatascience.com/automate-your-excel-using-python-91a7217e7e44?source=collection_archive---------25-----------------------

从手动到自动化的方法

图片由 Alexas Fotos 来自 Pexels

Python 是一种令人惊叹的编程语言。更容易学习和适应。python 中的错误消息是不言自明的。我们不需要花时间去寻找错误信息的解决方案。这就是我喜欢这种编程语言的原因。

我觉得这应该是最理想的编程语言。编程语言的目标应该是帮助我们构建令人兴奋的产品,而不是浪费时间解决错误。

最近,我学习了使用 python 自动化 excel 任务。我想与更多的观众分享这些惊人的技巧。这种自动化策略使用 python 编程。好的一面是 python 代码的每一行都是自我解释的,你不需要谷歌任何东西。

您可以使用自己选择的代码编辑器。在本文中,我将使用 Jupyter 笔记本进行演示。

安装所需的库

我们需要安装一个 python 库,openpyxl。在命令提示符下键入以下命令。

pip install openpyxl

加载现有工作簿

如果您有一个现有的 excel 工作簿,并且您想从特定的工作表中读取数据或修改任何工作表中的数据,openpyxl提供了一个名为load_workbook()的函数,可以如下使用。

from openpyxl import Workbook, load_workbookwb = load_workbook('my_demo_sheet.xlsx')

演示工作表

访问工作表

如果要访问活动工作表中的内容。那么 workbook 有一个名为active的属性,它可以帮助我们指向活动工作表。

ws = wb.active
print(ws)

但是,如果你想指向任何其他工作表,那么我们可以这样做。在这里,我从我的 excel 表中访问sheet2

ws = wb["Sheet2"]

访问单元格值

一旦我们定义了工作表,我们就可以引用工作表中的任何单元格。

cell_to_access= ws['A5']

为了获得单元格的值,我们必须使用value 属性。

cell_value = ws['A5']

更改单元格的值

我们可以使用下面一行代码来更改 excel 表格中的任何值。

ws['B1'].value="Second Tab"

我们还需要保存更改,如下所示。

wb.save("my_demo_sheet.xlsx")

获取工作表名称

如果您想知道工作簿中可用工作表的名称,您可以使用下面的 python 代码行来获取列表形式的工作表名称。

print(wb.sheetnames)

访问其他工作表

使用.active属性,我们可以访问默认的活动工作表。如果您想访问另一个表,即摘要,我们可以如下操作。

ws = wb["summary"]

创建新工作表

要在同一个 excel 工作簿中创建一个新的工作表,我们可以使用如下所示的create_sheet()。当我们修改工作表时,我们需要保存工作簿以将更改应用到 excel 工作簿。

wb.create_sheet("Index_sheet")
wb.save("test1.xlsx")

创建新工作簿

创建新的 Excel 工作簿非常简单。我们需要调用函数Workbook()。由于这是一个新工作簿,我们需要将该工作表设置为默认工作表。我们还可以使用title属性更改工作表的名称。

wb = Workbook()

定义默认工作表。

ws = wb.active
ws.title = "Demo_data"

向工作表添加数据

一旦我们定义了工作表,我们就可以使用append函数添加数据。这将按行添加数据。

ws.append(["This","Is", "A", "Header"])
ws.save("New_WB.xlsx")

添加新行

我们可以使用insert_rows()来添加任意数量的行。该函数将 row_number 作为输入。

for i in range(2):
    ws.insert_rows(row_num)

删除行

我们可以使用delete_rows()功能删除任何一行。该函数将 column_number 作为输入。

for i in range(3):
   ws.delete_rows(col_num)

添加新列

如果你想插入任何列,那么insert_cols()功能可以使用循环添加任何列。该函数将 column_number 作为输入。

ws.insert_cols(column_number)

删除列

要删除任何列,可以使用以列号为输入的delete_cols()函数。

ws.delete_cols(column_number)

在 excel 表中移动数据

假设您有一个包含数据的 excel 表,并且您想要将行或列的任何部分移动到另一个位置。

移动前

我们可以使用move_range()来移动我们的数据。该函数有三个参数—选定的数据、要移动的行数(+N,-N)和要移动的列数(+N,-N)。

ws.move_range("B2:D9", rows=0, cols=2 )

结论

本文到此为止。我们已经介绍了自动化 excel 任务的不同场景。这些任务也可以在 excel 中手动完成。但是,如果有一些重复的场景,您可以根据您的要求在这个自动化策略上投入一些时间,以节省您的日常时间。

我希望你喜欢这篇文章。谢谢你的阅读!

以下是我的一些最佳选择:

https://levelup.gitconnected.com/six-ultimate-daily-hacks-for-every-programmer-60f5f10feae https://betterprogramming.pub/how-a-single-mistake-wasted-3-years-of-my-data-science-journey-b7ca1e962085

走之前……

如果你喜欢这篇文章,并且想继续关注更多关于 Python &数据科学精彩文章——请点击这里https://pranjalai.medium.com/membership考虑成为一名中级会员。

请考虑使用我的推荐链接注册。通过这种方式,会员费的一部分归我,这激励我写更多关于 Python 和数据科学的令人兴奋的东西。

还有,可以随时订阅我的免费简讯: 普朗加尔的简讯

在一行 Python 代码中实现要素选择工作流的自动化

原文:https://towardsdatascience.com/automate-your-feature-selection-workflow-in-one-line-of-python-code-3d4f23b7e2c4?source=collection_archive---------9-----------------------

使用 Featurewiz 快速选择特征

图片来自阿雷克索查来自皮克斯拜

就实例数量而言,更多的训练数据会产生更好的数据科学模型,但这不适用于特征数量。真实世界的数据集有许多要素,其中一些对于训练稳健的数据科学模型非常有用,而其他一些则是会影响模型性能的冗余要素。

特征选择是数据科学模型开发工作流的一个重要元素。选择所有可能的特征组合是多项式解决方案。数据科学家使用各种特征选择技术和技巧来移除冗余特征。

阅读这篇文章,了解 7 个特征选择技巧。

在本文中,我们将重点介绍如何使用开源 Python 包 Featurewiz 实现特征选择工作流的自动化。

Featurewiz:

Featurewiz 是一个开源库,用于从数据集中创建和选择最佳特征,这些特征可进一步用于训练稳健的数据科学模型。Featurewiz 还提供了功能工程功能。只需点击一下代码,它就可以创建数百个新功能。Featurewiz API 有一个参数**‘feature_engg’**,可以设置为**‘interactions’****‘group by’****‘target’**,它会一口气创建上百个特性。

功能工程或创建新功能不仅仅是 featurewiz 的功能。它可以减少特征的数量,并选择最佳的特征集合来训练鲁棒的模型。

Featurewiz 是如何工作的?

Featurewiz 使用两种算法从数据集中选择最佳要素。

  • 苏洛夫
  • 递归 XGBoost

苏洛夫:

SULOV 代表 搜索不相关的变量列表 ,非常类似于 mRMR 算法。SULOV 算法遵循的步骤如下:

  1. 计算所有超过阈值的相关变量对。
  2. 相对于目标变量计算 MIS(交互信息得分)。
  3. 比较每一对相关变量,并移除具有低 MIS 的特征。
  4. 其余特征具有高的 MIS 和低的相关性。

递归 XGBoost:

在 SULOV 算法选择具有高 MIS 和对数相关性的最佳特征集之后,使用重复 XGBoost 算法来计算剩余变量中的最佳特征。步骤如下:

  1. 为剩余的要素集构建数据集,并将其分为训练和验证两部分。
  2. 使用验证计算列车上的前 10 个特征。
  3. 每次使用不同的功能集重复步骤 1 和 2。
  4. 组合所有 10 个特征的集合,并对它们进行去重复,这将产生最佳的特征集合。

Featurewiz 使用上面讨论的两种算法来寻找最佳的特征集,该特征集可以进一步用于训练健壮的机器学习模型。

安装和使用:

Featurewiz 可以使用 Pypl 安装

**pip install featurewiz**

安装后,可以导入 featurewiz:

**from featurewiz import featurewiz**

现在,开发人员只需要编写一行代码,就可以从数据集中获得最佳的功能集。

**out1, out2 = featurewiz(dataname, target, corr_limit=0.7, verbose=0,   sep=",", header=0, test_data="", feature_engg="", category_encoders="")**

Featurewiz 不仅可以处理具有一个目标变量的数据集,还可以处理具有多标签目标变量的数据集。从 featurewiz 返回的数据框包含最佳的要素集,可用于模型训练。开发者不需要指定问题的类型,如果是回归或分类,特性可以自动决定它。

结论:

在本文中,我们讨论了一个开源库 featurewiz,它可以自动选择数据集的特性。除了功能选择,featurewiz 还具有执行功能工程和生成数百个功能的能力,只需点击一下代码。
Featurewiz 使用两种算法(SULOV 和递归 XGBoost)来选择最佳的特性集。Featurewiz 只需点击一行代码即可完成整个功能选择,从而加快了数据科学家的工作流程。数据科学家可以使用几种特性选择技术来筛选出最佳特性,您可以在下面提到的文章中阅读其中的 7 种特性选择技术。

参考资料:

[1] Featurewiz GitHub 回购:https://github.com/AutoViML/featurewiz

感谢您的阅读

自动化您的终端改造

原文:https://towardsdatascience.com/automate-your-terminal-makeover-f3c152958d85?source=collection_archive---------25-----------------------

安装终端是你用新电脑做的第一件事吗?如果是,那么这是给你的。

在 Unsplash 上由 Haseeb Jamil 拍照。作者 Gif。

【更新:2021–12–18,font-fira-code-nerd-font 新增。]

《走向数据科学》在 2020 年 4 月发表了我的文章终端改造的终极指南。这是我最受欢迎的文章之一。自发布以来,它已经有超过 12 万的浏览量,每天大约 300 次。

这个月我不得不在我的新笔记本电脑上安装终端。按照我自己文章中的步骤,我想“嗯,我可以自动化所有这些安装。”

随后,我创建了TerminalMake overAautomated(Terma)。它会自动在新 Mac 上安装以下软件包:

  • 自制
  • iTerm2
  • ZSH
  • 哦-我的-Zsh
  • 星际飞船
  • 时髦的主题
  • 书呆子字体
  • iTerm2 首选项列表
  • 插件:自动跳转, brew , git ,zsh-语法-高亮,以及zsh-自动建议。

警告

我为一台新的 Mac 电脑创造了 Terma。如果你已经安装了 iTerm2 和插件,我建议保存~/.oh-my-zsh目录、~/.zshrc文件和~/Library/Preferences/com.googlecode.iterm2.plist

我建议首先使用 Automate Brew Installer 来保存您的 Brew 列表,然后在 Terma 安装完成后重新安装。

https://betterprogramming.pub/how-to-automate-homebrew-installs-on-your-new-mac-or-linux-51e06881c5b7

我推荐使用 Dotties 来保存你的.zshrc和其他点文件。

然后安装 Terma 并运行几次terma uninstall,从终端而不是 iTerm 卸载上面的包。然后运行terma两次。

安装 Terma

在查找器上查找终端。作者截图。

打开一个终端,安装牛逼包管理器。

https://medium.com/mkdir-awesome/a-new-simple-package-manager-for-script-languages-a1228fd0972a

安装令人敬畏的软件包管理器很容易。在您的终端上运行以下命令:

curl -s https://raw.githubusercontent.com/shinokada/awesome/main/install | bash -s install

一旦你安装了 Awesome 软件包管理器,安装 Terma。

awesome install shinokada/terma

入门:运行 terma 两次!

要在终端上运行 terma,请执行以下操作:

terma

安装家酿软件时,你会被要求输入密码。

Oh-My-Zsh 安装退出脚本,所以需要再次运行terma

terma

安装 Terma。图片作者。

iTerm2 准备好摇滚了!

当您打开新安装的 iTerm 时,按 Ctrl+右键并选择 open。

iTerm 首选项配置文件设置为名称“Terma”,颜色预设为时髦,字体为 Fira 代码。

可以使用 brew 别名,比如bubu,自动建议,自动跳转,以上所有插件。

运行中的插件。图片作者。

打印帮助

terma -h

卸载 Terma

您可以删除所有已安装的项目,包括 Homebrew。我建议先用自动 brew 安装保存你的 Brew 列表。

terma uninstall

我从写 Terma 中学到了什么

起初,我在 Bash 中编写脚本,然后运行source $HOME/.zshrc需要一个 ZSH 脚本。我把剧本改成了 ZSH。我需要改变的只是read命令。

# Bash
read -rp "Do you want to uninstall? yes/y or no/n   " PANS# ZSH
read "PANS?Do you want to uninstall Y/y or N/n?   "

该脚本使用自制软件安装除 Oh-My-Zsh 之外的软件包。为了避免不必要的错误消息,脚本提供了适当的.zshrc文件。对于 iTerm2 配置文件,它将一个预制的com.googlecode.iterm2.plist文件复制到~/Library/Preferences目录。

该脚本使用 heredoc 来显示最终消息。 Figlet 程序可以创建大字母。

结尾的留言是菲戈莱特和赫雷多克做的。图片作者。

结论

由于您将使用 Terma 安装许多程序,因此需要一些时间来完成。我在我的 2015 Mac (x86_64)和 2021 Mac (ARM 64,M1 芯片)上测试了terma,它运行得完美无缺。

如果您有自己喜欢的 iTerm2 设置,请用~/Library/Preferences/com.googlecode.iterm2.plist目录中的 plist 文件替换 Terma 的com.googlecode.iterm2.plist

编码快乐!

通过 成为 会员,可以完全访问媒体上的每个故事。

【https://blog.codewithshin.com/subscribe】

在一行 Python 代码中自动化您的文本处理工作流程

原文:https://towardsdatascience.com/automate-your-text-processing-workflow-in-a-single-line-of-python-code-e276755e45de?source=collection_archive---------7-----------------------

使用 CleanText 库处理 NLP 任务的文本数据

由 Unsplash 上的窗口拍摄

自然语言处理(NLP)是人工智能的一个子领域,涉及计算机和自然语言之间的交互。它围绕着如何训练一个可以理解和实现自然语言任务用法的数据科学模型。典型的 NLP 项目遵循流水线的各个方面来训练模型。流水线中的各个步骤包括文本清理、记号化、词干化、编码成数字向量等,然后是模型训练。

为 NLP 任务导出的数据集是文本数据,主要来自互联网。大多数时候,用于 NLP 建模的文本数据是脏的,需要在数据处理的早期进行清理。数据科学家将大部分时间花在数据预处理上,包括清理文本数据。

在本文中,我们将讨论一个有趣的库 CleanText,它简化了清理文本数据的过程,并加快了数据预处理管道。

什么是 CleanText?

图片由米哈尔·贾莫鲁克拍摄,来自皮克斯拜

CleanText 是一个开源的 Python 库,它能够清除从 web 或社交媒体上搜集的文本数据。CleanText 使开发人员能够创建规范化的文本表示。CleanText 使用 ftfy 、 unidecode 和各种其他硬编码规则(包括 RegEx)将损坏或不干净的输入文本转换为干净的文本,可以进一步处理这些文本以训练 NLP 模型。

安装:

可以使用以下命令从 PyPl 安装 CleanText 库:

**pip install clean-text**

安装后,您可以使用以下命令导入库:

**from cleantext import clean**

用法:

库 CleanText 只提供了一个函数“Clean ”,它采用各种参数来执行文本清理。清洗功能可以执行 11 种清洗,包括:

Unicode:

它修复了各种 Unicode 错误。

**s1 = 'Zürich'
clean(s1, fix_unicode=True)**# Output: zurich

ASCII:

它将文本翻译成最接近的 ASCII 表示。

**s2 = "ko\u017eu\u0161\u010dek"
clean(s2, to_ascii=True)**# Output: kozuscek

下限:

将文本数据转换成小写。

**s3 = "My Name is SATYAM"
clean(s3, lower=True)**# Output: my name is satyam

替换网址/电子邮件/电话号码:

用一个特殊的令牌替换文本数据中出现的所有 URL、电子邮件或电话号码。

**s4 = "https://www.Google.com and https://www.Bing.com are popular seach engines. You can mail me at satkr7@gmail.com. If not replied call me at 9876543210"****clean(s4, no_urls=True, replace_with_url="URL",
no_emails=True, replace_with_email="EMAIL"
no_phone_numbers=True, replace_with_email="PHONE")**# Output: url and url are popular search engines. You can mail me at EMAIL. If not replied call me at PHONE

替换货币:

用特殊标记替换文本数据中出现的所有货币。

**s5 = "I want ₹ 40"
clean(s5, no_currency_symbols = True)
clean(s5, no_currency_symbols = True, replace_with_currency_symbol="Rupees")**# Output: i want <cur> 40
# Output: i want rupees 40

删除号码:

用特殊符号替换或删除所有数字。

**s7 = 'abc123def456ghi789zero0'****clean(s7, no_digits = True)
clean(s7, no_digits = True, replace_with_digit="")**# Output: abc000def000ghi000zero0
# Output: abcdefghizero

替换标点符号:

用特殊符号删除或替换文本数据中的所有标点符号。

**s6 = "40,000 is greater than 30,000."
clean(s6, no_punct = True)**# Output: 40000 is greater than 30000

结合所有参数:

我们已经在上面单独讨论了所有的参数。现在让我们在 Clean 函数中组合它们,为一个脏的样本文本调用它,并观察干净文本的结果。

(作者代码),CleanText

因此,只需编写一行 Python 代码,就可以清除不干净的文本数据,并对其进行进一步的预处理。

结论:

CleanText 是一个高效的库,它可以处理或清理您收集的脏数据,只需一行代码就可以获得规范化的干净文本输出。开发者只需要根据他/她的需要调整参数。它简化了数据科学家的工作,因为现在他/她不必编写许多行复杂的正则表达式代码来清理文本。CleanText 不仅可以处理英语语言的输入文本,还可以处理德语,只需设置**lang=’de’**

CleanText library 只涵盖了一些文本清理参数,还有改进的空间。尽管如此,开发人员可以使用它来完成一些清理任务,然后继续手工编码来完成剩余的工作。

阅读下面提到的文章来了解 AutoNLP——一个自动化的 NLP 库。

https://medium.com/swlh/autonlp-sentiment-analysis-in-5-lines-of-python-code-7b2cd2c1e8ab

参考资料:

[1]明文知识库:https://github.com/jfilter/clean-text

感谢您的阅读

自动化客户细分

原文:https://towardsdatascience.com/automated-customer-segmentation-2f9cec9df4df?source=collection_archive---------18-----------------------

使用 Python 和 UbiOps

图片由Firmbee.com

介绍

客户细分是增进你对客户了解的好方法,这样你就能更好地对他们的需求做出反应。要真正从客户细分中获得最大收益,最好是将其自动化,这样可以最大限度地减少手动工作和花费的时间。在这篇文章中,我将向你展示如何使用 Python 和 UbiOps 来自动化你的客户细分。我将对存储在谷歌表单中的交易数据进行 RFM 分析。

你可以在这里找到本教程 的结果代码。

什么是 RFM 分析?

RFM 分析是一种基本的客户细分算法。代表近期、频率、货币分析。这种特定的分析基于三个因素将每个客户分配到一个组:

  • 客户最近购买了什么东西?
  • 他们多久买一次东西?
  • 当他们买东西的时候,他们会花多少钱?

使用这三个因素,该算法将通过以下方式为每个客户分配一个 RFM 分数:

  1. 根据最近将客户分成四分之一
  2. 根据频率将客户划分为四分位数
  3. 根据支出将客户分为四分之一
  4. 将客户所在的每个四分位数的数字串联起来,以获得一个分数

如果我们以客户 Annie 为例,她可能处于最近消费的第一个四分位数,第二个四分位数,第三个四分位数。她的 RFM 分数将会是 123 。111 分是最高分,444 分是最差分。

想深入了解 RFM 吗?我推荐叶小开·阿恩·贝克的这篇文章。

如何对您的数据进行 RFM 分析

RFM 分析需要交易数据。我将用这个 Kaggle 数据集作为一个例子来展示如何进行 RFM 分析。首先,我们需要导入熊猫并读入数据。

import pandas as pd
data_df = pd.read_excel(‘Online_Retail.xlsx’)`

如果你想看一眼数据,你可以使用data_df.head(),你应该会看到这样的内容:

现在我们有了数据,我们可以开始我们的 RFM 分析。在这篇博文中,为了保持简洁,我不会涉及数据清理,但是要注意,当您想要将下面的代码应用到您自己的数据集时,您需要确保您的数据是干净的。

我们需要做的第一件事是计算每笔交易的总价。为此,我们可以简单地将单价列乘以数量列,并将结果保存在一个新列中,我们称之为**总价。**您可以通过下面一行代码实现这一点:

data_df[‘TotalPrice’] = data_df[‘Quantity’].astype(int) * data_df[‘UnitPrice’].astype(float)

现在我们已经准备好了必要的列,我们可以对我们的近期、频率和货币值执行以下计算:

  1. Recency :计算每个客户最近一次购买日期和最后一次购买日期之间的天数。
  2. 频率:计算每个客户的订单数量。
  3. 货币:计算每个客户所花的所有钱的总和。

我们可以使用 lambda 函数快速进行计算:

data_df[‘InvoiceDate’] = pd.to_datetime(data_df[‘InvoiceDate’])
rfm= data_df.groupby(‘CustomerID’).agg({‘InvoiceDate’: lambda date: (date.max() — date.min()).days,
‘InvoiceNo’: lambda num: len(num),
‘TotalPrice’: lambda price: price.sum()})

完美!现在我们已经有了我们的值,我们需要做的最后一件事是完成这个分析,根据最近、频率和货币将客户分成不同的四分之一,并将每个四分之一的数字连接起来。

# Change the name of columns
rfm.columns=[‘recency’,’frequency’,’monetary’]# Computing Quantile of RFM values
rfm[‘recency’] = rfm[‘recency’].astype(int)
rfm[‘r_quartile’] = pd.qcut(rfm[‘recency’].rank(method=’first’), 4, [‘1’,’2',’3',’4']).astype(int)
rfm[‘f_quartile’] = pd.qcut(rfm[‘frequency’], 4, [‘4’,’3',’2',’1']).astype(int)
rfm[‘m_quartile’] = pd.qcut(rfm[‘monetary’], 4, [‘4’,’3',’2',’1']).astype(int)# Concatenating the quantile numbers to get the RFM score
rfm[‘RFM_Score’] = rfm.r_quartile.astype(str)+ rfm.f_quartile.astype(str) + rfm.m_quartile.astype(str)

在运行了这段代码并使用rfm.head()检查了“rfm”之后,得到的数据帧应该是这样的:

现在,每个客户都有一个 RFM 分数,以表明他们是什么类型的客户。您可以利用这些信息来制定营销和销售策略。

自动化您的 RFM 分析

为了最大限度地利用 RFM 分析,应该对您的数据定期执行自动化分析。要开始自动化,首先需要在分析和数据存储位置之间建立一个连接。现在,我们使用本地 excel 表,但更有可能的是,您将这些数据存储在某种共享位置,可以是数据库,也可以是更简单的共享驱动器。在本文中,我将向您展示如果您的交易数据存储在 Google Sheet 中,如何自动进行这种分析。当然,你的情况可能会非常不同,但我将向你展示的相同原则仍然适用。

为您的 Google Sheet 设置服务帐户

为了建立到您的 Google 表单的连接,我们需要一个能够访问表单的服务帐户。您可以创建一个,如下所示:

  1. 前往谷歌开发者控制台并创建一个新项目(或选择一个现有项目)
  2. 您将被重定向到项目仪表板,在那里点击**“启用 API 和服务”**,搜索“Sheets API”。
  3. 在 API 界面点击**“启用”**启用该 API

  1. 同样启用**“驱动 API”**。
  2. 转到**“凭证”选项卡,选择“创建凭证>服务帐户”**创建一个新的服务帐户。
  3. 给服务帐户一个名称和描述
  4. 将服务帐户权限设置为**“计算引擎服务代理”,跳过表单中的第三步,点击创建**。
  5. 导航到新创建的服务帐户,并转到“Keys”选项卡。点击**“添加密钥>创建新密钥”**。
  6. 将类型设置为 JSON 并点击创建。这将提示下载一个 json 文件,该文件包含帐户授权所需的私钥。将它存储在运行代码的同一文件夹中。

好了,我们现在有了一个具有正确权限的服务帐户。我们只需要让服务帐户访问仍然有数据的表。要做到这一点,带着你的数据去谷歌表单,点击“分享”。与您在前面步骤中创建的服务帐户的电子邮件地址共享 google 表单。服务帐户将需要编辑权限,因为它将执行读取和写入操作。

从 Google 工作表中检索数据

使用您之前创建的服务帐户,我们现在可以建立从您的 Python 代码到 Google Sheet 的连接。我正在使用图书馆的图片来帮助解决这个问题。

SCOPES = (‘https://www.googleapis.com/auth/spreadsheets', ‘[https://www.googleapis.com/auth/drive](https://www.googleapis.com/auth/drive)')# Change the json filename to your json file in the line below
service_account_info = json.loads(“your_json_file.json”)
my_credentials = service_account.Credentials.from_service_account_info(service_account_info, scopes=SCOPES)
gc = pygsheets.authorize(custom_credentials=my_credentials)

现在已经建立了一个连接,我们可以继续从 Google Sheet 中读取数据:

spreadsheet = gc.open(“Online_Retail”)
sheet_data = spreadsheet[0]# Transforming data into a Pandas DataFrame
data_df = sheet_data.get_as_df()

现在我们有了一个基于 Google 工作表中的数据的数据框架,我们可以用它来分析前面的部分。把data_df = pd.read_excel(“Online_Retail.xlsx”)线拿出来就行了。

将结果写入 Google 工作表

既然我们可以检索数据来执行分析,我们还应该确保我们可以将分析结果写到人们可以访问的地方。在这种情况下,我们将把结果写到同一个 Google Sheet 的一个单独的选项卡中。您可以通过在为 RFM 分析编码后添加以下代码行来实现这一点:

sheet_title = “RFM results”try:
   sh = spreadsheet.worksheet_by_title(sheet_title)
except:
   print('Worksheet does not exist, adding new sheet')
   spreadsheet.add_worksheet(sheet_title)
   sh = spreadsheet.worksheet_by_title(sheet_title)
finally:
   sh.set_dataframe(sorted_customers, 'A1', copy_index = True)
   sh.update_value('A1', 'CustomerID')
   print('Data inserted successfully')

从上到下运行结果代码后,首先读入数据,然后执行分析,然后写下结果,您应该能够在 Google Sheets 中看到您的结果!

将您的分析迁移到云中

所以我们现在有了一段 Python 代码,它从 Google 工作表中检索数据,对其执行分析,并将结果写入同一个工作表。在目前的情况下,每当您需要最新的客户细分结果时,代码都需要从笔记本电脑本地运行。如果我们将整个代码转移到云中,我们可以定期进行分析我们可以向公司内更多的人开放。为了实现这一点,我将使用 UbiOps ,这是一个允许你在 API 背后以可扩展的方式提供 Python 或 R 代码的平台。我会告诉你我如何使用它。

为 UbiOps 准备代码

在我将代码放入 UbiOps 的部署之前,我需要将代码放入所谓的部署包。这意味着我将代码放在部署类中。这只是为了确保 UbiOps 知道什么时候运行什么。我们用例的 deployment.py 文件如下所示:

在部署文件的旁边,我们需要创建一个 requirements.txt 文件来通知 UbiOps 我们代码的依赖关系。以下requirements.txt应该足够了:

google-api-core==1.28.0
google-api-python-client==2.5.0
google-auth==1.30.0
google-auth-httplib2==0.1.0
google-auth-oauthlib==0.4.4
googleapis-common-protos==1.53.0
numpy==1.20.3
oauthlib==3.1.0
pygsheets==2.0.5
pandas==1.2.4

一旦你有了这两个文件,把它们放在一个单独的文件夹中,然后压缩整个文件夹。这个 zip 文件是您的部署包。您也可以在这里找到完整的部署文件夹。

在 UbiOps 中创建部署

您可以通过 Python、CLI 或 WebApp 创建部署,这取决于您的偏好。我会使用 WebApp。

  1. 前往https://app.ubiops.com并使用您的帐户登录,如果您没有帐户,请创建一个免费帐户。
  2. 转到您的项目并导航到“部署”部分,单击创建
  3. 为您的部署命名,例如“automated-rfm”
  4. 输入下定义一个名为**“文件名”的输入字段,类型为字符串**

5.保留其他设置,点击下一步:创建版本

现在您已经有了一个部署,我们可以创建版本:

  1. 在部署包中,点击上传 zip 文件,上传您之前创建的部署包 zip 文件。
  2. 展开可选/高级设置,向下滚动到部署 环境变量
  3. 点击创建变量,填写“credentials”作为名称,并复制粘贴您的 google 服务帐户的 JSON 密钥作为值。将环境变量标记为 secret 并点击复选标记按钮。

4.您可以再次保留所有其他设置的默认值,然后单击创建

您的部署现在将开始构建。在后台,UbiOps 会为你的代码制作一个 Docker 镜像,并在它周围封装一个 API。完成后,您会看到状态将变为可用

一旦您的部署可用,您可以通过单击右上角的创建请求按钮来测试一切是否正常。使用 Google 工作表的名称作为请求的输入。

安排您的分析

自动化分析的最后一步是让它定期运行,以保持所有 RFM 分数是最新的。您可以通过在 UbiOps 中创建一个定期触发您的部署的请求调度来做到这一点。

转到 WebApp 中的“请求时间表”并点击创建。为您的计划命名,如“monthly-rfm ”,并从下拉菜单中选择您的部署。点击下一步进入创建表单的下一部分。在输入数据下,填写您的谷歌表单的名称,然后点击下一步。现在将提示您定义一个时间表。假设您需要在每月第一天的 8:00 进行分析,那么您可以设置以下 cron 作业:0 8 1 * *

设置好 cron 作业表达式后,单击 Create ,您的时间表将被打开!

结论

如果你一直跟着做,你现在已经有了一个 RFM 分析,它会在每个月的第一天自动执行。这样你就有了一个自动更新的客户细分,你的团队可以用它来指导他们的决策。我在本文中给出的例子可能是专门针对 RFM 分析的,但是我向您展示的原则也适用于其他类型的客户细分。

您需要自动化您的分析吗?欢迎在评论中告诉我!

更多信息

想了解更多关于本文中使用的库和工具的信息吗?看看其他媒体文章:

图片:

如何用 Python 自动化 Google Sheets——Dayal Chand Aichara

RFM:

与 RFM 一起了解你的客户——叶小开·阿恩·贝克

UbiOps:

如何从头开始构建和实现推荐系统(Python 语言)

利用 SQL 和机器学习进行大规模数据质量监控

原文:https://towardsdatascience.com/automated-data-quality-testing-at-scale-with-sql-and-machine-learning-f3a68e79d8a8?source=collection_archive---------19-----------------------

如何让您的数据管道更加可靠,具有可观察性

图片由 Pexels 上的 Edvin Richardson 提供

数据管道可能因为一百万种不同的原因而中断,但我们如何确保数据质量问题得到实时识别和解决— 大规模解决*?有时候,所需要的只是一点 SQL,一些精度和召回,以及一个整体的方法来**数据可观察性 *

在本文中,我们将介绍如何从头开始创建自己的数据可观测性监视器,并利用机器学习的基本原理在数据管道中大规模应用它们。

随着公司依赖越来越多的数据来驱动日益复杂的管道,这些数据必须可靠、准确和值得信赖。当数据损坏时——无论是由于模式更改、空值、重复还是其他原因——我们需要知道,而且要快。陈旧的表或错误的指标,如果不加以检查,可能会对您的业务产生负面影响。

如果您是数据专业人员,您可能会发现自己在试图了解数据的健康状况时会一次又一次地问以下问题:

  • 数据是最新的吗?
  • 数据是否完整?
  • 字段是否在预期范围内?
  • 零利率是高于还是低于它应有的水平?
  • 模式改变了吗?

要回答这些问题,我们可以从软件工程师的剧本中抽出一页:数据可观测性。数据工程师将数据可观察性定义为组织回答这些问题和评估其数据生态系统健康状况的能力。反映数据健康的关键变量,数据可观察性的五个支柱是:

  • 我的数据是最新的吗?我的数据是否有未更新的时间间隔?
  • 分布:我的现场数据有多健康?我的数据是否在预期范围内?
  • :我的数据接收量是否达到预期的阈值?
  • 模式:我的数据管理系统的正式结构改变了吗?
  • 血统:如果我的部分数据宕机,对上下游有什么影响?我的数据源如何相互依赖?

在本系列文章的中,我们拉开帷幕,研究代码中的是什么样的数据可观察性,在这最后一期文章中,我们将后退一步,思考一般来说什么是好的数据质量监控器。也许你已经阅读了第一部分**和第二部分并在想,“这些都是有趣的练习,但是我们如何在我的真实生产环境中应用这些概念呢?”

在高层次上,机器学习有助于大规模的数据可观测性。配备了机器学习的检测器可以更灵活地应用于大量的表,随着数据仓库的增长,不再需要手动检查和规则(如第一部分和第二部分所讨论的)。此外,机器学习检测器可以实时学习和适应数据,并捕捉复杂的季节模式,否则人眼将无法看到。

让我们开始吧——不需要预先的机器学习经验。

我们的数据环境

本教程基于奥莱利课程 练习 4 管理数据停机 。欢迎您使用 Jupyter 笔记本和 SQL 自行尝试这些练习。

你可能还记得第一和第二部分,我们正在研究关于可居住外行星的模拟天文数据。不幸的是,这些数据并不真实——它是为了教学目的而捏造的——但是如果你愿意,你可以假装它是直接来自于毅力。:)

我们使用 Python 生成数据集,对我们在生产环境中遇到的真实事件的数据和异常进行建模。(这个数据集完全免费使用,存储库中的 utils 文件夹包含生成数据的代码。)

在本练习中,我们使用 SQLite 3.32.3,它应该可以通过命令提示符或 SQL 文件以最少的设置访问数据库。这些概念实际上可以扩展到任何查询语言,并且这些实现可以扩展到 MySQL、Snowflake 和其他数据库环境,只需很少的改动。

在本文中,我们将把注意力限制在系外行星表:

请注意,系外行星被配置为手动跟踪一条重要的元数据 date _ added 列——它记录了我们的系统发现该行星的日期,并将其自动添加到我们的数据库中。在第一部分中,我们使用一个简单的 SQL 查询来可视化每天添加的新条目的数量:

该查询生成如下所示的数据:

换句话说,系外行星表每天都会更新大约 100 个条目,但在没有数据输入的日子里会“离线”。我们引入了一个名为 DAYS_SINCE_LAST_UPDATE 的指标来跟踪表的这一方面:

结果看起来像这样:

图表由作者提供。

通过一个小的修改,我们在查询中引入了一个阈值参数来创建一个新鲜度检测器。我们的探测器返回了所有系外行星最新数据超过 1 天的日期。

图表由作者提供。

图中的尖峰代表了系外行星表处理旧数据或“陈旧”数据的情况。在某些情况下,这种中断可能是标准的操作程序——也许我们的望远镜应该进行维护,所以一个周末都没有记录数据。然而,在其他情况下,中断可能代表数据收集或转换的真正问题——可能我们将日期更改为 ISO 格式,传统上推送新数据的工作现在失败了。我们可能有这样的启发:停机时间越长越糟糕,但除此之外,我们如何保证只检测数据中真正的问题呢?

简单的回答是:你不能。

建立一个完美的预测器是不可能的(无论如何,对于任何有趣的预测问题)。但是,我们可以使用机器学习中的一些概念,以更结构化的方式来构建问题,结果是,提供大规模的数据可观察性和信任。

通过机器学习改进警报

每当我们就数据管道中断发出警报时,我们不得不质疑警报是否准确。警报是否指示真正的问题?我们可能会担心两种情况:

  1. 发出了警报,但没有真正的问题。我们浪费了用户的时间来响应警告。
  2. 有一个真正的问题,但没有发出警报。我们忽略了一个真正的问题。

这两种情况被描述为假阳性(预测异常,实际上没问题)和假阴性(预测正常,实际上异常),我们希望避免它们。发布假阳性就像在喊狼来了——我们拉响了警报,但一切正常。同样,发布假阴性就像在站岗时睡觉——出了问题,但我们什么也没做。

我们的目标是尽可能避免这些情况,并专注于最大化真阳性(预测异常,实际上是一个问题)和真阴性(预测正常,实际上正常)。

精确度和召回率

因此,我们需要一个好的检测方案来减少误报和漏报。在机器学习实践中,更常见的是考虑相关但更有见地的术语,精确度和召回率:

****

图片由作者提供。

一般来说,精确度告诉我们,当我们发出警报时,我们的正确率是多少。具有良好精度的模型输出可信的警报,因为它们的高精度保证了它们很少谎报。

一般来说,回忆告诉我们实际上有多少问题需要警惕。记忆力好的模特是可靠的,因为他们的高记忆力保证了他们很少在工作时睡觉。

延伸我们的比喻,精度好的模型是很少喊狼来了的模型——当它发出警报时,你最好相信它。同样,一个具有良好回忆的模型就像一只优秀的看门狗——你可以放心,这个模型会捕捉到所有真正的问题。

平衡精确度和召回率

问题当然是,你不可能两全其美。请注意,这两者之间存在明显的权衡。我们如何获得完美的精度?简单:对没事 —值班时一直睡觉—迫使我们有 0%的误报率。问题?召回将是可怕的,因为我们的假阴性率将是巨大的。**

同样,我们如何获得完美的回忆?也很简单:警惕一切——抓住一切机会喊狼来了——迫使假阴性率为 0%。不出所料,问题是我们的假阳性率会受到影响,从而影响精确度。

解决方案:单一目标

我们的数据世界是由可量化的目标运行的,在大多数情况下,我们希望优化单个目标,而不是两个。我们可以将精确度和召回率结合成一个称为 F 的指标——分数:

F_beta 被称为加权的F-分数,因为不同的 beta 值在计算中对精确度和召回率的权重不同。一般来说,F_beta 分数表示,“我认为回忆是 beta 倍,与精确度一样重要。”

当β= 1 时,等式中的值相等。设置 beta > 1,回忆对于更高的分数会更重要。换句话说,beta > 1 表示,“我更关心捕捉所有异常,而不是偶尔引起一次错误警报。”同样,set beta < 1, and precision will be more important. beta < 1 says, “I care more about my alarms being genuine than about catching every real issue.”

Detecting freshness incidents

With our new vocabulary in hand, let’s return to the task of detecting freshness incidents in the EXOPLANETS table. We’re using a simple prediction algorithm, since we turned our query into a detector by setting one model parameter X. Our algorithm says, “Any outage longer than X days is an anomaly, and we will issue an alert for it.” Even in a case as simple as this, precision, recall, and F-scores can help us!

To showcase, we took the freshness outages in EXOPLANETS and assigned ground truth labels encoding whether each outage is a genuine incident or not. 没有某种基本事实就不可能计算模型的准确性,所以考虑如何为用例生成这些总是有帮助的。回想一下,在系外行星表中总共有 6 次持续时间超过 1 天的中断:

让我们武断地说,2020 年 2 月 8 日和 2020 年 5 月 14 日的事件是真实的。每一个都是 8 天长,所以有问题是有道理的。另一方面,假设 2020 年 3 月 30 日和 2020 年 6 月 7 日的断电不是实际事故。这些停机时间分别为 4 天和 3 天,因此这并不奇怪。最后,让 2020 年 6 月 17 日和 2020 年 6 月 30 日分别在 5 天和 3 天发生的中断,成为真实事件。

以这种方式选择了我们的基本事实后,我们看到更长时间的停机更有可能是实际问题,但没有保证。这种弱相关性将使一个好的模型有效,但不完美,就像在更复杂的真实用例中一样。

现在,假设我们将阈值设置为 3 天,换句话说,“每次超过 3 天的停机都是异常的。”这意味着我们正确地检测到了 2020 年 2 月 8 日、2020 年 5 月 14 日和 2020 年 6 月 17 日的异常,因此我们有 3 个真阳性。但是,不幸的是,我们将 2020–03–30 检测为一个事件,而它并不是一个事件,因此我们有 1 个误报。3 个真阳性/ (3 个真阳性+ 1 个假阳性)意味着我们的精度是 0.75。此外,我们未能将 2020–06–30 检测为事故,这意味着我们有 1 个假阴性。3 真阳性/ (3 真阳性+ 1 假阴性)意味着我们的召回率也是 0.75。f1-分数,由公式给出

意味着我们的 f1 分数也是 0.75。还不错!

现在,假设我们将阈值设置得更高,为 5 天。现在,我们只检测到 2020 年 2 月 8 日和 2020 年 5 月 14 日这两个最长的停机时间。这些都是真实的事件,所以我们没有误报,这意味着我们的精度是 1-完美!但是请注意,我们没有检测到其他真正的异常,2020 年 6 月 17 日和 2020 年 6 月 30 日,这意味着我们有两个假阴性。2 真阳性/ (2 真阳性+ 2 假阴性)意味着我们的召回率是 0.5,比以前更差。我们的回忆受到影响是有道理的,因为我们选择了一个更保守、阈值更高的分类器。我们的 f1 分数可以用上面的公式再次计算,结果是 0.667。

如果我们根据我们设置的阈值来绘制我们的精度、召回率和 f1,我们会看到一些重要的模式。首先,具有低阈值的积极检测器具有最好的回忆,因为它们更快地发出警报,从而捕捉到更多真正的问题。另一方面,更多的被动探测器具有更高的精度,因为它们只对更有可能是真实的最糟糕的异常发出警报。f1 分数在这两个极端之间的某个地方达到峰值——在这种情况下,在 4 天的阈值处。找到最佳点是关键!

图表由作者提供。

最后,我们来看最后一个对比。请注意,我们只查看了 f1 分数,它同等地衡量了精确度和召回率。当我们看β的其他值时会发生什么?

图表由作者提供。

回想一下,一个通用的 F_beta 说“召回是 beta 倍,和精度一样重要。”因此,当回忆被优先化时,我们应该预期 F2 高于 f1——这正是我们在阈值小于 4 时看到的。同时,对于更大的阈值,F_0.5 分数更高,显示出对于具有更高精度的保守分类器的更多容许量。

机器学习的大规模数据可观测性

我们已经对机器学习概念进行了一次快速的探索。现在,这些概念如何帮助我们将检测器应用到生产环境中?关键在于理解对于任何异常检测问题都没有完美的分类器。

假阳性和假阴性,或者同样的精确度和召回率之间总有一个折衷。你必须问自己,“我如何权衡这两者之间的取舍?什么决定了我的模型参数的‘最佳点’?”选择一个 F_beta 分数来优化将隐含地决定你如何权衡这些事件,从而决定在你的分类问题中什么是最重要的。

此外,请记住,如果没有某种基础事实与模型的预测进行比较,任何关于模型准确性的讨论都是不完整的。在你知道你有一个好的分类之前,你需要知道什么是好的分类。

这里祝你没有数据停机!

有兴趣了解如何解决大规模数据质量问题吗?伸出手去 巴尔瑞安 ,以及其余的 蒙特卡洛 团队以及 注册为我们的数据观测

本教程的关联练习可用,此处https://github.com/monte-carlo-data/data-downtime-challenge,本文所示改编代码可用,此处*https://github.com/monte-carlo-data/data-observability-in-practice***

自动化探索性数据分析

原文:https://towardsdatascience.com/automated-exploratory-data-analysis-da9fc5928e0d?source=collection_archive---------32-----------------------

使用 python edatk 库在数据中寻找见解

附身摄影在 Unsplash 上拍照

探索性数据分析是构建机器学习模型的关键初始步骤。更好地理解您的数据可以使发现异常值、特征工程和最终建模更加有效。

探索性数据分析的某些部分,如生成特征直方图和缺失值计数,大部分可以自动化。本文介绍了我创建的一个开源库,它运行一些基本的自动化 EDA 过程。

EDATK:自动化 EDA 工具箱

为了帮助加快探索性数据分析,我创建了 edatk 并开源了代码。这允许您通过 pip 安装,并使用几行代码运行自动化 eda。它仍处于 alpha 阶段,所以将其视为现有 eda 工作流的补充。

edatk 的主要特点是:

  1. 易用性:在 pandas 数据框架上运行自动化探索性数据分析只需要一行代码。
  2. HTML 报告输出:通过提供一个文件夹位置,edatk 将构建一个 HTML 报告,以一种简洁的方式呈现视觉效果和表格。
  3. 目标列探索:这是 edatk 的关键特性之一。传入可选的 target_column 参数指定在可能的情况下添加可视层和线索,帮助您发现输入特征和您在受监督的机器学习设置中预测的列之间的趋势。如果你的问题不符合监督机器学习模式,你可以简单地忽略这个参数。
  4. 推断的图表类型:基于数据框架中的列类型,edatk 将推断要计算的指标和要显示的图表类型。

在本次演示中,我们将使用常见的虹膜数据集。数据集具有鸢尾植物的各种特征,任务是预测物种。

在本文中,我们不会构建机器学习模型,但会运行自动化 eda 来发现可能有助于选择或构建新功能以纳入模型训练的趋势。

运行自动化 EDA

运行 edatk 的主要方法如下,包括几个关键步骤:

  1. 导入库并加载数据集。在这个演示中,我们使用 seaborn 将 iris 数据集加载到 pandas 数据帧中。
  2. 运行 auto_eda 方法,传入您的数据帧、保存(输出)位置和目标列。输出位置和目标列是可选的,但如果您可以提供这些值,则推荐使用。

就这么简单! Edatk 根据列类型和每列的基数运行各种例程。可视化是自动生成的,并且用输出构建一个 html 报告。下面代码生成的完整 html 报告可以在这里查看。

分析结果

单列统计

报告的第一部分遍历所有列,并计算基本的描述性统计数据。这采用初始表的形式,其中包含最小值、最大值、缺失值行的百分比等。下一部分显示了一些基本的描述性图表,如箱线图和直方图。

下面的屏幕截图显示了每列生成的内容,以萼片长度(用于预测物种的数据集特征之一)为例。

单列表格,按作者排序的图像

单列视觉效果,图片由作者提供

多列统计

探索数据最有用的事情之一是绘制要素对并针对目标进行分析。这可以给你一些如何设计新功能的想法。如果您在调用 auto_eda 时传入一个 target_column ,这些特征对可视化中的许多将包括根据该目标变量的颜色编码。这使得发现潜在趋势变得快速而容易。

例如,生成的图之一是散点图,x 轴上有 花瓣 _ 长度 ,y 轴上有 花瓣 _ 宽度 。我们希望训练模型预测的三种不同类型的物种是用颜色编码的。人们可以很快发现一些分离。仅仅包括这两个特性就应该为一个模型提供一个不错的起点。你也可以结合到一个新设计的功能中来捕捉这种关系。

成对的柱形图散点图,作者图片

生成的视觉效果并不总是散点图。该库查看列类型以确定应该生成的可视化类型。例如,使用方框图,根据 花瓣 _ 宽度 绘制分类列(如下例)。

成对的柱形视觉效果方框图,作者提供的图像

警告

Edatk 可以处理一些较大的数据集(就行数而言),因为对于已知的性能密集型绘图,确实会进行一些采样。但是,由于生成了成对图组合,包含大量列的极宽数据集可能会导致问题。在这种情况下, auto_eda 方法提供了一个 column_list 参数来传入一个较小的列名列表。

最后,edatk 仍然处于 alpha 阶段——所以把它作为现有 eda 工作流的补充。

贡献的

该库仍在开发中,但对所有希望做出贡献的人开放源代码以使其变得更好!

计划中的功能可以在 github repo 上的这里查看,以及一些基本指令和 git 命令,供那些希望提出第一个拉请求的人使用。

摘要

自动化的探索性数据分析可以帮助您更好地理解数据并发现初始趋势。

Edatk 就是这样一个库,它试图自动完成这些工作。看看吧,让我知道你的想法!

Github上可以找到所有的例子和文件。

原载于https://data stud . dev

使用神经网络的自动特征工程

原文:https://towardsdatascience.com/automated-feature-engineering-using-neural-networks-5310d6d4280a?source=collection_archive---------7-----------------------

数据艺术家温迪·安格斯,经许可使用

如何自动化并大大改进数据建模中最繁琐的步骤之一

很少有人会否认特征工程是生产精确模型的最重要的步骤之一。有些人喜欢,但我绝对不是其中之一。我发现这一步非常繁琐,我坚信任何繁琐的事情都可以自动化。虽然我的解决方案没有完全消除手工工作的需要,但它确实大大减少了手工工作并产生了更好的结果。它还产生了一个在结构化数据集上持续击败梯度增强方法的模型。

本文将回答以下问题:

  • 到底什么是自动化?
  • 它是如何工作的?
  • 你如何建造它?
  • 它与其他型号相比如何?

特征工程

“正确完成这一步可能需要做几周的 EDA。幸运的是,寻找互动是神经网络擅长的!”

当一个模型被输入一组特征时,它必须学习哪些特征相互作用,以及它们如何相互作用。对于大型数据集,可能有无数的组合需要测试,这些模型往往侧重于能够快速成功的交互。使用特征工程,您可以手动创建或组合特征,以确保模型给予它们适当的关注。

根据数据和问题,有许多不同类型的特征工程方法。大多数分为以下几类:

  • 数据清理:有些人认为这是一项功能工程,但这确实是它自己的一步。简而言之,在特性工程成为可能之前,您需要确保数据是可用的。它涉及修复数据中的错误、处理缺失值、处理异常值、一次性编码、扩展特性以及无数其他事情。在我看来,数据清理是唯一比特征工程更糟糕的一步,所以任何找到自动化这一步的人都将是我的新英雄。
  • 均值编码:这一步包括将邮政编码等分类特征转换成模型可用的信息。例如,您可以创建一个显示邮政编码的平均销售收入的列。在我之前关于特性嵌入的文章中,我已经在很大程度上删除了这个步骤。
  • 滞后变量:向数据中添加时间序列元素通常会有所帮助。通过添加以前期间的值,模型可以计算出事物随时间的变化趋势(例如,上个月的销售额、上个月的销售额等)。这个过程并不太复杂,可以通过简单的循环实现自动化。
  • 交互:这一步包括以不同的方式组合特性。例如,您可以通过用广告驱动的客户购买量除以广告被点击的总次数来衡量在线广告的转化率。但是,如果转化率因产品价格的不同而有很大差异,该怎么办呢?现在,您可以根据价格阈值创建单独的列。也很难发现和知道如何处理三阶(或更高阶)互动(例如,价格和类别不同的广告转换)。到目前为止,这是特征工程中最微妙、最耗时的步骤。正确完成这一步可能需要做几周的 EDA。幸运的是,寻找互动是神经网络擅长的!诀窍是确保模型实际上寻找它们,这将是以后的重点。

这个概念

神经网络获取一组输入特征,并在它们之间创建有助于最佳预测输出的交互。如上所述,我们可以通过设计它们来迫使模型考虑某些组合。但是如果我们可以强迫神经网络考虑它们呢?如果我们能够确保神经网络以一种对目标输出产生最佳精度的方式来设计这些特征,会怎么样?关键是训练模型先关注特征。

假设我们有目标输出为 y 的特性 A、B、C 和 D。这个问题的第一步是创建一个模型,预测每个特性。为什么我们关心预测特征?因为我们希望神经网络学习特定于每个特征的交互。

作者提供的要素网络图示例

关于这一步有趣的事情是,我们不关心模型输出。最后一个隐藏层(图中的绿色节点)包含我们新设计的特征,这是我们将要提取的。这些可以馈入我们的最终模型(连同原始特征)来预测我们的目标输出 y。

作者提供的全功能网络图示例

诀窍是确保特征网络训练 最终模型,而不是一个单独的过程。Trickier 还在训练一个嵌入层,嵌入到每个特征层中(见我的文章为什么这很重要)。对你来说,好消息是:经过几个月的努力,我终于找到了一个解决方案,并且超出了我的预期。

代码

为了演示这些方法,我们将试图预测一个新冠肺炎患者出现严重反应的概率。可以在这里找到“Cleaned-Data.csv”数据集:https://www . ka ggle . com/iamhungundji/covid 19-symptoms-checker?select=Cleaned-Data.csv

让我们引入数据并创建培训、验证和测试数据集:

import pandas as pd
import tensorflow as tffrom sklearn.model_selection import train_test_split
from tensorflow import feature_column
from tensorflow.keras import layers
from tensorflow.keras.callbacks import ModelCheckpoint
from sklearn.metrics import log_lossX_train = pd.read_csv('covid_data.csv')
y_train = X_train.pop('Severity_Severe').to_frame()
X_train = X_train.iloc[:,:23]X_train, X_val, y_train, y_val = train_test_split(
    X_train, y_train,test_size=0.2,random_state=42)X_val, X_test, y_val, y_test = train_test_split(
    X_val, y_val,test_size=0.5,random_state=42)

现在,我们将需要定义要为哪些特征创建特征模型。由于我们没有太多的特征,我们不妨全部使用(除了国家将用于嵌入)。当模型包含数百个特性时,最好只显式定义顶部的特性,如下所示:

model_cols = ['Fever','Tiredness','Dry-Cough',
              'Difficulty-in-Breathing',
              'Sore-Throat','None_Sympton',
              'Pains','Nasal-Congestion',
              'Runny-Nose','Diarrhea',
              'None_Experiencing','Age_0-9',
              'Age_10-19','Age_20-24','Age_25-59',
              'Age_60_','Gender_Female','Gender_Male',
              'Gender_Transgender','Contact_Dont-Know',
              'Contact_No','Contact_Yes']

这些特征中的每一个都将是我们整体模型的不同辅助输出,以及我们试图预测的目标特征( Severity_Severe )。在创建张量流数据集时,我们还必须将它们定义为输出要素。请注意,我们通过在末尾添加'_ out '【T7]来重命名这些特性,以便 TensorFlow 不会因重复的名称而混淆。注意,我们还为目标输出添加了一个额外的' _aux_out '列。这样我们就可以围绕目标特征训练一个独立的特征模型,这个模型也将输入到最终的模型中。这是一个被称为跳过连接的过程,它允许模型学习围绕相同特征集的深度和浅层交互。

Y_train_df = X_train[model_cols].copy()
Y_train_df.columns = Y_train_df.columns + "_out"
Y_train_df['Severity_Severe_out'] = y_train['Severity_Severe']
Y_train_df['Severity_Severe_aux_out'] = y_train['Severity_Severe']
trainset = tf.data.Dataset.from_tensor_slices((
    dict(X_train),dict(Y_train_df))).batch(256)Y_val_df = X_val[model_cols].copy()
Y_val_df.columns = Y_val_df.columns + "_out"
Y_val_df['Severity_Severe_out'] = y_val['Severity_Severe']
Y_val_df['Severity_Severe_aux_out'] = y_val['Severity_Severe']
valset = tf.data.Dataset.from_tensor_slices((
    dict(X_val),dict(Y_val_df))).batch(256)Y_test_df = X_test[model_cols].copy()
Y_test_df.columns = Y_test_df.columns + "_out"
Y_test_df['Severity_Severe_out'] = y_test['Severity_Severe']
Y_val_df['Severity_Severe_aux_out'] = y_val['Severity_Severe']
testset = tf.data.Dataset.from_tensor_slices((
    dict(X_test),dict(Y_test_df))).batch(256)

我们要创建的第一个函数是 add_model 。我们将为这个函数提供我们的特征名称,定义层数和大小,表明我们是否想要使用批量标准化,定义模型的名称,并选择输出激活。hidden_layers 变量将为每个层提供一个单独的列表,第一个数字是神经元的数量,第二个是辍学率。此功能的输出将是输出层和最终隐藏层(工程特征),它们将反馈到最终模型。当使用像 hyperopt 这样的工具时,这个函数允许简单的超参数调整。

def add_model(
    feature_outputs=None,hidden_layers=[[512,0],[64,0]],
    batch_norm=False,model_name=None,activation='sigmoid'):

    if batch_norm == True:
        layer = layers.BatchNormalization()(feature_outputs)
    else:
        layer = feature_outputs

    for i in range(len(hidden_layers)):
        layer = layers.Dense(hidden_layers[i][0], activation='relu',
                             name=model_name+'_L'+str(i))(layer)
        last_layer = layer

        if batch_norm == True:
            layer = layers.BatchNormalization()(layer)
        if hidden_layers[i][1] > 0:
            layer = layers.Dropout(hidden_layers[i][1])(layer)

    output_layer = layers.Dense(1, activation=activation,
                                name=model_name+'_out')(layer)

    return last_layer, output_layer

下一个功能是创建一个嵌入层。这将很有帮助,因为国家是一个稀疏分类特征。该函数将获取我们将转换为嵌入的特征的字典,以及此处定义的该特征的唯一可能值的列表:

emb_layers = {'Country':list(X_train['Country'].unique())}

我们还提供模型输入,这将在后面定义。对于尺寸参数,我选择遵循默认的经验法则,即使用唯一特征长度的 4 次方根。

def add_emb(emb_layers={},model_inputs={}):
    emb_inputs = {}
    emb_features = []

    for key,value in emb_layers.items():
        emb_inputs[key] = model_inputs[key]
        catg_col = feature_column
            .categorical_column_with_vocabulary_list(key, value)
        emb_col = feature_column.embedding_column(
            catg_col,dimension=int(len(value)**0.25))
        emb_features.append(emb_col)

    emb_layer = layers.DenseFeatures(emb_features)
    emb_outputs = emb_layer(emb_inputs)

    return emb_outputs

在我们进入下一个功能之前,我们需要定义需要从不同的特征模型中排除哪些特征。在基本层面上,我们想要排除被预测的特征(数据泄漏),以及用于嵌入的特征。还应小心移除可直接用于计算输出要素的要素。例如,一个模型将很快发现,对于像 Gender_Female 这样的特征,只需查看其他性别列的值并忽略所有其他特征,它就可以获得 100%的准确性。这不是一个非常有用的模型!为了解决这个问题,我们将从相应的特征模型中排除其他性别、年龄和接触特征。

feature_layers = {col:[col,'Country'] for col in model_cols}feature_layers['Gender_Female'] += ['Gender_Male',
                                    'Gender_Transgender']
feature_layers['Gender_Male'] += ['Gender_Female',
                                  'Gender_Transgender']
feature_layers['Gender_Transgender'] += ['Gender_Female',
                                         'Gender_Male']feature_layers['Age_0-9'] += ['Age_10-19','Age_20-24',
                              'Age_25-59','Age_60_']
feature_layers['Age_10-19'] += ['Age_0-9','Age_20-24',
                                'Age_25-59','Age_60_']
feature_layers['Age_20-24'] += ['Age_0-9','Age_10-19',
                                'Age_25-59','Age_60_']
feature_layers['Age_25-59'] += ['Age_0-9','Age_10-19',
                                'Age_20-24','Age_60_']
feature_layers['Age_60_'] += ['Age_0-9','Age_10-19',
                              'Age_20-24','Age_25-59']feature_layers['Contact_Dont-Know'] += ['Contact_No','Contact_Yes']
feature_layers['Contact_No'] += ['Contact_Dont-Know','Contact_Yes']
feature_layers['Contact_Yes'] += ['Contact_Dont-Know','Contact_No']

我们还打算为我们的辅助跳过连接模型添加一个特征层:

feature_layers['Severity_Severe_aux'] = ['Country']

现在我们有了构建特征模型所需的东西。该函数将使用所有输入特征的列表、上述定义的特征排除和嵌入字典、在 add_model 函数中描述的 hidden_layer 结构以及是否应使用批量标准化的指示器。

首先,该函数将以 TensorFlow 喜欢的方式定义输入要素。使用 TensorFlow 输入的一个主要优点是,我们只需要定义一次特征,它们可以在每个特征模型中反复使用。接下来,我们将确定是否定义了任何嵌入列,并创建一个嵌入层(可选)。对于每个特征模型,我们将创建 DenseFeatures 输入层(不包括上面定义的特征),并使用 add_model 函数创建一个单独的模型。就在返回之前,我们检查循环是否在跳过连接模型上运行。如果是这样,我们添加输入特征,以便最终模型也可以使用原始特征进行训练。最后,该函数将返回模型输入的字典、每个特征模型输出层的列表以及每个最终隐藏层的列表(即新工程特征)。

def feature_models(
    output_feature=None,all_features=[],feature_layers={},
    emb_layers={},hidden_layers=[],batch_norm=False):

    model_inputs = {}
    for feature in all_features:
        if feature in [k for k,v in emb_layers.items()]:
            model_inputs[feature] = tf.keras.Input(shape=(1,),
                                                   name=feature,
                                                   dtype='string')
        else:
            model_inputs[feature] = tf.keras.Input(shape=(1,),
                                                   name=feature)

    if len(emb_layers) > 0:
        emb_outputs = add_emb(emb_layers,model_inputs)

    output_layers = []
    eng_layers = []
    for key,value in feature_layers.items():
        feature_columns = [feature_column.numeric_column(f)
                           for f in all_features if f not in value]

        feature_layer = layers.DenseFeatures(feature_columns)
        feature_outputs = feature_layer({k:v for k,v in
                                         model_inputs.items()
                                         if k not in value})

        if len(emb_layers) > 0:
            feature_outputs = layers.concatenate([feature_outputs,
                                                  emb_outputs])

        last_layer, output_layer = add_model(
            feature_outputs=feature_outputs,
            hidden_layers=hidden_layers,
            batch_norm=batch_norm,
            model_name=key)

        output_layers.append(output_layer)
        eng_layers.append(last_layer)

        if key == output_feature + '_aux':
            eng_layers.append(feature_outputs)

    return model_inputs, output_layers, eng_layers

请注意,如果使用嵌入层,它将与这些模型的每个输入连接在一起。这意味着这些嵌入不仅将训练以最大化整体模型准确性,而且还将训练这些特征模型中的每一个。这导致了非常健壮的嵌入,并且是对我的前一篇文章中描述的过程的重大升级。

在我们进入最后一个函数之前,让我们定义我们将要输入的每个参数。其中大部分已经在上面描述过,或者对所有张量流模型是典型的。如果您不熟悉耐心参数,它用于在指定的时期数内验证精度没有提高时停止训练模型。

params = {'all_features': list(X_train.columns),
          'output_feature':y_train.columns[0],
          'emb_layers':emb_layers,
          'feature_layers':feature_layers,
          'hidden_layers':[[256,0],[128,0.1],[64,0.2]],
          'batch_norm': True,
          'learning_rate':0.001,
          'patience':3,
          'epochs':20
        }

对于最终模型,我们将通过运行前面的函数来生成输入、输出和工程特征。然后,我们连接这些层/特征中的每一个,并将它们输入到最终模型中。最后,我们构建、编译、训练和测试模型。

def final_model(params,test=True):

    print(params['batch_norm'],params['hidden_layers'])

    model_inputs, output_layers, eng_layers = feature_models(
        all_features=params['all_features'],
        feature_layers=params['feature_layers'],
        emb_layers=params['emb_layers'],
        hidden_layers=params['hidden_layers'],
        batch_norm=params['batch_norm'],
        output_feature=params['output_feature'])

    concat_layer = layers.concatenate(eng_layers)
    last_layer, output_layer = add_model(
        feature_outputs=concat_layer,
        hidden_layers=params['hidden_layers'],
        batch_norm=params['batch_norm'],
        model_name=params['output_feature'])

    output_layers.append(output_layer)

    model = tf.keras.Model(
        inputs=[model_inputs],
        outputs=output_layers)

    aux_loss_wgt = 0.5 / len(params['feature_layers'])
    loss_wgts = [aux_loss_wgt for i in 
                 range(len(params['feature_layers']))
    loss_wgts.append(0.5)

    model.compile(loss='binary_crossentropy',
                  optimizer=tf.keras.optimizers.Adam(
                      lr=params["learning_rate"]),
                  loss_weights=loss_wgts,
                  metrics=['accuracy'])

    es = tf.keras.callbacks.EarlyStopping(
        monitor='val_loss',mode='min',verbose=1,
        patience=params['patience'],restore_best_weights=True)

    history = model.fit(
        trainset,validation_data=valset,
        epochs=params['epochs'], verbose=0, callbacks=[es])

    yhat = model.predict(testset)
    loss = log_loss(
        np.array(y_test[params['output_feature']]),
        yhat[-1])**.5

    print('Binary Crossentropy:',loss)

    if test==True:
        sys.stdout.flush()
        return {'loss': loss, 'status': STATUS_OK}
    else:
        return history, model

注意,这个函数的输入之一叫做测试。该输入允许您在使用 hyperopt 求解最佳参数( test=True )或训练并返回您的最终模型( test=False )之间切换。在编译模型时,您可能还不熟悉 loss_weights 参数。因为我们有几个辅助输出,所以我们需要告诉 TensorFlow 在确定如何调整模型以提高准确性时给每个输出多少权重。我个人喜欢给辅助预测(总预测)50%的权重,给目标预测 50%的权重。有些人可能会觉得赋予辅助预测任何权重很奇怪,因为它们在损失计算步骤中被丢弃。问题是,如果我们不给它们任何权重,模型通常会忽略它们,阻止它学习有用的特征。

现在我们只需要使用上面定义的参数运行 final_model :

history, model = final_model(params,test=False)

现在我们已经有了一个训练好的模型,我们可以使用 keras get_layer() 函数有选择地提取新的特征用于其他模型。如果这能引起足够的兴趣,我将把这一步留到以后的文章中。

结果呢

“它一贯击败 XGBoost **,**与传统智慧相反,梯度增强模型对于结构化数据集来说更优越。”

可以想象,这是一个计算量很大的训练模型。好消息是,与典型的 MLP 相比,它通常会在更少的试验中收敛到更准确的答案。如果你把省下的时间包括在内,那就更快了。此外,预测延迟足够小,足以使其成为生产模型(与典型的 Kaggle 50+元模型相反)。如果你提取特征并用它们重新训练神经网络,那么它会变得更快。

问题依然存在,**准确吗?在我应用这个模型的每一个案例中,它都是最准确的。**它持续击败 XGBoost,与梯度增强模型对于结构化数据集更优越的传统智慧相反。让我们看看它是如何解决这个问题的!

方法和准确性

我测试了三种不同的模型:

  • XGBoost
  • 嵌入的标准 MLP
  • 上面训练的自动特征模型

对于自动特征模型,我使用 hyperopt 运行了 20 次试验,对不同的网络规模进行实验。对于这两个竞争模型,我进行了 40 次试验,因为它们的训练时间更快。结果如下:

各型号的准确度得分

正如所料,我们的自动特征模型表现最好。要记住的一点是,这个简单的数据集没有足够的有用信息来允许任何比边际收益更好的模型。当我处理利用数百个特征的大规模数据集时,自动特征模型比 XGBoost 高出 5–10%的情况并不少见。

当最高精度非常重要时,这已经成为我的首选生产模式。它在我的职业生涯中为我带来了很多成功,现在我希望它也能为你带来同样的成功。

关于我

我是一名拥有 10 多年经验的数据科学自由职业者。我一直希望与人交流,所以请随意:

  • 在 LinkedIn 上与我联系
  • 在推特上关注我
  • 访问我的网站

如有任何疑问,欢迎在下方评论

用几行 Python 代码实现 EDA、建模和超参数调整的自动化交互式软件包

原文:https://towardsdatascience.com/automated-interactive-package-for-eda-modeling-and-hyperparameter-tuning-in-a-few-lines-of-228c561fa63c?source=collection_archive---------10-----------------------

PyWedge —加快数据科学建模工作流程的交互式包

图片由 StockSnap 来自 Pixabay

数据科学家将大部分时间花在执行探索性数据分析(EDA)上。数据科学建模管道有各种组件,包括 EDA、数据处理、超参数调整、基线建模和模型部署。

有各种开源 Python 库可以加速管道上的一些组件。阅读这篇文章到 4 个这样的可以自动化 EDA 组件的库。当涉及到从 EDA、数据处理、基线建模和超参数调整模型开始的整个建模流程的自动化时,需要花费数据科学家大量的时间和精力。

在这里,PyWedge 开始发挥作用,它可以自动化整个建模工作流,包括 EDA、数据处理、基线建模和超参数调整。在本文中,我们将讨论 PyWedge 的实现和使用。

PyWedge 是什么?

PyWedge 是一个开源 Python 库,可以自动化数据科学建模管道的几个组件。它可以被视为交互式 EDA、数据处理、基线建模和超参数调整的完整套件。

PyWedge 提供了几个特性,包括:

  • 创建可视化的交互图,包括散点图、条形图、小提琴图、相关图等。
  • 使用开发人员选择的输入处理技术进行数据处理。
  • 训练数十种机器学习算法的各种基线模型训练,并返回每个模型的性能指标。
  • 交互式执行超参数调整小部件样式选项卡。

安装:

PyWedge 可以从 PyPl 安装,使用:

**!pip install pywedge**

它可以通过以下方式导入 Python:

**import pywedge as pw**

用法:

本文使用的数据集是 Titanic dataset,从 Kaggle 下载。这是一个二进制分类数据,目标类是“幸存”。

首先,开发人员需要使用 Pandas 导入数据集:

**import pandas as pd
df = pd.read_csv("titanic.csv")**

探索性数据分析:

模型构建管道的第一个组件是 EDA。PyWedge 可以用一行 Python 代码执行 EDA。它生成 8 种类型的交互图,包括散点图、饼图、小提琴图、条形图、箱线图、分布图、直方图和相关图。

**mc = pw.Pywedge_Charts(df, c=None, y="Survived")
chart = mc.make_charts()**

(图片由作者提供),使用 PyWedge 绘制图表的交互式选项卡

基线建模:

PyWedge 可以使用函数**baseline_model** 对各种分类和回归机器学习算法进行基线建模。建模从数据预处理开始,它依赖于开发人员使用各种数据处理技术。

输入参数:

  • 分类列编码技术:熊猫猫代码,或得到假人。
  • 色谱柱标准化:标准定标器、鲁棒定标器、最小-最大定标器。
  • 选择是否使用 SMOTE 来平衡等级。
  • 列车测试数据分割

(图片由作者提供),使用 PyWedge 训练基线模型的交互式选项卡

**baseline_model** 函数训练训练数据,并使用若干机器学习算法使用测试数据预测性能,并返回模型摘要报告,该报告提供前 10 个重要特征及其重要性分数。

(图片由作者提供),模型总结

超参数调谐:

Pywedge_HP 有两个函数**HP_Tune_Classification****HP_Tune_Regression**来执行超参数调谐。

**pph = pw.Pywedge_HP(train, test, c=None, y='Survived')
pph.HP_Tune_Classification()**

(图片由作者提供),使用 PyWedge 调整基线模型的超参数交互式选项卡

结论:

在本文中,我们讨论了 PyWedge 库的实现和使用,它可以自动化 EDA、数据处理、建模、超参数调整,从而扩展数据科学家的工作流程。建议使用自定义 python 包执行 EDA,以便更好地理解数据。然而,基线建模和超参数调整可以使用 PyWedge 来完成,因为它加快了方法的速度。

阅读下面的文章,了解 4 个可以在一行代码中执行 EDA 的库。

</4-libraries-that-can-perform-eda-in-one-line-of-python-code-b13938a06ae>

参考资料:

[1] PyWedge 文档:https://pypi.org/project/pywedge/

感谢您的阅读

使用 Plotly 和 Python 自动生成交互式报告

原文:https://towardsdatascience.com/automated-interactive-reports-with-plotly-and-python-88dbe3aae5?source=collection_archive---------9-----------------------

使用 Python 中的 Plotly 轻松生成交互式报告

Plotly 中的交互式加密货币报告(Gif 由作者提供)

生成报告是一项单调乏味的任务。相反,使用 Plotly 在 Python 中开发并创建自动化的交互式报告。

本文将讨论为不同的加密货币创建自动化交互报告所需的步骤。然后,最终报告被合并成一个单独的 HTML 文件,该文件在没有外部服务器的情况下保持 Plotly 的交互功能。

生成报告的完整代码在本文中。请随意收藏这篇文章以备将来使用。

生成报告的方法遵循 ETL 过程。

  • 首先是,数据被提取出来,在这种情况下,不同加密货币的价格
  • 接下来,信息被转换,生成有用的指标和互动的图形
  • 最后一个,数据被加载到一个包含所有报告的 HTML 文件中。

提取数据和财务分析

该报告使用了几种不同加密货币的价格数据。数据是使用免费的 Alpha Vantage API for python 提取的。

使用这个 API,您可以提取不同的股票、货币和加密价格。

用 Alpha Vantage 提取财务数据(作者代码)

烛台图表

蜡烛图是市场数据的标准可视化工具。这些图显示了股票的开盘价、收盘价、最低价和最高价。

由于市场中的价格不断变化,这些值代表了一天中每分钟的交易模式。

布林线

理解股票的波动性是理解风险的关键。布林线代表市场的波动。

使用移动平均线和滚动标准差计算波段。上带是用移动平均线加两个标准差确定的,下带是负两个标准差。

当市场波动越大,波段之间的差距越大。当波动性较小时,差距缩小。这些波段也有助于理解股票的价格范围。

相对强度指数

RSI 是一个动量指标。该值的范围在 0 到 100 之间。因此,该指数表明股票是超买还是超卖。

指数移动平均线的相对强度指数(作者提供图片)

惯例是 RSI 在 70 以上时超买,30 以下超卖。

RSI 也可以揭示市场趋势。比如 RSI 在 50 以上时,有上升趋势,RSI 在 50 以下时有下降趋势。

计算熊猫的 RSI(作者代码)

编写报告

我结合了 Plotly 的几种绘图类型,展示了开发报告的一些可用功能。这些图是使用 python 创建的。然而,从许多其他编程语言,包括 R 或 Julia,都有扩展。

这些报告旨在显示信息、一些指标和市场数据变化的高级表格摘要。

数据表

尽管图表能够有效地表现数据的行为,但仍然需要汇总。数据表非常适合于具体的数据快照。

在 Plotly 中,数据表是一个内置函数,可以与其他绘图无缝集成。Plotly 中的交互功能有限,但默认情况下,您可以重新排列数据表中的列。

汇总财务数据(按作者编码)

填充区域系列

构建布林线时,混乱的图表成为一个问题。数字太多会对图表的整体信息不利。

这里我使用了 Plotly 的填充区域功能。虽然每个时间序列都有一个填充选项,但要正确设置并不容易。

标准填充选项“至零”和“至下一层”会导致不规则的行为。所以取而代之的是使用单个散点图,它的长度是整个图表的两倍。

实际上,高频带和低频带作为列表附加在一起,形成两倍长的序列。接下来,使用填充选项“toself”。以这种方式设置系列可确保 Plotly 正确地仅填充带之间的空间。

恒纹

RSI 是衡量市场趋势的常用指标。当这个指标超过一个阈值时,你就可以判断股票是超买还是超卖。

因此,在图表上用一条明显的线来表示这些阈值是有帮助的。这一细节是通过附加散点图和改变标记类型来实现的,以表明这些线不是主要系列。

合并成一份报告

需要合并这些图表,以便将每个图合并成一个完整的报告。在 Plotly 中,函数“make_subplots”就是为这个目的而设计的。

此外,在组合图时,您可以指定在所有报告之间共享 x 轴。该属性非常适合时间序列图,因为当您与图形交互时,每个序列都会对齐。

创建 HTML 报告

设计完完整的报告后,可以将其保存为 HTML 文件。虽然这不如 PDF 常见(尽管保存为 PDF 仍然是可能的),但 HTML 文件包括 Plotly 的交互性,而不需要外部托管。

每个图形都可以单独保存为 HTML 文件。然后,像 python 中的任何其他文件一样,您可以重复地添加到 HTML 文件中,从而创建更广泛的报告。

您还可以向文件中添加任何想要的 HTML 元素,并进一步更新 Plotly 图表元素。对于那些精通 web 开发的人来说,这提供了更大的灵活性。

综合所有

整个过程被组合成一个基本的 ETL 过程。考虑为那些需要定期报告的用户设置一个事件触发器,以便使用脚本定期运行报告。

但是,报告生成过程如下:

  • 使用 API 提取数据(这里是 Alpha Vantage)
  • 将数据转换成汇总表、财务指标和图表。
  • 将数据加载到一个 HTML 文件中,发送给相关的利益相关者。

该报告还利用了 Plotly-Dark 模板。

自动化财务报告(作者代码)

单一报告示例(按作者分类)

结论

生成报告是一项相当简单的任务。然而,尽管提供了大量的信息,当信息不被理解时,报告就失去了价值。

在本文中,我展示了如何使用 Plotly 和 python 创建不同加密货币的财务报告。该过程遵循基本的 ETL 方法,并且可以完全自动化。

在您的报告中添加动态交互可以使审阅信息对您的受众更有吸引力。使用 Plotly,您可以生成人们想要监控、阅读和探索数据的报告。

如果你有兴趣阅读关于新颖的数据科学工具和理解机器学习算法的文章,可以考虑在 medium 上关注我。

如果你对我的写作感兴趣,并想直接支持我,请通过以下链接订阅。这个链接确保我会收到你的会员费的一部分。

https://zjwarnes.medium.com/membership

自动化机器学习模型测试

原文:https://towardsdatascience.com/automated-machine-learning-model-testing-d0f49a36a6ac?source=collection_archive---------38-----------------------

使用 LazyPredict 只用几行代码就尝试了 20 多个机器学习模型

作者图片

我们都遇到过这种情况,我们不知道哪种模型最适合我们的 ML 项目,最有可能的是,我们正在尝试和评估许多 ML 模型,只是为了看看它们在我们的数据中的行为。然而,这不是一项简单的任务,需要时间和努力。

幸运的是,我们可以使用 LazyPredict 只用几行代码就能做到这一点。它将运行 20 多个不同的 ML 模型,并返回它们的性能统计数据。

装置

pip install lazypredict

例子

让我们看一个使用来自 Kaggle 的泰坦尼克号数据集的例子。

import pandas as pd
import numpy as np
from lazypredict.Supervised import LazyClassifier, LazyRegressor
from sklearn.model_selection import train_test_split

data=pd.read_csv(‘train.csv’)

data.head()

在这里,我们将尝试预测是否有乘客在泰坦尼克号上幸存,因此我们有一个分类问题。

Lazypredict 还可以进行基本的数据预处理,如填充 NA 值、创建虚拟变量等。这意味着我们可以在读取数据后立即测试模型,而不会出现任何错误。然而,我们可以使用我们的预处理数据,这样模型测试将更加准确,因为它将更接近我们的最终模型。

对于这个例子,我们不做任何预处理,让 Lazypredict 做所有的工作。

#we are selecting the following columns as features for our models
X=data[['Pclass', 'Sex', 'Age', 'SibSp',
 'Parch', 'Fare', 'Embarked']]

y=data['Survived']X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,random_state=7)# Fit LazyRegressorreg = LazyClassifier(ignore_warnings=True, random_state=7, verbose=False)#we have to pass the train and test dataset so it can evaluate the modelsmodels, predictions = reg.fit(X_train, X_test, y_train, y_test)
models

作者图片

如您所见,它将返回一个包含模型及其统计数据的数据框。我们可以看到基于树的模型比其他模型表现得更好。知道了这一点,我们可以在我们的方法中使用基于树的模型。

您可以从 Lazypredict 获得完整的管道和使用的模型参数,如下所示。

#we will get the pipeline of LGBMClassifier
reg.models['LGBMClassifier'] Pipeline(steps=[('preprocessor',
                 ColumnTransformer(transformers=[('numeric',
                                                  Pipeline(steps=[('imputer',
                                                                   SimpleImputer()),
                                                                  ('scaler',
                                                                   StandardScaler())]),
                                                  Index(['Pclass', 'Age', 'SibSp', 'Parch', 'Fare'], dtype='object')),
                                                 ('categorical_low',
                                                  Pipeline(steps=[('imputer',
                                                                   SimpleImputer(fill_value='missing',
                                                                                 strategy='constant')),
                                                                  ('encoding',
                                                                   OneHotEncoder(handle_unknown='ignore',
                                                                                 sparse=False))]),
                                                  Index(['Sex', 'Embarked'], dtype='object')),
                                                 ('categorical_high',
                                                  Pipeline(steps=[('imputer',
                                                                   SimpleImputer(fill_value='missing',
                                                                                 strategy='constant')),
                                                                  ('encoding',
                                                                   OrdinalEncoder())]),
                                                  Index([], dtype='object'))])),
                ('classifier', LGBMClassifier(random_state=7))])

此外,您可以使用完整的模型管道进行预测。

reg.models['LGBMClassifier'].predict(X_test)

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

和 LazyClassifier 一样,我们可以使用 LazyRegressor 来测试回归问题的模型。

总结一下

Lazypredict 可以帮助我们对哪种模型在我们的数据中表现更好有一个基本的了解。它几乎不需要任何数据预处理就可以运行,因此我们可以在读取数据后立即测试模型。

值得注意的是,有更多的方法来进行自动化机器学习模型测试,如使用 auto-sklearn 但安装它非常复杂,尤其是在 windows 中。

使用 PyCaret 的自动机器学习

原文:https://towardsdatascience.com/automated-machine-learning-using-pycaret-4bb90ab3e2c7?source=collection_archive---------11-----------------------

用不到十行代码自动化您的机器学习工作流程

亨特·哈里特在 Unsplash 上的照片

介绍

您是否希望为您的企业实施机器学习,但没有太多时间来构建它?PyCaret 可以帮助你!

PyCaret 是一个用于 Python 的开源机器学习库,可以减少您准备数据集来测试模型的时间。PyCaret 很容易使用,所以您不必花时间编写代码,直到过程结束。

更有趣的是,不到十行代码就可以拥有最好的机器学习模型!多酷啊。!

本文将向您介绍如何使用 PyCaret,从准备数据到部署模型。没有进一步,让我们开始吧!

实施

数据源

在这种情况下,我们将使用一个名为丙型肝炎预测数据集的数据集。这个数据集是 fedesoriano 在 Kaggle 上创建的。它由几个变量组成,从年龄和性别等人口统计学变量到类似生物标记的变量。您可以在这里 访问数据集

作者捕捉到的。

以下是加载数据集的代码,以及从中进行的预览:

从上面可以看到,有一个名为“未命名:0”的列。我们需要从数据集中丢弃该列,因为它是每一行的标识符。为了删除该列,我们运行如下代码:

准备数据

加载数据后,下一步是准备数据。使用 PyCaret,准备数据很简单。我们可以使用 pycaret.classification 库中的一个名为 setup 的函数。下面是实现这一点的代码:

以下是我们运行代码时的流程预览:

从上图可以看出,这说明 setup 函数只用一个函数就完成了所有的预处理步骤。我们可以填充缺失的值,转换数据集,删除异常值,等等。

如果我们想设置自定义预处理步骤,我们可以在设置功能上设置参数。对于这种情况,让我们填充数据集上缺失的值。我们可以给出一个称为 numeric _ attraction 的参数,用于填充数字列上的缺失值。我们将用该列的中值来填充缺失值。

下面是实现这一点的代码:

在我们设置参数之前,数值插补行看起来是这样的:

下面是我们设置数值插补行后的样子:

现在,我们已经将数值估算器设置为中值。除了数值插补参数,您还可以在设置功能中给出其他参数。更多详情,可以在这里 阅读 PyCaret 的文档

比较模型

PyCaret 库的一个主要特性是,你可以同时运行任何机器学习模型,从逻辑回归、决策树、XGBoost 等等!

要运行模型比较,我们可以使用 pycaret.classification 库中的 compare_model 函数。下面是代码及其结果:

从结果中,我们可以看到该模型及其度量性能。如上所述,梯度推进分类器模型在几乎所有指标上都有很好的性能。

仅在精度指标上,该模型并没有获得很好的性能。线性判别分析模型取得了较好的精度结果。

想象一下,只要一个函数,你就可以同时得到所有的模型结果!多酷啊。

因此,我们将在下一步使用梯度提升分类器。

再现最佳模式

现在让我们再现最佳模型,其中我们将使用梯度推进分类器作为模型。下面是代码及其结果:

超参数调谐

虽然该模型得到了最好的结果,但我们可以通过超参数调整来改进它。超参数调整是一个从所有超参数组合中挑选最佳超参数的过程。简单来说,超参数是一个我们可以在数据集上训练模型之前在模型上设置的参数。

在 PyCaret 中,我们可以使用 tune_model 函数来调整模型的超参数。代码及其结果如下所示:

模型评估

在我们得到最佳超参数组合的模型后,我们再通过看几个图表来评价模型。

在 PyCaret 中,我们可以通过使用一个函数来可视化许多图表。例如,让我们使用 plot_model 函数绘制 ROC 曲线,如下所示:

为了可视化混淆矩阵,您可以使用如下相同的函数:

在 PyCaret 中,我们还可以可视化我们的模型对数据的决策边界。代码如下所示:

除此之外,该函数还可以从数据中可视化特征的重要性。所以我们知道模型如何预测数据,哪些变量决定最终结果。下面是实现这一点的代码:

模型检验

现在我们知道我们的模型已经达到了很好的效果。现在让我们在看不见的数据上测试这个模型。我们可以使用名为 predict_model 的函数进行预测,并显示每个指标的性能。下面是代码及其结果:

从上面的结果可以看出,该模型的性能比我们在超参数调整阶段的性能要低。但是记住,这个数据之前没有训练过,所以结果是好的。现在让我们保存最终的模型。

保存模型

在保存模型之前,我们需要重新训练模型。在 PyCaret 中,我们可以使用 finalize_model 函数来做到这一点。训练过程将采用完整的数据集,包括测试数据。因此,我们可以在以后的实际测试数据上使用该模型。下面是实现这一点的代码:

现在让我们保存模型。在 PyCaret 中,我们可以使用 save_model 函数来做到这一点。下面是实现这一点的代码:

如果您想在另一个项目中加载模型,您可以像这样使用 load_model 函数:

结束语

干得好!现在你已经学会了如何使用 PyCaret 来自动化你的机器学习管道。希望能帮助你缩短开发机器学习模型的过程。通过这样做,你可以更专注于问题,而不是解决技术问题。

如果你对我的文章感兴趣,你可以关注我的媒体以获得更多类似的文章。如果你有任何问题或者想打个招呼,你可以在 LinkedIn 上联系我。

谢谢你看我的文章!

H2O 的自动机器学习

原文:https://towardsdatascience.com/automated-machine-learning-with-h2o-258a2f3a203f?source=collection_archive---------6-----------------------

加速您的机器学习开发周期

拥有摄影的照片在 Unsplash 上

什么是自动 ML?

自动机器学习(AutoML)是机器学习管道中自动化任务的过程,例如数据预处理、超参数调整、模型选择和评估。在本文中,我们将探讨如何利用 H2O 的开源自动化机器学习包来加速数据科学家的模型开发过程。

设置

pip install h2o

让我们导入必要的包

import h2o
from h2o.automl import H2OAutoML

初始化 H2O 集群。

h2o.init()

数据准备

我们将使用来自 UCI 的数据集,该数据集描述了一家银行向客户提供定期存款的营销活动。如果客户同意,目标变量为yes,如果客户决定不进行定期存款,目标变量为no

将数据集作为H2OFrame加载

df = h2o.import_file(path='/kaggle/input/bank-marketing-campaigns-dataset/bank-additional-full.csv')

描述数据集。H2O 提供了 10 行样本数据以及数字列的基本汇总统计数据。

df.describe(chunk_summary=True)

将数据集分为训练集和测试集

train, test = df.split_frame(ratios=[0.8], seed = 1)

火车汽车模型

让我们配置 AutoML 训练参数。

  • max_models:训练模型的最大数量
  • balance_classes:设置为True,平衡数据不平衡任务的分类标签
  • seed:设定再现性
aml = H2OAutoML(max_models =25,
                balance_classes=True,
		seed =1)

我们可以通过限制以下各项来限制搜索最佳模型所花费的时间:

  • 使用max_models的最大型号数量
  • 使用max_runtime_secs花费的总时间
  • 使用max_runtime_secs_per_model训练任何单一模型所花费的时间。

通过指定以下内容开始培训:

  • training_frame:包含训练数据的数据帧
  • y:包含目标变量的training_frame中的列
aml.train(training_frame = train, y = 'y')

此外,我们还可以指定validation_frame,这是一个 H2OFrame,模型在训练过程中根据它进行评估。如果未设置此参数,将使用 k 重交叉验证来评估模型。其他可选参数参考文件。

那么引擎盖下发生了什么呢?

H2O 汽车公司按以下顺序训练和交叉验证以下模型:

  1. 三个预先指定的 XGBoost GBM(梯度增压机)型号
  2. GLMs 的固定网格
  3. 默认随机森林(DRF)
  4. 五个预先指定的 H2O GBM
  5. 一种近似默认的深度神经网络
  6. 极度随机的森林(XRT)
  7. XGBoost GBMs 的随机网格
  8. H2O GBM 的随机网格
  9. 深度神经网络的随机网格

此外,它还培训:

  1. 上面训练的所有模型的堆叠集合
  2. 包含每个算法类的最佳执行模型的“最佳系列”堆叠集成

估价

训练完模型后,我们可以使用排行榜来比较模型性能。H2O 汽车公司制作了一个排行榜,根据预定义的指标对训练好的模型进行排名。默认情况下,它按照 logloss 和 rmse 的升序对模型进行排序,分别用于分类和回归任务。

lb = aml.leaderboard
lb.head(rows=lb.nrows)

排行榜指标是根据交叉验证集计算的,除非在培训期间指定了leaderboard_frame

aml.train(training_frame = train,
          y = 'y',
	  leaderboard_frame = my_leaderboard_frame)

在分类任务的典型机器学习评估中,我们将有兴趣了解最佳性能模型的性能,如 ROC AUC、精确度、召回率、F1、精确度、增益/提升和交叉验证数据集上的混淆度量。H2O 只用两行代码就提供了所有这些指标。

让我们得到性能最好的模型,并检查其结果。

best_model = aml.get_best_model()
print(best_model)

交叉验证数据中报告的通用指标

混淆矩阵和度量在各自的最大阈值

增益/提升图表

我们还可以使用上面显示的相同评估指标来评估维持测试集上的最佳模型。

best_model.model_performance(test)

保存、加载和预测

让我们保存一个二进制模型

model_path = h2o.save_model(model=best_model,path='/kaggle/working/model', force=True)print(model_path)>> /kaggle/working/model/StackedEnsemble_AllModels_AutoML_20210803_232409

保存的二进制模型可以加载到不同的笔记本中,并用于在测试集上进行预测。注意,用于训练保存的二进制模型的 H2O 版本必须与我们的推理环境中使用的版本相同。

import h2o #must be same version used during training of the modelh2o.init()loaded_model = h2o.load_model(path='/kaggle/working/model/StackedEnsemble_AllModels_AutoML_20210803_232409')
loaded_model.predict(test)

可解释性

H2O AutoML 还提供了模型的全局可解释性的见解,如变量重要性,部分依赖图,SHAP 值和模型相关性,只有一行代码

explain_model = aml.explain(frame = test, figsize = (8,6))

此外,它还为单个记录提供了本地可解释性。我们可以在frame参数中输入一个H2OFrame,并指出我们希望使用row_index参数来解释哪一行。在这种情况下,我们解释测试帧的第 15 行的结果。

aml.explain_row(frame = test, row_index = 15, figsize = (8,6))

结论

在本文中,我们研究了如何使用 H2O 汽车公司:

  • 描述数据集
  • 用最少的人工输入训练模型
  • 根据训练好的模型进行预测
  • 解释模型的预测

您可以在此处找到用于训练和推理的笔记本:

  • 训练
  • 推论

使用 Sklearn 管道的自动机器学习

原文:https://towardsdatascience.com/automated-machine-learning-with-sklearn-pipelines-a2be2a0a6e1?source=collection_archive---------23-----------------------

一条管道来统治他们。

照片由 JJ 英在 Unsplash

P ipelines 提供了自动化训练和测试模型的结构。它们可以包含列转换、缩放、插补、特征选择和超参数搜索。

通过将所有这些步骤组合成管道,可以抽象出单独的步骤。

这篇文章展示了如何创建一个包含 Sklearn 中每个函数的管道。

*请随意将此页面加入书签以供将来使用 *

使用这个管道,定义您的数据,根据需要更新超参数,然后点击 run。

将这些步骤中的每一步抽象成一个管道,使得构建有效模型的整个过程更具可伸缩性。

此外,根据构建和测试管道的方式,您可以快速迭代许多不同的估计器、特征选择方法和其他可能提高模型整体性能的方法。

当开始一个数据科学项目时,需要管理许多不同的任务。例如,如果不进行大量测试,就不可能知道哪种模型最适合您的问题。

一种常见的方法是从一个简单的模型开始,以提供一个基线性能。我在这篇文章中讨论了应该首先使用什么模型,以及为什么更简单的模型更好:

设置

在这篇文章中,我使用了乳腺癌数据集。但是,管道还将展示列转换功能。因此,数据集用一个用于转换的虚拟分类变量来扩展。

这种改变是通过添加一个随机分类列来完成的。

import pandas as pd
from scipy.stats import uniform, geom, loguniform, randint, expon
from sklearn import ensemble, neighbors, tree, linear_model, svm, naive_bayes, gaussian_process, feature_selection, preprocessing, impute, metrics, decomposition, compose
from sklearn.model_selection import train_test_split, RandomizedSearchCV
from sklearn.metrics import roc_auc_score
from sklearn.pipeline import make_pipeline, Pipeline as Pipeline
from sklearn.datasets import load_breast_cancer
import itertools
import random
import pickleTEST_SIZE = 0.1
RANDOM_STATE = 10
data = load_breast_cancer()
df = pd.DataFrame(data.data, columns=data.feature_names)
df['target'] = data.target
X = df.drop(['target'], axis=1)
X['categorical'] = random.choices(['one', 'two', 'three'], k=len(X))
y = df['target'].astype(float)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=TEST_SIZE, random_state=RANDOM_STATE, stratify=y)

本文中生成的管道是为二进制分类问题而创建的。然而,管道也支持回归问题。

为了针对回归问题调整管道,更新输入的数据、测试中使用的模型和评分标准。然后,管道的其余部分可以保持不变。

带有随机分类变量的乳腺癌数据集(图片由作者提供)

管道设置

本节旨在从头到尾建立一个完整的管道,涵盖 sklearn 必须为监督学习提供的每种类型的功能。

不幸的是,sklearn 中的一些函数本质上有无限的可能性。例如,以一个简单的逻辑回归函数为例。理论上,正则化参数是一个连续变量,它使得可能的流水线的数量是无限的。

因为 sklearn 函数本质上有无限的排列,最终的管道将展示监督学习管道中每种类型的至少一个函数。

此外,由于最终管道将测试多个模型、特征选择技术、插补方法、缩放器和变换,因此管道的设置与其他示例所示略有不同。

然而,这种设置被设计成易于遵循和根据需要改变组件。

元参数

N_ITER = 1
N_JOBS = 1
K_FOLDS = 10
VERBOSE = 0
SCORING_METRIC = 'roc_auc'
SCORING_FUNCTION = metrics.roc_auc_score
MAX_ITER = 10000
LOGISTIC_REGRESSION_SOLVER = 'sag'
OPTIMAL_MODEL_FILENAME = 'optimal_model.pickle'
categorical_feature_names = ['categorical']
best_score = 0

与超参数相比,元参数控制如何设置问题、如何执行计算以及如何跟踪结果。

这里我提供几个选项。

  • 要改变超参数优化中执行的迭代次数,调整 N_ITER
  • 为了改变具有额外计算能力的模型的作业数量,调整 N_JOBS
  • 要调整验证的折叠数,请调整 K_FOLDS
  • SCORING_METRIC 是被监督问题的评估指标
  • 计分函数是计分指标的函数。由于管道设置,函数和名称都是必需的。
  • 最大 ITER逻辑回归求解器支持逻辑回归和支持向量机模型的收敛。其他解算器和这些模型的收敛性存在一些问题。这些参数缓解了这些问题。
  • OPTIMAL_MODEL_FILENAME ,存储所有模型类型的最优模型的名称。基于评分标准的最佳分数
  • 分类特征名称,转换为二元变量的分类特征列表。
  • best_score ,一个跟踪流水线优化的最佳分数的变量。

型号

例如,要测试的模型定义如下。元组列表,其中元组的第一个元素是模型(回归或分类器),第二个元素是超参数优化期间使用的参数网格。元组的第三个元素是超参数优化期间模型的迭代次数。

因为每个模型的超参数的数量不同,所以为每个模型指定迭代的次数。例如,对于一个随机森林分类,大约有一打不同的超参数。然而,对于逻辑回归,只有几个超参数。因此,寻找最佳模型需要较少的迭代。

models = [
    (ensemble.RandomForestClassifier(),{
    'model__n_estimators': randint(50,500),
    'model__max_depth': randint(3,10),
    'model__max_features': ['sqrt'],
    'model__min_samples_split': randint(2,20),
    'model__min_samples_leaf': randint(1,10),
    'model__criterion': ['gini', 'entropy'],
    'model__ccp_alpha': loguniform(0.1e-5, 0.1e-0)
    }, 1),

    (neighbors.KNeighborsClassifier(),{
    'model__n_neighbors': randint(3,20),
    'model__weights': ['uniform', 'distance'],
    'model__algorithm': ['auto', 'ball_tree', 'kd_tree', 'brute']
    }, 1),

    (svm.SVC(probability=True, max_iter=MAX_ITER),{
    'model__C': loguniform(3e-4, 3e-1),
    'model__kernel': ['linear', 'poly', 'rbf', 'sigmoid']
    }, 1), (linear_model.LogisticRegression(solver=LOGISTIC_REGRESSION_SOLVER,
    max_iter=MAX_ITER),{
    'model__C': loguniform(3e-4, 3e-1),
    'model__penalty': ['none', 'l2'],
    'model__class_weight': ['balanced', None]
    }, 1),

    (naive_bayes.GaussianNB(),{}, 1),
]feature_selectors = [
    (feature_selection.SelectFromModel(linear_model.LogisticRegression()),{
    'feature_selection__estimator__penalty': ['l2'],}),
    (decomposition.PCA(),{'feature_selection__n_components': randint(2, 5),}),
]scalers = [
    (preprocessing.MinMaxScaler(),{}),
    (preprocessing.RobustScaler(),{'scaler__quantile_range': [(25.0, 75.0),
    (10.0, 90.0)] })
]imputation = [
    (impute.SimpleImputer(),
    {'imputer__strategy': ['mean', 'median']})
]transformers = [
    (preprocessing.OneHotEncoder(),
    {'column_transformer__transformer__drop': ['first', 'if_binary', None]})
]hyparameters = list(
    itertools.product(
    transformers, imputation, scalers, feature_selectors, models
))

设置每组的参数以支持超参数优化中使用的随机网格搜索。对于连续变量,参数期望分布。这些是使用 scipy 库定义的,该库允许预先指定发行版。当超参数是分类的时,超参数可以简单地固定为一个列表。

使用 itertools 包建立完整的超参数网格。该包中的产品功能在每个参数网格之间创建所有可能的配置。

通过以这种方式设置超参数,迭代处于单个循环中。

这个相同的过程可以使用多个循环来完成。然而,为了便于阅读,itertools 将这些众多的列表压缩成一个列表。

注意每个超参数的命名。参数的前缀与管道中使用的名称相匹配。sklearn 知道什么参数去哪里的方式是基于参数的名称。

当管道中有链接的函数时,名称会稍有变化。例如,“feature_selection _ _ estimator _ _ penalty”对应于管道中的“feature _ selection”命名步骤,对于此选项,它是 SelectionFromModel 特征选择方法。“估计值”部分对应于 SelectionFromModel 中的估计值参数。最后,“惩罚”部分对应于 SelectionFromModel 中使用的估计量的惩罚参数,它是为逻辑回归而设置的。

双下划线“__”指定一个函数何时在另一个函数中使用,以控制哪个函数转到管道步骤中的不同函数。

迭代

下面的循环遍历每个参数组合,并为每个配置优化一个模型。

for transformer_params, imputer_params, scaler_params, feature_selection_params, model_params in hyparameters:
    hyperparameter_dict = {
        **transformer_params[1],
        **imputer_params[1],
        **scaler_params[1],
        **feature_selection_params[1],
        **model_params[1]
    }
    column_transformer = compose.ColumnTransformer(
        [('transformer', transformer_params[0],categorical_feature_names)],
        remainder="passthrough"
    ) pipe = Pipeline(steps=[
        ('column_transformer', column_transformer),
        ('scaler', scaler_params[0]),
        ('imputer', imputer_params[0]),
        ('feature_selection', feature_selection_params[0]),
        ('model', model_params[0])
    ])
    optimal_model = RandomizedSearchCV(
        pipe, hyperparameter_dict,
        n_iter = model_params[2], cv=K_FOLDS,
        scoring=SCORING_METRIC, n_jobs = N_JOBS,
        return_train_score=True, verbose = VERBOSE
    )
    optimal_model.fit(X_train, y_train)

    y_pred = optimal_model.best_estimator_.predict(X_train)
    y_pred_prob = optimal_model.best_estimator_.predict_proba(X_train)[:,1]
    y_pred_test = optimal_model.best_estimator_.predict_proba(X_test)[:,1]
    score = SCORING_FUNCTION(y_test, y_pred_test) print(
        'Optimal Training Score: ', optimal_model.cv_results_['mean_train_score'][optimal_model.best_index_],
        '\Optimal Test Score: ', optimal_model.best_score_,
        '\nHold Out Test Score: ', score
    )
    if score > best_score:
        best_score = score
        pickle.dump(optimal_model, open(OPTIMAL_MODEL_FILENAME, 'wb'))

分解每个组件:

  • 通过组合来自流水线中每个步骤的超参数来创建单个字典。
  • 列转换器是在管道之前单独创建的。此转换器为特征转换启用了单独的路径。
  • 管道“管道”已创建。步骤是一个元组列表,其中第一个元素是步骤的名称。(此名称匹配与步骤相关的超参数的前缀)。第二个要素是该步骤的函数,无论是缩放、插补还是预测。
  • 使用随机超参数搜索来确定最佳模型。这种搜索从超参数空间采样,用于每个模型所需的几次迭代。
  • 使用评分功能评估培训、测试和坚持测试的结果。
  • 如果模型的得分比当前的最佳模型好,则使用 pickle 存储该模型。

注:这里使用随机搜索,因为它比网格搜索更有可能找到最佳模型。有关不同超参数搜索方法的详细信息以及随机搜索优于网格搜索的原因,请阅读以下帖子:

结论

Sklearn 管道提供了很大的灵活性。然而,他们可能会面临挑战。

通常,在构建管道时,可用的示例仅显示了管道的特定部分。因此,将这些碎片放在一起并不总是简单的。

该代码允许 sklearn 中的大多数可用功能自动使用或稍加调整即可使用。希望这条管道能让你的发展流动起来。

如果你有兴趣阅读关于新颖的数据科学工具和理解机器学习算法的文章,可以考虑在 Medium 上关注我。

如果你对我的写作感兴趣,想直接支持我,请通过以下链接订阅。这个链接确保我会收到你的会员费的一部分。

https://zjwarnes.medium.com/membership

脸书实验公司的 Robyn 为自动化营销组合建模

原文:https://towardsdatascience.com/automated-marketing-mix-modeling-with-facebooks-robyn-fd79e60b489d?source=collection_archive---------1-----------------------

营销组合建模的新工具概述

斯科特·格雷厄姆在 Unsplash 上拍照。

这篇文章为你提供了脸书实验的罗宾的第一个概述。由于脸书营销科学团队已经创建了一个很棒的快速入门指南和非常详细的页面,我尽量保持文章简短切题。详细解释可以在这里找到更多信息。

TL;博士

  • 脸书实验公司的 Robyn 是一个自动营销组合建模(MMM)代码,目前处于测试版。
  • 它为特征转换提供了两种 adstock(几何和威布尔)和一种 s 曲线转换(收益递减)技术。
  • 为了考虑时间序列的特征,罗宾使用了脸书先知。
  • 它利用脸书的 Nevergrad 无梯度优化平台生成一组 Pareto 最优模型解。
  • 为了增加模型的准确性,它允许你包含随机控制实验的结果。

在我们开始之前…为什么 MMM 如此重要?

每个营销人员都有两个大问题:我当前的营销渠道有什么影响?和我应该如何战略性地分配我的预算以获得最佳营销组合?

这些问题并不新鲜。约翰·沃纳梅克(1838-1922)被一些人认为是市场营销的先驱,他也有同样的问题,并因其著名的经常被引用的名言而闻名:

我一半的广告支出都浪费了;问题是,我不知道是哪一半。

为了应对这些挑战,计量经济学家开发了被称为营销组合建模(MMM)的多元回归技术。这个领域的一个非常新的工具是脸书的 Robyn,目前它还处于测试阶段。脸书实验小组将罗宾描述为

[……]自动化营销组合建模(MMM)代码。它旨在通过岭回归和进化算法减少人为偏差,通过提供预算分配器和收益递减曲线实现可操作的决策制定,并允许对因果关系进行地面实况校准。

在下文中,我会给你一个 Robyn 的功能和主要思想的快速概述。由于它仍处于测试版本,所使用的代码和概念可能会发生变化。你可以在这里找到它的最新版本。

使用的数据集

为这篇文章找到一个合适的开放数据集是相当棘手的,所以我使用谷歌的aggregate 营销系统模拟器 (AMSS)来生成一个简单的数据集。如果你对 AMSS 的更多细节感兴趣,你可以在这里找到他们的论文,如果你想用我用过的数据集,你可以在这里找到。

您将在下面找到营销数据的描述表和图表,以便更好地熟悉数据集。

表 1。数据集的描述性指标(图片由作者提供)。

使用的数据集基于每周数据,包含 208 个条目。所有数值均以欧元(€)为单位,不存在北美数值。我们的目标变量收入,而其他列是可以用来解释它的特性。

_S 结尾的栏目是我们按渠道(电视、广播、付费搜索)划分的营销预算支出。我们的竞争对手销售额由自我解释栏竞争对手 _ 销售额给出。

描述表中没有显示的一列是日期列,以格式 YYYY-MM-DD 表示相应的周。

图 1 显示了一段时间内的收入、收入构成、竞争对手的销售和营销费用。

图一。收入、收入构成、销售和支出随时间变化的可视化(图片由作者提供)。

我们可以清楚地看到收入的季节性(A1)以及一点趋势(A2)。还可以看到,竞争对手的销售遵循与我们的收入非常相似的模式,我们在春季的广播费用和季节性以及付费搜索费用的趋势方面存在差距。

图 2 显示了我们的数据集的相关图,以初步了解变量之间的关系。

图二。我们数据集的相关图(图片由作者提供)。

我们可以看到竞争对手的销售额和我们的收入之间有很高的相关性,其次是我们的付费搜索费用和我们的收入以及竞争对手的销售额之间的相关性较低,为 0.4。

现在,您对数据集稍微熟悉了一些,让我们现在使用 Robyn。

建立我们的 MMM 项目

为了获得 Robyn 的最新版本,我们将它的存储库克隆到我们的机器上:

git clone https://github.com/facebookexperimental/Robyn

在我们克隆了存储库之后,我们创建了一个名为 plots新文件夹来存储后来结果的可视化。

您的文件夹结构现在应该如下所示:

Robyn/
├── *CHANGELOG.md*
├── *CODE_OF_CONDUCT.md*
├── *CONTRIBUTING.md*
├── *LICENSE.md*
├── *README.md*
├── **Robyn.Rproj** ├── **plots** ├── **source**
│   ├── *de_simulated_data.csv*
│   ├── **fb_robyn.exec.R**
│   ├── *fb_robyn.func.R*
│   ├── *fb_robyn.optm.R*
│   └── *holidays.csv*
├── *website*

我们感兴趣的主文件位于源文件夹中,名为 fb_robyn.exec.R 。这是我们必须设置配置和运行争论、建模、优化以及预算分配(如果需要)流程的文件。

但是在我们去那里之前,让我们简短地看一看 Robyn 使用了什么(建模)技术。

罗宾的技术

以下几点从较高的层面描述了罗宾的内心世界。有关更多详细信息和解释,请参见他们的文档。

岭回归

开发人员使用正则化方法的动机是解决许多回归变量之间的多重共线性,并防止模型过度拟合。图 3 显示了该模型的方程以及函数的主要组成部分。

图 3。通过Facebook experiment建立模型方程。

其中 yₜ是我们的因变量在时间 t 的收入。自变量由截距定义,随后是 ad-stocks 曲线 变换分量用于每种媒体 j节假日季节性趋势效果分别用节假日节假日趋势来表示。附加 独立 变量定义,后跟误差项 ε

特征转换选项

MMM 中非常常见的转换技术是 ad-stock 和 s 曲线(收益递减)转换。

广告股票转型 广告股票转型背后的想法是,广告效应通常不会立即生效。它们有一个半衰期。顾客(通常)不会在看到你的广告后立即跑到商店购买你的产品。你的广告需要一些时间来适应。

罗宾在这里提供了两种方法,经典的几何方法和更灵活的 T2 威布尔生存函数。更深入的解释请见文件。

S 曲线(收益递减)转变
这种转变背后的基本思想是,随着时间的推移,广告会失去其有效性,即使给它分配了更多的钱。

趋势、季节性和假日效应

为了在模型中包含趋势、季节性或假日等时间序列特征或成分,Robyn 使用了 FacebookProphet。

自动化超参数选择和优化

Robyn 使用脸书的 Nevergrad 无梯度优化平台执行多目标优化,通过提供一组帕累托最优模型解决方案来平衡支出份额和渠道系数分解份额之间的关系。

这些帕累托最优模型解是多次迭代(即,20,000 次迭代和可能的模型解)运行进化算法(自然选择)的结果

使用实验结果进行校准

Robyn 允许我们应用随机控制实验的结果来提高模型的准确性,其中这些结果被用作缩小媒体变量系数的先验。

这部分内容不在本文讨论范围内。如果你对更多细节感兴趣,你可以在这里找到他们的文档。

MMM 配置

现在我们对 Robyn 的技术有了一个基本的概述,让我们继续我们的用例。您将在本文末尾找到完整的代码。

我们经营罗宾。使用 R-Studio 运行 Rproj,并打开位于源文件夹中的 fb_robyn.exec.R。

避免时间序列特征的错误

如果您的操作系统不是英语,您应该做的第一件事是取消第 13 行的注释:

否则,您将在数据争论过程中出错(第 166 行)。

安装并加载库

确保安装所有使用的库,创建一个名为 r-reticulate 的 conda 环境,安装 nevergrad 并使用创建的 conda env。

加载数据

现在是时候加载我们的 csv 文件了。开发团队已经提供了一个名为 de_simulated_data.csv 的文件。

开发团队还提供了一个假日文件,其中包括几个国家(如美国、英国、印度、德国)的公共假日。

设置模型输入变量

在这一部分,我们将代码中的配置链接到数据集中的列。这一部分非常重要,因为在自动化数据争论过程中,打字错误会导致错误。

设置全局模型参数

Robyn 允许我们使用几何威布尔股票技巧。在本文中,我们将继续使用几何方法,但是尝试一下威布尔技术绝对是值得的。

由于 Robyn 使用 Nevergrad,我们必须选择一种算法以及试验次数。这里我们也坚持默认的。

设置超参数界限

根据我们定义的变量和使用的 ad-stock 方法,我们必须设置它们的超参数界。

运行模型

现在我们已经设置了所有的参数,我们可以使用下面的代码来运行我们的模型。

Robyn 现在正在运行,并将在我们指定的绘图文件夹中自动生成绘图。

输出和诊断

建模过程完成后,您应该在 plots 文件夹中找到几个文件。

这些图(以模型 id 作为其名称)代表基于 Pareto 最优过程(pareto_front.png)的最优模型解决方案,并为我们提供关于超参数选择(hypersampling.png)的附加信息。

图 4。显示了其中一种型号(3_30_1)的单页型号。

图 4。单页纸模型(图片由作者提供)。

响应分解瀑布通过预测器
显示每个特性对响应变量(收入)影响的百分比。在本例中,34.08%的收入可归因于季节性,11.62%可归因于电视广告等。

支出份额与效果份额 该图描述了各渠道的支出份额和效果份额。除此之外,它还显示了每个渠道的投资回报率(ROI)。对于我们的例子,我们可以看到频道广播的投资回报率最高,其次是电视和付费搜索。这也表明,电视上的平均费用比他们的平均效果份额大一点。这可能意味着他们正遭遇一些收益递减。

平均广告库存衰减率 显示每个渠道的百分比衰减率。衰变率越高,衰变效应持续的时间越长。对于这个例子,频道 TV 具有最高的平均衰减率。

实际响应与预测响应 该图将实际响应与我们的预测进行比较。我们的目标是我们的模型能够解释数据中的大部分差异。因此,我们寻求高 R 平方(rsq)和低 NRMSE。

响应曲线和渠道平均支出 表明每个渠道的饱和程度,并可能建议潜在的预算再分配策略。观察这些曲线,它们到达拐点和平坡的速度越快,每增加一次€消耗,它们就越快饱和。对于我们的例子,广播和付费搜索的曲线没有显示任何平坦的斜率,可能需要进一步的调查。

拟合与残差 经典图表检查我们的回归模型是否有问题。

模拟预算分配

一旦我们决定了一个合理的(!!)模型,我们可以运行预算优化模拟来计算最佳媒体支出分配。我们有两种类型的模拟场景:

  • max _ historical _ response
  • 最大响应预期花费

第一个将使用对模型有贡献的历史数据和花费来计算最佳媒体计划。

第二个是在给定预算和天数的情况下计算最佳媒体计划。

所有的模型都存储在model _ output _ collect $ all solutions变量中。假设我们想使用上面的模型(3_30_1 ),我们只需使用以下代码:

除了模型 id 和场景类型之外,我们还必须为我们使用的通道设置下限和上限。如果我们渠道的下限是 0.7,上限是 1.2,那么我们的花费变化将受到平均时间段花费的 0.7 倍和平均时间段花费的 1.2 倍的约束。

运行该代码后,Robyn 输出一个新的单页页面(图 5)。

图 5。预算分配器最佳结果单页纸(图片由作者提供)。

左图显示了如果我们遵循预算优化,预算分配和平均反应将如何变化。右侧的图表显示了每个渠道的响应曲线,以及初始平均支出水平与推荐平均支出水平的对比。

这篇文章的想法是向您提供脸书实验的 Robyn 的第一个概述,以及如何通过使用简化的数据集来使用它。对于更深入的解释,实验结果的使用,以及更多的细节,我强烈建议你查阅 Robyn 的文档。

与这个简短的介绍不同,在型号选择部分投入时间和精力也很重要。只有使用合理的模型,与企业讨论结果并使用预算优化步骤才有意义。

即使该项目仍处于测试阶段,但其背后的动机和想法及其功能非常巧妙,令人印象深刻!

如果我可以许三个愿望,我希望有一个选择,对横截面数据使用面板回归。其次,找到一种减少计算时间的方法也是很棒的。第三,类似于第一个愿望,不仅仅使用分类变量作为基线变量会很好。...如果我能做第四个 Python 的移植会很棒;)

完整文件的代码: