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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

MCMC 在密码学和最优化中的应用

原文:https://towardsdatascience.com/applications-of-mcmc-for-cryptography-and-optimization-1f99222b7132?source=collection_archive---------3-----------------------

增进理解的例子

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

Photo by Balázs Kétyi on Unsplash

MCMC 是一个很难理解的话题,但是例子确实很有帮助。

上次我写了一篇文章,直观地解释了 MCMC 方法。在那篇文章中,我展示了如何使用 MCMC 链来模拟分布部分已知的随机变量,即我们不知道归一化常数。

我还讲述了如何使用 MCMC 的 来解决大型状态空间的问题。 但没有给出例子。

在这篇文章中,我将提供一些真实的用例。

如果你到目前为止还没有真正欣赏 MCMC,我希望我能在这篇博文结束时激起你的兴趣。

这个帖子是关于借助一些计算机科学问题来理解 MCMC 方法的。

1.密码学——你是一个密码迷吗?

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

我喜欢密码学。

解谜一直是我的一个爱好,这个例子帮助我更好地理解了许多关于 MCMC 的想法。

这个问题也有很大的渊源,因为这个方法是由数学魔术师佩尔西·戴康尼斯提出的。

所以问题是:

有人带着下面的文字来找你。这条短信看起来像是胡言乱语,但实际上,这是一条可以拯救数百万人生命的秘密短信。他还告诉我们,它是用替代密码解密的。

XZ STAVRK HXVR MYAZ oak zm JKSSO SO MYR OKRR XDP JKSJRK XB masd SO YAZ tw dhz MYR JXMBYNSKF BSVRKTRM nya by NXZ BXKRTRZZTQ OTWDH SVRK MYR AKSD ERPZMRXP KWZMTRP MYR JXTR OXBR SO X QSWDH NSI xd NXZ kx azzrp or retq OKSI MYR jat tsn XDP X OXA DM vs ABR aijkorb mtq xkmabwttxmrp MYR NSKPZ TRM XDP MYR 女士

你能解密它吗?

让我们运用我们新发现的 MCMC 的力量。

关于替代密码的一个注意事项:替代密码就是我们用一个字母替代另一个字母。比如 A 变成 I,B 变成 C 等等。在原文中。

为了创造这个例子,这些数据实际上取自《雾都孤儿》。我们使用随机加密密钥对数据进行加密,加密后我们忘记了密钥,我们希望使用 MCMC 链对加密文本进行解密。真正的解密密钥实际上是

" ICZNBKXGMPRQTWFDYEOLJVUAHS "

所以让我们稍微思考一下这个问题。

解密密钥可以是任何 26 个字母的字符串,所有字母只出现一次。像这样的字符串排列有多少种?这个数字将会是 26!大约 10 个⁶排列。

这是一个相当大的数字,因此这个问题有一个 大的状态空间 (本质上是我们可能需要解析的大量排列)。

如果我们使用暴力的方法,也许我们的孙子或者他们的孙子会得到解决方案。那么我们能做什么呢?

谁是 MCMC?

我们将设计一个链,其状态理论上可以是这些排列中的任何一种。然后我们将:

  1. 从选择一个随机的当前状态开始。
  2. 通过交换当前状态中的两个随机字母来创建新状态的提议。
  3. 使用 评分函数 计算当前状态Score_C和建议状态Score_P的得分。
  4. 如果建议状态的分数大于当前状态,则移动到建议状态。
  5. 否则抛硬币决定哪个有正面的可能性Score_P/Score_C。如果它来了,头移动到提议的状态。
  6. 从第二步开始重复。

如果我们幸运的话,我们可能会达到一个稳定的状态,在这个状态下,这个链具有所需状态的稳定分布,这个链所处的状态可以作为一个解。

什么是评分函数?

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

这里我们需要担心的主要是评分函数。我们如何计算一个提议是否是一个好的提议?

还记得我上一篇文章中的 hill 例子吗?

我们想搬到最高的山上,并在那里呆很长时间。我们应该为每个状态(解密密钥)使用一个评分函数,该函数为每个解密密钥分配一个正的分数。

如果使用这个解密密钥解密的加密文本看起来更像真实的英语,这个分数直观上应该更高。

那么我们如何量化这样一个函数呢?

英语有一种特殊的结构。我们假设某一对字母一起出现的次数可能遵循某种特定的模式。因此“TH”比“ZF”更有可能出现。

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

我们将检查一个长文本并计算这些统计数据。

我们将会看到在像《战争与和平》这样合法的长文本中,一个字母一个接一个出现了多少次。这里文本的选择并不重要。

例如,我们希望找出“BA”在文本中出现了多少次,或者“TH”在文本中出现了多少次。

对于每对字符β₁和β₂(例如β₁ = T 和β₂ =H),我们让 R( β₁,β₂)记录该特定对(例如“TH”)在参考文本中连续出现的次数。

类似地,对于解密密钥 x,我们让 Fₓ(β₁,β₂)记录当使用解密密钥 x 解密密文时该对出现的次数

然后,我们使用以下公式对特定的解密密钥 x 进行评分:

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

这个函数可以被认为是对解密文本中的每个连续字母对乘以该对在参考文本中出现的次数。

直观上,当解密文本中的配对频率最接近地匹配参考文本中的配对频率时,得分函数较高,因此解密密钥最有可能是正确的。

为了使我们的计算生活更容易,我们将计算 log(Score(x))

让我们开始逐步解决这个问题。

首先,让我们加密一些文本来创建我们的例子。在这个残酷的世界上,我们必须自己做所有的事情。

我们可能希望首先为我们的评分函数和评分函数本身创建一些统计数据。

我们还想有一个功能来创建提案国和随机硬币投掷。

最后,这是我们使用 Metropolis-Hastings 算法运行的 MCMC 函数。

现在让我们使用上面的所有函数运行整个代码。

输出:

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

这个链大约在第 2000 次迭代时收敛,我们能够解读代码。

太棒了。

现在,正如您看到的,找到的 MCMC 密钥并不完全是加密密钥。因此,该解决方案不是确定性的,但我们可以看到,它实际上并没有减少 MCMC 方法提供的任何值。

现在让我们帮助比尔博。

2。背包问题

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

所以比尔博·巴金斯去了史矛革的巢穴。

他发现了 M 宝藏。

每个宝藏都有一定的重量和黄金价值。

但问题是比尔博真的承受不了这些。

他只能承受一定的最大重量。

但是作为一个聪明的霍比特人,他想最大化他拿走的财宝的价值。

考虑到重量和宝藏的价值以及比尔博能携带的最大重量,你能找到一个好的解决方案吗?

这就是计算机科学中的背包问题。

所以在这个问题中,我们有一个 1xM 数组的重量值 W,黄金值 G,以及一个比尔博可以携带的最大重量 w_MAX 的值。

我们想找出一个由 1 和 0 组成的 1xM 数组 X,它保存着比尔博是否携带了某个特定的宝藏。

该数组需要遵循以下约束:

WX < w_MAX

i.e. the total weight Bilbo Carries is less than Max Weight.

and we want to maximize

GX

i.e. the total Gold value for a particular state X.

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

Now as earlier this problem also has a **大境界空间。**如果我们尝试用蛮力来做,我们需要的排列数是 2^M.,我们可以看到它会变得很大。

如前所述,这是我们可以使用 MCMC 方法的地方。

因此,让我们首先讨论如何从先前的状态创建一个提案。

  1. 从状态中选择一个随机索引并切换索引值。
  2. 检查我们是否满足约束。如果是,则该状态是建议状态。
  3. 否则选择另一个随机索引并重复。

我们还需要考虑评分函数。

我们需要给黄金价值高的州以高价值。我们将使用:

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

分数越高,我们给予的价值就越大。这里的β是一个+ve 常数。(T 代表转置)

但是β怎么选呢?

如果β很大,我们会给好的解决方案一个很高的分数,链将不能尝试新的解决方案,因为它会陷入局部最优。

如果我们给一个小的值,这个链不会收敛到非常好的解。

因此,我们使用一种称为 模拟退火 的优化技术,即我们将从一个较小的β值开始,随着迭代次数的增加而增加。

这样,链将在开始阶段探索,并在后期阶段停留在最佳解决方案。

现在,我们已经有了开始行动所需的一切。

让我们从创建一个建议函数和得分函数开始。

以及 MCMC 项目。

运行主程序:

OUTPUT
________________________________________________________________MCMC Solution is : [0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0] with Gold Value: 2435

现在我不会说这是最好的解决方案。

使用 DP 的确定性解决方案对于这种用例来说是最好的,但是有时当问题变大时,拥有这样的技术变得非常有价值。

结论

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

在这篇文章中,我试图用 MCMC 解决计算机科学中的两个问题。

密码学本身是一个庞大的课题,有很多应用。背包问题出现在各种领域的现实世界决策过程中,例如寻找最少浪费的方法来切割原材料,选择投资投资组合,选择互联网下载管理器中的数据块以及其他优化。

这两个问题都有一个很大的状态空间,不可能用蛮力来解决。

你对 MCMC 方法有什么看法?

此外,如果您发现任何好的应用程序,或者想将这些技术应用到某个领域,我真的很乐意了解它们,并在可能的情况下提供帮助。

你可以在 GitHub 或者 Google Colab 上找到全部代码。

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

你可以关注的最新和最好的资源之一是 高级机器学习专业化 中的 贝叶斯机器学习方法 课程

我以后也会写更多这样的帖子。让我知道你对这个系列的看法。在 媒体 关注我,或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系。

参考

  1. 概率导论约瑟夫·K·布利茨泰因、杰西卡·黄
  2. 百科

零起点学习的应用

原文:https://towardsdatascience.com/applications-of-zero-shot-learning-f65bb232963f?source=collection_archive---------5-----------------------

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

作为计算机视觉研究小组的成员,我想写这篇短文来简要介绍我们所谓的“零射击学习”(ZSL),一种迁移学习的有趣变体,以及当前与之相关的研究。

今天,许多机器学习方法专注于分类实例,这些实例的类已经在训练中出现过。具体地说,许多应用程序需要对其类以前从未见过的实例进行分类。零炮学习是一种很有前途的学习方法,其中训练实例覆盖的类与我们要分类的类是不相交的。换句话说,零射击学习就是在没有额外训练数据的情况下利用监督学习。

零镜头学习指的是机器学习的一个具体用例(,因此深度学习),其中你希望模型基于很少甚至没有标记的例子对数据进行分类,这意味着动态分类。

让我们想想卷积神经网络(CNN)是如何工作的——它们将例如图像识别的一般任务分解为一系列由连续层执行的较小任务,其中每一层处理越来越复杂的特征。

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

当我们训练一个网络来识别一张给定的图片时,例如一个人,我们已经训练它来识别手臂、腿、*脸等等。*由于这一点,我们可以重复使用这些特征检测器,并重新排列它们来执行一些其他任务,而无需额外的培训。

换句话说,零射击学习是关于利用已经由监督学习以其他方式训练的深度学习网络,而不需要额外的监督学习。

零射击学习可以产生非常有趣的应用,尤其是在我们缺乏适当数据集的情况下。你可能知道,在几乎所有的计算机视觉项目中,缺乏数据是一个巨大的问题。如果要我用几句话来总结 ZSL,我会说是:

  • 无训练样本的模式识别
  • 基于语义转移

数据的自然稀缺

零射学习是人类已经具备的能力。事实上,我们可以用“最小数据集”学习很多东西。例如,你倾向于用每种水果的一些图片来区分同一种水果的不同品种(细粒度分类)和其他水果或外观相似的水果(常规分类)。机器的情况不同…他们需要大量的图像来学习适应自然发生的变化。

这种天生的能力来自于我们现有的语言知识库,它提供了对一个新的或未见过的类的高层次描述,并在它和见过的类和视觉概念之间建立了联系。

为什么我们需要零拍学习?

如你所知,在许多领域中有大量且不断增长的类别。因此,很难为每个类别收集大量带注释的数据。

在一些项目中,类的数量可以达到数千个,并且为每个类获取足够的训练数据是复杂的。零炮学习旨在仅使用来自一小组类的标记数据和关于类关系的外部知识来预测大量未看见的类。此外,类别的数量不断增加,为每个新类别收集新数据的难度也在增加。在需要大量数据的深度学习中尤其如此…

同一物体的不同种类可能很快变成一场噩梦,在这种情况下,无监督学习无法提供帮助。

此外,在正常的对象识别过程中,我们必须确定一定数量的对象类别以提高我们的准确性,并为选定的对象类别收集尽可能多的样本图像。此外,这些样本图像应该包含在各种环境中从不同角度拍摄的元素,以便丰富数据集。

在某些情况下,标签只能由专家来完成。像特定物种的识别这样的细粒度对象识别任务可以被认为是在专家的监督下进行标记的例子。

人们对用于扩大视觉识别的机器 ZSL 越来越感兴趣。

它是如何工作的

不需要太多的细节,零射击学习依赖于一个有标签的训练集的存在,这个训练集包括看得见的类和看不见的类。可见类和不可见类在一个叫做语义空间的高维向量空间中是相关的,可见类的知识可以转移到不可见类中。

零触发学习方法被设计成学习中间语义层及其属性,并在推理时应用它们来预测新的数据类别。

通常情况下,零炮学习算法首先将实例映射到中间属性,中间属性可以是可见的类(带标签数据的类),人类指定的或数据依赖的属性。然后通过知识库将预测的属性映射到大量的未知类别。通过这种方式,对未知类别的预测成为可能,并且这些类别不需要训练数据。

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

零投学习是一个两阶段的过程:训练和推理。在训练阶段,获取关于属性的知识,在推理阶段,这些知识用于在一组新的类别中对实例进行分类。**人们似乎已经做了很多努力来改善训练阶段,而推理阶段却很少受到关注。**例如,许多方法不能充分利用属性的辨别能力,并且不能利用在第一阶段获得的属性预测的不确定性。

研究

从研究的角度来看,我已经看到一些团队在研究更精确的 ZSL 模型,该模型使用称为生成对抗网络(GANs)的神经网络架构来读取和分析来自网络的文本,然后在视觉上识别它们描述的对象。这种新方法使系统能够根据类别对对象进行分类,然后使用该信息来识别其他类似的对象。

受益于这项研究的另一个重要因素是偏见。事实上,训练数据的收集和标记可能非常耗时,并且因为仍然难以收集足够多的统计上不同的训练图像,所以未标记的目标类(即,之前未见过的图像或对象)通常被归类为标记的类,这导致了一般化设置中的不良准确性。

当可用的训练图像很少时,现有的对象识别模型很难做出正确的预测,而 ZSL 主要是作为解决这个问题的手段而开发的。

由于我们的研究,我们设法建立了一个原型,可以通过分析相关的网络文章来识别物种。只看那些文字描述(没有看到物种的图像),系统提取关键特征,如动物的头部形状。然后,该系统可以以某种方式想象物种的样子,生成一个合成的视觉模型。

很重要的一点是,图像和文本理解的结果并没有消除训练的需要,但这是一个 ZSL 如何减少训练并帮助系统在面对意外数据时保持准确的例子。

随着 ZSL 的继续发展,我希望看到更多的应用程序,如更好的推荐和更先进的解决方案,自动标记社交媒体类别中的不良内容。我还预见了 ZSL 在机器人领域的强劲发展。

零镜头学习方法在许多方面与人类视觉相似,因此可以用于机器人视觉。不是在有限的一组对象上执行识别,而是使用零射击学习来识别每个对象是可能的。

我毫不怀疑 ZSL 能帮助人工智能从今天有限的应用领域过渡到对人类来说如此自然的多功能领域。

更多信息,我推荐这个视频:【https://www.youtube.com/watch?v=jBnCcr-3bXc】-t = 626s

应用人工智能:从概念到 ML 组件

原文:https://towardsdatascience.com/applied-ai-going-from-concept-to-ml-components-7ae9c5d823d3?source=collection_archive---------17-----------------------

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

敞开你的心扉,接受将机器学习应用于现实世界的不同方式。作者 Abraham Kang 特别感谢 Kunal Patel 和 Jae Duk Seo 为本文提供意见和建议。

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

Photo by Franck V. on Unsplash

行动纲要

候选问题

许多人对使用人工智能自动化组织内的冗余流程感兴趣。让我们从一个具体的问题开始,我注意到的是,当不好的事情发生时,律师通常会从客户那里收集事实。这些事实构成了个人可以起诉的诉因(疏忽、殴打、攻击、故意施加精神痛苦)的基础。一旦根据法律依据和事实确定了诉讼原因,就要写好诉状并提交给法院,以便开始法律诉讼。诉状是一份法律文件,列出了导致对另一方采取行动的法律依据的事实。手动创建此文档可能非常耗时,并且类似的事实会导致类似的行动原因。例如,如果有人打了另一个人,通常会有一个“电池”。如果有人不小心伤害了其他人,或者有人在商店里滑倒,可能会受到疏忽的起诉。基于这个问题,我们有一个客户想使用人工智能来学习如何根据描述所发生事情的事实段落写一份投诉。

理解问题

试图让人工智能/人工智能阅读事实,并找出一种方法让人工智能/人工智能撰写完整的投诉可能会超出模型的能力范围,可能需要数年才能解决。然而,如果你花时间去理解和思考潜在的问题,你可以找到现有的技术(稍加修改)来解决这个难题的不同部分。例如,当你看一份诉状时,它以对双方及其立场(原告对被告)以及代表他们的律师的描述开始。可能有集体诉讼部分、管辖权证明(法院是否有权管辖各方)、各方描述、地点证明(我们是否在适当的法院地点)、诉讼原因列表和事实描述。当你看这些部分的时候,你必须考虑构建各个部分的数据来自哪里。在某些情况下,你不会有答案,但如果你仔细观察,你会发现投诉的不同部分之间的模式和相关性。这将允许你考虑你对神经网络的输入和候选输出。

获取神经网络的输入

我们本身没有任何数据,但可能有一种方法可以从所有现有的投诉中解析出事实,并将它们用作我们神经网络的输入。提交给法院的每一份投诉都成为公共信息,因此会有大量的数据。这种解决方案将要求律师写下他们的事实,就像他们直接将它们插入到投诉中一样,但这对于能够让机器学习提供生成的投诉来说是一个小小的不便。提出完整的投诉可能很困难。所以我们把问题分解一下。

分解问题

从逻辑上讲,如何将文档的生成分解成更小的部分?你需要看一个例子:https://www . heise . de/downloads/18/1/8/9/1/3/4/6/NP-v-Standard-Innovation-complaint . pdf。为了让它变得有趣,我挑选了一家成人玩具制造商,这样可能会激发你的好奇心。基本上,我们希望最终从律师提供的事实中生成一份诉状(pdf 以上)。因此,如果你看看这份文件和其他投诉,你会发现类似的结构模式。

所以,你认为什么是分解事物的最好方法…在你有时间思考之前,不要向下滚动。

….真的好好想想……

好吧,如果你说使用模板按部分分解,那么这可能是最好的方法。

当你分解投诉时,投诉中会列出行动的原因。每个诉因(违反联邦窃听法案、伊利诺伊州窃听法规、侵扰隔离、不当得利、欺诈和欺骗性商业行为法案等)。)有基于事实的支持规则和理由。所以现在有两个问题。如何从事实文本中得出行动的原因,如何在每个行动原因下生成支持文本?

寻找行动的原因

当我们看案件的事实时,我们需要找到我们可以起诉的所有诉讼原因(违反的法律)。从文本中寻找行动的原因没有直接的解决方法,所以我们必须从根本上思考。

你认为我们可以用什么样的现有技术来观察文本并推断文本的意思或描述。如果你说的是多标签文本分类或者多标签情感分析,那么你就领先了(https://paperswithcode.com/task/text-classificationhttps://papers with code . com/task/perspective-analysis)。.)分析文本以确定其相关的行动原因的过程类似于对文本进行分类或寻找相关文本的情感。还有一些相关的问题,例如,随着法律的出台,诉讼原因需要更新。可能有另一种方法来创建事实的嵌入,然后基于三元组(https://arxiv.org/pdf/1503.03832.pdf)或四元组损失(https://arxiv.org/pdf/1704.01719.pdf)将诉因与事实联系起来,以在嵌入空间中将共享相似词的诉因推到一起,并将不相关的诉因推得更远。然后,使用聚类技术,找出与决定性词语嵌入相近的诉因,这些词语嵌入用于支持与诉状的个别诉因部分中的词语相关的论点。

在单个诉讼原因的支持论据部分生成文本

既然您已经知道如何从文本中获得高层次的诉因,那么您如何为每个单独的诉因部分(违反联邦窃听法案、伊利诺伊州窃听法规、侵扰隔离、不当得利、欺诈和欺骗性商业行为法案等)生成支持性的论据文本。)?

这一个不那么直截了当。想一想什么样的神经网络架构可以生成文本(不要向下滚动,直到你有了一些想法)…

….打开你的心扉…使用原力…

文本生成算法(https://paperswithcode.com/task/data-to-text-generationhttps://paperswithcode.com/area/nlp/text-generation)可能是一种选择,但即使是最好的算法也会经常产生乱码。更好的选择可能是使用类似神经网络的架构参与翻译(https://paperswithcode.com/task/machine-translationhttps://papers with code . com/task/unsupervised-machine-translationhttps://papers with code . com/paper/unsupervised-clinical-language-translation)。此外,为每个行动原因建立一个单独的“翻译”神经网络可能是一个好主意,它可以帮助每个神经网络专注于识别用于为每个行动原因生成支持论据的关键事实。

打扫

通过语法检查器/修正器(https://papers with code . com/task/grammatic-error-correction)运行每个诉讼原因的支持参数文本的候选文本可能是个好主意。这样,任何明显的混乱都会得到解决。

结论

我希望你学会了如何更广泛地应用机器学习解决方案。如果你遇到困难,请告诉我,因为我绝对有兴趣听到人们试图用机器学习来解决的问题。

将拓扑数据分析应用于深度学习?动手心律失常分类!

原文:https://towardsdatascience.com/applied-topological-data-analysis-to-deep-learning-hands-on-arrhythmia-classification-48993d78f9e6?source=collection_archive---------19-----------------------

医疗保健是一个令人兴奋的工作领域。每一次受控的性能增强都多少意味着拯救或改善生命。因此,足够好的概括不是你可以沾沾自喜的。

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

现在的问题是如何去做。有些人通过扩大数据集的规模来增强他们的推断,有些人提高了质量,有些人使用全新的模型,还有一些人发明了自己的技术。不用引用,深度学习的兴起大概就是最好的例子。今天,我将着眼于最后一个选项:在数据描述方面进行创新。我给你介绍一个:拓扑数据分析。也被缩写为 TDA ,这是从应用拓扑学和计算几何的各种研究中出现的一个新领域。它的目的是提供良好的数学,统计和算法的方法来利用数据中的拓扑和潜在的几何结构。TDA 通常在三维数据上可视化,在其他情况下也很有用,例如时间序列。感兴趣吗?😄

[## 从拓扑数据分析到深度学习:不劳无获

今天,我将尝试给出一些关于 TDA(用于拓扑数据分析)的见解,这是一个快速发展的数学领域…

towardsdatascience.com](/from-tda-to-dl-d06f234f51d)

因为我希望这篇文章实用,所以我将向您推荐我以前写的一篇文章,它揭示了一些理论概念。请随意花几分钟时间沉浸在 TDA 为您提供的多个主题中。这篇文章摘自我在东京富士通人工智能实验室与 INRIA(法国研究所)的 Datashape 团队合作时所做的工作。很不幸,当我不能分享整个工作时,泪水顺着我的脸颊流下,但是你应该有你需要的一切,用那个 Github 和那个论文

什么是心律失常?

这并不奇怪,但是你应该知道心脏病和中风是美国五大死亡原因之一。因为它关系到外面的每个人,难怪像苹果这样的公司正在通过开发他们自己的智能显示器来瞄准这个领域。事实证明,你的心脏可能是你全身最牛的肌肉:它 24/24 7/7 不间断地工作,并且以非常有节奏的方式工作。然而,它有时会跟不上节奏,这可能是因为酒精、闪电式恋爱、剧烈运动或恐怖电影。其中一些失败可能会致命。心律失常是一种衰竭,是一组描述心律不齐状况的总称,在形状或频率方面。检测这些事件并监测它们的频率可能对监督你的健康有巨大的帮助,并确保你在需要时获得正确的健康干预。然而,这需要智能监控。

弄脏你的手!

M 机器学习!这听起来像是智能监控的方式!但这需要的不仅仅是一个漂亮的模特。这是一件好事,人们一直在努力通过提供一系列开源数据集来促进研究。这些可在 Physionet 平台上获得,并以它们描述的条件命名:麻省理工学院-BIH 正常窦性心律数据库、麻省理工学院-BIH 心律失常数据库、麻省理工学院-BIH 室上性心律失常数据库、麻省理工学院-BIH 恶性室性心律失常数据库和麻省理工学院-BIH 长期数据库。这些数据库由单通道心电图组成,每一个都以 360 Hz 采样。两个或更多的心脏病专家独立地注释每个记录,他们的分歧被解决以获得每个搏动的参考注释。我们可能已经心存感激了!

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

注释还有一个好处,就是让我们从心跳检测的问题中解脱出来,这并不是一个很大的障碍:基线漂移小波变换1D-CNN 作为一个解决方案,它们都工作得很好。

如何描述心跳?

在我们的例子中,CGs 是一维时间序列,如何描述它们的形状和时间关系?这是一个非常普遍的问题,可以转移到许多领域。这就是拓扑将会有所帮助的地方!

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

Credits

让我们从我们想要从这些心跳中得到的时间信息开始。在单个事件的范围内,检索到的间隔是左侧描述的间隔( PQRST 事件)。该信息已经与形状高度关联。在 ECG 本身的范围内,我们还需要检索 RR 间隔,这是连续 R 峰之间的延迟,从而量化总体节律(及其异常)。

从那以后,你可能已经在考虑使用上面展示的特性来构建你的模型了(在等式中添加一些 FFT /小波/混沌理论/ …)。从这些特征(结合 SVM、增强树或神经网络)获得的结果是好的,但还不够令人满意。时间信息不是问题所在:问题在于心跳的形状。它们表明心脏本身有一个非常复杂的机制,而个体差异从一开始就意味着巨大的可变性。因此,我们需要一个模型,能够捕捉模式,而不会过度拟合由我们拥有的单个个体池产生的平均模式。这无疑是拓扑数据分析的魅力达到顶峰的地方,至少在时间序列方面。

在心律失常分类一般化所面临的主要挑战中,我们发现了个体差异,特别是心动过缓心动过速。TDA,更准确地说是持续同源理论,以简洁的方式有力地描述了 ECG 信号的形状,避免了复杂的几何特征工程。由于持久同源性的基本稳定性,TDA 特征对于 ECG 信号中感兴趣模式的变形,尤其是时间轴方向上的扩展和收缩,显得非常稳健。这使得它们对于克服个体差异和由心动过缓和心动过速引起的潜在问题特别有用。

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

Process Visualization: From ECG to Barcode Diagram to Betti Curve

持续同源理论来了(在这篇文章中提出)。它允许我们用一个持久性 条形码唯一地表示一个过滤的单纯复合(在我们的例子中,ECG 信号被转换成一个图形)的持久性同源性。条形码图用一条水平线表示每个持久性生成器,该水平线从它出现的第一个过滤级别开始,到它消失的过滤级别结束。现在,就过滤而言,我们有两种可能的图表:从上到下或从下到上。上图直观地分解了自上而下的策略,显示了使用 1D ECG 信号构建的条形码。不幸的是,条形码图表不能被机器学习直接利用,因为它们的尺寸不一致。为了使它们成为有用的形式,我们将图表转换成贝蒂曲线

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

贝蒂曲线 :让我们考虑一个 持久性条形码 ,为此我们对半径空间进行矢量化。条形码图的每个组成部分都被称为一个函数,在定义它的半径上取值为 1,在其他任何地方取值为 0。矢量化空间上的这些函数之和定义了贝蒂曲线。

对于每个心跳,我们现在有两条 Betti 曲线,它们的大小是一致的,并且是可控的。我个人倾向于 100 点矢量化,这样我可以将之前训练的模型重新应用到类似的问题中,这些问题将类似的分布曲线作为输入。

将深度学习带入等式

现在的问题是如何利用贝蒂曲线。除了作为一种奇特的数据表示,曲线在一维信号中包含了关于形状的复杂信息。寻找开发这些资源的最佳模式已经开始!

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

利用一维信号并不令人头痛。唯一不同的是,在这里,维度不是时间,而是空间。在您所拥有的选择中,您可以选择具有欧几里德或动态时间弯曲度量的 kNN,直接使用提升的树或使用 CNN 网络,这可能是在这些情况下最好的网络(可以通过 CNN 可以访问的多个尺度进行解释,这对于空间信息来说可能比时间更方便)。

我当时设计的模型可能更像是我想说的火箭筒,但它明确强调了我构想大多数深度学习问题应该基于的所需模块化的方式。你可以选择像斯坦福大学的论文 (34 层)那样走向堆叠策略,或者走向更水平的多模块方法,混合人类直觉(特征工程)和不可及的统计考虑(深度学习)。这正是下面描述的模型的全部内容:扩大你处理信息的范围

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

TDA 对归纳有多大影响?

您现在可能想知道 TDA 是否真的带来了我在本文开始时提到的性能提升。对于这一部分,我们花了大量时间进行实验:)

我们采取的第一步是试图评估 TDA 对我们深度学习架构的影响。突出了两个问题:二元分类 (~心律失常检测),包括从正常心跳中识别心律失常心跳,以及多类分类**,包括将正确的标签归属于每个异常心跳。我们在交叉验证框架的基础上运行,让患者接受训练,一些进行验证,另一些进行测试。每个 ID 代表一个三重分裂(基于 240 名可用患者,训练 60%,验证 10%,测试 30%)和一个从头开始训练的模型。**

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

第一个结论很有趣:尽管添加 TDA 确实有助于泛化,但最受影响的问题是实际的分类。解释这一结果的一种方式是将 TDA 视为拓扑和形状的高度专业化的度量。第一个问题主要是关于检测异常心跳,这又回到异常检测,而第二个问题更多地依赖于拓扑信息,因为形状是区分异常心跳的巨大组成部分。

当然,撇开这一步不谈,我们实际上陷入了比较。我在下面附上我们的总体架构的结果,但不会在这里讨论所有的细节。[实际上,我不喜欢在论文之间设计评分系统的方式,基于围绕泛化稳健性的度量和考虑的快速发展,将我们的评估限制在这些方面甚至不再有意义。]

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

结论被高估了

我希望这篇应用拓扑数据分析的介绍引发了你对潜在理论的兴趣,以及它实际上可以用于的无限问题集。当形状直观地涉及到问题时,使用 TDA 最有意义。会不会通过持久性图条形码图持久性景观持久性轮廓贝蒂曲线,TDA 可以被用来作为机器学习管道的一部分。不幸的是,无论你的创新水平如何,最大的限制因素是数据。让我们开始考虑集中的高质量数据源,然后我们肯定会改变赌注!

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

参考

有兴趣保持联系?😄Twitter|LinkedIn|Github|Medium

熊猫的应用和λ的使用

原文:https://towardsdatascience.com/apply-and-lambda-usage-in-pandas-b13a1ea037f7?source=collection_archive---------0-----------------------

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

Photo by chuttersnap on Unsplash

学习这些来掌握熊猫

熊猫是你可以随意使用的一个很好的工具。

我已经和熊猫一起工作了很多年,它的新功能、快捷方式和做一件特定事情的多种方式一直让我感到惊讶。

但我意识到,坚持我学到的一些惯例多年来对我很有帮助。

applylambda是我在熊猫身上学到的一些最好的东西。

每当我为一个新的列或过滤器构建复杂的逻辑时遇到困难,我就会使用applylambda

当企业向您提出定制请求时,这种情况经常发生。

这个帖子是向你展示 ***apply*** ***lambda*** 的威力。

我将使用 IMDB 上过去 10 年中 1000 部流行电影的数据集。你也可以跟随在 Kaggle 内核中。

创建列

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

Complex columns

您可以通过多种方式创建新列。

如果你想要一个列是列的和或差,你可以使用简单的基本算法。在这里,我得到了基于 IMDB 和标准化 Metascore 的平均评级。

df['AvgRating'] = (df['Rating'] + df['Metascore']/10)/2

但是有时我们可能需要围绕新列的创建构建复杂的逻辑。

举一个复杂的例子,假设我们想要基于各种因素构建一个自定义的电影评分。

比如说,如果电影是惊悚片,我想在 IMDB 评分保持小于等于 10 的条件下,在 IMDB 评分上加 1。如果一部电影是喜剧,我想从评分中减去 1。

我们怎么做呢?

每当我掌握了如此复杂的问题,我就使用apply/lambda。让我首先向您展示我将如何做这件事。

def custom_rating(genre,rating):
    if 'Thriller' in genre:
        return min(10,rating+1)
    elif 'Comedy' in genre:
        return max(0,rating-1)
    else:
        return rating

df['CustomRating'] = df.apply(lambda x: custom_rating(x['Genre'],x['Rating']),axis=1)

一般结构是:

  • 您定义了一个函数,该函数将接受您想要处理的列值,以得出您的逻辑。在这里,我们最终使用的两列是流派和评级。
  • 沿着 axis=1 的行使用带有 lambda 的应用函数。一般语法是:
df.apply(lambda x: func(x['col1'],x['col2']),axis=1)

您应该能够使用 apply/lambda 创建几乎任何逻辑,因为您只需担心自定义函数。

过滤数据帧

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

Filtering….

熊猫使过滤和子集化数据框架变得相当容易。您可以使用普通运算符和&,|,~运算符对数据帧进行过滤和子集化。

# Single condition: dataframe with all movies rated greater than 8df_gt_8 = df[df['Rating']>8]# Multiple conditions: AND - dataframe with all movies rated greater than 8 and having more than 100000 votesAnd_df = df[(df['Rating']>8) & (df['Votes']>100000)]# Multiple conditions: OR - dataframe with all movies rated greater than 8 or having a metascore more than 90Or_df = df[(df['Rating']>8) | (df['Metascore']>80)]# Multiple conditions: NOT - dataframe with all emovies rated greater than 8 or having a metascore more than 90 have to be excludedNot_df = df[~((df['Rating']>8) | (df['Metascore']>80))]

很简单的东西。

但有时我们可能需要进行复杂的过滤操作。

有时我们需要做一些操作,而仅仅使用上面的格式是做不到的。

例如:我们假设 我们想要过滤电影标题中字数大于或等于 4 的那些行。

你会怎么做?

尝试下面的会给你一个错误。显然,你不能做任何简单的事情,比如用一个系列分割。

new_df = df[len(df['Title'].split(" "))>=4]
-------------------------------------------
AttributeError: 'Series' object has no attribute 'split'

一种方法是首先使用 apply 创建一个标题中包含字数的列,然后对该列进行过滤。

#create a new column
df['num_words_title'] = df.apply(lambda x : len(x['Title'].split(" ")),axis=1)#simple filter on new column
new_df = df[df['num_words_title']>=4]

这是一个非常好的方法,只要你不需要创建很多列。但是,我更喜欢这个:

new_df = df[df.apply(lambda x : len(x['Title'].split(" "))>=4,axis=1)]

我在这里做的是 我的 apply 函数返回一个可以用来过滤的布尔值。

现在,一旦你理解了你只需要创建一个布尔列来过滤,你就可以在你的apply语句中使用任何函数/逻辑来得到你想要构建的复杂逻辑。

让我们看另一个例子。我会试着做一些稍微复杂的事情来展示它的结构。

我们想找到收入低于该年平均收入的电影?

year_revenue_dict = df.groupby(['Year']).agg({'Rev_M':np.mean}).to_dict()['Rev_M']def bool_provider(revenue, year):
    return revenue<year_revenue_dict[year]

new_df = df[df.apply(lambda x : bool_provider(x['Rev_M'],x['Year']),axis=1)]

这里有一个函数,可以用来写任何逻辑。只要我们能够处理简单的变量,这就为高级过滤提供了强大的功能。

更改列类型

我甚至使用 apply 来更改列类型,因为我不想记住更改列类型的语法,也因为它让我可以做更复杂的事情。

在 Pandas 中,改变列类型的正常语法是astype。因此,如果我的数据中有一个名为 price 的列,格式为str。我可以这样做:

df['Price'] = newDf['Price'].astype('int')

但有时并不会如预期般奏效。

你可能会得到错误:ValueError: invalid literal for long() with base 10: ‘13,000’.也就是说你不能把一个带有“,”的字符串转换成一个整型。要做到这一点,我们首先要去掉逗号。

在一次又一次地面对这个问题之后,我现在已经完全停止使用astype了,只使用 apply 来改变列类型。

df['Price'] = df.apply(lambda x: int(x['Price'].replace(',', '')),axis=1)

最后还有progress_apply

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

progress_applytqdm包附带的单一功能。

这为我节省了很多时间。

有时,当您的数据中有很多行,或者您最终编写了一个非常复杂的 apply 函数时,您会发现 apply 可能需要很长时间。

我见过应用程序在使用 Spacy 时花费数小时。在这种情况下,您可能希望看到带有应用的进度条。

你可以使用tqdm来实现。

在笔记本顶部的初始导入之后,只需将apply替换为progress_apply,一切都保持不变。

from tqdm import tqdm, tqdm_notebook
tqdm_notebook().pandas()df.progress_apply(lambda x: custom_rating_function(x['Genre'],x['Rating']),axis=1)

你会看到进度条。

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

结论

applylambda功能让你在操作数据的同时处理很多复杂的事情。

我觉得用熊猫不用担心很多事情,因为我可以很好地使用apply

在这篇文章中,我试图解释它是如何工作的。可能还有其他方法来做我上面做的事情。

但是我喜欢用apply / lambda来代替map / applymap,因为我觉得它可读性更强,也更适合我的工作流程。

如果你想了解更多关于 Python 3 的知识,我想从密歇根大学调出一门关于学习 中级 Python 的优秀课程。一定要去看看。

我以后也会写更多这样的帖子。让我知道你对这个系列的看法。在 媒体 关注我或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系。

应用数据挖掘更好地诊断自闭症谱系障碍

原文:https://towardsdatascience.com/apply-data-mining-to-better-diagnose-autism-spectrum-disorder-f7c8be226341?source=collection_archive---------25-----------------------

精神病学的数据科学方法

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

Photo by Anna Kolosyuk on Unsplash

简介

自闭症谱系障碍(ASD)是一种神经发育障碍,包括自闭症、阿斯伯格综合症和未特别指明的广泛性发育障碍(PDD-NOS)。根据 DSM-IV-TR 的定义,ASD 有三个特征。

  • 社会赤字
  • 沟通困难
  • 重复的行为。

在 DSM-V 中,标准被重组为两个领域。此外,所有以前定义的不同子类型都被合并到 ASD 中。

  • 社会交流和社会互动
  • 受限制的、重复的行为、兴趣或活动模式

根据疾病控制和预防中心(CDC)(2014),在美国,每 68 名儿童中就有 1 名(每 42 名男孩中有 1 名,每 189 名女孩中有 1 名)被确定患有自闭症。特别是,未特别指明的广泛性发育障碍(PDD-NOS)占 ASD 的 90%。尽管发病率如此之高,但没有具体的医学诊断方法。

传统方法

目前,ASD 通常是通过使用由专业训练有素的医生和心理学家评估的自闭症特定行为测量来诊断的。此外,父母,主要的照顾者,在发现他们孩子患自闭症的可能性上扮演着重要的角色。因此,我将数据挖掘应用于本提案的目的是为未来的 ASD 诊断找到最佳的数据驱动模型。

数据集正在使用

自闭症脑成像数据交换(ABIDE)是一个数据集,包括 7 个用于自闭症临床诊断的流行行为测量,它们是自闭症诊断访谈修订版(ADI-R)、自闭症诊断观察计划模块(ADOS)、社会反应量表(SRS)、社会沟通问题(SCQ)、自闭症商(AQ)、Vineland 适应行为量表(VABS)和韦克斯勒儿童智力量表-IV (WISC-IV)。在这个数据集中,有 539 个 ASD 和 573 个对照,总共包括 1112 个参与者。此外,有 16 个国际医疗站点对该数据集做出了贡献,每个医疗站点对 ASD 诊断应用了不同的测量。ABIDE 提供了多维视角来处理 ASD。

方法

了解哪种行为测量对 ASD 预测更好,进而确定哪种测量的子测试对预测 ASD 更好或更有代表性。我不仅应用了探索性分析来获得描述性统计数据,还应用了监督学习、决策树和回归模型的数据挖掘方法来分析 ASD 的这些数据。

决策树

决策树是一种预测模型,它使用决策及其可能结果的树状模型。此外,这是很容易理解的形象和明确的表示。在这个分析中,我提取了变量作为预测 ASD 的不同测量子测试,包括自闭症、阿斯伯格综合症和 PDD-NOS。所有子测试都是连续值,因此,决策树模型也可以称为回归树。

回归

回归是一个线性模型,它应用测量结果作为自变量来预测 DSM-IV-TR 诊断,因变量。通过交叉验证对所有模型的准确性进行了检验。

调查结果

总的来说,这项数据分析中显示的结果,SRS,对 4-18 岁儿童和青少年的相互社会互动的测量,预测 ASD 最好。互惠社会互动的特征被定义为所有发育障碍的核心特征。这意味着社会互动和交流的特点,具有更高的准确性,是一个更好的预测 ASD。因此,我的结论是,在 ABIDE 数据集中,SRS 是未来 ASD 诊断的最佳测量方法。

该提案被 2019 年美国心理学协会大会第 33 分部智力和发育残疾/自闭症谱系障碍所接受。

致挣扎的灵魂和未言明的心。

将人工智能应用于企业集成:我们准备好了吗?

原文:https://towardsdatascience.com/applying-ai-to-enterprise-integration-how-ready-are-we-912b2a954e60?source=collection_archive---------29-----------------------

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

介绍

最近,我们似乎每天都听到人工智能(AI),并看到它几乎在任何地方出现。人工智能可以做许多人类可以做的事情,而且速度比人类快几千到几百万倍。这使我们能够将人类从一些工作流中解脱出来,转而依靠人工智能在许多用例中驱动自动化。

因为人工智能有可能重新定义多种技术格局,所以值得仔细关注。在这种情况下,我们从整合的角度研究了人工智能,探索它如何以及在哪里改变整合的格局。在我们的研究背景下,我们将集成定义为"使用技术,使组织内部或组织之间通常不同的系统协同工作,以实现共同的业务目标。这篇文章总结了我们的发现。

人工智能相关的集成用例

首先,作为我们研究的一部分,我们确定了集成领域中 11 类人工智能相关的用例。

  1. 实现人工智能所需的集成——收集人工智能所需的数据并执行人工智能建议的操作,这产生了许多用例
  2. 数据集成——使用人工智能将来自许多不同格式和语义的数据源的数据协调成有意义的记录
  3. 从人类输入中提取有用的信息——使用人工智能提取有意义的输入数据,如音频、视频和自然语言
  4. 提高可用性——使用人工智能来提高系统的可用性
  5. 现有数据存储中的人工智能支持—支持人工智能作为现有数据存储中的交钥匙解决方案
  6. 算法经济——结合来自算法市场的算法来构建系统
  7. 自动驾驶操作(DevOps 和法规遵从性)—使用人工智能来减少或消除管理系统时对人工干预的需求
  8. 自动化和自助式集成—使用人工智能来简化创建集成的过程
  9. 安全性—使用人工智能来检测潜在的攻击和欺诈
  10. 业务自动化——使用人工智能实现业务运营自动化
  11. API 市场——使用人工智能在 API 市场中提供建议和评级

主要观察结果

在评估集成用例环境中的人工智能时,我们得出了一些观察结果。

值得注意的是,人工智能间接创造了整合需求。这是因为在企业中启用人工智能涉及收集、清理和创建数据的单一表示,以及执行决策和向外公开数据,每一项都会导致许多集成用例。

其次,人工智能决策中的弱点可能比人类决策中的弱点更加有害,原因有三:

  • 人工智能正在融入我们生活的大多数方面。
  • 由于每次重复的成本很小,AI 的使用频率高于人类。
  • 不同的人有不同的意见,这提供了监督和平衡错误的影响,而人工智能广泛应用相同的偏见。例如,人类面试官会有广泛的偏见,而人工智能会有一种偏见。

因此,实施人工智能用例的团队——无论它们是否涉及集成——都应该仔细考虑这些挑战的后果,例如偏见和隐私问题。

第三,挑战,如缺乏熟练的专业人员和数据以及模型可解释性,正在限制人工智能采用的有效性。例如,当应用于竞争性领域,如证券或股票市场时,基于人工智能的系统可能会相互竞争,这可能会导致比以前更糟糕的情况。一个例子是股票市场的闪电崩盘。

第四,多种力量正在推动未来将作为云 API 提供的人工智能应用。

  • 由于人工智能需要数据,在某些情况下拥有对数据的独家访问权会带来显著的竞争优势。这被称为“数据网络效应”云中的人工智能应用程序让供应商能够完全访问数据。
  • 由于缺乏专业知识和数据,定制人工智能模型的建立将仅限于大型组织。中小型组织很难构建和维护定制模型。许多人工智能用例将作为云 API 解决,让供应商集中数据和专业知识。
  • 人工智能的部署和管理是复杂的,当能够处理这些复杂问题的专业人员短缺时,它使部署变得复杂。使用云 API 将让人工智能消费者避开这些复杂性。

在我们的研究中,我们探索了每一类用例是如何受到上述机会、挑战和风险的影响的。在用例中,我们发现有四个已经有了可用的系统,并且可能会被更多的人采用。这些是“安全性”、“数据集成”、“从人类中提取有用的信息”和“现有数据存储中的人工智能支持”。

另一方面,我们已经确定了三个用例,它们不会面临关键的挑战,但在广泛采用之前需要 5 到 10 年的开发。其中包括,“提高可用性”、“自动驾驶操作(DevOps 和法规遵从性)”和“自动和自助服务集成”

最后,我们发现“业务自动化”用例虽然对大公司来说是可行的,但如果没有云 API 的支持,对中小型企业(SME)来说往往是遥不可及的。

结论

在我们的研究中,在严格评估人工智能如何影响集成领域的同时,我们确定了 11 类可以显著影响集成结果的用例。AI 有一个重要的开发者社区和丰富的工具集。许多现实生活中的人工智能用例已经证明了它们的有效性。尽管有希望,但仍有障碍。偏见和隐私问题等风险,以及模型可解释性和熟练专业人员短缺等挑战,正在限制人工智能的采用。我们的报告,人工智能将如何塑造未来的整合?详细讨论机会、风险和挑战;评估每个用例的可行性;并确定了四类准备开发的用例。

将数据科学应用于网络安全网络攻击和事件

原文:https://towardsdatascience.com/applying-data-science-to-cybersecurity-network-attacks-events-219fb6312f54?source=collection_archive---------11-----------------------

网络世界是一个需要理解的巨大概念。当时,我决定在大学期间进入网络安全领域。让我感兴趣的是理解恶意软件、网络安全、渗透测试的概念&在网络安全中真正发挥作用的加密方面。

能够保护基础设施很重要,但也很有趣。当然有编码,但我从来没有真正学会如何将代码应用到网络安全原则中。这是我接下来真正想知道的,可以扩展我在信息技术和计算机科学方面的知识。我学到了更多关于编码的知识,尤其是 Python。我涉猎了一点 Scala &我在大学期间已经有了 Sequel 和 Java 应用程序的良好基础,在新兵训练营期间学习它让我对它感觉更舒服一些。

数据科学沉浸式项目教会我如何通过 Sequel、JSON、HTML 或 web-screwing 应用程序收集数据,我在这些应用程序中清理数据&然后应用 Python 相关代码进行统计分析。然后,我能够对数据进行建模,以发现趋势、做出预测或提供建议/推荐。我想把这一点应用到我在思科 NetaCad、网络安全原则和软件开发的背景中

然后我想把这和我的网络安全背景联系起来。我决定从 Data.org 收集大量关于联邦通信委员会(FCC)的网络攻击的数据。在这篇博文中,我决定写一写我是如何将我的数据科学知识与我在现实行业中的网络安全背景联系起来的。我将提供这个项目的一些背景,一段代码&一些关于 FCC 如何像我一样更好地理解这些数据的见解。这可能对未来的情况或其他政府相关的网络安全项目有用。

据我所知,FCC 使用 CSRIC 最佳实践搜索工具,该工具允许您使用各种标准搜索 CSRIC 的最佳实践,包括网络类型、行业角色、关键字、优先级和 BP 编号。

通信安全、可靠性和互操作性委员会(CSRIC)的任务是向 FCC 提供建议,以确保通信系统的最佳安全性和可靠性,包括电信、媒体和公共安全。

CSRIC 的成员专注于一系列公共安全和国土安全相关的通信事务,包括:(1)通信系统和基础设施的可靠性和安全性,特别是移动系统;(2) 911、增强型 911 (E911)、下一代 911(ng 911);& (3)紧急警报。

CSRIC 的建议将解决有害网络事件的预防和补救、提高整体通信可靠性的最佳实践的开发、通信服务的可用性和性能以及在自然灾害、恐怖袭击、网络安全攻击或其他导致通信基础设施异常紧张的事件期间的紧急警报、在出现大范围或重大中断时通信服务的快速恢复以及通信提供商可以采取的帮助保护最终用户和服务器的步骤。

对我来说,处理这个项目的第一步是理解我需要完成什么&这个项目让我走什么样的方向。我记得我需要向 FCC 提供建议,以确保电信、媒体和公共安全领域通信系统的最佳安全性和可靠性。

在尝试这个项目时,我考虑了不同的方法。第一步是直接进入,以便更好地理解数据本身,我只关注事件的优先级&对其应用大量的机器学习分类模型。第二种方法是能够将自然语言处理技术应用于事件的描述&看看这与事件的优先级有什么关系。

有了这个,我们就可以做出预测&然后,提出更好地预防、理解或控制事件的建议。我的想法是,如果我们可以通过修复不太复杂的事件来关注更关键的事件,我们就可以节省足够的资产来进一步改善系统,以应对更复杂的事件。

需要什么:

  • Python IDE
  • 机器学习和统计软件包
  • 精通数据科学概念
  • 一些网络安全和网络相关概念的知识

我们开始吧!让我们首先从导入我们打算使用的任何包开始,我通常复制并粘贴对我以前的数据科学项目有帮助的有用模块的列表。

import pandas as pd 
import numpy as np  
import scipy as sp  
import seaborn as sns
sns.set_style('darkgrid') 
import pickle       
import regex as re  
import gensimfrom nltk.stem import WordNetLemmatizer
from nltk.tokenize import RegexpTokenizer
from nltk.stem.porter import PorterStemmer
from nltk.stem.snowball import SnowballStemmer
from nltk.corpus import stopwords
from sklearn.feature_extraction import stop_words
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizerimport matplotlib.pyplot as plt 
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler 
from sklearn.naive_bayes import MultinomialNB  
from sklearn.linear_model import LinearRegression,LogisticRegression
from sklearn import metrics
from sklearn.ensemble import RandomForestClassifier, BaggingClassifier, AdaBoostClassifier, GradientBoostingClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.pipeline import Pipeline
from keras import regularizers
from keras.models import Sequential
from keras.layers import Dense, Dropoutimport warnings
warnings.filterwarnings('ignore')%matplotlib inline

然后,我们需要加载数据,并通过以下方式查看数据:

# Loads in the data into a Pandas data frame
fcc_csv = pd.read_csv('./data/CSRIC_Best_Practices.csv')
fcc_csv.head()

现在我们有了数据,我们可以探索、清理和理解这些数据。下面,我提供了一个基础数据探索性分析的功能。我们希望这样做是为了充分理解我们正在处理的数据&需要达到什么样的总体目标。

以下函数将允许我们查看任何空值、用下划线替换任何空格、重新格式化数据框索引、查看每列的数据类型、显示任何重复的数据、描述数据的统计分析并检查形状。

# Here is a function for basic exploratory data analysis:def eda(dataframe):
    # Replace any blank spaces w/ a underscore.
    dataframe.columns = dataframe.columns.str.replace(" ", "_")
    # Checks for the null values.
    print("missing values{}".format(dataframe.isnull().sum().sum()))
    # Checks the data frame range size.
    print("dataframe index: {}".format(dataframe.index))
    # Checks for data types of the columns within the data frame.
    print("dataframe types: {}".format(dataframe.dtypes))
    # Checks the shape of the data frame.
    print("dataframe shape: {}".format(dataframe.shape))
    # Gives us any statistical information of the data frame.
    print("dataframe describe: {}".format(dataframe.describe()))
    # Gives us the duplicated data of the data frame. print("duplicates{}".format(dataframe[dataframe.duplicated()].sum()))
    # A for loop that does this for every single column & their 
    # values within our data frame giving us all unique values.
    for item in dataframe:
        print(item)
        print(dataframe[item].nunique())# Let's apply this function to our entire data frame.
eda(fcc_csv)

根据这些数据,我们认为这是一个不平衡的分类问题!我们接下来需要做的是消除任何“NaN”或空值&在某种程度上平衡我们的类。根据我们的探索性数据分析,我们可以看到大多数数据在对象类型列中都有“NaN”值。我们可以用下面的函数来解决这个问题!

# Here's a function to convert NaN's in the data set to 'None' for 
# string objects.
# Just pass in the entire data frame.
def convert_str_nan(data):
    return data.astype(object).replace(np.nan, 'None', inplace = True)convert_str_nan(fcc_csv)

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

Checking the amount of values in the Priorities column

查看优先级列,我们有一个与对象相关的列,它将事件的严重性分为重要、非常重要和关键。对应于该优先级列的另一列将它们排序为 1-3,1 表示重要,2 表示非常重要,3 表示关键。根据优先级的不同,我们看到数据是不平衡的。我们通过重命名我们的专栏来解决这个问题,以便更好地理解,然后在我们关注高度重要和关键事件的地方进行平衡。

# Let's rename the 'Priority_(1,2,3)' column so we can utilize it.
fcc_csv.rename(columns = {
    'Priority_(1,2,3)': 'Priorities'
},
inplace = True)# Let's view the values & how the correspond to the 'Priority' 
# column.
fcc_csv['Priorities'].value_counts()# We notice that we have an unbalanced classification problem.
# Let's group the "Highly Important" (2) & "Critical" (3) aspects 
# because that's where we can make recommendations.
# Let's double check that it worked.
fcc_csv['Priorities'] = [0 if i == 1 else 1 for i in fcc_csv['Priorities']]
fcc_csv['Priorities'].value_counts()

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

Result of the above code after we’ve balanced the class

第一种方法(理解数据)

在下一节中,我将讨论我理解优先级列的最初方法。我很快了解到,这种方法并不是最好的,但在提出建议时,当我查看攻击的优先级时,这种方法非常有用。

我的下一步是了解哪些列与我的优先级列最符合模式和趋势。似乎所有运行良好的列都是二进制的!描述列是文本相关的&机器不喜欢处理文本对象。使用下面的代码,我们可以看到哪些列与我们的预测列最正相关&最负相关。

# Let's view the largest negative correlated columns to our 
# "Priorities" column.
largest_neg_corr_list = fcc_csv.corr()[['Priorities']].sort_values('Priorities').head(5).T.columns
largest_neg_corr_list# Let's view the largest positive correlated columns to our 
# "Priorities" column.
largest_pos_corr_list = fcc_csv.corr()[['Priorities']].sort_values('Priorities').tail(5).T.columns.drop('Priorities')
largest_pos_corr_list

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

Most Negatively Correlated

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

Most Positively Correlated

现在,我们可以开始制作我们的模型,看看我们所做的会给我们准确的预测或足够的建议信息。让我们首先从训练测试分割开始,这些相关的列作为我们的特征&我们的优先级列作为我们的预测变量。

# Let's pass in every column that is categorical into our X.
# These are the strongest & weakest correlated columns to our 
# "Priorities" variable. 
X = fcc_csv[['Network_Operator', 'Equipment_Supplier', 'Property_Manager', 'Service_Provider', 'wireline', 'wireless', 'satellite', 'Public_Safety']]
y = fcc_csv['Priorities'] # Our y is what we want to predict.# We have to train/test split the data so we can model the data on 
# our training set & test it.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 42)# We need to transpose the trains so they contain the same amount of # rows.
X = X.transpose()

既然我们已经训练测试分割了我们的特征,让我们应用网格搜索在朴素贝叶斯分类器、随机森林分类器、Adaboost/梯度增强分类器 & a Keras 神经网络上找到完全准确的最佳参数或特征!但是这些分类器模型到底意味着什么呢?

简单来说,朴素贝叶斯分类器假设一个类中特定特征的存在与任何其他特征的存在无关。让我们看看我们的数据吧!

# Instantiates the Naive Bayes classifier.
mnb = MultinomialNB()
params = {'min_samples_split':[12, 25, 40]}# Grid searches our Naive Bayes.
mnb_grid = {}
gs_mnb = GridSearchCV(mnb, param_grid = mnb_grid, cv = 3)
gs_mnb.fit(X_train, y_train)
gs_mnb.score(X_train, y_train)# Scores the Naive Bayes.
gs_mnb.score(X_test, y_test)

随机森林分类器从随机选择的训练集子集创建一组决策树,然后汇总来自不同决策树的投票,以决定测试对象的最终类别。随机森林中的每棵树都给出一个类别预测,拥有最多票数的类别成为我们模型的预测。我们来建模吧!

# Instantiates the random forest classifier.
rf = RandomForestClassifier(n_estimators = 10)# Grid searches our random forest classifier.
gs_rf = GridSearchCV(rf, param_grid = params, return_train_score = True, cv = 5)
gs_rf.fit(X_train, y_train)
gs_rf.score(X_train, y_train)# Our random forest test score.
gs_rf.score(X_test, y_test)

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

Graph of our Adaboost Model, it’s overfit!

AdaBoost 是自适应增强的简称。它基本上是一种用作分类器的机器学习算法。每当你有大量的数据,你想把它分成不同的类别,我们需要一个好的分类算法来做到这一点。因此有了“boosting”这个词,因为它可以提升其他算法!

scores_test = []
scores_train = []
n_estimators = []for n_est in range(30):
    ada = AdaBoostClassifier(n_estimators = n_est + 1, random_state = 42)
    ada.fit(X_train, y_train)
    n_estimators.append(n_est + 1)
    scores_test.append(ada.score(X_test, y_test))
    scores_train.append(ada.score(X_train, y_train))# Our Ada Boost score on our train set.
ada.score(X_train, y_train)# Our Ada Boost score on our test set.
ada.score(X_test, y_test)

神经网络是一组算法,大致模仿人脑,设计用于识别模式。他们通过一种机器感知、标记或聚类原始输入来解释感官数据。我们甚至可以应用正则化来解决过度拟合的问题!

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

Our regularized Neural Network, it’s overfit!

model_dropout = Sequential()n_input = X_train.shape[1]
n_hidden = n_inputmodel_dropout.add(Dense(n_hidden, input_dim = n_input, activation = 'relu'))
model_dropout.add(Dropout(0.5)) # refers to nodes in the first hidden layer
model_dropout.add(Dense(1, activation = 'sigmoid'))model_dropout.compile(loss = 'binary_crossentropy', optimizer = 'adam', metrics = ['acc'])history_dropout = model_dropout.fit(X_train, y_train, validation_data = (X_test, y_test), epochs = 100, batch_size = None)

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

The Accuracy of Our Models

这告诉我们什么?!根据训练分数和测试分数,我们可以看到我们的模型过度拟合 &不擅长预测或分析趋势。我们的模型过适合是什么意思?我们有高方差 & 低偏差高方差会导致算法对训练数据中的随机噪声建模,而不是对预期输出建模。我们仍然不能对此提出建议,因为它并没有给我们提供太多的信息!

第二种方法(自然语言处理)—最佳途径

我的第二个方法是关注描述栏。在我第一次尝试后,我想看看攻击的优先级与描述中给出的内容是如何关联的。描述栏给了我们一个简短的解释,说明发生了什么&一个建议的 FCC 兼容的解决方案,他们可以做些什么来阻止类似的事件。

为了更好地理解描述栏,我需要应用自然语言处理(NLP ),因为计算机和统计模型不喜欢处理文本和单词。但是我们可以解决这个问题!在清理数据和平衡优先级列时,我的方法是类似的,但是我应用了一些 NLP 概念来更好地理解描述、分析它、提出建议&甚至根据特定于事件的单词的出现来预测下一个事件是什么。

一些概念包括:

  • 预处理是将原始数据转换成干净数据集的技术。
  • **Regex,**正则表达式是一个文本字符串,允许您创建模式来帮助匹配、定位&管理文本。另一种清理文本的方法。
  • T21 是将一个单词的词形变化组合在一起的过程,这样它们就可以作为一个术语来分析。
  • 词干化是将屈折词缩减为词干、词根或词根形式的过程。
  • 计数矢量化统计词频。
  • TFIDFVectorizer 是一个词的值随着计数成比例增加,但被该词在语料库中的出现频率所抵消。

让我们从将正则表达式概念应用到已经清理过的数据开始。我们还想剥离或清除有用但在每一个描述中零星出现的常用词。

# Let's clean the data using Regex.
# Let's use regex to remove the words: service providers, equipment # suppliers, network operators, property managers, public safety
# Let's also remove any mention of any URLs.fcc_csv['Description'] = fcc_csv.Description.map(lambda x: re.sub('\s[\/]?r\/[^s]+', ' ', x))
fcc_csv['Description'] = fcc_csv.Description.map(lambda x: re.sub('http[s]?:\/\/[^\s]*', ' ', x))
fcc_csv['Description'] = fcc_csv.Description.map(lambda x: re.sub('(service providers|equipment suppliers|network operators|property managers|public safety)[s]?', ' ', x,  flags = re.I))

现在我们已经清理了我们的数据,我们应该应用一些预处理技术来更好地理解在事件的每个描述中使用的单词。

# This is a text preprocessing function that gets our data ready for # modeling & creates new columns for the 
# description text in their tokenized, lemmatized & stemmed forms. 
# This allows for easy selection of 
# different forms of the text for use in vectorization & modeling.def preprocessed_columns(dataframe = fcc_csv, 
                        column = 'Description', 
                        new_lemma_column = 'lemmatized', 
                        new_stem_column = 'stemmed',
                        new_token_column = 'tokenized',
                        regular_expression = r'\w+'): 

    tokenizer = RegexpTokenizer(regular_expression)     
    lemmatizer = WordNetLemmatizer()                     
    stemmer = PorterStemmer()                            

    lemmatized = []                                      
    stemmed = []                                         
    tokenized = []

    for i in dataframe[column]:                        
        tokens = tokenizer.tokenize(i.lower())           
        tokenized.append(tokens) lemma = [lemmatizer.lemmatize(token) for token in tokens]     
        lemmatized.append(lemma)        stems = [stemmer.stem(token) for token in tokens]            
        stemmed.append(stems)                                         

    dataframe[new_token_column] = [' '.join(i) for i in tokenized]    
    dataframe[new_lemma_column] = [' '.join(i) for i in lemmatized]   
    dataframe[new_stem_column] = [' '.join(i) for i in stemmed]   

    return dataframe

然后,我们希望对词干化、词汇化和标记化的描述词应用 countvectorize,以便控制英语中常见的停用词,我们可以使用下面的代码来实现这一点。然后我们可以看到整个数据集中最常见的单词是什么。

# Instantiate a CountVectorizer removing english stopwords, ngram 
# range of unigrams & bigrams.cv = CountVectorizer(stop_words = 'english', ngram_range = (1,2), min_df = 25, max_df = .95)# Create a dataframe of our CV transformed tokenized words
cv_df_token = pd.SparseDataFrame(cv.fit_transform(processed['tokenized']), columns = cv.get_feature_names())
cv_df_token.fillna(0, inplace = True)cv_df_token.head()

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

Top Word Count in the Entire Data Set

我们可以看到,弹出来的词大部分都是网络或安全相关的。我们可以利用这些信息更好地了解这些事件的范围!是网络攻击吗?它们与网络仓库有关吗?等等。

但是如果我们想要更多的信息呢?我们可以根据事件重要性的紧急程度或严重性对描述进行分组。也许这没什么严重的,所以它被列为 0(不重要)或非常糟糕被列为 1(非常重要)。我们可以使用下面基于预处理列的代码来实现这一点。然后我们可以想象最常见的真正重要的单词是什么。

# Split our data frame into really "important" & "not important" 
# columns.
# We will use the "really_important" descriptions to determine 
# severity & to give recommendations/analysis.
fcc_really_important = processed[processed['Priorities'] == 1]
fcc_not_important = processed[processed['Priorities'] == 0]print(fcc_really_important.shape)
print(fcc_not_important.shape)

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

Top Word Count of the Really IMPORTANT words

最后,我们可以开始对标记化的数据建模回归和分类度量。让我们从通过管道应用逻辑回归模型开始,在管道中可以应用网格搜索工具来调整我们的最佳特性或最佳参数。让我们建立我们的 X 变量,我们的特征!我们将在上面创建的经过处理的数据框的标记化列中使用单词或要素。经过处理的数据帧是一个全新的数据帧,它包含了我们的标记化、词干化和词汇化的列。

在这里,我决定将重点放在标记化的列上,因为这个特定的列在参数调优和准确性方面表现最好。为了缩短这篇博文的时间长度,我决定把重点放在符号化上,也就是效果最好的地方!让我们也对它进行测试分割。

X_1 = processed['tokenized']# We're train test splitting 3 different columns.
# These columns are the tokenized, lemmatized & stemmed from the 
# processed dataframe.
X_1_train, X_1_test, y_train, y_test = train_test_split(X_1, y, test_size = 0.3, stratify = y, random_state = 42)

现在让我们创建我们的管道,它使用网格搜索概念来寻找最佳超参数。一旦网格搜索适合(这可能需要一段时间!)我们可以从网格搜索对象中拉出各种信息和有用的对象。通常,我们会希望将几个转换器应用于一个数据集&,然后最终构建一个模型。如果您独立地完成所有这些步骤,那么在预测测试数据时,您的代码可能会很混乱。它也容易出错。幸运的是,我们将有管道

在这里,我们将应用一个逻辑模型,该模型可以考虑拉索和山脊惩罚。

你应该:

  1. 拟合并验证数据的默认逻辑回归的准确性。
  2. 对不同的正则化强度、套索和山脊惩罚进行网格研究。
  3. 将优化的逻辑回归测试集的准确性与基线准确性&默认模型进行比较。
  4. 看看找到的最佳参数。选了什么?关于我们的数据,这说明了什么?
  5. 查看优化模型的(非零,如果 Lasso 被选为最佳)系数和相关预测值。最重要的预测因素是什么?
pipe_cv = Pipeline([
    ('cv', CountVectorizer()),
    ('lr', LogisticRegression())
])params = {
    'lr__C':[0.6, 1, 1.2],
    'lr__penalty':["l1", "l2"],
    'cv__max_features':[None, 750, 1000, 1250],
    'cv__stop_words':['english', None],
    'cv__ngram_range':[(1,1), (1,4)]
}

现在,我们可以在网格搜索对象中的逻辑回归模型上应用管道。请注意正在实例化的 countvectorize 模型。我们这样做是因为我们想看看这是如何影响我们的准确性和我们与网络攻击相关的词的重要性的因素。

# Our Logistic Regression Model.
gs_lr_tokenized_cv = GridSearchCV(pipe_cv, param_grid = params, cv = 5)
gs_lr_tokenized_cv.fit(X_1_train, y_train)
gs_lr_tokenized_cv.score(X_1_train, y_train)gs_lr_tokenized_cv.score(X_1_test, y_test)

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

Our Improved Accuracy of our Logistic Model

那么由此可以推断出什么呢?看起来我们已经看到训练数据的模型精度大幅提高,测试数据的精度也提高了 10%。但是,车型还是过合身!但仍然做得很好!我们的最佳参数是什么?如果我们想调整未来的物流模型,我们可以使用这些信息!下面的代码将告诉我们这一点!

gs_lr_tokenized_cv.best_params_

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

Our BEST Hyper Parameters from our Logistic Gridsearch within the Pipeline

使用 L1 正则化技术的回归模型称为 Lasso 回归,使用 L2 的模型称为 Ridge 回归。从我们的最佳超参数,我们的模型有利于岭回归技术。现在我们想根据我们的逻辑回归做出预测&能够提出建议。我们如何继续做那件事?让我们看看与我们的特征相关联的系数,这些系数将预测最佳 y 变量的结果。

coefs = gs_lr_tokenized_cv.best_estimator_.steps[1][1].coef_
words = pd.DataFrame(zip(cv.get_feature_names(), np.exp(coefs[0])))
words = words.sort_values(1)

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

Predictions for Suggestions Based off Occurrence & Importance of Words

建议和结论

既然我已经完成了数据建模和分析,我现在可以向 FCC 以及任何其他计划进行类似项目的数据科学家或数据分析师提出建议。

未来的数据科学家做一个类似的项目。获取更多数据,更好的数据样本,增加/降低模型的复杂性& 正则化。这有助于解决我在这个项目中经历过的过度拟合你的数据的问题。了解不平衡分类问题。这样可以引出你解决问题的主要方向。

对于 FCC 的 CSRIC 的最佳实践,我的最佳建议是先解决简单的问题,这样它们就不会经常发生&耗尽您的资源。这可以让他们专注于更重要和复杂的事件或攻击。基于我的预测和对给定数据的分析。

简单的问题:

  • 不同的电缆
  • 彩色编码电缆
  • 仓库通风更好
  • 增加功率容量
  • 更好的硬件
  • 天线间距

中度问题:

  • 利用网络监控
  • 在可行的情况下提供安全的电气软件
  • 寻找新硬件和软件的门槛
  • 病毒防护

复杂:

  • 最大限度减少单点故障和软件故障
  • 设备管理架构
  • 安全网络/加密系统

将人工智能应用于电子竞技(PUBG)

原文:https://towardsdatascience.com/applying-data-science-to-esports-pubg-b7950330423a?source=collection_archive---------21-----------------------

我们都是玩电子游戏长大的,对吗?那么,我们如何将数据科学和数据分析应用于视频游戏呢?PlayerUnknown’s Battleground 也被称为 PUBG,可以说已经彻底改变了皇室战争电子游戏领域!关于 PUBG 如何开启《皇室战争》竞技游戏模式有一个争论,其他视频游戏设计者、创造者&制造商,如*&【Apex 传奇】,仅举几个例子,都复制了重新设计的&,使自己更加独特!我决定从 Kaggle 举办比赛的网站上获取数据,看看我们能否根据单个玩家的特征统计数据,找出一个人在比赛中的排名。*

在 PUBG 游戏中,每场比赛最多有 100 名玩家开始(matchId)。玩家可以加入在游戏结束时(winPlacePerc)排名的队伍(groupId ),排名是基于当他们被淘汰时有多少其他队伍还活着。在游戏中,玩家可以捡起不同的弹药,救活倒下但没有被击倒的队友,驾驶车辆,游泳,跑步,射击&体验所有的后果——例如摔得太远或撞倒自己&消灭自己。

我们得到了大量匿名的 PUBG 游戏统计数据,格式化后每行包含一个玩家的赛后统计数据。数据来自各种类型的比赛:单人赛、双人赛、团队赛和定制赛;不能保证每场比赛有 100 名球员,也不能保证每组最多有 4 名球员。我们必须创建一个模型,根据球员的最终统计数据预测他们的最终排名,范围从 1(第一名)到 0(最后一名)。我创建了一个数据字典来获取更多关于数据的信息&让我们的生活更简单。

在整篇文章中,我打算提供允许我创建这样一个模型的代码——其他模型可能对其他人来说表现得更好。我的下一个目标是创造视觉效果&提供任何进一步的见解!这个项目和文章类似于我的关于爱荷华州房价的项目和文章!感兴趣的话,点击这里

理解这篇文章需要什么:

  • 丰富的 Python 经验和知识
  • Python 统计数据包的中级知识
  • IDE
  • 熟悉数据科学、分析和统计

让我们从进口开始吧!

*import pandas as pd 
import numpy as np  
import seaborn as sns 
import matplotlib.pyplot as plt 
from sklearn.model_selection import train_test_split, GridSearchCV 
from sklearn.preprocessing import PolynomialFeatures, StandardScaler, LabelEncoderfrom sklearn.pipeline import Pipeline
from sklearn.linear_model import LinearRegression, LogisticRegression, LassoCV, RidgeCVfrom sklearn.ensemble import RandomForestClassifier, BaggingClassifier, AdaBoostClassifier, GradientBoostingClassifier%matplotlib inline*

接下来,我们需要导入我们的文件。在这个项目中,我们使用了两个文件。一组训练数据和一组测试数据。训练集和测试集非常相似,除了我们在训练集中缺少了一列,球员的最后落点!请记住,无论我们对训练数据集做什么,我们都必须对测试数据做什么,以保持我们的数据无偏、精确和相似。

*# Imports the csv files from Kaggle
# Files are stored locally
pubg_train = pd.read_csv('./data/pubg_train.csv')
pubg_train.head()pubg_test = pd.read_csv('./data/pubg_test.csv')
pubg_test.head()*

接下来,我们希望对数据显示的任何内容应用一些数据清理、探索性数据分析和常识。下面我写了一个简单的数据清理和探索性数据分析的函数,我将它应用于两个 csv 文件。

*# Here is a function for basic exploratory data analysis:
def eda(dataframe):
    # Replace any blank spaces w/ a underscore.
    dataframe.columns = dataframe.columns.str.replace(" ", "_")
    # Checks for the null values.
    print("missing values: {}".format(dataframe.isnull().sum().sum()))
    # Checks the data frame range size.
    print("dataframe index: {}".format(dataframe.index))
    # Checks for data types of the columns within the data frame.
    print("dataframe types: {}".format(dataframe.dtypes))
    # Checks the shape of the data frame.
    print("dataframe shape: {}".format(dataframe.shape))
    # Gives us any statistical information of the data frame.
    print("dataframe describe: {}".format(dataframe.describe()))
    # Gives us the duplicated data of the data frame. 
    print("dataframe duplicates: {}".format(dataframe[dataframe.duplicated()].sum()))

    # A for loop that does this for every single column & their values within our data frame giving us all 
        # unique values.
    for item in dataframe:
        print(item)
        print(dataframe[item].nunique())# Let's apply this function to our entire data frame.
eda(pubg_train)
eda(pubg_test)*

经过一些探索性分析,我们意识到我们有一些“NaN”或空值,由于不准确的数据、创建者的错误输入或不适用于训练数据集中的某个球员而留空。记住,我们必须对训练集和测试集做同样的事情。我们的数据非常“脏”

下面,我创建了一个函数来解决这个问题。我们可以通过删除行来删除这些值,看看这些值是否扭曲了数据,这些值是否是某种异常值,或者我们可以手动编辑和替换它们。我决定将“NaN”值转换为 0.0 浮点类型。

*# Here's a function to convert NaN's in a specific column in the data # set to 0.0 for floats.
# Just pass in the entire data frame & specify a specific column w/ a # float NaN.
def convert_float_nan(data):
    return data.replace(np.nan, 0.0, inplace = True)
convert_float_nan(pubg_train["winPlacePerc"])*

清理完数据后,我们已经清除了训练集的所有空值数据,因此它将与测试数据集相似!两者都没有空值&都有八行,但是记住训练数据集有 24 列,而测试数据集有 25 列。但是,我们还没有定下来!让我们改变位于两个数据集中的列的类型!转换类型使分析更容易,有效和正确!

*pubg_train['damageDealt'] = pubg_train['damageDealt'].astype(int)
pubg_train['longestKill'] = pubg_train['longestKill'].astype(int)
pubg_train['rideDistance'] = pubg_train['rideDistance'].astype(int)
pubg_train['swimDistance'] = pubg_train['swimDistance'].astype(int)
pubg_train['walkDistance'] = pubg_train['walkDistance'].astype(int)
pubg_train['winPlacePerc'] = pubg_train['winPlacePerc'].astype(int)pubg_test['damageDealt'] = pubg_test['damageDealt'].astype(int)
pubg_test['longestKill'] = pubg_test['longestKill'].astype(int)
pubg_test['rideDistance'] = pubg_test['rideDistance'].astype(int)
pubg_test['swimDistance'] = pubg_test['swimDistance'].astype(int)
pubg_test['walkDistance'] = pubg_test['walkDistance'].astype(int)*

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

既然两个集合的数据都是干净的& set,我们是否可以可视化所有列与“winPlacePerc”列的关系?这是我们希望预测的仅位于定型数据集中而不在测试数据集中的列。以下代码将完成这项工作:

*# Let's make a simple heat map on what column we're trying to 
# predict to see correlations.
plt.figure(figsize = (5,5))
sns.heatmap(np.round(pubg_train.corr()[['winPlacePerc']].sort_values('winPlacePerc'), 30), annot = True, cmap = 'viridis')*

上图显示了我们想要预测的内容&每列如何与该列正相关和负相关。某一列的接近程度&该列中的数据量如何准确地与排名第一或最后相关?这是我们的目标!让我们看看哪些列为我们提供了最强的相关性:

*# Let's view the largest negative correlated columns to our 
# "winPlacePerc" column.
largest_neg_corr_list = pubg_train.corr()[['winPlacePerc']].sort_values('winPlacePerc').head(5).T.columns
largest_neg_corr_list*

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

Largest Negatively Correlated Columns

*# Let's view the largest positive correlated columns to our 
# "winPlacePerc" column.
largest_pos_corr_list = pubg_train.corr()[['winPlacePerc']].sort_values('winPlacePerc').tail(5).T.columns.drop('winPlacePerc')
largest_pos_corr_list*

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

Largest Positively Correlated Columns

出于特征工程的目的,我们需要这样做!特征工程是机器学习算法中使用的特征(变量)的创建和操作。(集思广益或测试特征,决定要创建的特征,检查特征如何与模型配合工作,改进特征(如果需要)。我们的特征,我们指定的相关列&它们的数据有助于预测和显示关系,在这种情况下是我们试图预测的关系!

现在我们已经得到了我们的特性,让我们从训练/测试分割数据开始&然后扩展它。我们可以通过将样本数据分割成子集来执行模型验证,这也称为训练/测试分割。这是我们可以用来训练模型和测试模型的代表性数据。这可以帮助表示未来的数据,避免某些调整的过度拟合,并提高我们预测的质量。

当我们缩放数据时,我们实质上是将我们的列转换成 Z 分数。这意味着您正在转换我们的数据,使其符合特定的范围,如 0-100 或 0-1。当您使用基于测量数据点之间距离的方法时,您希望缩放数据。

*# Here we can feature load our best correlated variables.
# Our y-variable is what we want to predict.
X = pubg_train[['killPlace', 'matchDuration', 'winPoints', 'killPoints', 'rankPoints', 'damageDealt', 'weaponsAcquired', 'boosts', 'walkDistance']]
y = pubg_train['winPlacePerc'] # What's being predicted# Let's train test split our data.
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 42)# Scales our data.
# Feature scaling is a method used to normalize the range of 
# independent variables or features of data. 
# In data processing, it is also known as data normalization.
ss = StandardScaler()
ss.fit(X_train)
X_train = ss.transform(X_train)
X_test = ss.transform(X_test)*

现在,我们已经完成了所有的预处理步骤,让我们开始创建我们的模型,该模型将帮助我们根据我们已经训练/测试的特性来预测胜率。对于这个项目,我决定使用逻辑回归函数,也称为 Logit 函数,因为我们能够处理带有分类标签数据的数字数据。分类标签数据是我选择的特征!

为什么是 Logit 模型?除了简单的线性回归,逻辑回归是一种替代方法。逻辑回归使用比值比的概念来计算概率。这被定义为一个事件发生的几率与它不发生的几率之比。我决定通过网格搜索来运行我的 Logit 模型,以找到最佳参数&在这个范围内,有一条优化的管道!

*# A pipeline that instantiates a tuned Logistic Regression model.
pipe_cv = Pipeline([
    ('lr', LogisticRegression())
])
# Here are our parameters we've tuned.
params = {
    'lr__C':[1.0],
    'lr__penalty':["l1"]
}# Our Logistic Regression Model ran through a Grid Search Object.
gs_lr = GridSearchCV(pipe_cv, param_grid = params, cv = 3)
gs_lr.fit(X_train, y_train)
gs_lr.score(X_train, y_train)*

这是我们基于跑步或 Logit 模型对训练/测试分割功能中的训练数据得出的分数。请记住,分割允许我们使用部分训练数据集作为测试数据集,因为整个训练数据集代表整个测试数据集!

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

Pipeline Gridsearch Training Score

注意我们的训练分数有多高!那太好了,如果我们的测试分数相似,那么我们就不是过度健康或不健康!更多了解过度拟合和欠拟合模型,查看我的数据科学家指南这里!这将展示如何避免过度装配&装配不足。

现在让我们给测试数据打分吧!

*# Let's run our model on the test data.
gs_lr.score(X_test, y_test)*

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

Pipeline Gridsearch Testing Score

我们的模型既不是过合身也不是欠合身!干得好!现在,我们对管道的最佳调整参数是什么?

*# Give's us our best parameters.
gs_lr.best_params_*

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

Best Parameters Based off of a Logit Model Pipeline

我们的 Logit 模型像一个套索逻辑回归特征,在调整参数中用“l1”表示!现在我们已经有了模型集,清理了数据,并发现基于这些特征预测成功率的可能性很大,我们的下一步是将它们可视化!这将在本文后面出现,所以请继续关注!

应用深度学习优化服装电子商务流程

原文:https://towardsdatascience.com/applying-deep-learning-for-fashion-e-commerce-7e9e28692172?source=collection_archive---------24-----------------------

自动选择鞋类的缩略图。

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

Image courtesy : https://www.myntra.com/

当我学习无监督学习方法时,我遇到了不同的聚类方法,如 KMeans,层次聚类。在学习阶段,我想在现实世界的问题上实现这种方法。此外,电子商务系统已经占据了我的心灵一段时间,了解这个系统是如何工作的非常有吸引力。所以我决定解决一个我将在本文中描述的问题。

在这篇博客中,我将分享我在为时尚电子商务(鞋类)选择缩略图的自动化过程中的经验和收获。它将涵盖以下内容:

  • 如何使用用于聚类过程的深度学习从图像生成特征
  • 如何找到 KMeans 的最佳聚类数(肘方法)
  • 选择哪种架构进行特征提取

问题陈述:

想象一下,为一家时尚电子商务公司工作,每天都能从供应商那里获得成千上万张鞋类图片。为缩略图选择正确的图像很重要,这样才能吸引用户进一步查看或购买产品。

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

Lace-Up shoes .

任务是从一堆鞋的图像中识别将被用作缩略图的最佳视图图像,并且还对鞋的类型进行分类。在上面的图像中,右侧图像是最好的图像,它将被用作缩略图。

W 为什么这是必要的?

  • 每个产品都有多个视图(前视图、后视图、左视图、右视图),只有少数视图有产品的信息,因此选择产品的最佳视图将是缩略图。它将自动完成某些手动完成的过程。
  • 当训练分类器来识别鞋的类型时,选择最佳视图也是有益的。通过这样做,分类器将仅从具有最多信息的视图(如前视图或侧视图)中学习特征。如果你给分类器提供描述鞋的鞋底的视图,那么它将不会学习对分类鞋的类型更重要的特征。像系带鞋一样,具有系带信息的视图将是对分类器最有用的特征,而不是鞋底信息。

数据

数据由Fynd-时尚电子商务公司提供。 CSV 文件,列名为“类”,图像 URL 指向不同的视图(5 个不同的视图)。从网址下载图片,并保存为以下格式: **footweartype_id_viewid.jpg。**此外,通过查看图像,view_1 将始终是鞋类的前视图也是不必要的。

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

数据集中总共有 6 类鞋。

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

Image Courtesy : Fynd . Types of Footwear

方法

在数据中,我们没有给出任何关于缩略图选择哪个视图的信息。我们只能从不同的角度来看特定的鞋子和它的类型。那么,如果数据没有用最佳视图标记,如何训练分类器呢?这类问题属于无监督学习。对于无监督学习,我们可以使用聚类等方法来标记数据。

在跳到任何非监督方法之前,有必要将问题一般化,以便方法变得简单。在观察数据集之后,我遇到了某些事情:

  • 对于系带鞋、便鞋、带扣鞋、钩环鞋、后带鞋,视图将是最重要的视图。

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

  • 对于 zip 类型,包含 zip 信息的视图将是最重要的视图。

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

现在我们已经决定了某些事情,这将概括我们的问题。现在转向无监督的方法来识别上述鞋的类型。

如何使用聚类?

现在的任务是将具有相同视图的图像聚集在一起。我决定使用 KMeans 进行聚类。要使用像 KMeans 这样的聚类算法,我们必须传递图像的某些特征。诸如形状上下文、要点、HOG、启发式等特征,并将这些特征提供给聚类算法。在可视化每种鞋类的聚类后,有一些不属于这些聚类的坏图像。

在这一切之后,我决定使用深度学习方法进行聚类。什么?怎么会?

基本思想是将图像传递给预训练的网络,然后移除模型的顶层,并将最后一层的输出传递给聚类算法。

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

使用预先训练的深度学习网络的好处是,在层中学习的抽象将捕捉一切,形状,模式等。所以我们不必手动从图像中提取特征。就像魔法一样。

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

有不同的预训练模型,如 VGG16、VGG19、ResNet50 等。为了决定选择哪种架构,我们可以使用 剪影得分 来找到最佳集群。

剪影得分是一种衡量一个聚类中的每个点与其相邻聚类中的点的接近程度的方法。这是在 k-means 聚类过程中找出 k 的最佳值的一种简洁的方法。轮廓值在[-1,1]范围内。值+1 表示样本远离其相邻聚类,而非常接近其所分配的聚类。同样,值为-1 表示该点与其相邻的簇的距离比其所分配的簇的距离更近。并且,值为 0 意味着其在两个集群之间的距离的边界处。值+1 是理想值,-1 是最不理想的值。因此,该值越高,集群配置越好。

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

在上图中,随着聚类数的增加,可以观察到 ResNet 的性能优于 VGG16。因为 ResNet50 更深入,它捕捉到更多的信息。

集群的可视化

从 ResNet 传递特征,并找到具有相同视图的集群。

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

Same Views of Hook Type Closure

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

Same views of Laceup Closure

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

Same views of Backstrap closures

model = ResNet50(weights='imagenet', include_top=**False**)# function to load a particular type of footwear . And pass the return the features from last layer**def** get_vec_footwear(footwear_dir):

    resnet50_feature_list = []
    filenames = listdir(footwear_dir)
    **for** i,fname **in** enumerate(filenames):
        **try** :
            img = image.load_img(footwear_dir+'/'+fname,target_size= (224,224))
            img_data = image.img_to_array(img)
            img_data = np.expand_dims(img_data,axis=0)
            img_data = preprocess_input(img_data)
            resnet50_feature = model.predict(img_data)
            resnet50_feature_np = np.array(resnet50_feature)
            resnet50_feature_list.append(resnet50_feature_np.flatten())

        **except** **IOError** :
            **continue**

    resnet50_feature_list_np = np.array(resnet50_feature_list)
    **return** resnet50_feature_list_np#Feature vectors from above function is passed into this function to get clusters**def** get_clusters(a,b,resnet50_feature_list_np):
    silloute_score = []
    objects = []
    cluster_errors = []
    **for** i **in** range(a,b):
        objects.append(i) 
        print(i)
        kmeans = KMeans(n_clusters=i, random_state=0, n_jobs=-1).fit(resnet50_feature_list_np)
        silloute_score.append(metrics.silhouette_score(resnet50_feature_list_np , kmeans.labels_,metric='euclidean'))
        cluster_errors.append( kmeans.inertia_ )

    **return** silloute_score , objects , cluster_errorsresnet50_feature_list_np = get_vec_footwear('lace_data_rgb')

silloute_score , objects , cluster_errors = get_clusters(2,20,resnet50_feature_list_np)

在上面的代码中,我们将目录名传递给 get_vec_footwear 函数。它返回图像的特征向量。在获得特征向量之后,它们被传递给 get_clusters 函数,该函数将特征向量传递给聚类算法。

您可以在这里找到进一步的实现:

[## amitpeshwani/鞋类-最佳视角-分类

在 GitHub 上创建一个帐户,为 amitpeshwani/鞋类最佳视角分类的发展做出贡献。

github.com](https://github.com/amitpeshwani/footwear-best-view-classification)

对于每种类型的鞋,基于轮廓得分的 肘分析 来决定最佳的聚类数。

肘方法的思想是对数据集的一系列值k(k-聚类数)运行 k 均值聚类,并对每个值 k 计算误差平方和(SSE)。然后,为每一个 k 值绘制一个上证指数的折线图。如果折线图看起来像一只手臂,那么手臂上的“肘”就是最好的 k 的值。

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

https://bl.ocks.org/rpgove/0060ff3b656618e9136b

在上图中,K 的最佳值是 5。在 k=5 的值之后,随着我们增加 k . ,SSE 趋向于向 0 下降,因此的目标是选择一个较小的值 k ,该值仍然具有较低的 SSE,并且肘部通常代表我们通过增加 k 开始具有递减收益的地方。

在聚类的基础上,图像被分成

  • Typeoffootwear _ bestview
  • Typeoffootwear _ nobestview

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

Laceup-best-views

按照上面的方法,我把每种鞋的相同视图的图片分开,保存到名为typeofootware _ best/nobestviews(上图中的 lace up _ best)**的文件夹中。**因此,我们为每种鞋类标注了最佳和非最佳视角的数据。现在,我们可以训练一个分类器,它不仅可以识别最佳视图,还可以对鞋的类型进行分类。将无监督学习问题转化为有监督学习问题。

在上面的图片上训练 VGG19。以下是模型的输出示例:

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

Laceup

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

Hook & Loop

最后的话

我在剪影评分的基础上使用了预先训练好的 ResNet50。resnet 的输出直接馈入聚类算法。使用肘分析找到了最佳聚类数。然后,在聚类的基础上分离图像,并用特定的视图标记每个聚类。现在有了带有鞋的类型的视图的标记信息,使用正常的 VGG 体系结构进行分类任务。进一步的 **改进:**我们可以使用在时尚 MNIST 数据集上训练的模型,而不是使用在 imagenet 数据集上训练的预训练 resnet,因为它将捕获鞋类的形状和纹理的更多信息,并使用该模型进行聚类。

希望本文概述了我解决这个特殊问题的实现。请随意纠正我的实现。

感谢阅读,

艾米特。

想聊天?在Linkedin上找我。

我的一些有趣的作品:

[## amitpeshwani/电影推荐案例研究

在 GitHub 上创建一个帐户,为 amitpeshwani/电影推荐案例研究的发展做出贡献。

github.com](https://github.com/amitpeshwani/Movie-Recommendation-Casestudy) [## amitpeshwani/NLP-亚马逊-食品-评论

在 GitHub 上创建一个帐户,为 amitpeshwani/NLP-Amazon-Food-Reviews 的发展做出贡献。

github.com](https://github.com/amitpeshwani/NLP-Amazon-Food-Reviews)

在 Java 中应用 NLP,全部来自命令行

原文:https://towardsdatascience.com/applying-nlp-in-java-all-from-the-command-line-1225dd591e80?source=collection_archive---------27-----------------------

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

Image source by Hannah Wright

介绍

我们都知道通过浏览器工作的机器学习工具和云服务,它们为我们提供了一个界面,我们可以使用它来执行日常数据分析、模型训练和评估以及其他不同程度的效率任务。

但是,如果您想在本地机器或组织中可用的基础设施上完成这些任务,您会怎么做呢?而且,如果这些可用的资源不能满足完成体面的端到端数据科学或机器学习任务的先决条件。这时,访问云提供商不可知的深度学习管理环境,如 Valohai 会有所帮助。此外,我们将使用所有人都可以使用的 自由层

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

Create a free account

我们将执行构建 Java 应用程序的任务,然后使用它训练和评估 NLP 模型,我们将从命令行界面完成所有这些工作,减少与可用 web 界面的交互,基本上这将是一个端到端的过程,一直到训练、保存和评估 NLP 模型。我们不需要太担心设置、配置或管理任何环境。

目的或目标

在这篇文章中,我们将学习做一系列的事情,涵盖不同层次的抽象(没有特定的顺序):

  • 如何在本地机器上构建和运行 NLP 模型?
  • 如何在云上构建和运行 NLP 模型?
  • 如何构建运行在 CPU 或 GPU 上的 NLP Java 应用?
  • 大多数例子都不是基于 Java 的,更不用说基于 Java 的了
  • 大多数例子都是基于 CPU 的,很少是基于 GPU 的
  • 如何根据资源(即 GPU)的存在与否来执行上述操作?
  • 如何为 Java 搭建一个 CUDA docker 容器?
  • 如何从命令行完成以上所有工作?
  • 通过单独的命令
  • 通过 shell 脚本

我们需要什么,如何需要?

以下是我们开始行动所需要的:

  • 可以在任何操作系统上构建和运行的 Java 应用程序
  • 允许连接到远程云服务的 CLI 工具
  • 管理上述所有内容的 shell 脚本和代码配置

一旦我们明确了我们的目标和需求,这个任务的如何部分就不难了,我们将在接下来的章节中展开。

面向 Java、DL4J 和 Valohai 的 NLP

面向 Java 的 NLP:DL4J

我们在 GitHub 上为你捕获了这篇文章所需的所有代码和说明。以下是您熟悉该项目的步骤:

快速启动

为了快速开始,我们只需要做这些事情:

$ git clone https://github.com/valohai/dl4j-nlp-cuda-example/
$ cd dl4j-nlp-cuda-example
$ vh project create
$ vh project open### Go to the Settings page > Repository tab and update the git repo address with https://github.com/valohai/dl4j-nlp-cuda-example/
  • 用来自 git repo 的最新提交更新 Valohai 项目
$ vh project fetch

现在,您已经准备好开始使用从命令行执行机器学习任务的能力了。

参见自述文件 中的 高级安装和设置部分,了解我们需要在您的系统上安装和配置什么,以便在您的本地机器上或 Docker 容器中运行应用程序和实验——目前这不是这篇文章所必需的,但您可以在以后尝试。

关于 valohai.yaml

您可能已经注意到,我们在 git repo 中有一个 valohai.yaml 文件,我们的 valohai.yaml 文件包含几个您可以使用的步骤,我们已经按它们的名称登记了它们,我们将在运行我们的步骤时使用它们:

  • build-cpu-gpu-uberjar :在 Valohai 上构建我们的 Uber jar(CPU 和 gpu 两个版本)
  • train-cpu-linux :在 Valohai 上使用 uber jar 的 cpu 版本运行 NLP 训练
  • train-gpu-linux :在 Valohai 上使用 gpu 版本的 uber jar 运行 NLP 训练
  • evaluate-model-linux :从上述 train-* 执行步骤之一评估经过训练的 NLP 模型
  • 了解您的 GPU:在任何实例上运行为了收集该实例上与 GPU/Nvidia 相关的详细信息,我们对上面的其他步骤(构建和运行步骤)运行相同的脚本

从命令行构建 Java 应用程序

假设您已经设置好了,我们将从在命令提示符下在 Valohai 平台上构建 Java 应用程序开始,这就像运行两个命令之一一样简单:

$ vh exec run build-cpu-gpu-uberjar [--adhoc]

### Run `vh exec run --help` to find out more about this command

您将会看到一个执行计数器的提示,它不是一个数字:

<--snipped-->
😼  Success! Execution #1 created. See https://app.valohai.com/p/valohai/dl4j-nlp-cuda-example/execution/016dfef8-3a72-22d4-3d9b-7f992e6ac94d/

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

注意:仅当您没有使用 git repo 设置您的valo hai项目或者有未保存的提交并且想要在确定配置之前进行试验时,才使用 *--adhoc*

您可以通过以下方式观看处决过程:

$ vh watch 1

### the parameter 1 is the counter returned by the `vh exec run build-cpu-gpu-uberjar` operation above, it is the index to refer to that execution run

您可以看到,当执行开始时,我们或者在等待分配实例,或者控制台消息在屏幕上移动。你也可以通过网络界面看到同样的内容。

注意:实例的可用性取决于它们的受欢迎程度以及您对它们的剩余配额,如果它们最近被使用过,则它们更有可能是下一个可用的。

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

一旦该步骤完成,您可以看到它产生了一些工件,在 Valohai 术语中称为输出,我们可以通过以下方式看到它们:

$ vh outputs 1

### Run `vh outputs --help` to find out more about this command

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

在接下来的步骤中,我们需要类似于datum://[....some sha like notation...]的 URL。您可以看到,我们有一个日志文件,其中捕获了关于正在运行的实例的 GPU 相关信息,您可以通过以下方式下载该文件:

$ vh outputs --download . --filter *.logs 1

### Run `vh outputs --help` to find out more about this command

从命令行运行 CPU/GPU 的 NLP 训练过程

我们将使用构建的工件,即用于 CPU 和 GPU 后端的 uber jars 来运行我们的培训流程:

### Running the CPU uberjar
$ vh exec run train-cpu-linux --cpu-linux-uberjar=datum://016dff00-43b7-b599-0e85-23a16749146e [--adhoc]

### Running the GPU uberjar
$ vh exec run train-gpu-linux --gpu-linux-uberjar=datum://016dff00-2095-4df7-5d9e-02cb7cd009bb [--adhoc]

### Note these datum:// link will vary in your case
### Run `vh exec run train-cpu-linux --help` to get more details on its usage

注:看看 Valohai CLI docs 的 输入,看看如何编写如上的命令。

如果我们喜欢,我们可以观看这个过程,但它可能会很长,所以我们可以切换到另一个任务。

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

上面的执行运行结束时,将模型保存到${VH_OUTPUTS}文件夹中,使其能够被 Valohai 归档。型号名称后面有后缀,以记录它们是如何生产的。

在我们构建、训练或评估步骤的任何时候,我们都可以通过这样做来停止正在进行的执行(排队或运行):

$ vh stop 3
(Resolved stop to execution stop.)
⌛   Stopping #3...
=>   {"message":"Stop signal sent"}
😁  Success! Done.

成功训练后下载保存的模型

我们可以通过计数器号查询执行的outputs,并使用以下命令下载:

$ vh outputs 2
$ vh outputs --download . --filter Cnn*.pb  2

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

看你 如何在你的本地机器 上评估下载的模型,既有由CPUGPU创建的模型基于进程(各自的妖孽 jars)。只需将下载模型的名称作为参数传递给 提供的 runner shell 脚本

评估来自先前训练执行的保存的 NLP 模型

### Running the CPU uberjar and evaluating the CPU-verion of the model
$ vh exec run evaluate-model-linux --uber-jar=datum://016dff00-43b7-b599-0e85-23a16749146e --model=datum://016dff2a-a0d4-3e63-d8da-6a61a96a7ba6 [--adhoc]

### Running the GPU uberjar and evaluating the GPU-verion of the model
$ vh exec run evaluate-model-linux --uber-jar=datum://016dff00-2095-4df7-5d9e-02cb7cd009bb --model=datum://016dff2a-a0d4-3e63-d8da-6a61a96a7ba6 [--adhoc]

### Note these datum:// link will vary in your case
### Run `vh exec run train-cpu-linux --help` to get more details on its usage

在模型评估结束时,我们得到了下面的模型评估指标和在模型上运行测试集后的混淆矩阵:

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

注: 源代码 以行内注释的形式包含了各阶段 ML 和 NLP 相关的解释。

捕获关于 Nvidia 的 GPU 和 CUDA 驱动程序的环境信息

此步骤与在云上构建和运行 Java 应用程序以及使用客户端工具远程控制和查看它的整个过程无关,尽管能够了解我们在何种系统上运行培训是有用的,特别是对于培训的 GPU 方面:

$ vh exec run know-your-gpus [--adhoc]

### Run `vh exec run --help` to get more details on its usage

记录你的实验

  • 在写这篇文章的时候,我做了几个实验,并以一种有效的方式跟踪成功和失败的实验,我能够使用 Valohai 的版本控制工具
  • 过滤执行
  • 通过“令牌”搜索具体执行
  • 重新运行成功和失败的执行
  • 确认执行是成功的,失败的原因是正确的
  • 另外,在下面的 Valohai 平台上检查数据目录数据来源是我的项目的一个例子(寻找跟踪按钮):

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

比较基于 CPU 和 GPU 的进程

我们可以从以下方面讨论基于 CPU 和 GPU 的进程之间的比较:

  • 应用程序构建性能
  • 模型训练速度
  • 模型评估准确性

但是我们不会在这篇文章中讨论这些话题,尽管你可以获得你需要的指标,如果你想进一步研究的话。

必要的配置文件和 shells 脚本

所有必要的脚本都可以在 GitHub repo 上找到,它们可以在:

  • 项目的根文件夹
  • docker 文件夹
  • 资源-存档文件夹

也请看看 README.md 文件,了解更多关于它们的用法和其他我们在这篇文章中没有提到的信息。

瓦罗海——编排

如果我们注意到上述所有任务都是通过一些不同抽象层次的工具来编排的:

  • docker 管理基础设施和平台级配置以及版本控制管理
  • java 能够在任何选择的平台上运行我们的应用
  • shell 脚本能够以平台无关的方式再次运行构建和执行命令,并且能够在 MacOSX 上的 GPU 等资源缺失时进行例外处理
  • 客户端工具,用于连接远程云服务,即 Valohai CLI ,并查看、控制执行和下载最终结果

您正在利用可用于完成各种数据和机器学习任务的工具和技术,从一个点协调您的任务。

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

Image source by Mark Rasmuson

结论

我们已经看到 NLP 是一项消耗资源的任务,拥有正确的方法和工具肯定会有所帮助。来自 SkymindDeepLearning4J 库和 Valohai 平台再次为我们服务。感谢两个平台的创造者。此外,我们可以看到这篇文章强调的以下好处(以及更多)。

利益

我们通过做上述事情获得了很多东西:

  • 不必担心硬件和/或软件配置和版本控制管理— docker 容器 FTW
  • 能够运行手动一次性构建、培训和评估任务— Valohai CLI 工具 FTW
  • 让您的团队定期自动执行任务,以便能够在远程云基础架构上运行任务— 基础架构即代码 FTW
  • 克服旧的或缓慢的机器或无法访问板载 GPU 的 Mac 的限制— 支持 CUDA 的 docker 映像脚本 FTW
  • 克服本地或服务器基础设施上没有足够资源的情况,并且仍然能够运行需要高吞吐量和高性能环境的实验——与云提供商无关的平台,即valo hai environmentsFTW
  • 运行任务,而不必等待任务完成,并且能够以经济高效的方式在远程资源上同时并行运行多个任务,这是一个与云提供商无关的平台,即valo hai CLItool FTW
  • 远程查看、控制配置和执行,甚至在成功执行后下载最终结果——一个与云提供商无关的平台,即 Valohai CLI 工具 FTW
  • 和许多其他你会发现自己

建议

  • **使用提供的支持 CUDA 的 docker 容器:**强烈建议不要在本地机器(基于 Linux 或 Windows)上安装 Nvidia 驱动程序或 CUDA 或 cuDNN 暂时搁置,留待以后试验
  • **使用提供的 shell 脚本和配置文件:**尽量不要执行手动 CLI 命令,而是使用 shell 脚本来自动执行重复的任务,前提是示例是一个很好的起点,并在此基础上更进一步
  • 尝试从提供的资源中学习尽可能多的:关于 GPU、CUDA、cuDNN,并寻找更多(参见帖子底部的资源部分)
  • 使用版本控制和基础设施即代码系统:git 和 valohai.yaml 就是很好的例子

在做上述所有事情时,我感到非常高效,我的时间和资源得到了有效利用,最重要的是,我可以与他人分享,每个人都可以直接重用所有这些工作——只需克隆回购就可以了

我们没有提到的,也可能是一个很好的话题,就是在未来的帖子中提到的瓦罗海管道

资源

瓦罗海资源

其他资源

其他相关岗位

最初发表于【https://blog.valohai.com】

在数据科学中应用产品方法

原文:https://towardsdatascience.com/applying-product-methodologies-in-data-science-a13aac70de0e?source=collection_archive---------17-----------------------

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

Photo by Stefan C. Asafti on Unsplash

什么是伟大的数据驱动产品?花式模特?开创性的想法?事实是,秘方通常在于成功实施产品方法论。

在这篇文章中,我回顾了最近的一次黑客马拉松经历,使用了最小可行产品、风险假设和峰值的精益和敏捷方法概念。我探索了这些方法如何帮助团队快速识别用例,映射所设想的解决方案的风险和复杂性,并快速迭代到可发布的产品。

GitHub 代码可用此处

黑客马拉松式的戏弄

“世界上哪些地方发生了侵犯人权的行为,发生了哪些类型的侵犯人权行为?”

这是在最近与微软的 AI for Good 倡议联合举办的黑客马拉松中,发给洞察数据科学研究员的一份不那么谦虚的简报。我是西雅图团队的一员,最初是由一屋子的博士组成的,他们摇着头,嘀咕着资源、范围,以及这份简报甚至是一个有效的研究问题的前提。我们勇往直前,走了很远,最终成为向微软展示的两个决赛团队之一。

我们的工作分析了美国国务院关于各国人权状况的年度报告,该报告每年为全球约 160 个国家发布。我们使用了一种量化评分方法,旨在总结每个人权领域的国家表现(使用来自 Cingranelli-Richards (CIRI)人权数据项目的数据和方法)。然后,我们制作了一个仪表板,显示(1)侵犯人权的类型如何在各国聚集,(2)它们与宏观经济和发展指标的关系,(3)国务院报告中通常与这些聚集相关的关键词。

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

Final output of the Seattle hackathon team: credit to Kyle Chezic for data vis code

这是我们的第一次黑客马拉松。我为我们的团队和我们所做的工作感到非常自豪。然而,评委的反馈给我的印象是,虽然我们使用的方法和模型显示了强大的技术能力,但我们有时很难清楚地讲述我们做了什么以及为什么做。从那以后,我开始思考如何将产品思维应用到数据科学项目中,说实话,这往往会在展示技术实力的热潮中迷失。

医生和数据科学

Insight 是一项博士后培训奖学金,旨在弥合学术界和数据科学之间的差距。该项目的职权范围确保其组织者特别乐于将博士们置于他们过去的学术应对策略痛苦地死去的境地。作为一个物种,我们生来就不具备快速切入问题核心,理解解决方案的受益者,并在两者之间画出最短路线的能力。更好的做法是,在接下来的一年里仔细提炼研究问题……在接下来的四年左右时间里,在埋在付费墙后面的期刊上发表大量警告性的答案。

需要澄清的是,我不想加入数据科学博客的活跃交易,这些博客胜利地痛斥学术界。博士成为优秀的数据科学家是因为他们受过科学训练,而不是尽管如此。然而,从学术界向科技行业的转变包括决定在旅途中带什么工具,以及哪些工具应该亲切地存放在阁楼上“以备后用”,与面包机、攀岩用具和其他过去雄心的遗物放在一起。

学术研究思维必须进入阁楼,特别是通过对知识主体的潜在贡献来评估研究问题价值的本能,以及相应的信念,即只有在同行评议的火焰中锻造的深入方法才能通过检验。要保留的,是理解领域知识是必不可少的;不管你的代码和数学有多好,如果你不理解你正在建模的系统,以及你自己的偏见的影响,你仍然在黑暗中徘徊。

从研究项目到产品开发

那么,从微软的反馈中我们能学到什么呢?嗯,一个评论指出用例不清楚。*谁在使用这个产品,我们为他们解决了什么问题?*第二是我们的产品方法不够清晰。我们需要讲述一个更好的关于特性优先级的故事,以及我们如何分配时间来开发它们。

定义用例

回想起来,我们心中的用例是建立在微软已经与联合国人权事务高级专员办事处(人权高专办)完成的一些工作的基础上的。总之,微软和人权高专办举行了一次联合构思会议,以确定人权高专办工作人员真正需要的是什么。其成果是 RightsView,实质上是一个关于世界各地新出现和正在发生的侵犯人权行为的实时信息仪表板。研讨会引用的一段话表明,人权高专办想要仪表板;

“对潜在的、新出现的或正在发生的危机提出明确的人权观点,并通过联合国其他部门和国际社会的更广泛参与,对这些危机作出适当的反应。”

会议还制作了仪表板模型的草图,这是决定产品开发方向的有用起点。

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

Product Vision: ‘The Right(s)View’, a dashboard for human rights monitoring. Source:https://news.microsoft.com/features/technology-helps-un-advance-protection-human-rights-new-ways/

MVP 方法

给定一个经过充分研究的用户和用例,任务就变成了描述该产品的功能,并确定开发的当务之急。这样做的主要方法是开发最小可行产品(MVP)。这种方法规定识别满足早期用户的最小功能集,尽快发布这些功能,并通过建立成功和整合用户反馈来迭代产品。

看看 RightsView 仪表板的例子,首先映入我眼帘的是,这本质上是一个“从消防水管喝水”的问题;我们试图提供一种服务,它吸收大量具有高度可变性和噪声的非结构化数据,并向用户返回结构化、相关、简洁和可预测的信息,从而引导或支持他们采取行动。这种服务中潜在功能的深度是令人生畏的,我们可以将它描述为一种多阶段的方法,在这种方法中,我们越来越接近“结构化、相关、简洁和可预测”的最终目标(见下图)。)

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

When drinking from the firehose, use a funnel.

从 MVP 的角度来看,我们可能会问,*帮助用户消化所有这些数据的最小功能是什么?*我认为这是摄取所有非结构化数据并以某种方式将其转换为分类和地理定位事件的第一步,并结合结构化数据的表示层(最有可能是地图仪表盘)。)

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

Prioritized MVP functionality

应该注意的是,MVP 方法经常被指责为落入了削减产品的陷阱,以至于最初的发布有些琐碎,用途有限。因此,作为一个独立的产品,这种功能的例子值得在市场上寻找。

在公共非结构化数据的事件映射的情况下,实际上有一个相当健康的市场。例如,武装冲突地点&事件数据项目 ( ACLED )就非常接近这第一步。然而,其数据依赖于研究人员手动编码提交给网站的非结构化报告。虽然这使它成为一个更值得信赖的数据来源和记者的最爱(例如卫报经常使用其数据),但其手动方式使其成为一个耗时和昂贵的产品。

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

The ACLED uses a mostly manual approach to codifying events data

另一个很好的例子是关于事件、语言和语气的全球数据库(GDELT),它代表了将公共媒体源解析为事件数据的过程完全自动化的尝试。该项目的创始人 Philip Schrodt 在 2011 年的一篇论文中概述了生成该数据集的必要步骤,该数据集现在可供任何人在这里使用。虽然 GDELT 几乎过于庞大,无法适用于正在发生何种类型的侵犯人权行为以及发生在何处的问题,但它确实表明,事件数据生产确实是它自己的研究领域,在政策分析和社会学方面拥有广泛的用户基础。

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

GDELT is an example of fully automated event detection

确定了一个 MVP,并从 Schrodt 的 2011 年的论文中概述的步骤开始,我选择进行一些我自己的进一步工作,看看工作的 MVP 迭代会是什么样子。有很多中型文章发布了文本分类程序的一步一步的过程,所以如果你感兴趣的话,我将只提供一个简短的概要和一个到 github 项目的链接。

MVP 从国务院 2015 年至 2018 年的年度人权国家中摘抄了文本。每年涵盖约 160 个国家,每份报告约 10,000 字,分为以下几节:

  • 政府腐败和缺乏透明度
  • 歧视、社会虐待和人口贩运
  • 尊重公民自由
  • 尊重人的完整性
  • 工人权利
  • 参与政治进程的自由

每个句子都由它出现的部分标记,然后形成标记的训练数据。在进行一些引导重采样以解决类别不平衡之后,数据被清理、矢量化并用于训练支持向量机。然后,这被用作从各种 RSS 提要中解析的新闻提要的分类算法。

同时,我使用自然语言工具包(NLTK)对每个新闻故事进行实体检测,特别是搜索地名。在找到一个名字的地方,这个名字被传递给谷歌地图的 API,以便对这个故事进行地理定位。结果存储在 pandas 数据框中,并使用 Tableau 可视化

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

Outline of the process for event coding RSS newsfeeds

其结果是我刚刚调查的现有方法的基本版本,但特别关注新闻报道中报道的侵犯人权行为。在训练中,该模型在 6 个类别中实现了 76%的准确率,当应用于 RSS 提要时,这一准确率下降到 67%。

Demo of MVP for human rights events in RSS feeds

显然,这是一个比我们团队采用的方法简单得多的结果。但是有没有好一点呢?我们的时间是否应该更好地花在改进产品的“第一步”上,或者我们探索更大范围的功能是否正确?要回答这个问题,调动第二种产品开发方法是有帮助的…

最危险的假设方法

一个 MVP 用一个清晰的、线性的路径来诱惑一个优化的解决方案。最危险的假设测试把重点放在学习上…

从这个角度来看,MVP 部分中概述的漏斗现在可以被认为是关于什么可以做什么不可以做的风险越来越大的假设,特别是在分配的时间框架内。

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

Taking a Risky Assumption perspective means explicitly acknowledging the scale and risk of the challenge

再说一次,在评估什么是可能的,什么是不可能的时候,做一些市场调查是值得的。事实证明,预测国家支持的犯罪,特别是暴力的爆发的领域已经被几个团体尝试过了。例如,早期预警项目宣称自己是第一个此类公共系统,旨在“关注那些尚未发生大规模暴行,但这种暴力风险很高的国家。”

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

The Early Warning Project attempts to highlight countries ‘at risk’ of mass killings

我首先注意到的是该项目的发言人强调它是而不是预测模型的谨慎。吉尔·萨维特是主持这个项目的美国大屠杀纪念馆的馆长;

“我们没有精确预测。这不是这个工具的目的,”Savitt 说。“我们正在做的是试图提醒政策制定者,这是一种恐怖发生的时机已经成熟的情况,并给他们一个警告,即可以采取行动来避免这种情况。”

类似的模型似乎在私营国防和安全部门略显模糊的水域中运行,它们的设计师显然不羞于预测它们的性能。例如,洛克希德·马丁公司宣传其综合危机预警系统(ICEWS)有 80%的准确率可以预测全球危机。这些“危机”实际上是什么的细节,或者如何测量准确性的任何意义都没有给出…

因此,看来我们的产品中确实存在一些有风险的假设,最值得注意的是,我们可以发现侵犯人权行为和社会经济指标之间的任何相关性,甚至可以预测人权表现随时间的变化。

探索有风险的假设和代码峰值的概念

我们的团队花了大量的时间来探索不同的方法,从描述到预测我们的数据,并在这个过程中消除了相当多的方法不起作用。这就是风险假设方法的本质:直接测试项目的核心假设,而不是从最简单/最少的元素开始,然后碰壁。正如一个描述所说,风险假设方法的关键是:

…快速、小型测试。为了检验你最大的假设,你能做的最小实验是什么?

当这些测试是以编写一些框架代码的形式来测试一个想法是否“有腿”,就像我们的情况一样,那么这个测试也可以被描述为一个尖峰。简而言之,尖峰是一个从极限编程(XP)产品开发学派中出现的术语。它被描述为一个开放式的,但理想情况下简短而集中的编码练习,旨在测试一个假设。换个说法;

“我们能编写的最简单的程序是什么,能让我们相信我们是在正确的轨道上?”⁴

回顾我们团队应对这一挑战的方式,识别风险假设的模型,结合使用尖峰来测试它们,是我们使用的直观方法。我们的团队分为四大任务,每个任务侧重于不同的假设和尖峰任务:

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

Risky Assumptions can be tested using Spikes

结果喜忧参半。我们找到了一个很好的方法来将结构化的文本转化为每个人权类别的“分数”,我们还找到了一个方法来将国家分组为不同类型的人权概况,我们至少开始探索社会经济变量在形成这些分组中的作用。预测,多少可以预见,是不可能的。

并列比较

在使用了 MVP 和最危险假设方法来描绘出产品是如何开发的之后,我们现在可以看看每种方法的结果,并反思其优缺点。

短期与长期风险

对我来说,一个收获是 MVP 方法似乎可以减轻短期风险,而处理风险最大的假设需要长远眼光。有了 MVP,你也许更有可能得到满足最少用户需求的东西。然而,你的路线图可能会掉下悬崖,因为你实际上试图做的事情——预测人权侵犯——最终可能无法实现。

管理速度

对于黑客马拉松来说,这是一个特别重要的问题,因为产品结果预计在几周之内就会出来。通常情况下,一个 MVP 将由一个复杂性和模糊性较低的用户故事组成,这样你就有更好的机会规划出需要多长时间。在精益方法中处理风险最大的假设本质上更具探索性,因此您需要更加积极地为每个代码峰值分配严格的时间余量。

功能膨胀

MVP 方法可以帮助你专注于一个单一的特性并抓住它。因为黑客马拉松是一场竞赛,所以我们不得不在我们最危险的假设中包含每个代码峰值的结果。因此,我们最终获得了大量的功能,展示了我们做了多少工作,但却淹没了微软的评委,以及潜在的未来用户。

感谢

非常感谢所有为我们的成功做出贡献的队友。请务必查看他们的个人资料:

普里西拉·艾迪森

泰勒·布莱儿

凯尔·切齐克

科林·迪特里希

斯蒂芬妮·李

玛丽·萨尔米

  1. https://news . Microsoft . com/features/technology-helps-un-advance-protection-human-rights-new-ways/
  2. https://hacker noon . com/the-MVP-is-dead-long-live-the-rat-233 D5 d 16 ab 02
  3. https://www . NPR . org/sections/goatsandsoda/2018/12/20/675582639/is-种族灭绝-可预测-研究者-说-绝对
  4. http://agiledictionary.com/209/spike/

通用机器学习工作流

原文:https://towardsdatascience.com/applying-the-universal-machine-learning-workflow-to-the-uci-mushroom-dataset-1939442d44e7?source=collection_archive---------12-----------------------

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

Photo by Phoenix Han on Unsplash

一个将弗朗索瓦·乔莱的通用机器学习工作流程应用于 UCI 蘑菇数据集

W e 将使用来自 UCI 的机器学习库蘑菇数据集来执行我们的演示。本书面向至少对 Python 基础有基本了解并有一些机器学习经验的读者。也就是说,我将为门外汉提供大量支持来源的链接,以便任何人都可以利用所提供的信息。

在我们开始之前,我想感谢我的 Lambdonian 同事 Ned H 对这篇文章的所有帮助。

通用机器学习工作流

  1. 定义问题并组装数据集
  2. 选择衡量成功的标准
  3. 决定评估协议
  4. 准备数据
  5. 开发一个比基线做得更好的模型
  6. 开发一个过度拟合的模型
  7. 正则化模型并调整其超参数

1.定义问题并组装数据集

简单地说,我们的问题是把蘑菇分为食用和有毒两类。我们得到了一个包含 23 个特征的数据集,其中包括蘑菇的类别(可食用或有毒)。

根据数据信息文件中列出的特性,我们可以为数据集创建一个列名列表。

column_names = ['class',
                'cap-shape',
                'cap-surface',
                'cap-color',
                'bruises?',
                'odor',
                'gill-attachment',
                'gill-spacing',
                'gill-size',
                'gill-color',
                'stalk-shape',
                'stalk-root',
                'stalk-surface-above-ring',
                'stalk-surface-below-ring',
                'stalk-color-above-ring',
                'stalk-color-below-ring',
                'veil-type',
                'veil-color',
                'ring-number',
                'ring-type',
                'spore-print-color',
                'population',
                'habitat']

让我们导入数据集,并从。数据文件使用[pd.read_csv()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html)

import pandas as pdurl = '[https://archive.ics.uci.edu/ml/machine-learning-databases/mushroom/agaricus-lepiota.data'](https://archive.ics.uci.edu/ml/machine-learning-databases/mushroom/agaricus-lepiota.data')mushrooms = pd.read_csv(url, header=None, names=column_names)

2.选择衡量成功的标准

鉴于我们问题的性质;分类蘑菇是否有毒,我们将使用精度作为我们成功的衡量标准。精度是分类器不将有毒蘑菇标记为可食用蘑菇的能力。我们宁愿人们丢弃我们的模型归类为有毒的可食用蘑菇,而不是食用我们的分类器标记为可食用的有毒蘑菇。

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

from sklearn.metrics import precision_score

3.决定评估协议

我们将使用 10 重交叉验证来评估我们的模型。虽然一个简单的拒绝验证集可能就足够了,但我怀疑它的可行性,因为我们有大约 8000 个样本。

from sklearn.model_selection import train_test_split, cross_validate

首先让我们把数据分成一个特征矩阵(X)和一个目标向量(y)。我们将使用[OneHotEncoder](http://contrib.scikit-learn.org/categorical-encoding/onehot.html)来编码我们的分类变量。

import category_encoders as ce#Drop target feature
X = mushrooms.drop(columns='class') #Encode categorical features
X = ce.OneHotEncoder(use_cat_names=True).fit_transform(X)

y = mushrooms['class'].replace({'p':0, 'e':1})print('Feature matrix size:',X.shape)
print('Target vector size:',len(y))____________________________________________________________________Feature matrix size: (8124, 117) Target vector size: 8124

接下来,我们将把数据分成训练集和测试集。

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42, test_size=.2, stratify=y)print('Training feature matrix size:',X_train.shape)
print('Training target vector size:',y_train.shape)
print('Test feature matrix size:',X_test.shape)
print('Test target vector size:',y_test.shape)____________________________________________________________________Training feature matrix size: (6499, 117) 
Training target vector size: (6499,) 
Test feature matrix size: (1625, 117) 
Test target vector size: (1625,)

4.准备数据

我们几乎准备好开始训练模型,但是首先我们应该探索我们的数据,熟悉它的特征,并格式化它,以便它可以输入到我们的模型中。

我们可以使用.dtypes().columns.shape来检查我们的数据集,但是 Pandas 提供了一个[.info](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.info.html)功能,允许我们在一个地方查看所有这些信息。

print(mushrooms.info())____________________________________________________________________<class 'pandas.core.frame.DataFrame'> 
RangeIndex: 8124 entries, 0 to 8123
Data columns (total 23 columns):
class                       8124 non-null object
cap-shape                   8124 non-null object 
cap-surface                 8124 non-null object 
cap-color                   8124 non-null object 
bruises?                    8124 non-null object 
odor                        8124 non-null object 
gill-attachment             8124 non-null object 
gill-spacing                8124 non-null object 
gill-size                   8124 non-null object 
gill-color                  8124 non-null object 
stalk-shape                 8124 non-null object 
stalk-root                  8124 non-null object 
stalk-surface-above-ring    8124 non-null object 
stalk-surface-below-ring    8124 non-null object 
stalk-color-above-ring      8124 non-null object 
stalk-color-below-ring      8124 non-null object 
veil-type                   8124 non-null object 
veil-color                  8124 non-null object 
ring-number                 8124 non-null object 
ring-type                   8124 non-null object 
spore-print-color           8124 non-null object 
population                  8124 non-null object 
habitat                     8124 non-null object 
dtypes: object(23) memory usage: 1.4+ MB None

另一个有用的步骤是检查空值的数量以及它们在数据帧中的位置

print(mushrooms.isna().sum())____________________________________________________________________class                       0 
cap-shape                   0 
cap-surface                 0 
cap-color                   0 
bruises?                    0 
odor                        0 
gill-attachment             0 
gill-spacing                0 
gill-size                   0 
gill-color                  0 
stalk-shape                 0 
stalk-root                  0 
stalk-surface-above-ring    0 
stalk-surface-below-ring    0 
stalk-color-above-ring      0 
stalk-color-below-ring      0 
veil-type                   0 
veil-color                  0 
ring-number                 0 
ring-type                   0 
spore-print-color           0 
population                  0 
habitat                     0 
dtype: int64

一个也没有……这似乎好得令人难以置信。

由于我们勤奋好学,阅读了数据集信息文件。我们知道所有缺失的值都标有问号。一旦清楚了这一点,我们就可以使用[df.replace()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.replace.html)来转换?敬 NaNs。

import numpy as np
mushrooms = mushrooms.replace({'?':np.NaN})
print(mushrooms.isna().sum())
____________________________________________________________________class                       0 
cap-shape                   0 
cap-surface                 0 
cap-color                   0 
bruises?                    0 
odor                        0 
gill-attachment             0 
gill-spacing                0 
gill-size                   0 
gill-color                  0 
stalk-shape                 0 
stalk-root               2480
stalk-surface-above-ring    0 
stalk-surface-below-ring    0 
stalk-color-above-ring      0 
stalk-color-below-ring      0 
veil-type                   0 
veil-color                  0 
ring-number                 0 
ring-type                   0 
spore-print-color           0 
population                  0 
habitat                     0 
dtype: int64

我们到了,stalk_root有 2480 个空白特征,让我们用m替换它们。

mushrooms['stalk-root'] = mushrooms['stalk-root'].replace(np.NaN,'m')print(mushrooms['stalk-root'].value_counts())____________________________________________________________________b    3776 
m    2480 
e    1120 
c     556 
r     192 
Name: stalk-root, dtype: int64

5.开发一个比基线做得更好的模型

基线模型

使用我们数据集中最常见的标签,我们将创建一个我们希望击败的基线模型。

首先让我们看看如何使用[df.value_counts()](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.value_counts.html)来分配类

mushrooms['class'].value_counts(normalize=True)____________________________________________________________________e    0.517971 
p    0.482029 
Name: class, dtype: float64

我们将使用 class 属性的模式来创建基线预测。

majority_class = y_train.mode()[0]baseline_predictions = [majority_class] * len(y_train)

让我们看看我们的基线模型有多精确。

from sklearn.metrics import accuracy_scoremajority_class_accuracy = accuracy_score(baseline_predictions,
                                         y_train)print(majority_class_accuracy)____________________________________________________________________ 0.5179258347438067

约 52%…这是给定初始数据集中类的分布后我们所期望的。

决策树

我们将尝试用决策树来拟合我们的训练数据,并产生大于 52%的准确率分数。

from sklearn.tree import DecisionTreeClassifier
import graphviz
from sklearn.tree import export_graphviztree = DecisionTreeClassifier(max_depth=1)# Fit the model
tree.fit(X_train, y_train)# Visualize the tree
dot_data = export_graphviz(tree, out_file=None, feature_names=X_train.columns, class_names=['Poisonous', 'Edible'], filled=True, impurity=False, proportion=True)graphviz.Source(dot_data)

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

现在,我们已经将决策树与我们的数据相匹配,我们可以通过查看分类器的预测概率分布来分析我们的模型。简单来说,预测概率表示模型对其分类标签的确信程度。

除了预测概率,我们还会看我们决策树的精度得分。Sklearn 为我们提供了一个简单的方法,用[classification_report](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.classification_report.html)看到分类模型的很多相关分数。

我们还将使用 sklearn 的[confusion_matrix](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.confusion_matrix.html)生成混淆矩阵。混淆矩阵显示了真假阳性和阴性的数量。

因为我们将再次使用这些工具,所以我们将编写一个函数来运行我们的模型分析。

import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics import classification_report, confusion_matrixdef model_analysis(model, train_X, train_y):
  model_probabilities = model.predict_proba(train_X) Model_Prediction_Probability = [] for _ in range(len(train_X)):
      x = max(model_probabilities[_])
      Model_Prediction_Probability.append(x) plt.figure(figsize=(15,10)) 

  sns.distplot(Model_Prediction_Probability) plt.title('Best Model Prediction Probabilities') # Set x and y ticks
  plt.xticks(color='gray') #plt.xlim(.5,1)
  plt.yticks(color='gray') # Create axes object with plt. get current axes
  ax = plt.gca() # Set grid lines
  ax.grid(b=True, which='major', axis='y', color='black', alpha=.2) # Set facecolor
  ax.set_facecolor('white') # Remove box
  ax.spines['top'].set_visible(False)
  ax.spines['right'].set_visible(False)
  ax.spines['bottom'].set_visible(False)
  ax.spines['left'].set_visible(False)
  ax.tick_params(color='white') plt.show();

  model_predictions = model.predict(train_X) # Classification Report
  print('\n\n', classification_report(train_y, model_predictions, target_names=['0-Poisonous', '1-Edible'])) # Confusion Matrix
  con_matrix = pd.DataFrame(confusion_matrix(train_y, model_predictions), columns=['Predicted Poison', 'Predicted Edible'], index=['Actual Poison', 'Actual Edible'])

  plt.figure(figsize=(15,10)) sns.heatmap(data=con_matrix, cmap='cool'); plt.title('Model Confusion Matrix')
  plt.show();

  return con_matrix

现在将这个函数应用到我们的决策树中。

model_analysis(tree, X_train, y_train)

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

我们将把我们的预测存储为一个tree_predictions变量,用于解释我们模型的准确性。

tree_predictions = tree.predict(X_train)accuracy_score(y_train, tree_predictions)____________________________________________________________________0.8862901984920757

88%的准确率已经不错了,但是让我们进入工作流程的下一步。

6.开发一个过度拟合的模型

我们将使用[RandomForestClassifier](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html)作为我们的过度拟合模型。

from sklearn.ensemble import RandomForestClassifierrandom_forest = RandomForestClassifier(n_estimators=100, max_depth=5)cv = cross_validate(estimator = random_forest, X = X_train, y = y_train, scoring='accuracy', n_jobs=-1, cv=10, verbose=10, return_train_score=True)____________________________________________________________________ [Parallel(n_jobs=-1)]: Using backend LokyBackend with 2 concurrent workers.[Parallel(n_jobs=-1)]: Done   1 tasks      | elapsed:    2.6s [Parallel(n_jobs=-1)]: Done   4 tasks      | elapsed:    3.2s [Parallel(n_jobs=-1)]: Done  10 out of  10 | elapsed:    4.7s finished

现在我们可以看到我们的随机森林的准确性得分。

random_forest.fit(X_test, y_test)
test_predictions = random_forest.predict(X_train)accuracy_score(y_train, test_predictions)____________________________________________________________________ 0.9924603785197723

99%的准确率对我来说太过了。

我们可以使用前面的model_analysis函数来分析我们的模型。

model_analysis(random_forest, X_train, y_train)

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

7.正则化模型并调整其超参数

现在,我们将调整RandomForestClassifier的超参数,并尝试在欠拟合和过拟合之间游走。我们可以使用 sklearn 的[RandmoizedSearchCV](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.RandomizedSearchCV.html)在我们的param_distributions字典中搜索超参数。

from sklearn.model_selection import RandomizedSearchCVparam_distributions = {
    'max_depth':[1, 2, 3, 4, 5],
    'n_estimators': [10, 25, 50, 100, 150, 200]}search = RandomizedSearchCV(estimator = RandomForestClassifier(), param_distributions = param_distributions, n_iter=100, scoring='precision', n_jobs=-1, cv=10, verbose=10, return_train_score=True)

search.fit(X_train, y_train)

我们可以用search.best_estimator_来看看哪个模型的精度得分最高。

best_model = search.best_estimator_
best_model____________________________________________________________________RandomForestClassifier
(bootstrap=True, class_weight=None, criterion='gini', max_depth=5, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=2,             min_weight_fraction_leaf=0.0, n_estimators=10, n_jobs=None,             oob_score=False, random_state=None, verbose=0,             warm_start=False)

从模型描述中我们可以看到,具有 5 和 10 个估计量的max_depthRandomForestClassifier是我们的最优模型。现在我们可以运行我们的分析功能。

model_analysis(best_model, X_test, y_test)

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

3 次误报,不完美,但相当不错。

结论

重申我们的工作流程。

  1. 定义问题并组装数据集
  2. 选择衡量成功的标准
  3. 决定评估协议
  4. 准备数据
  5. 开发一个比基线做得更好的模型
  6. 开发一个过度拟合的模型
  7. 正则化模型并调整其超参数

虽然 Chollet 将其描述为通用的机器学习工作流,但根据我们试图解决的具体问题,存在无限的变化。不过一般来说,你总是从定义你的问题和收集数据开始,(无论是从预先准备好的数据集还是自己收集的数据)。

我希望这篇文章展示了 Chollet 的通用机器学习工作流程的详细介绍。

感谢阅读!

在 T witterGitHubLinkedIn 上关注我

附:这是我在这篇文章中使用的 Colab 笔记本的链接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值