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

原文:TowardsDataScience

协议:CC BY-NC-SA 4.0

变换器的地图

原文:towardsdatascience.com/the-map-of-transformers-e14952226398?source=collection_archive---------4-----------------------#2023-04-18

变换器

变换器研究的广泛概述

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

·

关注Towards Data Science 上发表 · 25 分钟阅读 · 2023 年 4 月 18 日

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

图 1. 等距地图。由 vectorpocket / Freepik 设计。

1. 介绍

近年来,深度学习的研究进展显著加快,使得跟踪所有最新发展的难度越来越大。尽管如此,有一个特定的研究方向由于其在自然语言处理、计算机视觉和音频处理等多个领域的显著成功,受到了广泛关注。这在很大程度上归功于其高度适应的架构。这个模型被称为 Transformer,它利用了该领域的一系列机制和技术(即注意力机制)。你可以在以下文章中深入了解这些构建块及其实现,并查看多个插图:

## Transformer 的应用:注意力即是全部

简要调查、插图和实现

[towardsdatascience.com

这篇文章提供了更多关于注意力机制的细节,我将在本文中讨论这些机制:

## 重新思考:注意力机制究竟是如何工作的?

大脑、数学与深度学习——研究前沿

[towardsdatascience.com

2. Transformer 的分类

到目前为止,基于原始 Transformer 已经探索了广泛的模型,这些模型大致可以分为三类:

  • 架构修改

  • 预训练方法

  • 应用

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

图 2. Transformer 变体修改。照片由作者提供。

上述每个类别包含几个子类别,我将在接下来的部分中深入探讨。图 2 展示了研究人员对 Transformer 的修改类别。

3. 注意力

自注意力在 Transformer 中发挥了基本作用,但在实践中存在两个主要缺点[1]。

  1. 复杂性:对于长序列,这个模块变成了瓶颈,因为其计算复杂度为 O(T²·D)。

  2. 结构先验:它没有处理输入的结构偏差,需要在训练数据中注入额外的机制,模型才能后续学习(例如学习输入序列的顺序信息)。

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

图 3. 注意力修改类别及示例论文。照片由作者提供。

因此,研究人员探索了各种技术来克服这些缺陷。

  1. 稀疏注意力: 该技术通过只考虑输入序列的一小部分而不是整个输入序列来降低注意力机制的计算时间和内存需求,从而产生稀疏矩阵,相较于全矩阵。

  2. 线性化注意力: 通过使用核特征映射解构注意力矩阵,这种方法尝试以反向顺序计算注意力,从而将资源需求降低到线性复杂度。

  3. 原型和内存压缩: 这种修改线试图减少查询和键-值对,以实现较小的注意力矩阵,从而减少时间和计算复杂度。

  4. 低秩自注意力: 通过显式建模自注意力矩阵的低秩特性,使用参数化或用低秩近似替代,以期提高变换器的性能。

  5. 带有先验的注意力: 利用来自其他来源的先验注意力分布,这种方法将其他注意力分布与从输入中获得的注意力分布结合起来。

  6. 修改的多头机制: 有多种方法可以修改和提高多头机制的性能,这些方法可以归类于这一研究方向。

3.1. 稀疏注意力

变换器中的标准自注意力机制要求每个标记都关注所有其他标记。然而,已经观察到在许多情况下,注意力矩阵通常非常稀疏,这意味着只有少量标记实际上彼此关注[2]。这表明,可以通过限制每个查询关注的查询-键对的数量来减少自注意力机制的计算复杂度。通过仅计算预定义模式的查询-键对的相似性分数,可以在不牺牲性能的情况下显著减少所需的计算量。

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

Eq. 1

在非规范化的注意力矩阵Â中,-∞项通常不会存储在内存中,以减少内存占用。这是为了降低实现矩阵所需的内存量,从而提高系统的效率和性能。

我们可以将注意力矩阵映射到一个二分图,其中标准注意力机制可以被认为是一个完整的二分图,每个查询从记忆中的所有节点接收信息,并利用这些信息更新其表示。这样,注意力机制允许每个查询关注记忆中的所有其他节点,并将它们的信息纳入其表示中。这使得模型能够捕捉记忆节点之间复杂的关系和依赖性。另一方面,稀疏注意力机制可以被认为是一个稀疏图。这意味着图中的并非所有节点都相互连接,这可以减少系统的计算复杂性,提高其效率和性能。通过限制节点之间的连接数量,稀疏注意力机制仍然可以捕捉重要的关系和依赖性,但计算开销较小。

稀疏注意力方法主要有两类,基于用于确定节点之间稀疏连接的指标[1]。这两类是基于位置基于内容的稀疏注意力。

3.1.1. 基于位置的稀疏注意力

在这种类型的注意力中,注意力矩阵中的连接是根据预定模式进行限制的。它们可以表示为更简单模式的组合,这对理解和分析注意力机制的行为非常有用。

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

图 4. 主要的原子稀疏注意力模式。彩色方块展示了相应的计算注意力分数。图片来源于[1]

3.1.1.1. 原子稀疏注意力: 有五种基本的原子稀疏注意力模式可以用来构建各种不同的稀疏注意力机制,这些机制在计算复杂性和性能之间有不同的权衡,如图 4 所示。

  1. 全局注意力: 全局节点可以作为信息中心,能够关注序列中的所有其他节点,反之亦然,如图 4 (a) 所示。

  2. 带状注意力(也称为滑动窗口注意力或局部注意力): 数据不同部分之间的关系和依赖性通常是局部的而非全局的。在带状注意力中,注意力矩阵是一个带状矩阵,查询仅关注两侧一定数量的邻近节点,如图 4 (b) 所示。

  3. 扩张注意力: 类似于扩张卷积神经网络(CNNs)可以在不增加计算复杂性的情况下扩大感受野,通过使用扩张窗口(扩张𝑤_d >= 1)可以实现带状注意力的类似效果,如图 4 © 所示。此外,它也可以扩展到步幅注意力,其中扩张𝑤 𝑑 被认为是一个较大的值。

  4. 随机注意力: 为了提高注意力机制捕捉非局部交互的能力,可以为每个查询随机采样一些边,如图 4(d)所示。

  5. 块级局部注意力: 输入序列被分割成几个互不交叉的查询块,每个查询块都关联一个局部内存块。每个查询块中的查询仅关注相应内存块中的键,如图 3(e)所示。

3.1.1.2. 复合稀疏注意力: 如图 5 所示,许多现有的稀疏注意力机制由上述描述的多个原子模式组成。

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

图 5. 四种不同的复合稀疏注意力模式。图片来自[1]

3.1.1.3. 扩展稀疏注意力: 还有其他类型的模式已被探索用于特定数据类型。例如,BP-Transformer [3] 使用二叉树来捕捉输入序列中全局和局部注意力的组合。令牌是叶节点,内部节点是包含多个令牌的跨度节点。图 6 展示了多种扩展稀疏注意力模式。

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

图 6. 不同的扩展稀疏注意力模式。图片来自[1]

3.1.2. 基于内容的稀疏注意力

在这种方法中,构建一个稀疏图,其中稀疏连接基于输入。它选择与给定查询具有高相似度的键。构建此图的高效方法是使用最大内积搜索(MIPS),该方法在不计算所有点积的情况下找到键与查询之间的最大点积。

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

图 7. Routing Transformer 的 2-D 注意力方案,与局部注意力和跨步注意力相比。图片来自[4]

Routing Transformer [4] 如图 7 所示,通过使用在线 k-means 聚类对键和值进行同心心向量聚类,为自注意力机制配备了稀疏路由模块。它将查询隔离,只关注同一簇内的键。Reformer [5] 使用局部敏感哈希(LSH)代替点积注意力,为每个查询选择键和值。它使查询仅关注来自 LSH 生成的同一桶中的令牌。使用 LSTM 边预测器,稀疏自适应连接(SAC) [6] 从输入序列中构建图,并通过利用自适应稀疏连接来增强任务特定的性能。

3.2. 线性化注意力

点积注意力机制的计算复杂度(softmax(QK^⊤)V)随着输入的空间时间大小(长度)的增加而呈二次增加。因此,当暴露于大输入(如视频、长序列或高分辨率图像)时,它阻碍了其使用。通过将 softmax(QK^⊤) 解开成 Q′ K′^⊤,(Q′ K′^⊤ V) 可以按相反顺序计算,结果是线性复杂度 O(𝑇)。

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

图 8. 标准自注意力和线性化自注意力的复杂度差异。图片来自 [1]。

假设 Â = exp(QK^⊤) 表示未归一化的注意力矩阵,其中 exp(.) 逐元素应用,线性化注意力是一种近似未归一化注意力矩阵 exp(QK^⊤) 的技术,其形式为 𝜙(Q) 𝜙(K)^⊤,其中 𝜙 是逐行特征映射。通过应用这种技术,我们可以执行 𝜙(Q) (𝜙(K)^⊤ V),这是未归一化注意力矩阵的线性化计算,如图 8 所示。

为了更深入地理解线性化注意力,我将探索向量形式的公式。我将检查注意力的一般形式,以获得进一步的洞见。

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

公式 2

在这个背景下,sim(·, ·) 是衡量输入向量相似性的评分函数。在标准 Transformer 中,评分函数是内积的指数形式,exp(⟨·, ·⟩)。一个适合的选择是核函数 sim(·, ·) = K(x, y) = 𝜙(x)𝜙(y)^⊤ ,这进一步揭示了线性化注意力的洞见。

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

公式 3

在这个公式中,向量的外积用 ⊗ 表示。注意力可以通过首先计算突出显示的术语来线性化,这允许自回归模型,即 Transformer 解码器像 RNN 一样运行。

公式 2 表明,通过聚合(特征映射后的)键和查询的外积,它保留了一个内存矩阵。稍后通过将内存矩阵与特征映射后的查询乘以适当的归一化来检索它。

这种方法由两个基础组件组成:

  • 特征映射 𝜙 (·): 每种注意力实现的核特征映射(例如,Linear Transformer 提出的𝜙𝑖(x) = elu(𝑥 𝑖 )+1)。

  • 聚合规则: 通过简单求和将关联 {𝜙 (k)𝑗 ⊗ v𝑗} 聚合到内存矩阵中。

3.3. 查询原型化和内存压缩

除了使用稀疏注意力或基于核的线性化注意力,还可以通过减少查询或键值对的数量来缓解注意力的复杂性,从而引入查询原型和内存压缩技术。

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

图 9. 查询原型化和内存压缩。照片来自 [1]

3.3.1. 带原型查询的注意力: 实施带原型查询的注意力涉及使用一组查询原型作为计算注意力分布的主要依据。模型采用两种不同的方法,要么将计算得到的分布复制到代表查询的位置,要么在这些位置填充离散均匀分布。该过程的计算流程如图 9(a)所示。

聚类注意力,如[7]所述,涉及将查询聚合到几个簇中,注意力分布则是针对这些簇的质心计算的。簇内所有查询都被分配给相应质心计算出的注意力分布。

Informer,如[8]所述,采用了显式查询稀疏度测量的方法,该方法源自于对查询的注意力分布与离散均匀分布之间 Kullback-Leibler 散度的近似,以选择查询原型。然后,仅对由查询稀疏度测量确定为前𝑢个的查询计算注意力分布,而其余查询则分配离散均匀分布。

3.3.2. 压缩键值内存的注意力: 这种技术通过在应用注意力之前减少键-值对的数量来降低 Transformer 中注意力机制的复杂性,如图 9(b)所示。这通过压缩键值内存来实现。压缩内存然后用于计算注意力分数。这种技术可以显著降低注意力的计算成本,同时在各种自然语言处理任务上保持良好的性能。

Liu et al. [9] 在其论文中提出了一种名为 Memory Compressed Attention (MCA) 的技术。MCA 使用跨步卷积来减少键和值的数量。MCA 与本文中也提出的局部注意力一起使用。通过将键和值的数量减少到卷积核大小的因子,MCA 能够捕获全局上下文并处理比标准 Transformer 模型更长的序列,同时保持相同的计算资源。

Set Transformer [10] 和 Luna [11] 是两个利用外部可训练的全局节点来压缩输入信息的模型。压缩表示然后作为输入的注意力的压缩内存,有效地将自注意力的二次复杂度降低到与输入序列长度线性相关的复杂度。

Linformer [12]将自注意力的计算复杂度线性降低,通过将键和值从长度为 n 线性投影到更小的长度 n_k。这种方法的缺点是预设的输入序列长度,因此不适合自回归注意力模型。

Poolingformer [13] 采用了一个两级注意力机制,将滑动窗口注意力与压缩内存注意力相结合。压缩内存注意力有助于扩大感受野。为了减少键和值的数量,探索了几种池化操作,包括最大池化和基于动态卷积的池化。

3.4. 低秩自注意力

根据各种研究者 [14, 12] 进行的实证和理论分析,自注意力矩阵 A ∈ R𝑇 ×𝑇 在许多情况下表现出低秩特性。这一观察提供了两个含义:首先,可以使用参数化显式建模低秩特性。这可能会导致开发利用这一特性以提高性能的新模型。其次,可以用低秩近似代替完整的自注意力矩阵。这种方法可以实现更高效的计算,并进一步提高基于自注意力的模型的可扩展性。

3.4.1. 低秩参数化: 当注意力矩阵的秩低于序列长度时,这表明通过设置 𝐷𝑘 > 𝑇 来过度参数化模型会导致在输入通常较短的情况下出现过拟合。因此,限制 𝐷𝑘 的维度并利用低秩特性作为归纳偏差是明智的。为此,Guo 等人 [14] 提出了将自注意力矩阵分解为一个小的 𝐷𝑘 低秩注意力模块,用于捕捉长距离的非局部交互,以及一个带状注意力模块,用于捕捉局部依赖。这种方法在输入较短且需要有效建模局部和非局部依赖的场景中可能会有所帮助。

3.4.2. 低秩近似: 也可以利用注意力矩阵的低秩特性,通过使用低秩矩阵近似来降低自注意力的复杂性。这种方法与核矩阵的低秩近似密切相关,一些现有工作受到核近似的启发。例如,Performer(如第 3.2 节所讨论的)使用了一种最初用于近似高斯核的随机特征映射,将注意力分布矩阵 A 分解为 C𝑄 GC𝐾,其中 G 是高斯核矩阵,随机特征映射近似 G。

处理注意力矩阵低秩特性的一种替代方法是使用基于 Nyström 的方法 [15, 16]。在这些方法中,从输入序列中选择一部分地标节点,使用下采样技术,如步长平均池化。选择的地标节点被用作查询和键,以近似注意力矩阵。具体而言,注意力计算包括对原始查询与选择的键的乘积进行 softmax 归一化,然后计算选择的查询与归一化结果的乘积。这可以表示为:

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

方程 4

注意,矩阵 M^-1 = (softmax(Q̃K̃T))-1 的逆可能并不总是存在,但可以通过多种方式减轻此问题。例如,CSALR [15] 向 M 添加单位矩阵以确保逆矩阵始终存在,而 Nyström-former [16] 使用 M 的 Moore-Penrose 伪逆来处理奇异情况。

3.5. 带先验的注意力

注意力机制是一种关注输入序列中特定部分的方法。它通过生成序列中向量的加权和来实现,其中权重由注意力分布决定。注意力分布可以从输入中生成,也可以来自其他来源,如先验知识。在大多数情况下,输入的注意力分布和先验注意力分布通过计算它们分数的加权和后结合,然后应用 softmax,从而使神经网络能够从输入和先验知识中学习。

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

图 10. 带先验的注意力将生成的注意力分数和先验注意力分数结合起来计算最终的注意力分数。图片来自 [1]

3.5.1. 建模局部性的先验: 为了建模某些类型数据的局部性,如文本,可以使用位置上的高斯分布作为先验注意力。这涉及到将生成的注意力分布与高斯密度相乘,并对生成的注意力分数进行归一化或添加偏置项 G,其中更高的 G 表示对特定输入的先验概率更高。

Yang 等人 [17] 提出了预测每个输入的中心位置并相应地定义高斯偏置的方法:

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

方程 5

其中 𝜎 表示高斯的标准差。高斯偏置定义为中心位置与输入位置之间的平方距离的负值,除以高斯分布的标准差。标准差可以作为超参数确定,也可以从输入中预测。

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

图 11. 使用窗口大小为 2 (D = 2) 的[17]提出的方法进行说明。图片来自 [17]。

高斯 Transformer [18] 模型假设每个输入查询 𝑞𝑖 的中心位置为 𝑖,并将生成的注意力分数的偏置项 𝐺𝑖 𝑗 定义为

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

方程 6

其中 𝑤 是一个非负标量参数,控制偏差,𝑏 是一个负标量参数,减少中心位置的权重。

3.5.2. 来源于低层模块: 在 Transformer 架构中,相邻层之间的注意力分布通常被发现是相似的。因此,使用来自低层的注意力分布作为计算高层注意力的先验是合理的。这可以通过将当前层的注意力分数与前一层注意力分数的加权和以及将前一层分数映射到要应用的先验的转换函数相结合来实现。

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

Eq. 7

其中 A(𝑙) 代表 l- 层注意力分数,而 w1 和 w2 控制之前的注意力分数和当前注意力分数的相对重要性。此外,函数 𝑔: R𝑛×𝑛 → R𝑛×𝑛 将之前的注意力分数转化为应用于当前注意力分数的先验。

论文 [19] 中提出的 Predictive Attention Transformer 建议在之前的注意力分数上使用 2D 卷积层来计算最终的注意力分数,该分数是生成的注意力分数和卷积分数的凸组合。换句话说,生成和卷积分数的权重参数分别设置为 𝛼 和 1-𝛼,而 Eq. (6) 中的函数 𝑔(·) 是一个卷积层。论文中的实验表明,无论是从头开始训练模型还是在适配预训练 BERT 模型后进行微调,都比基线模型有了改进。

论文 [20] 中提出的 Realformer 模型通过直接将之前的注意力分数添加到新生成的分数中,引入了对注意力图的残差跳跃连接。这可以视为在 Eq. (6) 中将 𝑤 1 = 𝑤 2 = 1 和 𝑔(·) 设置为恒等映射。作者在该模型上进行的预训练实验报告称,该模型在多个数据集上优于基线 BERT 模型,即使在显著降低预训练预算的情况下。

Lazyformer [21] 提出了一个创新方法,通过在相邻层之间共享注意力图来降低计算成本。这是通过将 𝑔(·) 设为恒等映射并交替切换 𝑤 1 = 0, 𝑤 2 = 1 和 𝑤 1 = 1, 𝑤 2 = 0 的设置来实现的。这种方法使得只需计算一次注意力图,并在后续层中重复使用。Lazyformer 进行的预训练实验表明,他们的模型不仅高效,而且有效,超越了基线模型,并显著降低了计算预算。

3.5.3. 作为多任务适配器的先验: 作为多任务适配器的先验方法使用可训练的注意力先验,这些先验使得跨任务的参数共享更为高效 [22]。条件自适应多任务学习(CAMTL)[23] 框架是一种多任务学习技术,它使得在任务之间高效共享预训练模型成为可能。CAMTL 使用依赖于任务编码的可训练注意力先验,作为多任务诱导知识转移的适配器。具体来说,注意力先验被表示为块对角矩阵,添加到预训练 Transformer 的上层注意力分数中:

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

Eq. 8

在其中,⊕ 表示直接和,𝐴𝑗 是具有 (𝑛/𝑚)×(𝑛/𝑚) 维度的可训练参数,𝛾𝑗 和 𝛽𝑗 是具有输入和输出维度为 R𝐷𝑧 和 (𝑛/𝑚)×(𝑛/𝑚) 的特征线性调制函数 [24]。CAMTL 框架在实现中规定了最大序列长度 𝑛𝑚𝑎𝑥。注意力先验是一个可训练矩阵,它被添加到预训练 Transformer 的上层注意力分数中。这种添加创建了一个适配器,使得多任务诱导知识转移在参数上更高效。先验被组织为块对角矩阵以提高计算效率。

3.5.4. 仅使用先验的注意力: Zhang 等人 [25] 开发了一种替代的注意力分布方法,该方法不依赖于输入之间的成对交互。他们的方法称为“平均注意力网络”,它使用离散均匀分布作为注意力分布的唯一来源。然后将这些值聚合为所有值的累积平均值。为了增强网络的表达能力,在平均注意力模块上添加了一个前馈门控层。这种方法的好处是,修改后的 Transformer 解码器可以以并行方式进行训练,并且能够像 RNN 一样解码,避免了与解码相关的 O(𝑇²) 复杂性。

类似于 Yang 等人 [17] 和 Guo 等人 [18],它们使用固定的局部窗口进行注意力分布,You 等人 [26] 将硬编码的高斯分布注意力用于注意力计算。然而,他们完全忽略了计算得到的注意力,只使用高斯分布进行注意力计算,其中均值和方差是超参数。只要在自注意力上实现,它就可以在机器翻译任务中产生接近基线模型的结果。

Synthesizer [27] 提出了一种在 Transformers 中生成注意力分数的新方法。他们用两种变体替代传统的生成注意力分数的方法:(1) 可学习的、随机初始化的注意力分数,以及 (2) 由仅对输入进行条件处理的前馈网络输出的注意力分数。他们在机器翻译和语言建模任务上的实验结果表明,这些变体的表现与标准 Transformer 模型相当。然而,这些变体为何有效尚未完全解释,仍有进一步研究的空间。

3.6. 改进的多头机制

多头注意力是一种强大的技术,因为它允许模型同时关注输入的不同部分。然而,不能保证每个注意力头都会学习到独特且互补的特征。因此,一些研究人员探索了确保每个注意力头捕捉到不同信息的方法。

3.6.1. 头部行为建模: 多头注意力是自然语言处理模型中的一个有用工具,因为它允许同时处理多个输入和特征表示[28]。然而,传统的 Transformer 模型缺乏确保不同注意力头捕捉到不同且非冗余特征的机制。此外,也没有头部之间相互作用的规定。为了解决这些局限性,近期的研究集中于引入新颖的机制来指导注意力头的行为或使它们之间能够进行交互。

为了促进不同注意力头之间的多样性,Li 等人 [29] 在损失函数中提出了额外的正则化项。这个正则化由两部分组成:前两部分旨在最大化输入子空间和输出表示之间的余弦距离,而后者通过元素级乘法鼓励多个头部关注的位置的分散。通过添加这一辅助项,模型被鼓励在不同头部之间学习到更多样的注意力模式,从而提高在各种任务上的性能。

许多研究表明,预训练的 Transformer 模型展示了某些自注意力模式,这些模式与自然语言处理并不完全契合。Kovaleva 等人 [30] 在 BERT 中识别出其中的几种模式,包括专注于特殊标记 [CLS] 和 [SEP] 的注意力头。为了改进训练,Deshpande 和 Narasimhan [31] 提出了使用辅助损失函数,该函数测量注意力分布图与预定义注意力模式之间的 Frobenius 范数。这种方法引入了约束,以鼓励更有意义的注意力模式。

在 Shen 等人[32]的论文中,提出了一种名为“Talking-head Attention”的新机制,该机制旨在鼓励模型以可学习的方式在不同的注意力头之间传递信息。该机制包括将生成的注意力分数从隐藏维度线性投影到具有 h_k 个头的新空间,在该空间中应用 softmax,然后将结果投影到另一个具有 h_v 个头的空间以进行值聚合。通过这种方式,注意力机制可以学习在不同注意力头之间动态传递信息,从而提高各种自然语言处理任务的性能。

协作多头注意力是一种在[33]中提出的机制,涉及使用共享的查询和键投影,分别记作 W𝑄和 W𝐾,以及一个混合向量 m𝑖。该混合向量用于过滤𝑖-th 头的投影参数。具体而言,注意力计算被调整以反映这一机制,从而得出修改后的方程(3)。

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

Eq. 9

其中所有头共享 W^q 和 W^k。

3.6.2. 具有限制范围的多头注意力:

标准的注意力机制通常假设全范围注意力,允许查询对所有键值对进行注意。然而,已经观察到一些注意力头更倾向于关注局部上下文,而其他注意力头则关注更广泛的上下文。因此,对特定目的施加注意力范围的约束可能是有利的:

  • 局部性:限制注意力范围可以明确施加局部约束,这在局部性是重要考虑因素的情况下尤为有益。

  • 效率:如果实施得当,这种模型可以在不增加额外内存使用或计算时间的情况下扩展到更长的序列。

限制注意力范围涉及将每个注意力分布值与掩码值相乘,然后进行重新归一化。掩码值可以由一个非递增函数确定,该函数将距离映射到[0, 1]范围内的一个值。在标准注意力中,对于所有距离分配掩码值为 1,如图 12(a)所示。

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

图 12 展示了三种不同类型的范围掩码函数,记作𝑚(𝑥)。水平轴表示距离𝑥,而垂直轴表示相应的掩码值。这一视觉表示提供了这些掩码函数展示的不同行为和模式的洞见,清晰地展示了掩码值如何随着键值对之间的距离变化。图片来源于[1]

在 Sukhbaatar 等人 [34] 的研究中,提出了一种新颖的方法,引入了一个可学习的注意力范围,如有趣的图 12(b)所示。这种创新技术利用了由可学习标量 𝑧 参数化的掩码,并结合超参数 𝑅,自适应地调节注意力范围。实验结果表明,这些自适应范围模型在字符级语言建模上优于基线模型,同时需要显著更少的 FLOPS。值得注意的是,一个有趣的观察是模型的低层通常显示出较小的学习范围,而高层则表现出较大的范围。这一有趣发现表明模型可以自主学习特征的层次组合,展示了其捕捉数据中复杂模式和结构的卓越能力。

多尺度变换器 [35] 提出了一个新的注意力范围方法,挑战了传统范式。与假设所有头部具有统一注意力范围的普通注意力不同,该创新模型引入了一个具有动态缩放的固定注意力范围。如图 12©所示,固定注意力范围作为一个可以缩放的窗口,由标记为 𝑤 的尺度值控制。

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

图 13. 多尺度多头自注意力,其中描绘了三个头部,每个头部代表不同的尺度。蓝色、绿色和红色框分别表示尺度 ω = 1、ω = 3 和 ω = 5。照片由 作者 提供。

尺度值各异,高层倾向于使用较大的尺度以获取更广泛的上下文依赖,而低层则选择较小的尺度以获得更局部的关注,如图 13 所示。多尺度变换器的实验结果显示,它在各种任务上表现出优于基线模型的性能,展示了其在语言处理上的更高效和有效的潜力。

3.6.3. 多头与精细化聚合:

普通的多头注意力机制,如 Vaswani 等人 [28] 提出的,涉及计算多个并行操作的注意力头,以生成各自的输出表示。这些表示然后被串联,并进行线性变换,如 Eq. (11) 定义,以获得最终的输出表示。通过结合 Eq. (10)、(11) 和 (12),可以观察到这种串联与投影的形式等同于对重新参数化的注意力输出进行求和。这种方法允许高效地聚合多样的注意力头输出,使模型能够捕捉输入数据中的复杂依赖关系和关系。

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

Eq. 10

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

Eq. 11

其中

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

Eq. 12

为了便于聚合过程,线性变换使用的权重矩阵 W𝑂 ∈ R𝐷𝑚 ×𝐷𝑚 被划分为𝐻个块,其中𝐻表示注意力头的数量。

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

Eq. 13

权重矩阵 W𝑂_𝑖,维度为𝐷𝑣 × 𝐷𝑚,用于每个注意力头中的线性变换,通过连接-投影公式重新参数化注意力输出,如 Eq. (14)所定义:

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

Eq. 14

一些研究人员可能会争辩说,简单的加和聚合方法可能无法充分利用多头注意力的表达能力,更复杂的聚合方案可能更为理想。

Gu 和 Feng [36] 以及 Li 等人 [37] 提出了使用最初为胶囊网络 [38] 设计的路由方法,作为进一步聚合来自不同注意力头信息的一种手段。通过将注意力头的输出转化为输入胶囊并随后经历迭代路由过程,获得输出胶囊。这些输出胶囊随后被连接作为多头注意力机制的最终输出。值得注意的是,这些工作中使用的动态路由 [38] 和 EM 路由 [39] 机制引入了额外的参数和计算开销。然而,Li 等人 [37] 实证表明,选择性地将路由机制应用于模型的较低层次能在翻译性能和计算效率之间取得最佳平衡。

3.6.4. 其他多头修改:

除了上述修改之外,还提出了几种其他方法来增强多头注意力机制的性能。Shazeer [40] 引入了多查询注意力的概念,其中键值对在所有注意力头之间共享。这减少了解码过程中的内存带宽需求,并使解码速度更快,尽管与基线相比存在轻微的质量下降。另一方面,Bhojanapalli 等人 [41] 发现注意力键的大小可能会影响它们表示任意分布的能力。为了解决这个问题,他们提出将头的大小与头的数量分开,这与传统上将头的大小设定为𝐷𝑚/ℎ的做法相反,其中𝐷𝑚是模型维度,ℎ是头的数量。

4. 总结

总结来说,变换器的分类及注意机制的各种进展显著扩展了基于变换器的模型的能力和效率。稀疏注意技术,如基于位置和基于内容的稀疏注意,以及线性化注意,解决了传统稠密注意的计算限制。查询原型和内存压缩方法引入了创新的方法来提高注意机制的效率。低秩自注意使得参数化和近似技术用于更高效的注意计算。引入先验,如局部建模、较低模块先验和多任务适配器,在提高注意机制方面表现出令人鼓舞的结果。最后,对多头机制的修改,如头行为建模、受限跨度、精细聚合及其他变体,展示了进一步提升基于变换器的模型性能的潜力。

注意机制的这些进展为未来在自然语言处理、计算机视觉和机器翻译等多个领域的研究和应用提供了令人兴奋的前景。通过利用这些创新技术,基于变换器的模型可以继续突破性能和效率的界限,为高级机器学习应用打开新的可能性。

请在下方评论区分享你的想法、问题和意见。

5. 即将到来的主题:揭示变换器旅程中的下一个章节

在未来的文章中,将更详细地讨论以下主题:

  1. 其他模块级修改: 这些涵盖了模块级的其他修改,如位置表示、层归一化和位置-wise 前馈网络(FFN),它们在基于变换器的模型的性能和效率中发挥了至关重要的作用。

  2. 架构级变体: 本节将探讨变换器的各种架构级变体,包括将变换器调整为轻量级、增强跨块连接、适应性计算时间、采用分而治之策略的变换器,以及探索替代架构设计以进一步提升变换器的能力和效率。

  3. 预训练变换器: 深入探讨预训练变换器,这些变换器近年来因其利用大规模预训练数据提高下游任务性能的能力而受到广泛关注,本节将讨论不同的预训练技术,如 BERT、GPT 和 T5。

  4. 变压器的应用: 在这一部分中将突出显示变压器在各种领域展示出卓越性能的多样化应用,包括自然语言处理、计算机视觉、语音识别和推荐系统等。将讨论变压器在各个领域中的潜力和多样性。

  5. 研究方向: 提供关于变压器研究和开发未来方向的见解,讨论变压器模型在新兴趋势、挑战和机会方面的进一步发展,展示变压器在未来几年里的令人兴奋的可能性。

通过涵盖这些主题,本文旨在全面介绍变压器的进展、修改、应用和未来发展方向,揭示这些强大模型在推动下一代机器学习和人工智能应用中的潜力。

参与 TransformerX 项目:参与方式

[## GitHub - tensorops/TransformerX: Flexible Python library providing building blocks (layers) for…

灵活的 Python 库,为可重现的 Transformer 研究提供构建块(层)(Tensorflow ✅…

github.com

我感谢那些在开发 TransformerX 库中给予启发和鼓励的人。我们一直期待您以以下形式做出贡献:

  • 贡献代码和开发新层次: 查看特定问题标记为issue_list的想法,并在我们的指南的帮助下开始实施它们。

  • 建议新功能或报告错误: 创建问题来分享你的建议或报告你遇到的任何问题。

  • 编写文档和教程资源: 帮助我们改进库的文档。

  • 在社交媒体上分享和撰写 TransformerX 相关内容: 在 Twitter 上提及我们,进行转发,或在 LinkedIn 上分享。

如果你不确定编码,不用担心,我们会在每一步都帮助你进行第一次贡献。

🌟 在 GitHub 上为 TransformerX 点星,展示你对项目的支持!你的贡献帮助我们不断改进和发展这个库。谢谢!🚀

喜欢看更多相关内容吗?

关注我的Twitter🐦,GitHub🚀(我最活跃的平台),让我们在LinkedIn💼上连接,当然,关注我的Medium 📝,并订阅我的文章。

此外,这里是我的网站

参考文献

有关参考文献的列表,请访问这个gist。这将为您提供一份全面的参考资料列表,以便进一步阅读和深入了解该主题。祝您探索愉快!

线性回归的矩阵代数

原文:towardsdatascience.com/the-matrix-algebra-of-linear-regression-6fb433f522d5?source=collection_archive---------3-----------------------#2023-05-03

查看线性回归背后的矩阵运算

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

·

关注 发布于 Towards Data Science ·11 分钟阅读·2023 年 5 月 3 日

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

图片由 Mingwei Lim 提供,来源于 Unsplash

介绍

对大多数人来说,简单线性回归是理解基于模型的估计和模型比较的常见起点。无论你是在学习入门统计学还是数据科学课程,你都可以肯定线性回归会在某个时刻出现。这是有充分理由的。

简单线性回归通过将响应变量建模为仅由单个预测变量的线性组合,自然地扩展了简单描述性统计。这种简单性不仅有助于解释模型参数,而且使得通过普通最小二乘法(OLS)进行估计更容易理解。

虽然大多数教科书介绍会提供详细的数学处理,除了更广泛的概念元素外,但在实际实现模型时,几乎从不会通过第一性原理来进行。不论你使用什么语言,几乎总会有一个便利函数来为你拟合模型。那为什么不使用呢?你不必手动进行所有那些繁琐的计算!这无疑是一个优点;不过,我坚信花一些时间熟悉模型的统计机制是成为一个有效的分析师和数据科学家的重要部分。

在之前的文章中,我提供了一个线性代数的入门,涉及了一些基本原理和操作。在这篇文章中,我们将基于这些概念,深入了解线性回归背后的矩阵操作。

矩阵形式的简单线性回归

大多数人都对标准回归公式很熟悉,它将响应变量 Y 作为单个预测变量 X 的线性组合建模:

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

线性回归方程(作者提供的图片)。

在这里,我采用了假设误差服从正态分布的惯例。从这里开始,我们将通过将元素分配给向量和矩阵,建立矩阵表示。

首先,我们将所有响应放在一个 n 维的向量中,这个向量称为 响应向量

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

响应向量(作者提供的图片)。

我在这里非常明确地包括了向量的大小 —— 实际上它表示为一个 列矩阵 —— 这样我们可以跟踪情况。然而,如果你愿意,使用小写粗体 y 也是完全合理的。

接下来,预测变量 X 被放置在一个 n × p 的矩阵中,称为设计矩阵:

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

设计矩阵(作者提供的图片)。

其中 p 表示列的数量,并对应于模型中的系数数量。请注意,第一列仅包含 1 —— 我们稍后会讨论这一点 —— 这是为了适应截距,这是一个常数。因此,设计矩阵中的列数总是比你拥有的预测变量数多一个。在上面的示例中,我们只有一个预测变量,这意味着我们需要估计一个截距和一个斜率;因此,在这种情况下 p = 2。

回归系数也被放置在一个 p × 1 的向量中,这个向量称为 参数向量

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

参数向量(作者提供的图像)。

再次说明,p 表示参数的数量,不过这里的 p 表示行数,而设计矩阵中的 p 是列维度。这个安排很重要,因为我们需要对这两个对象进行一些矩阵乘法以计算线性预测器。

不过,在我们进行这些操作之前,还有最后一件事要做——将所有的误差项放入一个 n × 1 向量中:

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

误差向量(作者提供的图像)。

有了这些,我们现在可以使用矩阵符号来表示简单线性回归模型,如下所示:

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

矩阵形式的线性回归模型(作者提供的图像)。

线性预测器

用语言表述,线性回归模型的矩阵形式是两个矩阵 Xβ 的乘积加上一个误差向量。Xβ 的乘积是一个 n × 1 的矩阵,称为线性预测器,我在这里表示为:

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

线性预测器向量(作者提供的图像)。

现在,矩阵乘法的工作方式与您预期的稍有不同。我在我的线性代数入门中讲解过这一点——如果您还没有查看,可以在这里找到——但我现在会快速介绍一下细节。

如果我们有一个 m × q 矩阵 A 和另一个 q × r 矩阵 B,那么它们的乘积是一个 m × r 矩阵 C(注意 q 维度从结果中消失了)。这种大小变化的原因是,因为 C 中第 i 行第 j 列的元素是 A 中第 i 行和 B 中第 j 列的 点积

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

点积(作者提供的图像)。

因此,由于点积在 q 维度上取和,这一维度在结果矩阵中被省略了。

对于简单线性回归情况,乘积是一个 n × p 矩阵 X 和一个 p × 1 矩阵 β 之间的乘积,因此结果是一个 n × 1 矩阵 η。根据上述内容,η 中的(i, j)元素是使用以下点积计算的:

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

扩展的线性预测器(作者提供的图像)。

这里的和是对 p 进行的,我们知道 p 是模型中的系数数量,因此 p = 2。

如果我们将点积代入线性预测器向量,并代入设计矩阵第一列的值,我们得到以下结果(因为 j = 1,我将省略那个下标,以简化符号):

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

完整的线性预测器(作者提供的图像)。

所有这些都简化为非常熟悉的形式:η中的每个元素只是我们的线性回归方程应用于每个X值!希望你能理解为什么设计矩阵中包含了全 1 列。这确保了截距被加到每个观测值上。

模型误差

与误差项相关的三个关键假设 — 或扰动 — 源于高斯-马尔科夫定理。第一个假设是误差的期望条件均值为零,这意味着误差的平均值不应依赖于任何特定的X值。这被称为零条件均值假设

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

零条件均值假设(图片由作者提供)。

与此相关的是同方差性 假设,它表明误差的方差不应受到自变量值的影响。也就是说,误差的分布应完全独立于设计矩阵中的任何信息:

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

同方差性假设(图片由作者提供)。

最后的假设是无自相关假设,它要求误差项是无关的。这意味着对一个误差项的了解不会提供关于另一个误差项的信息,因此它们不会共变:

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

无自相关假设(图片由作者提供)。

在这些假设下,误差项的协方差矩阵是一个标量矩阵,误差被认为是球形的

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

高斯-马尔科夫假设下的协方差矩阵(图片由作者提供)。

在继续之前要说明的是,虽然我采用了正态分布误差的惯例,但高斯-马尔科夫定理并不要求误差项是正态分布的,也不要求误差是独立且同分布的;只要求误差项是同方差且无相关的。这意味着一个变量可以有依赖关系,但只要这些依赖关系不是线性的 — 这是相关性所衡量的 — 那么参数估计可以安全进行。

通过普通最小二乘法进行参数估计

当将线性回归模型拟合到数据时,目标是估计包含在β中的未知模型系数。通常的做法是满足最小二乘准则,其目标是最小化线性预测器与响应之间的总平方误差。我将逐步介绍如何为简单线性回归模型实现这一点,尽管会快速通过这一部分。

以矩阵形式,误差向量或残差定义如下:

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

模型误差或残差(图片由作者提供)。

其中,β 上方的帽子表示估计系数。平方残差的和可以写成误差向量与自身的点积:

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

平方和误差(作者提供的图像)。

其中 T 表示转置运算符¹。为了推导最小二乘准则,将误差完全展开是方便的,如下所示:

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

误差向量的点积展开(作者提供的图像)。

那么,想法是找到使该值最小化的参数。为此,我们需要对向量 β 取上面的导数并将其设为零*:*

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

平方误差的第一导数(作者提供的图像)。

从中可以推导出 正规方程

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

正规方程(作者提供的图像)。

从这里,我们可以通过将正规方程的两边乘以 XX 的逆来找到我们未知的参数。我在这篇 文章 中介绍了矩阵求逆的内容,虽然如果你还没有阅读,那些内容可以帮助你理解,矩阵 A 是可逆的,如果存在一个矩阵 B 使得它们的乘积返回单位矩阵 I

对于简单的线性回归模型,XX 是一个 2 × 2 的方阵,虽然更一般来说,矩阵将是一个 p × p 的矩阵*。* 我们接着需要找到另一个 2 × 2 的矩阵,它是 XX 的乘法逆。如果这样的矩阵不存在,则方程无法解决,但如果 XX 确实是可逆的,则我们可以得到参数向量 b,如下所示:

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

线性回归的估计方程(作者提供的图像)。

在这里你可以看到为什么设计矩阵必须不是秩亏的。如果列之间确实存在线性依赖,则 XX 不能被逆,且无法找到唯一解²。如果存在 完美多重共线性,这尤其适用。

参数估计的进一步观察

进一步考虑每个矩阵中包含的元素是很有趣的。首先,让我们看一下设计矩阵 XX 的叉积:

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

设计矩阵的叉积(作者提供的图像)。

从这里我们可以看到矩阵包含了设计矩阵中每一列的乘积。但我们需要的是这个矩阵的逆。我不会详细讲解如何推导逆矩阵,但它看起来是这样的:

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

设计矩阵叉积的逆(作者提供的图像)。

最后,我们还需要设计矩阵与响应向量 Y 的叉积,结果如下:

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

设计矩阵与响应向量的叉积(作者提供的图像)。

将矩阵完全写出后,我们可以将其代入估计问题,并按如下方式进行计算:

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

参数向量的推导(作者提供的图像)。

公平地说,这一推导过程有些复杂,但最有趣的实际上是最后一行。这一切归结为一个非常方便的东西;我们可以像这样使用样本协方差和方差来估计斜率系数:

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

斜率系数的估计(作者提供的图像)。

一旦我们有了这个估计值,我们可以利用这个估计值,以及yx的均值,来推导截距的估计值:

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

截距系数的估计(作者提供的图像)。

拟合值

我们现在使用了一些线性代数来找到简单线性回归模型的最佳拟合参数。既然我们已经掌握了这些参数,下一步是查看拟合值与响应向量中包含的值的对应程度。

我们需要获得拟合值的唯一条件是设计矩阵和参数向量b。将它们相乘,拟合值的计算如下:

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

拟合值的向量(作者提供的图像)。

请注意,我们的拟合值上面放有一个帽子,以表示它们是估计值。因此,表达拟合值的另一种方式是将其作为响应向量和帽子矩阵的组合,帽子矩阵之所以得名,是因为它给Y加了一个帽子。

要查看这一点,我们将通过用参数向量的完整方程替代b来写出拟合值的方程:

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

替代的参数向量扩展版(作者提供的图像)。

基本上,所有涉及设计矩阵X的项被归并在一起,形成了帽子矩阵的定义:

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

‘帽子’矩阵(作者提供的图像)。

最后的说明

如果你能读到这里,感谢你坚持下来。确实有很多内容需要解读。然而,我希望你能看到矩阵代数的原理是如何用于构建简单线性回归模型的。现在,虽然我在整个过程中专注于简单线性回归以保持示例简洁,但这里讨论的所有内容对多重回归同样适用。唯一变化的是矩阵和向量的维度增加。

脚注

[1] 我在这里使用的符号与我在入门文章中使用的不同,但它们的意思完全相同。之所以进行更改,是为了与矩阵公式的通常描述保持一致。

[2] 严格来说,奇异矩阵是可以被逆的。广义逆扩展了逆的概念,并可以应用于更广泛的矩阵类别。广义逆在寻找最小二乘解时尤其有用,特别是在没有唯一解的情况下。

相关文章

感谢阅读!

如果你喜欢这篇文章并希望保持更新,请考虑关注我在 Medium 的账号。 这样可以确保你不会错过任何新内容。

想要无限访问所有内容,可以考虑注册Medium 订阅

你也可以在TwitterLinkedIn上关注我,或者查看我的GitHub

R 中的线性回归矩阵代数

原文:towardsdatascience.com/the-matrix-algebra-of-linear-regression-in-r-b172ee5296e3?source=collection_archive---------12-----------------------#2023-05-10

探索如何使用 R 的矩阵运算符估计回归参数

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

·

关注 发表在 Towards Data Science ·12 分钟阅读·2023 年 5 月 10 日

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

图片由 Breno Machado 提供,来源于 Unsplash

介绍

我最近写了一篇文章,探讨了线性回归背后的矩阵代数和数学运算。虽然掌握理论原则确实很重要,但没有什么能比得上实际进行这些计算。所以,在这篇后续文章中,我们将探讨如何使用 R 实现这些矩阵运算。

本文应作为我之前的文章的补充,如果你还没读过这篇文章,我鼓励你去看看;不过即使没读过,你也能继续跟进。

数据

作为我们的工作示例,我选择了 R 中 datasets 包里的 cars 数据集。这是一个简单的数据集,包含了在不同速度下的汽车停止距离。因此,这个数据集包含两个变量:speeddist。不过,这些观测数据是 1920 年代的,因此绝不是最新的数据!尽管如此,它非常适合用来建立一个简单的线性回归模型。

首先,我们快速查看一下数据:

> str( cars )
'data.frame': 50 obs. of  2 variables:
 $ speed: num  4 4 7 7 8 9 10 10 10 11 ...
 $ dist : num  2 10 4 22 16 10 18 26 34 17 ...

这里没有什么复杂的。我们共有 50 个观测值和两个数值变量。需要注意的一点是 speeddist 都是整数值。这确实引入了一些离散化,但目前这不太重要。

为了了解 distspeed 之间的关系,下面我绘制了停止距离与速度的关系图。这些变量之间存在较强的正相关,表明停止距离随着速度的增加而增加。我还使用 ggplot 的 geom_smooth 函数叠加了最佳拟合回归线。

因此,我们的目标是使用内置的 lm 函数来估计这条直线的参数。相反,我们将应用矩阵运算来获得回归系数,然后生成应当落在这条直线上的拟合值。

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

这是一个展示停止距离与速度关系的图。数据来源于 R 的汽车数据集(图片由作者提供)。

简要回顾

值得提醒自己我们实际的目标是什么。为此,我们试图将包含 n 个观测值的响应向量 Y 建模为 m 个预测变量的加权线性组合,加上一个截距项。对于这里的示例数据,我们只有一个预测变量 speed,因此我们可以设定 m = 1。

预测变量和截距项共同形成一个 n × p 设计矩阵,其中 p = m + 1 反映了模型中需要从数据中估计的未知回归系数的数量。估计需要找到以下正规方程的解:

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

正规方程(图片由作者提供)。

重新排列方程以求解未知系数,我们得到以下解:

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

估计方程(图片由作者提供)。

其中 b 是一个 p 维向量,包含最佳拟合的回归系数。

在解决这个问题时,我将把估计方程分解成处理不同操作的部分,然后再将它们合并以估计模型参数。实际上,我们需要做三个操作,每个操作返回一个我们在某个时候需要使用的矩阵。

R 中的矩阵运算

在深入研究之前,我将快速回顾一下我们将要使用的矩阵运算。这个例子中只有 个重要的操作。第一个是 矩阵乘法。如果你还没有接触过这个,R 中的矩阵乘法是使用 %*% 运算符来执行的。第二个操作涉及求 矩阵的逆,在 R 中使用 solve 函数来完成(不,我们不会手动完成这部分!)。最后一个操作是 t,这是 转置 操作符。

设置

首先,我们需要定义一个 响应向量 并创建 设计矩阵。对于我们的示例,我们将距离建模为速度的函数,因此 dist 是我们的 响应变量。让我们为这些值分配一个名为 y_vec 的向量:

# Assign dependent variable to the response vector
y_vec <- cars$dist

请注意,在这里使用 $ 访问 cars 数据框中的 dist 列。我发现这种方法并不总是方便或整洁,因此你会看到我很快转而使用 with 进行一些计算。

接下来,我们需要使用 model.matrix 函数将 speed 分配给设计矩阵。在这里,我创建了一个名为 x_mat 的变量:

# Create a design matrix with the single independent variable
x_mat <- model.matrix( dist ~ speed, data = cars )

请注意,对 model.matrix 的调用与 lm 函数调用非常相似。显然,这样做有一个很好的理由,但在这里公式只是让 model.matrix 知道 speed 是一个预测变量。让我们快速看一下它产生了什么:

> head(x_mat)
  (Intercept) speed
1           1     4
2           1     4
3           1     7
4           1     7
5           1     8
6           1     9

我们可以看到我们有 列:一个是我们的 speed 变量,另一个只包含 1。回顾一下,设计矩阵包括一个额外的列以容纳截距项。

现在,我们已经将 y_vecx_mat 加载到我们的工作空间中,我们可以继续进行矩阵运算。

步骤 1

如果我们观察估计方程的右手边,第一项是设计矩阵的逆与其自身的乘积。在步骤 2 中,我们将处理逆,因此我们首先需要计算 XX

对于我们的简单线性回归模型,XX 将是一个 2 × 2 的方阵。出于实际目的,我将简单地将其表示为矩阵 A。使用矩阵乘法 %*% 和转置 t 运算符来计算这个矩阵,我将将输出赋值给一个叫做 A 的对象:

# Compute cross-product of the design matrix
A  <- t( x_mat ) %*% x_mat

现在,在我之前的帖子中,我们通过矩阵运算了解了这个矩阵中包含的元素的一些信息。我不会在这里重新讨论具体细节,只是将结果如下记录:

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

设计矩阵的交叉乘积(作者提供的图片)。

我们可以看到 A 中的每个元素都很容易解释,确实也容易计算。注意 a₁₁ 只是观察总数 n,对于 cars 数据集来说是 50。次对角线上的元素 a₁₂a₂₁ 只是 speed 的总和,而 a₂₂speed 的平方和。

我们可以做一些快速检查,以验证我们的对象 A 确实包含这些值。让我们首先打印 A 来看看我们得到了什么:

> A
            (Intercept) speed
(Intercept)          50   770
speed               770 13228

A[1,1] 的值与 cars 中的总观察数匹配,因此我们有了一个良好的开端。接下来,我们可以通过简单地对 speed: 进行求和来检查 A[1,2]A[2,1] 的值。

> sum( cars$speed )
[1] 770

另一个匹配——一切看起来都很好!最后,我们可以通过计算 speed 的平方并对这些值进行求和来检查 A[2,2] 的值。

> sum( cars$speed ^ 2 )
[1] 13228

这也是正确的!

第 2 步

下一步是找到矩阵 XᵀX。在 R 中,我们使用 solve 函数对 A 执行此操作。让我们先执行这个操作并将输出分配给一个名为 A_inv 的对象:

# Inverting the matrix A
A_inv <- solve( A )

现在,在查看 A_inv 之前,让我们先检查 XᵀX 的逆矩阵的解:

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

设计矩阵交叉乘积的逆矩阵(图片由作者提供)。

如果现在忽略第一个项,那么我们看到的是原矩阵 A 中的一些元素已经被交换,而其他元素稍微发生了变化。具体来说,元素 a₁₂a₂₁ 的符号被反转,现在反映了 speed总和。此外,原矩阵中 a₁₁a₂₂ 的值交换了位置,因此现在 a₂₂ 是观察总数,而 a₁₁speed 的平方和。

让我们编译一个包含这些调整后元素的矩阵,并将其分配给一个名为 A_rev 的对象,然后检查一切是否正常:

# Shifting the elements in A
n_obs <- nrow( cars )
A_rev <- with(cars, matrix( c(sum( speed ^ 2), -sum( speed ), -sum( speed ), n_obs), nrow = 2))
> A_rev
      [,1] [,2]
[1,] 13228 -770
[2,]  -770   50

一切看起来都很好!我们现在可以将 A_rev 乘以第一个项,即一个标量常数,它等于 n 的倒数乘以 speed 的平方偏差和。让我们通过创建一个名为 c 的变量来快速计算常数项:

# Computing the scalar constant for matrix inversion
c <- (n_obs * with( cars, sum( (speed - mean(speed)) ^ 2) )) ^ -1

我不会打印出来,因为这是一个极小的值。现在剩下的就是将 cA_rev 相乘,看看我们得到什么:

# Computation of the matrix inverse
> c * A_rev
            [,1]         [,2]
[1,]  0.19310949 -0.011240876
[2,] -0.01124088  0.000729927

现在让我们将这些值与使用 solve 得到的解进行比较,通过将 A_inv 打印到控制台:

# Print output from solve() function
> A_inv
            (Intercept)        speed
(Intercept)  0.19310949 -0.011240876
speed       -0.01124088  0.000729927

太棒了——A_inv 中的每个元素都与 A_rev 中的对应元素匹配。

在进入下一步之前,我们可以做一个额外的检查。如果出于某种原因我们怀疑 solve 的输出有误,我们可以依赖于以下事实:任何 n × n 的方阵 A 被认为是可逆的,当且仅当存在另一个方阵 n × n 的矩阵 B,使其结果为以下等式:

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

矩阵可逆性的条件(图片由作者提供)。

这意味着,如果A_inv确实是A的乘法逆矩阵,那么如果我们将AA_inv相乘,我们应该得到单位矩阵

> round( A %*% A_inv )
            (Intercept) speed
(Intercept)           1     0
speed                 0     1

看起来solve函数在做合理的事情。

在继续之前,有一点需要说明:这些对矩阵输出的检查对于任何实际目的并不必要。相反,我希望通过包含这些小测试进一步增强你对这些概念的理解,实际上将数学应用到实践中。

第三步

现在我们已经处理了XᵀX的逆矩阵,我们可以将注意力转向估计方程中的最后一项:XᵀY。这个操作涉及将设计矩阵响应向量相乘。鉴于我们处理的数据,这个计算将产生一个p × 1向量,我们将其简单地表示为B。同样,我们将应用矩阵乘法运算符,并将输出赋值给一个变量,这次我们称这个变量为B:

# Matrix multiplying the design matrix and response vector
B <- t( x_mat ) %*% y_vec

如上所述,让我们考虑一下这个操作的预期输出是什么:

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

设计矩阵与响应向量的叉乘(图片作者提供)。

再次,我们有一些相当容易直观理解的元素。其中一个是响应变量dist的总和,另一个是speeddist的乘积总和。让我们快速计算这些值,看看它们是否与已存储在B:中的值匹配:

# Compute vector and compare with B
> with( cars, matrix( c( sum( dist ), sum( speed * dist) ) , ncol = 1 ))
      [,1]
[1,]  2149
[2,] 38482
>
> B
             [,1]
(Intercept)  2149
speed       38482

我们匹配了!

参数估计

好的。我们现在拥有了估计模型系数所需的一切。实际上,我们只需要A_invB,然后只需将它们相乘即可:

# Estimate the parameter values using solution to normal equation
b_vec <- A_inv %*% B

让我们将其打印到控制台,看看我们得到什么:

> b_vec
                  [,1]
(Intercept) -17.579095
speed         3.932409

快速查看斜率参数,我们得到了一个正值。这是一个好兆头,因为之前观察到的正相关,且希望这意味着我们在正确的轨道上。现在让我们看看这些估计值与使用lm函数返回的系数相比如何:

> coef( lm( dist ~ speed, data = cars ) )
(Intercept)       speed 
 -17.579095    3.932409 

一致的!

我想指出最后一件事。我在之前的帖子中展示了,如果你对估计方程做一些代数运算,你会得到一个非常方便的解。也就是说,斜率参数等于:

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

斜率参数(图片作者提供)。

并且截距参数等于:

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

截距参数(图片作者提供)。

这两者计算起来非常直接,可以在 R 中如下进行:

# The slope parameter
b_1 <- with(cars, cov(speed, dist) / var(speed) )

# The intercept parameter
b_0 <- with(cars, mean(dist) - mean(speed) * b_1 )

将这些对象打印到控制台显示,我们得到相同的参数值:

> c( "intercept" = b_0, "slope" = b_1 )
 intercept      slope 
-17.579095   3.932409

解释系数

看我们的估计值,我们可以看到有一个负的截距项,这并不太合理。这里的截距是distspeed设为零时的值,这意味着当车辆的速度为零时——也就是说,静止不动——它的制动距离。我不会在这里解决这个问题,所以现在我们就这样接受它(尽管这并不合理)。

另一方面,斜率参数肯定更有用。这表明每增加一个单位的速度(以每小时英里为单位),制动距离增加接近 4 英尺。因此,如果车辆的速度从 10 英里每小时增加到 11 英里每小时,则制动距离从 21.7 英尺跳跃到 25.7 英尺。然而,如果汽车的速度从 60 英里每小时增加到 61 英里每小时,制动距离的增加也应该是相同的,这可能不太合理。

计算拟合值

我们需要做的最后一件事是计算拟合值。为此,我们只需取出b_vec中的参数估计值,并将其与设计矩阵相乘:

# Compute the fitted values
y_hat <- x_mat %*% b_vec

# Compute the residuals
e_vec <- y_hat - y_vec

我在上面的代码中也计算了误差向量,但这仅仅是为了向你展示如何计算。我们不会在这里处理这些值。

我们能做的最后一件事是将我们之前生成的图上的拟合值进行叠加。如果一切顺利,我们应该能看到拟合值很好地沿回归线分布:

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

在之前生成的图上叠加拟合值(图片作者提供)。

确实如此。

总结

这里的重点主要放在了参数估计上,因此有很多内容我没有涉及。例如,模型诊断、计算参数估计的标准误差以及像决定系数这样的模型拟合指标。由于这篇文章旨在作为我早期文章的补充,我希望避免在这里引入新概念,但我会在另一时间讨论这些概念。尽管如此,我希望这篇文章在你进行线性代数学习的过程中能有所帮助。如果你想查看本文使用的代码,可以在我的Git页面找到。

相关文章

感谢阅读!

如果你喜欢这篇文章并希望保持更新,请考虑关注我在 Medium 上的账号。这将确保你不会错过任何新内容。

要获取对所有内容的无限访问权限,请考虑订阅 Medium

你还可以在 TwitterLinkedIn 上关注我,或者查看我的 GitHub,如果你更喜欢这样的话。

从物理学看 logistic 分类的意义

原文:towardsdatascience.com/the-meaning-behind-logistic-classification-from-physics-291774fda579

在分类问题中,我们为什么使用 logisticsoftmax 函数?热物理学也许有答案。

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

·发表于 Towards Data Science ·阅读时间 9 分钟·2023 年 1 月 24 日

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

Logistic 回归无处不在,但它为什么有效的直觉是什么?(图片由作者提供)

Logistic 回归也许是最受欢迎和最知名的机器学习模型。它解决了二分类问题——预测数据点是否属于某个类别。

关键成分是 logistic 函数,其中一个输入被转换为概率,形式如下:

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

但是为什么指数函数会出现?它背后的直觉是什么,除了将一个实数转换为概率之外?

结果发现,热物理学有答案。但在深入物理学的见解之前,让我们首先了解数学部分。

数学难题

在处理 logistic 函数的“为什么”之前,让我们首先理解它的属性。

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

该是让数学见鬼去吧的时候了!(图片由 Michal Matlon 提供,来源于 Unsplash

理解 logistic 函数的一种更广泛的形式是有帮助的——这种形式适用于多个类别——这样 logistic 函数就成为了一个特殊的两类示例。

这可以通过引入多个额外变量 zᵢ 来完成,每个类别一个。然后我们得到 softmax 函数,其中每个类别 i 被分配一个概率:

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

对于线性模型,zᵢ 通常是特征的线性和。这个函数在超出线性模型的情况下还有很多额外的用途:

  • 作为神经网络中的最终分类层

  • 作为变压器中的注意力权重

  • 作为强化学习中选择行动的采样层

但为什么我们选择这种函数形式来参数化概率?常见的解释是它仅仅是一个转换工具。事实上,只要其中没有一个概率为零,任何概率集合都可以写成这种形式。从数学上讲,我们可以通过简单地取对数来求解 zᵢ

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

但这就是 softmax 作为转换工具的唯一特殊属性吗?其实不是,因为将数字转换为概率的选择是无穷无尽的。实际上,我们可以考虑其他形式的函数:

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

为了产生一个合理的优化概率函数,我们需要对 f 满足以下标准:

  • 始终为正,始终递增,范围从 0 到 ∞,并且可微分

因此,exp(z) 只是无数选择中的一种,下面可以看到:

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

exp(z) 的替代方案也可以合理地将数字转换为概率(图像来源:作者)

那么 exp(z) 是否只是海量可能性中的一个约定?exp(z) 是否应该更可取?虽然我们可以通过模型性能简单地证明这个选择,但我们应尽可能追求理解。在这种情况下,存在理论动机,它来自于热物理学。

一个热物理学链接

事实证明,这些概率在热物理学中无处不在,它们被称为 玻尔兹曼分布,它描述了一个粒子(或更广泛地说,一个系统)处于特定能量状态的概率:

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

其中 Eᵢ 表示状态的能量,T 表示温度。当温度非零时,可以将能量测量为温度的倍数,以便将 T 方便地设置为 1。

尽管玻尔兹曼分布有点令人困惑,因为它们建模的系统是由精确和确定性的方程支配的,那么概率和统计学是如何融入其中的(忽略量子物理学)?

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

热物理学利用概率来管理我们在复杂世界中的无知(照片来源:Rainer GelhotUnsplash

关键在于复杂性。虽然我们有描述系统细节的方程,它们往往非常复杂。此外,这些方程常常表现出混沌行为,导致高度不可预测性(蝴蝶效应)。因此,实际上,这些详细的确定性方程并不是很有用。

那么我们如何理解这些复杂系统呢?幸运的是,在现实生活中,我们很少需要了解系统的微观细节,因为我们无论如何都无法测量它们。通常,我们只需考虑宏观和涌现量(如温度、能量或熵)。这就是概率理论的作用——它是微观与宏观之间的桥梁:

  • 微观细节使用概率分布来建模

  • 宏观量被建模为这些分布的各种平均值

以一个类比来说,假设我们想研究某些无理数的所有数字,比如√2、πe

  • √2 = 1.41421356237309504880…

  • π = 3.14159265358979323846…

  • e = 2.71828182845904523536…

任务似乎很艰巨,因为每个数字来自不同的数学概念。要获得精确的数字,需要特定的数值方法来计算。然而,如果我们简单地观察这些数字的宏观行为,我们会发现每个数字大约出现 10%的时间。关键在于,这些数字像许多动态系统一样,倾向于无偏见地探索所有可能性。从更技术的角度来说,

混沌系统倾向于最大化所有可能性,换句话说,就是熵。

这和我们的玻尔兹曼分布有什么关系呢?数学上,玻尔兹曼分布是一个最大熵分布,在约束条件下,这些统计数据符合一个关键的物理法则——能量守恒。换句话说,玻尔兹曼分布是以下方程的解:

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

所以,exp(−E)的具体形式来源于能量守恒。

直观地说,我们可以把能量看作一种预算。混沌系统尝试探索所有可能性(以最大化熵)。如果某个类别需要的能量很高,它将较少探索该类别,从而有更多机会探索其他类别。然而,概率不会降为零,因为系统仍然希望探索这个能量低效的类别。指数形式是效率和探索之间的妥协结果。

回到数据科学和分类问题,我们的数据不是动态系统的一部分,也没有能量守恒,所以这些物理学见解如何有用呢?

类别的能量

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

能量是所有互动的基本单位,但它在分类问题中有用吗?(图片来源:Fré SonneveldUnsplash

关键在于,在数据科学中,我们不一定对数据是如何得来的感兴趣——这是一个几乎不可能完成的任务。相反,我们正在尝试构建一个可以模仿数据中相关行为的系统。从这个角度来看,模型成为一个由数据以某种可取方式塑造的动态系统(这一点在我的文章中探讨过)。

就像在热物理学中,玻尔兹曼分布在捕捉粗略的微观细节方面很有效,同时忠实地再现宏观物理量(温度、压力等)。因此,至少可以认为它可能将这种超能力赋予数据科学。

确实,与其在我们的数据中寻找某种能量守恒定律,我们不如在我们的分类模型中强制能量守恒的概念。这样,与热物理学中的玻尔兹曼分布类似:

模型中的 softmax 函数假设类别的最大熵猜测,前提是对这些猜测存在某种保守预算。

最大熵可以被视为一种最大似然估计(参见我的关于熵的文章)。剩下的问题是,为什么创建一个人为固定的能量预算是合理的?以下是一些原因:

  1. 中心极限定理:能量通常是特征的线性和,因此它们有明确的均值。所以,强制这些能量在类别间的平均值保持恒定并不是一个很大的跳跃。

  2. 正则化:这迫使概率的极值受到限制,因为概率为 1 或 0 将要求一些能量为无限大。

  3. 方差减少:通过施加合理的约束,我们在模型中引入偏差的同时减少方差(偏差/方差权衡)。

在深度神经网络中使用 softmax 时,点 1 和 3 尤其显著。由于网络层通常已经有某种规范化,因此强制固定能量以确保下游良好的统计行为更加有意义。

那么,这些见解如何帮助我们理解我们的模型呢?我们可以用它们来解释有关使用 softmax 的模型的轶事事实(即逻辑回归):

  1. 不平衡的问题:这是因为 softmax 假设最大熵。它故意试图让模型在没有偏见的情况下探索所有可能的类别。

  2. 大量类别的问题:softmax 尝试分配所有可能的类别,即使是那些不可能的类别(例如,将猫分配为车辆)。对于类别被干净地分开的数据,聚类、最近邻、支持向量机随机森林模型可能表现更好。

除了模型结构之外,我们的热物理类比还帮助我们理解训练范式,这也是我们接下来要讨论的内容。

施加训练压力

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

Boltzmann 分布允许我们计算类似压力的东西,在分类中有什么类比?(照片由NOAA提供,来源于Unsplash

Boltzmann 分布的实用性不仅仅在于对系统状态进行分类:它使我们能够计算其他有用的突现量——例如压力。这个压力可以是我们所经历的物理压力,也可以是更抽象的热力学力,如磁场和化学势。

例如,压力的方程是通过体积变化引起的 Boltzmann 因子的变化来定义的:

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

更一般地说,热力学压力被定义为我们统计分布中相对于某个变量的变化。

回到数据科学中,分类中的一些量类似于“压力”是什么呢?一个相关的量是交叉熵,这是训练分类模型时通常要最小化的损失函数。交叉熵通常通过采样来估计:

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

其中 l 表示特定数据点所在的正确类别。为了优化它,我们可以进行梯度下降:计算导数并更新,直到导数为零。

使用物理类比,我们可以将导数/梯度视为一种热力学压力!

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

那么对于模型训练来说,这意味着我们在对系统(我们的模型)施加压力,直到它达到平衡。当这种内部“模型压力”达到零时,模型就被训练完成——某种热平衡。

虽然这种类比并不是 100% 精确,但它给了我们关于分类模型如何工作的直观认识(更具体地说,利用 softmax 并通过诸如交叉熵的东西进行优化的模型)。所以我们可以得出结论:

分类模型是模拟热力学系统的模型,它们被驱动到平衡状态,以模拟我们数据中的类别。

这一观点或许可以解释为什么简单的逻辑回归模型是有效的,即使在现实生活中,关于线性模型的假设通常会被违反。

结论

希望我已经向你展示了一些简单逻辑回归与热力学之间的有趣联系。

数据科学是一个非常广泛的学科。像热力学一样,我们可以将数据科学视为一种高级的理解宏观世界的方式,同时妥善处理我们可能不知晓的微观细节。或许并不奇怪,数据科学中的许多概念和数学工具可以与物理学联系起来,甚至可以追溯到物理学,因为它们都有着建模我们世界的共同目标。

如果你喜欢这篇文章,请留下评论。如果你希望看到其他抽象概念被解密并得到正确解释,也请告诉我。祝阅读愉快👋。

如果你喜欢我的文章,你可能对我的其他见解也感兴趣:

## 熵的测量是什么?一个直观的解释

熵可以被认为是看到数据中某些模式的概率。以下是它是如何工作的。

towardsdatascience.com ## 物理学家的机器学习视角:机器学习的热力学

自然界中的复杂系统可以通过热力学成功研究。那么,机器学习呢?

towardsdatascience.com [## 熵不是混乱:物理学家的视角

熵通常被视为混乱的同义词。但它真正是什么呢?在这篇文章中,我们探讨了熵如何更…

medium.com](https://medium.com/swlh/entropy-is-not-disorder-a-physicists-perspective-c0dccfea67f1?source=post_page-----291774fda579--------------------------------) [## 为什么我们不生活在模拟中

将现实描述为一种模拟严重低估了我们世界的复杂性。以下是为什么这种模拟…

medium.com](https://medium.com/physicist-musings/why-we-dont-live-in-a-simulation-a-physicist-s-perspective-1811d65f502d?source=post_page-----291774fda579--------------------------------)

数据素养的威力

原文:towardsdatascience.com/the-might-of-data-literacy-3d91fcc5f46b

这是否是成功使用数据和分析的关键?

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

·发布于 Towards Data Science ·阅读时间 8 分钟·2023 年 8 月 23 日

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

图片由 Markus Spiske 提供,来源于 Unsplash

数据在当今世界是业务成功的关键驱动力。 然而,许多公司仍然难以充分利用其潜力。在我最近的一篇文章中,我深入探讨了多个原因 [1]。例如‘数据沼泽’问题。这是组织理想中希望避免的数据基础设施场景。但是,如果这如此令人不快,为什么无数公司会陷入其中?

你怎么能判断自己不再拥有数据湖,而是陷入泥潭?你可以问三个问题:

1. 结构: 获取所需数据的路径是否简单:是/否

2. 直观性: 是否容易找到那条路径:是/否

3. 一致性: 不同数据类型的路径是否看起来相同:是/否 [2]。

如果所有前面的问题的答案都是‘不’,那么你可以说:

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

图片由 Dmitrii Ko 提供,来源于 Unsplash

好的,所以我们已经识别出架构中的问题。我会咨询我的数据分析团队来解决这个问题。

等一下,这不是正确的方法!

问题不仅仅是数据架构功能失调。真正的问题在于无法从数据中提取价值。技术层面只是跟随其后。当数据未被使用时,它实际上没有价值。数据的价值的准确衡量标准在于从数据驱动的决策中产生的营业额或利润 [3]。

问题是否在于缺乏明显的数据战略?可能是。然而,虽然强健的数据战略至关重要,但如果公司的数据文化薄弱,它也无法发挥作用。员工必须在日常工作中采纳数据的使用。他们必须具备数据素养,以充分利用数据驱动的机会。

什么是数据素养?

数据素养包括读取、理解、分析和传达数据。培养数据素养对采纳它的个人和优先考虑它的企业都带来了好处。 在个人方面,它使我们能够更好地与数据和分析进行批判性互动。它还给我们(希望)带来了在当今就业市场上的竞争优势。对于企业来说,数据素养的好处也很明显,特别是在利用数据、理解客户、抓住机会和应对挑战方面。

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

数据素养的各个方面。来源:作者提供的图片。

成为数据素养者意味着什么?

根据 Brent Dykes 的说法 [4],数据素养有两个不同的方面:数据分析和数据解读。虽然它们通常被视为一个过程,但区分这两者是至关重要的。数据分析 是技术性的,包括数据清理、异常检测、趋势分析和识别关联等任务。另一方面,数据解读 则深入探讨这些发现的意义。它提出的问题包括:

观察到的趋势是什么驱动的?我们的组织如何利用特定的关联?检测到的异常是一个罕见的现象、一个未被发现的机会,还是在某些情况下,观察到的关联可能表明因果关系?

顺便提一下:对于上述最后一个问题得到“是”的答案通常被认为是业务分析的圣杯。

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

寻找圣杯。来源

不久前,我查看了最新的‘BARC 数据文化调查’。该调查显示,2022 年只有 32%的参与者完全依赖数据做决策。18%的人依靠经验或直觉做决定。其余的 51%则是两者结合使用 [5]。这让我思考:这个最后的数字是否是一个不好的现象?

一方面,确实是这样。尽管数据科学取得了进展,包括大模型(LLMs)的应用,但这种“人情味”仍然是必需的。只有人类才能理解其他人:他们的情绪、口味和感受。无论多么复杂,计算机程序在这方面仍然不如我们。 另一方面,过度使用人为因素有时可能会带来危害。一切都取决于使用了多少种成分(即数据或直觉),以及它们用于何种决策。我发现,决策越大,人们越倾向于依赖他们相信的或之前见过的东西。而这也许在当今并不是正确的方向。

为什么将数据分析与数据解读分开是有意义的?

嗯,这又是另一个“人类特质”。最大的挑战之一是切换详细视图与“高空”视图(以及反方向)。你不能期望一个已经负担过重的经理去花几个小时或几天时间处理给定的数据集。另一方面,数据科学家可能缺乏必要的背景知识,如战略变化、对公司环境的理解,以及已作出但尚未公布的关键决策。

鉴于他们繁多的职责,经理们常常依赖数据专业人员进行详细分析。这些专家在广泛的数据探索后提供宝贵的见解。然而,领导者必须参与数据解读,而不是被动接受结论。

经理的参与确保数据解读与更广泛的组织背景保持一致。

当领导者基于数据专业人员的基础见解做决策时,集体推理会导致更全面的决策。

提高组织中数据素养的目标不是将每个员工培养成数据科学家,而是培养具备数据敏感性的个人。重点是让大多数团队成员掌握基本的数据技能,以便他们在日常任务中使用,而不是处理复杂的数据驱动角色。

拥有数据素养意味着有信心在不具备高级统计或编程知识的情况下管理日常数据。

这种基础能力能够释放你组织的数据潜力。为了确定你的团队的数据素养,应该在数据层级上定位“最低可行能力”,而不是列出所有可能的技能。Brent Dykes 建议我们可以将所需技能拆解成一个 3x3 矩阵,其中列出数据素养的水平(纵轴)以及每个水平所需的(最低)技能(横轴)[6]。

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

数据素养矩阵。表格由作者基于[6]制作。

阅读类别中,数据层次涉及基本的数字能力和特定领域的度量理解。信息层次增加了对视觉图表(图形)的理解能力和基础统计知识,而沟通阶段则强调数据解释和关键评估。

对于工作与数据层次优先考虑对分析工具和数据处理的熟悉程度。信息层次关注描述性和诊断性分析技能,而洞察层次则强调基于数据洞察的决策制定。

沟通领域,数据层次技能包括应对请求和讨论数据话题。信息层次突出数据呈现和可视化,而洞察阶段则强调具有影响力的数据讲故事的艺术[6]。

遵循 80/20 原则,我认为洞察力水平对获得数据素养至关重要。虽然其他层次也有帮助,但从决策者的角度来看,它们并不是关键的。

“阅读”领域

首先,组织内的每个人——特别是管理者和领导者——必须培养对数据科学工具和技术的基础理解。这并不意味着每个人都应该参加统计课程或深入学习 Python 或 R。相反,目标是掌握基本术语,了解特定工具的优缺点,并具备进行基础分析的能力。虽然我认识到企业角色中的时间限制,但我发现即使是基础的理解也能提升我与数据科学家的互动,避免了重温基础概念的需要,从而改善了协作。我在自己身上验证了这一点。

“工作与”领域

改变我们处理数据的方式可能会显著改变我们的公司文化。 强有力的领导至关重要。如果领导者对数据不感冒,他们会更信任直觉而非数字。

我相信我们可以在团队中利用“数据冠军”。这些人对数据充满热情,并愿意帮助他人理解数据。他们展示了数据和分析不仅仅是复杂的表格,还有令人兴奋的发现。

我们还需要用户友好的工具,让每个人即使没有技术技能也能探索和理解数据。管理者应使用有效、设计良好的仪表板来快速获得清晰的图景[7]。

然而,也存在风险。随着对有价值数据的炒作,一些公司收集了过多的数据,浪费时间进行分析,并拖慢了决策过程。

此外,如果我们看不到使用数据的快速收益,可能会失去热情。庆祝小成功是至关重要的,特别是当我们刚刚接触数据驱动的方法时。

‘沟通’领域

在这里,“数据讲故事”发挥作用。为什么它至关重要? 讲故事,通过叙述和视觉辅助,帮助理解庞大的数据。引人入胜的讲故事可以使任何故事变得清晰,无论多么复杂。这项技能如此重要,以至于《福布斯》将其列为数据科学家的顶级要求。然而,许多分析师在这方面挣扎。有效的数据故事:

  • 使复杂的话题变得易于理解和分享。

  • 促成决策变化比个人经历更为重要。

  • 将复杂的数据分析结果简化。

引人入胜的讲故事指的是“那么又如何”的声明:核心信息。许多分析师缺乏设计创意或害怕简化。然而,不清晰的视觉效果可能会阻碍业务决策 [8]。

我计划很快写关于我在数据讲故事方面的方法:敬请关注!

请记住,提高数据素养是一场马拉松,而不是短跑。

这与许多人选择的快速解决培训趋势相反。技术的迅猛发展,例如 LLMs 的崛起,突显了持续学习的必要性。优先考虑一致的、每日的自我教育——例如阅读一篇 15 分钟的文章——而不是短期的强化课程。如果可能,将这两种活动类型结合起来。然而,请记住,熟练度,尤其是在讲故事等领域,要求的是实践和经验,而不仅仅是正式培训。这涉及到理解什么有效、引起共鸣并与你的受众以及可能的舒适区相契合。

结论

在今天的数据驱动环境中,组织的所有成员,特别是领导层,必须具备对数据科学工具和方法的基础理解。这并不要求你报名参加统计课程或精通编程语言。相反,它是关于掌握基本术语、识别各种工具的优缺点,并能够进行基本的数据分析。尽管企业界时间有限,但即使是基础知识也能显著提升和简化与数据专业人士的互动。在日常操作中增强我们对数据驱动决策的依赖,加上讲故事的强大应用,处于这一过程的巅峰。到那时,我们才能真正称自己为数据素养的专家。

你喜欢这篇文章吗?考虑在 Medium 上关注我。

参考文献:

[1] 斯泽德科,米哈伊从数字到行动:让数据为公司服务,2023 年 8 月 14 日

[2] 皮尔彻,布赖斯我的数据湖实际上是数据沼泽吗?,2023 年 3 月 23 日

[3] 克莱门斯·梅瓦尔德为什么数据不是新石油,以及数据市场为何让我们失望,2023 年 7 月 13 日

[4] 布伦特·戴克斯提升任何管理者的数据解读技能的 4 个关键,2022 年 6 月 16 日

[5] BARCBARC 数据文化调查 23 — 如何开放数据访问以赋能数据用户

[6] 布伦特·戴克斯数据素养与数据讲故事:它们如何结合?,2022 年 5 月 12 日

[7] 米哈尔·苏代科利用管理仪表板讲故事:一种可行的途径?,2023 年 8 月 3 日

[8] 解码今天的世界可视化:用数据讲故事,2022 年 7 月 29 日

《极简主义者的 DVC 实验跟踪指南》

原文:towardsdatascience.com/the-minimalists-guide-to-experiment-tracking-with-dvc-f07e4636bdbb

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

图片由 Zarak Khan 提供,来源于 pexels.com

开始进行实验跟踪的最低要求指南

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

·发布于 Towards Data Science ·阅读时间 6 分钟·2023 年 5 月 15 日

本文是一个系列文章的第三部分,展示了如何利用 DVC 及其 VS Code 插件进行机器学习实验。在 第一部分 中,我展示了一个机器学习项目的完整设置,并演示了如何在 VS Code 中跟踪和评估实验。在 第二部分 中,我展示了如何使用不同类型的图,包括实时图,用于实验评估。

阅读完这些文章后,你可能有兴趣在下一个项目中使用 DVC。然而,你可能会认为设置它需要大量工作,例如定义管道和数据版本控制。也许对于你下一个快速实验来说,这可能有些过于复杂,你决定不尝试。那将是很可惜的!

虽然这些步骤有充分的理由存在——你的项目将完全被跟踪并可重现——我理解有时我们会面临很大的压力,需要快速进行实验和迭代。因此,在本文中,我将向你展示开始使用 DVC 跟踪实验所需的最低要求。

从零开始,用几行代码进行实验跟踪

在我们开始编写代码之前,我想提供一些关于我们将使用的示例的背景信息。目标是构建一个模型,以识别欺诈信用卡交易。这个数据集(可以在 Kaggle 上找到)被认为高度不平衡,只有 0.17% 的观察值属于正类。

正如我在引言中承诺的那样,我们将涵盖一个基本的场景,在这个场景中,你几乎可以立即开始跟踪你的实验。除了某些标准库,我们将使用dvcdvclive库,以及DVC VS Code 扩展。最后一个不是硬性要求。我们可以从命令行检查跟踪的实验。然而,我更喜欢使用集成到 IDE 中的特殊标签。

让我们从创建一个基本的脚本开始。在这个简短的脚本中,我们加载数据,将其分为训练集和测试集,拟合模型,并评估其在测试集上的表现。你可以在下面的代码片段中看到整个脚本。

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import f1_score, precision_score, recall_score

# set the params
train_params = {
    "n_estimators": 10,
    "max_depth": 10,
}

# load data
df = pd.read_csv("data/creditcard.csv")
X = df.drop(columns=["Time"]).copy()
y = X.pop("Class")

# train-test split
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# fit-predict
model = RandomForestClassifier(random_state=42, **train_params)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

# evaluate
print("recall", recall_score(y_test, y_pred))
print("precision", precision_score(y_test, y_pred))
print("f1_score", f1_score(y_test, y_pred))

运行脚本将返回以下输出:

recall 0.7755102040816326
precision 0.926829268292683
f1_score 0.8444444444444446

我不认为我需要说服你将这些数字写在纸上或电子表格中并不是跟踪实验的最佳方式。这尤其如此,因为我们不仅需要跟踪输出,还需要知道哪些代码和潜在的超参数导致了这个分数。如果不知道这些,我们永远无法重现实验结果。

说到这里,让我们使用 DVC 来实现实验跟踪。首先,我们需要初始化 DVC。我们可以通过在终端中(在项目的根目录下)运行以下代码来完成。

dvc init
git add -A
git commit -m "initialize DVC"

然后,我们需要稍微修改一下我们的代码,使用dvclive

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import f1_score, precision_score, recall_score
from dvclive import Live

# set the params
train_params = {
    "n_estimators": 10,
    "max_depth": 10,
}

# load data
df = pd.read_csv("data/creditcard.csv")
X = df.drop(columns=["Time"]).copy()
y = X.pop("Class")

# train-test split
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# fit-predict
model = RandomForestClassifier(random_state=42, **train_params)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)

# evaluate
with Live(save_dvc_exp=True) as live:
    for param_name, param_value in train_params.items():
        live.log_param(param_name, param_value)
    live.log_metric("recall", recall_score(y_test, y_pred))
    live.log_metric("precision", precision_score(y_test, y_pred))
    live.log_metric("f1_score", f1_score(y_test, y_pred))

唯一改变的部分是评估。使用Live上下文,我们正在记录模型的参数(存储在train_params字典中)以及我们之前打印的相同分数。我们还可以跟踪其他内容,例如,图表或图像。为了帮助你更快上手,你可以在dvclive文档中或在 DVC 扩展的设置屏幕上找到很多有用的代码片段。

在查看结果之前,值得一提的是dvclive期望每次运行都由 Git 跟踪。这意味着它将把每次运行保存到相同的路径,并每次覆盖结果。我们指定了save_dvc_exp=True以便自动跟踪为 DVC 实验。在后台,DVC 实验是 DVC 可以识别的 Git 提交,但同时,它们不会使我们的 Git 历史记录杂乱无章或创建额外的分支。

运行修改后的脚本后,我们可以在 DVC 扩展的Experiments面板中检查结果。正如我们所见,分数与我们手动打印到控制台中的分数相匹配。

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

为了清楚地看到设置跟踪的好处,我们可以快速运行另一个实验。例如,假设我们认为应该将max_depth超参数减少到 5。为此,我们只需在train_params字典中更改超参数的值,并再次运行脚本。然后,我们可以立即在汇总表中看到新实验的结果。此外,我们可以查看哪种超参数组合导致了该得分。

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

简单明了!自然,我们展示的简化示例可以轻松扩展。例如,我们可以:

  • 跟踪图表并比较实验结果,例如它们的 ROC 曲线。

  • 添加 DVC 管道以确保我们项目每一步的可重复性(加载数据、处理、拆分等)。

  • 使用 params.yaml 文件对我们管道中的所有步骤进行参数化,包括 ML 模型的训练。

  • 使用 DVC 回调。在我们的例子中,我们手动存储了模型的超参数及其性能信息。对于像 XGBoost、LightGBM 或 Keras 这样的框架,我们可以使用回调自动存储所有这些信息。

总结

在这篇文章中,我们探讨了使用 DVC 的最简单实验跟踪设置。我知道开始一个项目时考虑数据版本控制、可重复管道等可能会让人感到望而生畏。然而,运用本文描述的方法,我们可以以最小的开销开始跟踪实验。虽然对于较大的项目,我仍然强烈建议使用所有确保可重复性的工具,但对于较小的临时实验,这种方法无疑更具吸引力。

一如既往,任何建设性的反馈都非常欢迎。你可以通过 Twitter 或评论区联系我。你可以在 这个仓库 中找到本文使用的所有代码。

喜欢这篇文章?成为 Medium 会员,继续无限制地阅读学习。如果你使用 这个链接 成为会员,你将以零额外成本支持我。提前感谢,期待与你见面!

你可能也会对以下内容感兴趣:

## 11 个你可能忽略的有用 Pandas 功能

本系列探索 Pandas 隐藏宝石的第三部分

towardsdatascience.com [## 数据科学的十大 VS Code 扩展

提升生产力的必备工具!

medium.com ## 将 VS Code 转变为 ML 实验的一站式平台

如何在不离开 IDE 的情况下运行和评估实验

[towardsdatascience.com

除非另有说明,否则所有图片均为作者提供。

企业 AI 的护城河是 RAG + 精细调整 — 为什么如此重要

原文:towardsdatascience.com/the-moat-for-enterprise-ai-is-rag-fine-tuning-heres-why-fb2038e40ce9?source=collection_archive---------0-----------------------#2023-11-13

要在规模上成功实现生成式人工智能,我们需要给予 LLMs 应有的勤奋。RAG 和精细调整应运而生。

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

·

关注 发表在Towards Data Science ·10 分钟阅读·2023 年 11 月 13 日

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

Volodymyr Hryshchenko拍摄的照片,来源于Unsplash

围绕 LLM 的炒作是前所未有的,但也是有充分理由的。从 AI 生成的全副装扮的教皇没有脉搏的客户支持代理人,生成式 AI 有改变我们所知社会的潜力。

在很多方面,LLM(大型语言模型)将会使数据工程师变得更加重要 — 这是令人兴奋的!

不过,向老板展示一个数据发现工具或文本转 SQL 生成器的酷炫演示一回事,将其与公司的专有数据,甚至更令人担忧的是客户数据一起使用则是另一回事。

太多时候,公司匆忙建立 AI 应用程序,却对其实验的财务和组织影响缺乏远见。而这并不是他们的错 — 高管和董事会对这(以及大多数)新技术的“赶快上路”的心态负有责任。(还记得 NFT 吗?)

要让 AI — 特别是生成式 AI — 取得成功,我们需要退一步,回想一下任何软件如何变得企业就绪。为了达到这一点,我们可以从其他行业获取启示,了解企业就绪的标准,并将这些原则应用到生成式 AI 中。

我认为,企业级生成式 AI 必须:

  • 安全与隐私: 您的 AI 应用程序必须确保您的数据安全、私密且符合法规,具备适当的访问控制。想象一下:AI 的安全运营。

  • 可扩展性: 您的 AI 应用程序必须易于部署、使用和升级,同时还要具备成本效益。如果一个数据应用程序需要花费数月才能部署,使用起来繁琐,并且升级时会引入无数其他问题,那么您也不会购买或自行开发这样的应用程序。我们不应该对待 AI 应用程序有任何不同。

  • 可信赖。 您的 AI 应用程序应该足够可靠和一致。我很难想象有哪位 CTO 愿意赌自己的职业生涯,去购买或开发一个生成不可靠代码或生成的见解混乱且误导的产品。

在这些限制条件下,现在是我们开始认真对待生成式 AI 的时候了。但这并不容易……

为什么企业级 AI 如此难以实现?

简而言之,尚缺乏适合扩展、安全和运作 LLM 应用程序的基础设施。

不同于大多数应用程序,AI 很大程度上是一个黑匣子。我们知道我们输入了什么(原始、通常是非结构化数据),我们也知道我们得到了什么结果,但我们不知道它是如何做到的。这使得扩展、安全和运作都变得困难。

以 GPT-4 为例。虽然 GPT-4 在某些任务(如 SAT 和 AP Calculus AB 考试)表现出色,但其部分输出被幻觉所困扰或缺乏足够的上下文来充分完成这些任务。幻觉的产生是由多种因素引起的,从低质量的嵌入到知识截断,经常影响由公开或开放 LLM 模型生成的响应质量,这些模型是根据从互联网上获取的信息训练的,占大多数。

为了减少幻觉,甚至更重要的是——回答有意义的业务问题——公司需要用自己的专有数据增强 LLMs,包括必要的业务背景。例如,如果客户要求航空公司聊天机器人取消他们的机票,模型需要访问关于客户、其过往交易、取消政策以及可能的其他信息。所有这些信息当前都存在于数据库和数据仓库中。

没有这些背景信息,AI 只能根据公开信息进行推理,通常这些信息是最初训练模型的互联网上发布的。这就产生了一个难题——暴露专有企业数据并将其纳入业务工作流程或客户体验几乎总是需要坚实的安全性、可扩展性和可靠性。

两条通向企业就绪 AI 的路线:RAG 和微调

当涉及使 AI 企业就绪时,最关键的部分出现在 LLM 开发过程的最后阶段:检索增强生成(RAG)微调

但需要注意的是,RAG 和微调并不是互斥的方法,应根据您的具体需求和用例来利用——通常是并行使用的。

何时使用 RAG

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

图片由作者提供。

RAG 是一种通过让模型访问数据库来改进 LLM 输出质量的框架,试图在回答提示时提供支持。数据库作为一个经过精心策划和可信任的潜在专有数据集,允许模型将最新和可靠的信息整合到其响应和推理中。这种方法最适合需要额外上下文信息的 AI 应用,例如客户支持响应(例如我们的航班取消示例)或在公司企业通信平台中进行语义搜索。

RAG 应用程序旨在从知识来源中检索相关信息,然后生成响应,因此非常适合查询结构化和非结构化数据源,如向量数据库和特征存储。通过检索信息来提高 LLM 在输出生成时的准确性和可靠性,RAG 在减少幻觉和降低培训成本方面也非常有效。RAG 还为团队提供了一定程度的透明度,因为您知道将数据输入模型以生成新响应的数据源。

关于 RAG 架构的一点需要注意的是,它们的性能在很大程度上依赖于您建立有效数据管道的能力,使企业数据对 AI 模型可用。

何时使用微调

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

图像由作者提供。

微调是在现有的语言模型上训练一个更小、任务特定且标记数据集的过程,根据这些新数据调整模型参数和嵌入。微调依赖于预先筛选过的数据集,这些数据集不仅仅用于信息检索,还包括所需领域的细微差别和术语。

在我们的经验中,微调最适合特定领域的情况,比如以特定的语调或风格对详细提示作出回应,比如法律简报或客户支持票证。它还非常适合克服信息偏见和其他限制,比如语言重复或不一致之处。几项 研究 在过去的一年中表明,经过微调的模型显著优于 GPT-3 和其他公开可用模型的即用版本。已经确定,对于许多用例来说,经过微调的小型模型可以胜过大型通用模型 —— 这使得在某些情况下,微调成为成本效率的一种可行路径。

与 RAG 不同,微调通常需要更少的数据,但耗费更多的时间和计算资源。此外,微调操作像一个黑盒子;由于模型内化了新数据集,难以准确指出新响应背后的推理过程,并且幻觉仍然是一个值得关注的问题。

和 RAG 架构一样,微调需要建立有效的数据管道,使(标记的!)企业数据可用于微调过程。这绝非易事。

为什么 RAG 可能适合您的团队

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

图像由作者提供。

重要的是要记住,RAG 和精细调整并非互斥的方法,它们各有优势和劣势,并可以一起使用。然而,对于绝大多数用例来说,RAG 在交付企业生成 AI 应用程序时可能是最合适的选择。

以下是原因:

  • RAG 的安全性和隐私更易管理: 数据库具有内置角色和安全性,而不像 AI 模型那样,由于标准访问控制,非常明确谁看到什么。此外,通过访问专有数据的安全和私密语料库,您可以更好地控制使用哪些数据。通过精细调整,包含在训练集中的任何数据都暴露给应用程序的所有用户,没有明显的方法来管理谁看到什么。在许多实际场景中——特别是涉及客户数据时——失去这种控制是不可接受的。

  • RAG 更具可扩展性: 与精细调整相比,RAG 成本更低,因为后者涉及更新大型模型的所有参数,需要大量计算资源。此外,RAG 不需要标记和制作训练集,这是一个人力密集型过程,可能需要数周甚至数月来完善每个模型。

  • RAG 提供更可信赖的结果。 简单来说,RAG 在动态数据中运作更佳,从最新的策划数据集生成确定性结果。由于精细调整很大程度上像黑匣子,很难准确指出模型生成特定结果的方式,这降低了信任和透明度。通过精细调整,出现幻觉和不准确可能性,因为您依赖模型的权重以损失方式编码业务信息。

依我们的谦逊看法,企业就绪 AI 将主要依赖于 RAG,并涉及对更微妙或特定领域用例的精细调整。对于绝大多数应用程序来说,精细调整将是一种对于小众场景而言很好的可选项,并且在行业能够降低运行大规模 AI 所需成本和资源后,它将更频繁地发挥作用。

无论您使用哪种方法,您的 AI 应用程序开发都将需要通过某些数据存储(如 Snowflake、Databricks、像 Pinecone 这样的独立向量数据库或其他完全不同的东西)向这些模型提供公司数据的管道。归根结底,如果生成式 AI 用于内部流程以从非结构化数据中提取分析和见解——它将被用于……鼓掌……数据管道。

要使 RAG 正常工作,您需要数据的可观察性。

在 2010 年代初期,机器学习被吹捧为一种神奇算法,只要您给予其特征完美的权重,就能随时随地执行奇迹。然而,通常改善 ML 性能的是投资于高质量的特征,特别是数据质量。

同样,为了让企业 AI 正常工作,你需要关注生成模型所依赖的数据的质量和可靠性——这很可能通过 RAG 架构来实现。

由于它依赖于动态的、有时是实时的数据,RAG 需要 数据可观测性 来满足其企业级期望。数据可能因多种原因而中断,例如格式错误的第三方数据、故障的转换代码或失败的 Airflow 作业。数据总是会出现问题。

数据可观测性使团队能够在整个数据生态系统中以规模化的方式监控、警报、分类和解决数据或管道问题。多年来,它一直是现代数据栈中的必备层;随着 RAG 重要性的增加和 AI 的成熟,可观测性将成为 LLM 开发中的关键合作伙伴。

RAG 和企业 AI 能否正常工作的唯一方法是你能信任数据。为此,团队需要一种可扩展的、自动化的方式来确保数据的可靠性,以及一种企业级的方法来快速识别根本原因并解决问题——在这些问题影响到它们服务的 LLM 之前。

那么,事实上的 LLM 技术栈是什么呢?

正如我们所说,AI 工具的基础设施和技术路线图正在开发中,每天都有新的初创公司涌现出来解决各种问题,行业巨头也声称他们在应对这些挑战。涉及到将企业数据整合到 AI 中时,我看到三大主要的“竞赛选手”。

第一匹“竞赛选手”:向量数据库。Pinecone、Weaviate 等正在成为驱动 RAG 架构的必备数据库平台。虽然这些技术展现了很大的潜力,但它们确实需要构建新的一层技术栈,并创建支持它的工作流程,包括从安全性、可扩展性和可靠性方面。

第二匹“竞赛选手”:由第三方 LLM 开发者如 OpenAI 或 Anthropic 构建的模型的托管版本。目前,大多数团队通过这些新兴 AI 领导者提供的 API 来获取生成 AI 的支持,因为使用起来很方便。接入 OpenAI API,几分钟内就能利用前沿模型?我们在其中。如果你需要模型生成代码或解决基于公开信息的常见、非特定提示,这种方法效果很好。如果你想将专有信息整合到这些模型中,你可以使用这些平台提供的内置 微调RAG 功能。

最后,第三匹马:现代数据堆栈SnowflakeDatabricks 已经宣布他们正在将向量数据库嵌入其平台以及其他工具,以帮助将已存储和处理在这些平台上的数据整合到 LLM 中。对于许多人来说,这是非常合理的,并允许负责 AI 项目的数据团队利用他们已经使用的工具。当您已经有了基础时,何必重新发明轮子呢?更不用说可以轻松地将传统关系型数据与向量数据结合起来的可能性了……像其他两匹马一样,这种方法也有一些缺点:Snowflake Cortex、Lakehouse AI 和其他 MDS + AI 产品还处于萌芽阶段,需要一些前期投资来将向量搜索和模型训练整合到您现有的工作流程中。如果您想更深入地了解这种方法,请查看 Meltano 在其相关文章中为什么最好的 LLM 堆栈可能就在您眼前的观点。

无论我们选择哪匹马,宝贵的商业问题都不能通过仅基于互联网数据训练的模型来回答。它需要具有公司内部背景的上下文。通过安全、可扩展和可信赖的方式提供这种背景,我们可以实现企业级 AI。

企业 AI 的未来就在您的管道中。

要使 AI 实现其潜力,数据和 AI 团队需要认真对待 LLM 增强,并将安全性、可扩展性和可靠性作为首要考虑因素。无论您的用例是否需要 RAG 或精细调整 — 或两者兼有 — 您都需要确保您的数据堆栈基础设施已经就位,以保持成本低、性能稳定且可靠性高。

数据需要安全和隐私保护;LLM 部署需要可扩展性;而您的结果需要得到信任。通过可观察性保持数据质量的稳定脉搏对这些需求至关重要。

这种从孤立的 X 演示转向企业级 AI 的演变中最好的部分是什么?RAG 使数据工程师在拥有和推动生成 AI 投资的 ROI 方面处于最佳位置。

我已准备好迎接企业级 AI。你准备好了吗?

Lior Gavish 为本文作出了贡献。

巴尔在领英上联系 以获取有关数据、AI 和数据信任未来的更多见解。

最强大的气候数据仍然被隐藏

原文:towardsdatascience.com/the-most-powerful-climate-data-remains-hidden-87cb0a0bf302

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

·发表于Towards Data Science ·13 min read·2023 年 2 月 20 日

支撑全球可持续决策的气候数据和模型往往是专有的,对我们来说是隐藏的。数据市场、数据合同、数据许可和数据定价提供了共享这些重要信息的激励和做法。

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

Olga Vilkha拍摄,来源于Unsplash

有几位贡献者和顾问为理解当前气候数据格局并塑造本文提供了巨大的帮助:Ellie Young(Common Action)、Philippe Höij(DFRNT.com)和 Andrew Padilla(Datacequia.com)。

使隐藏的气候数据可共享

向他人学习一直是人类进步的标志。我们在构建新的发明时,实际上是在前人的工作基础上“站在巨人的肩膀上”。因此,当我们看到丰富的公共气候数据,以及这些数据如何在全球范围内共享时,我们实际上是在气候数据巨人的隐喻肩膀上,他们免费分享气候数据以造福广大公众。

然而,简单而不幸的事实是,许多最有价值的气候数据对公众隐藏。那些被组织转换和丰富的数据。精炼的数据以支持更好的投资决策。被整理成专有模型的数据,推动组织做出的全球可持续性和气候决策。那些在组织内部“隐藏”的数据。

现在,“隐藏”这个词可能暗示着不良意图。明确地说,事实并非如此。实际上,“隐藏”的本质是转换、精炼和策划赋予公共数据巨大价值的结果。但这些数据并不可用。它是专有的。它是封闭的。因此,它被隐藏了。

实际问题是,每个组织几乎都在进行相同的工作,以处理、丰富和精炼这些公共数据,使其用于指导企业的可持续性和气候决策。但这些精炼的数据及其相关模型很少甚至从未被共享。

在这篇文章中,我将探讨这种不幸情况的根本原因。但或许更重要的是,我还将提供几种潜在的解决方案,以便更容易分享数据,揭示幕后情况,看到之前隐藏的内容。

气候数据是应对气候变化的基石

气候变化是我们时代最紧迫的问题之一,而气候数据的可用性对于理解问题、识别实际解决方案以及确定政策变更的实际影响至关重要。意识到这一点,政府和私人组织都会收集并发布大量的降水、风速和温度数据,以衡量和了解它们对气候变化的暴露。

这些数据至关重要——它用于提供政策决策、创建预测模型以及评估气候变化对经济各个部门的风险。

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

图 1,大多数气候数据是未经精炼的原始格式

从气候数据的消防栓中饮水

但今天,我们面临着大量免费的公共气候数据。像 NASA、NOAA 以及许多欧洲和国际组织都发布了大量有关温度、降水和各种传感器数据的精细数据。这些数据已经发布了几十年,并且每天仍在发布。比喻来说,我们正从气候数据的消防栓中饮水!

然而,大多数数据仍然是以原始格式存在,包含数值测量或文本。这些数据有很多不同的格式和结构,存在一致性和可用性方面的差异,使得非专家和专家都难以理解或使用。

应用气候数据——转换、精炼和策划

与此相比,“应用”的气候数据已经被转换、精炼和策划,以提取有意义的见解和模式。这通常涉及将多个原始的公共气候数据集结合起来,将它们与其他公共和私有数据关联,清理和组织数据,然后应用统计或机器学习技术来提取有意义的信息。

以保险公司为例。保险公司希望确保被保险资产的价格反映未来的气候风险。例如,他们可能会使用公开的天气、地形(洪泛区、河流)和人口数据来创建算法和模型,更好地理解洪水发生的概率。这些模型帮助决定是否为靠近洪泛区的财产提供保险。

资产管理者,例如,可能会使用各种排放、能源效率和政府数据,包括公共和私人数据,以了解他们的资产对气候变化的潜在暴露,从而更好地调整其风险和回报目标。

随着更严格的气候法规的出现,大多数组织正在准备报告他们自身的气候足迹。例如,他们可能会汇总来自核心业务、子公司和全球运营单位的排放数据,以向公众和其运营区域的监管机构提供报告。

应用数据是专有数据

然而,很明显,这些公司中的许多都在收集类似的数据并创建类似的算法。这种对气候数据轮子的“再发明”发生的原因有很多。

首先,许多公司不愿意共享他们的数据,因为他们担心竞争对手会利用这些数据获得竞争优势,或者他们的数据会被用来创建与自己直接竞争的新产品或服务。

其次,缺乏法律和监管框架来支持数据共享和数据定价。这使得公司难以建立有关数据共享和数据定价的明确规则和期望,进一步抑制了公司共享数据的意愿。

第三,数据可能缺乏来源和溯源,从而可能产生不可信的印象。

最后,也许最具挑战性的情况是,数据共享给数据发布者带来了实质性的潜在长期风险和义务,尤其是当第三方以意想不到的方式使用这些数据时。

简而言之,基于气候数据做出的决策具有长远的时间跨度和长期的后果,尤其是当数据可能出错时;这不是故意的错误,而是可能在长时间内被放大的小错误导致大错误,或者算法被错误调整。任何具有长期尾部的决策,都可能引发巨大的成本。

例如,考虑以下情景:一个资产管理者发布了关于沿海房地产洪水概率的数据。一个房地产开发商使用这些数据,在根据资产管理者的分析,洪水概率相对较低的土地上进行建设。几年后,尽管洪水概率较低,但新建的物业却意外被淹没了。会发生什么?损失和法律诉讼。

使应用数据可用

但如果其他组织可以通过共享他们的私人气候数据来帮助他人更好地预测洪水会怎么样?如果组织共享他们的气候模型来帮助他人做出更明智的气候投资决策会怎么样?如果可以更容易地分享私人气候数据和模型,而没有下游风险呢?

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

图 2,公开隐藏的气候数据

一些努力正在解决这些挑战。例如,一些倡议(如OS-Climate)正在建立共同的数据标准、协议和平台,以便更容易找到和使用气候数据。联合国以及许多前瞻性的政府正在建立监管指南和框架,鼓励气候数据共享。此外,还建立了数据市场和数据合作社,以促进合作,创建一个公平的数据生态系统,提供透明的数据定价。

还有更多工作需要完成。现今在其他行业中有哪些用例可以教会我们如何共享数据?也许我们可以将“创意共享”许可中学到的经验应用于限制或管理共享气候数据的风险;或者开源软件许可提供了一些新的思路?或者可能有“数据合同”的示例,可以标准化气候数据格式和结构?

从隐喻上说,我们应该站在数据巨人的肩膀上,运用现今最佳实践来增强和赋能未来的气候数据工作。我们已经学到了哪些教训可以应用——现在——使共享气候数据变得更加广泛和安全。

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

图 3,迈向气候数据生态系统

经验教训:创意共享(可共享的理念——许可)

创意共享组织提供了一套版权许可,使创作者能够分享他们的作品,同时通常允许第三方将创作者的内容用于非商业目的或制作衍生作品。但它也至关重要地让创作者保留对其作品使用方式的一定控制权。

创意共享常用于创意作品,如音乐、艺术、写作和软件。这些许可容易理解且免费使用,使创作者在保护自己权利的同时相对容易地分享他们的作品。

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

图 4,可共享的理念——创意共享许可

我们可以从非常流行的**创意共享(CC)**许可方案中学到什么教训?通过使用 CC 许可概念,数据许可应该允许数据创作者指定他人使用数据的条件,比如允许他人将其用于非商业目的、制作衍生作品或与他人分享。

例如,创建了数据集的数据科学家可以使用 CC 许可允许他人利用数据进行进一步分析或研究;政府机构可以使用 CC 许可允许他人利用其数据创建新产品或服务;公司可以使用 CC 许可允许他人利用其数据创造对社会有益的新创新。

经验教训:开源软件许可证(可共享软件)

软件许可是一种保护软件创作者免受意外使用和发布软件的意外后果风险的方法,通过明确定义可以使用的条款和条件。通过创建软件许可证,创作者可以明确指定软件的使用方式、使用者和目的。这有助于防止软件被用于创作者未预期的方式,或者可能对创作者或他人造成伤害的方式。

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

图 5,可共享软件 — 开源软件许可

以下是几种保护软件创作者的开源软件许可技术:

  • 使用:许可证可以包括对软件使用方式的限制,例如禁止将软件用于商业目的。

  • 归属:许可证可以要求对软件的任何使用都必须归属创作者,这有助于保护创作者的知识产权。

  • 责任:许可证可以包括规定,要求用户对因使用软件而可能造成的任何损害负责,这有助于保护创作者免受法律诉讼。

  • 审计:许可证可能包括允许创作者监控和跟踪软件使用情况的条款,这有助于确保遵守许可证条款。

今天有几种流行的开源许可证,例如 GNU 通用公共许可证(GPL)、MIT 许可证和 Apache 许可证,每种许可证都有类似但不同的条款和条件。

那么,我们如何将开源软件许可证中的概念应用于气候数据共享呢?通过调整基于开源软件许可证的共享方案模型,气候数据创作者可以明确:

  • 使用:气候数据发布者可以限制使用或根据需要进行灵活调整;例如,原始气候数据可能会被自由和开放地共享,没有限制。但复杂的模型和算法可能需要严格的使用条款。

  • 归属:气候数据发布者可能会出于多个原因要求对其数据进行归属:这可能会为发布者建立声誉,从而带来商业机会,或者它可能作为促进正式数据来源和血统的工具。

  • 责任:气候数据发布者可能要求包括保护条款,以防第三方使用或滥用。这将使数据发布者能够减轻由于数据不准确、错误或缺乏精确性所带来的潜在风险。

  • 审计:气候数据发布者,特别是当其数据被用于商业用途时,可能要求数据使用者验证使用量,以确保适当的计费。

经验教训:OpenAPI 规范(可共享合同)

数据合同是一种定义数据共享、使用和保护条款和条件的协议。在许多情况下,它规定了数据提供者、数据接收者以及任何中介的权利和责任。但数据合同也提供了数据交换格式和结构的定义。

发布数据交换的格式和结构具有多个好处,包括:

  • 互操作性:标准化的格式和结构使得不同的系统和应用能够轻松交换信息。

  • 重用性:数据可以被许多系统和应用重复使用,从而减少数据重复(并且提高效率)。

  • 可访问性:发布数据交换的格式和结构使得理解和共享变得更加容易。

  • 创新:清晰的数据格式和结构能够促进创新,使开发者能够在现有数据基础上轻松构建新的应用和服务。

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

图 6,可共享合同 — OpenAPI 规范

那么,我们如何使用基于 OpenAPI 规范(OAS)建模的合同来定义数据如何交换呢?数据创建者可以使用类似 OAS 的数据交换规范来获得几个好处:

  • 数据规范文档:与 OAS 类似,数据创建者可以创建规范,允许开发者自动生成他们 API 的人类可读文档,这使得其他开发者更容易理解和使用 API。

  • 数据规范测试:与 OAS 类似,数据创建者可以自动生成数据交换的测试用例,这有助于确保其按预期工作。

  • 数据规范客户端生成:与 OAS 类似,数据创建者可以自动生成他们 API 的客户端代码,这使得将数据产品与其他应用进行集成变得更加容易。

  • 数据规范访问权限:与 OAS 类似,数据创建者可以嵌入安全模式和范围,定义访问数据产品所需的权限。

经验教训:数据市场(可共享数据)

数据市场是一个平台或网络,使得查找、理解、共享和信任数据变得容易。它通常将数据提供者(发布数据的)与数据消费者(寻找特定类型数据以供使用的)连接起来。数据市场帮助组织快速、轻松地访问高质量的数据,同时也为数据提供者提供了新的发布方式,甚至可能将数据资产货币化。

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

图 7,可共享数据 — 数据市场

考虑以下场景:假设一个前瞻性的非营利组织(一个没有商业动机的非营利组织)正在建立一个“气候数据市场”,作为气候数据的注册中心。该非营利组织的气候数据市场类似于互联网的 DNS(域名服务)——气候数据市场通过提供气候数据的指针(URL)目录,使搜索和查找所需气候数据变得简单(实际上,它可能还会提供更多内容:直观的用户界面、气候数据类别的策划层级和知识图谱、文档和数据术语表,但这属于另一篇文章的内容)。

数据市场也提供了可以应用于数据共享的教训。数据市场可以解决当前的数据所有权和控制问题,个人和社区对其数据的控制有限,且从使用中获益较少。数据市场提供了实施上述教训的总体结构,包括:

  • 用户界面和支持平台,旨在使数据的查找和理解变得简单。

  • 许可,旨在通过提供一致、标准和易于理解的数据共享条款和条件,使数据共享变得容易。

  • 规范,旨在通过定义访问数据所需的交互机制,使数据集成变得容易。

  • 合同,旨在通过提供数据科学家和开发者构建模型和应用所需的元数据定义、信息结构和格式,使数据更易于使用。

结论性思考

本文讨论了为什么许多最有价值的气候数据对公众视野和使用隐藏。我还强调了为什么会这样,同时提出了几种潜在的解决方案,所有这些方案都基于对现有方法的调整,使其更易于分享数据。

我还发现了一个潜在的根本原因,那就是当前气候数据共享实践未能充分保护数据创造者的权利和需求。艺术、软件、创意、数据合同及其他领域提供了丰富的建议,用于保护数据产品的逻辑、内容、使用等方面,并进一步提供了规范数据更新、贡献和改进的协作协议的建议。

我们希望这些想法能够扩展并付诸实践,以便将一些精炼、处理和丰富的数据——以及背后的算法——置于公共领域或以更简单、更负责任的方式共享。我们希望各组织在重新发明、重建和复制数据、算法和模型方面所付出的努力,能够更具建设性和有效性地应对我们的气候危机。


除非另有说明,本文档中的所有图片均由 Eric Broda(本文作者)创建。所有图像中使用的图标都是库存的 PowerPoint 图标和/或不受版权保护的。

本文中表达的意见仅代表作者的观点,并不一定反映任何客户的观点。

多任务优化争议

原文:towardsdatascience.com/the-multi-task-optimization-controversy-793cbb431d98

我们是否需要特殊的算法来同时训练多个任务的模型?

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

·发表于Towards Data Science ·阅读时间 6 分钟·2023 年 9 月 29 日

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

Javier Allegue BarrosUnsplash拍摄的照片

多任务学习范式 —— 即同时训练多个任务的能力 —— 既是一种祝福,也是一种诅咒。

这是一个祝福,因为它使我们能够构建一个单一的模型,而之前我们需要多个模型。这使得生活更简单:减少需要维护、重新训练、调整和监控的模型数量。

这是一个诅咒,因为它开启了一个全新的潘多拉盒子:哪些任务应该一起学习?我们真正需要哪些任务?如果任务之间存在竞争会发生什么?我们如何让模型优先考虑某些任务而不是其他任务?我们如何避免“任务腐蚀”,即任务头的积累最终导致模型性能的下降?

正是这些问题催生了一个新的机器学习子领域,即多任务优化,也就是如何在多个有时相互竞争的任务上优化模型的科学。

标量化

标量化是数学对多任务优化问题的回答。在多任务模型中,我们试图学习 K 个任务,例如在电子商务推荐系统中预测“点击”、“添加到购物车”和“购买”。(实际上,现代推荐系统可能包括十多个任务!)在这样的设置中,我们可以定义解决方案为最小化

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

…也就是说,任务特定损失的加权和,其中权重大于 0 且总和为 1。

将多任务学习问题重新表述为单一优化问题的技巧被称为 标量化,它借鉴了更广泛的数学优化学科,该学科在诸如 Boyd & Vandenberghe 等教科书中有详细介绍。

在这种问题中的一个重要定义是 帕累托最优性:如果一个解 θ 对所有任务都实现了最低损失,则称之为帕累托最优,即不存在一个 θ 对任何任务具有更低的损失。通常,没有一个单一的解 θ 是帕累托最优的,而是多个解形成了损失空间中的高维曲线——即 帕累托前沿

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

(具有 2 个任务的多任务问题中的帕累托前沿。图片来源:Xin et al 2022

最后,这是在数学优化背景下可以推导出的最重要的结果之一:

从数学上讲,可以证明无论我们选择哪种权重组合,我们总会得到一个恰好位于帕累托前沿的解 θ。在实际应用中,我们需要做的就是遍历可能的权重组合,并选择与业务目标最为一致的那个。

可学习的损失权重

多任务优化的故事本可以通过标量化及其对帕累托最优性的保证来结束。然而,正如机器学习中的常见情况,实践者最终开发出一些在经验上效果出乎意料好的技巧。

其中一个技巧是“可学习的损失权重”(LLW),这是由剑桥大学的研究人员在 2018 年的一篇论文中提出的(Kendall et al 2018),主要应用于计算机视觉领域。其关键思想是自动分配与该数据点预测的模型不确定性成反比的任务特定损失权重。直观上,如果模型错误但不确定,我们应该分配较小的损失,而不是模型错误且确定时的损失。

从数学上讲,这意味着我们最小化

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

其中 L_i 是任务 i 的损失,σ_i 是任务 i 预测中的不确定性。损失中的最后一项,简单地加上不确定性自身的对数,促使模型做出高确定性的预测,而不是仅仅以小的确定度预测每一种可能的结果。对于多于 2 个任务的情况,我们只需在此方程中添加更多项,每项对应一个任务的损失。

实际上,我们可以通过将预测结果与实际情况进行比较,并拟合一个均值为预测结果自身、标准差为模型不确定性的高斯分布 N 来估计不确定性 σ:

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

在剑桥论文中,作者将可学习的损失权重应用于一个多任务图像分割问题,其中单个任务包括语义分割、实例分割和深度预测。与均匀权重(1/3, 1/3, 1/3)相比,使用可学习的损失权重(结果为 0.89, 0.01, 0.1)后,得到的分割结果的 IoU 提高了 13%,证明了这种方法的有效性。

梯度操控

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

(梯度“手术”。图片来源:Yu et al 2020

多任务学习中的一个问题是来自不同任务的不同梯度可能相互冲突,导致模型同时被拉向多个不同方向。在标量化中,我们通过根据认为最重要的任务来简单地调整损失权重(直接影响梯度的尺度)来解决这个问题。在 LLW 中,我们尝试从数据中学习这些权重,而不是手动调整。但为什么不直接操控梯度,而不是损失呢?

直接梯度操控的这个想法催生了一些研究论文,这些论文声称通过以各种方式缩放或重新对齐梯度来改进多任务学习:

  • Gradient Surgery中,我们简单地将一个冲突的梯度投影到“锚点”梯度的法向平面上(即,我们试图预测的最重要任务的梯度),

  • GradNorm中,我们将所有梯度的尺度标准化为该训练迭代中的平均梯度尺度(对所有任务进行平均),

  • GradSimilarity中,我们仅考虑与锚点梯度有正余弦值的其他任务 i 的梯度,

  • MetaBalance中,我们将所有梯度的尺度标准化为与锚点梯度的尺度相同(类似于MTAdam),还有更多。

每一篇论文声称比其后继论文更好地解决了多任务学习问题,并且在 2023 年撰写本文时,关于梯度操控的更多论文仍在不断发布。梯度操控是一个迅速增长的研究领域!

争议

所有这些都导致了一个奇怪的结论。从数学上可以证明,我们在多任务问题中需要做的就是应用标量化并在损失权重上进行遍历,以找到最符合业务目标的点——这是(可以证明的!)帕累托最优的。《可学习的损失权重》的作者声称,学习损失权重比手动调整它们更好。这没问题,但他们可能通过精细的参数遍历也会发现相同的结果。

有争议的是,研究者在直接梯度操作算法上的主张,即改变损失权重是不够的:我们需要直接调整梯度以解决训练过程中的冲突。这一主张与标量化理论相矛盾!

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

梯度操作算法不如标量化(蓝色曲线)。图片来源:Xin et al 2022

那么,谁对呢?在他们的论文《当前深度学习中的多任务优化方法真的有帮助吗?》中,Derrick Xin 等人比较了标量化(结合损失权重的参数扫描)与一些现代梯度操作算法,包括梯度手术和 GradNorm 的预测性能。结果是?它们都不如标量化!

作者解释道:

“研究人员可以通过简单地调整竞争基线,毫无察觉地创造出显著的性能提升错觉。”

这种“错觉”突显了现代机器学习研究中的一个问题:也许发表机器学习研究论文太容易了。也许仅仅通过稍微调整算法并减少基线的调整,就可以轻松证明一种新算法在固定数据集上的有效性。

也许,那么,推进机器学习研究的最佳方法之一是开发更好的理论。

p 值的神话:为什么它们不是数据科学中的圣杯

原文:towardsdatascience.com/the-myth-of-p-values-why-theyre-not-the-holy-grail-in-data-science-a6636e27e489

p 值谬论:我们为什么需要停止把它们当作真理

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 费德里科·特罗塔

·发表于Towards Data Science ·15 分钟阅读·2023 年 4 月 27 日

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

图片由Gerd Altmann提供,来自Pixabay

近期文章中,我提到我们在数据科学中并不总是需要计算p-values,展示了我们在不计算它们的情况下找到了解决 ML 问题的好模型。

现在是时候写一篇澄清这一声明的文章了。我知道:这将是一篇有争议的文章,我非常希望在评论中听到你的意见。

如果你是一个有志成为数据科学家的读者,这里你将找到p-values的定义以及对其使用的有趣讨论。而如果你是专家,我知道你了解p-values的定义,希望你会喜欢对其使用的讨论。

我的观点并不是为了说服任何人:这些讨论在科学界非常严肃,正如你将在文章中看到的。我只是想对p-values这一话题进行一些探讨,建议我们作为数据科学家是否必须使用p-value,或者是否可以跳过它们,使用其他方式测试我们的 ML 模型(我们将看到具体方法)。

**Table of Contents:**

Definingthe p-values
Why we could avoid p-values as Data Scientists
What to use instead of p-values as Data Scientists
An example in Python

定义 p 值

引用自维基百科:

在零假设显著性检验中,p-value是在假设零假设正确的情况下,获得至少和实际观察结果一样极端的测试结果的概率。

现在,我不认识你,但我的数学学习方式一直是:将其转化为实践。 作为工程师,我喜欢实用数学因为它帮助我更好地理解它。但我必须告诉你真相:我从未从根本上理解过这个定义。

对我来说好消息是……我不是世界上唯一一个这样的人!实际上,我鼓励你阅读这篇(非常简短的)文章 在这里,在那篇文章中我们可以读到:

明确一点,我在 METRICS 谈话过的每个人都能告诉我p-value的技术定义[…]但几乎没有人能够将其翻译成容易理解的东西。

这不是他们的错,METRICS 的共同主任斯蒂文·古德曼说。即使在“整个职业生涯”中一直在思考p-values,他说他可以告诉我定义,“但我不能告诉你它的意义,几乎没有人能。”

好吧,让我告诉你,当我读到这些话时,我既感到惊讶又感到高兴。惊讶是因为这意味着“科学世界”似乎在处理某种未知的东西。高兴是因为……我不是错的!

如你所知,我们认为 0.05 的p-value是可以接受的。还有另一个问题:为什么是这个数字?乔治·科布,霍利奥克学院数学与统计学名誉教授,在美国统计学会(ASA)讨论论坛上提出了这些问题(这是完整的文章):

问:为什么这么多大学和研究生院教 p = 0.05?

答:因为这仍然是科学界和期刊编辑使用的标准。

问:为什么这么多人仍然使用 p = 0.05?

答:因为这是他们在大学或研究生院时学到的。

这就像是:鸡和蛋哪个先出现?

这种方法的问题在于,p 值不会告诉我们关于结果的任何信息。这导致了ASA 声明

原则 5:p-value,或统计显著性,并不衡量效应的大小或结果的重要性。

常用的统计显著性阈值是 0.05 的p-value。这是惯例和随意的。它并不传达效应大小的任何有意义的证据。p-value为 0.01 并不意味着效应大小比p-value为 0.03 时更大。

这是 ASA 在p-values方面提出的六个原则中的第五个。我们来阅读所有这些原则(这是 ASA 的完整文章):

p-values 可以指示数据与指定统计模型的不兼容程度。

p-values 并不衡量所研究的假设为真的概率,或者数据是仅由随机机会产生的概率。

科学结论和商业或政策决策不应仅仅基于p-value是否超过特定阈值。

适当的推断需要完全的报告和透明度。

p-value 或统计显著性,并不衡量效应的大小或结果的重要性。

p-value 本身并不能提供关于模型或假设的良好证据度量。

因此,根据我们到目前为止阅读的领域专家的观点,我们可以说p-values——尤其是它们的使用——在某种程度上是一个有争议的话题。因此,我将继续讨论为什么在我看来,作为数据科学家我们可以避免使用p-values,除非在某些情况下。然后,我们将用 Python 实现一个示例。

为什么我们作为数据科学家可以避免使用 p 值

我将告诉你一些可能看起来不好的事情,但请让我解释。数据科学是一个非常庞大的领域,许多专业人士在不同的行业中担任数据科学家的角色,他们来自不同的背景。因此,在我看来,根据我的经验,有三种类型的数据科学家:

  • “统计学家”。

  • “软件工程师”。

  • “其他所有人”。

“统计学家”是那些毕业于统计学、数学、物理学或相关领域的人,他们拥有大量的高级统计学知识,并在应用大量高级统计学。例如,研究病毒等生物学领域的人。这些数据科学家通常是研究人员。

“软件工程师”通常是那些学习过计算机工程(或在该领域精通)的人,因为他们喜欢数据,所以转而成为数据科学家。他们特别专注于编程,并学习统计学以成为数据科学家。当然,他们也可以从事研究领域的工作,但我发现他们通常在某些特定领域工作,为业务提供价值(而不是专注于研究)。

“所有其他人”指的是那些通过不同背景成为数据科学家的其他人。这些人拥有丰富的领域知识,并学习编程和统计学,以将数据科学应用于他们的领域。例如,作为一个兼职数据科学家,我毕业于机械工程专业,并学习了统计学和编程,将数据科学应用于我的知识领域(主要是工业领域)。所以,我可以归类为“所有其他人”类别。当然,这些人也可以从事研究,但我发现大多数人从事的是为企业创造价值的工作。

这就是说,我们都知道统计学在数据科学中很重要,但根据我的经验,如果我们在为企业创造价值,我们通常只需掌握基础知识(在某些情况下多了解一点)即可,因为我们不是研究人员。

请不要误解我的意思:我并不是贬低研究的价值与商业的价值。即便我也通过一些合作在某种程度上贡献于研究:所以我可以看到贡献于研究和商业之间的区别。这只是我的观点。

所以,这是一个有争议的观点:p-values 在我们进行高级统计分析时,尤其是使用科学方法时,更具意义。特别是在贡献于研究时。我意思是,科学方法——正如其名称所示——是一种由一些简单步骤组成的方法:

  • 确定要解决的问题。

  • 提出解决问题的假设。

  • 解决实际问题。

很简单,不是吗?其实并非如此:这主要取决于领域和问题。例如,我们都知道科学中存在一些未解的问题或仅部分解决的问题。例如,Navier-Stokes 方程目前只能在一些精确且特定的假设下求解。一般情况目前尚未解决。实际上,准确地说:目前没有人证明 Navier-Stokes 方程的解存在,并且如果存在,它是否唯一(如果我的记忆没有错误的话:如果我错了,请告诉我)。

但关键在于:在科学中,我们总是提出假设。记住我们的代数和分析课程:当我们的教授教我们定理时,他们总是从一个问题开始,展示假设,并在假设的基础上解决问题。

现在,关于 p-values 的问题,如上所述,是(引用):

通常使用的统计显著性阈值是 p-value 为 0.05。这个值是传统的,也是任意的。它没有传达任何关于效应大小的有意义的证据。

所以,根据这一声明,我的经验告诉我,这种方法更适用于与研究和高级数学相关的数据科学应用。例如,在生物学、医学、粒子物理学等领域。

在这些领域,事实上,科学方法对于得出结论非常重要,因为我们需要遵循一些标准化的方法,以便我们的工作可以与他人的工作进行比较。通常因为结论被发表在科学论文中,我们需要严格的方法来展示我们的结果。

但让我们说实话:今天的数据科学远不止于研究。这就是为什么我告诉你,在所有需要将数学和统计应用于“日常”案例的情况中,我们通常需要一些基础统计知识。而且,当我们得出结果时,重要的是结果本身,因为它能满足一些业务需求,这些需求不需要科学验证。

所以,这里是我们在这些情况下可以做的事情,而不是使用p 值

数据科学家可以使用什么来代替 p 值

数据科学是一个今天甚至被用来通过数据为企业提供一些见解的领域,通常得益于机器学习进行预测。

为此,我们可以利用“点查”方法,例如,这是一种非常简单的方法,其工作方式如下:

  • 我们需要通过机器学习进行预测来解决业务问题。

  • 我们获取数据,清理数据,并将其划分为训练集和测试集。

  • 我们在训练集上测试 3-5 个机器学习模型,并从中选择表现最好的 2-3 个模型。

  • 我们调整在训练集上表现良好的 2-3 个机器学习模型的超参数,并在测试集上测试它们。

  • 我们决定哪一个 2-3 个模型表现最好。

因此,根据这种方法,我们可以通过选择一组机器学习模型来解决业务问题。这样,如果我们使用p 值,我们应该计算一个机器学习模型的p 值,测试它,找到结果,查看不满意的结果,然后更换机器学习模型。

因此,考虑到p 值不能说明结果的任何信息,为什么要在“非严格科学环境”中使用它们呢?对我来说,这没有太大意义……

此外,我们通常在数据上使用多个机器学习模型的事实与所谓的**“无免费午餐定理”**(NFL)有关。该定理声明(引自维基百科):

任何两个优化算法在其性能平均到所有可能问题时都是等效的

这意味着一个算法在特定的机器学习问题上表现非常好,但这并不意味着它在另一个问题上表现也会同样好,因为相同的假设可能不适用。

换句话说,一些算法在某些类型的问题上可能表现优于其他算法,但每个算法由于其先验假设都有优缺点。

所以,这里有一个基本概念要记住:我们不能仅仅因为在先前类似问题上取得了良好表现,就将一个机器学习模型应用到一个新问题上,因为这意味着会对解决方案产生偏见。

这就是为什么我们在选择最佳模型之前,最好在同一数据集上测试不同的 ML 模型。我们不能仅仅因为它在类似问题上有效就使用一个模型,因为这样会偏向我们的解决方案。

Python 中的一个示例

所以,让我们在 Python 中做一个示例。为了学习的目的,我们创建了一个由三次多项式生成的简单数据集(多么大的剧透!)。然后,我们对数据集进行缩放并将其拆分为训练集和测试集:

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
from sklearn.preprocessing import PolynomialFeatures

# Set random seed for reproducibility
np.random.seed(42)

# Generate some random data
n_samples = 1000
X = np.random.uniform(-10, 10, size=(n_samples, 5))
y = 3*X[:,0]**3 + 2*X[:,1]**2 + 5*X[:,2] + np.random.normal(0, 20, n_samples)

# Create a pandas DataFrame
df = pd.DataFrame(X, columns=['x1', 'x2', 'x3', 'x4', 'x5'])
df['y'] = y

# Fit a 3-degree polynomial regression model
X = df[['x1', 'x2', 'x3', 'x4', 'x5']]
y = df['y']
poly_reg = LinearRegression()
poly_reg.fit(X ** 3 + X ** 2 + X, y)

# Calculate the R-squared value
y_pred = poly_reg.predict(X ** 3 + X ** 2 + X)
r2 = r2_score(y, y_pred)

# Split into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

现在,我们将把线性回归模型拟合到X_train数据集,并使用statsmodels.api包计算统计摘要,其中包括p-values

import statsmodels.api as sm

# Add a constant term to X_train
X_train_with_const = sm.add_constant(X_train)

# Fit linear regression model with statsmodels
lin_reg_sm = sm.OLS(y_train, X_train_with_const).fit()

# Print summary of the model
print(lin_reg_sm.summary())

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

线性回归模型的统计摘要(注意:由于

ML 的随机性。图像由 Federico Trotta 提供。

使用普通最小二乘法,我们可以获得关于模型的大量统计信息,包括 R²和调整后的 R²。如果你不知道我们所说的是什么,可以阅读我的文章:

## 掌握回归分析的艺术:每个数据科学家应该知道的 5 个关键指标

这是关于回归分析中使用的指标的所有知识的权威指南

[towardsdatascience.com

此外,上述摘要给出了在某个置信区间(0.025, 0.975,即 2.5%、97.5%)下计算的p-values。特别是,我们对“t”和“P>|t|”列感兴趣。

让我解释一下:

  • 首先,我们可以看到这些值是针对每个特征(x1, x2, x3, x4, x5)计算的,包括常数值(const)。

  • “t”列衡量估计系数在零假设下距离其假设值多少个标准差。t 统计量的绝对值越大,相应系数在预测目标变量时就越显著。

  • “P>|t|”列表示每个系数的p-value。我们说低p-value表示相应的系数在统计上显著,而高p-value则表明其不显著。理想情况下,我们知道统计显著性的标准是:p-values < 0.05。

所以,在这种线性回归模型的情况下,许多特征看起来很显著。很好!所以,让我们看看一个二次和一个三次多项式,看看会发生什么。

为此,我们需要将我们的领域转换为二次和三次模型,并拟合线性回归模型。然后,我们这样打印摘要:

#creating quadratic and cubic features
quadratic = PolynomialFeatures(degree=2)
cubic = PolynomialFeatures(degree=3)

X_quad = quadratic.fit_transform(X_train) #quadratical transformation
X_cubic = cubic.fit_transform(X_train) #cubical tranformation

# Add a constant term to X_train
X_train_with_const_quad = sm.add_constant(X_quad)
X_train_with_const_cub = sm.add_constant(X_cubic)

# Fit polynomial regression models with statsmodels
quad_reg_sm = sm.OLS(y_train, X_train_with_const_quad).fit()
cub_reg_sm = sm.OLS(y_train, X_train_with_const_cub).fit()

# Print summary of the model
print(quad_reg_sm.summary())
print(cub_reg_sm.summary())

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

二次回归模型的统计摘要(注意:由于

机器学习的随机性质)。图像由费德里科·特罗塔提供。

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

三次回归模型的统计摘要(注意:由于

机器学习的随机性质)。图像由费德里科·特罗塔提供。

首先,多项式模型比线性模型有更多的特征,因为多项式模型的公式是:

多项式模型的公式。作者撰写,嵌入-dot-fun 提供技术支持。

所以这个公式在线性模型的公式中添加了多项式项。

所以,对我们的结果进行评论,我们在 R² 和调整后的 R² 上有所改进,但根据 p-values,许多特征似乎并不具有统计显著性。特别是,三次多项式的 R²=1(当然!我们用三次多项式创建了数据集,所以……一切都符合!),但许多特征似乎并不具有统计显著性。

现在,让我问你一个问题:根据这些统计数据,你会选择哪个模型?线性模型看起来很不错,不是吗?

所以,这里是问题:正如我们所说,使用 p-values 并不能保证结果。

此外,考虑到我们已经用 3 次多项式构建了这个数据集,几乎所有特征都没有统计显著性,这怎么可能呢?嗯,很难说。我们只知道模型的一个或多个假设没有得到尊重(多项式模型的假设与线性模型相同;你可以在这篇文章中找到)。但在这些情况下,多重共线性通常是最可能的原因。

现在,让我们使用抽样检查方法来解决这个 ML 模型。记住,线性回归模型没有超参数,所以我们可以直接将其(以及多项式模型)拟合到测试集上:

**NOTE:**

for the sake of clarity, we are using again the 2-degree and 3-degree
polynomial transformation, even if we shouldn't if we were using
a Jupyter Notebook (we've already done the transformation above).
# Fit linear regression model to the train set
lin_reg = LinearRegression().fit(X_train, y_train)

# Create quadratic and cubic features
quadratic = PolynomialFeatures(degree=2)
cubic = PolynomialFeatures(degree=3)

X_quad = quadratic.fit_transform(X_train) #quadratical transformation
X_cubic = cubic.fit_transform(X_train) #cubical tranformation

# Fit quadratic and cubic transformed set
quad_reg = LinearRegression().fit(X_quad, y_train)
cubic_reg = LinearRegression().fit(X_cubic, y_train)

# Calculate R² on test set
print(f'Coeff. of determination linear reg test set:{lin_reg.score(X_test, y_test): .2f}')
print(f'Coeff. of determination quadratic reg test set:{quad_reg.score(quadratic.transform(X_test), y_test): .2f}') 
print(f'Coeff. of determination cubic reg test set:{cubic_reg.score(cubic.transform(X_test), y_test): .2f}')

>>>

  Coeff. of determination linear reg test set: 0.81
  Coeff. of determination quadratic reg test set: 0.81
  Coeff. of determination cubic reg test set: 1.00

所以,我们为所有模型获得了高 R² 值。特别是,三次多项式在训练集和测试集上都有 R²=1。这应该告诉我们一些事情……

现在,让我们在测试集上验证我们的模型,即使使用 KDE 图。如果你不知道 KDE 模型是什么以及如何使用它,你可以阅读我在这里的文章:

## 精通线性回归:有志数据科学家的权威指南

你需要知道的线性回归的所有信息都在这里(包括 Python 中的应用)

[towardsdatascience.com

我们可以这样使用它们:

#Kernel Density Estimation plot
ax = sns.kdeplot(y_test, color='r', label='Actual Values') #actual values
sns.kdeplot(y_test_pred_lin, color='b', label='Predicted Values', ax=ax) #predicted values

#showing title
plt.title('Actual vs Predicted values for linear model')
#showing legend
plt.legend()
#showing plot
plt.show()

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

线性模型的 KDE 图。图片来源于费德里科·特罗塔

#Kernel Density Estimation plot
ax = sns.kdeplot(y_test, color='r', label='Actual Values') #actual values
sns.kdeplot(y_test_pred_quad, color='b', label='Predicted Values', ax=ax) #predicted values

#showing title
plt.title('Actual vs Predicted values for quadratic model')
#showing legend
plt.legend()
#showing plot
plt.show()

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

二次方模型的 KDE 图。图片来源于费德里科·特罗塔

#Kernel Density Estimation plot
ax = sns.kdeplot(y_test, color='r', label='Actual Values') #actual values
sns.kdeplot(y_test_pred_cub, color='b', label='Predicted Values', ax=ax) #predicted values

#showing title
plt.title('Actual vs Predicted values for the cubic model')
#showing legend
plt.legend()
#showing plot
plt.show()

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

三次方模型的 KDE 图。图片来源于费德里科·特罗塔

所以,通过观察 KDE,我们可以说三次方模型显然过拟合了数据(但即使因为训练集和测试集的 R²都为 1,我们也可以这样判断。不过,再次提醒:我们在这里发现了一些明显的东西。发现明显的事情是好的,因为我们知道自己做得很好!)。

此外,即使我们在线性和二次方模型的两个数据集上得到了非常好的 R²值,KDE 也清楚地告诉我们这些模型并不适合解决这个机器学习问题。因此,我们应该研究其他模型。

最后,给一个最终建议,如果我们真的想计算p-values以确保我们的模型符合假设,我们可以在最后进行计算(所以我们只会为我们认为是最佳的模型计算它们)。

但请记住:基于p-values,线性模型可能是解决这个机器学习问题的一个好选择,而 KDE 却告诉我们相反的结果!

结论

感谢阅读这篇文章:我非常希望在评论中听到你的意见。

让我总结一下这些观点:

  • p-values的使用在某种程度上是一个有争议的话题。它有助于测试我们的假设,但正如 ASA 所说,它并不能保证结果。

  • 我个人认为p-values更适合科学研究,在那里重要的是展示我们在得出某些结果时使用了严格的方法(记住,正如 ASA 所说,结果不能仅仅依赖于p-values)。

  • 考虑到我们需要在给定的数据集上测试不同的机器学习模型,以验证无免费午餐定理,当提供业务价值时,实际上不需要使用p-values来为我们的结果提供科学依据。无论如何,如果我们想使用它们,可以在最后测试假设,以展示我们选择的模型符合假设。

  • 订阅 我的新闻通讯 以获取更多关于 Python 和数据科学的内容。

  • 觉得有用吗? 请给我买一杯 Ko-fi

  • 喜欢这篇文章?通过 我的推荐链接加入 Medium: 每月 5 美元(无额外费用)解锁 Medium 上的所有内容。

  • 想联系我?请在 这里

AI 中解释性的渐变的必要性

原文:towardsdatascience.com/the-necessity-of-a-gradient-of-explainability-in-ai-743ee0bcb848

过多的细节可能让人不堪重负,而不足的细节则可能产生误导。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 凯文·贝尔蒙特博士

·发表于 数据科学的未来 ·4 分钟阅读·2023 年 7 月 29 日

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

图片由 No Revisions 提供,发布在 Unsplash

任何足够先进的技术都与魔法无异” — 阿瑟·克拉克

随着自动驾驶汽车、计算机视觉和最近的大型语言模型的发展,科学有时会让人觉得像魔法一样!模型每天都在变得越来越复杂,当试图向新受众解释复杂模型时,很容易挥手一抹,随口说点关于反向传播和神经网络的话。然而,有必要描述一个 AI 模型、其预期影响和潜在偏见,这就是可解释 AI 的作用所在。

在过去十年中,AI 方法的爆炸式增长使得用户接受他们得到的答案而不加质疑。整个算法过程通常被描述为黑箱,即使是开发它的研究人员,也不总是直接或甚至可能理解模型如何得出特定结果。为了建立用户的信任和信心,公司必须描述它们所采用系统的公平性、透明度和基本决策过程。这种方法不仅导致对 AI 系统的负责任态度,而且增加了技术的采纳 (www.mckinsey.com/capabilities/quantumblack/our-insights/global-survey-the-state-of-ai-in-2020)。

AI 解释性中最困难的部分之一是明确界定正在解释的内容的边界。高管和 AI 研究人员对信息的需求和接受度不同。找到在简单解释和所有可能路径之间的合适信息层次需要大量的训练和反馈。与普遍观点相反,去除数学和复杂性的解释并不会使其毫无意义。确实存在过度简化的风险,可能会误导对方认为他们对模型及其功能有深入理解。然而,运用正确的技术可以在适当的层次上提供清晰的解释,从而引导对方向数据科学家等进一步询问以增加知识。这个过程的关键在于进行有效的对话和沟通,以确保必要的信息得到传达。

如何获得有效沟通的经验?与普遍观点相反,获得解释经验并不需要达到高级职位。虽然确实解释复杂概念的技能通过试错过程随着时间的推移而提高,但初级员工往往在这方面非常有效,因为他们刚刚学习了相关内容。关键是通过实践获得向非技术观众解释的经验,任何人都可以做到这一点,而不需要等待成为高级员工。事实上,理解复杂概念并能够向非技术观众解释这些概念并不互相排斥。要提高这一技能,唯一的方法就是:实践、实践、再实践。

解释复杂概念可能因被称为知识诅咒的因素而具有挑战性。需要从不同角度反复讲解以创造持久的记忆。生成性 AI 通过大型语言模型正变得越来越普及,这也产生了对理解的需求。虽然有关于 ChatGPT 提供错误信息的担忧,但理解其原因对于掌握技术的能力和局限性是很重要的。我们都熟悉手机和电子邮件中的预测文本,大型语言模型的工作原理也是如此,只是规模更大。像我们十年前的手机一样,它们并不总能正确预测下一个词。回顾技术的众多进步,很明显一切都是渐进的,利用这种渐进性是解释否则看似魔术的概念的关键。

AI 中的可解释性不仅在向他人解释概念时很重要;在现有的机器学习模型中加入可解释性也可能具有挑战性。在决定选择哪种模型时,应考虑需求和最终用户,以确保在复杂模型和可解释性之间进行权衡。有时,线性回归的简单性胜过更复杂模型的复杂性。对某人生活产生重大影响的决策,例如授权银行贷款,需要解释。特别是当模型的输出不是期望结果时,信息尤为宝贵。在这种情况下,拥有可解释性流程可以揭示模型或使用的训练数据中的缺陷。

总结来说,AI 中的可解释性发生在不同的阶段。向最终用户解释概念,以确保他们理解潜在的局限性。向同行和非技术观众解释模型,以了解算法的详细情况。解释模型应用结果的决策,以确保符合规定且不存在隐性偏见。这三个方面对 AI 的发展都至关重要,如果这些方面中的一个对你正在解决的问题来说过于复杂,那么可能需要考虑所用模型是否是最合适的。

如果你喜欢这个故事,请不要犹豫地点赞或在评论中与我联系!关注我在Medium的账号,获取更多关于数据科学的内容!

新的最佳 Python 包用于可视化网络图

原文:towardsdatascience.com/the-new-best-python-package-for-visualising-network-graphs-e220d59e054e

一份指南,介绍谁应该使用它,何时使用,如何使用,以及我之前的错误…

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

·发布于 Towards Data Science ·10 分钟阅读·2023 年 11 月 23 日

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

图片由Chris Ried拍摄,来源于Unsplash

介绍

在这篇文章中,我将向你介绍一个我偶然发现的 Python 包,依我拙见,它是目前为止我见过的最佳网络图可视化工具。

需要紧凑且强大的可视化包来进行快速原型设计、探索性数据分析或调试网络模型的数据科学家最适合阅读下面的内容。

我们将要检查的包叫做:gravis

[## gravis — gravis 0.1.0 文档

编辑描述

robert-haas.github.io](https://robert-haas.github.io/gravis-docs/?source=post_page-----e220d59e054e--------------------------------)

我个人在日常工作中经常使用图神经网络,坦白说,我很烦恼之前没有早些知道这个包,因为它本可以节省我很多时间和精力,避免了在使用我之前提到的那些包(ipysigmapyvis)时遇到的不足。

[## 绘制互动网络图的两个最佳工具

一份指南,说明如何使用它们,何时使用它们,以及谁应该使用它们。

medium.com](https://medium.com/@bl3e967/the-two-best-tools-for-plotting-interactive-network-graphs-8d352aa894d4?source=post_page-----e220d59e054e--------------------------------)

什么使网络可视化软件包成为最佳?

一个可视化软件包需要具备:

  • 创建一个完全交互的可视化,其中我可以点击节点和边并查看其属性,还可以拖放它们。

  • 方便实现——不需要太多代码(像 Dash 那样),但对大多数用例来说足够强大和灵活。

  • 对节点和边的数量具有适度的良好扩展性——我们不是在做生产级别的东西,但我们需要它至少能处理几百个节点。

  • 兼容 Python 中常用的网络包,如networkx

我们将对什么进行测试?

广义地说,我们可以根据图是否是同质的或异质的,或者是否有向或无向边来对图进行分类。

因此,我们将对使用networkx生成的两种类型的图进行测试。

(1)一个同质的无向图

(2)一个异质的有向多重图

因为这代表了可能遇到的两个极端。如果你不熟悉这些术语,我建议你访问我的上一篇文章并快速阅读介绍部分。

TL;DR

  • 同质 = 1 种类型的节点

  • 异质 = 多种类型的节点和/或边

  • 无向 = 边没有方向

  • 有向 = 边有方向

  • 多重图 = 两个节点之间可以有多条边

设置和安装

该软件包可以通过 pip 简单安装:

pip install gravis

我们还需要安装以下软件包以生成测试图。

pip install numpy, matplotlib, networkx

你还可以在这个仓库中找到我使用的所有代码。

[## GitHub - bl3e967/medium-articles: 我在 Medium 文章的附带代码。

我在 Medium 文章的附带代码。通过创建一个账户来贡献 bl3e967/medium-articles 的开发…

github.com](https://github.com/bl3e967/medium-articles?tab=readme-ov-file&source=post_page-----e220d59e054e--------------------------------)

同质无向网络示例

所以,为了开始,我们需要一个图来绘制。我们将编写一个简单的图生成器函数,它将返回一个networkx.Graph对象。我们将向其节点和边添加属性,以模拟数据科学家在工作中可能看到的数据。

图生成器

我们使用一个随机图生成器,我选择了networkx.dual_barabasi_albert_graph方法来模拟一个无尺度网络。

我们添加了节点级别的属性,例如degreebetweenness_centrality,以及一些用随机数字生成的虚构特性,我们称之为feature1feature2feature3

我们对边也做了相同的处理,并添加了特性feature1feature2

我们最终为每个节点标上uuidUniversally Unique IDentifier),使其看起来更像真实数据。

def get_new_test_graph():
    NUM_NODES = 50
    p = 0.5
    seed = 1
    test_graph = nx.dual_barabasi_albert_graph(n=NUM_NODES, p=p, seed=seed, m1=2, m2=1)

    # add node properties
    nx.set_node_attributes(test_graph, dict(test_graph.degree()), name='degree')
    nx.set_node_attributes(test_graph, nx.betweenness_centrality(test_graph), name='betweenness_centrality')

    for node, data in test_graph.nodes(data=True):
        data['node_identifier'] = str(uuid.uuid4())
        data['feature1'] = np.random.random()
        data['feature2'] = np.random.randint(0, high=100)
        data['feature3'] = 1 if np.random.random() > 0.5 else 0

    # add edge properties
    for _, _, data in test_graph.edges(data=True):
        data['feature1'] = np.random.random()
        data['feature2'] = np.random.randint(0, high=100)

    return test_graph

当我们使用networkx绘制图形时,我们会得到如下结果:

test_graph = get_new_test_graph()
nx.draw(test_graph)

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

50 节点的测试图,均匀且无向。

使用 gravis 绘图

现在我们开始使用gravis绘制这个图。使用这个包非常简单,完整的效果如下。

import gravis as gv 

gv.d3(
    test_graph, 

    # graph specs
    graph_height=500,

    # node specs
    node_size_data_source="betweenness_centrality",
    use_node_size_normalization=True,
    node_size_normalization_min=15,
    node_size_normalization_max=35,
    show_node_label=True,
    node_label_data_source='node_identifier',

    # edge specs
    edge_size_data_source='feature1',
    use_edge_size_normalization=True,
    edge_size_normalization_min=1,
    edge_size_normalization_max=5,

    # force-directed graph specs
    many_body_force_strength=-500
)

让我们将其拆分为几个部分。

假设我们想根据节点的betweenness_centrality值来缩放节点大小,并根据边的feature1值来缩放边的厚度。

我们设置use_node_size_normalization=True,以便节点大小根据betweenness_centrality的归一化值进行设置,并定义node_size_normalization_minnode_size_normalisation_max来设置我们希望的最小和最大节点大小。

 # node specs
    node_size_data_source="betweenness_centrality",
    use_node_size_normalization=True,
    node_size_normalization_min=15,
    node_size_normalization_max=35,

我们使用等效的参数来控制边的厚度:

 # edge specs
    edge_size_data_source='feature1',
    use_edge_size_normalization=True,
    edge_size_normalization_min=1,
    edge_size_normalization_max=5,

最后,我将many_body_force_strength参数设置为-500,使边的长度比默认值更长,以使图形更清晰可见。

结果图如下所示。

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

我们的均质无向图通过 gravis 进行可视化

添加颜色

除了按照betweenness_centrality缩放节点大小外,我还希望根据此进行着色。

我们可以通过简单地向节点添加color属性来实现这一点。我可以使用命名颜色,如‘red’,‘blue’,‘green’,在这里我不会做这个,因为这太简单了。让我们尝试使用颜色比例。

我想根据matplotlib中的winter颜色图来缩放这些值。

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

低中心性值将被映射为蓝色,高中心性值将被映射为绿色。

我有一个非常有用的MplColorHelper类,我在项目中使用过很多次,它可以将数值转换为RGB字符串。

class MplColorHelper:

    def __init__(self, cmap_name, start_val, stop_val):
        self.cmap_name = cmap_name
        self.cmap = plt.get_cmap(cmap_name)
        self.norm = mpl.colors.Normalize(vmin=start_val, vmax=stop_val)
        self.scalarMap = cm.ScalarMappable(norm=self.norm, cmap=self.cmap)

    def get_rgba(self, val):
        return self.scalarMap.to_rgba(val, bytes=True)

    def get_rgb_str(self, val):
        r, g, b, a = self.get_rgba(val)
        return f"rgb({r},{g},{b})"

我只需要指定我们希望缩放颜色图的最小和最大值。

所以,要根据betweenness_centrality着色节点,我们可以如下操作:

# the matplotlib colourmap we want to use
CM_NAME = "winter"

# initialise colour helper
vals = nx.get_node_attributes(test_graph, 'betweenness_centrality').values()
betweenness_min, betweenness_max = min(vals), max(vals)
node_colors = MplColorHelper(CM_NAME, betweenness_min, betweenness_max)

# get rgb string for each node
for node, data in test_graph.nodes(data=True):
    data['color'] = node_colors.get_rgb_str(data['betweenness_centrality'])

对于边,我们可以根据feature1来着色它们。

# initialise colour helper 
vals = nx.get_edge_attributes(test_graph, 'feature1').values()
val_min, val_max = min(vals), max(vals)
edge_colors = MplColorHelper(CM_NAME, val_min, val_max)

# get rgb string for each node
for u, v, data in test_graph.edges(data=True):
    data['color'] = edge_colors.get_rgb_str(data['feature1'])

完成了,让我们来添加颜色:

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

同质无向网络的节点和边的颜色

最后,gravis允许我们使用可视化底部的信息栏显示每个节点或边上存储的任何自由文本。

我们将使用它来显示我们的特征值——我们将特征值格式化为一些文本,并保存到名为click的属性中:

# node features
for node, data in test_graph.nodes(data=True):
    data['click'] = (
        f"Node: {data['node_identifier']}"
        "\nNode Features:" +
        f"\nfeature 1: {data['feature1']:.3f}" + 
        f"\nfeature 2: {data['feature2']:.3f}" + 
        f"\nfeature 3: {data['feature3']:.3f}" + 
        f"\nBetweenness Centrality: {data['betweenness_centrality']:.3f}" + 
        f"\nDegree: {data['degree']}"
    )

# edge features
for u, v, data in test_graph.edges(data=True):
  data['click'] = (
        f"Edge: {test_graph.nodes[u]['node_identifier']} -> {test_graph.nodes[v]['node_identifier']}" +
        f"\nEdge Features:" + 
        f"\nfeature 1: {data['feature1']}" + 
        f"\nfeature 2: {data['feature2']}"
    )

现在我们能够通过屏幕底部的面板非常好地显示我们的特征值(我把图形做得特别大,以便你可以像在屏幕上看到的那样看到它)。

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

显示在底部面板中的节点特征详细信息的可视化。

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

显示在底部面板中的边特征详细信息的可视化。

我们有一个完全互动的可视化,允许我们拖动节点,并且有一个侧边栏用于更改节点和边的可视化设置、标签和布局算法。

它还允许你使用设置栏将可视化导出为图像——无需额外代码!最后,如果你希望与他人分享这个互动图,你可以将其导出为自包含的 HTML 文件:

fig = gv.d3(test_graph, *args, **kwargs)
fig.export_html("graph_to_export.html")

异质有向网络示例

我们现在尝试使用gravis可视化一个异质有向网络。

图生成器

再次,我们需要一个函数来返回这样的图。我们将使用之前的相同函数,但这次使用nx.scale_free_graph函数。

我们还添加了一个node_type属性来模拟异质图。前 25 个节点将是node_type = 0,其余的将是node_type = 1

def get_new_test_digraph():
    NUM_NODES = 50
    # We change the graph generator function here
    test_graph = nx.scale_free_graph(n=NUM_NODES, seed=0, alpha=0.5, beta=0.2, gamma=0.3)

    # add node properties
    nx.set_node_attributes(test_graph, dict(test_graph.degree()), name='degree')
    nx.set_node_attributes(test_graph, nx.betweenness_centrality(test_graph), name='betweenness_centrality')

    for node, data in test_graph.nodes(data=True):

        # assign node type so we have heterogeneous graph
        data['node_type'] = 0 if node < 25 else 1

        # same as before, a add ther node features.
        data['node_identifier'] = str(uuid.uuid4())
        data['feature1'] = np.random.random()
        data['feature2'] = np.random.randint(0, high=100)
        data['feature3'] = 1 if np.random.random() > 0.5 else 0

    # add edge properties
    for u, v, data in test_graph.edges(data=True):
        data['feature1'] = np.random.random()
        data['feature2'] = np.random.randint(0, high=100)

    return test_graph

使用nx.draw绘制得到如下图:

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

异质有向多图,编号以显示哪些节点属于哪种类型。

使用 gravis 绘图

我们对异质图的绘制方式与上述完全相同。我们可以使用相同的方法:

  • 生成测试多有向图

  • 为节点和边添加特征值

  • 根据属性值为节点和边添加颜色

现在我们需要做的就是指定每个节点的形状,因为现在我们处理的是多种不同的节点类型。

对于我们的图生成函数get_new_test_digraph,我们只需要在遍历节点的for循环中添加这一行代码:

for node, data in test_graph.nodes(data=True):

    data['node_type'] = 0 if node < 25 else 1 # add this line 

对于模拟实际数据的目的,我们将图中的前 25 个节点设置为node_type = 0,其余为node_type = 1

接下来,我们可以使用shape属性在 gravis 中指定我们想为每个节点使用的形状。

在这里,我们将node_type = 0设置为圆形,将node_type = 1设置为矩形。

for node, data in test_graph.nodes(data=True):
    data['value'] = data['betweenness_centrality'] # node size
    data['label'] = data['node_identifier'] 
    data['title'] = (
        f"Node: {data['node_identifier']}"
        "\nNode Features:" +
        f"\nfeature 1: {data['feature1']}" + 
        f"\nfeature 2: {data['feature2']}" + 
        f"\nfeature 3: {data['feature3']}" + 
        f"\nBetweenness Centrality: {data['betweenness_centrality']}" + 
        f"\nDegree: {data['degree']}"
    ) 
    data['color'] = node_colors.get_rgb_str(data['betweenness_centrality'])

    ## add this line to specify shape. 
    data['shape'] = 'dot' if data['node_type'] == 0 else 'rectangle'

我们现在准备在gravis中绘制我们的网络。注意我们添加了edge_curvature参数,使其不为零。这是为了防止当节点很多时,两个节点之间的边重叠。

 gv.d3(
    test_graph, 

    graph_height=700,

    node_size_data_source="betweenness_centrality",
    use_node_size_normalization=True,
    node_size_normalization_min=15,
    node_size_normalization_max=35,
    show_node_label=False,
    node_label_data_source='node_identifier',

    edge_size_data_source='feature1',
    use_edge_size_normalization=True,
    edge_size_normalization_min=1,
    edge_size_normalization_max=5,

    # Specify curvature to differentiate between the multiple
    # edges between two nodes.
    edge_curvature=-0.5,

    many_body_force_strength=-500
)

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

在 gravis 中绘制的 MultiDiGraph,边的曲率和形状根据节点类型设置。

完美!简单方便。你可以看到图左侧和顶部一些节点之间的多个连接。

总结——为什么我认为 Gravis 是最好的

我已经提到过我写了另外两个包,我坚信它们是最好的——pyvisipysigma。当时我对此深信不疑,因为我自己在日常工作中一直在使用它们。

然而,它们各自都有独特的问题,事后看来,这使得它们的效果不尽如人意,这也是我在同一个博客中讨论这两者的原因!根据使用场景,它们中有一个比另一个更好,我建议用户在不同情况下使用哪个。

这就是为什么我在发现gravis时感到震惊,因为它似乎有人完全按照相同的思路开发了这个包,结合pyvisipysigma的优点,制作了一个完美的工具。

首先,gravis提供了完全互动的用户界面,你可以:

  • 不仅可以点击节点和边以显示信息,还允许用户拖放节点,这对于需要手动调整物理引擎的复杂网络非常有用(而ipysigma缺乏这一点)。

  • 节点或边的信息通过屏幕上的一个栏展示,该栏整齐地容纳了信息,还允许从中复制信息(这是一个小但非常重要的功能,pyvis中缺乏这一点,这让我在工作中非常困扰)。

  • 提供了一个不同的侧边栏,通过它你可以调整物理引擎参数,改变节点和边的可视化设置,并通过按钮将图形导出为图像。

  • 另外,它可以显示节点之间的多个边(再次说明,ipysigma无法做到这一点)。

因此,gravis消除了在pyvisipysigma之间进行选择的必要性,因为它将这两个包合并为一个,同时保持了它们的所有优点。

简而言之,它满足了所有要求,并且表现出色。

我强烈推荐这个包。

在评论区告诉我你的想法,如果你喜欢我的文章,请鼓掌或者分享给可能感兴趣的人。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值