了解用于对象分类和检测的 SPPNet
SPPNet 的分析与评述
SPPNet 允许可变大小的 CNN 输入图像,并可用于分类和对象检测
谢尔盖·阿库利奇在 Unsplash 上的照片
在论文“用于视觉识别的深度卷积网络中的空间金字塔池”中,介绍了一种称为空间金字塔池层的技术,该技术使得 CNN 模型与输入图像大小无关。它是 ILSVRC 2014 中物体检测的亚军和分类挑战的亚军,因此值得一读。
在这篇文章中,我解释了 SPP 层,然后回顾了整篇文章。博客的结构是学生和老师之间的对话。
学生
我希望了解更多关于物体检测的知识。上次,你已经解释了用于物体探测的 R-CNN 网络。在 R-CNN 之后,在目标检测领域还有其他研究吗?
教师
在 R-CNN 之后不久,SPP-Net 被引入。与 R-CNN 相比,SPPNet 使模型与输入图像大小无关,并显著提高了边界框预测速度,而不影响地图。我将首先解释如何使模型不可知的输入图像大小。
CNN 网络的固定大小限制不是因为卷积层,而是因为全连接(FC)层。单个卷积层或一组卷积层获取图像,并产生与输入图像的特定比率(称为子采样比率,稍后解释)成比例的特征图。但是对于完全连接的层,输入必须是固定长度的向量。为了解决这个问题,作者用一个空间金字塔池(SPP) 层替换了最后一个池层(FC 层之前的层)。
**注意:**SPP 方法受词汇袋方法的启发。不需要对单词包有深入的理解,但是了解它将有助于对概念的理解。
学生
我所看到的池层有一个固定的大小,比如说,2 x 2,两个方向的步幅都是 2。所以在这种情况下,输出与输入保持比例。池层如何解决问题?
教师
在上面描述的池层中,您已经设置了固定步幅(2)和固定窗口大小(2 x 2)。正因为如此,你的输出总是与输入成正比。现在**如果你让池窗口和步幅与输入图像成比例,你总能得到固定大小的输出。**此外,SPP 层不仅仅应用一个池化操作,它还应用了几个不同输出大小的池化操作(这就是相同操作的来源——空间金字塔池化),并在将结果发送到下一层之前将其合并。
空间金字塔池(SPP)层— 论文
在上图中,作者使用了三个池操作,其中一个操作只为每个地图输出一个数字。另一个为每个贴图提供 2 x 2 的网格输出,同样,最后一个提供 4 x 4 的输出。该操作被应用于由先前卷积操作给出的每个特征图(在上述情况下为 256 个图)。SPP 层输出被展平并发送到 FC 层。
现在要计算窗口大小和步幅大小,让我们声明一些变量和公式。
- 假设输入到 SPP 层的特征地图的大小为
[a x a]**↔**[13 x 13]
- 我们需要单个地图的输出大小为
[n x n]**↔**[4 x 4]
window = ceiling(a/n)
↔ 天花板(13/4) ↔4stride = floor(a/n)
↔ 楼(13/4) ↔3
现在在[13 x 13]地图上,应用上面的窗口([4 x 4])和步幅([3 x 3]),我们得到的输出是[4 x 4]。该操作应用于所有的特征映射,对于 256 个特征映射,我们得到[4 x 4 x 256]的输出。因此,现在我们可以改变[n x n]网格大小,以获得所需的输出大小。
学生
SPP 层是网络的直观设计,因为它使 CNN 模型产生的结果与输入图像大小无关。所以根据我的理解,在把特征发送到全连接层之前,我可以把这个层应用到任何 CNN。作者在本文中使用了哪些模型?此外,由于在 FC 层之前引入了一个全新的层,因此对于分类任务,作者是否使用了任何预训练的架构或者他们从一开始就训练了一个模型?
教师
人们可以将 SPP 层应用于任何 CNN 架构。但是,我们谈论的是 2014 年的时间。当时出席的模特不多。作者使用了 ZF 网、AlexNet 和 over fat(5 层和 7 层)架构。然而,通过改变填充来修改这些网络,以获得期望的输出特征图。
SPPNet 中使用的 CNN 模型架构— 论文
作者在 ImageNet 2012 数据集上训练了该模型,并提供了对训练细节的详细分析,并将它们与没有在其上使用 SPP 层的当代模型进行了比较。然而,在深入本质细节之前,让我们先弄清楚一些定义。
**多尺寸/多比例图像:**改变输入图像尺寸
**多视图:**使用图像增强——从输入图像中截取部分并翻转。
首先,作者在模型上用一个单一大小的输入[224 x 224]训练,然后用一个可变大小的输入[224 x 224]和[180 x 180]训练。作者在固定大小的图像上执行训练,以利用 GPU 实现的优势。在为多尺寸训练时,它们在一个时期发送相同的图像尺寸,然后改变到另一个时期。用于上述两种训练的金字塔是:{6 x 6,3 x 3,2 x 2,1 x 1}。
**注意:**为了训练,图像被调整大小,使得最小值(高度、宽度)等于 256,并且剩余部分基于纵横比被调整。之后,从中心和四个角拾取 224 x 224 的作物,给我们总共 5 个 224 x 224 的图像。图像被翻转以从相同的位置产生 5 个以上的图像,从每个输入图像给出总共 10 个图像。
ImageNet 12 验证集分析— 论文
作者将单一大小训练的 SPP 模型与没有 SPP 的模型进行了比较,发现误差减少了。为了证明误差的减少是由于 SPP 层而不是由于参数的增加,他们将 SPP 层的金字塔更改为{4 x 4,3 x 3,2 x 2,1 x 1},这大大减少了参数,但误差仅略有增加。
对填充尺寸和裁剪图像的验证— 纸张
作者还尝试用 224 次裁剪和不用 224 次裁剪来检验该模型,并对结果进行了分析。观察到误差减少,如上图所示。根据这种损失的减少,作者说:
由此可见维护完整内容的重要性。
学生
从上面的数字,我们可以说 SPPNet 论文中引入的新层确实减少了分类任务的误差。我还想知道作者是如何推断出对象检测任务的模型的?
教师
作者可以使用该模型进行对象检测,并可以添加一个包围盒检测器来拍摄地图。然而,为了理解这是如何发生的,我们将首先理解子采样率的概念
了解子采样率-作者提供的图像
子采样率可用于从输入图像形状确定 CNN 特征图的输出形状。简单地将输入图像尺寸乘以子采样率将得到特征图尺寸。我们一会儿会用到这个概念。
**注意:**填充确实会影响子采样率,因为我们可能需要根据填充增加/减少一个常数。文件附录中提供了详细信息。
SPPNet 论文已经显示了用于对象检测的 ZF 网论文的分析。ZF 网论文的次抽样比率为 16。现在,对于对象检测,他们仍然使用选择性搜索算法来确定区域(每幅图像约 2k 个区域)的建议。但与 R-CNN 不同,它们不会将每个建议区域发送到 CNN,而是将这些区域映射到最后一个卷积层(Conv5)的输出特征图。
从图像到特征图的对象映射——来自视频的SS
在上面的图像中,图像中的对象被映射到特征映射。让我们看看数学,看看如何做到这一点。
- 设图像尺寸为
[img_height, img_width]
↔【688×920】 - 让出现在图像中的一个物体的中心在
[x, y]
↔【340,450】 - 上述物体的高度和宽度是
[obj_height, obj_width]
↔【320,128】 - 现在,为了将它们映射到特征图上相应的空间位置,我们简单地将它们乘以
sub-sampling ratio (S)
↔ 16。 - 特征地图的尺寸将会是
[img_height * S, img_width * S]
↔[43 x 58】 - 特征图上的物体中心将在
[x * S, y * S]
↔[21,28】的空间位置 - 特征图上对象的高度和宽度将为
[obj_height * S, obj_width * S]
↔[20 x 8】
这样,我们可以将输入图像中的任何对象映射到输出特征图。对象的坐标也被投影到特征地图,然后只有该区域被发送到 SPP 层进行特征提取,然后发送到 FC 层。
对象窗口到特征图的映射— 论文
学生
将输入图像中的区域投影到特征图上以避免在图像的相同部分上进行冗余的卷积运算是减少计算量的一种聪明的方法。与 R-CNN 相比,这种机制是否影响了检测图谱?
教师
在比较它的性能之前,我们还需要了解一些细节。作者使用了单一大小([224 x 224]而已)的 ImageNet 预训练 ZF-5 网络。为了检测,他们使用了两种不同的方法进行预测:单尺度 —其中最小值(高度,宽度)= 688,多尺度其中最小值(高度,宽度)= {480,576,688,864,1200}和其他尺寸根据长宽比调整大小。
在多尺度检测的情况下,作者使用了一种选择尺度的新策略,该尺度具有最接近对象的像素总数(224 x 224 = 50,176),以确定该尺度中对象的存在。
与 R-CNN 相比,在单尺度下,性能下降了 0.5%,而在多尺度下,性能提高了 0.7%。虽然地图的增加并不大,但速度却有相当大的提高。作者还比较了有和没有微调 FC 层的模型,并将其与 R-CNN 进行了比较,结果如下所示。
**注:**卷积层没有微调,只有 FC 层。
与 R-CNN 在 Pascal VOC 07 — 论文上的比较
**注:**我们已经讨论了 Pascal VOC 2007 数据集上的对象检测结果。
论文中的大部分关键概念都已经讨论过了。但是,我建议您阅读这篇论文,因为他们在分类和检测部分提供了更详细的分析。
理解 SPP 层使得学习在此之后构建的两阶段模型变得更加容易。我将很快在 FastR-CNN 的报纸上写作。敬请期待!!
参考
K.何,X 张,s 任,孙军,用于视觉识别的深度卷积网络空间金字塔池,,2014
理解统计和概率:贝叶斯推理
了解统计的一个关键领域,这一领域在许多部门引起了兴趣
贝叶斯推理是最流行的统计技术之一。这是一种在收集新数据时更新事件先验概率的技术。贝叶斯推理是一种数据驱动的技术。
传统上,贝叶斯模型是首先使用的模型之一。它们被用作基线模型,因为它们基于对世界的简单看法,并使科学家能够更容易地解释推理。因此,贝叶斯推理是统计学中最重要的学习技巧之一。
本文将向读者介绍贝叶斯推理。这是一个必须知道的话题。
概率统计中的一个重要概念
文章目标
本文将概述以下概念:
- 什么是贝叶斯推理?
- 什么是贝叶定理?
- 理解概念的例子
- 朴素贝叶斯模型
贝叶斯推理在很多领域都有应用,包括保险、医疗保健、电子商务、体育、法律等等。贝叶斯推理在分类算法中被大量使用,由此我们试图将文本或数字分类/分组到它们适当的类别中。
此外,中国对银行业,尤其是金融业的兴趣日益浓厚。
1.什么是贝叶斯推理?
在我解释什么是贝叶斯推理之前,我们先来了解一下关键的构建模块。
我先举一个例子。
计算机工程师示例
假设我有一台停止工作的电脑。我家附近有两个电脑工程师会修电脑。
两位工程师都声称有不同的技术来诊断和解决问题。
第一工程师——频率主义方法
第一个工程师有一个模型,由一个数学方程组成。这个模型是根据一个事件的发生频率建立的。该模型需要一组输入来计算计算机为什么停止工作的诊断。
第一个工程师诊断问题的方式是询问模型需要作为输入的问题。
例如,工程师会询问计算机规格,如操作系统、硬盘大小和处理器名称。然后,他会将答案输入模型,然后模型会给出计算机故障的原因。
该模型将使用观察到的事件频率来诊断计算机停止工作的原因。
频繁主义方法
第二工程师—贝叶斯方法
第二个工程师有一个稍微不同的机制来诊断问题。他还使用了第一个工程师使用的相同模型,但是除了该模型之外,他还利用了事件的先前历史来诊断问题。因此,工程师会问与第一个工程师相同的问题,但他也会询问问题的先前历史。
例如,第二个工程师会询问计算机规格,如操作系统、硬盘大小和处理器名称。此外,他还会询问有关计算机历史记录的问题,例如,它过去是否停止过工作,如果知道的话,它停止工作的原因以及事件发生的次数。
工程师将收集该台计算机的适当历史记录,以便更好地了解问题。这种技术被称为贝叶斯推理。简而言之,在贝叶斯推理中,我们使用先验历史和已知模型来计算后验结果。
贝叶斯方法
第一个工程师使用频率主义方法,第二个工程师使用贝叶斯推理方法。
频率主义方法在小样本量的情况下并不准确,因为它是基于积极事件发生的观察频率,而贝叶斯方法依赖于关于事件发生概率的先验信念。话虽如此,频率主义方法比贝叶斯推断更容易实现和理解,通常用于大样本量。
贝叶斯推断是一种统计推断方法,在这种方法中,随着更多的证据或信息变得可用,贝叶斯定理用于更新假设的概率。贝叶斯更新在数据序列的动态分析中尤其重要。
贝叶斯推理技术是基于贝叶斯定理的。贝叶斯定理可以通过使用先验和似然分布计算后验分布来帮助我们更新随机变量的知识。
这就把我们带到了文章的第二部分。
2.贝叶斯定理
简单地说,贝叶斯定理计算一个事件的后验概率。它使用事件的先验概率和似然概率。
让我们考虑一下,我们想要估计一个目标变量的行为。这个目标变量本质上可以是随机的。因此,我们从收集随机样本的数据开始。这个数据是我们的样本集,它有自己的抽样分布。由于每个样本都有不同的数据点,分布可以帮助我们量化采样技术中的误差。
一旦收集了样本,进行了实验,我们现在可以使用贝叶斯定理来获得新的信息,以更新我们先前的理解。
贝叶斯定理是一个框架,它使我们能够在一个事件已经发生的情况下计算另一个事件发生的概率。
贝叶斯定理公式
两个随机变量 A 和 B 的贝叶斯定理是:
贝叶斯定理公式
让我们来理解一下公式
上面的公式表明有两个事件:A 和 B
我们试图找到条件概率;假设事件 B 已经发生,事件 A 发生的概率。这就是所谓的后验分布。
- 它的计算方法是,假定事件 A 已经发生,通过计算事件 B 发生的概率与事件 A 的无条件概率的乘积,得出事件 A 和 B 的联合概率。这显示在分子中。
2.最后,我们将联合概率除以事件 B 发生的概率。
三个主要组成部分
贝叶斯推理得出后验概率。它假设后验概率是两个主要输入(为简单起见)的结果:先验概率和似然函数。似然函数来源于统计模型本身。贝叶斯推理根据贝叶斯定理计算后验概率。
- 我们计算的是后验分布。这是 P(给定 B)。
2.我们已经有的是 P(B)。这是事件 B 已经发生的概率。
3.最后,P(B|A)是似然概率。它是在 A 已经发生的情况下,B 发生的概率。
每当我们想要预测一个随机变量时,我们已经有了一个先验的已知分布。举个例子,我们有一个先验分布,如果我们掷硬币一百万次,那么我们看到正面的次数大约是 50%
贝叶斯统计的目标是计算后验分布。
对于先验分布,我们使用贝叶斯定理来获得后验分布。这是我们看到数据后更新的认识。利用后验分布,我们可以总结我们对数据的理解。
贝叶斯推理是数据驱动的,因为先验分布和后验分布是由数据驱动的
3.理解概念的例子
我相信应用概念来解决实际问题,因为只有这样我们才能彻底理解概念。
1.让我们来看一个简单的例子:跑步和训练
让我们假设你正在训练在 25 分钟内跑完 5 公里。
如果你在健身房训练,你想知道达到跑步目标时间的概率。
让我们用贝叶斯公式来找出概率
在高层次上,我们需要四个数字
- P®是在 25 分钟内跑完 5 公里的概率。50%是基于收集的数据,因此 50%的人在 25 分钟内跑完 5 公里。
- P(T)是在健身房训练的概率。60%是基于收集的数据,因此 60%的人进行训练,不管他们是否在 25 分钟内完成了跑步。
- P(T|R)是假设一个人在 25 分钟内完成了 5 公里跑步,他/她正在健身房训练的概率。是 75%。
问题:假设你在健身房训练,在 25 分钟内跑完 5 公里的目标时间的可能性有多大?
因此,问题是找到 P(R|T)。我们知道它的计算方法是:
答案是 62.5%
2.另一个例子是金融机构的债券违约
让我们假设我们在一家金融机构工作,并希望在另一只债券 Y 已经违约的情况下,找出债券 X 违约的概率。
我们可以创建一个概率矩阵来可视化这个问题:
债券的概率矩阵
使用概率矩阵求解非常简单。
- 假设债券 X 已经违约,债券 Y 违约的联合概率是 10%(右下角方框)
- 不管债券 X 是否违约,债券 Y 违约的概率都是 20%(第二栏的总和)
举例回答
因此,如果债券 Y 已经违约,债券 X 有 50%的可能违约。
3.让我们用另一个例子来理解
让我们假设我们知道每天有 X 个读者阅读这个博客。假设一个读者是数据科学家,我想计算他/她是 Python 开发者的概率。
让我们把 A 称为一个数据科学家读者。
- 读者是数据科学家的概率是 P(A)
- 读者不是数据科学家的概率是 P(A’)
让我们把 B 称为是 Python 开发者的读者。
- 读者是 Python 开发者的概率是 P(B)
- 读者不是 Python 开发者的概率是 P(B’)
假设一个读者是数据科学家,那么他/她是 Python 开发者的概率有多大?
解决方案是:
问题的公式
因此,我们可以从收集一天所需的数据开始。
让我们考虑以下数字:
今天有 200 名读者阅读了这个博客
在 200 名读者中:
- 20 名读者是数据科学家,因为他们是 Python 开发人员
- 30 读者不是数据科学家,他们是 Python 开发者
- 60 名读者是数据科学家,而不是 Python 开发者。
- 90 位读者既不是 Python 开发者,也不是数据科学家。
那么问题是——假设一个读者同时也是数据科学家,那么他成为 Python 专家的可能性有多大?P(B|A)
我们可以计算一棵树来形象化它:
概率决策树
问题的公式
因此,概率计算如下:
得到概率的方程式
这给了我们 25%
因此,假设读者是数据科学家,那么他/她有 25%的机会是 Python 开发人员。
4.贝叶斯模型—朴素贝叶斯
最后,我想向读者介绍朴素贝叶斯模型。在大多数分类数据科学项目中,特别是在文本挖掘项目中,朴素贝叶斯模型被用作基准/基线模型。
该模型本质上是概率性的。它基于我上面解释的概念。因此,它使用贝叶定理来计算结果。
这个模型之所以被称为天真,是因为它的基础是对现实的极度简化。它假设数据中的要素在给定类标签的情况下相互独立。对于大多数数据集来说,这种假设并不完全正确。
作为一个实例,这些特征可能被链接在一起。解释一下,像国家历史博物馆或白金汉宫或白宫或黑色日等词,当它们一起写在不同的句子中时,有完全不同的意思。因此,这表明对这些特征有某种形式的依赖。
简单起见,朴素贝叶斯模型假设所有特征都是独立的。有时一个可以解释的模型比一个无法解释的精确模型更重要
传统上,贝叶斯模型是首先使用的模型之一。它们很容易解释,因为它们是基于对世界的简单看法。此外,参数很容易理解。因此,为什么朴素贝叶斯分类器被视为基线模型。
摘要
本文解释了什么是贝叶斯推理和贝叶斯定理。
感谢您的阅读
特别是,它概述了以下主题:
- 什么是贝叶斯推理?
- 什么是贝叶定理?
- 理解概念的例子
- 朴素贝叶斯模型
贝叶斯推理在很多领域都有应用,包括保险、医疗保健、电子商务、体育、法律等等。贝叶斯推理在分类算法中被大量使用,由此我们试图将文本或数字分类/分组到它们适当的类别中。
此外,中国对银行业,尤其是金融业的兴趣日益浓厚。
理解统计和概率:成为专家数据科学家
介绍数据科学家的专业技能以及最佳实践和成功的数据科学项目步骤
数据科学是当今的热门话题。组织认为数据科学家是 T2 的精英。业内每个人都在谈论数据科学的潜力,以及数据科学家可以为他们的 BigTech 和 FinTech 组织带来什么。做数据科学家很有吸引力。
本文将概述成为数据科学领域专家所需了解的一切。
关于专家数据科学家的话题。作者图片
在困难时期,对数据科学家的需求更大,因为能够从事削减成本和创造收入的项目至关重要。数据科学项目之所以成为可能,主要是因为先进的计算能力、数据可用性和廉价的存储成本。
定量分析师、软件工程师、业务分析师、测试人员、机器学习工程师、支持人员、开发人员、项目经理到销售主管都可以在数据科学领域工作。
文章目标
这是本文的四个部分:
- 数据科学家——魔术师
- 专家数据科学家的基本技能
- 数据科学项目阶段
- 数据科学常见陷阱
- 数据科学最佳实践
本文将介绍什么是数据科学以及它是如何工作的。我还将概述成为一名成功的数据科学家所需的技能。此外,本文将概述成功的数据科学项目的 10 个阶段。然后,文章将提到我们在数据科学建模项目中面临的最大问题,以及我建议每个人都熟悉的最佳实践。
我还将强调成为专家数据科学家所需的技能。有时,很难写下所有的东西,但我会尝试向有抱负的数据科学家提供我推荐的所有信息。
1.数据科学家——魔术师
专家数据科学家可以利用他们的高级编程技能、卓越的统计建模知识、领域知识和直觉,提出本质上具有创造性的项目想法,可以降低成本,并为企业带来可观的收入。
我们所需要做的就是在谷歌趋势中找到术语数据科学,来想象这个领域有多受欢迎。随着时间的推移,人们的兴趣越来越浓,而且还在不断增长:
2004 年以来数据科学的全球趋势。来自谷歌趋势
数据科学项目可以解决曾经被认为不可能解决的问题。
专注于数据科学的解决方案将技术推向了更高的水平。我们看到了试图模拟波动性、价格和实体行为的解决方案。许多公司已经实现了奇妙的数据科学应用,而不仅限于 FinTech 或 BigTech。
在我看来,数据科学的保护伞要求个人具备多种多样的技能;从开发、分析到 DevOps 技能。
2.专家数据科学家的基本技能
要成为一名成功的专家数据科学家,必须具备正确的基础。
首先,数据科学是计算机科学和统计学的一个分支。因此,它涉及到一个人获得计算机科学和统计知识。关于它没有两种方法。虽然知识越多越好,但是我们不能一下子学会所有的东西。有些领域比其他领域更重要。本文将只关注必须知道的技能。
成为专家数据科学家的关键技能。作者图片
在这一部分,我将概述所需的技能。在我看来,只有 4 个主要技能。
1.领域知识
在我们发明解决方案之前,我们需要了解问题。理解这个问题需要非常了解这个领域。
本部分的必备技能是:
- 了解领域内当前的问题和解决方案,以突出低效之处
- 对用户工作方式的深刻理解
- 收入是如何产生的,在哪里可以节省成本
- 了解谁是决策者以及难点是什么
该领域的用户是该领域最好的老师。成为某个领域的专家需要数年时间。在我看来,了解该领域的最佳方式是为用户编写一个数据科学应用程序,以解决该领域中最棘手的问题。
2.讲故事
对于数据科学家来说,最重要的技能是讲述并销售故事的能力,这一点我怎么强调都不为过。讲故事的必备技能是:
- 富有想象力
- 开放实验
- 自信地清晰简明地表达观点
- 有说服力的
- 自信地寻求领域专家的指导
- 展示数据和方法
最重要的是,关键要素是真诚地相信你的想法。
因此,最重要的技能本质上是一种软技能。相信我,只要训练得当,我们都能掌握它。
故事应简明清晰地解释提议的数据科学解决方案要解决的问题。决策者应该能够确定问题确实存在,并且建议的解决方案可以帮助他们削减成本并产生更多收入。
没有讲故事,几乎不可能获得企业资助的项目,而没有项目,数据科学家的技能可能最终会腐烂。
利益相关者询问的常见问题围绕着时间线,这些时间线严重依赖于所需的数据。因此,帮助他们理解那些所需的数据集是什么以及到哪里去获取它们是至关重要的。
在项目生命周期中,解决方案通常会呈现给几个用户。因此,一个人应该能够自信地表达他/她的想法。
因此,关键技能是能够讲述您的数据科学项目的故事,并向目标受众介绍正确的细节。
3.技术技能:
我们需要能够至少准备一个原型,然后将其生产成生产质量的软件。
必备的技能是能够:
- 创建类、函数、调用外部 API,并彻底理解数据结构。
- 通过编程(SQL + Python)从各种来源加载和保存数据的专业知识
- 能够编写函数将数据转换成适当的格式
很明显,理解使用微服务架构设计可伸缩的技术解决方案,以及持续集成和部署的知识是很重要的,但是我现在有意避免提及这些技能,我只关注必须知道的技能。还是那句话,知识越多越好,但是在这里,让我们只关注那些必须知道的。
虽然我们可以使用 R 编程语言,我也写过关于 R 的文章,但是我推荐并且更喜欢使用 Python 编程语言。Python 已经开始成为数据科学家事实上的选择。此外,还有巨大的社区支持。我还没有发现一个关于 Python 的问题没有得到回答。
Google trends 显示 Python 的受欢迎程度正在不断提高:
2004 年以来的全球 Python 趋势。摘自谷歌趋势
因此,技术部分的第一个关键技能是牢固掌握 Python 编程语言。
我强烈推荐阅读这篇文章:
在一篇文章中你需要知道的一切
medium.com](https://medium.com/fintechexplained/everything-about-python-from-beginner-to-advance-level-227d52ef32d2)
众所周知,数据科学家花费大量时间设计收集数据的解决方案。大多数数据本质上要么是基于文本的,要么是数字的。另外,数据集通常是非结构化的。Python 包的数量是无限的,要了解所有的包几乎是不可能的。有 3 个套装我一直推荐给大家:熊猫,Numpy 和 Sci-kit Learn。
Numpy 是数据科学生态系统中广泛使用的包。它在处理数字时非常高效和快速。Numpy 允许我们处理数组和矩阵。
了解如何做到这一点很重要:
- 创建集合,如数组和矩阵。
- 如何转置矩阵
- 执行统计计算并保存结果。
我强烈推荐这篇文章。理解 Numpy 就足够了:
在重新发明车轮之前了解 NumPy 特征
medium.com](https://medium.com/fintechexplained/why-should-we-use-numpy-c14a4fb03ee9)
最后,由于我们大部分时间都花在玩数据上,我们严重依赖数据库和 Excel 电子表格来揭示数据集中隐藏的秘密和趋势。
为了找到这些模式,我推荐读者去学习熊猫图书馆。在熊猫的特性中,有必要了解:
- 什么是数据帧
- 如何将数据加载到数据帧中
- 如何查询数据框
- 如何连接和过滤数据框架
- 操纵日期,填补缺失值,并执行统计计算。
我推荐这篇文章,它正好解释了这一点:
不先探索熊猫就不要编码 Python
medium.com](https://medium.com/fintechexplained/did-you-know-pandas-can-do-so-much-f65dc7db3051)
只要我们能够操纵数据并将其转换为适当的结构,我们就可以使用 Python 来调用任何机器学习库。我推荐每个人阅读 Scikit-learn 库的接口。
4.统计和概率技能
调用机器学习模型本质上是技术性的,但解释和增强模型需要概率和统计的知识。
让我们不要将机器学习模型视为黑盒,因为我们必须向利益相关者、团队成员解释工作方式,并在未来提高准确性。
统计和概率部分的必备技能是:
- 概率分布
- 取样技术
- 模拟技术
- 力矩的计算
- 透彻理解精度测量和损失函数
- 回归和贝叶斯模型理解
- 时间序列知识
一旦我们有了数据,理解数据的底层特征是很重要的。所以我推荐大家去了解统计和概率。特别是,关键是要掌握各种概率分布,它们是什么,采样如何工作,我们如何生成/模拟数据集,以及执行假设分析。
除非我们了解统计学领域,否则机器学习模型可能看起来是一个黑箱。如果我们知道统计学和概率是如何工作的,那么我们就能理解模型并自信地解释它们。
有两篇必读的文章,我推荐大家阅读,以便牢固掌握统计学和概率。
第一篇文章将解释概率的关键概念:
为统计学家解释概率的关键概念
towardsdatascience.com](/understanding-probability-and-statistics-the-essentials-of-probability-for-data-scientists-459d61a8da44)
第二篇文章概述了统计推断技术:
构成数据科学家工作基础的一个必须知道的话题
towardsdatascience.com](/understanding-probability-and-statistics-statistical-inference-for-data-scientists-fd05bde7d63)
虽然神经网络、激活函数、耦合函数、蒙特卡罗模拟和伊藤微积分的知识很重要,但我想专注于必须知道的统计和概率技能。
随着我们开始从事更多项目,我们可以研究高级/专家级架构和编程技能,了解深度学习模型如何工作,以及如何部署和监控数据科学应用,但有必要建立正确的基础。
3.数据科学项目阶段
让我们首先了解一个成功的数据科学项目需要什么。
我们可以用一百万种方式分割数据科学项目,但简单来说,有 10 个关键阶段。
我将在下面解释每个阶段。
数据科学项目的前 5 个阶段。作者图片
1.理解问题
这是数据科学项目的第一阶段。它需要获得对目标业务领域的理解。
它涉及数据科学家与企业主、分析师和团队成员的沟通。首先了解领域中的当前流程,以发现是否有任何低效之处,以及解决方案是否已经存在于领域中。关键是尽早向用户呈现问题和解决方案。
2.阐明解决方案
然后,选择的解决方案清晰地呈现给决策者。项目的输入、输出、交互和成本已经确定。
这种技能有时需要很长时间才能掌握,因为它需要销售和分析技能。人们需要非常好地理解这个领域,并向决策者推销这个想法。
关键是评估概念的合理性,写下并同意所有的假设和基准结果。总是选择一个基准过程。它可以是当前的过程,目标是产生一个优于当前基准过程的解决方案。用户通常知道并理解基准流程。始终记录基准解决方案的工作情况,因为这将有助于比较新的解决方案。
重要的是要提到这些假设,记下它们,并得到用户的确认,因为应用程序的输出将取决于这些假设。
3.数据探索
现在问题陈述已经确定,这一步需要研究项目中所需的数据。它涉及到寻找数据的来源以及所需的数量,例如历史数据的记录数或时间线,以及我们可以从哪里获取数据。
因此,它需要商业和定量分析技能。
4.数据采集
这一阶段主要是与数据团队进行沟通,并获取所需的数据。它需要使用高级编程技术构建工具来收集数据,并将数据保存到存储库中,如文件或数据库。可以通过 web 服务调用、数据库、文件等提取数据。
这需要调用 API 并将它们保存在适当的数据结构中的技术技能。我还建议每个人都充分理解 SELECT SQL 语句。
5.数据转换
此阶段需要检查每个要素,了解我们需要如何填充缺失值,需要执行哪些清理步骤,是否需要操纵日期,是否需要对数据进行标准化或规范化,和/或从现有要素创建新要素。
这个阶段需要理解数据统计概率分布。
数据科学项目的最后 5 个阶段。作者图片
6.模型选择和评估
这一阶段需要将数据输入统计机器学习模型,以便它们能够解释数据、训练自己并输出结果。然后,我们需要调整所选模型的参数,以获得最高的精度。这个阶段需要理解统计模型和准确性度量。有大量的模型可用,每一个都有其优点和缺点。
大多数机器学习模型已经用 Python 实现了,并且它们是公开可用的
关键是要能够知道调用哪个模型,用什么参数,以及如何衡量其准确性。
将输入数据分成三部分至关重要:
- 训练-用于训练模型
- 测试-用于测试已训练模型的准确性
- 验证-用于在微调模型超参数后提高模型准确性
我强烈推荐这篇文章。它以直观的方式解释了端到端的机器学习过程:
解释如何通过简单的步骤构建成功的机器学习模型
medium.com](https://medium.com/fintechexplained/end-to-end-guide-for-machine-learning-project-146c288186dc)
首先选择一个简单的模型也是明智的,它可以给你预期的结果。这个模型被称为基准模型。回归模型传统上是很好的基准模型。
回归模型很简单,可以在早期发现数据集中的错误。记住过度拟合是一个问题,模型越复杂,就越难向用户解释结果。因此,总是先查看更简单的模型,然后应用正则化来防止过度拟合。我们还应该利用 boosting 和 bagging 技术,因为它们可以根据频率对观测值进行加权,并提高模型预测能力。一旦我们穷尽了简单的模型,只有这样我们才应该研究高级模型,比如深度学习模型。
要了解神经网络是如何工作的,请阅读本文:
让我们来理解革命的概念
medium.com](https://medium.com/fintechexplained/understanding-neural-networks-98e94251fb97)
7.测试应用程序
这个阶段需要测试当前代码,以确保它按照预期工作,从而消除任何模型风险。我们必须对测试和 DevOps 技能有一个很好的理解,以便能够实现可以在每次签入时运行的持续集成构建计划。
构建计划应该执行代码的检验,运行所有的测试,准备代码覆盖报告,并产生所需的工件。我们的测试还应该包括向应用程序提供意想不到的数据。我们应该对应用程序进行压力和性能测试,并确保所有的集成点都能工作。关键是在您的解决方案中构建单元、集成和冒烟测试。我还建议构建一个行为驱动的测试框架,确保应用程序按照用户需求构建。我用过behave
Python 包,推荐给大家。
8.部署和监控应用程序
这个阶段包括将代码部署到用户可以测试和使用应用程序的环境中。这个过程需要在没有任何人工干预的情况下运行。这涉及到实现持续部署的 DevOps 技能。它应该获取工件并部署解决方案。该流程应该运行冒烟测试,并通知用户应用程序已成功部署,这样一切都是自动化的。
我们经常被要求在容器中使用微服务架构来跨服务器水平部署解决方案。
解决方案启动后,我们需要对其进行监控,以确保它正常运行,没有任何问题。我们应该记录所有的错误,并实现我们可以调用的心跳端点,以确保应用程序成功运行。
数据科学项目不是一次性的项目。他们需要持续监控获得的数据集、问题和解决方案,以确保当前系统按预期运行。
我强烈推荐这篇旨在从基础知识方面解释微服务架构的文章:
微服务架构越来越受欢迎,几乎在所有主要的软件项目中都有使用。这是…
medium.com](https://medium.com/fintechexplained/what-is-microservices-architecture-1da41a94a29b)
9.应用结果演示
我们现在准备展示结果。我们可能希望构建一个 web 用户界面,或者使用其他工具中的报告工具(如 Tablaue)向用户呈现图表和数据集。
这又回到了领域和讲故事的技巧。
10.回溯测试应用程序
最后,对应用程序进行回测也很重要。一旦模型被激活,我们想要确保它总是按照我们期望的那样工作。验证模型的一种方法是输入历史数据,并从数量和质量上验证结果。
当前项目成为下一阶段的基准。接下来的阶段可能涉及改变数据集、模型,或者只是微调超参数。
很难找到一个人可以独立完成所有阶段的工作,但这些超级明星在行业中确实存在,他们是专家数据科学家。获得所有需要的技能需要多年的努力,是的,只要有合适的项目和足够的时间,这是可能的。在一个阶段比另一个阶段更自信当然很好,但关键是对每个阶段都有足够好的理解。
4.数据科学常见陷阱
在从事数据科学项目时,记住常见的陷阱很重要。
这一部分将提供陷阱的概述。
数据科学项目的常见陷阱。作者图片
错误的输入数据
确保你的输入数据是高质量的,否则,你将花费大量的时间来产生一个对用户没有好处的解决方案。
错误的参数
模型本质上是一组函数。函数的参数通常是基于直觉和知识来校准和决定的。确保参数是正确的,并且参数中传递的数据是好的,这一点很重要。
错误的假设
验证关于数据和模型及其参数的假设是很重要的。错误的假设最终会浪费大量的时间和资源。
型号的错误选择
有时我们选择了错误的模型,并给它输入正确的数据集来解决正确的问题。不出所料,应用程序会产生无效的结果。有些模型只适合解决特定的问题。因此,一定要确保所选择的模型适合您试图解决的问题。
编程错误
数据科学项目有时需要大量编码。在实现不正确的映射、数据结构、函数和一般的编码错误时,这些错误会被引入到项目中。关键是在您的解决方案中构建单元、集成和冒烟测试。我还建议建立一个行为驱动的测试框架。
软件工程师/分析师/经理或任何人都可以成为专业的数据科学家,只要他们继续在数据科学阶段工作
5.数据科学最佳实践
最后,我想概述一下数据科学项目的最佳实践。
最佳实践。作者图片
- 注意模型的优缺点。不是所有的模型都能解决所有的问题。如果您选择了平滑技术,那么请确保您了解衰减因子以及该方法是否有效。始终选择一个简单的基准模型,并尽早将结果呈现给最终用户。另外,将数据分为训练集、测试集和验证集。
- 始终构建一个基准模型,并向领域专家展示结果。根据预期输入测试项目,以确保结果符合预期。这将澄清假设和输入数据集的大部分问题。
- 根据意外输入测试项目,以确保结果不是意外的。对项目进行压力测试极其重要。
- 测试应用程序的性能。必须确保它能够处理大型数据集和请求。从一开始就建立 CI/CD 计划。
- 总是根据历史数据对你的模型进行回溯测试。输入历史数据来统计遇到的异常数量是很重要的。由于历史不会重演,关键是要记住回溯测试可以验证项目实施时设定的假设。因此,总是对模型进行回溯测试。
- 记录和评估提议方法的合理性,并监控应用。确保领域的业务用户在项目的早期阶段和各个阶段都参与进来。持续监控应用程序,以确保它的响应和工作符合预期。
摘要
感谢您的阅读。作者图片
数据科学是当今非常热门的学科。本文概述了成为一名成功的专家数据科学家所需的技能。然后,它概述了我们在数据科学模型构建项目中面临的最大问题以及最佳实践。
随着时间的推移,我们可以开始收集更多的数据,例如并行运行代码或构建容器来启动应用程序,或者模拟数据来预测模型。然而,这里的关键点是概述必须知道的技能。
让我知道你的想法。
理解 T5 模型:文本到文本转换转换器模型
介绍
最近几年已经有太多的预训练模型被开源到 NLP 社区,比如乌尔姆菲特、伯特、 GPT 等等。鉴于这种庞大模型的规模,考虑到所需的数据量和计算量,从头开始训练这种网络几乎是不可能的。这就是一种新的学习范式“迁移学习”开始发挥作用的地方。迁移学习是机器学习中的一个研究问题,它专注于存储在解决一个问题时获得的知识,并将其应用于不同但相关的问题。这个想法是使用预先训练好的网络权重,并对其进行微调,以完成手头的一些特定任务。我们希望利用网络权重的事实要求它首先在一个非常大的高质量语料库上进行训练,以学习语言结构、语法和语义。大多数现有的模型,如乌尔姆菲特、GPT,都是用维基百科和谷歌新闻数据集上的语言模型目标进行预训练的。然而,另一方面,伯特接受了 MLM(掩蔽语言模型)目标的训练。在这篇文章的后面,我们将会看到什么是 MLM,以及 T5 是如何以相似的目标进行训练的,只是做了一些一般化的调整。只是为了确保每个人都在同一页上,一个语言模型是一个机器学习模型,它查看句子的历史部分并预测句子中的下一个单词。
T5:****Text-To-Text-Ttransfer-Ttransformer模型提出将所有 NLP 任务重新组织成一个统一的文本到文本格式,其中输入和输出总是文本串。这种格式使一个 T5 型号适合多种任务。从特色动画中可以看出,它从左侧为各种 NLP 任务接收文本输入,并为相应的任务输出文本。我们将在下面的章节中看到更多关于模型如何被训练的内容。在此之前,我想讨论一下用于预训练模型的数据。作者将其命名为 C4 (庞大干净的爬行语料库)。它的大小约为 700GB,是清理后的版本通用抓取数据集。作者提到了仅提取英文文本、删除代码行、重复数据删除等意义上的清理。这是一个高质量的预处理英语语料库,他们已经提供了下载。此外,T5 模型在 C4 上进行了预先训练,在许多 NLP 基准测试中取得了最先进的结果,同时具有足够的灵活性,可以针对各种重要的下游任务进行微调。
培训目标
第 10 页—https://arxiv.org/pdf/1910.10683.pdf
T5 的训练目标也与 BERT 的相同,即稍加修改的掩蔽语言模型。掩蔽语言模型是双向模型,在任何时候 t,单词的表征都是从它的左右语境中导出的。T5 采用的细微差别是用单个掩码关键字替换多个连续的标记,这与对每个单词使用掩码标记的 BERT 不同。从上图中可以看出,通过添加扰动,原始文本被转换为输入和输出对。由于最终目标是训练一个输入文本和输出文本的模型,目标被设计成产生一个序列,与 BERT 不同,它试图通过最终的前馈和 softmax 在输出级别输出一个单词(本身)。
该模型在 C4 语料库 *(如上所述)*上进行训练,其目的与预训练的一部分相同。然后,它在各种任务上进行微调,如语言翻译、摘要、句子相似度等。微调是通过向每个输入中添加特定于任务的前缀文本来显示模型 I/O 文本对。例如— 将英语翻译成德语:< text > ,添加这样的前缀使模型能够针对手头的特定任务调整其权重,并且通过缩小其生成范围,仅产生该任务的预期输出。所有的任务本质上都有相同的目标、训练程序和解码过程。作者还声称,他们没有发现任何一个案例,其中模型变得混乱,并输出完全随机的东西或另一项任务的预期输出。一件非常有趣的事情是,他们甚至将回归任务建模为文本生成目标,比如句子相似度。为了缩小实数的范围,他们生成了一个 0 到 5 之间的 0.2 量化的数字,这意味着,该模型只能生成 0.2 差异的数字,例如-3.2,3.4,3.6 等。LR 计划、符号化、序列长度等训练级别细节可在 3.1.2 中详细阅读。培训科。
作者进行了广泛的超参数调整和跨各种任务的测试。下图显示了不同级别的调整-
- 预训练风格 —他们尝试了典型的自回归风格语言建模目标、BERT 风格掩蔽语言模型目标和去混洗去噪目标。他们发现 BERT 风格(缺失上下文预测)是预训练模型的最佳选择。
- 讹误方案——他们试验了 3 种讹误策略,屏蔽一个随机单词,屏蔽一个跨度(超过 1 个连续单词),从输入中删除一个单词。考虑到手头的任务类型,即两个 I/O 都是文本字符串,破坏 span 最适合它们。
- 腐败率-在尝试了不同的腐败率后,他们发现所有腐败率的表现几乎相同,其中 15%的腐败率略好。
- 讹误长度 —他们还试验了不同的讹误跨度长度,发现跨度长度越大,模型的性能越差,这似乎也是真的,考虑跨度长度等于句子长度将意味着模型从空输入中产生文本,使其具有高度可变性的灵活性。
第 19 页—【https://arxiv.org/pdf/1910.10683.pdf
我也鼓励读者阅读第 32 页:反思来理解培训模型的要点。
演示
本节将重点对预训练的 T5 模型进行推理。所有代码已经提交到Github:Text-to-Text-Transfer-Transformer。随意克隆和玩。此外,不要忘记开始回购,以防你喜欢它。
针对各种预培训任务的 T5 模型演示。-prak har 21/T5-文本到文本转换器
github.com](https://github.com/prakhar21/T5-Text-to-Text-Transfer-Transformer)
你的母语不是英语吗?查看多语言字幕视频解说版本(同样,更详细)——
参考文献
1。谷歌 AI 博客—T52。https://arxiv.org/pdf/1910.10683.pdf
你也可以查看我写的其他研究论文的解释
我希望这本书值得你花时间阅读。谢谢大家!
【https://prakhartechviz.blogspot.com】最初发表于。
理解文本向量化 I:如何拥有一袋单词已经显示了人们对你的产品的看法
自然语言处理
Sklearn 管道、SHAP 和面向对象编程在情感分析中的应用
你知道吗,在神经网络变得无处不在之前,我们已经(几乎)解决了情感分析问题?
在当前自然语言处理(NLP)越来越依赖深度学习模型来产生惊人性能的时代,我们经常忽略最简单类型的文本矢量化技术的重要性——单词袋(BOW)和词频-逆文档频率(TF-IDF)。事实上,通过这两种技术,我们已经能够以超过 80%的准确率预测一段给定文本的情感。换句话说,我们对最先进的深度学习模型所做的一切只是试图从这些分类问题中挤出更多的性能改进。在某种程度上,几乎所有更复杂的模型都依赖于 BOW 和 TF-IDF 的概念。在这篇博文中,我们将在 sklearn pipelines 的帮助下,尝试理解和实现 BOW 和 TF-IDF。
为什么选择 Sklearn 管道?
您可能会认为使用管道是一种极端的大材小用。事实上,实现管道需要在面向对象编程(OOP)中大量使用,这可能会使调试变得相当困难。虽然我花了两周的时间来实现 BOW 和 TF-IDF(其间我犯了一些错误,在另一篇博客中会有更多的介绍),但这绝对值得花时间和精力。通过使用 sklearn 管道,我们能够在单个函数调用中使用原始数据进行转换和训练/预测。例如,如果我们想使用 sklearn 的 TF-IDF 矢量器,训练 logistic 回归模型,我们只需使用以下几行代码。
**from** sklearn.feature_extraction.text **import** CountVectorizer
**from** sklearn.linear_model **import** LogisticRegression
**from** sentiment_analysis.models.model **import** StreamlinedModellogistic = StreamlinedModel(
transformer_description="Bag of words",
transformer=CountVectorizer,
model_description="logisitc regression model",
model=LogisticRegression,
)
TfidfVectorizer
和LogisticRegression
是来自 sklearn 的模块对象,而StreamlinedModel
是我们将要实现的管道对象。正如你可能已经看到的,有了这个结构,我们将能够很容易地用任何变形金刚和模型交换上述两个对象——这个结构将保持界面的通用性,并使特征提取变得轻而易举。还有一些其他真正重要的原因,我们希望以这种方式构建模型,但这将在另一篇博客文章中讨论。
实现流线型模型
要实现StreamlinedModel
类,我们应该回忆一下我们熟悉的大多数 sklearn 包是如何使用的。举个例子,
logistic = LogisticRegression()
logistic.fit(X_train, y_train)
logistic.predict(X_test)
我们的StreamlinedModel
将有相同的行为,因此我们将在类中添加相同的.fit
和.predict
方法。其他有用的方法包括.predict_proba
和.score
。这些方法可以只是 sklearn 的BaseEstimator
中相同方法的包装器。例如,管道培训模型可以简单地是
然后,我们可以构建一个名为make_model_pipeline
的类方法,它在类实例化时使用 4 个参数,并创建一个 sklearn 管道对象。
这个self.pipeline
就是我们可以称之为.fit
和.predict
等的同一个对象。就是这样!我们已经创建了StreamlinedModel
。下面是完整的实现
词汇袋模型
由于可以灵活地将变压器转换为我们选择的任何变压器,我们现在可以将相同的接口用于我们定制的 BOW 和 TF-IDF 变压器。出于区分的目的,我们将我们定制的弓变压器称为WordFrequencyVectorizer
。同样的StreamlinedModel
可以以如下方式使用
**from** models.feature **import** WordFrequencyVectorizer
**from** sklearn.linear_model **import** LogisticRegression
**from** sentiment_analysis.models.model **import** StreamlinedModellogistic = StreamlinedModel(
transformer_description="Bag of Words",
transformer=WordFrequencyVectorizer,
model_description="logisitc regression model",
model=LogisticRegression,
)
在这篇博文中,我们将重点讨论单词包模型的实现,而将 TF-IDF 留给下一篇。
大意
弓模型的想法非常简单。我们希望找到能够强烈反映积极或消极情绪的特定单词的分数。例如,一篇评论包含更多积极的词,如“棒极了”,“棒极了”会被认为比一篇评论包含“一般”这样的词更积极。由于评论都有不同的长度,我们需要用 0 填充每个评论中没有包含的单词。例如,如果我们有以下 3 个评论,
I love dogs, I think they have adorable personalities.
I don't like cats
My favorite pet is a bird
我们会让每一个独特的词占据一个特定的位置。那些没有包含在评论中的单词将被填充为 0,而出现不止一次的单词将被增加到它们出现的次数。
矢量化的评论
现在我们了解了 BOW 模型如何工作的一般概念,是时候看看我们如何将这个概念应用到我们的情感分析任务中了。我们将从从数据源加载评论开始。
加载评论
我们将在这个项目中使用的数据是来自约翰·霍普斯金大学多领域情感数据集的评论。一旦我们下载并解压缩数据,我们将看到一系列具有以下结构的文件夹。
/reviews
|--/books
|--positive.review
|--negative.review
|--/dvd
|--positive.review
|--negative.review
|--electronics
|--positive.review
|--negative.review
|--kitchen_&_house_supplies
|--positive.review
|--negative.review
我们希望将所有正面/负面的评论合并在一起,这样我们就不需要分别引用各个文件夹。我们将创建一个名为LoadReviews
的类来实现这个目标。这个类的完整实现如下所示
由于评论是以 XML 格式存储的,我们必须使用BeautifulSoup
将评论解析成文本字符串。实际的文本评论存储在标签review_text
中。在阅读文本评论时,我们还会过滤掉不是 Unicode 字符串的字符。静态方法strip_non_printable
完成这样的任务。所有处理过的评论都将存储在类别属性reviews
中。正如您可能注意到的,我们的 BOW 模型将只对单个单词令牌而不是长字符串进行操作,我们将需要采取进一步的措施来将评论预处理成 BOW transformer 可以使用的正确的矢量化格式。
文本预处理
为了开始预处理步骤,我们将首先把每个评论的长 str 格式转换成评论的标记化版本,这可以通过用空格分割字符串来容易地完成。比如字符串“我爱 nlp”就会变成列表[“我”、“爱”、“NLP”]。
tokens = s.split()
使用 split 可能会导致常见的边缘情况,即单词有标点符号,但中间没有空格,例如“hello”。为了避免这个单词作为“hello”被区别对待,我们将去掉所有的标点符号,用空白替换它。
s = s.translate(str.maketrans(string.punctuation,
" " * len(string.punctuation)))
很多没有强烈感情指示的词,如“我”、“他们”、“一个”,但还是会占空格。我们将继续从唯一单词列表中删除它们,使它们不再占据位置。
tokens = [t for t in tokens
if t not in stopwords.words("english") + [""]]
此外**,不同形式的相同词语,如“work”到“worked”,需要被视为相同词语**。这将要求我们对所有单词进行词干分析和词序分析,使其恢复到原始形式,这可以通过使用 NLTK 的词干分析器来完成。
tokens = [wordnet_lemmatizer.lemmatize(t) for t in tokens]
最后,我们还将删除长度小于 2 个字符的单词,因为它们可能对情感没有什么意义。
tokens = [t for t in tokens if len(t) > 2]
所有这些步骤都可以打包成一个名为WordTokenizer
的实用程序类,实现如下。
准备好所有这些组件后,我们现在准备实现 BOW 模型。
BOW 实现
由于模型将被StreamlinedModel
对象用作转换器,我们需要遵循 sklearn 管道构建定制转换器的指导方针。这意味着对象需要有一个.transform
和一个.fit
方法。.fit
方法将负责保存训练中的特定参数的转换,并在预测过程中应用它们。具体来说,在我们的情况下,数据集中包含的唯一单词列表将在训练期间拟合,但在预测期间不会再次重新拟合。
word_index_mapping
将是对象ReviewProcessor
的一个属性,本质上是所有唯一单词的枚举。如果预测过程中的单词不是唯一单词列表的一部分,我们还会将向量的最后一个位置设置为“未知单词”。
.transform
方法用于将输入的原始文本转换成词频向量。
get_word_frequency_vector
方法将接受检查,并根据预先计算的word_to_index
映射增加向量中相应索引处的值。如果输入的审查文本包含未知单词,则word_frequency_vector
的最后一个索引将递增。
弓形变压器的完整实现如下所示
现在我们已经将 BOW 实现为一个变压器,我们可以使用StreamlinedModel
构建 4 个不同版本的模型并比较性能。
绩效评估
正如StreamlinedModel
能够使用任何转换器一样,我们也可以通过交换model
参数来使用不同的机器学习模型。例如,之前我们通过调用LogisticRegression
对象使用了逻辑回归模型,我们可以将它更改为 lightGBM 模型,如下所示
**from** models.feature **import** WordFrequencyVectorizer
**import** lightgbm **as** lgb
**from** sentiment_analysis.models.model **import** StreamlinedModellgbm = StreamlinedModel(
transformer_description="Bag of words",
transformer=WordFrequencyVectorizer,
model_description="logisitc regression model",
model=lgb.LGBMClassifier,
)
我们将尝试 4 种不同的模型,并收集它们的预测 AUC 分数,以制作柱状图。
使用逻辑回归模型已经可以得到 0.82 的 AUC 分数。
LightGBM 模型还帮助我们将性能提高到 0.888,显示了树模型比线性模型更好的预测能力。
最有趣的结果来自两种不同的朴素贝叶斯模型,它们产生了截然不同的结果,高斯朴素贝叶斯比多项式朴素贝叶斯表现得更差。由于高斯朴素贝叶斯模型被设计为对连续变量进行操作,而词频只是离散的,因此低于标准的性能是意料之中的。
您可能已经注意到,在这个情感分析任务中,相对简单的多项式朴素贝叶斯模型取得了与相当高级的 lightGBM 模型相当的性能。那么我们的模型是如何做出决定的呢?让我们仔细看看。
错误分类的正面/负面评论
由于有多个评论被错误分类,我们将只显示与正确标签距离最大的评论。为此,我们将对预测概率进行排序,打印出第一个/最后一个(取决于标签)
# get the indices of the misclassified reviews
wrong_positive_inds = np.where((y_test == 1)
& (y_pred != y_test))[0]
wrong_negative_inds = np.where((y_test == 0)
& (y_pred != y_test))[0]# most wrong positive review
most_wrong_positive_index = wrong_positive_inds[
y_prob_lgbm[:, 1][wrong_positive_inds].argmax()
]# most wrong negative review
most_wrong_negative_index = wrong_negative_inds[
y_prob_lgbm[:, 1][wrong_negative_inds].argmin()
]
最错误的正面评价
这是一篇相当长且详细的正面评论,提到了这本书的优点和缺点。在弱点部分,一些负面词汇如“ 问题 ”、“ 而不是 ”被多次提及,这反过来增加了对该复习进行分类的难度。
我们来看看最错误的负面评论。
这个负面评论还包含一个正面词“ 有趣的 ”,没有明显的负面词(可能“ 过时的*”*是一个负面词),使得将这个评论归类为负面的可能性更小。
那么模型认为一篇评论到底哪些词是正面/负面的呢?接下来我们来看看。
特征重要性
在这一点上,我们经常会提出如何在两个性能最好的模型(LightGBM 和多项式朴素贝叶斯)之间进行选择的问题。答案在于互操作性。由于朴素贝叶斯依赖于计数和概率,我们可以很容易地找出哪些词对情感有贡献。然而,LightGBM 模型并不那么简单。由于大量独特的词,树分裂是相当具有挑战性的形象化。我们真的没有运气解释它们吗?
不完全是。在模型解释包 SHAP 的帮助下,我们可以在一个单独的评论中产生一个特性重要性的可视化(更多关于 SHAP 的信息在另一篇文章中)。在下面的 SHAP 可视化图表中,红色表示预测的情绪接近 1,而蓝色表示预测的情绪为 0。下面是模型预测为正的示例审查
一个非常正面的评论的例子
由于该评论包含强烈的积极词汇,如“ 最佳 ”和“ 享受 ”,因此该评论被预测为积极的。
非常负面的评论的例子
负面评论通常由负面词汇组成,如“”、“ 失败 ”或“ 不好 ”。
结论
对于情感分析任务来说,单词包可能是最简单的文本矢量化类型,但它已经非常有效了。GitHub 项目可以在这里找到。下面是我们今天学到的内容。
- 面向对象编程极大地提高了整个工作流程的灵活性。在 sklearn pipelines 的帮助下,我们可以用同一个 BOW transformer 快速迭代和测试多个机器学习模型。
- 我们必须为底层任务使用正确的模型。高斯朴素贝叶斯模型是唯一不能获得超过 80% AUC 分数的模型。这只是一个错误的模型,因为它被设计为对连续特征进行操作。
- LightGBM 赢得了比赛(以微弱优势)。基于树的模型能够产生相当大的拟合度和最佳性能,尽管多项朴素贝叶斯的性能仅稍差。
- LightGBM 需要依靠一些特殊的解释包才能被理解,现在我们正在得到它。随着模型解释在我们的行业中变得越来越重要,我们经常被迫选择更简单的模型来实现互操作性。SHAP 的存在改变了这一切。
在下一篇文章中,我们将在单词袋模型的基础上,用一个智能加权方案来改进它。下次见!
理解文本矢量化 II:TF-IDF 如何让您的简单模型拥有与高级模型匹敌的能力
自然语言处理
Sklearn 管道、SHAP 和面向对象编程在情感分析中的应用
L 让我们继续我们的情感分析之旅。
记得上次我们谈到使用单词袋模型来检测评论文本的情绪,我们已经有了一个相对较好的性能。今天,我们将在已有成果的基础上,用智能加权方案升级单词袋模型。在本帖中,我们将利用来自第 1 部分的自定义管道StreamlinedModel
对象,并见证从逻辑回归等简单模型应用 TF-IDF 转换器所获得的惊人改进。
词频—逆文档频率(TF-IDF)
我们已经知道计算词频可以帮助我们判断评论文本的情感,但是这种方法忽略了单词在整个文档中的重要性。我们讨论了使用智能加权方案来解决这个问题,但是我们具体如何执行呢?
大意
答案是使用一种加权方案,该方案与该单词在所有文档中出现的频率成反比。如果这个词出现在几乎每一篇文档中(比如“ 我 ”、“ 你 ”或者“ 他们 ”),那么如果我们对它们进行同等的加权,很可能会被视为非常重要。因此,我们想增加那些不经常出现的单词的权重。例如,使用相同的 3 篇评论
I love dogs, I think they have adorable personalities.
I don't like cats
My favorite kind of pet is bird
我们可以看到“ 萌 ”只出现在 3 个文档中的 1 个,文档频率为 3/(1+1)。我们在分母上加 1 以避免它变成 0。然后,我们将获取文档频率的自然对数值,这将为我们提供以下内容
idf(adorable) = log(3/2) = 0.176
与在 3 个文档中的 2 个中出现的类似于“ I 的单词相比,我们将得到如下的逆文档频率
idf(I) = log(3/3) = 0
然后我们将这袋字数乘以这个权重,得到 tf-idf 值。具体来说,
tf-idf(t, d) = tf(t, d) x log(N/(df + 1))
现在我们了解了 TF-IDF 的大致思想,让我们看看我们应该如何将这个模型实现为一个转换器。
TF-IDF 实施
我们将经历与第一部分中概述的相同的文本预处理步骤。由于术语频率定义与单词袋模型相同,我们将关注如何有效地计算所有单词的逆文档频率。
因为我们必须检查每个单词是否存在于每个文档中,所以运行时间可能是 O(n),这将相当慢。我们可以将预计算的 IDF 保存在属性化的类中,并在计算词频时引用它。
我们从获取所有单词的文档频率的辅助方法开始。在 pandas .str.contains
方法的帮助下,该方法将检测一列字符串中部分字符串的存在并返回一系列 0/1,我们可以对这些系列求和以获得单词的文档频率。然后,我们将重复相同的过程,并将结果存储在字典中。
我们将在转换器的.fit
方法中使用get_document_frequency
方法,对每个单词的文档频率应用对数转换。得到的 idf 值将被保存为一个类属性,当我们计算词频时,它将被用作权重。
我们的.transform
方法将由两部分组成。除了计算词频(在 part 1 中也有),我们还会把它们乘以对应的 IDF 值。因为对于每个评论,我们将具有相同的 IDF 权重(因为单词索引顺序是固定的),所以我们将重复 IDF 向量 N 次(等于评论的数量),以使 IDF 矩阵具有与单词频率矩阵相同的形状。最后,我们将在两个矩阵之间执行元素级乘法,以获得所有评论的 TF-IDF 值。
我们现在准备将 tf-idf 用作变压器。完整的实现如下所示。正如你可能注意到的,TermFrequency_InvDocFrequency
变压器与第一部分中的WordFrequecyVectorizer
变压器共用多个部分。最好的实现是类继承。实现每一个 helper 函数仅仅是为了清晰起见,以防您对将单词包转换器作为主类不感兴趣。
现在我们已经将 TF-IDF 实现为一个变形器,我们将做同样的事情,使用StreamlinedModel
构建 4 个不同版本的模型并比较性能。
绩效评估
同 part 1 ,我们将使用以下函数原型生成 4 个StreamlinedModel
对象。
**from** models.feature **import** TermFrequency_InvDocFrequency
**import** lightgbm **as** lgb
**from** sentiment_analysis.models.model **import** StreamlinedModellgbm = StreamlinedModel(
transformer_description="TF-IDF",
transformer=TermFrequency_InvDocFrequency,
model_description="logisitc regression model",
model=lgb.LGBMClassifier,
)
我们将尝试 4 种不同的模型,并收集它们的预测 AUC 分数,以制作柱状图。这一次我们将比较我们以前获得的 AUC 分数,看看我们是否实际上能够获得任何改进。
确实有所改善。
使用我们的 tf-idf 转换器,即使使用逻辑回归模型,我们也能够获得 0.896 的 AUC。这将给我们的模型解释带来显著的优势——因为单个词的逻辑回归系数可以直接解释为对评论情感的重要性。不再需要外部包装。
我们还看到多项式朴素贝叶斯模型的性能略有提高,其 AUC 从 0.883 增加到 0.898,现在略高于旧的 winner lightGBM 模型,后者几乎没有任何改进。
还记得这篇博文的标题吗?TF-IDF 确实为逻辑回归这样的简单模型提供了击败 lightGBM 这样的高级模型的能力。这是一个完美的例子,使用正确的特性工程工具会给你带来难以置信的性能提升。
接下来我们来看看,是不是因为换了变形金刚,才发现最错误的正/差评都变了。
错误分类的正面/负面评论
我们将使用与第 1 部分相同的行来获得最错误的正/负指数。
# get the indices of the misclassified reviews
wrong_positive_inds = np.where((y_test == 1)
& (y_pred != y_test))[0]
wrong_negative_inds = np.where((y_test == 0)
& (y_pred != y_test))[0]# most wrong positive review
most_wrong_positive_index = wrong_positive_inds[
y_prob_lgbm[:, 1][wrong_positive_inds].argmax()
]# most wrong negative review
most_wrong_negative_index = wrong_negative_inds[
y_prob_lgbm[:, 1][wrong_negative_inds].argmin()
]
最错误的正面评论(来自多项朴素贝叶斯模型,因为它现在是表现最好的模型)是
老实说,我不知道这是一个积极的评论。它包含了强烈的否定词,如“”和“ 而不是 ”。我们的模型出错是可以理解的。
最错误的负面评论(来自多项朴素贝叶斯)是
我可以看出这篇评论是负面的,但是这篇评论没有任何强烈的负面词汇(见下一节),犯这个错误也是可以理解的。
特征重要性
我们已经在第 1 部分中看到了使用 SHAP 来可视化个人评论的例子,我们可以使用 SHAP 来可视化总体水平上的功能重要性。
最重要的词其实是明显的情绪指示词。
“ 伟大的 ”、“ 容易的 ”、“ 爱情的 ”作为强有力的肯定
“”、“”、“ 废物 ”为强负者**
结论
我们使用 tf-idf 作为情感分析模型的特征工程工具,改进了我们的文本矢量器。事实上,tf-idf 也是许多更复杂的特征工程工具的基础,例如 word2vec。同样,GitHub 项目可以在这里找到。现在,让我们总结一下我们在这篇博文中学到了什么。
- 获得正确的功能比使用更先进的型号更重要。使用 TF-IDF 将提高特征质量,甚至允许简单的模型胜过更高级的模型。
- 将值缓存为类属性将提高计算时间。保存每个字的 IDF 值使我们能够加快速度,否则这将是一个相当缓慢和昂贵的双 for 循环操作。
这就是文本矢量化的全部内容!接下来,我们将了解一些使用深度学习的更高级的特征提取工具。下次见!
使用数据可视化理解 2020 年美国股市下跌
使用数据可视化和历史背景分析与新冠肺炎相关的美国股票市场抛售的严重性。
如果你不知道美国股市在过去两个月下跌,那么你要么:
- 一个大学生,或者
- 一个没有投资和一生价值的学生贷款的初级工人
不管怎样,不管你是否投资了这个市场,你都应该知道过去几周发生了什么。取决于你站在哪里,你是幸运还是不幸,足以目睹一场 黑天鹅 事件。快速水平设置:Investopedia 将黑天鹅事件漂亮地定义为:
超出正常情况预期的不可预测的事件,具有潜在的严重后果。黑天鹅事件的特点是极其罕见,影响严重,而且人们普遍认为事后才明白。
在这篇文章中,我将量化 2020 年美国股市下跌的影响,并使用数据科学将其与近期(和不太近期)历史上的其他主要下跌进行比较。我将收集数据来帮助构建我的案例,构建比较统计数据来给出背景,并构建可视化来传达重要的想法。
最后一件事,我只使用公开可用的数据,所以本文中使用的数据可视化和原始数据的所有代码都可以在我的项目 GitHub 中获得。现在,让我们开始吧!
量化过去几周的市场动荡
我们可以使用一些不同的数据集来理解市场中的绝对混乱。让我们从分析过去 3 个月(01/02/20–03/20/20)标准普尔 500 的标准统计数据开始。这是我的数据集的样子:
显示标准普尔 500 的开盘价、最高价、最低价、收盘价、变化率和成交量的标准数据集
你可能每次在网上搜索股票时都会看到这些描述符;现在,让我们做一些分析来更好地理解它们。我将首先展示简单的价格/时间图表,它已经揭示了很多信息。
你可以清楚地看到,大约在 2 月中旬(02/19),市场波动开始急剧增加。请注意,波动性的增加是重点,而不一定是趋势是上升还是下降。让我们更进一步,添加一个随时间变化的市场交易量的可视化,它显示了发生了多少交易。
现在你也可以看到市场波动和交易量都增加了,特别是在过去几周。至少在表面上,从上面的图表中你可以看到的另一件事是,成交量第一次真正暴涨是在市场开始几次大跌后的一两天。
让我们使用另一个可视化工具来查看价格和市场容量的变化百分比。这些描述符使用不同的尺度,因此我们将使用派生统计来查看异常情况。一个很好的方法是使用 Z 分数。简而言之,Z 分数是一种统计数据,它让您了解一个数据点离平均值有多远。鉴于我们过去 3 个月的样本量,平均值非常偏斜,所以我将使用修正的 Z 值,它依赖于中位数,因为它对异常值和偏斜不太敏感。此外,我将只使用修改后的 z 得分的绝对值,因为我只对距离中值的距离感兴趣,而不是方向。你可以在下面看到结果。
现在我们已经确认了异常的市场百分比变化先于异常的交易量。从图表中,您可以看到在 2 月 22 日的周末发生了一些事情,导致百分比变化从中位数的大约 0.5 个标准差上升到大约 2 个标准差。在后续的帖子中,我将在那个周末探索冠状病毒病例,以进一步了解发生了什么。
虽然从 Z 分数的角度来看这个时间线是有用的,但是下面可以看到进一步捕捉市场恐慌的最后一个可视化,其中我简单地绘制了标准普尔 500 的每日%变化。注意峰值和谷值在过去几周是如何真正爆发的,以及相同数据的箱线图中异常值的数量。
我们花了几分钟单独分析美国市场的下跌。在下一节中,我们将把这次下跌与近期历史上的其他下跌进行比较,以获得更好的背景,并真正回答以下问题:
这次市场下跌有多严重?
漂亮。不好。
在理解任何时候的市场行为时,最有用的策略之一是了解一些历史背景。在本节中,我们将把 2020 年美国股市下跌与近期历史上的其他下跌进行比较,以进一步分析市场反应。
为此,我收集了市场上最近 10 次 10%以上的下跌数据。正如你所看到的,这个列表包含了大约 10-20%的提款,以及 2007-2008 年的金融危机和 2000 年的网络泡沫,它们都要严重得多。在此之后,我收集了这些时间段的每日 S%P 500 收益。我在这里的目标是,在其他统计数据中,比较 2020 年股市下跌的速度与过去 20 年的下跌速度。
在构思了一些不同的数据可视化后,我决定用一个意大利面条图来最好地展示最近下跌的严重性。可视化可以在下面看到。
正如你所看到的,我决定建立一个图表来展示一笔 10,000 美元的投资从提款开始时价值的下降。这为分析下降的严重程度创造了一个平台。从图表中可以看出,2020 年美国市场不仅投资价值的绝对跌幅更大,而且跌幅也更快。这可以在下面的图表中再次看到,我已经将每种下降分开。
好了,现在你知道了!2020 年美国市场的下跌绝不是一个小事件。在 30 天的时间里,标准普尔 500 的总市值蒸发了近 8 万亿美元。更具体地说,那超过 80 亿美元。未来,我将关注与冠状病毒相关的数据集,以进一步分析市场行为。
我希望你喜欢读这篇文章,就像我喜欢把它放在一起一样。如果您有任何问题、反馈或意见,请随时通过 LinkedIn 或我的网站与我联系。此外,本文中使用的数据可视化和原始数据的所有代码都可以在我的项目 GitHub 中获得。
每个人都要保持安全,继续创造酷的东西。
从卫星图像检测森林砍伐
数据规格,来源:星球:从太空了解亚马逊
对于我作为 Udacity 的机器学习工程师 Nanodegree 的一部分的顶点项目,我的任务是通过应用整个课程中学到的机器学习算法和技术来解决我选择的一个问题。我决定选择一个我非常热爱的领域:拯救环境。我听说过一个过去的 Kaggle 比赛,其中包括通过奇妙的 fast.ai 课程对亚马逊雨林的卫星图像进行分类。你可以在这里找到比赛。我决定踏上探测雨林砍伐的旅程,看看我能在 Kaggle 排行榜上爬多高。
背景
亚马逊是世界上最大、最具生物多样性的热带雨林,占地 210 万平方英里。它由大约 3900 亿棵树组成,分为 16000 个种类。亚马逊被称为“地球的肺”,因为它有助于稳定地球的气候,并通过固定二氧化碳和产生世界上 20%的氧气来减缓全球变暖。
自 1978 年以来,超过 289,000 平方英里的亚马逊雨林已经在巴西、秘鲁、哥伦比亚、玻利维亚、委内瑞拉、苏里南、圭亚那和法属圭亚那遭到破坏。每一分钟,世界都会失去 48 个足球场大小的森林面积。人们担心,森林的破坏将导致生物多样性的丧失、栖息地的丧失以及植被中所含碳的释放,这可能会加速全球变暖。关于森林砍伐和人类侵占森林的位置的更好数据可以帮助政府和当地利益攸关方更快、更有效地做出反应。
亚马逊的选择性伐木,来源:星球:从太空了解亚马逊
问题陈述
这个项目的目标是利用卫星图像数据追踪由于森林砍伐导致的亚马逊雨林的变化。这些数据由 Planet 提供,由 Kaggle 主办,作为之前比赛的一部分——Planet:从太空了解亚马逊。这项任务的标签是与 Planet 的影响团队合作选择的,代表了亚马逊盆地感兴趣的现象的合理子集。该任务是一个多标签图像分类问题,其中每幅图像将具有一个并且可能不止一个大气标签以及零个或多个常见和稀有标签。
带有标签的数据示例,来源:星球:从太空了解亚马逊
估价
模型基于它们的平均 F2 分数进行评估。F 分数通常用于信息检索,它使用精度 p 和召回率 r 来衡量准确性。精度是真阳性(tp)与所有预测阳性(tp + fp)的比率。召回率是真阳性与所有实际阳性的比率(tp + fn)。F2 分数由下式给出:
F2 评分公式,来源:星球:从太空了解亚马逊
履行
对于这个任务,我选择使用 fastai 库来实现深度学习模型,该库使用现代最佳实践来简化训练神经网络。fastai 库的主要特点之一是使用循环学习率。这是一种相对未知的设置学习率的技术(由于 fast.ai 课程的流行,这种技术可能不再适用),它提高了分类精度,同时与固定学习率值相比,需要更少的迭代。这种方法不是单调地降低学习率,而是让学习率在合理的边界值之间循环变化。fastai 的另一个好处是它使迁移学习变得异常简单:
from fastai.vision import *learn = cnn_learner(data, models.resnet50)
我的最终解决方案由五个模型组成,所有模型都在 ImageNet 上进行了预训练:resnet50、resnet101、resnet152、densenet121 和 densenet169。我分别对每个模型进行了微调,将训练数据分为 80%的训练和 20%的验证。我使用逐步调整图像大小来训练模型,这是我从杰瑞米·霍华德教授的 fast.ai 课程中学到的技术。渐进式调整大小是一种训练计算机视觉模型的方法,首先在比原始图像更小的尺寸上训练模型,然后继续将图像的尺寸增加两到三倍,直到最终在原始图像尺寸上训练。我首先在 64x64 像素图像上训练模型五个时期,只有网络的最后一层是可训练的,然后再训练五个时期,整个网络都是可训练的。我对 128x128 像素的图像做同样的处理,然后是原始的 256x256 像素的图像。最后,我在所有可用的训练数据上训练了五个以上的时期,合并了训练和验证集。我还尝试了半监督学习,使用我的最佳提交的标签在测试集上进行训练,但发现我的性能略有下降。在整个训练过程中,我使用 64 个批次,而学习率是在每五个时期之前使用 fastai 的内置函数选择的,以找到最佳学习率:
learn.lr_find()
learn.recorder.plot()
你想选择下降曲线最陡部分的学习率。这里我选了 0.01。
精炼
为了获得一个基线分数来衡量未来实验的影响,我实现了一个没有渐进调整大小的 resnet50,使用 256x256 像素的图像大小。我没有使用测试时间增强,并将阈值设置为 0.20。这款车型在比赛的私人排行榜上获得了 0.92746 的 F2 分。为了提高基线分数,我首先实现了渐进式改进。我尝试了几个不同的尺寸,并选定了 64 -> 128 -> 256,这使我的 F2 分数上升到 0.92881。在利用测试时间增加后,我的分数进一步增加到 0.92979。然后,我开始尝试给预测设定阈值,看看我是否能挤出更多的零点几个百分点。通过将阈值设置为 0.17,我可以将分数提高到 0.93024。最后,我将训练集和验证集结合起来,再训练五个时期,使单一 resnet50 模型的得分达到 0.93041。
使用所有训练数据、tta 和阈值 0.17 的 resnet50 模型的结果
结果
我对其他四个模型遵循了与上述相同的过程,通过创建五个模型的组合,我能够在私人排行榜上获得 0.93173 的 F2 分数。这个分数对于 938 支参赛队伍中的第 19 名来说已经不错了,只比第一名少了 0.00144 分。
使用所有训练数据、tta 和阈值 0.17 的五个模型集合的结果
竞赛排行榜星球:从太空了解亚马逊
反思/改进
我想尝试但没有时间/资源的一种技术是使用暗通道先验的单幅图像去霾-何等人。我相信这将是非常有益的,因为许多卫星图像包括霾和/或云,这使得模型更难对森林的底层特征进行分类。事实上,竞赛的获胜者在对他的解决方案的简要描述中提到他使用了这种技术。我实际上实现了算法来处理整个数据集,但是我的本地机器仅处理训练数据就花了大约 30 个小时,而且我没有处理测试数据。这是我未来打算做的事情。
左:原稿,中间:使用导向过滤去除霾,右:去除霾
我可以尝试的另一个策略是 k-fold 交叉验证,而不是将数据分成训练集和验证集。这样,模型可以在整个过程中看到所有的训练数据,而不是分别对验证数据进行训练。第三名完成者提到在他们的解决方案中使用 5 重交叉验证。
我还可以尝试训练更多的模型或不同的架构来试验更大的整体。竞赛的获胜者提到每个不同的标签都有一个模型,第三名完成者使用了 30 个不同的模型,经过 5 次交叉验证,产生了 150 个重量文件。
总的来说,我对自己的成绩非常满意——仅用五款产品就取得了排行榜前 2%的成绩。我希望通过实施上面列出的一些可能的改进领域,达到前 10 名,甚至最好是第一名。
你可以从我的GitHub下载复制我的结果的所有代码。
理解分析开发生命周期
将您的分析从摇篮带到坟墓。
照片来自像素上的铁木尔·萨格兰比莱克
正如我在之前的一篇文章中所讨论的,理解分析开发生命周期是至关重要的。你的分析不会永远持续下去,相反,会变得过时,需要退休。随着您收集更多更新的数据,您将需要继续维护当前的分析,同时创建新的分析。*了解你在分析生命周期的每个阶段需要做什么是至关重要的。*如下所示,我将分析生命周期视为开发的五个关键组成部分:研发、部署、测试、验证、维护和退役。因此,让我们一起来了解每个元素吧!
分析开发生命周期——作者使用 LucidChart 创建的图像
研究与开发
研究和开发包含了分析开发生命周期的前几个步骤。收到数据后,您将花时间查看它,理解它的结构,并清理它。在进行这个过程时,您需要考虑您从数据中看到了哪些分析机会,您意识到的任何业务问题,以及它们是如何重叠的。当你开发你的问题陈述时,你可以开始测试分析概念并发展你的分析。
如果您正在使用现有的分析,此过程会有所不同。对于当前分析,您需要了解需要改进的领域、您将使用的方法以及您获得的任何主题专业知识(SME ),以帮助您完成这些更新。与 SME 进行后续对话将有助于您验证您的更新是否朝着正确的方向发展。
我发现这个过程的研究和开发阶段是最有趣的,因为在这个阶段你可以对你的数据了解得最多。我每天与其他数据科学家、数据工程师和主题专家一起工作。这些人帮助创建数据集和开发数据字典,以理解数据代表什么。然后,我可以理解如何将这些数据与其他数据集结合起来构建我的分析。我想确保我看到了更大的画面,并在继续下一步之前讲述一个令人信服的故事。
部署时的测试和验证
在与 SME 确认分析看起来符合预期并且产生了有意义的可靠结果后,就该准备部署分析了。部署过程可能有所不同,但概念是相同的。在这个阶段,我已经为我的分析开发或更新了代码,并且我结合了一个更加软件工程化的方法。
软件工程师通常在 CI/CD 管道中使用单元测试和验证技术来测试和验证代码是否按预期工作。当您测试和验证您的分析时,可以从一个小得多的数据集开始。这种测试和验证是为了确保您编写的代码能够按预期运行,不会引入任何重大缺陷或错误。在将代码部署到更大的数据集之前,添加单元测试会让您对代码运行良好感到满意。
既然您已经在小范围内测试并验证了代码,那么您可以将代码部署到测试环境中,以便在大型数据集上运行它。此时,您将希望对大多数(如果不是全部)数据运行您的代码,以验证结果是否仍然符合预期。您可以与您的 SME 进行复查,以确保自分析想法的概念或更新以来没有发生任何变化。如果分析看起来像预期的那样,您可以进入维护阶段。否则,您应该回到研发阶段来调查所看到的问题。在小范围内用单元测试和在大范围内用大部分或全部数据对测试代码进行两步验证,将有助于为经过良好测试和维护的分析代码创建一个坚实的基础。
我发现这个过程很有帮助,因为它通过单元测试显示了代码设计问题,并在大规模测试时提出了分析问题。测试和验证代码的多个步骤也确保了代码按预期执行。当使用 CI/CD 进行分析开发时,我发现代码更新的问题和迭代更少。
维护
既然您已经部署了您的分析工具,现在是时候让它过渡到维护模式了。在维护模式下,您可以监控您的分析是否存在任何缺陷或与预期结果的偏差。分析维护需要考虑的一些方面包括:
- 是否引入了新数据?您是否需要通过添加新数据来更新代码?
- 是否删除了影响您分析的数据?如果你不能解决这个问题,那么你可能需要考虑退休。
- 分析输出的表现是否符合预期,还是已经开始表现不佳?如果它表现不佳,是什么改变了?
- 你的分析试图预测的问题解决了吗,现在你的分析没有被使用?如果是这样,你可能需要考虑退休了。
- 问题陈述改变了吗?如果是的话,这对你的分析有什么影响?
- 需要重新培训一个模特吗?当您用于输入的数据发生变化或引入新信息时,可能会出现重新培训。
这些只是你在维护分析生命时需要考虑的一些领域。还有更多的可能性会出现,你需要抓住它们,评估可能的结果和下一步。
退休
退休可能是这个过程中最快的阶段。当一个分析不再有用时,是时候退出代码并转移到下一个项目了。根据您的团队,退出可能与删除代码、禁用部署或关闭结果仪表板有所不同。在这一点上,您需要向用户传达分析停止的原因和时间。这种沟通是必要的,因为您应该告知用户任何可能影响他们决策过程的重大变化。如果你用新的东西代替你的分析,也让他们知道。沟通是其他人理解你的过程的关键,没有它,事情会变得一团糟。
最后的想法
您的分析生命周期可能会有所不同,包括或删除我在这里提到的不同方面。我的想法是,分析生命周期非常类似于软件开发生命周期,因为您正在开发将被迭代、维护并最终退役的代码。唯一的主要区别是如何进行验证和测试,以确认您的工作得到了预期的结果。
我有兴趣了解更多关于这个生命周期如何与您今天所做的事情相适应的信息。你能做些改变吗?
如果你想阅读更多,看看我下面的其他文章吧!
当我参加大学讲座时,最常被问到的问题是“我需要具备什么技能?”
towardsdatascience.com](/top-8-skills-for-every-data-scientist-79e6b1faf3e1) [## 停止浪费你的时间,咨询一个主题专家
在从事数据科学项目时,请一位主题专家来审查您的工作可能会有所帮助。
towardsdatascience.com](/stop-wasting-your-time-and-consult-a-subject-matter-expert-f6ee9bffd0fe) [## 创建用于熊猫分组的自定义聚合
Pandas groupby 是一个函数,您可以在数据帧上使用它来分割对象、应用函数以及组合…
towardsdatascience.com](/creating-custom-aggregations-to-use-with-pandas-groupby-e3f5ef8cb43e) [## 数据可视化的前 3 篇文章
如果您想更好地构建数据可视化,这些文章很有帮助。
towardsdatascience.com](/top-3-articles-for-data-visualization-956a08a54b04) [## 不要太骄傲而不愿寻求帮助
如果你被一个 bug 卡住了或者感到不知所措,你可以寻求你需要的帮助。
towardsdatascience.com](/dont-be-too-proud-to-ask-for-help-76f21d16f318)
理解视频分类的支柱:I3D 架构
单个图像中的信息和视频中的信息之间的显著差异之一是时间元素。这导致了深度学习模型架构的改进,以结合 3D 处理,从而额外处理时间信息。本文通过 I3D 模式总结了从图像到视频的建筑变革。
I3D
图一。基于动力学数据集的双流 I3D 训练过程。图片由作者提供,改编自 Carreira 和 Zisserman (2017) [1]。
I3D 模型是由 DeepMind 和牛津大学的研究人员在一篇名为“ Quo Vadis,动作识别?新模型和动力学数据集【1】。本文比较了以前解决视频中动作检测问题的方法,同时还介绍了一种新的体系结构,这是本文的重点。他们的方法从 2D 架构开始,膨胀所有的过滤器和池内核。通过膨胀他们,他们增加了一个额外的维度要考虑,在我们的情况下是时间。虽然 2D 模型中的过滤器是方形的 N x N ,但是通过对它们充气,过滤器就变成了立方体的NxNxN
在这篇论文中,研究人员在已经训练好的模型上从 2D 滤波器中引导 3D 滤波器。换句话说,在他们的 3D 实现中,他们使用在非常大的数据集(如 ImageNet)上训练的 2D 模型的参数。为了直观地思考这个问题,他们重复给定图像 T 次。他们实际做的是沿着时间维度重复 2D 滤波器的权重 N 次,然后通过除以 N 来重新缩放它们。为确保正确完成,2D 案例的平均和最大池层应与 ImageNet 的 3D 案例相同。
另一个要考虑的修改是池和卷积层的接收域。为了刷新,卷积神经网络中的感受域是图像的一部分,一次只能被一个过滤器看到,随着我们堆叠更多的层,它会增加。2D 卷积和池集中在图像的高度和宽度上,因此是对称的(例如,7×7 的核是对称的,而 7×3 的核是不对称的)。然而,当包括时间维度时,找到最佳感受野是重要的,这取决于帧速率和图像维度。根据研究人员在[1]中的说法,如果感受野在时间上相对于空间增长过快,它可能会合并来自不同对象的边缘,破坏早期特征检测。如果感受野生长太慢,它可能无法捕捉场景动态。总之,由于额外的时间维度,I3D 的核是不对称的。
建筑
考虑到这些,作者用下面的图表形象化了他们的架构:
图二。图片由作者提供,改编自 Carreira 和 Zisserman (2017) [1]。
从图中可以看出,网络的起点使用不对称滤波器进行最大汇集,在空间维度上汇集的同时保持时间。直到后来在网络中,他们才运行包含时间维度的卷积和池。初始模块通常在 2D 网络中使用,不在本文讨论范围之内。然而,总的来说,它是最佳局部稀疏结构的近似。它还处理不同比例的空间(在这种情况下还有时间)信息,然后汇总结果。这个模块的目的是让网络变得“更宽”而不是“更深”。1x1x1 卷积用于减少更大的 3x3x3 卷积之前的输入通道数,也使其计算成本低于替代方案。
贡献
虽然该架构的正式介绍是本文的主要贡献,但主要贡献是从动力学数据集到其他视频任务的迁移学习。动力学人体动作数据集包含人体动作的注释视频。这就是在各种与动作相关的深度学习任务中使用预训练的 I3D 网络作为特征提取网络的原因。功能通常从“混合 5c”模块中提取出来,并传递到新的架构或 I3D 的微调版本中。
结论
I3D 是视频处理中最常用的特征提取方法之一。虽然也实现了像 S3D 模型[2]这样的其他方法,但是它们是在 I3D 架构的基础上构建的,对使用的模块做了一些修改。如果你想对视频或视频中的动作进行分类,I3D 是个好地方。如果你想为你的视频相关实验从一个预先训练好的模型中获得特征,I3D 也是值得推荐的。我希望你喜欢这个总结!
参考
[1]卡雷拉,j .,&齐塞尔曼,A. (2017)。Quo vadis,动作识别?一个新的模型和动力学数据集。在IEEE 计算机视觉和模式识别会议论文集(第 6299–6308 页)。
[2]谢,s,孙,c,黄,j,涂,z .,&墨菲,K. (2018)。重新思考时空特征学习:视频分类中的速度-精度权衡。在欧洲计算机视觉会议(ECCV) (第 305–321 页)。
*本文中的图像与[1] 中的原始图像相似
理解自然语言处理中的单词包
自然语言处理是人工智能的一个重要分支,许多有趣而重要的研究正在这里进行。作为一个机器学习爱好者,了解 NLP 的子流程很重要。
在这里,我想分享一个在 NLP 中使用的术语,并附有代码示例(链接到底部的笔记本)。“包话!!!"。
NLP 中的单词包是什么?
单词包是一种用来找出文本(段落)中重要主题的方法。有哪些话题?假设你正在阅读下面的段落,
As a pet, cat is a very useful animal and helps in protecting or saving our rashan from rats. *The offspring of a cat is called as kitten*, it is a smaller and a cuter version of a cat. Cat has got four thin, short and sturdy limbs that helps it in walking, running and jumping for long distances.It’s bright eyes help it in seeing long distances and also help during the dark. Cats are found all over the world. There is no place without a cat. Sometimes a cat can be mistaken for a tiger cub, because of its extreme similarities with it.A cat’s body is completely covered with soft and beautiful fur. Cats make meaw meaw sound. God has provided cats with soft shoes or pads, which help a cat in walking without making a sound.
【文字鸣谢:【https://www.atozessays.com/animals/essay-on-cat/
作为一个人,当你读到这里的时候,你知道这一段是关于猫的。Cat 是上一段的一个重要话题。但是,
- 一台机器应该如何解决这个问题?
- 你怎么知道你的模型猫是这一段的一个重要话题?
**"The more frequent a word, the more important it might be!!!"**
这就是单词袋发挥作用的地方!!!
如何获得一个段落的单词袋?
- 首先,使用标记化创建段落的标记,标记可以是文本的任何部分,例如单词、数字、标点符号或特殊字符
- 应用必要的文本预处理步骤来过滤掉好的标记,例如小写单词、词汇化/词干化(将单词变成它们的根形式)、去除停用单词和标点符号等。
- 统计每个单词出现的次数,找出最常见的单词。
# declare your text here
paragraph = "As a pet, cat is a very useful animal and helps in protecting or saving our rashan from rats........................."# tokenize the paragraph using word_tokenize,return tokens
tokens = word_tokenize(paragraph)# change the tokens to lower case
lower_tokens = [token.lower() for token in tokens]# Retain alphabetic words: alpha_only, eliminate punctions and special characters
alpha_only = [t for t in lower_tokens if t.isalpha()]#remove all stop words
stop_words = set(stopwords.words('english'))
filtered_tokens = [token for token in alpha_only if not token in stop_words]# lemmatize the words to bring them to their root form
wordnet_lemmatizer = WordNetLemmatizer()
lemmatized_tokens = [wordnet_lemmatizer.lemmatize(token) for token in filtered_tokens]# create bag of words
bag_of_words = Counter(lemmatized_tokens)# print the top 5 most common words
print(bag_of_words.most_common(5))Output:
[('cat', 11), ('help', 5), ('walking', 2), ('long', 2), ('without', 2)]
通过查看输出,您可以简单地说,这是一篇关于猫的文章,因为它是文章中出现频率最高的单词。现在,您可以使用这袋单词作为特征来进行 NLP 的下一步。
这只是一种方法,为了简单起见,我只添加了简单的预处理步骤。但是预处理步骤将因情况而异。阅读类似的作品,针对你的情况微调预处理步骤。
你可以看看这个例子的笔记本。希望这篇文章对你有帮助!!!
使用 OpenCV 了解数字图像处理和计算机视觉的基础知识
CV 的基本概念:二值化,阈值,灰度和更多的见解。
这篇文章是关于数字图像背后的基本概念,它的处理,因此,也是 CV 的基础。最后,您可以找到一个使用 OpenCV 的 Python 的简单代码实现。
读完这篇文章后,你将能够回答以下问题:
- 计算机是如何看到图像的?
- 有哪些典型的意象类型?
- 什么是图像处理中的二值化?
- 什么是阈值处理?
- 阈值和二值化是如何应用的?
介绍
每幅图像都由像素组成,这些像素是用一种颜色填充的小方块。将所有不同的方块放在一起,然后缩小以看到所有的像素,就产生了我们所知道的图像。在下图中,可以清楚地看到小方块。它由 119 个水平像素列和 82 个垂直像素行组成。总的来说,这导致 119 x 82 = 9758 像素和 16 KB 的非常小的数据大小。
119 x 82 像素。来源:自己的图像
图像的平滑和清晰程度取决于图像的大小,因此也取决于像素的数量。放大一幅只有大约 10000 个像素的图像(如上图)会导致不清晰的结构,看起来更像俄罗斯方块,而不是平滑的线条。将此大小增加到 904 个水平像素列和 604 个垂直像素行,得到 904x604=546.016 个像素和 209 KB 的数据大小。图像现在已经更清晰了,但仍然有纹理,有点脆。
904 x 604 像素。
进一步缩小以看到由 4928 × 3264 = 16.084.992 像素组成的整个图像,会产生一个平滑且漂亮的图像。该映像现在的数据大小为 6,7 MB,即 6700 KB。
4928 x 3264 像素。
这就是我们看到的数字图像。但是对于计算机来说,它看起来怎么样呢?它得到什么,它如何处理输入?对于计算机来说,图像是形状的二维函数
它是两个连续空间变量 x 和 y 的函数,x 是像素的行值,y 是列值。为了处理它,计算机对它进行采样和量化,将输入转化为矩阵,如上图所示。图像的每一个像素都用 f(x,y)进行处理(达席尔瓦和门东萨,2005)。
先说像素
在典型的数字图像中,每个像素由一个 8 位整数组成,导致 256 种可能的状态:
颜色深度:比特和阴影。来源:自有。
对于彩色数字图像,每个像素都有三个函数
彩色数字像素由一个 1x3 矩阵组成,代表红色、绿色和蓝色三个原色通道,每个通道都是一个 8 位整数。每个像素的 256 个状态是指每个颜色通道的亮度,0 是颜色的最暗版本,255 是原色的最亮版本(Fisher 等人,a,2003)。
随后,R = 0、G = 0 和 B = 0 的向量将导致黑色像素,因为所有三个颜色通道都由最暗的阴影组成。R = 3,G = 168,B = 124 的星座将导致浅绿色像素,具有真正浅的红色值(只有 3 ),因此红色对所得像素颜色的影响很小,但是绿色和蓝色的值平衡,绿色是最强的值。这两种颜色都可以在下面的图片中看到。
使用数字色度计选择颜色以查看 RGB 值。
图像类型
基本上存在多种类型的图像,但我们将考虑四种典型类型:
- **二值图像:**仅由黑白像素组成,白色为 0,黑色为 1。这种类型通常用于图像处理,例如在光学字符识别中识别图像中的字母和文本。
- 黑色&白色图像: 黑白图像,特别是在摄影中,是典型的灰度图像。这意味着像素不仅由黑白颜色组成,而且每个像素都有 256 种不同的灰色阴影。
- 8 位彩色图像: 你遇到的大部分数码彩色图像都是 8 位彩色图像。它是最受欢迎的类型,也是上一节*中用来解释的类型,我们来谈谈像素。*如前所述,8 位导致 256 种不同的颜色深浅。
- **16 位彩色图像:**它是一种更复杂的彩色图像,没有它的小兄弟 8 位彩色图像那么受欢迎。对于一个像素的每个颜色通道,2 的 16 次方会产生 65536 种不同的色度。
*灰度调整。*在图像处理中,灰度是标准化和折衷数字彩色图像的常用技术。而彩色图像中的三维 RGB 空间导致
可能的组合,灰度图像具有明显较少的状态
由于 256 种可能状态中的每一种状态对应于不同的亮度,因此灰度调整与提高自动亮度和对比度校正程序的速度相关。在成千上万幅图像的预处理中,灰度图像由于其单通道结构而比彩色图像处理得更快。因此,彩色图像必须转换成灰度图像。对于这一步,1x3 向量必须减少到 1x1 向量。想到的最简单的方法是给每个颜色空间分配相同的权重,即 0.33。该方法是众所周知的,并且是典型的方法:
然而,三原色的波长各不相同(Choudhury,第 10 页及以后,2014 年)。这导致颜色对人类视觉的不同贡献。由于原色对人类颜色感知的这种不同贡献,比例不应该被认为是相等的,而应该适应人眼。Open CV 的变换公式是基于亮度不变的原理/BT601 (Open CV c,n.d .):
使用此公式,由三个值(RGB)组成的像素被转换为一个值(Y),即 256 种不同灰度范围(0–255)内的一种灰度。因此,这也减少了每个像素包含的信息,从而减少了图像的数据量。
以上面的绿色调为例,R=3,G=168,B=124,将其填入灰度公式,得到 Y = 114,考虑到 256 种灰度,这是一个中等范围的灰色调。
灰度输入图像:
灰度图像。
将输入图像转换为灰度图像并绘制其像素值的直方图,可以显示图像中每种灰度的出现频率。在 200 到 250 范围内具有暗灰色阴影的像素具有最高的频率,如下面直方图右侧所示。看一看图片,底部的暗像素和气泡的一些像素是直方图中这个峰的一部分。
灰度的频率分布(直方图)。
二值化图像
向二进制图像的转换称为阈值处理。阈值化背后的思想是将所有像素分割为 1 或 0。超过定义阈值的灰度图像的所有像素都是 1,而低于定义阈值的值被转换为 0。输出是仅由黑白像素组成的图像,0 表示黑色,1 表示白色。为了定义阈值,存在不同的技术。该算法在这项工作中提出了两个步骤。它结合了简单的二值阈值和 OTSU 阈值。它计算使 1 和 0 两个类的加权类内方差最小的 t 值。
OTSU 阈值法(OpenCV,f,n.d .)
然后通过(OpenCV,f,n.d .)将检索到的值用于二进制阈值处理
阈值化后,图像被分割成前景和背景。所有不等于 0 并因此为 1 的像素可以被定义为文档的内容和前景。下图的阈值处理是用 Open CV 和上面解释的两种方法完成的。
产生二值化图像的阈值处理。
感谢阅读!
请继续关注 Marius Hucker 的新文章。如果您还没有注册,您将创建一个中型帐户…
medium.com](https://medium.com/subscribe/@hucker.marius)
下面是应用所解释方法的一小段代码:
**#import the OpenCV library**
import cv2**#read your file** file=r’/Users/marius/Desktop/color.jpg’
img = cv2.imread(file)**#Grayscaling the image via OpenCV**
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)**#Thresholding the image**
gray,img_bin = cv2.threshold(gray,127,255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)**#Showing the image** cv2.imshow(‘image’,img_bin)
cv2.waitKey(0)
参考文献
Da Silva,E. A. B .,& mendon ca,G. V. (2005 年)。数字图像处理。电气工程手册,891–910。
费希尔,r .,帕金斯,s .,沃克,a .,&沃尔法特,E. (2003 年)。像素值。【https://homepages.inf.ed.ac.uk/rbf/HIPR2/value.htm
打开 CV c .(未标明)。颜色转换。
打开 CV d .(未标明)。对数组的操作。https://docs . opencv . org/2.4/modules/core/doc/operations _ on _ arrays . html
打开 CV e .(未标明)。图像阈值处理。https://docs . opencv . org/master/D7/d4d/tutorial _ py _ thresholding . html
打开 CV f .(未标明)。其他图像转换。https://docs . opencv . org/master/D7/d1b/group _ _ imgproc _ _ misc . html # gae 8 a4 a 146 D1 ca 78 c 626 a 53577199 e9 c 57
理解偏差-方差权衡,并通过示例和 python 代码将其可视化
机器学习中最重要和最基本的主题之一是偏差-方差权衡。在本文中,我们将详细介绍什么是偏差-方差权衡,它来自哪里,为什么必须考虑它,它如何影响我们的底层系统,以及可以做些什么来改进我们的 ML 模型。
上下文:它源于哪里?
ML 系统背后的总体思想是从收集的样本中建模数据集的隐藏分布。如果您从分布中抽取足够的样本,您可以得到一个相当精确的分布的重新创建,如下所示。
给定(x,y)对,估计 f。
但问题是,在现实生活中,收集的样本通常是嘈杂的。这种噪声的来源可能有很多因素,如量化、感官限制等。因此,我们得不到分布的精确输出,而是在其中加入了噪声因子。因此,现在的问题是,在给定输入 x 的情况下,估计函数 f 及其相应的噪声输出 y。
目标是有效地估计函数 f 并滤除噪声。由于您对添加到样本输出中的噪声了解不多,如果处理不当,ML 系统最终会将输入 x 映射到有噪声的输出 y(称为过拟合)。这种映射不是函数 f 的精确表示,并且对于看不见的测试数据产生很高的误差。
偏差-方差权衡告诉我们,在存在噪声的情况下,我们的基础系统(f`(x))应该有多复杂,才能相当准确地代表数据集的分布。
术语:什么是 ML 系统中的偏差和差异:
在我们的 ML 系统中,偏差和方差都是误差的来源。假设我们有一个训练数据集***【D】*,由从隐藏分布中采样的(x,y)对组成( y=f(x)+e )。我们从数据集建立模型 f*** ,使得训练标签和预测值之间的误差最小化(***error = y-f
(x))。
偏见:
偏差被定义为平均模型预测值 f`(x) 和地面真实值 f(x) 之间的误差
对从不同数据子集 D_i 预测的函数进行期望。更简单地说,你从隐藏分布中采样 n 个不同的数据集 D_i (每个数据集由多个(x,y)对组成),然后估计 n 个不同的函数 f_i .
估计函数的偏差告诉我们基础模型预测值的能力。一般来说,更简单的模型不能捕捉高维数据的复杂性,因此它们有更高的偏差。例如,您有一个从正弦曲线采样的数据集,并且您试图使用一次多项式来估计它,即通过函数 y = ax+b. 无论您采样多少个数据点(x,y),直线将永远无法捕捉正弦曲线的趋势。因此,对于正弦曲线,直线模型具有非常高的偏差。另一方面,假设您将多项式的次数增加到 3 次,即现在通过 y = ax +bx+c. 对其进行估计,该多项式将比前一个多项式的性能好得多,因此在估计正弦曲线时,3 次多项式的偏差比 1 次多项式的偏差小得多。
模型的高偏差与以下因素有关
- 拟合不足—未能捕捉到数据趋势
- 更强调概括
- 训练和测试数据集的错误率都很高
- 过于简化的模型
差异:
方差是指给定数据集的模型预测的平均可变性。
估计函数的方差告诉您该函数能够根据数据集中的变化进行多大程度的调整。方差越大,函数对变化的数据集越稳健。例如,假设您训练两个不同的多项式来拟合从正弦曲线(1 次和 3 次多项式)采样的数据。你在三个不同的数据集(D1、D2 和 D3)上训练这两个多项式。下图显示了跨多项式次数和数据集的估计函数。
可以看出,1 次多项式在三个不同的数据集之间变化不大(因此方差较低),而 3 次多项式的估计彼此相差很大(因此方差较高)。
模型的高方差与以下因素有关
- 过度拟合-结束对数据集中噪声的建模
- 更加强调尽可能接近地拟合每个数据点
- 训练数据误差小,但测试数据误差大
- 过于复杂的模型和稀疏的训练数据。
一般来说,如果你增加底层系统的复杂度,系统的偏差会减小,而方差会增大。它们两者彼此成反比。不能两个都减。这一点将是偏差-方差权衡的基础。
权衡:
ML 模型的预期测试误差可通过以下公式分解为其偏差和方差
测试误差=偏差+方差+不可约误差
这一点的完整推导可以在这里找到。不可约误差是由于数据中的噪声引起的误差,并且与模型的选择无关。
所以为了减少估计误差,你需要减少偏差和方差。你必须选择一个模型(在我们的例子中是多项式的次数),以最小化误差的方式权衡偏差和方差。在过拟合和欠拟合的情况下,测试误差都可能很高。因此,我们需要偏差和方差的最佳平衡,这样我们的模型既不会过度拟合也不会欠拟合我们的数据。
考虑前面的例子。我们必须使用多项式从噪声采样数据 D 中估计正弦曲线。我们可以从各种不同次数的多项式中选择。在理想情况下,我们可以访问足够大量的无噪声数据(噪声=0),泰勒级数展开告诉我们,如果我们不断增加多项式的次数,我们可以越来越好地逼近正弦曲线。但是在有噪声和有限数据集的情况下,增加多项式的次数将开始拟合数据中的噪声,并且在测试数据集上表现不佳。因此,我们需要找到在我们的数据集上最有效(即测试误差最小化)的多项式的最佳次数。
下图描绘了不同多项式的正弦曲线的估计值。1 次多项式过于简单,无法捕捉正弦曲线,而 11 次多项式则非常复杂,甚至可以包含噪声(因此偏离了我们试图估算的实际正弦曲线)。
正弦曲线的多项式回归
为了找到估计正弦曲线的最佳多项式,我们找到测试数据集的多项式(1、3、5、7、9 和 11 次)的偏差和方差。图表绘制如下。
可以看出,在存在噪声的情况下,7 次多项式为我们的正弦曲线提供了最佳拟合。该多项式的选择取决于
- 样本数据中噪声的数量和性质
- 训练数据量
我们假设采样的数据集没有噪声。对这个干净的数据集运行相同的实验得到了下面的图表
上图符合正弦曲线的泰勒级数展开,表明多项式的次数越高,逼近越好。完整的代码附后。
Python 代码:
正弦曲线估计问题的 python 代码可以在下面找到。模块 gen_data()中的变量 b 用于控制采样数据中的噪声量。通过对 num_data=2000 个不同的(但重叠的)数据集估计 f(x ),并对其进行平均,可以得到估计函数 f
(x)的期望值。
总结:
对于干净且足够大的数据集:
- 模型越复杂,估计误差越低,近似性越好。
- 模型越复杂,偏差越小
- 模型复杂度越大,方差越低
对于噪声数据集:
- 更高的模型复杂度并不意味着更低的估计误差
- 模型越复杂,偏差越小
- 模型复杂度越大,方差就越高
由于现实世界中的数据集几乎总是有噪声和有限的,因此我们需要找到底层模型的最佳复杂性,使我们在数据集上的误差最小。更高的复杂度并不能保证最合适。
奖金:
可以在下面的链接中找到这个主题和机器学习中许多其他重要主题的紧凑备忘单
ML 面试的视觉备忘单(www.cheatsheets.aqeel-anwar.com)
medium.com](https://medium.com/swlh/cheat-sheets-for-machine-learning-interview-topics-51c2bc2bab4f)*
如果这篇文章对你有帮助,欢迎鼓掌、分享和回复。如果你想了解更多关于机器学习和数据科学的知识,请关注我@Aqeel an war或者在LinkedIn上与我联系。
了解图形神经网络的构建模块(简介)
GRL 系列
对用于分析和学习图形数据的神经框架的直觉(带有运行代码)
T 他的帖子是关于图形神经网络 (GNNs)的一系列文章的介绍。本系列的目标是通过直觉和例子提供 GNNs 构建模块的详细描述。
在这个系列中,我还会分享运行代码,使用 Numpy,Pytorch,以及这个领域采用的最突出的库,比如深度图形库(DGL) 和 Pytorch 几何。在本系列的最后,您将能够组合这些构建块并创建一个神经架构来对图形数据执行分析和学习任务。
本系列将分析建立 GNN 的主要组件,包括(I)输入层,(ii)GNN 层,和(iii)多层感知器(MLP)预测层。
分析和分解标准 GNN 体系结构的框架基于最近发表的题为“基准图神经网络”的论文,其元数据如下:
Dwivedi,V. P .,Joshi,C. K .,Laurent,t .,Bengio,y .,& Bresson,X. (2020)。基准图神经网络。arXiv 预印本 arXiv:2003.00982 。
来源:https://arxiv.org/abs/2003.00982
这篇文章不包括图论和神经网络的基础。对于这个主题的介绍,我建议阅读下面的文章:
图形学习和几何深度学习—第 0 部分
towardsdatascience.com](/graph-theory-and-deep-learning-know-hows-6556b0e9891b)
GNN 建筑:主要组成部分概述
输入层定义图形数据的初始表示,它成为 GNN 层的输入。基本上,其思想是为图的节点和边分配一个要素表示。
GNN 层对图形结构的信息进行编码。然后,它利用这些信息来更新节点和边的初始表示。
MLP 预测层执行特定的学习任务,包括节点分类或链路预测,采用从 GNN 层输出获得的编码图表示。
这篇文章介绍了输入层和 GNN 层背后的主要原理。接下来的文章将描述不同类型的 GNN 层,解释相关的功能,并显示它们之间的主要差异。同时,我将概述传统的 MLP 预测图层,以对图表数据执行特定的任务。
这个动画 gif 描述了通过 GNN 网络传播更新的节点特性——原始图片来自 GraphSAGE 网站的主页
输入层
如前所述,输入层的目标是定义图形数据的初始表示,将要素分配给节点和边。为了简单起见,我目前只考虑节点特性。
在图中表示节点的最简单的方法是使用单键向量。这种表示通常被用来区分 NLP 任务词汇表中的不同单词。在我们的例子中,它被用来表示图的不同节点。表示每个节点的向量的长度等于节点的数量,并且对于每个向量,不同位置的元素被设置为 1,而其他元素被设置为 0。
为了阐明这种表示,下面的脚本创建了一个包含 5 个节点的图,用一个热点向量表示。
import numpy as npX = np.eye(5, 5)
n = X.shape[0]
np.random.shuffle(X)print(X)-- output:[[0\. 0\. 1\. 0\. 0.] # Node 1
[0\. 0\. 0\. 1\. 0.] # Node 2
[1\. 0\. 0\. 0\. 0.] # ..
[0\. 0\. 0\. 0\. 1.] # ..
[0\. 1\. 0\. 0\. 0.]] # Node 5
这个矩阵的每一行代表图的一个节点。为了给每个节点分配初始特征,输入层将线性变换(也称为投影)应用于编码节点表示的一键矢量。简单回顾一下线性变换,定义如下:
Y = WX + b
如 Dwivedi 等人所报道的,在独热向量的情况下,偏置值 b 不用于线性变换。因此,以下脚本执行线性变换:
# Dimension of the node features (embedding)
emb = 3# Weight matrix (initialized according to Glorot & Bengio (2010))W = np.random.uniform(-np.sqrt(1\. / emb), np.sqrt(1\. / emb), (n, emb))print(W)-- output:
[[-0.34857891 -0.5419972 0.43603217]
[ 0.26261991 0.04720523 -0.42555547]
[-0.09968833 0.3218483 0.09688095]
[-0.36646565 0.37652735 -0.45564272]
[-0.24990413 -0.50164433 -0.51217414]]
--# Linear projection
L_0 = X.dot(W)print(L_0)-- output:[[-0.09968833 0.3218483 0.09688095]
[-0.36646565 0.37652735 -0.45564272]
[-0.34857891 -0.5419972 0.43603217]
[-0.24990413 -0.50164433 -0.51217414]
[ 0.26261991 0.04720523 -0.42555547]]
投影步骤为图中的每个节点分配一个 d 维向量表示。在这个例子中,表示节点的 5 长度的独热向量被映射(或投影)成 3 长度的密集特征向量。
转述 Dwivedi 等人的话:
输入层的目标是将节点(和边)的输入要素嵌入到隐藏要素的 d 维向量中。这种新的表示是通过简单的线性变换(也称为投影)获得的。
为了阐明这一方面,可以分析以下块:
# X: One-hot vectors representing the nodes
[**[0\. 0\. 1\. 0\. 0.] ** **# Node 1 - 1 element in the *3rd* position**
[0\. 0\. 0\. 1\. 0.] **0 in the other positions**
[1\. 0\. 0\. 0\. 0.]
[0\. 0\. 0\. 0\. 1.]
[0\. 1\. 0\. 0\. 0.]] # W: Weight matrix
[[-0.34857891 -0.5419972 0.43603217]
[ 0.26261991 0.04720523 -0.42555547]
**[-0.09968833 0.3218483 0.09688095] # Emphasis to the *3rd* row**
[-0.36646565 0.37652735 -0.45564272]
[-0.24990413 -0.50164433 -0.51217414]]# L_0 (projection) = X.dot(W)
[[**-0.09968833 0.3218483 0.09688095**] # **Features of Node 1,** [-0.36646565 0.37652735 -0.45564272] **represented by the *3rd* row**
[-0.34857891 -0.5419972 0.43603217] **of the weight matrix**
[-0.24990413 -0.50164433 -0.51217414]
[ 0.26261991 0.04720523 -0.42555547]]
当前特征是随机生成的。因此,这些特征实际上并不传达关于节点的任何类型的信息。然而,节点的这些初始特征将通过两个不同的步骤来更新:
- 通过 GNN 层聚合相邻节点的特征。
- 通过 MLP 层为特定目的对神经结构进行的训练。
在这个双重过程的最后,我们将能够获得节点的嵌入表示,它将由传达特定信息的特征来表征。换句话说,节点的矢量表示将表达有意义的信息,作为人类,我们应该能够通过观察图形来识别这些信息。在最简单的情况下,相似的嵌入特征将被分配给图中相似的节点。
GNN 层
GNN 层的目标是更新从输入层获得的节点的维维表示。这个目标是通过 Dwivedi 等人定义的计算来实现的。al,一个“递归邻域扩散”,通过所谓的“消息传递框架”。该框架背后的主要思想是每个结点要素都用其相邻结点的要素进行更新。邻居特征通过边作为消息被传递到目标节点。因此,节点的新表示编码并表示图形的局部结构。为了执行这个步骤,我们需要一个描述图中节点之间关系(边)的结构。描述图中节点之间关系的邻接矩阵在这个方向上帮助了我们。
考虑下面的脚本,它初始化一个 5 节点图中的随机邻接矩阵:
# Randomly generated adjacency matrix
A = np.random.randint(2, size=(n, n))
np.fill_diagonal(A, 1) # Include the self loop# The following lines are a trivial ack to create a symmetric
# Adj matrix that defines the edges of an undirected
# graph of 5 nodes
A = (A + A.T)
A[A > 1] = 1print(A)-- output:[**[1 1 1 0 1]** # Connections to Node 1
[1 1 1 1 1]
[1 1 1 1 0]
[0 1 1 1 0]
[1 1 0 0 1]]
邻接矩阵的每一行代表由 1 元素标识的到一个节点的连接。例如,第一行表示节点 1 连接到自身、节点 2、节点 3 和节点 5。另一方面,节点 1 没有连接到节点 4,因为位置(1,4)中的值等于 0。
让我们看看当我们将邻接矩阵与应用了投影的输入图层的输出相乘时会发生什么:
# A: Adjacency matrix
[**[1 1 1 0 1]** **# Connections to Node 1**
[1 1 1 1 1]
[1 1 1 1 0]
[0 1 1 1 0]
[1 1 0 0 1]]# L_0: Output from the input layer
[**[-0.09968833 0.3218483 0.09688095] # Features of Node 1**
[-0.36646565 0.37652735 -0.45564272]
[-0.34857891 -0.5419972 0.43603217]
[-0.24990413 -0.50164433 -0.51217414]
[ 0.26261991 0.04720523 -0.42555547]]# L_1 = A.dot(L_0)
[**[-0.55211298 0.20358368 -0.34828506] # What is this?**
[-0.8020171 -0.29806065 -0.86045919]
[-1.06463701 -0.34526588 -0.43490372]
[-0.96494868 -0.66711419 -0.53178468]
[-0.20353407 0.74558089 -0.78431723]]
为了更好地理解节点表示发生了什么,考虑下面的脚本,它将节点 1 的 d 维表示求和为节点 1、节点 2、节点 3 和节点 5 的 d 维表示。
print(L_0[0, :] + L_0[1, :] + L_0[2, :] + L_0[4, :])-- output:
**[-0.55211298 0.20358368 -0.34828506]i**# L_1 = A.dot(L_0)
[**[-0.55211298 0.20358368 -0.34828506] # Features of Node 1,**
[-0.8020171 -0.29806065 -0.86045919] **obtained summing the**
[-1.06463701 -0.34526588 -0.43490372] **features of local neighbors**
[-0.96494868 -0.66711419 -0.53178468]
[-0.20353407 0.74558089 -0.78431723]]
如您所见,节点 1 的更新矢量表示对应于邻居特征的聚合(在这种情况下是求和运算)。换句话说,这种表示编码了图的局部结构。
这种表示的关键思想之一是在神经架构中堆叠 L 层,得到的目标节点表示聚集了节点的特征,其与目标节点的距离等于 L 。这种行为是“递归邻域扩散”的结果。
正如 Dwivedi 等人所强调的:
“堆叠 L GNN 层允许网络从每个节点的 L 跳邻居构建节点表示。”
不同 GNN 层之间的主要差异包括聚合类型,聚合是通过利用本地图结构来执行的。在最简单的 GNN 公式中,例如普通图卷积网络(GCNs),聚集/更新是一种各向同性操作。这意味着以同样的方式考虑邻居节点的特征。更高级的神经架构,如图形注意力网络(GAT),引入了各向异性运算,其中每个邻居节点在聚合中的贡献根据其重要性进行加权。
下一步是什么
在下一篇文章中,我将介绍 GCN 层,还将描述带标记边的图(知识图)的一个特定扩展,名为关系图卷积网络(R-GCN)。
从 GCNs 到 R-GCNs:用神经架构编码知识图的结构
towardsdatascience.com](/graph-neural-networks-for-multi-relational-data-27968a2ed143)
关于 GAT 层计算的各向异性操作的更多细节,我建议阅读下面的文章,它提供了“从 math 到 NumPy”的详细解释。
从数学到数学的循序渐进指南
towardsdatascience.com](/graph-attention-networks-under-the-hood-3bd70dc7a87)
【https://towardsdatascience.com/tagged/grl-series】:要进一步阅读关于图形表征学习的文章,可以点击以下链接关注我的系列文章。
如果你喜欢我的文章,你可以支持我使用这个链接https://medium.com/@giuseppefutia/membership成为一个中等会员。
理解商业周期
卢卡·布拉沃在 Unsplash 上的照片
也许是经济学中最强大的力量
经济学是一门不精确的科学,金融和投资更是如此(有人称之为艺术)。但如果经济学中有一样东西是你可以长期持续依赖的,那就是由于商业周期,事物的趋势意味着回归。
你可能听说过大数定律。它指出,当我们多次运行一个实验时,结果的平均值趋向于期望值(也称为平均值)。在更多处理时间序列数据的经济学和金融学中,数据也有向长期均值回归的趋势,尽管这种趋势有所减弱。例如,看看失业率在经济周期中的起伏,但会定期回到均值(橙色线):
由于商业周期,失业率回复到平均值(资料来源:圣路易斯美联储银行)
当然,这不同于大数定律,大数定律的思想是我们一遍又一遍地重复同样的实验。在经济学中,事情从来都不是一成不变的——十年前推动事情发展的许多力量如今往往已经大不相同了。因此,均值回归的幅度和速度会随着时间而变化。此外,平均值的精确值也是不确定的,可能会随着时间的推移而发生变化。
然而,驱动商业周期的最强大的力量是相当一致的,这解释了为什么尽管不断变化,许多经济变量如失业仍然倾向于可靠地意味着恢复:
- 尽管美联储可能会偏向鸽派或鹰派,这取决于谁在掌舵(严重偏向鸽派),但它的任务是利用货币政策引导经济走向充分就业(和稳定的通胀)。美联储通常更喜欢稳定的经济增长、低失业率和不断上涨的资产价格。资产价格上涨(尤其是房地产)更受欢迎的原因是它会导致信贷扩张(资产价值上涨通过更健康的银行资产负债表、债务需求和更多贷款抵押品推动贷款),这是经济增长的关键组成部分。
- 美国政府也通过财政刺激大力鼓励人们就业(幸福的公民、更高的支持率和更多的税收)。
- 过热行业或经济中的过度投资和过度就业增长最终会自我纠正——过多的供应和竞争(通常伴随着需求冲击)会压低价格和利润。而那些加入得太晚的企业往往以破产告终。
- 在失业率低于平均水平时(劳动力市场紧张),高工资增长会推高通胀。如果通胀上升到足以让美联储开始加息,那么这也会减缓经济增长(通过减缓信贷增长——信贷减少,也就是借款,意味着每个人口袋里的钱减少,消费支出减少)。通常情况下,美联储最终会多次加息,导致经济陷入衰退,失业率超过平均水平。
- 受打击的行业或经济最终会复苏。一旦过剩供应被消除(通过违约或整合),价格战就会停止,企业可以再次获得合理的投资回报。这种情况,加上扩张性货币和财政政策的影响,导致新一轮的经济扩张和失业率下降。
周期
在我们研究受周期影响的更多变量之前,让我们先描绘出它的大致形状和驱动力:
商业周期
每个周期都不同,推动过剩的行业也很少相同——上世纪 90 年代末是互联网,2005 年至 2008 年是房地产和银行。但是起作用的力量是相似的:
过热
紧张的劳动力市场以及强劲的企业利润和投资支出推动工资增长和信贷增长,这导致大量美元外流和通货膨胀。这刺激了(美联储的)利率上升。
衰退
更高的利率伤害了资产价格,降低了借贷的吸引力——净效应是支出减少,经济增长放缓,失业,最终是衰退(但不会有更多的通货膨胀)。
恢复
一旦通胀得到控制,美联储就能够专注于充分就业任务,并降低利率和/或印钞(量化宽松),以刺激信贷增长和资产价格。通常,扩张性货币政策还伴随着政府的财政刺激——降低利率本身通常不足以扭转严重的衰退。
随着许多竞争对手的离去和业务的精简,幸存下来的企业逐渐恢复盈利,并开始重新招聘。
循环又开始了…
通过经济变量观察周期
早些时候,我们看到了这个周期如何导致失业潮涨潮落——尽管将失业率视为周期的主要驱动因素可能更准确(就业通常滞后于经济增长,但对大多数主要经济变量都有重大反馈影响)。
其他的是什么?工业生产的同比变化(与 GDP 高度相关)是另一个原因。请注意,当经济增长时,蓝线如何保持在橙线之上,而在衰退时,蓝线如何突破橙线之下。还要观察当前的低值,这暗示了由于持续的疫情导致的经济萎缩。好消息是,它已经开始意味着恢复,但仍远低于我们对健康和扩张的经济的预期。
工业生产年同比变化也在恢复(资料来源:圣路易斯美联储银行)
请记住,尽管有回归均值的趋势,但数据很少会在均值上停留很长时间。所以你不要把均值当成你以后会经常观察的一个水平。
我还增加了每月汽车销售总量——汽车销售对经济周期也非常敏感,因为当经济不景气时,人们往往会推迟大额购买。注意蓝线和橙线有多接近。这意味着,尽管疫情,目前的汽车销售速度几乎回到了可以被认为是正常的水平。
每月汽车总销量(资料来源:圣路易斯美联储银行)
我最喜欢观察的一个指标是信用利差,它衡量的是贷款人承担破产风险所需的额外收益率。它是公司债券(Baa 是仍然是投资级的最低评级)和安全债券(美国国债)利率之间的差异。我喜欢它,因为它是最近发生的事情的函数(有很多公司违约吗?)以及债券市场对未来的预期(未来几年是否会有很多公司开始违约?).这是一个很好的衡量市场风险偏好的指标——低于平均收益率意味着投资者认为一切都很好,高于平均收益率意味着投资者恐慌或接近它。
看起来投资者几个月前相当恐慌,但自那以后基本上平静下来了。
公司信用利差(来源:圣路易斯美联储银行)
我们可以做的一件事是查看每个时间序列的去趋势版本——为了消除趋势,我们只需减去平均值(蓝线减去橙线)。让我们将去趋势化(和 Z 得分)变量相互叠加,看看它们是如何关联的:
各种宏观经济变量的 z 分数(来源:圣路易斯美联储银行)
我们可以看到,虽然失业率明显落后于其他两个系列,但这两个系列总体上是一致的。正如我前面提到的,失业率通常滞后于其他经济数据,因为企业往往不会轻易解雇员工,也不会轻易重新招聘员工(因为它们会在商业周期中实时摸索)。目前的疫情是一个例外,非自愿关闭迫使数千家企业关闭,数百万人几乎在一夜之间失业——所以这一次没有滞后。
如果你发现很难从前面的图中看出它们之间的相关性,下面是相关矩阵。汽车销售和工业生产高度相关(请注意,工业生产和汽车销售已经反转,使它们与失业方向一致,因此当汽车销售在图中出现高值时,实际上表示低于平均值)。失业率看起来相关性较低,因为与其他两个变量相比,它的移动具有滞后性(如果我们将失业时间序列滞后几个月,我们会看到更高的相关性)。
相关
最后,我们可以看看利差,包括投资市场对未来的预期(可能非常不准确),如何与我们之前绘制的三个宏观经济变量的平均值相关联(时间序列绘制为 Z 分数)。
z 得分的宏观因素平均值与信用利差(来源:圣路易斯联邦银行)
它们通常一起移动(相关性=0.63)。这是金融的肮脏秘密之一——因为基于市场价格(以及市场嵌入和获取所有可用信息的方式)而被认为具有前瞻性的变量实际上是非常被动的。这意味着它们与经济数据同步(甚至略微落后),几乎从不超前。真正的冲击会突如其来,通常会让投资者措手不及。
一件有趣的事情是,公司债券投资者对 2008 年和今天的看法有多么不同。尽管经济受到了类似规模的负面冲击,但信贷息差在这次疫情期间几乎没有变化,已经恢复到 10 年滚动平均水平。回到 2008 年,信贷息差最初受到的冲击要大得多,复苏也花了更长时间。
结论
宏观经济学是一个非常深奥的课题,这篇文章仅仅触及了商业周期的表面。尽管我把它命名为“理解商业周期”,但我怀疑任何没有先验知识和经验的人读了这篇文章后会对商业周期有深刻的理解。相反,更重要的是,你要认识到商业周期的存在——它是我们经济和金融生活中潮起潮落的原因。
一想到商业周期,就让我想起那句老话,“历史不会重演,但往往会押韵”。记住这一点,我们不仅应该认识到商业周期的存在,而且还应该在我们仍然处于当前阶段时,至少付出一些努力和思考来为周期的下一阶段做准备。干杯!
理解中心极限定理
照片来自pixabay.com
以及它在假设检验中的重要作用
中心极限定理(CLT)是统计学中的一个流行概念。我相信大多数(有抱负的)数据科学家都以某种形式听说过它,或者至少在高层次上听说过这个定理。当数据量很大时,该定理经常被说成是神奇地提供了任何数据分布与正态(高斯)分布之间的相互联系。
话虽如此,我观察到这个定理的真正概念对许多人来说相当不清楚——包括我。是的,该定理将任何分布与正态分布联系起来。但是什么样的联系呢?不清楚。以及实现连接的过程是怎样的?也不清楚。
对我来说更糟糕的是,我曾经认为这个定理意味着当数据量很大时,任何数据都将遵循正态分布。或者换句话说,在大数据点上不可能有偏斜(或任何非正态)分布。废话!
通过这篇文章,我将试着解释 CLT,这样你就不会陷入和我上面一样的误解。最后,我还讨论了该定理在每个数据科学家都应该理解的核心能力之一,即假设检验中的重要性。
本文的菜单如下:
- 重温定理
- 揭穿“均值的抽样分布”这一关键概念
- 演示:一个疯狂的骰子
- 假设检验中的 CLT
定理
下面是中心极限定理(CLT)的精确(数学)形式。
不要慌!因为我不假设你们每个人都是铁杆数学家,所以我提供该定理的“简单英语”版本:
给定一个足够大的样本量,一个变量的均值的抽样分布将近似为正态分布,而不管该变量在总体中的分布如何。
更好的是,均值的抽样分布的均值等于总体均值。
或者在更高的层次上,变量的值可以遵循不同的概率分布,如下所示。
图一。分布的可能形状(来源)
然而,如果样本量很大,平均值的采样分布将始终遵循钟形曲线(正态分布)形状。
平均值的抽样分布
从上面的讨论中,我想再强调一次:保证遵循/近似正态分布的不是总体中的原始变量分布;取而代之的是均值的抽样分布。
均值的抽样分布是什么?这真的是一个关键概念,帮助我理解这个定理到底是关于什么的。所以下面就通过一个循序渐进的例子来一起揭穿吧!
根据以上,均值的抽样分布就是我们从多组样本中收集的每一个均值所形成的分布。在我们的例子中,我们有 k 组样本(每组包含 n 个高度值)。
演示:一个疯狂的骰子
来自 pixabay.com的照片
现在是时候看看中央极限定理的作用了!
假设我们有一个疯狂(不平衡)的骰子,其概率质量函数如下。
我们疯狂骰子的概率质量函数
读上表的一个例子:骰子显示 5 的概率是 0.3(而不是像在平衡骰子中的 1/6 ~ 0.166)。此外,注意这个骰子分布的平均值是 4。因为
(1x 0.15)+(2x 0.05)+(3x 0.05)+(4x 0.3)+(5x 0.3)+(6x 0.15)= 4
接下来,我们来可视化一下这个骰子分布!显然,这种分布是不对称的,更不用说呈钟形了。
图二。骰子分布
现在,我们做以下事情。我们假装不知道骰子的分布。我们所知道的是我们手头有骰子,我们想通过执行下面的过程来估计骰子分布的平均值。
注意,上面选择 n = 5 只是为了说明的目的(为了计算每个样本的平均值)。它太小了,容不得 CLT 插手。下面,我们展示了当 n = {10,30,50}遵循完全相同的程序时的直方图。
直方图为 n = 10
图 3。n = 10 的直方图
突然之间,直方图(均值的采样分布)已经有些钟形了!(回想图 2,原分布严重不。)这确实是 CLT 在行动中的示范。
然而,它仍然是不对称的(见红色圆圈),意味着平均值大于 4(地面真相)。
直方图为 n = 30
图 4。n = 30 的直方图
对于 n = 30,对称性越来越好。尽管它仍然稍微向左倾斜,再次意味着平均值比 4 稍大一点。
直方图为 n = 50
图 5。n = 50 的直方图
对于 n = 50,我们有一个几乎对称的高斯分布。分布以 4 为中心。这意味着如果我们在实验中选择了 n = 50,我们就能正确地估计出我们疯狂掷骰子的平均值。
要观察的东西
随着样本量 n 的增加,我们的演示中有两件事值得注意:
- 平均值的抽样分布更接近正态(钟形)分布。
- 此外,分布形状的可变性更强(越来越集中于总体平均值)。
图 6。不同 ns 对分布的影响
假设检验中的 CLT
中心极限定理在假设检验中至关重要,至少在以下两个方面。
测试的正态假设
众所周知,许多参数检验假设数据是正态的,如 t 检验、方差分析等。多亏了 CLT,考虑到我们的样本量很大,我们更有信心使用这样的测试方法。
为了更详细地说明这一点,假设我们要比较一个连续指标的两个平均值(来自两组),每个平均值都来自 1000 个样本。我们最初想使用 t 检验来继续,但在有人质疑我们数据的正态性假设后,我们开始怀疑。
如果我们理解 CLT,这种担心是不必要的,因为我们知道,即使数据总体是非正态的,均值的抽样分布将遵循正态分布。这就是我们需要关心的,因为我们将要测试的是手段。
点估计精度
回想我们在进行上述演示后的第二个观察结果;随着 n 变大,分布形状在可变性上变紧。这意味着假设检验的样本量越大,我们就越有信心从我们的数据中得到的点假设估计精确地逼近真实的总体参数。
继续我们比较两个平均值的例子。如果样本量增加到 10,000——与原始设置中的 1000 相比,我们会对两组的两个平均估计精度更有信心。
概述
祝贺并感谢您读到这里!🎉
在这篇文章中,我们讨论了中心极限定理,它是统计学中最重要的结果之一。特别是,我们强调理解“均值的抽样分布”的关键概念,当样本量很大时,其分布(而不是其他)保证遵循正态分布。后来,我们用这个定理来估计一个假想的疯狂骰子的平均值,从而证明了这个定理的有效性。
我想用一句话来结束这个话题。CLT 只对方差有限的分布有效。这意味着对于具有无限方差的分布,如柯西分布,CLT 的结果将不成立。
总而言之,希望这篇文章对你理解中心极限定理有所帮助!
理解中心极限定理
理解统计学中最重要概念之一的实用指南
中心极限定理(简称 CLT)是统计学领域中最重要的概念之一。
在这篇文章中,我将尝试用简单而非技术性的方式来解释这个概念。
简介
让我们继续从高中的例子开始,就像这篇帖子中讨论的那样
您现在决定进一步研究这些数据。
接下来,您想要找出在美国读 10 年级的所有男性高中生的平均身高。
但是为了得到准确的数据,你需要找出 10 年级每个学生的身高,然后除以学生总数,这几乎是一个不可能的任务。
这就是中心极限定理来拯救我们的地方。
中心极限定理表明充分样本均值将近似等于总体均值。
这意味着我们可以从数据的基本样本中找到人口的平均身高。
让我们看看怎么做。
方法学
从总体人口中挑选一个样本(样本 1),大约 30 名学生,收集他们的身高,然后记录他们的样本均值,这也称为 x̄1
从另外 30 名学生中选择另一个样本(样本 2),记录平均值,x̄2(样本平均值 2)
对大约 100 个样本做这个练习,并标绘数值(x̄1,x̄2…x̄100)并找出这些值的平均值。
随着样本数量的增加,上面的图将开始看起来更像正态分布(其中数据关于平均值对称,接近平均值的数据比远离平均值的数据出现的频率更高)
样本平均值将近似等于总体平均值
此外,无论原始总体的数据分布如何(可以是正态分布/偏斜分布/均匀分布或任何其他分布),都会发生这种情况
这个概念的力量在于,我们甚至可以将我们最初的问题扩展到一个更大的环境中。
例如,找出不同国家十年级学生的平均身高。
在这里,我们将不得不包括来自每个国家的样本,并包括更多的样本。
请注意,这里的原始人口分布可能是倾斜的,一些国家的高个子学生分布相对较高。
如果我们将所有样本均值数据点绘制在图上,它看起来就像正态分布。
实际应用
现在我们知道,不管人口数据点是如何分布的,样本均值图看起来总是像正态分布。
对于正态分布,我们知道
- 均值、中值和众数相等
- 数据关于平均值是对称的
利用这些性质,我们可以从总体上对人口进行推断
这有很多实际的应用。例如,预测哪个政党将在选举中获得多数席位,计算生活在不同地区的家庭每月的债务。
理解中心极限定理
图片由 Willi Heidelbach 来自 Pixabay
在我们编码之前,快速回顾一下
今天,我想分解中心极限定理,以及它与数据科学家执行的这么多工作的关系。
直方图刷新程序
首先,任何数据科学家的核心工具都是一种非常简单的图表类型,称为直方图。虽然你肯定见过很多直方图,但我们经常忽略它的重要性。直方图的核心目的是了解给定数据集的分布。
作为复习,直方图表示在 x 轴上发现的变量的不同值在 y 轴上的出现次数。
这里有一个这样的例子,我们想了解在我们的数据集中,汽车每加仑行驶英里数的分布情况。这里我们使用的是mtcars
数据集,可以看到在我们图表的右边有一点尾巴;这个直方图就是所谓的右偏直方图。这背后的概念是,是的,有汽车的极限汽油里程,但他们是非常少的。
标准正态分布
与您刚才看到的类似,您可能已经看到的经典分布是众所周知的正态分布,也称为钟形曲线,或标准正态分布。核心思想是事件的“分布”是**对称的* *。
看看下面的剧情。我们看到的直方图与之前的相似,但这里更加对称。
中心极限定理到底是什么?
中心极限定理指出样本均值的分布应该是近似正态的。
让我们在实践中看看这个定理
考虑下面的例子。假设你在一所大学工作,你想了解一个校友离开学校第一年的收入分布。
事实上,你不可能为每个校友收集数据。或者,您将对总体进行多次采样,以获得每个“样本”的单个样本均值。
我们现在通过直方图绘制样本均值,可以看到正态分布的出现。
这里的关键要点是,即使输入变量不是正态分布,抽样分布也会接近标准正态分布。
我们来编码吧!
作为这个想法的最后一个演示,我们最初从mtcars
数据集绘制了 MPG 的分布。这里,我们为每个 mpg 样本生成一个向量,然后循环 50 个样本,每个样本取数据集中 10 个随机记录的平均值。我们再次将它们绘制成直方图,可以看到正态分布的出现。
mpg_samples <- c()for (i in 1:50) {
mpg_samples[i] = mean(sample(mtcars$mpg, 10, replace = TRUE))
}
hist(mpg_samples, col = 'purple', xlab = "MPG")
这应该作为数据科学培训的基本概念,是假设检验、实验以及其他数据科学方法和技术的基础。
我希望这对你有所帮助!
祝数据科学快乐!