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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

检测在线社交网络中的可疑账户

原文:https://towardsdatascience.com/detecting-suspicious-accounts-in-online-social-networks-48eabf4c75b6?source=collection_archive---------38-----------------------

基于特征的分类方法

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

图片来源:www.bluecoat.com/

近年来,社交媒体的覆盖范围和受欢迎程度大幅上升。许多社交媒体平台拥有数百万用户。就像他们说的,好的会带来坏的。除了吸引真正的订户,在线社交网络也吸引了不良行为者的注意。僵尸程序和恶意账户占据了用户群的很大一部分。幸运的是,就像真实用户一样,虚假用户也会在数据中留下痕迹,从而能够检测到这些不需要的和潜在危险的帐户。

在这篇文章中,我描述了不同的虚假用户场景,以及如何使用基于特征的分类技术来检测这些用户,正如研究论文中所解释的那样。

检测个人虚假账户

一般来说,人类的行为与假账户或机器人账户不同。如果这种行为差异可以在数字或分类属性中捕捉到,那么机器学习技术就可以应用于检测真假。这是检测恶意账户的基于特征的分类方法的本质。

在账户层面检测真实或虚假状态的洗钱过程有 3 个组成部分。

  1. 功能设计

网络中的单个用户和用户组可以用两类特征来描述:

  • 注册时或注册前后出现的属性-个人资料特征
  • 随着时间发展的属性——与网络中其他用户的联系、活动或行为模式

根据检测假冒用户的时间敏感性,设计的功能可能来自上述一个或两个类别。如果限制虚假用户与真实用户的交互是至关重要的,那么仅使用简档特征的方法是有用的。

研究和调查有助于通过增加用户了解来更好地进行功能设计。

2.功能选择

在 OSN(在线社交网络)中,可能有大量属性与一个账户相关联——使用所有这些特征可能会变得计算量很大。在一些特征中可能存在冗余,或者一些特征可能不是用户状态的良好预测器。

特性选择解决了其中的一些问题。包装器和过滤器方法通常用于包括最佳预测器。为每个属性分配一个权重,所选择的属性是那些权重高于某个阈值的属性。

3.模型训练和评估

在分类任务中表现良好的一些算法——随机森林、决策树、支持向量机、朴素贝叶斯和神经网络。从特征选择步骤确定的加权属性可以应用于这些算法。常用的指标有精度、召回率和 F 值。

表演

对于所使用的数据集,考虑到 F-score 和精度,随机森林算法表现良好。随着权重的增加,其他算法也开始表现得更好。当使用权重高于 50%的特征时,考虑到精度,SVM 给出了最好的预测,而朴素贝叶斯在 F 分数度量中表现最好。

检测由同一代理创建的虚假账户群

在大规模的 OSN 中,一个坏演员可以创建几十到几千个恶意账户。像大多数虚假用户检测技术一样,对每个账户进行预测,可能不具有可扩展性或效率。在这种情况下,集群级检测是合乎需要的。

合法用户群显示出档案模式的多样性,而由单个参与者创建的虚假账户群显示出相似的属性分布和频率。因此,描述整个聚类的工程特征允许检测虚假账户的聚类。

预测每个用户的状态和一个组的状态的方法之间的主要区别是特征的级别——个体或集群。

接下来描述在集群上操作的基于分类的机器学习流水线。有 3 个主要组件。

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

群集检测 ML 管道

  1. 聚类生成器

该组件获取帐户的原始列表,并构建帐户聚类及其原始特征。该模块有 3 个用户指定的参数 a)最小和最大集群大小 b)注册账户的时间跨度(例如,过去 24 小时),以及 c)集群标准(例如,注册 IP 地址)。

该组件的输出是一个帐户表,其中每一行代表一个帐户,并包含用户名、组织、教育和帐户集群特有的集群标识符等特性。

集群生成器还使用个人帐户的假或真状态来将集群标记为假或真。阈值“x”决定分类标签—分类中的虚假帐户少于 x %,则它是真正的分类。

2.个人资料特征化

该模块将每个聚类的原始数据转换成代表该聚类的单个数字向量。它被实现为一组从原始特征中提取信息的函数。这些特征可以是

a)基本分布特征——每列的统计测量。数值特征的平均值或四分位数,类别特征的唯一值的数量

b)模式特征—将用户生成的文本映射到分类空间(例如电子邮件地址中的模式)

c)频率特征——每个特征值在所有单个账户中的频率,以及它们在这些频率上的分布。合法帐户的群集有一些高频率和一些低频率的数据,然而,恶意帐户的群集在它们的数据频率上显示较少的变化。

3.账户计分器

第三个组成部分是训练模型,并根据以前未见过的数据评估它们的性能。该模块可以在训练模式或*评估模式下运行。*输出为模型描述和评估指标(训练模式)或聚类得分(评估模式),即由虚假账户组成的聚类的可能性。

绩效和评估指标

考虑的回归方法 1)具有 L1 正则化的逻辑回归 2)具有径向基函数核的支持向量机 3)随机森林

当考虑由 AUC 和 95%精度的召回测量的预测性能时,随机森林表现最佳。采用 RBF 核的 SVM 在 AUC 值方面也有不错的表现,但是它的召回@p95 不如 random forest。逻辑回归的性能最差,因为它是线性分类器,不能很好地模拟模式中的非线性。

基于特征的分类方法的考虑

用户行为模式很少是固定不变的,它们会随着时间的推移而发生变化,通常是对应用程序内外因素的反应。攻击者也一样!他们修改自己的内容和活动模式,以逃避检测。基于特征的技术易受此影响,必须定期进行多样化以跟上变化的模式。

使用分类器时,高维(非常大量的特征)数据可能导致计算成本增加。这可以通过使用降维或特征子集选择等特征降维技术来缓解。

结论

基于特征的分类方法是检测机器人和其他恶意用户的常用方法。它可以很好地扩展到大型 osn,并提供良好的性能。基于图形的技术也常用于检测虚假用户,但是基于特征的方法和简档属性允许早期检测。有许多分类算法可以迭代和调整性能。像 SVM 神经网络这样的组合可以进一步改善预测。总的来说,基于特征的分类提供了一个多样化的工具箱,可以调整并应用于多种情况。

[1]:埃拉扎布,艾哈迈德&马哈茂德,马哈茂德&赫夫尼,希沙姆。(2016).基于最小加权特征集的 Twitter 虚假账户检测。《国际计算机、电气、自动化、控制与信息工程杂志》2016 年第 10 卷第 1 期。

[3]:哈立德、萨拉&埃尔-塔齐、尼亚马特&莫赫塔尔、霍达。(2018).检测社交媒体上的虚假账号。3672–3681.10.1109/bigdata . 18666 . 186686866616

检测异常数据:共形异常检测

原文:https://towardsdatascience.com/detecting-weird-data-conformal-anomaly-detection-20afb36c7bcd?source=collection_archive---------31-----------------------

共形预测和共形异常检测框架介绍(附代码)

怪异的数据很重要。通常在数据科学中,目标是发现数据的趋势。然而,考虑医生查看肿瘤图像、银行监控信用卡活动或使用摄像头反馈的无人驾驶汽车,在这些情况下,知道数据是否怪异或异常可能更重要。怪异数据更正式地称为异常,并且在数学上可以被认为是从用于生成训练数据的分布的尾端生成的数据。通俗地说,我们的模型没有准备好处理这些奇怪的数据,因为它从未被训练过这样做,导致模型错误地对待这些数据。最终结果是——医生可能看不到恶性肿瘤,欺诈性的信用卡活动可能不会被发现,无人驾驶汽车可能会做出错误的决定。接下来的挑战是检测和消除这些异常。

为了举例说明这一点,让我们考虑图 2**中显示的简单二维数据。**其中每个圆圈代表训练数据,并根据 10 个可能的类别进行着色。黑色十字是在 2D 平面上均匀随机生成的测试数据,其标签目前未知。一个模型如何知道哪些测试数据点应该被标记为异常并被丢弃,以及哪些可以被准确地分类?一种方法是使用聚类算法,并忽略距离每个聚类质心超过预定义异常阈值的新数据;然而,设置这些阈值需要微调,并经常导致许多假阳性异常检测[1]。相反,我们更喜欢一种超参数少且易于解释的方法,这种方法独立于数据集和手头的任务。

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

**图一。**上面的数据是随机构建的,用来说明训练数据(标记=圆圈)和测试数据(标记=十字)。在这个场景中,异常检测器的目标是将每个测试数据点分类为异常或不异常。

本文将描述一种相对新的、有效的、可扩展的方法,通过称为共形异常检测(CAD) 的过程来检测异常数据,该过程构建在共形预测(CP) 框架上。CP 适用于任何监督任务,其中每个数据由一个输入-输出对表示;然而,我们不需要测试输入的标签来确定它是否异常。此外,CP 和 CAD 具有与几乎任何算法家族(神经网络、SVM、决策树等)一起工作的优势。)和任何类型的任务(回归或分类)。CP 框架也有很好的统计解释,并且只有一个超参数,这使得它可以扩展到各种情况。除了介绍基本理论之外,本文还提供了执行 CAD 的代码。链接可以在下面的*【资源】* 中找到。对于 CP/CAD 的正式数学定义,我推荐查阅[1]。

这篇文章涵盖了什么

  1. 共形预测(CP)框架
  2. 共形异常检测(CAD)
  3. 从这里去哪里

资源

  1. Google Colab 笔记本: 一个简单的 CAD 实现

第一节。保形预测

通常,回归或分类模型在给定输入的情况下预测单个输出,回归模型返回连续输出,而分类模型返回离散输出。乍一看,这似乎很奇怪,但是 CP 框架返回的不是单个值,而是一组看似合理的输出。例如,对于回归,输出是潜在值的范围,而对于分类,输出是所有可能标签的子集。您可能想知道这有什么用——我们不是对输出更不确定了吗?实际上,通过一些基本的假设,我们可以验证我们的测试输入的真实输出将落在预测的一组可信输出中,并具有预期的置信度。使用这个 CP 框架作为异常检测机制的基础,我们可以确定地确信是否将新的测试输入标记为异常。

那么做一个 CP 框架需要什么呢?该框架只需要三个特定的要素:一个训练数据集、一个显著性水平(ϵ)和一个为我们的每个输入产生不一致分数的不一致度量。我们将在简单分类示例的上下文中逐一查看这些组件。

成分 1:训练数据集

在监督任务中,训练数据只是输入-输出对,其中输入通常表示为具有 m 样本和 n 自变量或特征的 m x n 矩阵,输出通常表示为具有 m 样本和 d 因变量的 m x d 矩阵。我们的训练数据集由 250 个输入-输出对组成,每个输入有 2 个特征,每个标签都是集合{0,…,9}的成员。训练数据平均分布在 10 个类中,每个类有 25 个数据点。很简单。

成分 2:显著水平ϵ

显著性水平与统计显著性有直接的相似性,统计显著性通常被用作实验中确定是否拒绝零假设的阈值。为了理解 CP 框架上下文中的显著性水平,让我们首先考虑它是如何使用的。记住,CP 框架计算一组潜在的标签,而不是为一个新的测试输入产生一个单一的输出预测。假设训练数据和测试数据是独立且同分布 (I.I.D .),错误概率或我们测试数据的真实标签不在那组潜在标签中的概率等于显著性水平。因此,显著性水平允许我们将预测集解释为置信区间。这就是我们(1-ϵ)%确信,给定我们的独立同分位数的假设,真正的标签在我们预测的集合中)

如果你仔细观察,你可能会注意到在图 1 中。违反了测试数据和训练数据之间的 I.I.D 假设。然而,这个例子是用来说明不管这个假设如何,CP 仍然可以用来检测异常(尽管统计保证消失)。在现实生活中,假设测试数据和训练数据之间的 I.I.D .很少是准确的;然而,这种假设也很少被违反。提到 I.I.D .假设的要点是,它允许对我们的预测集进行统计保证。实际上,使用可交换性鞅[5]在线测试 I.I.D 假设是可能的,可交换性鞅[5]接受一系列 p 值而不是单个 p 值,并且仅由于一系列小 p 值而增长,这意味着大量奇怪的输入同时进入。如果测试分布与训练分布相同,这显然是不常见的。鞅可用于拒绝可交换性假设(也是 I.I.D .假设),并检测出大于某个阈值的异常[4]。

成分 3:不合格度量(NCM)和不合格分数(α)

不一致测量(NCM)是我们测量陌生感的方式。理论上,NCM 可以是给每个输入分配不符合分数 α 的任何实值函数。这甚至可以是一个简单地返回随机不符合分数的函数;然而,我们倾向于根据其效率来评估 NCM,即其返回小的、有区别的预测集的能力。当给定新的输入时,随机 NCM 可能会返回无信息的预测集。相反,我们更希望 NCM 能够有意义地测量物体之间的相似性和不相似性。

NCM 通过计算一个值来计算不合规分数,该值考虑了相对于其他输入子集的特定输入。该子集可以包括其余的训练数据和测试输入(即,除了所考虑的输入之外的一切)。我们将较大的不合规分数解释为更奇怪,即更有可能是异常。

可能的 NCM 的一个例子是 k-最近邻函数,它计算输入的 k-最近邻的平均距离(例如欧几里德距离)。例如,如果输入 1 到类 0 的 5 个最近邻的平均距离是 25,而输入 2 到类 0 的 5 个最近邻的平均距离是 100,我们会认为输入 2 比输入 1 对类 0 更陌生。通常,流行的 NCM 是到同一类中的 k 个最近邻居的平均距离与到不同类中的 k 个最近邻居的平均距离的比率,从而捕获类内和类间的相似性和不相似性。

计算 P 值

一旦选择了合适的 NCM,CP 框架就可以用于预测新测试输入的一组潜在标签。为此,CP 框架为每个可能的标签计算 p 值。p 值是具有至少与测试输入一样大的不符合性度量的训练输入的归一化比例。情商。1 显示了如何计算单个 p 值。

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

方程式 1 。对于每个可能的标签(k=10),计算所有可能输入(n=250)和测试输入的不合格分数,并使用这些分数计算 p 值。在这个例子中,我们将得到 10 个 p 值。

最后,如果对应于每个 p 值的标签的 p 值大于或等于指定的显著性水平,则该标签被包括在预测集中。换句话说 根据我们的共形分数【1】,如果我们的训练集的重要部分比我们的测试输入更陌生,则标签被添加到我们的预测集。

共形预测的一些有用和无用的性质

已经提到的有用的性质是 CP 产生一个我们所处的置信区间(1-ϵ)%确信真正的标签存在于我们预测的集合中。另一个有用的属性是 CP 框架在 I.I.D 假设下校准良好,这意味着即使训练集用测试输入更新(即测试输入的真实标签被确定)并且收集了新的测试输入,这两个预测集的误差也将是独立的。因此,给定足够的测试输入,我们的错误率将接近ϵ.如果我们的训练数据足够大,并且 I.I.D .是真实的,大数定律告诉我们,真实的错误率可能已经被ϵ.精确地估计出来了

CP 框架的一个明显的缺点是,它必须为每个新的测试输入重新计算保形分数,这可能是耗时的,尤其是如果我们的不符合性度量是复杂的。一种解决方法是使用归纳保形预测(ICP)框架,该框架使用单独的训练集(称为校准数据集),不需要对每个新输入进行重新计算,对于大型数据集更实用。

第二节。共形异常检测(CAD)

共形异常检测(CAD)建立在 CP 框架上,可用于执行异常检测。如果您遵循了上一节的内容,CAD 应该很容易理解。我们来看算法。

共形异常检测(CAD)算法

*输入/输出:*CAD 算法的输入是显著性水平ϵ和一组输入,包括训练集和新的测试输入。输出是一个布尔变量,指示测试输入是否异常。

  1. NCM 为每个输入分配一个非一致性分数,该非一致性分数是该输入与其余输入之间相似性的度量。
  2. CAD 为我们的测试输入计算一个 p 值,它是大于或等于我们的测试输入( Eq)的不合格分数的数量的标准化比例。2 )。
  3. 如果计算的 p 值小于我们的显著性水平ϵ.,则测试输入被标记为异常换句话说,如果一个输入比我们训练集的一个重要部分更奇怪,那么它就被标记为异常。

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

****方程式 2。计算 CAD 的 p 值。

情商。2Eq 来说应该很熟悉。1 用于计算 CP 框架的 p 值。CP 中的 p 值和 CAD 中的 p 值之间的主要区别在于,CP 生成一组 p 值,每个 p 值对应一个可能的标签,而 CAD 只为每个测试输入提供一个 p 值。

回到例子

让我们回顾一下之前的分类示例。让我们假设ϵ为 0.025,并考虑我们的训练数据集有 250 个输入输出对。让我们选择其中一个黑叉作为新的测试输入。我们可以使用 10 个最近的邻居为 251 个输入中的每一个分配一个不符合分数。为此,我们可以计算一个 251 x 251 距离矩阵,并对行进行排序,使得最近的距离在第一列(该距离矩阵的第一列被忽略,因为它将始终为 0,因为欧几里德度量总是产生非负值,并且当两个输入相同时为 0)。然后,我们通过计算距离矩阵每一行中接下来的 10 个元素的平均值,来计算一个大小为 251 x 1 的不合格分数数组。然后,我们对这个平均 k-最近邻数组中的元素大于我们的测试输入的不一致性分数的次数进行求和。接下来,通过将总和除以 251 来计算我们的归一化 p 值。最后,如果 p 值小于 0.025,则测试输入被视为异常。

****图二。显示了使用具有该特定参数化的 CAD 来确定我们的假测试数据是否异常的结果。根据 CAD,红叉被视为异常,蓝叉被视为有效输入。

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

****图二。CAD 算法发现 21/25 的假输入被认为是异常——那些被标记为符合(非异常)的输入是直观的。

幸运的是,我们可以看到图 2** 中的结果。有道理。CAD 倾向于将所有远离类簇的测试输入标记为异常,而将所有位于类簇中的测试输入标记为有效测试数据。对于更高维的数据,尽管我们不能在不执行降维的情况下可视化结果,但是同样的原理也适用。**

CAD 的有用属性

CAD 优于典型异常检测技术的原因有很多。与许多异常检测技术不同,CAD 只有一个阈值超参数ϵ,它代表统计显著性水平,而不是异常阈值。在实践中,指定置信度阈值而不是异常阈值减少了执行异常检测所需的假阳性和微调的数量。其次,CAD 可以被解释为一个零假设测试,其中ϵ控制异常检测器的灵敏度。也就是说,如果我们可以合理地假设训练输入和测试输入是同分布的,那么ϵ就是应该拒绝零假设的比率,即期望 CAD 将随机生成的测试输入标记为异常的比率。这在实践中很有用,因为对于安全相关的任务,如信用卡欺诈检测或自动驾驶应用,我们可以增加ϵ以提高 CAD 的灵敏度。因为它是建立在 CP 框架上的,所以当不能假定 I.I.D .时,同样的限制也适用。在这种情况下,鞅可以用来测试独立同分布,并从 p 值序列中确定异常[5]。

第三节。从这里去哪里

希望您发现这次讨论内容丰富且有趣。如果您想了解更多,有几篇研究论文继续研究异常检测中使用的 CP 框架。已经提到的是比 CP 框架更有效的非正式共形预测(ICP)框架。但是,ICP 的一个缺点是,它可能无法生成与 CP 一样准确的预测集,并且它需要将训练数据分成校准和训练数据集,如果数据有限,这可能会很困难。一篇解释使用 CP 和 ICP 框架进行异常检测的论文可以在这里 [1]找到。此外,虽然我没有真正深入研究,但对于高维数据,通常使用一个模型来产生共形分数,如这篇使用神经网络产生共形分数的[论文](http://Papadopoulos, Harris, Volodya Vovk, and Alex Gammermam. “Conformal prediction with neural networks.” 19th IEEE International Conference on Tools with Artificial Intelligence (ICTAI 2007). Vol. 2. IEEE, 2007.)或这篇在医疗诊断背景下使用随机森林的论文【3】。这就是为什么保形预测如此有用的一个原因——只要你能提取有意义的不合规分数,它就可以与任何类型的模型一起使用。

我的母校范德比尔特大学写的另一篇伟大的论文对变分自动编码器(VAE)的潜在空间进行了采样,不仅为给定的测试输入提供了一个 p 值,还提供了几个用于鞅测试的 p 值[4]。我强烈建议你去看看那本书,因为它也对 CP/ICP 做了很好的、简洁的解释。

感谢您的阅读!像往常一样,对于任何问题或顾虑,请随时在下面留下评论。我所有文章的目标都是帮助人们理解和使用这项技术,所以我很乐意帮忙。干杯!

引文

[1]拉克萨马尔、里卡德和约兰·福尔克曼。"感应共形异常探测用于异常子轨迹的连续探测."数学与人工智能年鉴74.1–2(2015):67–94。

2帕帕多普洛斯、哈里斯、沃洛佳·沃夫克和亚历克斯·甘默尔曼。"用神经网络进行保形预测."第 19 届 IEEE 人工智能工具国际会议(ICTAI 2007 年)。第二卷。IEEE,2007 年。

[3] Devetyarov 和 I. Nouretdinov。"基于医学诊断的随机森林分类器学习的可靠预测."第六届 IFIP 工作组会议记录。第 12 卷。

[4]蔡、和谢诺丰·库特苏科斯。"学习型信息物理系统中的实时非分布检测."arXiv 预印本 arXiv:2001.10494 (2020)。

[5] Fedorova,Valentina 等,“在线测试可交换性的插件鞅” arXiv 预印本 arXiv:1204.3251 (2012)。

利用多普勒雷达径向速度探测风切变

原文:https://towardsdatascience.com/detecting-wind-shear-using-radial-velocity-of-doppler-radar-e10e4ae440?source=collection_archive---------45-----------------------

推导公式,选择最佳有限差分和源代码

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

照片由 Kelvin YanUnsplash 上拍摄

风切变是速度和/或方向突然改变的风。我在之前的 帖子 中已经讨论了很多关于风切变的内容。能够探测风切变的众多工具之一是多普勒雷达。多普勒雷达利用多普勒效应来计算周围的风。但是我们将得到的只是一个径向速度(标量,远离将导致< 0 值,而另一方面对于靠近的风将具有> 0 速度),而不是作为笛卡尔矢量的风(南北、东西和上下分量)。通常的风切变公式是矢量运算。那么我们如何使用雷达来探测或计算风切变呢?我们将在这里讨论它。我们将使用众多风切变雷达产品之一,HSHEAR

**HSHEAR** 产品

遗憾的是我们无法获得实际的风矢量,但我们仍然可以通过径向速度监测风的变化来检测风切变。风切变的本质是变化,记住。当我们说“风的变化”时,我们指的是空间的变化。

在数学中,如何表达空间的变化?它是

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

或者“状态”的梯度(在每一维度)。我们所说的水平剪切(HSHEAR)乘积的量纲当然是水平量纲(南北和东西),而“状态”是径向速度(Vr),所以方程变成

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

现在我们得到了每个维度的变化。我们想知道的是变化的幅度或者说风的变化有多大。很简单,就是向量的长度。

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

单位向量可以被抵消,因为我们平方了它。所以更简单的形式是

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

由此我们得到了许多风切变雷达产品的公式HSHEAR,1。

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

数值解

基本上,我们都知道,计算机甚至不能解决最基本的微分方程。所以我们必须把我们的HSHEAR公式转换成数字形式。最简单的方法是使用有限差分。有 3 种有限差分:

前进差

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

向后差异

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

中枢差异

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

其中i是维度中f(状态)的指标数据,h是维度的分辨率。想象我们有网格形式的f

**我们会选择什么?当然是误差最小的公式。而且是中央差!**为什么?所以基本上,你可以从泰勒级数得到所有的有限差分,截断误差最小的是中心差分。证明?就当练习自己试试吧。我不会在这里详细说明,因为会有相当多的方程弹出。

让我们用中心差分代替之前HSHEAR公式中的所有微分方程。

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

这里ij分别是 x 和 y 维度上的索引。hxhyx(东西)和y(南北)维度的分辨率。

源代码

事实上,如果你不在乎这是如何运作的,你可以跳过所有的解释,只看这一部分。是的,最重要的部分,给我看看代码!基于我们的数值解,这里是代码

关于示例数据,您可以在这里下载

上面这个脚本的结果会是这样的。

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

在上面的图中,通常没有风切变发生。你可以看到这个情节从无到有,逐渐变成一个点,然后看起来像一个甜甜圈。这是雷达扫描方案的效果。这就是我们在雷达数据中所说的“沉默锥”。我想(如果我有心情的话)我们会讨论天气雷达是如何工作的。就目前而言,这就足够了。

所有关于雷达的代码和资料,包括我们以前的代码和数据,都可以在我的 GitHub 知识库这里访问。再见!

使用 CNN 和类激活图从胸部 X 射线扫描检测新冠肺炎存在的尝试

原文:https://towardsdatascience.com/detection-of-covid-19-presence-from-chest-x-ray-scans-using-cnn-class-activation-maps-c1ab0d7c294b?source=collection_archive---------12-----------------------

作者:Souradip Chakraborty

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

图 1:冠状病毒病 2019, 来源

冠状病毒病 2019 ( 新冠肺炎)是由严重急性呼吸综合征冠状病毒 2 引起的高度传染性疾病。这种疾病于 2019 年 12 月首次起源于中国武汉,自那以来,它已经在全球范围内传播,影响了超过 200 个国家。影响如此之大,以至于 T21 世界卫生组织(世卫组织)宣布正在进行的新冠肺炎疫情为国际关注的突发公共卫生事件

截至 2020 年 4 月 1 日的日,全球超过 200 个国家共有 873,767 例确诊病例,其中 645,708 例活跃病例, 43,288 例死亡病例(来源: 维基百科 )。

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

图 2:冠状病毒(新冠肺炎)地图。 来源

各国政府正在努力关闭边境,实施接触者追踪,识别和接纳受影响者,隔离可能的病例,但在大多数国家,受病毒影响的人数呈指数增长,不幸的是,预计在大量临床试验后开发和应用药物/疫苗之前,这一数字还会增加。

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

图 3a:冠状病毒在几个国家的传播速度。 来源

虽然研究表明,社会距离可以显著减少传播和平坦的曲线,如图 3a 所示,但这是可持续的吗?好吧,我把答案留给你们大家。

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

图 3b:社会距离对冠状病毒传播的影响。 来源

因此,在这种特殊的情况下,需要做的一件主要事情是多重测试,并且大多数国家已经开始这样做,这样才能了解真实情况并做出适当的决定。

但我们可以理解,这些测试非常关键,应该绝对精确地进行,这肯定需要时间。这可能非常危险,因为如果被感染的人没有及时被隔离,他们会感染其他人,这可能导致指数增长,如图 3b 。特别是在像印度这样人口密度极高的国家,这可能是造成灾难的原因。

标准的新冠肺炎测试被称为 PCR(聚合酶链式反应) 测试,用于寻找特定感染的抗体的存在。但是这个测试有一些问题。 病原实验室检测 是诊断的金标准,但费时且假阴性结果显著,如本文 论文 所述。

此外,*的 大规模实施 新冠肺炎测试对于许多发展中的&不发达国家来说是负担不起的,因此,如果我们能够使用 人工智能&机器学习 *并利用历史数据来进行一些并行的诊断/测试程序,将会非常有帮助。这也有助于在过程中选择主要测试的项目。

迫切需要快速准确的诊断方法来对抗这种疾病。在最近由王帅等人发表的论文“ 中,一种深度学习算法使用 CT 图像来筛选冠状病毒疾病(新冠肺炎) ”。al 他们已经使用深度学习计算机断层扫描(图像)中提取新冠肺炎的图形特征,以便在病原测试之前提供临床诊断,从而为疾病控制节省关键时间。

这项研究利用初始卷积神经网络(CNN)对1119 次 CT 扫描进行迁移学习。模型的内部和外部验证精度分别记录在 89.5%79.3%

在我的实验中,我进行了类似的分析,但是是在胸部 X 射线图像上,主要原因是对人们来说,获得 CXRs(T21)比获得 CT 扫描更容易,特别是在农村和偏远地区。还会有更多的潜在数据可用。

现在来看看我用过的数据集。于是,约瑟夫·保罗·寇恩 ( 蒙特娄大学博士后 ),最近开源了一个数据库,里面有患有 【新冠肺炎】 疾病患者的胸部 x 光照片。所使用的数据集是一个开源数据集,包括来自公开研究的 新冠肺炎 图像,以及不同肺炎致病疾病(如 SARS、链球菌和肺囊虫)的肺部图像。

因此,数据集由 新冠肺炎 X 射线 扫描图像以及进行扫描时的角度组成。原来最常用的视图是 后前视图 并且我考虑了新冠肺炎 PA 视图 X 射线 扫描用于我的分析。****

现在,我还使用了 Kaggle 的胸部 x 光 竞赛数据集来提取健康患者和肺炎患者的 x 光,并对每个类别的 100 张图像进行了采样,以与新冠肺炎的可用图像进行平衡。(不过我会在这部分下功夫,改进方法)。****

从 X 射线中检测新冠肺炎存在的卷积神经网络方法:

让我们看一下数据集的类级分布。

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

图 4:数据集的分类分布

所以,在我的方法中,我在三个分类问题上运行了卷积神经网络

  1. 对正常与新冠肺炎病例进行分类。【2 类问题】
  2. 肺炎 vs 新冠肺炎病例分类。【2 类问题】
  3. 分类正常 vs 新冠肺炎 vs 肺炎病例。【3 类问题】

我在一些分析中看到,人们将正常和肺炎病例结合在一起,我认为这不合适,因为模型将试图忽略这两个类别之间的组间差异,因此获得的准确性将不是真正的衡量标准。

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

图 5:将两个不同的类别合并为一个类别可能会产生误导。 来源

所以,这是我上述假设的一个简单说明(只是为了解释)。假设“特征 1”和“特征 2”代表潜在空间,在潜在空间中,CNN 将图像投射到潜在空间中,并且属于三个类别中的每一个的图像已经在图像中被标记。

可以看出,它们目前是线性可分的,但如果我们将“正常”和“肺炎”这两个类别合并为一个类别,则可分性消失,结果可能会产生误导。因此,如果我们要合并类,就需要进行某些验证。

虽然有人可能会说投影会解决这个问题,但这并不成立,因为我们使用的是迁移学习。

反正在我的分析中,重点是既要减少的假阳性。让我们来分析一下。我已经使用转移学习与 VGG-16 模型和微调最后几层。****

*******vgg_pretrained_model = VGG16(weights="imagenet", 
                             include_top= False,
                             input_tensor=Input(shape=(224, 224,3)))new_model = vgg_pretrained_model.output
new_model = AveragePooling2D(pool_size=(4, 4))(new_model)
new_model = Flatten(name="flatten")(new_model)
new_model = Dense(64, activation="relu")(new_model)
new_model = Dropout(0.4)(new_model)
new_model = Dense(2, activation="softmax")(new_model)
model = Model(inputs=vgg_pretrained_model.input, outputs=new_model)*******

我们模型的最终参数如下所示。该模型已经使用 Kaggle GPU 进行了训练。

******Total params: 14,747,650
Trainable params: 2,392,770
Non-trainable params: 12,354,880******

案例 1:正常 vs 新冠肺炎分类结果

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

图 6:新冠肺炎与正常模型的分类报告

可以清楚地看到,该模型几乎可以以 100%的准确率和召回率区分这两种情况。现在,为了有更多的理解,我使用了基于梯度的类激活图的概念,以便找到图像中最重要的部分,这有助于模型进行如此精确的分类。

现在要了解更多关于【GRAD-CAM】如何工作,请参考 论文 。我可能会在我未来的博客中详细介绍它们。

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

图 7:基于梯度的类激活图

绘制 Grad-CAM 热图的代码如下所示。为了看得更清楚,我做了一些修改。

****def get_class_activation_map(ind,path,files) :

    img_path =  path + files[ind]
    img = cv2.imread(img_path)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img = cv2.resize(img, (224, 224))
    img = np.expand_dims(img,axis=0)

    predict = model.predict(img)
    target_class = np.argmax(predict[0])
    last_conv = model.get_layer('block5_conv3')
    grads =K.gradients(model.output[:,target_class],last_conv.output)[0]
    pooled_grads = K.mean(grads,axis=(0,1,2))
    iterate = K.function([model.input],[pooled_grads,last_conv.output[0]])
    pooled_grads_value,conv_layer_output = iterate([img])

    for i in range(512):
        conv_layer_output[:,:,i] *= pooled_grads_value[i]

    heatmap = np.mean(conv_layer_output,axis=-1)

    for x in range(heatmap.shape[0]):
        for y in range(heatmap.shape[1]):
            heatmap[x,y] = np.max(heatmap[x,y],0)
    heatmap = np.maximum(heatmap,0)
    heatmap /= np.max(heatmap)
    plt.imshow(heatmap)img_gray = cv2.cvtColor(img[0], cv2.COLOR_BGR2GRAY)
    upsample = cv2.resize(heatmap, (224,224))

    output_path_gradcam = '/kaggle/working/' + files[ind] + 'gradcam.jpeg'
    plt.imsave(output_path_gradcam,upsample * img_gray)****

正常患者的分类激活图输出:

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

图 8:正常患者的 Grad-CAM 热图******

因此,我们可以看到,该模型更侧重于突出显示的部分,以识别和分类他们为正常/健康的患者。

新冠肺炎患者的分类激活图输出:

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

图 9:新冠肺炎患者的 Grad-CAM 热图******

同样,突出显示的部分朝向图像的右端部分,这表明该部分可能是确定患者是否患有新冠肺炎的重要特征,或者可能是 新冠肺炎已经影响了 部分中的患者。这可以通过临床记录进行验证。**

病例 2:肺炎 vs 新冠肺炎分类结果

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

图 10:新冠肺炎 vs 肺炎模型分类报告

肺炎患者的分类激活图输出:

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

图 11:肺炎患者 Grad-CAM 热图******

病例 3:肺炎 vs 新冠肺炎 vs 正常分类结果

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

图 12:新冠肺炎 vs 肺炎 vs 正常模型的分类报告

在这三种情况下,即使数据集很小,模型的表现也非常好。此外,建立三个不同模型的目的也是为了检查模型与 【新冠肺炎】 病例检测的一致性。在这三种情况下,测试数据中的案例的准确率和召回率都明显较高。******

*******话虽如此,但这仅仅是对一些图像进行的实验,并未经过外部卫生组织或医生的验证/检查。还没有基于这种方法的临床研究来验证它。该模型已被用作概念验证,不能从该结果中得出任何结论/推断。 *******

但是,这种方法有巨大的潜力,可以成为一种优秀的方法来拥有高效、快速的 诊断系统 ,这正是当前所需要的。以下列出了主要优势:

优点:

优点已经从这个 来源 中提到了。

  1. 运送测试或样本是 PCR 测试的缺点之一,而 x 光机可以解决这个问题。
  2. 如果放射科医生&医生受到影响,AI 可以生成初步诊断,以了解患者是否受到影响。

结论:

因此,作为总结,我想重申一下我自己,分析是在有限的数据集上进行的,结果是初步的,不能从中推断出任何结论。该方法尚未进行临床试验/医学验证。

我计划用更多的 X 射线扫描来增加我的模型的稳健性,这样模型就可以推广了。此外,与健康人群的数量相比,COVID 病例的数量将会更少(尽管是指数增长),因此将会出现阶层失衡。我想改进我的采样技术,建立一个可以处理类别不平衡的模型,为此我需要更多的数据。

此外,当前的方法是基于微调 I mageNet 权重 ,但是如果我们能够专门为此目的建立一个模型,结果将更加可信和可推广。

因此,如果您有库可接受的新冠肺炎患者的 X 射线扫描图像, 请将 贡献给 ,因为它将在这些关键时刻有所帮助。

一个好消息是麻省理工已经发布了一个 数据库 包含了 新冠肺炎 受影响患者的 x 光照片。因此,作为下一步,我将尝试将这些数据整合到我的建模方法中,并检查结果。

此外,我将根据梯度值对 类激活图输出 进行处理,并使用临床记录对其进行验证。

注意——我不是来自医学领域/生物学背景,所做的实验是为了证明概念。

编者注: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里

保持安全和快乐阅读:)

**** [## Souradip Chakraborty -数据科学家-沃尔玛印度实验室| LinkedIn

我是一名有抱负的统计学家和机器学习科学家。我探索机器学习、深度学习和…

www.linkedin.com](https://www.linkedin.com/in/souradip-chakraborty/) [## 专家|谷歌开发者

机器学习我是 Souradip Chakraborty,目前在沃尔玛实验室担任统计分析师(研究)

developers.google.com](https://developers.google.com/community/experts/directory/profile/profile-souradip_chakraborty)

参考资料:

  1. https://github.com/ieee8023/covid-chestxray-dataset
  2. 艾尔顿·圣华金撰写的类似的精彩博客:https://towardsdatascience . com/using-deep-learning-to-detect-ncov-19-from-x-ray-images-1a 89701 D1 ACD
  3. https://github . com/harsh Casper/Brihaspati/blob/master/新冠肺炎/COVID19-XRay.ipynb
  4. 论文“Grad-CAM:通过基于梯度的定位从深度网络进行视觉解释”。
  5. https://www . ka ggle . com/paultimothymooney/胸部 x 光-肺炎
  6. 【https://www.kaggle.com/michtyson/covid-19-xray-dl#1. -数据准备****

Python 中价格支持和阻力位的检测

原文:https://towardsdatascience.com/detection-of-price-support-and-resistance-levels-in-python-baedc44c34c9?source=collection_archive---------0-----------------------

Python 中寻找价格支撑位和阻力位的算法

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

算法交易是交易和统计的一个迷人领域,量化交易者经常希望自动化的最有用的交易技术之一是价格行为,这是在不使用衍生指标如振荡器或移动平均线的情况下对价格运动的分析。

在这篇文章中,我将介绍一种自动检测价格行为的两个重要工具的算法,这两个工具是支撑和阻力。

什么是支撑和阻力?

支撑和阻力通常被称为“关键水平”。它们是股价反转的价格水平。如果价格上涨,然后反转其向下移动的趋势,它所达到的最高点被称为阻力。如果价格已经下降,然后开始上升,最低价格值被称为支持

这些价格水平确定了供给和需求区域,交易者在这些区域增加了交易量,并表现出一定的兴趣。这就是为什么,一旦价格接近关键水平,交易者必须睁大眼睛,看看会发生什么。

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

支撑和阻力示例

关键能级非常重要,因为在这些反转能级附近可能会发生许多有趣的事件。例如,市场可以再次反弹,让均值回归策略获胜,或者它可以突破关键水平,这对突破交易者来说更好。

有一个经验法则是,一个关键水平被测试的次数越多(即市场在它附近反弹了很多次),这个水平的重要性就越高。

另一个经验法则是,一旦阻力位被突破,它会自动成为支撑位。反之亦然,一个被打破的支撑位变成了阻力位。

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

反抗变成了支持

级别或区域?

在这篇文章中,我将关键水平称为价格水平,但有一些交易者说关键水平是区域,而不是水平。发生这种情况是因为波动性让一切都变得更嘈杂,所以供需区从来没有那么清晰。这就是为什么,在现实生活的交易中,你应该总是考虑围绕关键水平的某种包络线,大致与波动性一样宽(例如,平均真实范围,标准差)。为了简单起见,在本文中,我将把关键价格水平视为固定价格水平,而不是更广泛的区域。

如何识别关键级别

关键水平是拒绝点,所以我们必须检查市场是否达到了一定的水平,然后拒绝向相反的方向移动。

一个好主意是使用蜡烛图,检查每根蜡烛的高低价格。如果一根蜡烛线的低点比前一根低,下一根蜡烛线的低点,这是一个支撑。这种特殊的价格行为模式被称为摆动。不幸的是,由于市场波动和噪音,这种模式经常显示出一些缺陷,这就是为什么我们可以使用一种更好的模式,称为分形

分形

分形是由 5 根蜡烛组成的烛台图案。第三根蜡烛的价格最低,前面的蜡烛价格越来越低,后面的蜡烛价格越来越低。根据这种模式,第三根蜡烛线的低点是支撑位。同样的概念也适用于阻力位,第三根蜡烛线是五根蜡烛线中最高的。

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

使用分形的支持识别

分形非常有用,因为它们消除了一些由摆动显示的噪声,并以更高的精度识别关键水平。这就是为什么我要在我的算法中使用它们。

Python 中的自动检测

让我们看一个使用标准普尔 500 数据的 Python 示例。我的笔记本可以在 GitHub 上找到这里:https://GitHub . com/gianlucamalato/machine learning/blob/master/Support _ and _ resistance . ipynb

对于所有的烛台图表代码,我使用了一些在这里找到的代码:https://saralgyaan . com/posts/python-烛台图表-matplotlib-tutorial-chapter-11/

我们先安装 yfinancempl_finance 库。

!pip install yfinance
!pip install mpl_finance

让我们导入一些有用的库并初始化绘图环境。

import pandas as pd
import numpy as np
import yfinance
from mpl_finance import candlestick_ohlc
import matplotlib.dates as mpl_dates
import matplotlib.pyplot as pltplt.rcParams['figure.figsize'] = [12, 7]
plt.rc('font', size=14)

现在我们可以下载标准普尔 500 日报的数据。

name = 'SPY'
ticker = yfinance.Ticker(name)
df = ticker.history(interval="1d",start="2020-03-15", end="2020-07-15")df['Date'] = pd.to_datetime(df.index)
df['Date'] = df['Date'].apply(mpl_dates.date2num)
df = df.loc[:,['Date', 'Open', 'High', 'Low', 'Close']]

让我们不要创建两个识别 4 蜡烛分形的函数。

def isSupport(df,i):
  support = df['Low'][i] < df['Low'][i-1]  and df['Low'][i] < df['Low'][i+1] and df['Low'][i+1] < df['Low'][i+2] and df['Low'][i-1] < df['Low'][i-2] return supportdef isResistance(df,i):
  resistance = df['High'][i] > df['High'][i-1]  and df['High'][i] > df['High'][i+1] and df['High'][i+1] > df['High'][i+2] and df['High'][i-1] > df['High'][i-2] return resistance

最后,让我们创建一个包含我们找到的级别的列表。每个级别都是一个元组,其第一个元素是信号蜡烛线的指数,第二个元素是价格值。

levels = []
for i in range(2,df.shape[0]-2):
  if isSupport(df,i):
    levels.append((i,df['Low'][i]))
  elif isResistance(df,i):
    levels.append((i,df['High'][i]))

我们现在可以定义一个将价格和关键水平绘制在一起的函数。

def plot_all():
  fig, ax = plt.subplots() candlestick_ohlc(ax,df.values,width=0.6, \
                   colorup='green', colordown='red', alpha=0.8) date_format = mpl_dates.DateFormatter('%d %b %Y')
  ax.xaxis.set_major_formatter(date_format)
  fig.autofmt_xdate() fig.tight_layout() for level in levels:
    plt.hlines(level[1],xmin=df['Date'][level[0]],\
               xmax=max(df['Date']),colors='blue')
  fig.show()

最后,我们可以绘制结果。

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

如您所见,我们已经能够检测出主要的剔除水平,但仍有一些噪声。有些级别高于其他级别,但本质上是同一级别。

我们可以通过修改检测关键电平的函数来清除这种噪声。如果一个级别接近另一个级别,它将被丢弃。那么,我们必须决定“近”是什么意思。如果一个级别与另一个级别之间的距离小于图表中的平均蜡烛线大小(即蜡烛线中最高价和最低价之间的平均差值),我们可以说这个级别接近另一个级别。这将给我们一个波动性的粗略估计。

s =  np.mean(df['High'] - df['Low'])

让我们定义一个函数,给定一个价格值,如果它接近某个先前发现的关键级别,则返回 False。

def isFarFromLevel(l):
   return np.sum([abs(l-x) < s  for x in levels]) == 0

现在我们可以使用这个函数作为过滤器来扫描价格历史,寻找关键水平。

levels = []
for i in range(2,df.shape[0]-2):
  if isSupport(df,i):
    l = df['Low'][i] if isFarFromLevel(l):
      levels.append((i,l)) elif isResistance(df,i):
    l = df['High'][i] if isFarFromLevel(l):
      levels.append((i,l))

最后,我们可以再次策划一切。

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

现在级别更清楚了,它们彼此不重叠,我们可以很容易地看到,有时价格在每个级别上不止一次地跳跃。

结论

自动化价格水平对定量交易者非常有用,可以消除一些市场噪音,使图表更加清晰。关键水平可用于均值回归策略(即当价格从支撑位反弹时买入)或突破策略(即当价格突破阻力位时买入)。

注来自《走向数据科学》的编辑: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

Detectron2 和 Python Wheels 缓存

原文:https://towardsdatascience.com/detectron2-python-wheels-cache-bfb94a0267ef?source=collection_archive---------29-----------------------

在 Windows 上构建一个 Detectron2 wheel 包并缓存它

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

巴尼·莫斯Flickr 上的原始照片

检测器 2

我最近在做一些定制的探测器 2 模型的工作。我一直在云中的 Linux VM 上训练我的模型,但是我想在 Windows 环境中使用这个训练过的模型。脸书研究公司关于 Detectron2 的官方说法是它在 Windows 上不受支持。但我不会让这阻止我去尝试!好消息是我能够做到,这篇文章描述了我使用的过程。

初始设置

在解释我是如何做到这一点的过程中,我将假设您熟悉/熟悉以下内容:

  • Python 虚拟环境
  • GIT 命令行

首先要创建一个虚拟环境,然后激活它:

virtualenv detectron2
detectron2\Scripts\activate

从您的虚拟环境安装 PyTorch 和 torchvision(仅限 CPU 版本):

pip install torch==1.5.1+cpu torchvision==0.6.1+cpu -f https://download.pytorch.org/whl/torch_stable.html

或许还值得安装 fvcore 和 windows 版本的 pycocotools,即 pycocotools-windows :

pip install fvcore
pip install pycocotools-windows

下载并安装检测器 2

为了下载 Detectron2 源代码,我们将使用 GIT 命令行克隆一个特定的标记版本(这里的标记是“v0.1”)。

git clone --depth 1 --branch v0.1 https://github.com/facebookresearch/detectron2.git

将发布变更克隆到刚刚在虚拟环境(不是 GIT 命令行)中用这个克隆创建的 detectron2 文件夹之后。例如,如果您将 GIT 克隆到文件夹D:\ Source \ Python \ detectron 2中,则切换到该目录并发出以下命令:

pip install -U .

不要忘记结尾的句号,这真的很重要!

这应该会构建 detectron2 包,如果一切顺利,您应该会在最后看到如下内容:

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

构建检测器 2 包

因为我们克隆了 v0.1 标签,所以您会看到它是由 detectron 2–0.1 构建的

缓存车轮

你会注意到,当你安装一个 python 包时,它会检查它的本地轮缓存,看看它过去是否下载过这个包,如果下载过,它就使用缓存的版本。要创建您自己的车轮缓存,您需要首先安装车轮包:

pip install wheel

完成后,我们要列出当前为我们的虚拟环境安装的包,并将它们放入一个文件中(这里称为 requirements.txt):

pip freeze > requirements.txt

要为当前安装的包复制/创建所有的轮子,并把它们放在一个缓存文件夹中(这里我使用的是 D:\wheels_cache ),请执行以下操作:

pip wheel --wheel-dir=D:\wheels_cache -r requirements.txt

车轮缓存的优势

使用 wheels 缓存的好处之一是,将来您可以使用缓存的 wheels 直接安装,而不必再次构建一个包。如果你想在一台不同的电脑上做这件事,这是很有用的,因为你可能没有所有的依赖项。你可以这样做:

pip install D:\wheels_cache\detectron2-0.1-cp38-cp38-win_amd64.whl

这种方法需要注意的一点是轮子依赖于目标平台和 Python 版本。这个是针对 Windows 64 位和 Python 3.8 的。

你甚至可以安装来自 requirements.txt 文件的所有东西,告诉它在你的缓存文件夹中寻找轮子:

pip install --no-index --find-links=D:\wheels_cache -r requirements.txt

有一次,我必须在客户处安装一台电脑,而这台电脑是隔离的,即不允许连接到互联网或本地网络。我必须能够在这台机器上安装 Python 和所有需要的包,以运行我实现的机器学习软件。我采用的方法是为机器构建一个包含所有需要的包的 wheels 缓存。这样,安装可以从缓存中进行。

参考

探测器 2:最基本的端到端教程

原文:https://towardsdatascience.com/detectron2-the-basic-end-to-end-tutorial-5ac90e2f90e3?source=collection_archive---------5-----------------------

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

https://commons . wikimedia . org/wiki/File:simmon _ Telescope _ at _ Eiffel _ Tower _ In _ Paris . jpg

历史第一

2018 年,脸书 AI 开发了一个名为 Detectron 的物体检测库。这是一个了不起的图书馆,但有点难以使用。我的早期版本写了一篇关于如何安装 Detectron 和运行示例演示的博文,仅此而已。Detectron 的安装和使用有点困难,它是由 Caffe2 供电的。自 2018 年以来,有许多代码更改将 Caffe2 & PyTorch 纳入了一个单一的存储库,这增加了使用 Detectron 的难度。

看起来社区里有一些建设性的反馈,脸书推出了 v2。

根据 Detectron2 的 GitHub 页面:

Detectron2 是脸书人工智能研究所的下一代软件系统,实现了最先进的物体检测算法。

Detectron2 是使用 PyTorch 构建的,py torch 现在拥有更活跃的社区,可以与 TensorFlow 本身竞争。此外,设置指令更容易,加上一个非常容易使用的 API 来提取评分结果。像 YOLO 这样的其他框架有非常模糊的评分结果格式,以普通多维数组的形式提供。任何与 YOLO 一起工作的人都可以想象首先解析评分结果并将其正确无误需要付出的努力。

历史已经足够了,在这篇文章中,我将带你做一个端到端的练习,学习如何准备一个 Detectron2 docker 映像来托管一个用于对象检测的 web API,并在一个充当服务消费者的小型 web 应用程序中使用它。

1.装置

我将首先从安装开始。不幸的是,Windows 不被支持,但是我将使用容器绕过它。快速地说,我们不介意安装一个 CPU 版本,因为 GPU 需要(猜猜是什么)一个 GPU,CUDA 和所有来自 NVIDIA 的可爱的东西。

因此,使用您喜欢的文本编辑器,用这个内容创建一个 docker 文件。

首先,根据 Detectron2 设置指令的要求,选择 Python 版本≥ 3.6 的基础映像。接下来安装一些先决条件,然后在 Detectron2 安装页面上安装相同的安装说明。安装的版本是一个 CPU 版本,它不会超级快,但足够好的教程。最后,Flask 包含在内,因为这个 docker 映像将托管一个 web API 网站,以接受客户的评分请求。

让我们先建立形象。

docker build --rm . -t ylashin/detectron2:latest

您可以使用任何您想要的名称/标签,并为接下来的步骤做相应的调整。接下来,让我们试一试。

docker run -it ylashin/detectron2:latest bin/bash

希望上面所有的工作都很好,现在我们已经有了一个安装了 Detectron2 的容器。因此,我们需要验证没有任何东西损坏,我们有独角兽和彩虹。

必须使用 docker CLI 或使用安装在容器上的 nano 将以下test.py脚本复制到容器中。

涉及的主要任务有:

  1. 印刷检测器 2 版本。
  2. 莱昂内尔·梅西和一个足球下载图片。
  3. 使用预先训练的架构之一创建预测器实例。
  4. 使用预测器实例对下载的图像进行评分。

接下来,我们将运行测试脚本,如下一个屏幕截图所示。

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

在撰写本文时,Detectron2 的版本似乎是 0.1.1。此外,评分是正确的,结果不是一个简单的张量像 YOLO。它是一个类型化的类,具有易于使用的成员,如边界框和预测类。稍后我们将讨论将类代码映射到人类可读的名称。我们在这里有一对夫妇的边界框和一对夫妇的高分加上预测类 0(人)和 32(运动球)。

附注:根据你正在解决的问题,你需要选择正确的架构,看看它是否针对类似的数据集进行了训练,否则你可能需要进行定制训练。

2.发布 API

下一步是让这个评分功能可以从容器外部访问。Flask web API 需要驻留在该容器中,以接受图像并返回评分结果。为了简单起见,API 将接受一个图像 URL 并自己下载。它不接受二进制有效负载,这是很自然的事情,但它只是很容易使用相同的测试脚本稍加修改。

此外,响应将是一个序列化为 JSON 对象的字典,其中包含调用者所需的足够信息,无需任何复杂的解析。

现在,因为容器将托管 Flask web 服务器,所以必须通过发布 web API 端口来启动它。因此,退出当前容器,并使用端口发布再次启动它。

docker run -p 8181:5000 -it ylashin/detectron2:latest bin/bash

烧瓶端口 5000 映射到主机端口 8181。

现在,在名为web_api.py的容器中创建一个文件,并将下面的 GitHub 要点粘贴到其中。

这与之前使用的测试脚本几乎相同,但有以下区别:

  • 进行了一些重构,以便为每个请求准备好一个全局预测器实例。
  • 映射到 web API 端点的函数用于接收带有 JSON 对象的 HTTP 请求,该对象具有要评分的图像 URL。
  • 该函数进行评分和一些后处理,以准备最终的响应对象。

要启动 web 服务器,请运行:

python web_api.py

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

显示的 URL 有一个 5000 端口,但那是因为它只是在容器内部。任何像 Postman、curl 或 PowerShell 这样的工具都可以用来测试 API 是否按预期工作。对于您使用的任何工具,请记住包含带有键content-type和值application/json的请求头。

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

如果我们在 Postman 中向下滚动响应,我们将找到预期的得分字段,如边界框、得分和类别预测。

现在 web API 服务器似乎工作得很好,最好将其作为 Dockerfile 定义的一部分。这将允许我们将构建好的映像推送到 docker hub 或任何其他注册表,并与其他人共享或使用它,而不必担心每次都要构建它。

更新的 Docker 文件可以在链接到这篇文章的报告中找到,但是为了简洁起见,添加到 Docker 文件的增量是:

WORKDIR /appCOPY web_api.py web_api.pyENTRYPOINT ["python", "/app/web_api.py"]

一旦构建了修改后的 docker 映像,我们可以再次启动容器,但这一次我们不需要复制 web API 文件,也不需要自己启动它。实际上,我们可以将容器作为守护进程启动。

docker run -p 8181:5000 -d ylashin/detectron2:latest

可以使用 Postman 再次测试 web API 以进行验证,但我们需要给容器几秒钟时间来下载预测器准备的权重文件部分。

一旦我们对运行的容器满意了,我们就可以关闭它并发布图像。

docker push ylashin/detectron2:latest

我将该图像发布到我自己的 Docker Hub 帐户,以便我稍后可以向您展示如何将它用于 Azure 容器实例。我将用来消费评分服务的 web 应用程序将在本地托管,因此它可以轻松地访问本地运行容器。但是我更喜欢进入下一个层次,将容器托管在云中的某个地方,以模拟更真实的实现。

客户端应用程序

唷,快到了。最后一个阶段是从任何 RESTful 客户端使用 web API。但首先,我将使用 Azure CLI 和 Azure container instances 服务启动 Azure 中的容器。如果你想继续在本地使用容器,你可以跳过这个 Azure 位,但在稍后到来的 web 应用中调整 web API URL。

az group create --name detectron2 --location eastusaz container create --resource-group detectron2 --name predictor --image ylashin/detectron2:latest --cpu 2 --memory 4  --dns-name-label detectron2api --ports 5000az container show --resource-group detectron2 --name predictor --query "{FQDN:ipAddress.fqdn,ProvisioningState:provisioningState}" --out table

上面的最后一个命令将显示容器的 FQDN,我们可以用它来测试使用 Postman 的云托管 API。请注意,这里使用的端口是普通烧瓶端口,没有映射到其他端口。

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

我们有一个在云中运行的 web API 端点,可以从任何地方的任何 REST 客户端使用。我已经建立了一个小的 JavaScript 应用程序。这款应用非常简单:

  • 它有一个文本框和一个按钮。
  • 在文本框中输入一个公共图像 URL,然后单击按钮。
  • 该应用程序将调用我们的 API,呈现请求的图像并绘制边界框。

要试用该应用程序,请先克隆它并安装所需的 npm 软件包:

git clone [https://github.com/ylashin/detectron2-tutorial](https://github.com/ylashin/detectron2-tutorial)
cd '.\3\. client\'
npm install
npm install -g browserify
npm install -g watchify
watchify index.js -o bundle.js

在文本编辑器中打开index.html文件,并更新函数scoreImage中 API 的 URL,以匹配本地或云托管 API 的 URL。然后双击index.html文件,这将在您的默认浏览器中打开应用程序。使用不同的图片网址,但是请注意一些图片网站有一点严格的 CORS 政策,所以不是所有的图片都能正常工作。这与我们的 web 应用程序或 API 无关,而是更多地与 web 的工作方式有关。

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

本帖安装部分使用的图片是上面试用过的。我们可以看到梅西和球上的边框、分数和标签。开发人员控制台窗格也显示了 API 的 JSON 响应。

在这个 web 应用程序中要考虑的主要部分是解析和使用 API 响应,这非常简单明了。

所有剩下的代码都是通过 npm 包进行管道和 HTML 画布渲染。

包裹

我们仅仅触及了 Detectron2 的表面,它还有许多令人惊奇的特性有待探索。此外,为了使帖子尽可能简洁,我们还设置了许多快捷方式。总之,Detectron2 是任何开发人员工具箱的一个非常受欢迎的补充,因为它的特性,但更重要的是易于使用。

如果你碰巧在 Azure 中创建了容器,请记住一旦完成实验就删除资源组或停止容器,否则它将继续消耗你的信用。

资源

[## ylashin/检测器 2-教程

使用 Detectron2 进行物体探测的端到端教程-ylashin/detectron 2-教程

github.com](https://github.com/ylashin/detectron2-tutorial) [## Detectron2:一个基于 PyTorch 的模块化对象检测库

自 2018 年发布以来,Detectron 对象检测平台已成为脸书人工智能研究(FAIR)最…

ai.facebook.com](https://ai.facebook.com/blog/-detectron2-a-pytorch-based-modular-object-detection-library-/) [## Facebook 研究/检测器 2

Detectron2 是脸书人工智能研究所的下一代软件系统,实现了最先进的物体检测…

github.com](https://github.com/facebookresearch/detectron2) [## 准备 Detectron 沙盒的快速简单指南

medium.com](https://medium.com/@ylashin/quick-and-easy-guide-to-prepare-a-detectron-sandbox-940ccad8ffe2)

使用 Python 为您的投资组合确定安全的提款率

原文:https://towardsdatascience.com/determine-a-safe-withdrawal-rate-for-your-investment-portfolio-with-python-cf2df9185f73?source=collection_archive---------54-----------------------

在钱不用完的情况下能取多少?

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

蒂埃拉·马洛卡在 Unsplash 上拍摄的照片

1999 年,一项研究发表,详细说明了一系列名义和通胀调整提款率对投资组合的影响,最长支付期为 30 年。在金融、投资咨询和退休规划领域,这项研究被非正式地称为三位一体研究

该研究表明,至少 75%股票的投资组合提供了 4%至 5%的通胀调整后提款。换句话说,如果你有一个 100 万美元的投资组合,你可以每年提取 40,000 至 50,000 美元(经通胀调整),至少在未来 30 年内没有资金耗尽的风险。

在阅读了这项研究后,我受到启发,扩展了本文的工作。因此,我编写了一个 python 脚本,遵循本研究中描述的方法来确定任何投资组合的可持续提款率(假设有足够的历史数据)。

这篇文章由以下部分组成,首先,我将解释数据和方法。其次,我将详细阐述 Python 实现并解释如何使用它。最后,给出了一个关于确定安全撤出率的结论。

数据和方法

为了确定一个可持续的退出率,该研究使用了一个比率,称为投资组合成功率。该比率用于比较具有不同提款率和支付期的所有投资组合。投资组合成功率被定义为投资组合成功的次数除以模拟的次数。如果投资组合在支付期结束时的期末值大于或等于零,则该投资组合被视为成功。

研究中使用的数据是标准普尔 500 指数的总月回报率和所罗门兄弟长期高等级公司债券指数。总月回报是给定期间投资的实际回报,包括利息、资本收益、股息和分配。

使用这些历史月总回报,通过使用不同支付期的重叠年方法来进行模拟。下图详细说明了这种方法:

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

此图中的三个点( )指的是两年和/或模拟之间的年份和/或模拟。

为了确定投资组合的成功率,需要计算月末投资组合的价值。该研究区分了具有名义提款率的投资组合和经通胀调整后提款的投资组合。这些月末投资组合价值确定如下:

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

通货膨胀调整是根据消费者价格指数(CPI)确定的。

在继续 python 实现之前,我还想进一步阐述两个项目。这些是投资组合回报( Rₜ )和每月提取金额( Wₜ )的确定。请参考下图:

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

投资组合回报的计算隐含地假设每月对投资组合进行再平衡以达到期望的投资组合权重。请注意,研究或实施中未考虑交易佣金和费用。

不幸的是,由于数据限制,python 实现的范围仅限于确定名义提款率。此外,我只能找到历史月回报,而不是总月回报。因此,不考虑股息或其他分配,这可能会影响投资组合的实际成功率。不过,我相信这个影响不会很大。

Python 实现

首先,我用于这个实现的库是 yfinanceplotly 。要使用这个 python 实现,您需要安装这些库。您可以使用pip来安装这些库。

pip install yfinance --upgrade --no-cache-dir
pip install plotly

在安装了必要的库之后,我们可以将注意力转向 python 实现。考虑到不同的投资组合构成、支付周期和提款率的数量,我发现创建一个名为sustainable_withdrawal_rate的 python 类是合适的。

在加载这个类之前,如果你在 Yahoo Finance 上查找你选择的符号会有所帮助,因为你将需要它作为 python 类的输入。例如,我想确定包含英国、德国和法国指数的投资组合的(名义)可持续提款率。雅虎财经上这些指数的符号是:

  • 英国富时指数:^FTSE
  • 德国 DAX 指数:^GDAXI
  • 法国 CAC 40 指数:^FCHI

加载 python 类后,需要实例化它。对于实例化,需要符号作为输入。以下是使用上述符号的示例:

symbols = "^FTSE ^GDAXI ^FCHI"
port = sustainable_withdrawal_rate(symbols)

观察到以下输出:

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

输出表明所有三个指数的历史(月度)数据范围从 1991 年到 2020 年,这是可用于分析的 30 年历史数据。这是有用的,因为它表明,对于这种投资组合,没有足够的历史数据来确定 30 年支付期的可持续提款率。

基于该投资组合的历史数据量(30 年),我们可以使用 10 年的支付期。如果您想要确定给定投资组合组合和 10 年支付期的成功率,您可以使用以下代码:

portfolio_composition = {"^FTSE":0.4, "^GDAXI":0.4, "^FCHI":0.3}
payout_period = 10
port.portfolio_success_rate(payout_period, portfolio_composition)

代码显示,该投资组合的权重包括 40%的富时指数、40%的 DAX 指数和 30%的 CAC 40 指数。运行此代码会产生以下输出:

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

输出是一个表格,其中包含不同的年度提款率及其相应的成功率。换句话说,由 40%的富时、40%的 DAX 和 30%的 CAC 40 组成的投资组合可以在 10 年的支付期内维持高达 7%的年提款率而不会被耗尽。

如果你想调整投资组合的组成和/或支付期,看看这些变化如何影响成功率。通过调整portfolio_composition和/或payout_period,并运行代码port.portfolio_success_rate(payout_period, portfolio_composition),你可以很容易地做到这一点。

最后,您还可以绘制特定年提款率的投资组合模拟图。让我们根据上面描述的投资组合构成和支付期,模拟 8%的年提款率。您可以使用以下代码来绘制模拟:

annual_withdrawal = 0.08
port.plotsimulations(annual_withdrawal)

运行此代码应该会在您的 webbrowser 中产生以下图形:

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

该研究和实施的基本假设是,本金在支付期间也被消耗。因此,提款率越低,在支付期后剩余大量资金的可能性就越大。

该图显示了年提款率为 8%,支付期为 10 年(120 个月)的不同投资组合模拟。投资组合模拟是根据方法一节中讨论的重叠年方法确定的。此外,该图显示了初始投资组合价值 1,以及对于不同的模拟,月末投资组合价值如何在整个月份中变化。

图中的绿线是被认为是成功的投资组合模拟,因为期末值大于零。相反,图中的红线是失败的投资组合模拟,因为它们的期末价值是负的。

如果您想绘制不同年提款率的投资组合模拟图,只需调整annual_withdrawal并运行代码port.plotsimulations(annual_withdrawal)

python 类sustainable_withdrawal_rate的完整代码如下所示:

三位一体研究的 Python 实现

结论

在本文中,我扩展了三一研究的工作,假设有足够的数据,任何投资组合的(名义)可持续提款率都可以确定。

通过使用 python 类sustainable_withdrawal_rate,您可以为您的投资组合确定一个可持续的提款率。选择一个可持续的退出率是主观的,不存在全局最优的退出率。

可持续的提款率取决于许多个人偏好,如当前消费、可变金融需求以及个人是否希望将初始退休投资组合的大部分留给其继承人。因此,这一分析的结果应被视为一种输入,以确定您的可持续戒断率。

这项研究中没有考虑的一个重要因素是个体的预期寿命。对于那些感兴趣的人,我写了一篇文章详细说明了预期寿命对提前退休人数的影响,这里是链接

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指南 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

参考

[1] Phillip L. Cooley、Carl M. Hubbard 和 Daniel T. Walz,《投资组合的可持续提款率》( 1999 年),《财务咨询和规划》第 10 卷第 1 期。

本文表达的金融观点来自作者的个人研究和经验。本文仅供参考。不应将其视为财务或法律建议。

确定您的数据是否可以建模

原文:https://towardsdatascience.com/determine-if-your-data-can-be-modeled-e619d65c13c5?source=collection_archive---------48-----------------------

你收集到正确的数据了吗??

一些数据集并不意味着具有可以聚类的地理空间表示。你的特征有很大的变化,理论上也有很大的特征。但是,这并不意味着统计上是可分的。

那么,我什么时候停止?

  1. 始终根据您试图预测的类别标签来可视化您的数据
columns_pairplot = x_train.select_dtypes(include=['int', 'float']).join(y_train)
sns.pairplot(columns_pairplot, hue = 'readmitted')
plt.show()

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

作者图片:不可分割的类

不同阶层的分布几乎是精确的。当然,这是一个不平衡的数据集。但是,请注意这些类的分布是如何重叠的?

2.应用 t-SNE 可视化

t-SNE 是“t-分布随机邻居嵌入”。它将高维数据映射到二维空间。这个 大致保持了样本的接近度。

您可能需要应用不同的学习率来找到最适合您数据集的学习率。通常,尝试 50 到 200 之间的值。

超参数,困惑度平衡了 t-SNE 赋予数据的局部和全局可变性的重要性。这是对每个点的近邻数量的猜测。使用 5-50 之间的值。更高,如果有更多的数据点。困惑值不应超过数据点的数量。

注意:轴到 t-SNE 图是不可解释的。每次应用 t-SNE 时,它们都会有所不同

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

作者图片:T-SNE 可视化

嗯,让我们再看多一点——调整一些超参数。

# reduce dimensionality with t-sne
tsne = TSNE(n_components=2, verbose=1, perplexity=50, n_iter=1000, learning_rate=50)
tsne_results = tsne.fit_transform(x_train)

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

图片作者:重叠数据-无法分类!

你看到集群是怎么分不开的吗!我应该停在这里的!但是,我不能让自己走出这个疯狂的洞。[是的,我们有时都会这样]。

3.多类分类

从上面我们已经知道,决策边界是非线性的。因此,我们可以使用一个 SVC (具有 RBF 核的支持向量分类器)

from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCVsvc_model = SVC() ## default kernel - RBF
parameters = {'C':[0.1, 1, 10], 'gamma':[0.00001, 0.0001, 0.001, 0.01, 0.1]}
searcher = GridSearchCV(svc_model, param_grid = parameters, n_jobs= 4, verbose = 2, return_train_score= True)
searcher.fit(x_train, y_train)
# Report the best parameters and the corresponding score

训练分数:0.59
测试分数:0.53
F1 分数:0.23
精度分数:0.24

所以,我应该早点停止…在你试图过度调整和复杂化模型以期望更好的结果之前,理解你的数据总是好的。祝你好运!

使用 Scikit-Learn 确定报价来源

原文:https://towardsdatascience.com/determining-a-quotes-source-using-scikit-learn-9d3e2af894f4?source=collection_archive---------58-----------------------

使用逻辑回归和朴素贝叶斯进行整体平均,以确定一条消息更有可能是伯尼·桑德斯或唐纳德·川普发的。

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

用于文本分类的机器学习管道。图片作者。

人们可以利用视觉和听觉等感官来学习。机器学习遵循类似的概念,但有一个关键的区别。电脑不能像我们一样看或听。它只懂一件事——数字。因此,在机器能够学习之前,它首先需要将人类能够感知的信息转换为数字。数字图像以像素的形式存储数字信息就是一个例子。

在本文中,我们将开发一个机器学习模型,它可以接收打字信息,并确定伯尼·桑德斯或唐纳德·川普更有可能发微博。在我的 GitHub 上可以找到包含数据集、Python 代码和将要讨论的 Jupyter 笔记本的存储库。现在让我们开始吧!

最小化数据集偏差

为了最大限度地减少偏见,我们需要根据我们两位政治家在类似情况下使用的文本来训练我们的模型。例如,如果我们只从一个政治家对国家悲剧的回应中提取文本,从另一个政治家对积极事件的回应中提取文本,那么我们的模型将学习区分积极和消极的文本,而不一定是他们的写作风格。因此,我们将在自 2015 年*(即*,他们为 2016 年美国总统大选发起竞选活动)以来的两位政治家的推特上训练模型。我们将不包括转发,因为尽管它们可能反映了政治家的社会经济观点,但它们不一定反映他们的语言模式。

特征抽出

清理推文

推文可以包含指向其他网站、图像或视频的链接,这些链接将带有自己的 URL,包括诸如(https://…)之类的术语。标签(#)和提及(@)也包含一些符号,这些符号不一定是这些政客文章的一部分,但却是使用某些 twitter 功能的必需品。因此,我们将删除这些项目和任何其他非字母数字字符,并将剩下的内容转换为小写。本质上,我们将只剩下包含小写字母、数字和空格的文本。例如:

  • 她打算买电视机。它以 500 美元出售。

会变成:

  • 她打算买这台减价 500 英镑的电视机

该消息在阅读时仍然有意义,并且现在将更容易在我们的模型中实现。

词袋模型

让我们考虑以下三个 文件 :

  • 我们正在学习机器学习。
  • 具体来说,我们正在学习文本分类。
  • 你考虑过学习 Python 吗?

清理这些文件给了我们:

  • 我们正在学习机器学习
  • 具体来说,我们正在学习文本分类
  • 你考虑过学习 python 吗

接下来,我们将把每个文档标记成 个术语 :

  • 我们|正在|学习|关于|机器|学习
  • 具体来说,我们正在|学习|关于|文本|分类
  • 你考虑过学习 python 吗

注意“|”符号在我们的模型中实际上并不存在,它只是在这里用来帮助可视化标记。每个文档现在可以被认为是一个包含每个单词的术语的袋子。因此得名*。让我们看看标记化对文档的影响:*

  • 我们是→我们|是
  • 我们→曾经是
  • 曾经→曾经

前两个术语(“我们是”和“我们是”)具有相同的含义,但将被注册为不同的术语。而且“我们”和“是”这两个词已经分离开了。这可能看起来不可取,但是请记住某人是否使用缩写是他们如何书写的一个显著特征。相反,“we 're”和“was”有不同的意思,但现在已经合并为同一个术语。

n-gram 模型

在前面的例子中,我们将文档标记为一个单词术语,称为 unigrams ( ,即,1-grams)。为了改进我们的模型,我们还可以提取由包含两个单词的术语组成的二元模型(,2-grams):

  • 我们正在学习→我们|正在|学习|我们正在|正在学习
  • 我们在学习→我们在学习
  • 你是吗?你是吗

使用二元模型,我们现在可以包括新的术语,如“我们是”。我们也有更多的信息来区分“我们是”和“曾经是”,因为“曾经是你”可能比“我们是你”更常见。我们还可以提取像“机器学习”这样的新术语,以前只能作为“机器”和“学习”使用。

将二元模型添加到我们的模型中会增加每个文档中的术语数量,使我们的模型更加复杂,但是我们必须小心不要忘乎所以。**包括比必要特征更多的特征(,例如*,3-grams,4-grams,5-grams,等。 ) 来描述我们的模型会使它容易过拟合,以及增加它的规模和计算时间。*虽然在本文中我们不会对过度拟合进行详细的讨论,但总的想法是,我们希望尽可能用最少的必要特征制作最精确的模型。

计数矢量化

考虑下面的 文集 ( ,文献集):

  • 这是语料库中的第一个例子。
  • 这是第二个。
  • 每一个例子都在增加。

首先,我们的模型不知道任何术语。因此,我们需要创建一个字典,包含我们希望模型知道的所有术语。这些术语组成了模型的 词汇 ,并且可以使用 Python 中的 scikit-learn 的[CountVectorizer](https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html)从语料库中提取:

*from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd

corpus = ['This is the first example in the corpus.',
          'This is the second.',
          'The corpus is growing with each example.']

count = CountVectorizer(ngram_range=(1, 2))
count.fit(corpus)
df = pd.DataFrame.from_dict(count.vocabulary_,
                            orient='index', columns=['INDEX'])
df.sort_values(by=['INDEX'], inplace=True)

X_count = count.transform(corpus)
df['doc1_tf'] = X_count.toarray().T[df['INDEX'], 0]
df['doc2_tf'] = X_count.toarray().T[df['INDEX'], 1]
df['doc3_tf'] = X_count.toarray().T[df['INDEX'], 2]
print(df)*

输出是我们的词汇表,其中包含我们的语料库中所有唯一的术语(,单词和双词)和 术语频率 ( tf ) ( ,每个术语在文档中出现的次数)表。

 *INDEX  doc1_tf  doc2_tf  doc3_tf
corpus             0        1        0        1
corpus is          1        0        0        1
each               2        0        0        1
each example       3        0        0        1
example            4        1        0        1
example in         5        1        0        0
first              6        1        0        0
first example      7        1        0        0
growing            8        0        0        1
growing with       9        0        0        1
in                10        1        0        0
in the            11        1        0        0
is                12        1        1        1
is growing        13        0        0        1
is the            14        1        1        0
second            15        0        1        0
the               16        2        1        1
the corpus        17        1        0        1
the first         18        1        0        0
the second        19        0        1        0
this              20        1        1        0
this is           21        1        1        0
with              22        0        0        1
with each         23        0        0        1*

术语频率-逆文档频率(tf-idf)

有很多大家都用的常用词,在某人的写作中不会成为显著特征。例如,“is”和“the”都有一个 文档频率 ( df )等于 3 ( ,它们出现在我们语料库的所有三个文档中),因此,它们不会像具有 df = 1 ( ,它只出现在一个文档中)的术语“growing”那样给我们提供那么多有区别的信息。我们希望对文档出现频率低的术语赋予更高的权重。注意,在计算 df 时,一个术语在文档中出现多少次并不重要,只要它至少出现一次。例如,术语“the”仍然有 df = 3,尽管在语料库中总共出现了 4 次。我们可以通过将术语频率乘以 逆文档频率 ( idf )来应用这个权重。这给了我们 术语频率—逆文档频率 (tf-idf 或 tfidf ):

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

其中 n 是语料库中的文档总数(在我们最后的例子中, n =3)。请注意,等式中“+ 1”的用法因实施方式而异。它们的目的是避免产生零,尤其是在分母中。这里显示的等式是我们即将使用的[TfidfTransformer](https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfTransformer.html)的默认 scikit-learn 实现。

最后,我们希望确保文档的长度不会影响我们的模型。例如,如果一个政客通常比另一个政客写得更短,我们不希望用户能够通过简单地写较长的消息来欺骗我们的模型。因此,我们将标准化每个文档向量,使其平方和等于 1。换句话说,在计算了 tfidf 值之后,我们将把每个文档缩放到一个单位向量

*from sklearn.feature_extraction.text import TfidfTransformer

tfidf = TfidfTransformer()
X_tfidf = tfidf.fit_transform(X_count)
df['doc1_tfidf'] = X_tfidf.toarray().T[df['INDEX'], 0]
df['doc2_tfidf'] = X_tfidf.toarray().T[df['INDEX'], 1]
df['doc3_tfidf'] = X_tfidf.toarray().T[df['INDEX'], 2]
print(df[['INDEX', 'doc1_tfidf', 'doc2_tfidf', 'doc3_tfidf']])*

这为我们提供了下面的 tfidf 表:

 *INDEX  doc1_tfidf  doc2_tfidf  doc3_tfidf
corpus             0    0.227103    0.000000    0.235457
corpus is          1    0.000000    0.000000    0.309598
each               2    0.000000    0.000000    0.309598
each example       3    0.000000    0.000000    0.309598
example            4    0.227103    0.000000    0.235457
example in         5    0.298613    0.000000    0.000000
first              6    0.298613    0.000000    0.000000
first example      7    0.298613    0.000000    0.000000
growing            8    0.000000    0.000000    0.309598
growing with       9    0.000000    0.000000    0.309598
in                10    0.298613    0.000000    0.000000
in the            11    0.298613    0.000000    0.000000
is                12    0.176366    0.280520    0.182854
is growing        13    0.000000    0.000000    0.309598
is the            14    0.227103    0.361220    0.000000
second            15    0.000000    0.474961    0.000000
the               16    0.352732    0.280520    0.182854
the corpus        17    0.227103    0.000000    0.235457
the first         18    0.298613    0.000000    0.000000
the second        19    0.000000    0.474961    0.000000
this              20    0.227103    0.361220    0.000000
this is           21    0.227103    0.361220    0.000000
with              22    0.000000    0.000000    0.309598
with each         23    0.000000    0.000000    0.309598*

注意,即使一些术语在不同的文档中有相同的 tf ,它们也可以有不同的 tfidf

既然我们知道了如何从语料库中提取特征并转换成模型可以理解的格式,我们就可以继续前进,开始训练实际的模型。

训练模型

在前面的例子中,我们查看了一个包含 3 个文档和 24 个词汇的小型语料库。在实践中,如果我们想要开发一个模型来确定一个引用是属于伯尼·桑德斯还是唐纳德·川普,我们将需要更多的文档和更大的词汇表。如前所述,我们将使用他们自 2015 年以来的所有推文。

使用新的 Jupyter 笔记本,让我们从使用 Python 标准库中的[re](https://docs.python.org/3.7/library/re.html)清理推文开始:

*import os
import re
import pandas as pd

def clean_text(text):
    text = re.sub(r"'", '', text)
    text = re.sub(r'http\S+', '', text)
    text = re.sub(r'pic.twitter\S+', '', text)
    text = re.sub(r'\W+', ' ', text.lower())

    return text

df = pd.read_csv(os.path.join('tweets', 'tweets.csv'),
                 low_memory=False)
df.drop_duplicates(inplace=True)
df['tweet-clean'] = df['tweet'].apply(clean_text)
drop_index = []

for i in range(len(df)):
    if df['tweet-clean'].iloc[i] in ('', ' '):
        drop_index.append(i)

df.drop(drop_index, inplace=True)*

我们定义了clean_text,它获取一个字符串,并根据我们之前讨论的需求对其进行清理。然后,我们将数据集加载到一个[pandas.DataFrame](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html)中,并将clean_text应用到每条推文中。最后,在我们的清理过程之后,我们会删除任何现在是空白的推文。在我们训练模型之前,让我们定义两个常数:

*random_state = 0
n_jobs = -1*

注意,通过设置random_state = 0,我们实际上并没有初始化我们的随机种子,而是将一个整数传递给我们的各种 scikit-learn 实现,这将允许我们在每次运行代码时保持相同的随机状态。在调整超参数时,我们希望确保每次测试我们的模型时都生成相同的随机序列,这样我们就可以确定我们看到的任何性能改进都是由于我们所做的更改,而不是由于随机数生成器产生的随机性。

Scikit-learn 支持多线程。今天大多数电脑都使用多核 CPU。我们可以设置[n_jobs](https://scikit-learn.org/stable/glossary.html#term-n-jobs) = -1使用一个 CPU 上的所有线程来加快模型训练。

现在我们将计算推文的矢量化。使用[TfidifVectorizer](https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html)可以将语料库直接转换为 scikit-learn 中的 tfidf 向量,这实际上是一个CountVectorizer后跟TfidfTransformer的管道,两者我们之前都使用过。

*from sklearn.feature_extraction.text import TfidfVectorizer

tfidf = TfidfVectorizer(ngram_range=(1, 2), min_df=2)
X = tfidf.fit_transform(df['tweet-clean'])

print(f'Number of documents: {X.shape[0]}')
print(f'Size of vocabulary:  {X.shape[1]}')*

它为我们的数据集输出一些统计数据:

*Number of documents: 34648
Size of vocabulary:  86092*

为了在整篇文章中保持一致,我们将它们指定为:

  • 文档数量: n = 34 648 条推文
  • 词汇量: v = 86 092 个词汇

我们设置了ngram_range=(1, 2)min_df=2,这表明我们的词汇表将由单词和双词组成,文档频率至少为 2。通过消除文档频率仅为 1 的术语,我们可以减少模型中的特征数量,并减少过度拟合。注意,这种方法在这里工作得很好,因为我们的语料库包含成千上万的文档。这可能不适合较小的语料库,这些参数需要针对每个项目进行专门调整。

就像我们的模型需要以数字的形式接收 tweets 一样,它也需要以数字的形式接收政客的名字。这可以使用 scikit-learn 的[LabelEncoder](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html)来完成:

*from sklearn.preprocessing import LabelEncoder

le = LabelEncoder()
y = le.fit_transform(df['name'])

for i in range(len(le.classes_)):
    print(f'{le.classes_[i]:<15} = {i}')*

它分配以下标签:

*Bernie Sanders  = 0
Donald J. Trump = 1*

在训练我们的模型之前,将我们的数据集分成训练和测试集是极其重要的。训练集将用于训练我们的模型,但重要的是要有一个单独的测试数据集,以真正衡量我们的模型在以前从未见过的数据上有多准确。使用 scikit-learn 的[train_test_split](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html)功能:

*from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y,
                                    test_size=0.5,
                                    random_state=random_state,
                                    stratify=y)*

在这里,我们用test_size=0.5指定我们将保留 50%的数据集作为我们的测试集。我们还设置了[stratify](https://en.wikipedia.org/wiki/Stratified_sampling)=y,以确保我们的测试和训练数据集具有相同的伯尼·桑德斯和唐纳德·川普推文比率。

现在我们已经建立了数据,让我们看看我们的第一个算法。

逻辑回归

逻辑回归是最著名的机器学习模型之一,通常是大多数人在开始机器学习时首先学习的算法之一。标准逻辑函数如下所示:

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

标准逻辑函数。图片作者。

标准逻辑函数接收值 z 并输出 0 和 1 之间的值。我们正在处理一个二元分类问题,这意味着结果必须是伯尼·桑德斯或唐纳德·特朗普,没有其他选择。这就是为什么我们之前给每个政治家分配 0 或 1 的值。

现在让我们看看如何将一条 tweet 转换成一个值:

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

从这个等式中,我们看到 z 等于我们的 tfidf 向量( x )与添加了偏置项( b_0 )的权重向量( w )的点积。注意,虽然 Python 列表从 0 开始索引,但更常见的是在描述数学模型时从 1 开始索引,并为我们的偏差项保留索引 0(有时也会出现为 w_0 )。对于每条推文,我们可以计算一个值 z ,通过逻辑函数传递它,并四舍五入到最接近的整数,得到 0 =伯尼·桑德斯或 1 =川普。为了做到这一点,我们的机器学习算法需要计算出权重向量( w )的哪些值将导致最高比例的推文被归因于正确的政治家。

我们不会探究解决 w 的各种方法,因为这本身就是一篇完整的文章。Scikit-learn 实现了各种求解器来训练一个[LogisticRegression](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html)分类器。在这个应用中,我们将solver='[saga](https://arxiv.org/abs/1407.0202)'设置为我们的优化方法,将C=20设置为我们的逆正则项,以减少过度拟合,并使我们的模型更容易训练:

*from sklearn.linear_model import LogisticRegression

clf_log = LogisticRegression(C=20, solver='saga',
                             random_state=random_state,
                             n_jobs=n_jobs)

clf_log.fit(X_train, y_train)
log_score = clf_log.score(X_test, y_test)
print(f'Logistic Regression accuracy: {log_score:.1%}')*

这返回了我们在测试数据集上的准确性:

*Logistic Regression accuracy: 95.8%*

伯努利朴素贝叶斯

朴素贝叶斯分类器在文本分类任务中相对流行。我们将实现一个称为伯努利朴素贝叶斯的特定事件模型。每个政治家写的特定推文的可能性可以计算如下:

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

其中 p_ki ,是政客 C_k 在推文中使用术语 i 的概率。让我们使用 scikit-learn 的[BernoulliNB](https://scikit-learn.org/stable/modules/generated/sklearn.naive_bayes.BernoulliNB.html)分类器来训练我们的模型,然后看看这些参数代表了什么:

*from sklearn.naive_bayes import BernoulliNB

clf_bnb = BernoulliNB(alpha=0.01, binarize=0.09)
clf_bnb.fit(X_train, y_train)*

现在让我们来看看下面伯尼·桑德斯的名言:

“全民医疗保险” -伯尼·桑德斯

此报价将包含术语“medicare for”。让我们看看这如何转化为上述等式中的参数:

*import numpy as np

C_k = 'Bernie Sanders'
k = le.transform([C_k])[0]
i = tfidf.vocabulary_['medicare for']
p_ki = np.exp(clf_bnb.feature_log_prob_[k, i])
print(f'k = {k}')  # class label
print(f'i = {i}')  # index for term 'medicare for'
print(f'C_k = {C_k}')
print(f'p_ki = {p_ki:.3}')*

它返回:

*k = 0  
i = 44798  
C_k = Bernie Sanders
p_ki = 0.0289*

这里, p_ki = 0.0289 可以解释为在我们的训练集中,来自伯尼·桑德斯的推文有 2.89%包含术语“医疗保险”。关于伯努利朴素贝叶斯有趣的是可以直接求解 p_ki。它简单地等于政治家 C_k 语料库中术语 i 的文档频率除以政治家 C_k 语料库中的文档总数:

*df_ki = clf_bnb.feature_count_[k, i]
n_k = clf_bnb.class_count_[k]
p_ki_manual = df_ki / n_k
print(f'{p_ki:.5}')
print(f'{p_ki_manual:.5}')*

这两者都为我们提供了相同的值,p_ki 有 4 个有效数字:

*0.028924
0.028922*

在逻辑回归中, x 包含 tfidf 值。在伯努利朴素贝叶斯中, x_i 必须等于 0 或 1。最简单的形式是,如果术语 i 出现在 tweet 中, x_i 等于 1,如果没有出现,则等于 0。然而,我们可以通过在我们的 tfidf 值上设置一个阈值来提取更多的信息。最佳阈值通常通过试错法或穷举搜索法找到,例如 scikit-learn 中的[GridSearchCV](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html)。对于这个应用程序,一个最佳的阈值是binarize=0.09。因此,高于 0.09 的任何 tfidf 值被设置为 1,低于 0 的任何值被设置为 0。我们还设置了alpha=0.01,这是一个平滑参数。

回到我们的等式,我们可以看到,如果我们从用户那里接收到一个文档,其中 x_i = 1,那么我们正在乘以术语 i 出现在政治家 C_k 的推文中的概率( p_ki )。相反,如果 x_i = 0,那么我们就在成倍增加这个词 i 不会出现在政客 C_k 的推特上的概率。对词汇表中的每个术语和每个政治家都进行这种乘法运算。然后输出具有最高联合对数似然的政治家作为结果。记住当逻辑函数输出概率时,伯努利朴素贝叶斯输出可能性。这两个术语是相关的,但并不意味着同一件事。这里将不讨论将可能性转换成概率的方法,但是下面的维基百科条目包含了对该主题及其与逻辑回归的关系的简明讨论。此外,BernoulliNB可以使用它的[predict_proba](https://scikit-learn.org/stable/modules/generated/sklearn.naive_bayes.BernoulliNB.html#sklearn.naive_bayes.BernoulliNB.predict_proba)方法将可能性转换成概率。现在让我们计算一下测试数据集的准确度:**

*bnb_score = clf_bnb.score(X_test, y_test)
print(f'Bernoulli Naive Bayes accuracy: {bnb_score:.1%}')*

它返回:

*Bernoulli Naive Bayes accuracy: 96.2%*

整体平均

我们训练了两个模型,逻辑回归和伯努利朴素贝叶斯,这两个模型在测试数据集上都具有相对较高的准确性。使用 scikit-learn 的[VotingClassifier](https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.VotingClassifier.html),我们可以通过使用estimators=[('log', clf_log), ('bnb', clf_bnb)]选择我们的分类器并设置voting='soft'来获得一个更准确的结果,从而获得它们各自计算的概率的加权平均值。通过设置weights=(0.6, 0.4)将 60%的逻辑回归概率与 40%的伯努利朴素贝叶斯概率相加具有最高的准确性。一个有趣的结果,考虑到我们的伯努利朴素贝叶斯有更高的准确性,但我们赋予它更小的权重。这可能是因为来自我们的伯努利朴素贝叶斯分类器的潜在概率估计不一定像来自我们的逻辑回归分类器的概率计算那样可靠。现在让我们训练我们的集合模型:

*from sklearn.ensemble import VotingClassifier

clf_vot = VotingClassifier(
    estimators=[('log', clf_log), ('bnb', clf_bnb)],
    voting='soft', weights=(0.6, 0.4), n_jobs=n_jobs)

clf_vot.fit(X_train, y_train)
vot_score = clf_vot.score(X_test, y_test)
print(f'Ensemble Averaging accuracy: {vot_score:.1%}')*

这返回了我们在测试数据集上的准确性:

*Ensemble Averaging accuracy: 96.4%*

虽然这只是准确性的微小提高,但我们应该记住人们可能会输入不一定是任何一个候选人可能会说的信息。在这些情况下,整体平均可能是有益的,因为这相当于在决定哪位政治家更有可能在推特上发布用户所写的内容之前获得第二种意见。

最终培训

一旦我们确定不再改变任何超参数(,例如*,朴素贝叶斯的阈值,投票的加权平均值,等)。)然后,我们可以在整个数据集上重新训练我们的模型,以获得两倍的训练样本。*

*clf_vot.fit(X, y)*

使用应用程序

我希望你现在对 scikit-learn 如何应用于文本分类有了更好的理解,如果你是机器学习的新手,你现在有兴趣学习更多关于它的知识。

现在您可以亲自试用应用来看看我们实际操作过的模型!

*[## 谁说的?

写一条信息,看看伯尼·桑德斯和唐纳德·川普谁更有可能说出来。

www.shawnchahal.com](https://www.shawnchahal.com/who-said-it)*

确定兼容性

原文:https://towardsdatascience.com/determining-compatibility-b952d941c22a?source=collection_archive---------40-----------------------

配置管理示例

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

在各种行业和商业模式中,公司寻求评估兼容性;例如,关于工业配置管理、合同条款、供应链点、买方和供应商等等。

无论这一过程是与装配、生产还是数据分析相关,都需要检查数百万个组合,以评估组件是否匹配以及是否满足特定要求。大量的数据、复杂的流程和可扩展性问题意味着传统方法效率低下。

本文将展示如何使用 RDFox 使兼容性解决方案正确,迭代次数几乎不明显,并且比其他 RDF 存储快 50-100 倍。它将使用一个工业配置管理解决方案的例子。

例如,参见 Festo 案例研究。或者点击此处跟随配置解决方案网络研讨会

传统解决方案

传统上,SQL 数据库可用于确定兼容性。但是,这个过程很长,需要为每个组件创建表,连接表以形成更大的表,等等。然后使用完整的系统来评估兼容性。

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

确定与 SQL 数据库的兼容性

由于可能有数以千计的组件具有许多不同的特征,并且没有通用的模式,因此这个过程极其复杂并且令人厌倦,可扩展性有限。对于包含数万个组件的数据库,这个过程可能需要几个小时。

对于有时间压力和限制的企业来说,这带来了挑战,并可能限制竞争活力。每次添加或删除组件时,整个系统都需要更新,导致开发或修改过程中的长时间迭代。

为什么是 RDFox?

RDFox 是一个高性能的知识图和语义推理引擎。知识图由存储数据的图形数据库和解释并操作数据的推理层组成。关系数据库(如上面的 SQL 示例)以严格的表格结构存储数据,而图形数据库以节点(数据点,即主体或客体)和边(数据点之间的关系)的形式存储信息。这些结构差异为需要计算兼容性的用例提供了显著的优势,因为知识图克服了关系数据库的灵活性限制,允许将数据点编码为丰富连接的实体。

RDFox 是一个内存解决方案,这使得它非常快。强大的推理引擎在效率和推理能力方面无与伦比,通过使用规则,它可以提供灵活、增量的数据添加和撤销,以及新事实的快速并行具体化。

但是在配置解决方案的上下文中,推理意味着什么呢?

在这种情况下,推理就是理解和应用组件如何装配以满足客户需求的逻辑。

配置挑战

“给我造一个能以每分钟 2000 转的速度旋转并提供 800 克/厘米扭矩的装置”

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

一个基于 RDFox 的配置管理界面的例子。

对于这个例子,我们已经创建了一个简单的配置管理 web 应用程序,它允许我们查询数据库以获得提供特定需求的配置解决方案。结果是实时更新的,可以在右边看到。

对于一个包含数万个组件的数据库,包括电机、齿轮、开关、电源和控制器,我们需要检查数百万个潜在的组合来确定兼容性。这是通过计算组件是否匹配以及它们是否满足彼此的要求来完成的。每个组件都有一定的要求,并负责一定的规定;例如,如果电池电源和电机需要兼容的电压量。

为了开始这个过程,我们将每个组件的属性映射到知识图中。在这个例子中,我们有 500 个组件。

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

每个组件都会添加到图表中。此图提供了一个特定的 DC 发动机及其规定和要求的示例。

此外,我们可以向图中添加组件的本体。这将捕获组件层次结构并编码到系统中,提供子类和关系。在为特定配置解决方案查询数据集的过程中,以及在编写规则时,使用本体是有帮助的。

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

一旦所有组件的数据都存储在知识图中,我们就可以使用推理能力来建立组件的兼容性。使用 datalog 中表达的规则,我们可以轻松、正确地将组件兼容性的逻辑写入系统。

规则允许将组件的约束与组件属性进行比较,从而确定兼容性并为兼容性解决方案提供选项。然后,兼容的配置解决方案可以作为节点(数据点,在这种情况下是组件)之间的新边(关系)存储在知识图中。

这是 datalog 中兼容性规则的一个示例,可能会导致以下结果:

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

在检查这个特定的规则时,很明显规则是逻辑的表达式,datalog 提供了一种清晰的语言来编码规则。规则读作“如果…那么”语句。例如:左边的公式:- operator 是规则头*(then '部分 ) ,右边的公式是规则体(’ if '部分)。*

直觉上,这个规则说,如果电源提供 DC 电压、特定量的电压和特定量的电流,而电机需要 DC 电压、相同量的电压和相同量的电流,那么这两者是兼容的。该示例显示了这两个组件基于组件的要求和规定是相互兼容的。

此示例仅代表一个配置序列。然而,该数据库包含 500 个组件和许多兼容性链。如果所有配置解决方案都经过计算并具体化到数据库中,那么配置解决方案将有多种途径,例如:

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

可以构建 Web 应用程序并将其附加到 RDFox 控制台,允许用户与知识图进行交互,而不必编写 SPARQL 查询。这对于要求整个公司的每个人都能够正确、快速地访问信息的企业来说有着重大的好处。通过在左侧的“搜索参数”框中键入搜索约束,将触发一个 SPARQL 查询,从知识图中请求信息。

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

配置管理应用程序

或者,不使用 web 应用程序,您可以使用 RDFox 的控制台直接与知识图交互。RDFox 使用 RDF 标准查询语言 SPARQL,它向知识图发送信息请求。

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

带有兼容性查询的 RDFox 控制台

上面的控制台包含使用示例数据库的配置解决方案的查询。查询表明选择了特定的扭矩和速度要求。该查询获取了 47 个答案,并在 0.702 秒内执行—眨眼之间,它就出现了!

通过使用规则,RDFox 可以在查询时间之前计算配置解决方案的所有兼容性。这种高级功能意味着查询比其他知识图解决方案更快,从而提高了企业的效率,因为解决方案提供得更快。这对用户体验和客户满意度产生了间接影响。不使用规则的系统将不得不在查询过程中确定兼容性,导致结果明显变慢。

添加或删除新项目时会发生什么?

在现实世界的应用程序中,组件将被添加到数据库中或从数据库中删除。这对使用长迭代周期数据库的公司来说是一个很大的限制。

新的组件数据可以在任何时候导入到 RDFox 中,同时还有它的兼容性规则。由于 RDFox 以增量方式处理更新,因此可以在不需要整个系统更新的情况下添加。

类似地,要删除一个组件,需要告诉 RDFox 删除它。一旦从数据中删除了组件,从该组件到其他组件(节点)的所有关系(边)也将被逐渐删除。

如果约束条件改变了呢?

与添加组件数据的过程类似,可以更新规则。这对于必须满足不断变化的约束(如预算、环境、需求等)的公司和客户来说非常重要。

这个增量特性是 RDFox 所独有的,并且提供了巨大的好处,因为它允许从应用程序中实时添加或删除规则和数据;例如,当组件不再生产、进货或缺货,或者产品被召回时。与其他兼容性解决方案相比,RDFox 在不影响性能的情况下提供灵活性的能力非常重要。

整体情况:

1.数据和规则进去了

2.RDFox 评估规则

3.使用 RDFox 控制台或基于该控制台构建的 web 应用程序,通过 SPARQL 查询来访问轮换解决方案。

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

知识图为数据建模提供了绝对的灵活性,因为规则可以对领域专业知识进行编码,并且可以定制以适应每个公司的需求。有关这一特定使用案例的更多信息,请观看网络研讨会。

要了解更多关于 RDFox 的信息,请访问我们的网站媒体出版物。要申请评估许可,请点击此处

团队和资源

牛津语义技术背后的团队于 2011 年在牛津大学计算机科学系开始研究 RDFox,他们坚信灵活和高性能的推理是数据密集型应用的一种可能性,而不会危及结果的正确性。RDFox 是第一个面向市场的知识图,它是从底层开始设计的,并考虑到了推理。牛津语义技术公司是牛津大学的一个分支,由主要投资者支持,包括三星风险投资公司(SVIC)、牛津科学创新公司(OSI)和牛津大学的投资部门(OUI)。笔者很自豪能成为这个团队的一员。

封面照片由作者在征得其子女同意后使用的主题。

利用加权 K-均值确定最优配送中心位置

原文:https://towardsdatascience.com/determining-optimal-distribution-centers-locations-using-weighted-k-means-1dd099726307?source=collection_archive---------20-----------------------

寻找在美国分发新冠肺炎疫苗所需的 DC 的位置和最佳数量

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

Unsplash 上的 CHUTTERSNAP 拍摄

背景

在座的各位一定听说过亚马逊及其近年来的增长。亚马逊成功的主要原因之一是其供应链管理。所有至少从亚马逊订购过一次的人都应该熟悉他们广受欢迎的 1 日送达服务。有没有想过像亚马逊这样的公司如何能如此迅速地将产品送到美国的任何地方?

考虑到美国广袤的土地和他们每天从全国各地收到的订单数量,这不是一个简单的任务。事实证明,你订购的大多数产品都是直接从你所在的州发货,而不是从其他地方。所有像沃尔玛、亚马逊这样的公司都会根据客户需求预测,在配送中心储存客户不急需的剩余产品。

所有的服务,如产品混合、订单履行、跨站台、包装都在配送中心完成。这些 DC 的位置便于在最短的时间内将货物运送到最大的区域。任何公司要想取得成功,有效的供应链战略是必不可少的,而 DC 在供应链战略中扮演着至关重要的角色。

问题

9 月 24 日,美国的 COVID 19 例病例总数已突破 700 万大关。另一方面,许多国家,如英国,声称他们的新冠肺炎疫苗开发已进入最后阶段,将于 2020 年底发布。我认为了解疫苗何时最终发布并在所有医院分发会很有趣,包括美国治疗新冠肺炎患者的临床中心。如果美国政府计划利用配送中心向所有治疗新冠肺炎患者的医院提供疫苗接种,DC 的配送中心应该设在哪里?需要多少个 DC?

首先,我从维基百科的一些网络垃圾开始,得到美国所有医院的地址和郡名。并将医院区域的县名与该区域中活跃的新冠肺炎病例进行匹配。为了使绘图和查找距离更容易,我使用地理编码找到了所有地址的纬度和经度,对此我在之前的博客中清楚地解释了步骤。

[## 使用 Python 进行地理编码和反向地理编码

当地址已知时查找纬度和经度,或者如果纬度和经度是…

towardsdatascience.com](/geocoding-and-reverse-geocoding-using-python-36a6ad275535)

找到所有医院的经纬度后对数据集的一瞥

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

图一。美国医院位置数据

既然我们有了纬度和经度,就很容易把它们标绘出来。下图显示了美国所有使用 python 中的 follow 地图生成的活跃新冠肺炎病例的医院。

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

图二。美国有活跃新冠肺炎病例数的医院位置(图片由作者提供)

这里,圆圈较大的点代表新冠肺炎活跃病例较多的区域。可以清楚地看到,加利福尼亚州的一些地区的活跃病例数最高。回到我们的问题,我们正试图找到配送中心向所有医院供应疫苗的最佳位置。这里,为特定医院确定 DC 的位置类似于将所有医院分成不同的集群,并为每个医院集群定位一个质心点。这种情况与 K-Means 聚类算法非常相似。因此,可以应用 K-均值聚类。

(标准)K 均值聚类是如何工作的?

K 均值聚类是一种流行的无监督 ML 算法,用于将数据划分为 K 个聚类。该算法反复工作,将每个数据点分配给 K 个组中的一个。数据被随机分成 K 组,每组分配一个平均质心点,算法迭代以找到:

  1. 所有数据点到质心点之间的距离,并通过将数据点重新分配到其最近的质心来形成新的聚类。
  2. 再次通过取距离的平均值找到新的质心点。

重复这个过程,直到距离平方和最小,或者达到预定的极限。

在开始 k-means 之前要执行的一个重要步骤是决定聚类的数量。K 的数量是一个预定义的超参数,应该对其进行调整以获得最佳结果。这可以使用肘方法来完成,本文稍后将对此进行简要说明。

这是一个通用的算法,可用于任何分组。用例的一些例子是基于需求的库存分组或基于购买的客户细分。

解题:

我们在这里的唯一问题是,应该更多地优先考虑新冠肺炎病例更活跃的地点。这就是加权 K 均值聚类发挥作用的地方。

标准的 K-means 方法不会起作用,因为它没有考虑到这样一个事实,即医院所在的一些地区有更多活跃的新冠肺炎病例,这意味着对要供应的疫苗有更高的需求量。

加权 K 均值与标准 K 均值有何不同?

加权 K-均值与标准 K-均值聚类的工作原理相同。唯一的区别是,不是仅仅根据距离的平均值来计算质心点。应该使用加权平均值。因此,数据点的权重越大,质心将被拉得越近。下图显示了标准 K 均值和加权 K 均值的对比。这里,在右图中,W2 和 W3 的数据点权重较高。所以,质心被拉着它们而不是位于中心。

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

图三。不带权重的左侧图像与带权重的右侧图像(作者提供的图像)

权重可以赋予我们想要从数据集中得到的任何变量,如城市或城市的总人口。在我们的例子中,权重将给予每个县的总活跃新冠肺炎病例。所以应该给他们更多的优先权。

另一个问题是,我们不能使用传统的欧几里德距离作为距离度量来寻找质心点,因为我们有代表地球球面维度的纬度和经度,而不是欧几里德距离中的 2D (x,y)坐标。许多选项可用于计算两个球形点之间的距离,如哈弗线距离或大圆距离。我们将使用哈弗线距离。

哈弗森距离

哈弗线距离 d 可以用下面的公式求出,其中φ代表纬度,λ代表经度。

A = sin((φB—φA)/2)+cosφA * cosφB * sin((λB—λA)/2)

c = 2 * atan2( √a,√( 1a))

d = R ⋅ c (R =地球半径,即 6371 公里)

幸运的是,我们不需要使用所有这些公式来计算哈弗辛距离,因为在 python 中,有一个名为哈弗辛的库,它用一行代码直接计算位置坐标之间的距离

from haversine import haversine
haversine((31.215827,-85.363433),(28.703230,-81.815668))

使用具有哈弗线距离的加权 K-Means 作为距离度量,创建了一个改进的加权 K-Means 算法,可以在我的 Github 库中找到。

最后,我们需要确定配送中心的最佳数量,以更好地满足需求并最小化配送费用。即 k 的最佳数量。这可以使用肘方法来确定。

肘法

在聚类分析中,肘方法是一种启发式方法,用于确定数据集中聚类的最佳数量。计算’ k’ 的不同值的组内误差平方和(SSE)。对于而言,无论哪个**‘k’值 WSS 首先开始变小,都选择那个特定的‘k’**。通常,形成弯头形状的 K 值被认为是最佳值。SSE 只不过是所有聚类中每个数据点到各自质心的距离的平方和。下图显示了 SSE 与我们数据的聚类数的关系。因为在 4 个聚类之后 SSE 值的降低不再显著。K=4 可以被认为是我们的最佳 K 值。

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

图 4。确定最佳聚类(K=4)的肘方法(图片由作者提供)

最后,我们发现 4 是所需配送中心的最佳数量。在用 4 个集群实现了我们的算法之后,DC 发现的位置如下所示:

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

图五。美国最佳配送中心位置(图片由作者提供)

实施该算法后发现的推荐 DC 位置为:

  1. 加州河滨
  2. 德克萨斯州达拉斯
  3. 伊利诺伊州厄巴纳
  4. 弗吉尼亚州彼得斯堡。

结论

在本文中,应用加权 K-均值聚类算法来确定最佳分布位置进行了演示。综上所述,在这种改进的 K-Means 聚类中,通过考虑加权平均值而不是平均值来计算质心,并且使用哈弗斯距离而不是欧几里德距离。

希望那有用!如果你有任何问题,请随时在 LinkedIn 上给我发信息。并且代码可以在我的 Github 库中找到。

德国联邦议院:谁是我们的代表?

原文:https://towardsdatascience.com/deutscher-bundestag-who-are-our-representatives-85a0e0c9669a?source=collection_archive---------46-----------------------

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

联邦议院:德国政治体系的议会和中央机构

利用主题建模和无监督学习分析第 19 届德国联邦议会

政治过程和政治机构的透明度是民主制度的关键要素。德国政治的核心机构是联邦议院,有来自六个不同政党的 700 多名议员。联邦议院通过法律,监督联邦预算,选举联邦总理。此外,全体会议是德国政治体系中交流政治立场和意见的核心小组。

但是组成议会并代表德国人民的 700 多人是谁呢?虽然联邦部长和一些选定的政治家经常出现在媒体和报刊上,但议会的大多数成员对普通公民来说实际上仍然是匿名的。

如果仔细观察德国的选举制度,这一观察结果会更加引人注目。对于德国议会的选举,每个选民投两票。在第一次投票中,地方代表被直接选举并送往议会,而第二次投票则是为政党名单投票。

为了确保透明度,议会讨论在电视上播出,每次辩论后都公布书面记录。然而,只有少数选民有时间和资源密切关注议会辩论,并在很大程度上依赖媒体报道。因此,几乎没有选民知道他们的地方代表在做什么,更不知道他或她在说什么,而这些地方代表实际上是被派到议会来代表他们的。

这个数据科学项目旨在通过应用机器学习和自然语言处理(NLP)的技术,进一步提高德国议会及其成员的透明度。项目的最终结果被可视化为 Tableau Public 上的一个交互式仪表盘:

桌面上的仪表盘公共(英文)(针对桌面优化&链接仅在桌面浏览器中有效)

【Dashboard on Tableau Public(德语)(针对桌面优化&链接仅在桌面浏览器中有效)

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

交互式 Tableau 仪表盘可视化结果摘录

该控制面板公开提供,并提供以下使用案例:

  • 了解每位议员的政治专业领域
  • 探索政党/政治家讨论的主题以及它们如何随着时间的推移而演变
  • 确定涉及类似主题的跨党派议员
  • 通读个别议员的全会发言

项目方法

在这个项目中,用 Python 分析了联邦议院的全体辩论,以得出关于个别议员的结论。为此,使用一种称为主题建模的 NLP 技术来检查全体会议演讲,以识别演讲中的潜在主题。使用主题洞察,然后通过应用无监督聚类将政治家分组到政治领域中。最后,开发了一种启发式方法来识别具有相似主题简介的对等组。

数据汇总

该项目的数据来源是第 19 届联邦议院从 2017 年 10 月 24 日首次会议到 2019 年 7 月 24 日夏季休会前最后一次会议的 109 份全体会议讨论记录。

德国议会已经在其网站上发布了自 1949 年德意志联邦共和国成立以来所有全会讨论的文字记录。然而,只有第 19 届联邦议院的 XML 文本包含了详细的标记,可以清楚地区分演讲和各自的演讲者。

使用 Python 库 Selenium 和 Beautiful Soup 对抄本进行抓取和解析,以提取日期、发言者姓名、政党和各自的发言等信息。然后,这些数据经过清理,并增加了额外的信息,最终得到一个由 717 位政治家的逾 1 万篇演讲(约 650 万字)组成的数据集。

请注意,第 19 届联邦议院正式成员为 709 人。这种差异可以通过以下偏差来解释:

1.当前内阁中在议会中没有正式席位的联邦部长也包括在数据集中。

2.根据某些议员的退出日期,数据中可能只反映前任、继任者或两者。

3.对于一些议员来说,在相关时间段内没有确定的发言。

主题建模概念

非负矩阵分解(NMF)是线性代数中的一种算法,应用于自然语言处理中,从一组文档中提取潜在的主题。

来自 NMF 的主题模型的基线构建了文档-术语矩阵 A。A中的每行描述了术语在文档中的出现频率,即每行代表一个文档,每列代表一个术语(文档 x 术语)。在 NLP 中,文档是文本的术语,术语是单词的术语。

NMF 算法将文档项矩阵 A 分解成仅具有非负值的两个矩阵,两个矩阵的乘积以最低误差再现原始矩阵。两个结果矩阵是文档-主题矩阵 H(文档 x 主题)和主题-术语矩阵 W ( 主题 x 术语)。

A(文档 x 期限)≈ H(文档 x 题目)x W(题目 x 期限)

直观地说,文档-主题矩阵 H 描述了文档中的主题是什么,而主题-术语矩阵 W 描述了特定主题中哪些词被频繁使用。

文本预处理

要使用 NMF 主题建模生成有意义的结果,需要几个预处理步骤,这些步骤按如下方式实现:

  • 通过删除标点符号、将所有单词转换为小写字母并排除所有数字来清理演讲
  • 通过应用 Python 的 NLTK 库中的德语停用词表,停用词(最常见的词)被移除。此外,用经常出现的上下文含义较低的单词手动扩展列表
  • 词干分析(将单词缩减为单词库)是通过应用 NLTK 雪球斯特梅尔公司的德语模块来完成的

然后,通过应用 sklearn 的 TF-IDF 矢量器,将议会演讲转换成文档术语矩阵。与简单的单词包方法(只统计单词在文档中的出现次数)相比,TF-IDF(术语频率-逆文档频率)减少了在所有文档中频繁出现的单词的影响。结果,具有高信息增益的单词在文档中也具有相对较高的权重。

话题识别

事实上,NMF 主题建模是一种矩阵分解技术,并不提供关于底层文本中存在多少主题或者主题的上下文含义是什么的指导。因此,这些步骤需要手动实现。

为了确定全体会议发言中的主题,将 sklearn 的 NMF 模块应用于先前创建的文件术语矩阵。这产生了各自的文档-主题和主题-术语矩阵。然后,对于主题-术语矩阵中的每个主题,手动检查具有最高权重的单词,即对于该主题最重要的单词。基于这种分析,每个主题被识别和命名。

例如,权重最高的词是“银行”、“贷款”、“存款保险”、“银行联盟”、“欧洲央行”、“纳税人”、“风险”、*“金融危机”、*等。(德语中这些都是单字)定义为“金融体系”。

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

9 个主题及其前 20 个单词的摘录(德语)

由于主题模型中的主题数量需要手动设置作为算法的输入,所以对不同数量的主题重复该过程,以识别在主题内的上下文一致性方面产生最有意义的结果的数量。对于联邦议院的演讲,选择了一个包含 35 个不同主题的模型。

在识别和命名每个主题后,文档-主题矩阵指示每个演讲涉及的主题。每个演讲都是所有 35 个主题的组合,其中一些主题的权重高于其他主题。

语音聚合

为了不仅对演讲,而且对议员个人产生洞察力,对每个政治家的主题信息(演讲中每个主题的权重)进行总结。议员的发言通过将发言中的主题权重之和缩放至 100%并取所有发言中主题的平均值来汇总。

聚类分析

这种汇总显示了每个议员在 35 个确定的主题中所占的份额。虽然这些信息本身就已经很有见地,但仍然相对难以解读,因为 35 个不同的主题很难同时掌握。此外,只有将几个话题结合起来,才能对政治家关注的政治领域得出有意义的结论。

因此,每位议员都根据其演讲的主题被分配到一个特定的政治领域。为此,使用 sklearn 的 KMeans 模块应用 k-means 聚类(无监督学习)。

直观上,k-means 分割一个数据集,将具有相似特征的数据点分配到一个组(聚类)中。基于距离度量(在这种情况下是欧几里德距离)来评估特征的相似性。该算法以这样的方式定义聚类,使得数据点到相应聚类质心的距离(一个聚类中所有数据点的特征的平均值)最小化。

通过将每个议员的话题权重作为特征,每个代表被反映为 35 维空间中的一个数据点。这些特征随后被用于对政客进行聚类。最后,手动检查每个聚类质心的主题份额,以分配政治领域。

例如,在“f 金融系统(11%)、“联邦预算(10%)、“经济(10%)中具有最高份额的集群被定义为“经济/金融政策”。

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

4 个集群的摘录和各自的前 8 个主题(按权重)

与主题模型类似,k-means 中的聚类数需要手动选择,并且通过手动检查不同数量的聚类的结果来选择。这导致 15 个不同的政治领域集群。

为了可视化聚类分析的结果,在最后一步中,通过使用来自 sklearn 的 TSNE 模块应用 t-SNE 维数缩减,将 35 维空间缩减为二维空间。

同等群体分析

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

同行群体分析的示例性结果(针对联邦总理安格拉·默克尔)

仪表板的一个用例是显示具有相似主题简介的不同政党的议会成员,即涵盖相似主题范围的政治家。为此,为每个政治家构建一个对等组,该对等组由来自每个政党的三名议会成员组成,基于 35 维主题向量具有最近的欧几里德距离。

可视化&验证

最后,分析的结果被可视化在一个 Tableau 仪表板中,可以交互地用于更好地理解联邦议院及其政治家。

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

联邦部长和国务秘书的集群分配

同时,仪表板提供了验证分析结果的机会:

  • 按党派划分份额最高的主题似乎是合理的,例如环境/能源对于邦迪尼斯 90/迪格鲁 NEN劳工对于迪克林以及数字化对于 FDP
  • 联邦部长和国务秘书的集群分配基本上与各自的度假胜地一致
  • 同辈群体似乎是合理的,例如,对于联邦总理安格拉·默克尔来说,同辈群体包括海科·马斯安东·霍夫赖特克里斯蒂安·林德纳莎拉·瓦根克内希特亚历山大·高兰

最终,我们希望该项目能够为提高德国政治环境的透明度做出自己的贡献,使选民能够做出更明智的决定,并增强对民主制度的信任。

一个 GitHub 项目的资源库可以在 这里找到

免责声明:本文仅代表作者个人观点,不代表作者雇主的工作或观点。

开发一个图像到图像的转换模型,以捕捉机械网络(GAN)中的局部相互作用

原文:https://towardsdatascience.com/develop-a-image-to-image-translation-model-to-capture-local-interactions-in-mechanical-networks-9c2f45230849?source=collection_archive---------45-----------------------

入门

生成式对抗网络,用于在各种机械网络的图像上自动绘制链接。

概观

超材料是一种机械性能依赖于其结构的材料,这种结构赋予了它们传统系统中没有的变形模式。超材料的一个流行模型由通过机械链接相互连接的构建模块组成,这定义了材料的结构。这些被称为机械网络。两个机械网络的不同之处在于:

  • 积木是如何连接的。这将定义我们处理的系统类别(例如 Kagome 系统、正方形、三角形等…).
  • 区块在空间中的分布情况,即区块之间的距离。

换句话说,为了对系统进行分类并掌握其机械特性,了解块体的位置和连接性是至关重要的。通常情况下,机械网络可以用一个晶格表示 : (也称为位置)来直观地描述,代表建筑块,并通过(也称为边)连接。在研究界经常被考虑的一个典型的机械网络是 Kagome 系统,如下图所示。

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

Kagome 点阵:点(黑点)由边(直线)连接。图片作者。

问题陈述和方法

在某些情况下,特别是在处理微观超材料时,用户/研究人员将只处理构件(点)的图像,连接键太小而无法检测,但仍然存在并对系统的机械性能有贡献。该项目旨在使用深度学习和神经网络在仅包含点的图像上自动绘制出键连接。

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

用户仅提供块的图像;模型绘制连接键。图片作者。

为此,我们将使用 Jason Brownless 博士的文章介绍如何开发一个生成式对抗网络(GAN) 作为图像到图像算法。该模型仅通过对三种不同机械网络(Kagome、三角形和正方形网格)的 90 张图像进行训练,就成功地在看不见的系统图像上绘制了连接键。虽然结果相当惊人,但了解该模型的架构也同样令人着迷。

用于训练/测试/验证模型的数据包括由 Mathematica 生成的图像,Mathematica 是一个经常用于研究和学术社区的程序。提供的每个图像实际上由一对图像组成,分别是具有和不具有结合的相同系统(即,点在空间上相同分布)。然后,我们选择 30 个随机生成的 Kagome 点阵,以及另外 30 个正方形点阵和 30 个三角形点阵:

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

无键和有键的变形正方晶格。图片作者。

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

变形的三角形晶格,有键和无键。图片作者。

这里使用的代码显然是由 Python 编写的,并且主要依赖于包 Keras (以及常见的嫌疑人 numpymatplotlib )来构建和训练多个神经网络。笔记本(可以在这里找到)是通过 Google Colab 编写的,它允许我们利用 Google 的 GPU 服务。

生成对抗网络

GAN 的架构由两个以对抗方式训练在一起的主要模型组成——鉴别器和生成器——以及将它们绑定和训练在一起的其他功能

鉴别器

鉴别器是一个深度卷积神经网络(CNN) ,它获取图像形状并执行条件图像分类。总之,它获取源图像(无焊接)和目标图像(有焊接),并分类目标是否是源的真实转换。在被传送到网络之前,这两幅图像被连接成一幅图像。

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

鉴别器模型。图片作者。

深度 CNN 由 6 层组成,每一层都缩小前一层的输出图像,以输出一个分数,该分数用作分类度量

发电机

生成器遵循 U-net 架构,由三部分组成:编码器(收缩)、瓶颈和解码器(扩展)。

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

发电机型号。Jason Brownless 关于机器学习掌握的图片。

  1. 编码器部分由多个对输入图像进行下采样的模块组成。每个块都是一个卷积层,具有数量不断增加的过滤器。
  2. 相反,解码器由几个扩展模块组成,滤波器数量不断减少。重要的是,每个扩展层的输入既有前一个扩展块的输出,也有相应收缩块的输出。这确保了在编码阶段学习的特征被重新用于在解码阶段重建图像。
  3. 瓶颈部分连接编码和解码部分。

复合模型和训练模型

生成对抗网络是一个同时包含鉴别器和生成器的复合模型。当生成器通过鉴别器更新其权重时,鉴别器不被训练并“自己”更新其权重。关键特征是,与生成器相比,鉴别器的权重更新需要较慢,因此生成器可以快速学习绘制焊接。

每个训练步骤包括使用复合模型以及来自训练数据的“真实”图像和来自生成器的“虚假”生成图像。这个想法是,真实目标和假生成图像的组合,分别被分类为 1 和 0,将帮助生成器建立一个模型,更快地收敛到一个解决方案。

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

GAN 的整体架构及其训练方式。图片作者。

这个模型中有许多可调参数和复杂的设计。为了保持这篇文章的简单和可读性,我故意忽略了代码的复杂性,但是请读者查看我的 Github 库以获得更多细节。

结果

我们在 90 幅图像上训练该模型,分成 3 批,这意味着在每个时期的每批中随机抽取 30 幅图像。我们选择在 500 个历元上训练模型,这意味着总共有 500 x 30 = 15,000 个迭代步骤。虽然在本地机器上训练模型可能需要长达一天的时间,但谷歌 GPU 将这一过程加快到不到 2 小时!通过迭代过程,我们显示了从训练数据集中随机抽取的样本的生成图像:

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

通过模型训练生成的图像(随机选择)的演变。图片作者。

对照模型自己的训练集测试模型不是检查其性能的好选择,但它让我们了解生成功能执行得有多好。因此,我们还需要展示模型如何处理看不见的数据:

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

验证集:戈薇,正方形和三角形格子。图片作者。

最初,我的目标是只针对 Kagome 类构建模型。然后,我决定扩大模型的应用范围,将正方形和三角形格子包括在内:

  • 顶行:第一个模型仅在 Kagome 系统的图像上进行训练,显然在绘制正方形和三角形的连接方面存在困难
  • 底部一行:第二个模型包含了所有三个格子,产生了更好更重要的结果

非常重要的是,除了绘制键之外,第二个模型还保持所生成图形上的点的位置,这是一个必须保持不变的关键属性,因为这些点的位置决定了系统的机械属性(如上所述)。

结论和进一步改进

通过只对 90 对图像进行训练,该模型可以获取部分完整的机械网络的看不见的图像,并绘制正确的键连接,这是理解系统力学的关键特征。这样做,模型不会改变材料的基本属性(点/块的位置),并为研究者提供额外的信息。令人兴奋的是,该模型能够在不止一个,而是三个机械系统上区分和执行其图像到图像的翻译功能:Kagome,正方形和三角形晶格。

虽然这是一个令人满意的结果,但是可以做许多事情来提高模型的性能。特别是,我们可以:

  • 在更大的一组图像上训练模型并持续更长的时间(更多的时期)
  • 扩大训练批次,以包括额外的超材料类别,特别是更复杂的结构,如每个站点的平均连接数比我们迄今为止看到的更多

参考文献和致谢

同样,代码、幻灯片和报告可以在这里找到。所有图片(除非另有说明)均由作者制作。我要特别感谢我在 Springboard 的导师卢卡斯·艾伦(Lucas Allen),感谢他在这个项目中的指导。我还要感谢 Brownlee 博士在帮助开发人员构建机器学习模型方面的多个在线教程。

[1] J. Brownlee,如何开发一个 Pix2Pix GAN 用于图像到图像的翻译 (2020),机器学习之谜

开发基于 CNN 的交互式绘图识别应用程序——使用 Flask 部署

原文:https://towardsdatascience.com/develop-an-interactive-drawing-recognition-app-based-on-cnn-deploy-it-with-flask-95a805de10c0?source=collection_archive---------20-----------------------

数据科学项目

关于数据科学项目的基本技术的快速简单的教程。

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

照片由 Dries AugustynsUnsplash 拍摄

建立机器学习模型是一项常见的任务,你可能会觉得很舒服。然而,一旦你离线训练和测试的模型让你满意了,你该怎么做呢?你会如何向你的非技术型老板或客户展示它?你将如何在线部署它,以便其他人可以使用它?

在本文中,我将尝试解决那些在学校里通常不会详细讨论的问题,尽管这些问题是数据科学项目中非常重要的一部分。

为此,我决定以一个绘图应用程序为例,它使用一个卷积神经网络模型对用户绘制的绘图进行分类。

工作流程如下:

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

我将首先介绍模型,然后描述应用程序的开发。通读之后,我希望本文对您未来的数据科学项目部署有所帮助!

以下所有代码都可以在我的 github 上找到。

CNN 模型

这个项目的第一部分是准备数据和建立我们的模型!

我已经决定使用来自*的数据,‘快,画!’*游戏中用户需要尽可能快地绘制任意对象。数据集在这里可用。

我将我的用例集中在 6 动物上:猫、长颈鹿、羊、蝙蝠、章鱼和骆驼,使任务成为多类分类。下面是一个数据示例:

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

预处理

幸运的是,来自这个数据集的图像已经被预处理成统一的 2828* 像素图像大小。以下是接下来的步骤:

  • 我们需要结合我们的数据,以便我们可以使用它进行培训和测试。我只为这个模型使用了 10 000 个样本。
  • 然后,我们可以分割要素和标注(X 和 y)。
  • 最后,我们按照通常的(80–20)比率在训练和测试之间分割数据。当灰度图像的像素位于 0 和 255 之间时,我们还归一化了 01 (X/255)之间的值。

预处理. py

架构

一旦一切准备就绪,让我们使用 Keras 建立我们的模型!该模型将具有以下结构:

  • 卷积层 : 30 个滤波器,(3 * 3)内核大小
  • 最大池层数 : (2 * 2)池大小
  • 卷积层 : 15 个滤波器,(3 * 3)内核大小
  • 最大池层 : (2 * 2)池大小
  • 脱落层:脱落 20%的神经元。
  • 展平图层
  • 密集/全连接层 : 128 个神经元,Relu 激活功能
  • 密集/全连接层 : 50 个神经元,Softmax 激活功能

下面是相应的代码:

Cnn 模型

现在我们的模型已经准备好了,我们只需要训练它并评估它的性能。

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

经过 15 个时期后,我们的分类器达到了 92.7% 的准确率,这对于我们的识别 app 来说已经足够了!让我们检查一下混淆矩阵。

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

正如我们所看到的,大部分的画都被很好的分类了。然而,有些类别似乎比其他类别更难区分:例如,猫与蝙蝠或骆驼与羊。这可以用它们形状的相似性来解释!

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

这是一些被我们的模型错误分类的图片。这些图像中的大部分很容易被误认为是错误的,甚至是被人眼误认为是错误的!别忘了我们的数据集收集了玩**‘快,画吧!’的手工人类图画**游戏。因此,许多图像可能与一个类无关。

保存模型

现在我们的模型已经准备好了,我们想把它嵌入到一个Flask Web App中。为此,使用 pickle 保存(序列化)我们的模型会更方便。

注意:你可以直接将你的模型训练到 flask 中,但是这将会非常耗时,而且对用户不友好。

**import** **pickle**
**with** open('model_cnn.pkl', 'wb') **as** file:
      pickle.dump(model_cnn, file)

用 Flask 开发我们的绘图应用程序

烧瓶

Flask 是一个用 Python 编写的 web 微框架。它允许你设计一个可靠和专业的 web 应用程序。

它是如何工作的?

虽然它不需要特定体系结构,但是有一些好的实践可以遵循:

  • app.py :是运行 Flask 应用程序的主要代码。它将包含我们的应用程序的不同路由,响应 HTTP 请求并决定在模板中显示什么。在我们的例子中,它还会调用我们的 CNN 分类器对我们的输入数据进行预处理步骤,并进行预测
  • 模板文件夹:模板是一个 HTML 文件,可以接收 Python 对象,链接到 Flask 应用。因此,我们的 html 页面将存储在这个文件夹中。
  • 静态文件夹:样式表、脚本、图片等永远不会动态生成的元素必须存放在这个文件夹中。我们将把 Javascript 和 CSS 文件放在里面。

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

该项目将需要:

  • 两个静态文件: draw.jsstyles_draw.css
  • 两个模板文件:draw.htmlresults.html
  • 我们的主文件: app.py
  • 我们的 model_cnn.plk 早存了。

现在,让我们来构建我们的应用程序吧!

获取用户输入

这个项目的第二部分是获得用户输入**:一个将被我们训练好的模型分类的绘图。为此,我们将首先使用 javascriptHTML5 设计绘图区域。我不会在本文中介绍 styles_draw.css 但是你可以在我的 github 上找到它。**

draw.html

draw.html

  • 我们使用{{url_for('static',filename='styles_draws.css’)}}{{url_for('static',filename='draw.js’)}}导入位于静态文件夹中的 css 和 js 文件。这是 Jinja 导入文件的语法。
  • 我们用<canvas>标签设置我们的绘图区域。
  • 我们调用 draw.js 中包含的 drawCanvas() javascript 函数。
  • 我们初始化表单,这样就可以使用POST方法将数据发送到 flask 实例/ app.py
  • action = “{{url_for('predict')}”又是金贾句法。它指定了提交表单时将在 app.py 中使用的路径。
  • 我们在表单中添加了一个额外的隐藏字段,用于传输图像。<input type = “hidden“ id =’url' name = ‘url' value = “”>
  • 仅此而已!简单对吗?

我们现在必须使用 javascript 来使它更加动态!否则,你的画布什么也做不了…

draw.js

draw.js

这段 Javascript 代码允许我们设计绘图区域并与之交互。

  • drawCanvas() 旨在初始化画布的主要功能(mouseUp、mouseDown、…),这些功能将允许与用户的鼠标进行交互。
  • addClick() 保存用户点击画布时光标的位置。
  • redraw() 每次调用该函数时,清除画布并重新绘制所有内容。

在我画完之后,画布看起来是这样的(顺便说一下,这是一只长颈鹿) :

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

Draw.html

现在我们的画布已经准备好获取用户的绘图,我们需要确保图像能够到达我们在 app.py 中的应用程序。

通常我们可以直接使用POST函数,通过一个表单提交数据。然而,目前不能用这种方法提交原始图像。此外,我不希望用户保存然后上传他的画,因为这会影响他的体验的流畅性。

我用来克服这个问题的一个小技巧是,在通过表单发送之前,使用之前在results.html中设置的隐藏输入字段,在 base64 中对图像进行编码。该编码过程将在 app.py. 中反向进行

  • 当用户点击‘预测’按钮时,调用 save() 。它将通过表单发送 base64 编码的图像。

做预测

既然我们能够获得用户输入,那么是时候使用它来进行预测了!为此,我们只需要一个文件:

app.py

如前所述, app.py 是我们项目的主文件,Flask 应用程序在其中被实例化。

app.py

本规范的要点:

1) 初始化 app,指定模板文件夹。我们可以使用这行代码来实现:

app = flask.Flask(__name__, template_folder =’templates’)

2) 定义路线(我们的应用程序只有两条) :

  • @app.route(‘/’) :是我们默认的路径——它会返回默认的draw.html模板。**
  • @app.route(‘/predict’) :点击‘预测’按钮时调用。处理用户输入后返回results.html模板。**

**3)预测功能将由表单中的POST动作触发(还记得我们在result.html中设置此路径时感谢 Jinja 语法!).然后,它将按如下方式进行:

  • request.form['url']访问 base64 编码图形输入,其中“url”是包含编码图像的表单中隐藏输入字段的名称**。**
  • 解码图像并将其设置为一个数组。
  • 调整图像的大小和形状,为我们的模型获得一个 28 * 28 的输入。我们关心的是保持它的比例。
  • 使用我们的 CNN 分类器进行预测。
  • 由于model.predict()返回单个数组中每个类的概率,我们必须找到数组的最高概率,并使用预定义的字典获得相应的类。
  • 最后返回results.html模板,并将之前做的预测作为参数传递:

return render_template('results.html', prediction= final_pred)

:

—我们的 base64 编码图像看起来会像这样:data:image/png;base64,iVBOR…。因此,我们只需要删除第一个 21 字符就可以得到干净的 url。为此,我们使用了draw[init_base64:]行代码。—

显示结果

仅此而已!几乎一切都搞定了。下一步是展示我们的结果。

results.html

最后,我们使用results.html来显示在 app.py 中计算的预测。我们将再次需要使用 Jinja 语法来显示预测

results.html

下面是我们预测是“长颈鹿”时的渲染图:

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

显示结果

运行应用程序

最后一步是启动我们的应用程序!你可以进入你的绘图应用文件夹(你可以在根目录下找到 app.py 并使用flask run.

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

烧瓶运行

您的应用将在本地服务器上运行。默认为 127.0.0.1:5000

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

绘图应用程序

结论

就是这样!在本文中,我们看到了如何开发一个烧瓶绘图应用程序,它使用以前构建的 CNN 模型对用户绘制的绘图进行分类。

这是 Flask 部署机器学习模型的众多可能用途之一。事实上,可以找到无限的用例,我希望这个具体的项目将帮助您构建其他 ML web 应用程序,使您的代码更容易被他人访问!

所有代码在我的github上都有!

祝您愉快!

参考

当然,这不是我一个人做的。我在这里找到了一些灵感:

** [## “快,画!”-使用 Python 对图形进行分类

图像识别一直是机器学习中的一个主要挑战,与大规模标记数据集一起工作来训练…

www.datacareer.de](https://www.datacareer.de/blog/quick-draw-classifying-drawings-with-python/) [## 欢迎使用 Flask - Flask 文档(1.1.x)

欢迎阅读 Flask 的文档。开始安装,然后了解快速入门概述。有…

flask.palletsprojects.com](https://flask.palletsprojects.com/en/1.1.x/) [## 使用 HTML5 Canvas 和 JavaScript 创建一个绘图应用程序

威廉·马隆:本教程将带你一步一步地开发一个简单的网络绘图应用程序…

www.williammalone.com](http://www.williammalone.com/articles/create-html5-canvas-javascript-drawing-app/) [## 用 Python 中的卷积神经网络进行手写数字识别

深度学习技术能力的最新流行演示是图像中的对象识别…

machinelearningmastery.com](https://machinelearningmastery.com/handwritten-digit-recognition-using-convolutional-neural-networks-python-keras/)**

开发和销售机器学习应用程序—从头到尾教程

原文:https://towardsdatascience.com/develop-and-sell-a-machine-learning-app-from-start-to-end-tutorial-ed5b5a2b6b2b?source=collection_archive---------2-----------------------

入门

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

摄影丹尼尔·科尔派https://unsplash.com/photos/HyTwtsk8XqA

新冠肺炎预测端到端 app

在开发和销售 Python API 之后,我现在想用机器学习解决方案来扩展这个想法。所以我决定快速编写一个新冠肺炎预测算法,部署它,并使它可以销售。如果你想知道我是如何做到的,可以查看帖子里的一步一步的教程。

目录

关于这篇文章

在本文中,我从我的上一篇文章“如何从头到尾销售一个 Python API”中汲取了一些思想,并构建了一个机器学习应用程序。如果这里描述的步骤太粗糙,可以考虑先看看我以前的文章。

本项目涉及许多新的、更复杂的问题:

  1. 机器学习内容。该应用程序采取构建机器学习模型的基本步骤。这包括准备,也包括预测。
  2. 在预测的时间评估(不是时间训练)中。这意味着数据集是新获取的,并且对最新数据执行预测。
  3. 部署。部署机器学习应用程序面临各种挑战。在本文中,我们遇到并解决了在 AWS 上外包训练模型的问题。
  4. 它不仅是一个 API,而且还有一个小前端。

它从头到尾描绘了一幅开发 Python API 的图画,并在更困难的领域提供了帮助,比如 AWS Lambda 的设置。

有各种各样的困难,这让我对部署和构建过程有了更多的了解。这也是一个很好的方式来建立副业项目,甚至可能赚一些钱。

如目录所示,它由 4 个主要部分组成,即:

  1. 设置环境
  2. 使用 Python 创建问题解决方案
  3. 设置 AWS
  4. 设置 Rapidapi

你会发现我所有的代码都在 Github 上打开:

您将在 Rapidapi 上找到最终结果:

放弃

我与本文中使用的任何服务都没有关联。

我不认为自己是专家。如果你觉得我错过了重要的步骤或者忽略了什么,可以考虑在评论区指出来或者联系我。此外,始终确保监控您的 AWS 成本,不要为您不知道的事情付费。

我总是乐于听取建设性的意见以及如何改进。

有许多事情需要改进和发展。比如机器学习部分,付出的努力非常低。准备工作非常粗糙,缺少许多步骤。从我的专业工作来看,我知道这个事实。然而,我无法在一篇文章中涵盖所有细节。尽管如此,我还是很想在评论中听到你们的改进建议。😃

如果你需要更多关于某些部分的信息,请在评论中指出来。

关于术语“教程”

我认为这是一个循序渐进的教程。然而,由于我作为一名开发人员已经工作了很长时间,我假设对某些工具有所了解。这使得教程很可能是一个中级/高级应用程序。

我假定了解:

  • 计算机编程语言
  • 饭桶
  • Jupyter 笔记本
  • 终端/Shell/Unix 命令

使用的堆栈

我们将使用

  • Github(代码托管),
  • 依赖和环境管理,
  • Docker(可能在微服务中进一步使用)
  • Jupyter 笔记本(代码开发和文档),
  • Python(编程语言),
  • AWS,尤其是 AWS Lambda 和 S3(用于部署)、
  • Rapidapi(销售市场)

1.创建项目手续

它总是一样的,但却是必要的。我按照以下步骤来做:

  1. 创建本地文件夹mkdir NAME
  2. NAME在 Github 上创建一个新的存储库
  3. 创造康达环境conda create --name NAME python=3.7
  4. 激活康达环境conda activate PATH_TO_ENVIRONMENT
  5. 创建 git 回购git init
  6. 连接到 Github repo。添加自述文件,提交并
git remote add origin URL_TO_GIT_REPO
git push -u origin master

2.开发解决问题的方法

由于我们将开发一个机器学习解决方案,Jupyter 笔记本将非常有用。

正确安装软件包和跟踪 Jupyter 文件

安装 jupyter 笔记本和 jupytext:

pip install notebook jupytext

在 jupyter 中注册新环境ipython kernel install --name NAME--user

.git/hooks/pre-commit中设置一个钩子,用于正确跟踪 git 中的笔记本变化:

touch .git/hooks/pre-commit
code  .git/hooks/pre-commit

把这个复制到文件里

#!/bin/sh
# For every ipynb file in the git index, add a Python representation
jupytext --from ipynb --to py:light --pre-commit

之后让钩子可执行(在 mac 上)

chmod +x .git/hooks/pre-commit

找到解决问题的方法

目标

目前,世界处于疫情,我想我使用了新冠肺炎案例的多个数据集之一。鉴于数据集的结构,我们希望预测一个国家每天的新增感染病例。

pip install -r requirements.txt

这将安装我们需要的所有软件包。看看/development/predict_covid.ipynb笔记本,看看都用什么库。

最重要的是图书馆

  • 熊猫用于转换数据集和
  • 用于机器学习的 sklearn

对于以下小标题,请查看 Jupyter 笔记本了解更多详情:

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

https://github . com/Createdd/ml _ API _ covid/blob/master/development/predict _ covid . ipynb

下载数据

我们将使用来自https://ourworldindata.org/coronavirus-source-data的 csv 格式的数据集。

准备

简而言之,我做到了:

  1. 检查丢失的数据
  2. 删除丢失数据超过 50%的列
  3. 删除剩余缺失内容的行,如洲或等编码。(对需要国家/地区的应用程序解决方案没有帮助)
  4. 用标签对分类数据进行编码
  5. 用该列的平均值填写剩余的数字缺失数据
  6. 分为训练集和测试集

创建分类器并预测

  1. 创建随机森林回归变量
  2. 用数据训练它并评估
  3. 使用 RandomizedSearchCV 执行超参数调整
  4. 保存训练好的模型
  5. 通过提供国家名称来预测新病例

构建一个服务器来执行 REST 的功能

对于 API 功能,我们将使用 Flask 服务器(在app.py中)

服务基本前端

@app.route('/')
def home():
    return render_template("home.html")

它提供一个基本的 HTML 和 CSS 文件。

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

应用程序前端

负荷预测

这个有点复杂。

关键路线是这样的:

但是在我们返回预测结果之前,我们需要获得最新的数据并再次对其进行预处理。这已经结束了

为了机器学习的目的,Pre-process再次转换下载的数据集,而get_prediction_params获取输入值(要预测的国家)和最新数据集的 URL。

这些过程使最新数据的预测成为现实,但也减慢了应用程序的速度。

你可能想知道我们为什么做rf = load_model(BUCKET_NAME, MODEL_FILE_NAME, MODEL_LOCAL_PATH)。这样做的原因是,当使用 AWS Lambda 执行所有操作时,我们需要从 AWS S3 存储桶中加载预训练模型以节省内存。向下滚动查看更多详细信息。

但是如果我们不想把它部署在云中,我们可以简单地做一些类似于joblib.load(PATH_TO_YOUR_EXPORTED_MODEL)的事情。在笔记本中,我们用joblib.dump导出模型。 sklearn 文档中关于模型导出的更多信息

但这仅仅是高射炮服务器的功能。提供用于服务 HTML 模板的路径和用于预测的路径。相当简单!

正在运行

env FLASK_APP=app.py FLASK_ENV=development flask run

将启动服务器。

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

工作应用

好处:使 Docker 可复制

也许你想扩展应用程序,或者让其他人更容易地测试它。为此,我们可以创建一个 Docker 容器。我不会详细解释它是如何工作的,但如果你感兴趣,可以查看我的“灵感”部分的一个链接。

构建一个 Docker 容器并不是让这个应用程序工作的必要条件!

创建 Dockerfile 文件

FROM python:3.7ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1ENV FLASK_APP=app.py
ENV FLASK_ENV=development# install system dependencies
RUN apt-get update \
    && apt-get -y install gcc make \
    && rm -rf /var/lib/apt/lists/*sRUN python3 --version
RUN pip3 --versionRUN pip install --no-cache-dir --upgrade pipWORKDIR /appCOPY ./requirements.txt /app/requirements.txtRUN pip3 install --no-cache-dir -r requirements.txtCOPY . .EXPOSE 8080CMD ["gunicorn", "--bind", "0.0.0.0:8080", "app:app"]

注意:最后一行用于启动 Flask 服务器

创建Dockerfile运行后

docker build -t YOUR_APP_NAME .

然后呢

docker run -d -p 80:8080 YOUR_APP_NAME

之后,你会看到你的应用在[http://localhost/](http://localhost/)上运行

3.部署到 AWS

到目前为止,这是一条相当容易的道路。不要太复杂,也不要太花哨。现在我们开始部署,它变得有趣和具有挑战性。

同样,如果您对 Zappa 和 AWS 有任何问题,我强烈建议您查看我以前的文章https://towardsdatascience . com/develop-and-sell-a-python-API-from-start-to-end-tutorial-9a 038 e 433966

这里我不再赘述,而是指出痛点。

设置 zappa

在我们本地创建应用程序后,我们需要开始在一个真实的服务器上设置主机。我们将使用 zappa

Zappa 使得在 AWS Lambda + API Gateway 上构建和部署无服务器、事件驱动的 Python 应用程序(包括但不限于 WSGI web apps)变得超级简单。可以把它想象成 Python 应用程序的“无服务器”网络托管。这意味着无限扩展、零停机、零维护,而成本只是您当前部署的一小部分!

pip install zappa

由于我们使用的是 conda 环境,我们需要指定它:

which python

会给你/Users/XXX/opt/anaconda3/envs/XXXX/bin/python(针对 Mac)

移除bin/python/并导出

export VIRTUAL_ENV=/Users/XXXX/opt/anaconda3/envs/XXXXX/

现在我们能做的

zappa init

来设置配置。

只要点击浏览所有内容,你就会有一个zappa_settings.json的样子

{
    "dev": {
        "app_function": "app.app",
        "aws_region": "eu-central-1",
        "profile_name": "default",
        "project_name": "ml-api-covid",
        "runtime": "python3.7",
        "s3_bucket": "zappa-eyy4wkd2l",
        "slim_handler": true,
        "exclude": [
            "*.joblib", "development", "models"
        ]
    }
}

没错。不要为 s3 存储桶输入名称,因为找不到它。我真的不知道给你的 s3 桶命名有什么问题,但是从来没成功过。有多个错误语句,我无法解决这个问题。只要留下建议的那个,一切都很好。;)

请注意,我们还没有准备好部署。首先,我们需要获得一些 AWS 凭证。

设置 AWS

注意:这需要相当大的努力。不要因为 AWS 及其策略管理的复杂性而气馁。

AWS 凭据

首先,你需要得到一个 AWS access key idaccess key

使用 IAM 中的用户和角色设置凭据

我尽可能简单地分解它:

  1. 在 AWS 控制台中,在搜索框中键入 IAM。IAM 是 AWS 用户和权限仪表板。
  2. 创建一个组
  3. 为您的群组命名(例如 zappa_group)
  4. 为您的小组创建我们自己的特定内联策略
  5. 在“权限”选项卡的“内联策略”部分下,选择链接以创建新的内联策略
  6. 在设置权限屏幕中,单击自定义策略单选按钮,然后单击右侧的“选择”按钮。
  7. 创建一个用 json 格式编写的定制策略
  8. 通读并复制此处讨论的一项政策:https://github.com/Miserlou/Zappa/issues/244
  9. 向下滚动到“我的自定义策略”查看我的策略的片段。
  10. 使用您的 AWS 帐号粘贴和修改 json 后,单击“验证策略”按钮以确保您复制了有效的 json。然后单击“应用策略”按钮,将内联策略附加到该组。
  11. 创建一个用户并将该用户添加到组中
  12. 回到 IAM 控制面板,使用“用户”左侧菜单选项和“添加用户”按钮创建一个新用户。
  13. 在“添加用户”屏幕中,为新用户命名,并选择编程访问的访问类型。然后点击“下一步:权限”按钮。
  14. 在“设置权限”屏幕中,选择您之前在“将用户添加到组”部分创建的组,然后单击“下一步:标记”。
  15. 标签是可选的。如果需要,添加标签,然后单击“下一步:查看”。
  16. 查看用户详细信息,然后单击“创建用户”
  17. 复制用户的密钥
  18. 先不要关闭 AWS IAM 窗口。在下一步中,您将把这些密钥复制并粘贴到一个文件中。此时,将这些密钥复制并保存到一个安全位置的文本文件中不失为一个好主意。确保不要在版本控制下保存密钥。

我的自定义策略:

正如你在政策中看到的,我添加了 S3 的相关政策。这是因为我们想从 S3 下载我们的预训练模型。稍后会有更多信息。

在项目中添加凭据

在你的根目录下创建一个.aws/credentials文件夹

mkdir ~/.aws
code ~/.aws/credentials

并从 AWS 粘贴您的凭据

[dev]
aws_access_key_id = YOUR_KEY
aws_secret_access_key = YOUR_KEY

config相同

code ~/.aws/config# and add:[default]
region = YOUR_REGION (eg. eu-central-1)

注意,code是用我选择的编辑器 vscode 打开一个文件夹。

将分配给用户的 AWS 访问密钥 id 和秘密访问密钥保存在文件~/中。AWS/凭据。请注意。aws/ directory 需要在您的主目录中,并且凭据文件没有文件扩展名。

部署

现在,您可以使用

zappa deploy dev

但是,有一些事情需要考虑:

  1. Zappa 将打包您的整个环境和整个根内容。这个会很大。
  2. AWSλ有一个上传限制

减小上传大小

有几个关于如何用 zappa 减少上传大小的讨论。查看灵感部分的链接。

首先,我们需要为上传减少包的大小。

我们将把所有探索性的内容放入一个自己的文件夹中。我把它命名为“发展”。之后,您可以使用 exclude 在 zappa_settings.json 中指定排除的文件和文件夹:

{
    "dev": {
        ...
        "slim_handler": true,
        "exclude": [
            "*.ipynb", "*.joblib", "jupytext_conversion/", ".ipynb_checkpoints/",
            "predict_covid.ipynb", "development", "models"
        ]
    }
}

您可以添加部署时不需要打包的任何东西。

另一个问题是环境依赖性。在我们的例子中,我们有多个依赖项,这是部署所不需要的。为了解决这个问题,我创建了一个新的“requirements_prod.txt”文件。这应该只有 AWS 上需要的依赖项。

请确保使用导出您当前的包

pip freeze > requirements.txt

之后,卸载所有软件包

pip uninstall -r requirements.txt -y

安装用于部署的新包,并将它们保存在文件中

pip install Flask pandas boto3 sklearn zappapip freeze > requirements_prod.txt

当你点击zappa deploy dev时,需要打包的尺寸应该会小很多。

你会注意到我还设置了slim_handler=true。这允许我们上传超过 50MB。在幕后,zappa 已经将内容放入自己的 S3 桶中。阅读 zappa 文档了解更多信息。

将模型装入 S3 存储桶

因为我们从 AWS Lambda 上传中排除了我们的模型,所以我们需要从其他地方获取模型。我们将使用 AWS S3 铲斗。

在开发过程中,我试图上传程序,但我只是手动上传,因为它现在更快了。(但您仍然可以尝试上传它——我在回购中仍有一个注释文件)

去 https://console.aws.amazon.com/s3/

  1. “创建存储桶”
  2. 给定一个名称,将 rest 作为缺省值。检查是否有足够的权限。
  3. “创建存储桶”

检查您是否有足够的策略来与 bucket 和 boto3 交互。您应该有类似于

{
      "Effect": "Allow",
      "Action": [
        "s3:CreateBucket",
        "s3:ListBucket",
        "s3:ListBucketMultipartUploads",
        "s3:ListAllMyBuckets",
        "s3:GetObject"
      ],
      "Resource": [
        "arn:aws:s3:::zappa-*",
        "arn:aws:s3:::*"
      ]
    }

调试和更新

最后,不应该再有任何错误了。但是,如果还有一些,您可以使用以下命令进行调试:

zappa status# andzappa tail

最常见的错误是与权限相关的(然后检查您的权限策略)或关于不兼容的 python 库。无论哪种方式,zappa 都会为调试提供足够好的错误消息。根据我的经验,最常见的错误是:

  1. IAM 用户的政策问题
  2. Zappa 和大小问题
  3. Boto3 和文件的权限/位置问题

如果您更新您的代码,不要忘记使用

zappa update dev

AWS API 网关—限制访问

要在市场上设置 API,我们需要首先用 API-key 限制它的使用,然后在市场平台上设置它。

分解一下:

  1. 转到 AWS 控制台并转到 API 网关
  2. 点击你的 API
  3. 我们希望创建一个 x-api-key 来限制对 api 的不希望的访问,并且也有一个计量使用
  4. 为 API 创建一个使用计划,包括所需的限制和配额限制
  5. 创建关联的 API 阶段
  6. 添加 API 密钥
  7. 在 API 键概述部分,单击 API 键处的“显示”并复制它
  8. 然后将 API 与键相关联,并丢弃所有没有键的请求
  9. 回到 API 概述。在“资源”下,单击“/任意”转到“方法请求”。然后在“设置”中,将“需要 API 密钥”设置为真
  10. 对“/{proxy+}方法执行相同的操作

现在,您已经限制了对 API 的访问。

4.设置 Rapidapi

  • 添加新 API
  • 使用 rapidapi 测试端点
  • 创建使用 API 的代码

在这篇文章中我不再赘述。再次查看我之前的https://towardsdatascience . com/develop-and-sell-a-python-API-from-start-to-end-tutorial-9a 038 e 433966设置好一切。我的新机器学习模型没有大的区别。

最终结果

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

上的 API 接口 https://rapidapi . com/Createdd/API/covid _ new _ cases _ prediction

https://rapidapi . com/Createdd/API/covid _ new _ cases _ prediction

灵感

这次我的主要动机来自于 Moez Ali,他提供了很多关于部署机器学习系统的文章。我也喜欢在社交媒体上关注他。我可以推荐他的文章:

还有弗朗索瓦·马索

常见问题

附加阅读

最终链接

开放源代码:

在 Rapidapi 上:

关于

丹尼尔是一名企业家、软件开发人员和商业法毕业生。他曾在各种 IT 公司、税务咨询、管理咨询和奥地利法院工作。

他的知识和兴趣目前围绕着编程机器学习应用程序及其所有相关方面。从本质上说,他认为自己是复杂环境的问题解决者,这在他的各种项目中都有所体现。

如果您有想法、项目或问题,请不要犹豫与我们联系。

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

你可以在 https://www.buymeacoffee.com/createdd 或者 https://etherdonation.com/d?支持我 to = 0xc 36 b 01231 a8f 857 b 8751431 c 8011 b 09130 ef 92 EC

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

连接到:

艺术相关:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值