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

原文:TowardsDataScience

协议:CC BY-NC-SA 4.0

为什么我作为数据科学家要学习 JavaScript

原文:towardsdatascience.com/why-im-learning-javascript-as-a-data-scientist-e2b87bcdac03

以及为什么感觉我在转向黑暗面

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

·发布于 Towards Data Science ·6 分钟阅读·2023 年 11 月 4 日

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

这有点像我的 JavaScript 代码。图片由 Towfiqu barbhuiyaUnsplash 提供

现在是 2023 年,Python 的公众热度无法再高了。

我们已经有 Python 脚本 在火星上运行,以及 pandas DataFrames 随意帮助 解决 NHS 危机

但如果我告诉你 Python 并不是数据科学中唯一有用的语言呢?

(我也不是在说 R 或 Julia)。

在 Python 原教旨主义者拿起火把和叉子之前,请听我说。

在过去几个月里,我一直在探索 JavaScript 的魔力,在这篇文章中,我将给出两个理由,说明我为什么要投资 JavaScript,以及为什么我觉得自己在使用它时像是在与黑暗面调情。

原因 #1: 我想用 D3.js 构建酷炫的可视化

你听说过 D3.js 吗?

这是一种用于构建定制数据可视化的 JavaScript 库。当我说“定制”时,我指的是 花里胡哨的,我可能会开始翩翩起舞 的可视化。

我最喜欢的使用场景是 scrollytelling

Scrollytelling,一个将“滚动”和“讲故事”结合起来的术语,是一种动态讲述多媒体故事的方式,这些故事随着你的滚动而展开—— G2

使用像 D3.js 和 Scrollama.js 这样的库,你可以在用户滚动网页时让数据/图表动起来。

这是一个我使用 Google 的 Covid-19 社区流动报告 公共数据构建的例子:

在视觉上,我认为滚动条是一种了不起的叙事媒介。我喜欢能够将读者的注意力集中在可视化的特定部分,并将他们沉浸在我讲述的故事中的想法。这肯定比我那令人厌烦的橙色和绿色 matplotlib 条形图要好得多。

D3.js 的附加好处是你可以构建可以直接部署到网站上的可视化。如果你使用像 matplotlib/ggplot2 这样的包或像 Power BI/Tableau 这样的软件来构建可视化,你就依赖于使用其他工具将你的可视化放到线上。这并不是坏事(D3.js 的学习曲线比这些工具陡峭得多),但它确实限制了你对可视化的操作。

D3 可视化没有这个问题;它们是完全可定制的,可以以你喜欢的方式嵌入网页。例如,我上面的滚动条中的图表是通过一个简单的 figure HTML 标签 (id="myPlot") 调用并嵌入到常规网页中的。

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

图片由作者提供

如果你有兴趣学习如何构建像这样的滚动叙事作品,我建议你查看 freeCodeCamp.org 的免费 D3.js 课程 和 Russell Goldenberg 的 Scrollama.js 仓库。为了获得灵感,我还强烈推荐查看 这个 由 Heshan Eissa 和 Lindsey Poulter 制作的不可思议的 Ben 和 Jerry 的主题滚动条。

理由 #2:我想成为一名“全栈数据科学家”

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

图片由作者提供

在数据科学领域工作的一件奇怪的事情是,你经常是机器中的一个小齿轮。你在组织中扮演着重要的角色,但这是一个高度专业化的角色,你非常依赖其他团队来使你的工作变得“可操作”。

我什么意思呢?你可能需要:

1. 数据工程师为你获取原始数据,

2. ML 工程师将你的模型投入生产,并

3. 软件工程师将这些模型的输出嵌入到面向客户的产品中。

这些依赖关系并没有错,但它们可能会创建令人烦恼的瓶颈,因此,许多公司已经开始招聘“全栈数据科学家”。

你问那是什么?这是 Shopify 工程团队的观点:

[…] 全栈数据科学家的范围涵盖从头到尾的数据科学项目,包括:

  • 发现和分析:你如何从多个不同来源收集、研究和解释数据。这个阶段包括识别业务问题。

  • 获取:将数据从各种来源移动到你的数据仓库中。

  • 数据建模:使用批处理、流处理和机器学习工具转换数据的过程。

我喜欢这种思维方式,但我会批评这个定义还不够深入。根据我的经验,这听起来只是一个普通的数据科学家角色!这让我想知道,如果全栈数据科学家应该这样做,那么非全栈的数据科学家应该做什么。

不过,抛开具体定义,我喜欢作为数据科学家发展更广泛技能的精神(超越数据分析和机器学习等基本技能)。而且,或许有争议的是,我认为学习 JavaScript 是实现这一目标的绝佳方式。

为什么?因为(1)学习任何新的编程语言都会让你成为更好的程序员,(2)特别是学习 JavaScript 使你能够接触到一些作为数据科学家通常不会看到的技术栈部分。我说的是用户界面、网站、与某些 API 的交互,以及所有这些内容。通过学习 JavaScript,我积极投资于数据科学工作流上下游的技术栈部分。拥有这些知识对于理解我的工作如何融入更大的图景以及允许我构建自己的全栈项目(如theSQLgym)是无价的。

我是不是要走向黑暗面了?

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

作者提供的图像

当我第一次告诉一个数据科学家朋友我在学习 JavaScript 时,他们无法理解。

完全不。

他们问:“为什么要学习 JavaScript,而不是把时间花在学习更直接与数据科学相关的技能上,比如 Cypher 或计算机视觉?”“或者为什么不花时间提高普通的 Python 技能呢?”

说实话,我实际上不知道这个问题的完整答案。

我想学习这些东西,但我也想推动自己学习新事物,并在技术领域成为一个更全面的“万事通”。从长远来看,我认为这会让我成为一个更出色的数据科学家,但如果我说这是唯一的动机,那我就是在说谎。

我也受到智力好奇心和建立酷炫东西的愿望驱动。建造者就是要建造,对吧?

学习 JavaScript 缺乏与数据科学的即时相关性,使其感觉有点像是转向黑暗面/脱离数据科学的经典范畴。但目前,我仍抱有希望。我觉得学习 JavaScript 会有非常宝贵的收获,值得去追求。

你怎么看?

还有一件事—

我创建了一个免费的通讯,叫做AI in Five,每周分享关于最新 AI 新闻、编码技巧和数据科学家/分析师的职业故事的 5 个要点。没有炒作,没有“数据是新的石油”的废话,也没有来自 Elon 的推文(或者我现在应该说‘x-es’?)——只有实用的技巧和见解,帮助你在职业生涯中发展。

点击这里订阅,如果这对你有吸引力!谢谢阅读。

[## 五分钟了解 AI | Matt Chapman | Substack

最新的新闻、职业故事和来自数据科学与人工智能领域的编程技巧,概述为 5 个要点……

aiinfive.substack.com](https://aiinfive.substack.com/?source=post_page-----e2b87bcdac03--------------------------------)

为什么特征缩放在机器学习中很重要?讨论 6 种特征缩放技术

原文:towardsdatascience.com/why-is-feature-scaling-important-in-machine-learning-discussing-6-feature-scaling-techniques-2773bda5be30

标准化、归一化、鲁棒缩放、均值归一化、最大绝对缩放和向量单位长度缩放

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

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

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

照片由 Mediamodifier 提供,来自 Unsplash

许多机器学习算法需要特征在相同的尺度上。

我们可以在不同场景中选择不同类型的特征缩放方法。它们有不同的(技术)名称。术语特征缩放仅指这些方法中的任何一种。

**Topics
------**
**1\. Feature scaling in different scenarios**

   a. Feature scaling in PCA
   b. Feature scaling in k-means
   c. Feature scaling in KNN and SVM
   d. Feature scaling in linear models
   e. Feature scaling in neural networks
   f. Feature scaling in the convergence
   g. Feature scaling in tree-based algorithms
   h. Feature scaling in LDA

**2\. Feature scaling methods**

   a. Standardization
   b. Min-Max Scaling (Normalization)
   c. Robust Scaling
   d. Mean Normalization
   e. Maximum Absolute Scaling
   f. Vector Unit-Length Scaling

**3\. Feature scaling and distribution of data

4\. Data leakage when feature scaling

5\. Summary of feature scaling methods**

不同场景下的特征缩放

  • 主成分分析中的特征缩放: 在主成分分析中,如果原始特征的相对范围不同,PCA 组件对这些范围非常敏感。PCA 尝试选择能最大化数据方差的组件。如果由于某些特征的范围较大而导致方差最大化,这些特征可能会主导 PCA 过程。在这种情况下,组件可能无法捕捉真实的方差。为避免这种情况,我们通常在 PCA 之前进行特征缩放。然而,有两个例外。如果特征之间的尺度差异不显著,例如一个特征范围在 0 和 1 之间,另一个特征范围在 0 和 1.2 之间,虽然进行特征缩放不会有害,但我们不需要执行特征缩放!如果你通过分解相关矩阵而不是协方差矩阵来进行 PCA,即使特征不是在相同的尺度上测量的,也不需要进行特征缩放。

  • k-means 聚类中的特征缩放: k-means 聚类的主要假设之一是所有特征都在相同的尺度上进行测量。如果不是,我们应该进行特征缩放。k-means 算法计算数据点之间的距离。范围较高的特征可能主导计算,这些计算可能不准确。为避免这种情况,我们需要在 k-means 之前进行特征缩放。缩放特征还会提高 k-means 模型的训练速度。

  • KNN 和 SVM 算法中的特征缩放: 通常,计算数据点之间距离的算法大多受到特征相对范围的影响。KNN 和 SVM 也不例外。范围较高的特征可能会由于其范围较高而贡献更多,但并不是因为其重要性。我们不希望算法在这种方式上产生偏差。因此,我们需要缩放特征,以便它们在距离计算中贡献均等。

  • 线性模型中的特征缩放: 线性模型如线性回归的参数值高度依赖于输入特征的尺度。因此,最好使用在相同尺度上测量的特征。这也会提高线性模型的训练速度。

  • 神经网络中的特征缩放: 我们通常将特征缩放方法应用于输入数据。然而,也可以将特征缩放应用于神经网络中隐藏层的激活值!经过缩放的输出值随后成为下一层的输入。这被称为批量归一化,它能有效消除梯度消失问题和协变量偏移问题,并提高网络在训练过程中的稳定性。它还加快了神经网络模型的训练速度。

  • 算法收敛中的特征缩放: 学习率是决定深度学习和机器学习算法收敛速度的主要因素。特征缩放也对这一点有影响!当特征在相同的尺度上进行测量时,计算可以更快地执行,算法也会更快地收敛!

  • 基于树的算法中的特征缩放: 对于基于树的算法,不需要特征缩放,因为它们对特征的相对尺度不太敏感。流行的基于树的算法包括:决策树、随机森林、AdaBoost、梯度提升、XGBoost、LightGBM 和 CatBoost。

  • LDA 中的特征缩放: 线性判别分析(LDA)是一种线性降维技术,通过最大化分类数据集的类别可分离性来进行降维,而不是通过最大化数据的方差。因此,LDA 对特征的相对范围不敏感,因此不需要对 LDA 进行特征缩放。

特征缩放方法

1. 标准化

标准化是最流行的特征缩放方法,其中我们将值居中于 0 并使标准差为 1。结果是 z-score,因此这种缩放方法也称为 z-score 标准化或归一化。应用标准化到特征后,数据的分布具有均值 0 和标准差 1。这样的分布称为标准正态分布。

要对变量应用标准化,首先,我们需要计算该变量的均值和标准差。然后,从每个值中减去均值,并将结果除以标准差。对于一组特征,这些计算是同时在特征级别上进行的。

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

标准化公式(图片由作者提供)

z-score 或标准化的输出实际上表示一个值偏离均值多少个标准差!

z-score 值不受限于某个特定范围。标准化过程不会受到数据中异常值的影响。

标准化在数据遵循高斯分布或正态分布,或分布未知时特别有用。

在 Scikit-learn 中,可以使用**StandardScaler()**函数进行标准化。

from sklearn.preprocessing import StandardScaler

sc = StandardScaler()
sc.fit(data)
scaled_data = sc.transform(data)

调用 fit()方法时,会计算每个变量的均值和标准差。如果我们需要对数据应用缩放过程,也应调用 transform()方法。

2. 最小-最大缩放(归一化)

最小-最大缩放或归一化是将数据缩放到您选择的特定范围的过程。最常用的范围是(0, 1)。

要对变量应用最小-最大缩放,首先,我们需要找到该变量的最小值和最大值。然后,我们从每个数据值中减去最小值,并将结果除以范围(最大值与最小值的差)。对于一组特征,这些计算是同时在特征级别上进行的。

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

最小-最大缩放公式(图片由作者提供)

最小-最大缩放在数据分布未知或不遵循正态分布时特别有用。

最小-最大缩放过程对数据中的异常值非常敏感。

在 Scikit-learn 中,可以使用**MinMaxScaler()**函数进行最小-最大缩放。

from sklearn.preprocessing import MinMaxScaler

sc = MinMaxScaler(feature_range=(0,1))
sc.fit(data)
scaled_data = sc.transform(data)

调用 fit()方法时,会找到每个变量的最小值和最大值。如果我们需要对数据应用缩放过程,也应调用 transform()方法。

**MinMaxScaler()**函数还提供了更改您选择的范围的选项。默认设置为(0, 1)。

3. 鲁棒缩放

鲁棒缩放也称为分位数缩放,其中我们根据第 1、第 2 和第 3 分位数缩放数据。第 2 分位数是中位数,如您所知。

要对变量应用鲁棒缩放,首先需要找到该变量的分位数。然后,我们从每个数据值中减去中位数(第 2 个分位数或 Q2),并将结果除以 IQR(第 3 个分位数与第 1 个分位数之间的差异)。对于一组特征,这些计算会同时在特征层面进行。

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

鲁棒缩放公式(图片由作者提供)

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

鲁棒缩放替代公式(图片由作者提供)

当数据中存在异常值时,鲁棒缩放尤其有用。这是因为分位数对异常值具有鲁棒性(因此命名为鲁棒缩放)。

在 Scikit-learn 中,可以使用**RobustScaler()**函数执行鲁棒缩放。

from sklearn.preprocessing import RobustScaler

sc = RobustScaler()
sc.fit(data)
scaled_data = sc.transform(data)

调用 fit()方法时,找到每个变量的分位数值。如果我们需要对数据应用缩放过程,还应调用 transform()方法。

4. 均值归一化

均值归一化是另一种流行的特征缩放技术,我们从每个数据值中减去均值,并将结果除以范围(最大值与最小值之间的差异)。

这个公式与最小-最大缩放公式非常相似,只是我们从每个数据值中减去了均值,而不是从每个数据值中减去最小值。

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

均值归一化公式(图片由作者提供)

均值归一化无法直接在 Scikit-learn 中实现,因为没有专门的函数来执行这一操作。但我们可以通过将**StandardScaler()RobustScaler()**转换器结合创建一个 Scikit-learn 流水线来执行均值归一化。流水线顺序地将多个转换器应用于数据。

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import RobustScaler

ss = StandardScaler(with_mean=True, with_std=False)
rs = RobustScaler(with_centering=False, quantile_range=(0, 100))

mean_normalizer = Pipeline([('Std_Scaler', ss),
                            ('Rob_Scaler', rs)
])

mean_normalizer.fit(data)
scaled_data = mean_normalizer.transform(data)

在上面的代码示例中,我通过更改默认超参数值自定义了**StandardScaler()RobustScaler()**转换器!

ss = StandardScaler(with_mean=True, with_std=False)

这行代码并没有执行典型的标准化。相反,它从每个值中减去均值,并将结果除以 1,因为with_std=False。这将成为下一转换器的输入。

rs = RobustScaler(with_centering=False, quantile_range=(0, 100))

通过设置with_centering=False,不会从输入值中减去中位数。此外,它还通过**quantile_range=(0, 100)**将输入值除以范围(最大值与最小值之间的差异)。0 表示最小值,100 表示最大值。

流水线将上述自定义的转换器顺序地应用于数据。当数据经过上述流水线时,将执行均值归一化!

5. 最大绝对缩放

最大绝对缩放可以通过将每个数据值除以特征的最大值来执行。与之前的方法相比,它的公式非常简单。

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

最大绝对缩放公式(图片由作者提供)

之前的方法通过从每个数据值中减去均值、最小值或中位数来中心化数据。但最大绝对值缩放不会以这种方式中心化数据。因此,该方法适用于 稀疏数据,其中大多数值为零。

在 Scikit-learn 中,可以使用 MaxAbsScaler() 函数执行最大绝对值缩放。

from sklearn.preprocessing import MaxAbsScaler

sc = MaxAbsScaler()
sc.fit(data)
scaled_data = sc.transform(data)

调用 fit() 方法时,会找到每个变量的最大值。如果我们需要对数据应用缩放过程,也应该调用 transform() 方法。

6. 向量单位长度缩放

单位向量的大小为 1。要将非零向量转换为单位向量,需要将该向量除以其长度,该长度可以通过使用曼哈顿距离(L1 范数)或欧几里得距离(L2 范数)来计算。

现在,考虑以下非零向量。

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

向量(图片来源:作者)

该向量的长度(大小)可以通过曼哈顿距离(L1 范数)来计算。

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

向量的曼哈顿距离(L1 范数)(图片来源:作者)

向量的长度(大小)也可以通过使用最常用的方法,即欧几里得距离(L2 范数)来计算。

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

向量的欧几里得距离(L2 范数)(图片来源:作者)

要将 x 转换为单位向量,我们需要将其除以长度,如上所示。这称为 归一化向量。归一化后,向量变成一个大小(长度)为 1 的单位向量,并且具有与 x 相同的方向。

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

单位向量公式(图片来源:作者)

之前的特征缩放方法是按特征进行计算,即考虑所有观测值中的每个特征。然而,在单位长度缩放中,计算是按观测值进行的,即考虑所有特征中的每个观测值。

为了说明这一点,请考虑以下表格数据。

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

(图片来源:作者)

数据中有三个观测向量。例如,第一个观测可以由以下向量表示,

Ob1 = (2, 3, 5)

Ob1 = (2, 3, 5)

Length of Ob1 = Sqrt(2² + 3² + 5²) = Sqrt(38) --> Euclidean distance (L2 norm)

Unit Vector = [2/Sqrt(38), 3/Sqrt(38), 5/Sqrt(38)]

Length of Unit Vector = 1

所有其他观测值可以用类似的格式表示。

单位长度缩放以这种方式应用于观测向量。

在 Scikit-learn 中,单位长度缩放是通过 Normalizer() 函数进行的。

from sklearn.preprocessing import Normalizer

sc = Normalizer(norm='l2')
sc.fit(data)
scaled_data = sc.transform(data)

调用 fit() 方法时,这次没有任何变化。它仅验证模型的参数。在之前的情况下,参数是通过学习获得的。调用 transform() 方法将除以每个观测向量的长度,即执行单位长度缩放。

Normalizer() 函数还提供了更改距离类型的选项,曼哈顿(‘l1’ 范数)或欧几里得(‘l2’ 范数)。默认情况下使用‘l2’。

特征缩放与数据分布

以上讨论的任何特征缩放方法都不会改变数据的基础分布。在应用特征缩放前后,变量的分布保持不变!只有值的范围会发生变化!

为了说明这一点,我将创建同一特征的两个直方图,一个是在应用 z-score 标准化之前,另一个是在应用之后。

# Load iris data
from sklearn.datasets import load_iris

iris_data = load_iris().data
p = iris_data[:, 0] # Select the first feature

# Apply feature standardization
from sklearn.preprocessing import StandardScaler
p_scaled = StandardScaler().fit_transform(iris_data)[:, 0]
import matplotlib.pyplot as plt
plt.style.use('ggplot')

fig = plt.figure(figsize=(5.5, 4))
plt.hist(p, bins=20)
plt.title("Before scaling")
plt.show()

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

未缩放变量的直方图(图像作者提供)

fig = plt.figure(figsize=(5.5, 4))
plt.hist(p_scaled, bins=20, color='green')
plt.title("After scaling")
plt.show()

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

缩放变量的直方图(图像作者提供)

变量的分布保持不变!但是,值的范围会发生变化!

import numpy as np

np.min(p), np.max(p) # Before scaling

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

缩放前的范围(图像作者提供)

np.min(p_scaled), np.max(p_scaled) # After scaling

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

缩放后的范围(图像作者提供)

特征缩放时的数据泄漏

在数据预处理过程中,当训练集中的某些信息泄漏到测试集中时,就会发生数据泄漏。

训练模型时,用于训练的数据不应用于测试。这就是为什么我们将数据集划分为训练集和测试集的原因。训练集和测试集应该是独立的,不应混合使用。

在特征缩放中,数据泄漏主要有两种方式。

  • 在将数据划分为训练集和测试集之前进行特征缩放
from sklearn.datasets import load_iris
X = load_iris().data
y = load_iris().target

from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_scaled = sc.fit_transform(X)

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, 
                                                    test_size=0.20,
                                                    random_state=42)

当调用缩放器 (sc) 的 fit() 方法时,参数(每个变量的均值和标准差)是从整个数据集中学习得到的。由于在数据缩放后再进行划分,训练集和测试集中的一些信息可能会混淆。

为避免这种情况,应该在划分数据后进行特征缩放。

from sklearn.datasets import load_iris
X = load_iris().data
y = load_iris().target

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, 
                                                    test_size=0.20,
                                                    random_state=42)

from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
sc.fit(X_train)
X_train_scaled = sc.transform(X_train)
X_test_scaled = sc.transform(X_test)
  • 在对训练集和测试集分别调用缩放器 (sc) 的 fit() 方法两次时
from sklearn.preprocessing import StandardScaler

sc = StandardScaler()
X_train_scaled = sc.fit_transform(X_train)
X_test_scaled = sc.fit_transform(X_test)

当对训练集和测试集分别调用 fit() 方法两次时,参数会被学习两次。参数应该只在训练集上学习,而不是在测试集上学习。训练集上学习到的参数也可以应用于转换测试集。换句话说,你只需要在训练集上调用一次 fit() 方法。这样,我们可以避免将数据从训练集泄漏到测试集。

from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train_scaled = sc.fit_transform(X_train)
X_test_scaled = sc.transform(X_test)

# Or

from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
sc.fit(X_train)
X_train_scaled = sc.transform(X_train)
X_test_scaled = sc.transform(X_test)

特征缩放方法总结

  1. 标准化: StandardScaler(),用法 — 当数据遵循高斯或正态分布或分布未知时 | 对数据中的异常值不太敏感

  2. 最小-最大缩放(归一化): MinMaxScaler(),用法 — 当数据分布未知或不遵循正态分布时 | 对数据中的异常值高度敏感

  3. 鲁棒缩放: RobustScaler(),用法 — 对数据中的异常值鲁棒

  4. 均值归一化: StandardScaler()RobustScaler(),用法 — 对数据中的异常值敏感

  5. 最大绝对值缩放: MaxAbsScaler(),用法 — 与其他方法不同,不会对数据进行中心化 | 与稀疏数据效果良好

  6. 向量单位长度缩放: Normalizer(),使用方法——逐观测进行计算,即考虑所有特征下的每个观测值(所有其他方法按特征进行计算,即考虑所有观测下的每个特征)

今天的文章到此结束。

如果您有任何问题或反馈,请告诉我。

AI 课程怎么样?

加入我的私人邮件列表

再也不会错过我的精彩故事。通过订阅我的邮件列表,您将直接在我发布新故事时立即收到。

非常感谢您的持续支持!我们在下一篇文章中见。祝大家学习愉快!

参考文献

特别感谢以下书籍的作者,我通过阅读该书获得了有关特征缩放方法的一些知识。

  • Python 特征工程实用手册(第 2 版 2022)作者:索莱达德·加利

Iris 数据集信息

本文最初由我在Substack上发布。

设计与撰写: Rukshan Pramoditha

2023–08–15

为什么将人工智能技术成功应用于临床护理如此困难?

原文:towardsdatascience.com/why-is-it-so-difficult-to-successfully-get-ai-technologies-adopted-into-clinical-care-4fa549d2c36?source=collection_archive---------7-----------------------#2023-03-30

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

图片由 国家癌症研究所 提供,发布在 Unsplash

探讨了一篇科学综述论文,该论文提出了这个问题并找到了答案

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

·

点击这里 发表在 数据科学前沿 · 9 分钟阅读 · 2023 年 3 月 30 日

人工智能(AI)在我们日常生活中变得越来越普遍。从几乎每个网络商店中的推荐系统,到自动翻译你访问的网站上的外语。然而,对于某些行业而言,这一过渡似乎比其他行业更加顺利。医疗领域似乎特别难以进入,但为什么呢?虽然有如此多的学术活动专注于医疗领域的人工智能,但是什么让这些技术突破在医疗保健中无法产生切实影响?Sendak 等人在他们的综述论文《机器学习产品在医疗服务中的转化路径》(2020 年)中尝试寻找这个问题的答案。他们的发现与我在UbiOpsMedTech 初创公司合作的经验非常契合,因此在本文中,我将带您逐步了解他们的论文。

机器学习在医疗保健中的现状

在我们深入探讨论文本身之前,让我们快速了解一下医疗领域中机器学习的现状。对机器学习在医疗领域的潜力的热情和兴奋程度非常高,导致了大量相关文献的出现。你几乎每隔一周就能看到有关利用机器学习进行癌症检测的新研究,而利用机器学习进行药物发现似乎也是一个热门话题。许多会议、组织和学术期刊已经建立,以传播围绕机器学习在医疗保健中的知识。

尽管研究正在快速增长,但切实的临床影响证据仍然稀少。你可能会想:“哦,但新技术通常需要一段时间才能成熟到能够应用于实践中”,但与此同时,我们也看到,利用机器学习提高用户留存率的新发现被 TikTok、Instagram 和 LinkedIn 等迅速采纳。Panch 等人巧妙地描述了这一医疗保健中机器学习的‘不便之处’

“目前,研究文献中突出的算法实际上在临床实践的前线大多无法执行。”

幸运的是,有一些医疗公司成功地将人工智能/机器学习整合到了他们的产品中。例如,Ellogon 这样帮助医生选择合适的癌症免疫疗法患者的公司,证明了从概念验证过渡到可以轻松完全融入现有医疗协议的成熟产品是可能的。

是什么使成功融入医疗保健的机器学习产品与那些停留在概念验证阶段的产品有所不同? 让我们看看 Mark Sendak 等人的研究,找出答案。

Sendak 等人的研究

Mark Sendak 及其同事开始进行叙述性综述,以帮助理解如何将机器学习转化为医疗保健。他们结合了自己在构建机器学习产品方面的第一手经验,并与 21 个成功进入临床护理的机器学习模型案例研究相结合。这正是我对他们的研究感兴趣的原因,因为他们尝试从那些真正进入生产阶段的人身上学习。

根据他们对这 21 个案例研究的分析,作者确定了在医疗保健世界中将产品推向成熟阶段的核心阶段和挑战。

“转化路径”

作者成功地将 21 个成功案例映射回他们所称的“转化路径”(见图)。他们指出,在从概念验证到正式产品的过程中,有四个关键阶段。这些阶段是:

  1. 设计与开发: 这是识别正确问题并设计和开发能够提供可操作见解的机器学习工具的过程。

  2. 评估与验证: 评估产品是否真的能改善临床护理和患者结果,是否准确可靠,以及是否有商业案例。

  3. 扩展与推广: 这一步描述了将概念验证真正扩展为集成产品的过程。它需要扩展模型的部署并将其推广给早期采用者。

  4. 持续监控和维护: 重要的是要注意,没有一个机器学习产品是最终完成的。模型需要持续监控和更新,以避免出现故障行为。特别是在医疗保健领域,这一点可能会带来严重的后果。

这些阶段不一定是顺序进行的,团队可能会在这些阶段之间反复迭代。有关转化路径的更多细节,请参见下图。

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

图片由 Sendak 等人提供,摘自《机器学习产品转化为医疗保健服务的路径》。图片描述了转化路径的各个阶段。

主要障碍

综述很好地描述了在医疗保健中创建机器学习驱动产品时面临的各种挑战和挫折点,从技术基础设施挑战到伦理风险。我不会逐一列举所有问题,但我想突出几个我认同的点。

领域知识与产品化知识

在开发医疗技术工具时,总会存在领域知识与生产化知识之间的紧张关系。你团队中的人员数量有限,同时你需要确保有足够的医学专家参与,还要有能实际构建和部署解决方案的合适人员。关注点的选择高度依赖,但 Sendak 等人很好地强调了如果你想成功,团队中需要在某种程度上具备这两种能力。

当然,并非每种技能都需要团队中实际有人具备!某些任务也可以外包,或引入可以处理标准任务的工具,以便专家可以专注于你解决方案中的独特之处。我看到许多公司因开源工具的免费而忙于构建自己的平台。但别忘了,团队中需要投入时间和精力来设置这些技术的成本!当他们忙于使部署工具工作时,你正浪费可以用于实际改进模型和创造价值的时间…

什么时候一个模型是“好”的?

好模型和坏模型的区别往往不清晰,也不明确你在特定情况下应追求什么样的性能。如果不讨论这一点,可能会导致期望与现实的不匹配。这里需要注意的是,这不仅仅关乎模型的准确性,还涉及到可用性和潜在的经济性能。一个准确性很高但运行需 10 小时的模型,可能不会很有用,也不实惠。每个案例都不同,因此在早期进行讨论以识别和达成相关模型性能指标的共识至关重要。

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

作者提供的图片

在孤立的背景下证明产品的有效性是不够的

仅仅因为产品在受控测试环境和测试数据集上表现良好,并不意味着该产品在实际环境中也会表现良好。重要的是要让真实数据通过产品,并用它来评估产品性能。在 UbiOps,我们专注于部署和服务,我们多次看到模型在引入实际生产数据后,性能可能会发生巨大的变化!即使只是作为影子部署,尽早进入这一阶段也很重要。

集成到生产环境中是困难的

作者指出,实际生产环境和开发/数据存储环境之间通常存在巨大差异。在他们调查的所有示例案例中,他们发现通常需要大量的努力和投资才能将产品集成到现有系统中。一项研究估计,在一个地点验证和集成肾衰竭风险方程到临床工作流程的成本接近$220,000。这只是一个地点!

数据分布在云和本地环境中

这篇评论突显了一个重要问题,即数据分布在各种云解决方案和本地数据中心。通常这在扩展阶段开始时会引发问题。设计产品和架构时意识到这一点,可以大大有利于从概念验证过渡到正式推出的产品。

不断变化的监管框架

另一个主要挑战与合规性、数据安全以及医疗设备和软件所需的大量法规和认证相关。更不用说规则不断变化。很难跟上所有内容并确保你的产品每个部分都完全合规。数据安全尤其是一个障碍,因为数据非常敏感。

接下来呢?

我已经向你介绍了翻译路径及其主要障碍,那么接下来呢?我认为,当你开始创建一个新型的医疗保健领域的 ML 驱动产品时,一切都始于意识和开放讨论。了解前人遇到的挑战,你如何从他们的错误中学习?

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

作者提供的图片

在我看来,最重要的是不要害怕实际进入那个模糊和扩展的步骤。从开发环境中走出来并在生产中运行事物是绝对关键的,尽管是在阴影模式下。只有在迈出这一步后,你才能开始朝着真正具有影响力和价值的产品前进。

那么,你如何确保实际在生产环境中运行这些东西?确保你投资于一个可以帮助你快速迭代的基础设施,并且让你专注于你擅长的事情:为医疗用例构建模型。投资于可以帮助你快速部署和监控的 MLOps 工具,确实有助于确保你能专注于实际挑战,而不是标准的基础设施挑战。我看到许多公司因为开源工具免费而投入大量精力构建自己的平台。但别忘了,团队成员投入时间和精力去设置这些技术的成本!当他们忙于让部署工具运作时,你却浪费了可以用来真正改进模型和创造价值的时间……

在数据安全方面,确保你使用的工具已获得正确的认证(如 ISO 认证)是有帮助的。特别是在欧洲,选择一些较小的云服务提供商而非三大巨头也可能更合适。与专注于医疗数据的云服务提供商合作,你将大大减少在证明你符合所有规定时的麻烦。

简而言之

在将 AI 纳入日常临床护理时,有许多因素需要考虑。从法规、架构问题,到吸引合适的人参与。Sendak 等人成功地在他们的“转化路径”中简洁地捕捉了所有阶段和障碍。了解这一转化路径的四个不同阶段以及可能遇到的不同障碍,肯定有助于你为成功做好准备。

想要讨论医疗保健中 ML 的架构设置吗?

如果你喜欢本文的内容,并希望深入探讨该领域的 ML 架构设置,不要犹豫,随时联系我!我很乐意讨论 MLOps。你可以在评论区联系我,或者直接在 LinkedIn 上找到我。

参考文献

Panch T 等人。关于医疗保健中 AI 的“令人不便的真相”。npj Digital Medicine. 2019

Sendak, MP 等人。将机器学习产品转化为医疗保健服务的路径。EMJ 评审。2020

Sendak MP 等人。分析 EHR 数据中实现规模经济的障碍:一个警示性的故事。Applied Clinical Informatics. 2017

Xiao C 等人。使用电子健康记录数据开发深度学习模型的机遇与挑战:系统综述。J Am Med Inform Assoc. 2018

为什么更多即是更多(在人工智能中)

原文:towardsdatascience.com/why-more-is-more-in-deep-learning-b28d7cedc9f5

大型神经网络如何泛化

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

·发表于 Towards Data Science ·阅读时间 10 分钟·2023 年 8 月 15 日

少即是多。

-路德维希·密斯·范·德·罗赫

只有当更多已经太多时,少即是多。

  • 弗兰克·劳德·赖特

深度神经网络(DNNs)深刻地改变了机器学习的格局,常常与人工智能和机器学习的广泛领域同义。然而,它们的崛起若没有它们的“搭档”——随机梯度下降(SGD),将是难以想象的。

SGD 及其衍生优化器构成了许多自学习算法的核心。其核心概念很简单:使用训练数据计算任务的损失,确定相对于其参数的损失梯度,然后调整参数以最小化损失。

听起来很简单,但在应用中,它已经被证明极其强大:SGD 可以为各种复杂问题和训练数据找到解决方案,只要它与足够表达力的架构结合使用。它特别擅长找到使网络在训练数据上表现完美的参数集合,这被称为插值机制。但在什么条件下,神经网络被认为是良好泛化的,即在未见过的测试数据上表现良好?

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

总体化的追求是机器学习的核心。由 DALL-E 构想。

在某些方面,这几乎过于强大:SGD 的能力不仅限于可以期望带来良好泛化的训练数据。例如,在这篇有影响力的论文中已经表明,SGD 可以使网络完美记忆一组随机标记的图像(关于记忆与泛化之间的深层关系,我之前有过相关的讨论)。虽然这看起来具有挑战性——考虑到标签与图像内容之间的不匹配——但对于使用 SGD 训练的神经网络来说,这出奇地简单。实际上,这并不比拟合真实数据更具挑战性。

这种能力表明,使用 SGD 训练的神经网络存在过拟合的风险,避免过拟合的正则化措施,如范数、早期停止和减少模型大小变得至关重要。

从经典统计学的角度来看,少即是多,因此多即是少,如这幅 DALL-E 画作简洁总结的那样:

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

更多即是更少,由 DALL-E 创作。

“一切事物都应尽可能简单,但不能更简单。” — 阿尔伯特·爱因斯坦

但问题在于:最令人惊讶的现代深度学习特性之一是,大多数架构在高度过参数化的阶段,即参数远多于数据点时表现最佳。这令人惊讶,因为标准学习理论,基于基本直觉,认为如此多的参数使得深度神经网络(DNNs)会过度调整到特定的训练数据上,从而在处理新的、未见过的数据时表现较差。

这在著名的**“双重下降”**曲线中得到了很好的体现,该曲线由 Belkin 等人在 2019 年的论文《调和现代机器学习实践与偏差-方差权衡》中推广。

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

观察到的经典 U 型学习曲线和双重下降现象。 摘自 Belkin 等,2019 年。

在“经典”领域,增加容量会导致训练和测试损失的减少,但在最佳点之后,测试风险会再次增加,而训练风险降至零(“过拟合阶段”)。

但现代机器学习算法已经突破了这一门槛:移动到现代插值阶段,使用高度过参数化的模型,测试风险再次降低,甚至降到经典阶段无法达到的水平,实现了前所未有的泛化能力。

数学语言在物理法则表述中的适用性奇迹,是我们既无法理解也不配拥有的美妙礼物。

尤金·维根

神经网络能够泛化,即便其固有的过拟合倾向,表明存在所谓的归纳偏差。归纳偏差指的是学习算法在预测未见数据点的输出时,基于其训练数据所作的(通常未言明的)一系列假设。就像我们常常无意识的(且常常相当麻烦的)认知偏见一样,架构的归纳偏差决定了它对某些解决方案的偏好,在不确定性或存在多种可能解决方案时引导它。

事实证明,我们非常幸运:许多研究指出,使用 SGD 训练的 DNNs 对函数具有良好的泛化能力(在结构化数据上,这也是我们在应用 DNNs 时最关心的数据)。这是一系列使深度学习如此有效的惊喜之一,特伦斯·塞伊诺斯基在“深度学习在人工智能中的非理性有效性”中讨论了这一点,回响了尤金·维根的六十年前关于数学在自然科学中的非理性有效性的著名论文,我们“既无法理解也不配拥有”。

“深奥的科学真理之所以被发现,并不是因为它们有用;而是因为它们可以被发现。”

J. 罗伯特·奥本海默

这种非理性的有效性使许多看似不可能的深度学习应用得以实现。

这也可能是我们不配拥有的,或者更确切地说,(尚未)不该拥有的:鉴于人工智能的迅速发展和越来越多的警示声音呼吁暂停人工智能研究,深度学习的成功也打开了潘多拉的盒子,这可能会定义未来一个世纪的人类道路。

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

DALL-E 设想的潘多拉盒子的开启。

但,与维根提出的关于数学与物理、思想与现实之间的基础关系的形而上学问题相比,深度学习的成功至少是我们可以理解的。

尽管对神经网络为何能如此良好地进行泛化进行了大量理论研究,但深度学习的理论仍滞后,目前尚无明确且普遍接受的解释来说明为何深度神经网络(DNNs)能够如此出色地进行泛化。

许多理论提议,例如局部最小值是全局最小值的见解,通常只适用于有限的架构,如线性神经网络或简单的非线性网络。通常,从学习理论中得出的结果可能与实际使深度神经网络有效的实践经验相矛盾,例如实际深度神经网络中存在许多次优的局部最小值(在这篇恰如其分标题的论文中探讨了真相或反向传播)。

尽管尚未有普遍认可的解释,但深度学习理论中有许多引人入胜的见解可以推进我们对为什么 DNNs 中的泛化有效的理解和直觉。

在本文的其余部分,我想探索几种解释尝试,以理解为什么更多往往意味着更多对于神经网络训练(简要说明:我将专注于分布内泛化,而不讨论分布转移领域,即被称为分布外/OOD 泛化的领域)。

如开头所提,大致有两个潜在的罪魁祸首:SGD/优化神经网络本身。

认为 SGD 可能是导致良好泛化的归纳偏差的原因,已经引发了大量研究。这些研究深入探讨了在这些泛化特性显现的各种机制和优化器。值得注意的是,在今天的众多优化器变体中,从 SGD 到 Adam 再到 Adagrad 到 LBFGS,选择优化器对泛化的影响很小大多数,甚至所有,都能在不同任务中实现相当的泛化结果。虽然有人理论认为,SGD 固有的随机性有助于模型逃离尖锐的、不具泛化性的最小值,推动其向损失景观中更广泛、更具泛化性的区域移动,并对参数具有正则化效果,即使是全批次 SGD(一次性在整个训练数据上进行训练)在许多情况下也表现良好。

这表明泛化可能与损失景观的特征更加密切相关,而非特定的优化器引导学习算法的过程。这引出了一个有趣的问题:特定最小值的泛化能力如何与周围损失景观的属性相关联?

一个自 90 年代以来流行的解释认为,尖锐的最小值相较于平坦的最小值通常推广效果较差。直观上,这与分类时决策边界距离数据点的远近有关:在泛化效果不佳和过拟合严重的情况下,决策边界紧贴数据点,因此参数的微小变化可能导致损失的剧烈变化,因为它们也会改变多个点的分类。相反,平坦的最小值会导致较宽的决策边际,类似于支持向量机中的目标边际。

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

崎岖的损失景观中包含尖锐的局部最小值与较平滑且较宽的局部最小值。损失景观的平滑度也取决于训练技术和正则化技术,如丢弃法。摘自我们最近的 ICML 论文

由于梯度下降在优化过程中更容易遇到平坦的最小值,因此自然更倾向于泛化的解决方案,这种效果因通常非常高维的损失景观而加剧。尖锐的最小值就像是高维稻草堆中的,而平坦的最小值则是稻草堆中的稻草,考虑到问题的高维性质,找到尖锐的过拟合最小值比找到平坦的最小值要困难几个数量级

此外,平坦的最小值在体积上也比尖锐的最小值大,而高维空间中体积的反直观扩展意味着这可能导致它们各自体积上的数量级差异。

另一个在实践中经常观察到的现象可以进一步发挥作用:局部最小值在实践中通常被认为由小损失的山谷连接,即“损失山谷”。SGD 以其迭代性质可以穿越这些山谷,更容易找到并停留在这些更广泛、可泛化的区域。

在讨论了 SGD 及其与损失景观的相互作用后,现在该直接思考神经网络了:随机初始化的深度神经网络本身是否已经表现出某种**“简单/泛化”解的归纳偏差**,无论简单指的是什么?

如果简单的网络导致简单的解决方案,而 DNNs 所建模的许多过程实际上是简单的(即,比拟合随机噪声的维度低得多),那么神经网络表现出简单解决方案的倾向将给我们带来很多信息。

检查 SGD 是否与神经网络的成功有很大关系的一个好方法是观察它们在没有明确通过 SGD 训练的情况下如何解决问题。

一篇近期论文 (SGD 是贝叶斯采样器吗?差不多。) 提出,促使 DNN 朝向“简单”解决方案的归纳偏差,可能不仅仅是 SGD 的特殊属性,而是网络的固有特征

论文的核心前提围绕两个概率:P_SGD(f∣S)— 使用 SGD 或其变体训练的过参数化 DNN 收敛到一个与训练集 S 一致的函数 f 的可能性;以及 P_Bayesian(f∣S)— 给定训练集 S,函数 f 由 DNN 表示的贝叶斯后验概率,当其参数随机初始化时。

不讨论细节,这项研究发现这两个概率之间存在显著的相关性。更重要的是,贝叶斯采样器表现出强烈倾向于具有低错误和最小复杂性的函数。这一发现表明,DNN 的固有结构及其庞大规模,而不是 SGD 的具体细节,可能是其在过参数化设置中具备良好泛化能力的主导因素。

然而,论文也指出,尽管这两个概率紧密相关,但仍存在对超参数敏感的细微差异。这意味着架构变化、批量大小、学习率和优化器选择等因素在 DNN 性能中仍然非常重要。

“幸运是准备与机会相遇时发生的事情。”

— 塞内卡

架构偏好简单解决方案的事实也与过参数化网络的另一个新见解相契合,即所谓的彩票票据假设

它提出,在大型的过参数化网络中,存在着较小、稀疏的子网络,这些子网络具有成功的潜力。这些被称为“赢票”的网络,不仅仅是幸运的发现,而是已经以一种特别适合学习特定任务的方式初始化。在过参数化模型中,存在着众多的“赢票”或最佳子网络。这些子结构倾向于高效学习和良好的泛化能力。整体网络的冗余性提供了一种集成学习的形式,其中多个“优质”子网络共同收敛到稳健的解决方案。此外,参数的过剩可能有助于探索损失景观,使模型能够有效地发现和利用这些子网络。

在我之前的文章中,我深入探讨了免费午餐定理,以及大型预训练模型的迁移学习如何给我们提供类似于免费午餐的东西。这与泛化的主题紧密相关:大型预训练模型通常表现出显著的泛化能力,即使在特定领域的数据有限的情况下。这种现象似乎违背了传统的偏差-方差权衡,呼应了过参数化模型良好泛化的更广泛主题。像 GPT-4 这样的模型向我们展示了,拥有更多参数并辅以足够多样化的数据,确实可以导致模型不仅能够很好地拟合训练数据,而且在看似新颖且未见过的场景中也表现出色。

但用于训练的数据质量可能是泛化的最关键因素。Sam Altman 经常强调数据策划在 GPT-4 的有效性中发挥了重要作用。而在正确类型的数据上“过拟合”可能足以让你获得所需的结果。正如AI Coffee Break的主持人 Letitia Parcalabescu 在我们一起录制的最新播客集中所说:“如果你在整个世界上过拟合,你基本上就完成了。”

大型神经网络之所以能够良好泛化,可能有多种原因。这是大多数人没有预料到的,尤其是在 20 世纪对偏差-方差权衡的深刻传统思维影响下。

但它确实有效。尽管所有的模型和算法都是由人类开发的,但我们仍然不确定发生了什么。也许,未来某天,我们会找到答案。如果我们找不到答案,我相信 AI 算法在自我探索的过程中会找到的。

感谢阅读!

如果你喜欢我的写作,请订阅以通过邮件获取我的故事,或考虑成为推荐会员

为什么 OpenAI 的 API 对非英语语言更昂贵

原文:towardsdatascience.com/why-openais-api-is-more-expensive-for-non-english-languages-553da4a1eecc

超越文字:字节对编码和 Unicode 编码如何影响定价差异

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

·发表于 Towards Data Science ·阅读时间 7 分钟·2023 年 8 月 16 日

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

怎么会“Hello world”这个短语在英语中有两个令牌,而在印地语中却有 12 个令牌呢?

在发布了 我最近关于如何估算 OpenAI API 成本的文章 后,我收到了一条有趣的评论,有人注意到 OpenAI API 在其他语言中的费用远高于英语,例如使用汉字、日语或韩文 (CJK) 字符的语言。

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

有读者在 我最近关于如何估算 OpenAI API 成本的文章 上评论了 [tiktoken](https://medium.com/towards-data-science/easily-estimate-your-openai-api-costs-with-tiktoken-c17caf6d015e)

我之前并未意识到这个问题,但很快意识到这是一个活跃的研究领域:今年年初,Petrov 等人发表了一篇名为“语言模型分词器在语言之间引入不公平性”的论文[2],该论文显示“同一文本翻译成不同语言后,其分词长度可能会有剧烈差异,在某些情况下差异可达 15 倍。”

作为补充,分词是将文本拆分为一系列令牌的过程,这些令牌是文本中的常见字符序列。

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

分词的一个示例

符号化长度的差异是一个问题,因为OpenAI API 按 1,000 个符号计费。因此,如果你在类似的文本中有多达 15 倍的符号,这将导致 15 倍的 API 费用。

实验:不同语言中的符号数量

让我们将短语“Hello world”翻译成日语(こんにちは世界)并转录成印地语(हैलो वर्ल्ड)。当我们用 OpenAI 的 GPT 模型中使用的cl100k_base分词器对这些新短语进行符号化时,得到以下结果(你可以在本文末尾找到我用于这些实验的代码):

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

“Hello world”在英语、日语和印地语中的字母和符号数量(cl100k_base

从上图中,我们可以得出两个有趣的观察:

  1. 这个短语的字母数量在英语中最多,而在印地语中最少,但产生的符号数量在英语中最少,而在印地语中最多。

  2. 在印地语中,符号的数量多于字母的数量。

这怎么可能发生?

基础知识

要理解为什么在除英语之外的语言中,相同的短语会产生更多的符号,我们需要回顾字节对编码和 Unicode 的两个基本概念。

字节对编码

字节对编码(BPE)算法最初是由 Gage [1]于 1994 年发明的,用作一种压缩算法。

“[BPE]算法通过查找数据中最频繁出现的相邻字节对来压缩数据,并用一个原始数据中不存在的字节替换所有出现的对。该算法重复此过程,直到无法进一步压缩,无论是因为没有更多频繁出现的对,还是没有更多的未使用字节来表示对。”[1]

让我们通过原始论文中的例子[1]。假设你有一个最小的文本语料库,由字符串“ABABCABCD”组成。

1. 对于每一对字节(在这个例子中,即字符),你将统计它在语料库中的出现次数,如下所示。

"ABABCABCD"

pairs = {
  'AB' : 3,
  'BA' : 1,
  'BC' : 2,
  'CA' : 1,
  'CD' : 1,
} 

2. 取出现次数最多的一对字节,并用一个未使用的字符替换它。在这种情况下,我们将把“AB”这对字节替换为“X”。

# Replace "AB" with "X" in "ABABCABCD":
"XXCXCD"

pairs = {
  'XX' : 1,
  'XC' : 2,
  'CX' : 1,
  'CD' : 1, 
}

3. 重复步骤 2,直到无法进一步压缩或没有更多的未使用字节(在这个例子中,即字符)为止。

# Replace "XC" with "Y" in "XXCXCD":
"XYYD"

pairs = {
  'XY' : 1,
  'YY' : 1,
  'YD' : 1,
}

Unicode

Unicode 是一种编码标准,定义了不同字符如何用称为码点的唯一数字表示。在本文中,我们不会涵盖 Unicode 的所有细节。如果你需要复习,可以参考这个优秀的 StackOverflow 回答

对于以下解释,你需要知道的是,如果你的文本是以 UTF-8 编码的,不同语言的字符将需要不同数量的字节。

从下面的表格中可以看出,英语字母可以用 ASCII 字符表示,只需要 1 个字节。但例如,希腊字符需要 2 个字节,而日文字符需要 3 个字节。

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

(灵感来自维基百科关于 UTF-8 的文章StackOverflow 的回答

探索内部机制

现在我们理解了不同语言的字符在数值上需要不同的字节量,并且 OpenAI 的 GPT 模型使用的分词器是 BPE 算法,它在字节级别上进行分词,让我们深入探讨一下我们的开篇实验。

英语

首先,让我们看看英文分词的普通例子:

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

分词短语“Hello world”

从上面的可视化中,我们可以得出以下观察:

  • 一个字母等于一个代码点

  • 一个 Unicode 代码点等于 1 个字节

  • BPE 将“Hello”分词为 5 个字节,将“ world”分词为 6 个字节,分成两个独立的标记

这一观察结果与OpenAI 分词器网站上的声明一致:

“一个有用的经验法则是,一个标记通常对应于~4 个字符的常见英文文本。”

注意到它说“对于常见的英文文本”?让我们看看非英文文本。

日语

那么在那些一个字母不对应一个字节而是多个字节的语言中会发生什么呢?让我们看看翻译成日语的“Hello world”,它使用了在 UTF-8 编码中为 3 字节的 CJK 字符:

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

分词短语“こんにちは世界”

从上面的可视化中,我们可以得出以下观察:

  • 一个字母等于一个代码点

  • 一个 Unicode 代码点等于 3 个字节

  • BPE 将 15 个字节的こんにちは(“Hello”的日文)分词为一个单独的标记

  • 但字母界被分词为一个单独的标记

  • 字母世被分词为两个标记

印地语

在那些一个字母不等于一个代码点而是由多个代码点组成的语言中,情况变得更加复杂。让我们看看“Hello world”翻译成印地语的情况。用于印地语的天城文字符表中的字符必须拆分成多个代码点,每个代码点需要 3 个字节:

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

分词短语“हैलो वर्ल्ड”

从上面的可视化中,我们可以得出以下观察:

  • 一个字母可以由多个 Unicode 代码点组成(例如,字母है由代码点ह和ै组合而成)

  • 一个 Unicode 代码点等于 3 个字节

  • 与日文字符世类似,一个代码点可以被分为两个标记

  • 一些标记跨越一个以上但少于两个字母(例如,标记 ID 31584)

总结

本文探讨了相同短语“Hello world”翻译成日语并转录成印地语后是如何进行分词的。首先,我们了解到 OpenAI 的 GPT 模型使用的分词器是在字节级别进行分词的。此外,我们还发现,日语和天城文字符号需要多个字节来表示一个字符,而不是像英语那样。因此,我们看到 UTF-8 编码和 BPE 分词器在最终令牌数量中发挥了重要作用,并影响了 API 成本。

当然,不同的因素,例如 GPT 模型在多语言文本上的训练不均等,会影响分词。在撰写时,这个问题是一个活跃的研究领域,我很期待看到不同的解决方案。

享受这个故事吗?

免费订阅 以便在我发布新故事时收到通知。

[## 每当 Leonie Monigatti 发布新内容时,你会收到电子邮件。

每当 Leonie Monigatti 发布新内容时,你会收到电子邮件。通过注册,如果你还没有 Medium 帐户,你将创建一个…

medium.com](https://medium.com/@iamleonie/subscribe?source=post_page-----553da4a1eecc--------------------------------)

LinkedIn,Twitter Kaggle上找到我!

参考文献

图片参考

如果没有另行说明,所有图片均由作者创作。

网络与文学

[1] Gage, P. (1994). 一种新的数据压缩算法。C 用户杂志, 12(2), 23–38.

[2] Petrov, A., La Malfa, E., Torr, P. H., & Bibi, A. (2023). 语言模型分词器在语言间引入了不公平性。arXiv 预印本 arXiv:2305.15425

代码

这是我用来计算和解码文章中令牌数量的代码。

# pip install tiktoken

import tiktoken

# Define encoding
encoding = tiktoken.encoding_for_model("gpt-3.5-turbo")

# Tokenize text and get token ids
tokens = encoding.encode(text)

# Decode token ids
decoded_text = [encoding.decode_single_token_bytes(token) for token in tokens]

为什么概率链结比模糊匹配或基于术语频率的方法更准确

原文:towardsdatascience.com/why-probabilistic-linkage-is-more-accurate-than-fuzzy-matching-or-term-frequency-based-approaches-15a28c733e73?source=collection_archive---------7-----------------------#2023-10-26

不同的记录链结方法如何有效利用记录中的信息进行预测?

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

·

关注 发表在 Towards Data Science ·4 min read·2023 年 10 月 26 日

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

从数据中提取信息。图像由作者使用 DALL·E 3 创建

一个普遍存在的数据质量问题是有多个不同的记录指向同一实体,但没有唯一的标识符将这些实体联系在一起。

在缺乏唯一标识符如社会安全号码的情况下,我们可以使用一组合在一起的非唯一变量,如姓名、性别和出生日期来识别个人。

为了在记录链接中获得最佳准确性,我们需要一个从输入数据中提取尽可能多信息的模型。

本文描述了在做出准确预测时最重要的三种信息类型,以及 Fellegi-Sunter 模型如何利用这三种信息,该模型用于Splink(一个用于数据链接和去重的免费 Python 包)。

它还描述了一些替代的记录链接方法如何丢弃部分信息,从而降低了准确性。

三种信息类型

大致上,有三类信息在预测一对记录是否匹配时是相关的:

  1. 记录对的相似性

  2. 整体数据集中的值的频率,以及更广泛地测量不同情景的普遍性

  3. 整体数据集的数据质量

让我们逐一查看。

1. 配对记录比较的相似性:模糊匹配

预测两个记录是否表示同一实体的最明显方法是测量列中是否包含相同或相似的信息。

每列的相似性可以使用模糊匹配函数如LevenshteinJaro-Winker进行定量测量,或使用绝对或百分比差异等数值差异。

例如,HammondHamond的 Jaro-Winkler 相似度为 0.97(1.0 是完美分数)。这可能是一个拼写错误。

这些度量可以分配权重,并求和以计算总相似性分数。

这种方法有时被称为模糊匹配,它是准确链接模型的重要组成部分。

然而,仅使用这种方法有一个主要缺陷:权重是任意的:

  • 用户需要猜测不同领域的重要性。例如,应该给年龄的匹配分配什么权重?这与名字匹配相比如何?当信息不匹配时,我们应该如何决定惩罚性权重的大小?

  • 预测的强度与每个模糊匹配度量之间的关系必须由用户猜测,而不是被估计。例如,如果名字的 Jaro-Winkler 相似度为 0.9 而不是完全匹配,我们的预测应该改变多少?如果 Jaro-Winkler 分数降至 0.8,预测的变化量是否相同?

2. 整体数据集中值的频率,或更广泛地测量不同情景的普遍性

我们可以通过考虑整体数据集中值的频率(有时称为“术语频率”)来改进模糊匹配。

例如,JohnJohn,以及JossJoss都是完全匹配,因此具有相同的相似性评分,但后者比前者更有力地证明匹配,因为Joss是一个不常见的名字。

JohnJoss的相对术语频率提供了这些不同名字相对重要性的基于数据的估计,这可以用来指导权重设置。

这个概念可以扩展到包括那些不是完全匹配的类似记录。权重可以通过估计在数据集中观察到模糊匹配的常见程度来推导。例如,如果在 Jaro-Winkler 评分为 0.7 的情况下,即使在不匹配记录之间,看到模糊匹配非常常见,那么如果观察到这样的匹配,这并不能提供多少支持匹配的证据。在概率连接中,这些信息被捕捉在被称为u概率的参数中,详细描述见这里

3. 整体数据集的数据质量:衡量不匹配信息的重要性

我们已经看到,模糊匹配和基于术语频率的方法可以让我们对记录之间的相似性进行评分,甚至在某种程度上对不同列上的匹配重要性进行加权。

然而,这些技术都无法帮助量化非匹配与预测匹配概率之间的相对重要性。

概率方法通过估计数据质量明确地估计这些情景的相对重要性。在概率连接中,这些信息被捕捉在m概率中,详细定义见这里

例如,如果性别变量的数据质量极高,那么性别的不匹配将是强有力的证据,表明这两条记录不是真正的匹配。

相反,如果记录已经被观察了多年,那么年龄的不匹配不会是两条记录匹配的有力证据。

概率连接

概率模型的强大之处在于以其他模型无法实现的方式结合所有三种信息来源。

不仅所有这些信息都被纳入预测中,Fellegi-Sunter 模型中的部分匹配权重使得不同类型信息的相对重要性可以从数据本身中估计出来,从而正确地加权以优化准确性。

相反,模糊匹配技术通常使用任意权重,不能充分融入所有三个来源的信息。术语频率方法缺乏利用数据质量信息来负面加权不匹配信息的能力,也没有适当加权模糊匹配的机制。

作者是 Splink的开发者,这是一个用于大规模概率链接的免费开源 Python 包。

为什么数据科学家应该采用机器学习(ML)管道

原文:towardsdatascience.com/why-should-data-scientists-adopt-machine-learning-ml-pipelines-8fc5e24920dd

意见

MLOps 实践 — 作为数据科学家,你是将一个笔记本还是一个 ML 管道交给你的 ML 工程师或 DevOps 工程师,以便在生产环境中部署 ML 模型?

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

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

背景

在我之前的文章中:

我谈到了构建 ML 管道的重要性。在今天的文章中,我将深入探讨 ML 管道的主题,并详细解释:

  • 为什么构建 ML 管道是必要且重要的

  • ML 管道的关键组件是什么

  • 为什么以及数据科学家如何采用 ML 管道?

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

照片由Jon Tyson拍摄,发布在Unsplash

为什么构建 ML 管道是必要且重要的?

数据科学家在笔记本环境中开发 ML 模型是很常见的。在笔记本中,他们会实验不同的数据集、不同的特征工程技术,以及不同的参数和超参数组合,以找到表现最佳的 ML 模型。在经过多轮性能调优和特征工程之后,他们找到理想的 ML 模型。他们继续用测试数据验证模型的性能,以确保模型没有“过拟合”并且满足业务要求。模型验证代码很可能是在同一个笔记本环境中开发和运行的。当他们对整体模型性能满意时,他们会交接一个笔记本(其中的代码可能涵盖数据摄取、数据探索、特征工程、模型训练和日志记录以及模型验证)给 ML 工程师或 DevOps 工程师,以便将模型部署到生产环境中。

然而,这个交接过程可能会出现许多问题:

  • 缓慢和手动的迭代 — 当在部署的 ML 系统中检测到问题时,数据科学家需要回到他们的笔记本中寻找解决方案,并再次将解决方案交给生产工程师,以便将更改部署到生产环境中。每次需要更新模型时,这个过程都会重复。这可能会有无尽的交接。这是一种非常缓慢的迭代方式。更糟糕的是,这种手动和缓慢的迭代可能会导致显著的业务损失。

  • 重复工作 — 数据科学家在笔记本环境中生成的代码很可能不适合生产环境。因此,ML 工程师需要投入精力重新编写和测试代码,并将代码转换为生产部署的模块。ML 管道可以显著减少代码重写的工作量。我将在本文后面解释原因。

  • 易出错 — ML 应用程序依赖于各种外部库来辅助模型训练过程,这使得数据科学家需要导入这些库。例如,他们通常利用 Pandas 进行数据清洗和特征工程,利用 ML/DL 框架进行特征和模型开发,利用 Numpy 进行张量和数组计算。除了这些流行的库,他们还可能会使用一些适合特定环境的小众库。由于这种依赖性,生产环境中使用的库与开发环境中使用的库不匹配时可能会引发错误。在前一点中,我们提到当笔记本被交给 ML 工程师时,通常会有大量的代码重写。在代码转换过程中可能会产生很多无意中的错误,比如模型超参数配置错误、训练和测试集不平衡、由于特征工程逻辑误用导致的数据泄露。

  • 难以扩展 — 由于在这个交接过程中花费了大量时间和精力,因此数据科学家和 ML 工程师团队很难实现大规模扩展。如果组织想要开发更多的 ML 应用程序,他们需要招聘更多的数据科学家和工程师。因此,消除数据科学家和 ML 工程师之间的手动交接可以显著提高团队效率,从而在有限的资源下构建更多的 ML 应用程序。

现在让我们看看 ML 流水线如何简化或甚至消除这一手动交接过程,并弥合开发环境中的笔记本 ML 模型实验和生产环境中的 ML 模型部署之间的差距。最终目标是以快速、自动和安全的方式部署和更新 ML 应用程序。

首先,让我们了解一下什么是 ML 流水线。

什么是 ML 流水线以及 ML 流水线的关键组件

在深入了解 ML 流水线之前,我们首先要理解“流水线”是什么。以下是来自维基百科的定义:

在计算中,流水线,也称为数据流水线,是一组数据处理元素****串联在一起的,其中一个元素的输出是下一个元素的输入。流水线的元素通常并行按时间切片执行。在元素之间通常会插入一些缓冲存储

上述定义中有几个关键组件,这些组件同样适用于 ML 流水线。让我们看看它是如何工作的:

  1. 一组数据处理元素 — 定义的第一部分讨论了一组数据处理元素。这是非常直接的。如果我们将其应用于 ML 管道,则数据处理元素的集合可能包括数据摄取、数据预处理、特征工程、模型训练、模型预测等。对于你的 ML 管道,你可以自定义每个组件,并根据需要在管道中添加多个组件。每个组件执行一个任务,所有任务结合起来形成一个管道。将工作流分解为多个元素对于 ML 应用非常有用。原因是,ML 管道中的每个元素可能需要非常不同的计算资源。为每个元素分配适当的计算资源,而不是为整个工作流使用巨大的计算资源,这为提高计算效率提供了良好的机会。

  2. 连接 — 第二个元素是这些组件是相互连接的。它们不是完全独立运行的。更重要的是,捕捉了上述数据处理元素的依赖关系。在 ML 管道的上下文中,数据摄取步骤必须在运行数据预处理之前完成,或者模型训练步骤必须在模型预测之前完成。

  3. 输入/输出 — 管道中的每个数据处理元素都有输入和输出。通常,一个元素的输出文档作为后续步骤的输入文档使用。这些文档将存储在中央位置,如文档库。

  4. 并行/分时执行 — 定义 ML 管道中每个元素的执行顺序。“并行”意味着两个元素可以同时运行;而“分时执行”则意味着两个元素之间有依赖关系。一个元素必须等到另一个完成后才能执行。

  5. 缓冲存储 — 缓冲存储是我们在输入/输出部分提到的文档库。缓冲存储提供了一个中央位置,用于数据文档,以便下游元素可以使用上游元素的输出、日志和用于监控和跟踪的指标。通过文档库,你可以重用某些元素的输出,而不是在需要重新运行工作流时运行每个元素。这也可以提高管道效率并降低计算成本。此外,你还可以为 ML 元数据设置数据库,包括实验、作业、管道运行和指标。

以下是一个 ML 训练管道可能的示例:

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

一个示例 ML 模型训练管道 | 作者提供的图像

此示例 ML 训练管道包括 10 个任务。通常,ML 管道是通过 Python SDK 或 YAML 文件定义的。对于每个任务,你可以定义以下配置:

  • 名称 — 任务的名称

  • 描述 — 对任务的描述

  • 输入 — 任务的输入设置

  • 输出 — 任务的输出设置

  • 计算 — 用于执行任务的底层计算资源

  • 参数 — 运行任务时提供的附加参数

  • 需求 — 在计算资源中需要安装的环境依赖关系

  • 任务依赖关系 — 连接的上游和下游任务。

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

ML 流水线任务的配置 | 图片作者

采用 ML 流水线的好处

与将所有代码放在一个笔记本中相比,将代码模块化为 ML 流水线提供了以下特点:

  • 自包含 — ML 流水线中的每个任务都是一个自包含的处理单元。你可以定义必要的配置和依赖关系,并为每个任务选择最合适的计算资源。

  • 重用 — 因为每个任务都是自包含的,任务输出和相关的元数据都存储在一个中央工件位置。因此,你可以灵活决定在触发流水线重新运行时可以跳过哪些任务。例如,如果你只想重新运行模型训练任务,你可以重用之前任务的输出,如数据处理和特征工程。

  • 模块化代码 — 在流水线中,每个任务都模块化了配置和依赖关系,这与通用的 DevOps 标准一致。这可以减少 ML 工程师所需的代码重写工作,并最小化此代码重写过程带来的潜在错误。

因此,构建 ML 流水线带来了以下好处:

  • 快速迭代 — 一旦 ML 解决方案部署到生产环境中,数据科学家可以在必要时更新流水线,他们的代码更改将按照定义的 DevOps 标准合并并部署。这可以显著减少更新 ML 模型所需的时间,并缩短迭代周期。

  • 完全自动化 — 一旦 ML 解决方案部署到生产环境中,所有代码更改将遵循定义的 DevOps 标准并自动部署。因此,数据科学家和 ML 工程师之间无需手动交接。

  • 生产就绪 — 因为所有代码都模块化在流水线中,数据科学家交付的代码基本上是生产就绪的,重写工作可以非常少。

  • 更好的协作 — ML 流水线的构建方式避免了数据科学家和 ML 工程师之间大量不必要的沟通,因为流水线定义和任务配置包含了 ML 工程师部署流水线所需的几乎所有信息。如果所有代码都在一个大笔记本中,ML 工程师肯定需要更多的沟通来寻求明确性。

  • 大规模执行 — ML 管道的快速迭代和完全自动化特性最小化了在生产环境中操作 ML 解决方案所需的人工努力。因此,相同数量的数据科学家和 ML 工程师能够处理更多的 ML 应用。这使得组织能够在有限的资源下扩展 ML 和 AI 的好处。

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

ML 管道的好处 | 图片作者

总结一下,我想重申:

笔记本的输出是一个模型;而管道的输出是一段软件。在生产阶段,部署的是ML 系统,而不是ML 模型 因此,ML 管道是弥合 ML 开发环境(以笔记本驱动)和 ML 生产环境(以系统驱动)之间差距的绝佳机制。

实现 ML 管道的开源框架

如果您现在更有动力生成 ML 管道,而不是创建笔记本,下面是您可以利用的一些开源框架的列表:

  • ZenML — 用于统一您的 ML 技术栈的开源 MLOps 框架

  • MLflow RecipesMLflow 的一个模块,使数据科学家能够快速开发高质量的模型并将其部署到生产环境中

  • Metaflow — 适用于现实世界数据科学和 ML 的框架

  • Kubeflow Pipelines — Kubeflow Pipelines (KFP) 是一个通过使用 Docker 容器来构建和部署可移植且可扩展的机器学习 (ML) 工作流的平台

  • MLRun — 开源 MLOps 编排框架

如果您希望看到我撰写关于构建 ML 管道的实践教程,请在 Medium 上关注我,并留言告诉我您最感兴趣的具体框架。

如果您想查看更多关于现代和高效的数据+AI 技术栈的指南、深入探讨和见解,请订阅我的免费通讯——高效的数据+AI 技术栈,谢谢!

注:如果您还没有成为 Medium 会员,您真的应该成为会员,这样您可以无限制访问 Medium,您可以使用我的推荐链接注册!

非常感谢您的支持!

为什么简单模型往往更好

原文:towardsdatascience.com/why-simple-models-are-often-better-e2428964811a

奥卡姆剃刀在数据科学和机器学习中的重要性

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

·发表于 Towards Data Science ·8 分钟阅读·2023 年 1 月 26 日

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

摄影:Pablo ArroyoUnsplash

在数据科学和机器学习中,简洁是一个重要概念,对模型的性能和可解释性等特性有着显著影响。过度工程化的解决方案往往会通过增加过拟合的可能性、降低计算效率和减少模型输出的透明度,从而对这些特性产生不利影响。

后者对于需要一定解释性领域尤为重要,如医学和医疗保健、金融或法律。无法解释和信任模型的决策,并确保这一决策公平无偏,对那些命运依赖于此的个人可能带来严重后果。

本文旨在强调在实施数据科学或机器学习解决方案时优先考虑简洁性的重要性。我们将首先介绍奥卡姆剃刀的原则,然后深入探讨简洁性的优势,并最终确定何时需要增加复杂性。

奥卡姆剃刀

奥卡姆剃刀,也称为简约法则,是一个哲学问题解决原则,归功于 14 世纪的英语哲学家和神学家威廉·奥卡姆。原始原则通常被引用为Entia non sunt multiplicanda praeter necessitatem,大致翻译为“实体不应超出必要性而被增多”。

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

摄影:Hair SpiesUnsplash

在数据科学和机器学习领域,这通常被解释为“简单模型通常比复杂模型更受青睐”或“在其他条件相同的情况下,最简单的解决方案往往是最好的”。奥卡姆剃刀中的 剃刀 象征着“剃去”不必要的复杂性和假设。

简单解决方案的优势

减少过拟合的敏感性

简单模型的主要优势之一是它们不易过拟合。过拟合发生在模型变得过于复杂并开始拟合训练数据中的噪声,而不是潜在的模式。这通常会导致在未见数据上的表现不佳,结果是模型的泛化能力差,应用性有限。

可以应用几种技术来获得对过拟合敏感性较低的模型:

  • 交叉验证: 模型在训练集上训练,并在独立的验证集上评估其性能。最常见的类型是 k 折交叉验证,其中数据被分成 k 个子集,模型在 k-1 个子集上训练,并最终在剩余的子集(验证集)上进行评估。

  • 数据增强: 较大的数据集往往能减少过拟合。然而,如果没有大数据,可以通过生成人工或合成数据来增强现有数据。具体过程取决于数据的性质。例如,在处理图像数据时,可以通过对图像应用旋转、翻转、缩放等变换来增加数据量。

  • 正则化: 这种技术通过在损失函数中添加惩罚项来限制模型的参数。最常见的技术是 L1(Lasso)正则化和 L2(Ridge)正则化。L1 正则化可以导致一些模型权重被设置为零,从而有效地从模型中移除这些特征,而 L2 正则化仅将权重渐近地减少到零,结果是所有特征都被用来决定模型输出。此外,dropout 是一种常用于神经网络的正则化方法,在每次训练迭代中,随机将一定比例的神经元设置为零。这确保了剩余的神经元学习到更强大的特征,因为它们不再依赖被丢弃的神经元来承担预测的负担。

  • 特征选择: 从训练数据中删除被认为是冗余或不相关的特征将不可避免地简化模型并提高其计算性能。特征可以通过领域知识手动删除,也可以通过单变量过滤、基于树的特征重要性、递归特征消除等方法删除。

  • 降维: 与特征选择类似,降维技术如主成分分析(PCA)、线性判别分析(LDA)或 t 分布随机邻居嵌入(tSNE)将输入维度减少到模型中。然而,它们返回的特征要么是原始特征的线性组合,要么是非线性组合,这会减少模型的可解释性,因为很难确定哪些原始特征对模型的决策做出了贡献。

  • 早停法: 这是应用于神经网络的一种方法,当模型在验证集上的性能开始下降时,停止模型训练。本质上,它通过在模型变得过于复杂之前停止训练来防止过拟合。

  • 减少模型复杂性: 选择一个初始参数较少、架构更简单的模型也可以显著有助于防止过拟合。

提高计算效率

更简单的模型通常能提升计算性能。这种提升主要通过模型需要更少的参数更少的计算更低的内存使用来实现。

在模型部署方面,这也可能带来显著的好处。由于更简单的模型通常具有较低的推理时间和内存使用,因此它们可以更容易地部署到资源受限的设备,如智能手机和智能手表,从而可能建立一个新的客户群体。

例如,在自然语言处理领域,简单的 n-gram 模型已被证明能够与其神经网络模型表现相当,同时速度明显更快。Doval & Gómez‐Rodríguez(2019)比较了递归神经网络和 n-gram 模型在词汇分割任务上的表现,发现 n-gram 模型的精度几乎与神经网络方法相当。此外,n-gram 模型在执行时间上显著优于递归神经网络。

同样,在光学字符识别中,简单的 k 近邻(kNN)算法已被证明在某些任务上具有与卷积神经网络(CNNs)相似的准确度,同时执行时间显著较短。例如,Sharma 等(2022)评估了各种分类器在手写数字识别任务上的性能,发现虽然 CNN 的准确度为 98.83%,但轻量级 kNN 的表现几乎一样好,准确度为 97.83%,同时具有更好的计算性能。

提高可解释性

能够解释模型的决策,并确保这些决策不不公平或有偏见,这是至关重要的,尤其是在那些结果可能对个人造成严重后果的领域。

医学影像领域,例如,医生能够解释、理解并信任他们的模型结果是很重要的。如果放射科医生无法确认或反驳模型对癌症诊断的负面预测,他们可能会要求进一步的检查——一些需要侵入性程序——以确立诊断。如果这些检查最终确认患者没有癌症,可以说,由于模型的不可解释性,患者暴露于不必要的侵入性程序中,而这些程序本可以避免,如果放射科医生能在最初就信任模型的决定。

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

图片由国家癌症研究所提供,发布在Unsplash

类似地,预测模型的输出可以决定癌症患者是否接受治疗。显然,这些结果对相关个人可能有重大后果,因此模型必须足够简单,以便透明和可信。

信用评分中,一个不透明的模型可能会产生与现实完全脱节的偏见结果。想象一个旨在预测信用 worthiness 的模型,如果它在包含各种偏见的历史数据上训练,就会导致它偏向某些群体。如果一个来自被低估群体的人申请贷款,该模型可能会认为他们是高风险借款人,从而拒绝申请,即使他们实际上有良好的信用记录。这种模型缺乏可解释性可能严重影响那些计划购买房屋、创业或探索需要一些初始资本的机会的个人。

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

图片由艾蒂安·马丁提供,发布在Unsplash

相同的原则适用于刑事司法领域。想象一个用于预测个人再犯罪概率的模型,这个模型基于个人信息、犯罪历史和各种其他因素。如果该模型在偏见数据上训练,它可能会偏向社会经济地位较高的群体,因此预测其他群体的再犯罪可能性更高。来自低社会经济地位的个人可能因此被拒绝保释并继续拘留,即使实际上他们可能再犯罪的风险非常低。再次强调,使用一个既简单又透明的模型可以减少这些不良结果的概率。

在上述所有类别中,实现更高可解释性的最简单方法是选择更简单的模型。例如,选择基于决策树的算法而不是复杂的神经网络,可以显著提高输出的透明度,因为内部树结构可以轻松可视化。这使得个别决策可以被追溯,从而提供有关特定预测形成过程的关键见解。这使得决策树在预测错误可能产生严重后果的领域(如上述所列)中广泛适用。

复杂性必要时

虽然简单通常更好,但这并非总是如此。一个过于简单的模型可能会遗漏特征与目标变量之间的相关关系,最终导致欠拟合。

在处理具有非线性关系大规模高维数据集时,可能需要更复杂的模型,如神经网络,以捕捉数据中的潜在模式。

某些应用可能还具有高准确性要求,简单模型无法满足。当实施更复杂的模型以提高性能时,结果通常是透明度降低。因此,找到模型性能与可解释性之间的平衡也很重要。例如,在医学影像中,高准确性对于检测异常和做出有关患者生命的决策至关重要。然而,如上所述,同样重要的是医生能够理解、解释和信任这些决策,以建立可靠的诊断程序。

结论

尽管简单模型确实不是所有问题的万灵药,但在需要高可解释性和计算效率时,它们是首选。此外,它们往往能防止过拟合,从而提高模型的泛化能力和适用性。

在某些情况下,确实有必要增加解决方案的复杂性。当处理高维非线性数据或当解决方案需要高度准确性而简单模型难以实现时,这种情况尤为常见。

参考文献

[1] Doval & Gómez‐Rodríguez (2019). “比较神经网络与 N-gram 语言模型进行词语分割*”。* J Assoc Inf Sci Technol, 70(2): 187–197.

[2] Sharma (2022). “识别手写数字的机器学习和深度学习方法*”。* Comput Intell Neurosci, doi: 10.1155/2022/9869948.

为什么 SOLID 设计很重要:避免代码异味并编写可维护的代码

原文:towardsdatascience.com/why-solid-design-matters-avoid-code-smells-and-write-maintainable-code-553b3c6c0ca8

使用 SOLID 原则来设计可读、可扩展和易于维护的软件

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

·发布于 Towards Data Science ·阅读时间约 11 分钟·2023 年 1 月 6 日

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

照片由 Markus Spiske / Unsplash 提供

引言

SOLID 是面向对象设计的五个原则的首字母缩略词,这些原则最早由Robert C. Martin在 2000 年代初期提出。这些原则可以帮助开发人员创建更易于维护和扩展的软件系统。五个原则是:

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

所有五个 SOLID 原则——由作者可视化

在本文中,我想展示 SOLID 原则在构建可读和可维护的软件应用程序中的威力。此外,我还将提供如何使用 TypeScript 应用 SOLID 原则的实际示例。

这些例子将展示如何使用 SOLID 原则来设计和构建更好、更具可扩展性的应用程序。

无论你是开发人员、数据科学家,还是去中心化应用的用户,这些例子都将为你提供应用 SOLID 原则于代码中的宝贵起点。

单一职责原则

每个模块应当有且仅有一个变更的理由。

  • Robert C. Martin

单一职责原则是一个面向对象设计的原则,规定一个类或模块应当只有一个职责或变更的理由。这意味着一个类应该有明确的范围,并且不应承担过多职责。

在 TypeScript 中,单一职责原则可以通过将一个大型复杂类划分为更小且更专注的类来应用,每个类都有其明确的职责。例如,考虑一个负责管理用户账户信息的类,包括他们的个人资料细节、偏好设置和支付信息。这个类可能有许多处理用户账户不同方面的方法,例如更新个人资料、管理偏好设置和处理支付。

为了应用单一职责原则,我们可以将这个大型类拆分为几个较小的类,每个类都有特定的职责。例如,我们可以有一个 UserProfile 类,负责管理用户个人资料信息,一个 UserPreferences 类,负责管理他们的偏好设置,以及一个 UserPayments 类,负责处理他们的支付。每个类都有一个狭义的范围,它们比原来的单体类更容易维护和扩展。

下面是这些类在 TypeScript 中可能实现的示例:

class UserProfile {
  constructor(userId) {
    this.userId = userId;
  }

  loadProfile() {
    // load the user's profile details from the database
  }

  updateProfile(data) {
    // update the user's profile details in the database
  }
}

class UserPreferences {
  constructor(userId) {
    this.userId = userId;
  }

  loadPreferences() {
    // load the user's preferences from the database
  }

  updatePreferences(data) {
    // update the user's preferences in the database
  }
}

class UserPayments {
  constructor(userId) {
    this.userId = userId;
  }

  loadPaymentMethods() {
    // load the user's payment methods from the database
  }

  processPayment(data) {
    // process a payment for the user using the specified payment method
  }
}

在这个示例中,每个类都有一个狭义的职责和一个明确的接口。UserProfile 类负责管理用户个人资料信息,UserPreferences 类负责管理他们的偏好设置,而 UserPayments 类负责处理他们的支付。

这使得理解每个类的目的和行为变得更容易,同时也使得扩展和维护代码变得更加简单。

开放/封闭原则

模块应该对扩展开放,但对修改封闭。

  • 罗伯特·C·马丁

开放/封闭原则是面向对象设计的一项原则,表示一个类应该对扩展开放,但对修改封闭。这意味着该类应该以某种方式设计,以便可以通过继承或组合添加新行为,而无需更改现有代码。

在 TypeScript 中,可以使用抽象类、接口和多态性来应用开放/封闭原则,以创建灵活且可扩展的设计。例如,考虑一个简单的 Shape 类,表示不同的几何形状,如圆形、正方形和三角形。这个类可能有一个 draw() 方法,可以用来在屏幕上渲染任何形状。

为了应用开放/封闭原则,我们可以定义一个抽象的 Shape 类,该类包含所有形状的共享行为,例如 draw() 方法。然后,我们可以为每种特定类型的形状定义子类,例如 CircleSquareTriangle,这些子类继承自 Shape 类并重写 draw() 方法以提供其特定行为。

下面是如何在 TypeScript 中实现这一点的示例:

// define the abstract Shape class
class Shape {
  constructor() {}

  // the draw() method is abstract and must be implemented by subclasses
  draw() {
    throw new Error('The draw() method must be implemented by a subclass.');
  }
}

// define the Circle class, which extends the Shape class
class Circle extends Shape {
  constructor(radius) {
    super();
    this.radius = radius;
  }

  draw() {
    // draw a circle with the specified radius
  }
}

// define the Square class, which extends the Shape class
class Square extends Shape {
  constructor(sideLength) {
    super();
    this.sideLength = sideLength;
  }

  draw() {
    // draw a square with the specified side length
  }
}

// define the Triangle class, which extends the Shape class
class Triangle extends Shape {
  constructor(sideLengths) {
    super();
    this.sideLengths = sideLengths;
  }

  draw() {
    // draw a triangle with the specified side lengths
  }
}

在这个例子中,Shape 类是开放扩展的,因为可以定义新的子类来添加新行为。我们可以定义一个 Rectangle 类,扩展 Shape 类并重写 draw() 方法来提供其特定行为。然而,Shape 类是封闭修改的,因为我们不能在不破坏扩展它的子类的情况下更改 Shape 类中的现有代码。

这使得代码更加灵活和可维护,因为我们可以在不改变现有代码的情况下添加新行为。

里氏替换原则

使用接口/协议来分离可替换的部分。

  • 罗伯特·C·马丁

里氏替换原则是面向对象设计的一个原则,指出程序中的对象应该可以用其子类型的实例来替换,而不会改变程序的正确性。这意味着子类应该能够扩展或重写其父类的行为,而不破坏父类的合同。

换句话说,里氏替换原则是一种确保子类型可以替代其基类型的方式,这意味着任何编写为使用基类型的程序,在使用子类型时应该能够正常运行,而无需修改。

在 TypeScript 中,通过定义一个类并确保子类扩展它,可以应用里氏替换原则。例如,考虑一个简单的 Vehicle 类,它表示不同类型的车辆,如汽车、摩托车或船只。这个 Vehicle 类可能包括 startEngine() 方法,以及所有车辆共有的其他方法或属性。然后,我们可以为每种具体类型的车辆定义子类,如 CarMotorcycle,这些子类扩展了 Vehicle 类,并提供 startEngine() 方法的具体行为。

下面是如何在 TypeScript 中实现这一点的示例:

class Vehicle {
  startEngine() {
    throw new Error('The startEngine() method must be implemented by a subclass.');
  }

  stopEngine() {
    throw new Error('The stopEngine() method must be implemented by a subclass.');
  }
}

class Car extends Vehicle {
  startEngine() {
    console.log("Starting the engine of a car");
  }

  stopEngine() {
    console.log("Stopping the engine of a car");
  }
}

class Motorcycle extends Vehicle {
  startEngine() {
    console.log("Starting the engine of a motorcycle");
  }

  stopEngine() {
    console.log("Stopping the engine of a motorcycle");
  }
}

function useVehicle(vehicle) {
  vehicle.startEngine();
  // Do some other stuff with the vehicle...
  vehicle.stopEngine();
}

const vehicle = new Car();
useVehicle(vehicle);

const vehicle = new Motorcycle();
useVehicle(vehicle);

在这个例子中,CarMotorcycle 类是 Vehicle 类的子类型。useVehicle() 函数期望一个 Vehicle 类型的对象,但由于里氏替换原则,我们可以将 CarMotorcycle 类型的对象传递给这个函数,它将正确工作。

这是因为 CarMotorcycle 可以替代 Vehicle —— 即 CarMotorcycle 类型的对象可以在期望 Vehicle 类型对象的地方使用,而不会改变程序的期望属性。

接口分离原则

客户不应该被迫依赖他们不使用的接口。” — 罗伯特·C·马丁

接口隔离原则是面向对象设计的一项原则,它说明对象的客户端不应被迫依赖于他们不使用的方法。这意味着一个类的接口应该设计成每个接口都服务于特定的目的并被特定的客户端使用。这个原则有助于减少程序中的未使用代码,使程序更加高效和易于维护。

这个原则的动机是避免单一接口的问题,这种接口定义了许多可能对所有客户端不相关的方法。这可能导致客户端代码膨胀且难以维护,因为它被迫实现或模拟未使用的方法以满足接口契约。

为了应用接口隔离原则,最好定义多个小而集中的接口,而不是一个单一的庞大接口。这允许每个客户端只实现必要的方法,而不被迫实现未使用的方法。这可以导致一个更加模块化和易于维护的设计,因为接口与其客户端的需求更紧密地对齐。

在 TypeScript 中,接口隔离原则可以通过为程序中的每种对象类型创建小而具体的接口来实现。

例如,考虑一个有两种类型对象的程序:CatFish。一个鱼对象可能有一个 eat() 方法,而猫对象可能有 eat()move() 方法。为了遵循接口隔离原则,我们可以为 CatFish 创建两个独立的接口,每个接口都有其独特的方法:

interface Eating {
  eat(): void;
}

interface Moving {
  move(): void;
}

class Cat implements Eating, Moving {
  eat() {
    console.log('cat eats');
  }

  move() {
    console.log('cat moves')
  }
}

class Fish implements Eating {
  eat() {
    console.log('fish eats')
  }
}

在这个例子中,定义了 EatingMoving 接口。Eating 接口有一个方法 eat(),而 Moving 接口有一个方法 move()

Cat 类被定义为 EatingMoving 的子类型——也就是说,它实现了这两个接口。这意味着 Cat 类需要具体实现 eat()move() 方法。

Fish 类被定义为 Eating 接口的一个子类型。这意味着 Fish 类只需要实现 eat() 方法。Fish 类提供了该方法的实现,但不需要实现 move() 方法,因为鱼的移动方式与其他动物不同。

接口隔离原则通过将大型、通用的接口拆分为更小、更具体的接口,帮助改善程序的设计。

这可以使程序更加高效并且更容易维护。

依赖倒置原则

实体必须依赖于抽象,而不是具体实现。这说明高层模块不应依赖于低层模块,而应依赖于抽象。

  • 罗伯特·C·马丁

依赖倒置原则是一个软件设计原则,它指出高层模块不应该依赖于低层模块,而是两者都应该依赖于抽象。这个原则有助于提高程序的灵活性和可维护性,使程序的不同部分能够独立演进。

在 TypeScript 中,可以通过定义抽象(接口或抽象类)来应用依赖倒置原则,这些抽象定义了程序不同部分的合同。例如,考虑一个有 Database 类和 UserService 类的程序。UserService 类可能依赖于 Database 类来存储和检索用户数据。为了遵循依赖倒置原则,我们可以定义一个抽象 DataStore 接口,Database 类实现这个接口,并让 UserService 类依赖于 DataStore 接口,而不是直接依赖 Database 类。这样,UserService 类就不会绑定到具体的数据存储实现上,可以与任何实现了 DataStore 接口的类一起使用:

// DataStore interface
interface DataStore {
  get(id: string): any;
  set(id: string, data: any): void;
}

// Database class
class Database implements DataStore {
  // Implementation of DataStore methods
}

// UserService class
class UserService {
  constructor(private dataStore: DataStore) { }

  getUser(id: string) {
    return this.dataStore.get(id);
  }

  saveUser(user: any) {
    this.dataStore.set(user.id, user);
  }
}

在这个例子中,UserService 类依赖于 DataStore 接口,并且可以与任何实现该接口的类一起使用。这使得我们可以在不影响 UserService 类的情况下更改 Database 类的实现,或使用任何实现了 DataStore 接口的不同类。

如果应用依赖倒置原则,程序的设计将通过将高层模块与低层模块解耦,并使两者都依赖于抽象来得到改善。

这可以使程序更具灵活性,更容易维护。

小心!避免常见误解

不幸的是,关于 SOLID 原则存在一些误解,并且这些原则很容易被错误使用。

一个常见的误解是,这些原则应该盲目遵循,而不考虑当前项目的具体需求和限制。但实际上,这些原则是可以帮助开发者创建更具可维护性和可扩展性的指导方针。SOLID 原则应始终谨慎和有判断地应用。

例如,为了提高类的性能或简洁性,单一责任原则有时会被违反。

另一个常见的误解是,SOLID 原则只适用于面向对象的语言,如 Kotlin、TypeScript、Java 或 C++。这是错误的,因为这些原则是与语言无关的,可以应用于任何软件系统,无论使用的是何种编程范式或语言。

记住,SOLID 原则并不是一个能够解决软件设计中每一个问题的灵丹妙药。这些原则只是众多工具中的一个,可以帮助开发者创建更好的软件。

它们应该与其他设计原则和实践一起使用,例如重构、测试和持续集成。

结束语

总之,SOLID 原则是一套指导方针,可以帮助开发人员通过专注于创建单一目的、封装良好且易于修改的类和模块,来创建更具可维护性、可扩展性和易于理解的软件。

通过遵守 SOLID 原则,开发人员可以通过编写更易于维护和随时间适应的代码,从长远来看节省时间和精力。

需要明白的是,这些原则不应在所有情况下严格遵循。它们应该被视为可以根据项目的具体用例以不同方式应用的指导方针。

作为开发人员,以灵活和开放的心态对待 SOLID 原则是很重要的。这样,你可以充分利用这些指导方针,并用它们来创建更好的软件。

此外,SOLID 原则在软件设计中并不是新颖或革命性的想法。这些原则基于几十年的面向对象设计经验和研究,并且建立在许多前辈软件开发人员和研究者的工作基础上。

如果你想深入了解如何开发可读、可扩展和可维护的代码,可以查看这个视频(以及接下来的 5 个视频)。这是 Robert C. Martin 的《Coding Better World Together》的第一课,他推广了 SOLID 原则。

Robert C. Martin 的《Coding Better World Together》的第一课

最后,你对 SOLID 原则有什么看法?另外,你是否对这五个原则中的任何一个有疑问?我很愿意听听你的想法并回答你的问题。请在评论中分享你的想法。

欢迎在我的博客LinkedInTwitterGitHub上与我联系。

为什么 Taskgroup 和 Timeout 在 Python 3.11 Asyncio 中如此重要

原文:towardsdatascience.com/why-taskgroup-and-timeout-are-so-crucial-in-python-3-11-asyncio-c424bcc88b89

PYTHON CONCURRENCY

拥抱 Python 3.11 中的结构化并发

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

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

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

图片由Brett Jordan提供,Unsplash

Python 3.11 asyncio 包的新功能

1. 介绍

在去年的 Python 3.11 版本中,asyncio 包添加了TaskGrouptimeoutAPI。这两个 API 引入了官方的结构化并发功能,帮助我们更好地管理并发任务的生命周期。今天,我将向你介绍这两个 API 的使用以及 Python 引入结构化并发后对我们并发编程的重大改进。

2. TaskGroup

TaskGroup 是使用异步上下文管理器创建的,并且可以通过create_task方法将并发任务添加到组中,如下代码示例所示:

当上下文管理器退出时,它会等待组中的所有任务完成。在等待期间,我们仍然可以向TaskGroup添加新任务。

请注意,假设组中的一个任务在等待时抛出asyncio.CancelledError之外的异常,组中的所有其他任务将被取消。

此外,除了asyncio.CanceledError之外的所有异常将被合并并抛出在ExceptionGroup中。

3. 超时

asyncio.timeout 也是使用异步上下文管理器创建的。它限制了在上下文中并发代码的执行时间。

假设我们需要为单个函数调用设置超时,那么调用asyncio.wait_for就足够了:

但当需要为多个并发调用设置统一的超时时间时,问题就会出现。假设我们有两个并发任务,并希望它们在 8 秒内完成。让我们尝试为每个任务分配一个平均超时时间为 4 秒的设置,代码如下:

你可以看到,尽管我们为每个并发方法设置了平均超时,但这种设置可能会导致不可控的情况,因为对 IO 绑定任务的每次调用无法保证同时返回,我们仍然遇到了TimeoutError

在这时,我们使用asyncio.timeout块来确保为所有并发任务设置一个整体超时:

4. 结构化并发是什么

TaskGroupasyncio.timeout 上述使用了async with特性。就像with结构块一样,可以统一管理资源的生命周期:

但在with块中调用并发任务不起作用,因为并发任务会在背景中继续执行,而with块已经退出,这将导致资源的不当关闭:

因此,我们在这里引入了async with特性。像withasync withTaskGroup 用于统一管理并发代码的生命周期,从而使代码更清晰并节省开发时间。我们称这个特性为我们今天的主角:结构化并发

为什么结构化并发如此重要

1. 并发编程的历史

在并发编程出现之前,我们的代码是串行执行的。代码会根据调用栈的顺序依次执行for_loop循环、if_else条件分支和函数调用。

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

作者图片

然而,随着代码执行速度对计算效率的要求越来越高,以及计算机硬件的显著发展,逐渐出现了并行编程(CPU 绑定)和并发编程(IO 绑定)。

在协程出现之前,Python 程序员使用线程来实现并发编程。但 Python 的线程存在一个问题,即 GIL(全局解释器锁),GIL 的存在使得基于线程的并发无法达到预期的性能。

因此,asyncio 协程应运而生。没有全局解释器锁(GIL)和线程间切换,并发执行变得更加高效。如果线程是由 CPU 控制的基于时间片的任务切换,那么协程则是将子任务的创建和切换交到程序员自己手中。虽然程序员享受了便利,但也遇到了一系列新问题。

2. 并发编程模型的问题

正如这篇文章中详细描述的,并发编程引发了有关控制流的几个问题。

并发编程是在主线程中打开多个分支进程。这些分支任务在后台默默地执行网络请求、文件访问、数据库查询等工作。

并发编程将把我们的代码流程从这样改变成这样:

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

作者提供的图片

根据编程中的“低耦合,高内聚”原则,我们都希望在执行后将所有后台任务集中在一个模块中,如下所示:

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

作者提供的图片

但实际上,由于多个成员开发我们的应用程序或调用了许多第三方组件,我们需要知道哪些任务仍在后台执行,哪些任务已经完成。一个后台任务很可能会分支成几个其他的分支任务。

终极目标是这些分支任务需要被调用者找到,并等待其执行完成,因此变成了这样:

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

作者提供的图片

虽然这不是漫威的多元宇宙,但目前的情况就像多元宇宙一样,给我们的自然世界带来了绝对的混乱。

有读者表示,asyncio.gather 可以负责合并所有后台任务。但asyncio.gather也有其问题:

  • 它无法以统一的方式集中管理后台任务。通常是在一个地方创建后台任务,而在另一个地方调用asyncio.gather

  • asyncio.gather 接收的参数aws是一个固定列表,这意味着在调用asyncio.gather时,我们已设置后台任务的数量,它们无法在等待过程中随意添加。

  • 当任务在asyncio.gather中等待时抛出异常时,它无法取消正在执行的其他任务,这可能导致一些任务在后台无限运行,程序错误地终止。

因此,Python 3.11 引入的结构化并发特性是解决我们并发问题的绝佳方案。它允许相关的异步代码在同一位置完成执行,同时,它还使tg实例能够作为参数传递给后台任务,从而使在后台任务中创建的新后台任务不会跳出当前异步上下文的生命周期管理。

因此,结构化并发是对 Python asyncio 的革命性改进。

与其他实现结构化并发的库的比较

结构化并发并不是 Python 3.11 中首个此类特性;在 3.11 之前,我们已经有几个并发基础的包很好地实现了这个特性。

1. Trio 中的托儿所

Trio 是 Python 世界中首个提出结构化并发的库,在 Trio 中,API open_nursery 被用来实现这个目标:

2. **create_task_group** 在 Anyio 中

但随着官方 Python asyncio 包的出现,越来越多的第三方包使用 asyncio 实现并发编程。在这一点上,使用 Trio 不可避免地会遇到兼容性问题。

此时,声称兼容 asyncio 和 Trio 的 Anyio 出现了。它还可以通过 create_task_group API 实现结构化并发:

3. 在低版本 Python 中使用 quattro

如果您希望在未来轻松享受 Python 3.11 asyncio 的便利,保持代码本地化,有一个不错的替代方案,quattro,其星标较少,风险较低。

结论

Python 3.11 引入的 TaskGroup 和 timeout APIs 为我们带来了官方的结构化并发功能。

通过结构化并发,我们可以使并发编程代码更好地抽象化,程序员可以更容易地控制后台任务的生命周期,从而提高编程效率并避免错误。

由于经验有限,如果本文中关于并发编程或结构化并发的内容有遗漏,或者您有更好的建议,请发表评论。我会很感激并回答您。

在下一篇文章中,我们将讨论在 asyncio 中使用不同 APIs 的并发编程最佳实践。您可以在这里阅读:

[## 使用这些方法提升你的 Python 并发任务表现]

asyncio.gather、asyncio.as_completed 和 asyncio.wait 的最佳实践

towardsdatascience.com](/use-these-methods-to-make-your-python-concurrent-tasks-perform-better-b693b7a633e1?source=post_page-----c424bcc88b89--------------------------------)

通过 加入 Medium,您将能够无限制地访问我所有的帖子以及其他成千上万作者的帖子。这只需一杯咖啡的价格,对我来说是极大的鼓励。

本文最初发布于:www.dataleadsfuture.com/why-taskgroup-and-timeout-are-so-crucial-in-python-3-11-asyncio/

为什么似乎存在“免费午餐”

原文:towardsdatascience.com/why-there-kind-of-is-free-lunch-56f3d3c4279f

神经科学与人工智能中模式的普遍性

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

·发表在 Towards Data Science ·11 分钟阅读·2023 年 6 月 27 日

**‘没有所谓的免费午餐。’

  • 罗伯特·A·亨莱因

机器学习领域中的“No Free Lunch”定理让我想起了数学世界中的哥德尔不完备性定理。

虽然这些定理经常被引用,但很少有深入的解释,而且对实际应用的影响往往不明确。正如哥德尔定理成为 20 世纪初数学家对完整自洽形式系统信仰的障碍一样,“No Free Lunch”定理挑战了我们对通用机器学习算法有效性的信任。然而,这些定理对日常实际应用的影响通常较小,大多数从业者在这些理论限制下仍能顺利进行工作。

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

一位机器学习者意识到或许真的存在免费午餐,如 DALL-E 所设想的那样。

在这篇文章中,我想探讨“No Free Lunch”定理的内容,并深入研究它与视觉、迁移学习、神经科学和人工通用智能的关系。

“No Free Lunch” 定理,由 Wolpert 和 Macready 于 1997 年提出,并常用于机器学习的背景中,指出没有一种算法可以普遍适用于所有可能的问题。没有一种神奇的“一刀切”解决方案。一个算法可能在某一任务上表现非常好,但在另一个任务上可能表现不佳。

机器学习的一个基本目标是辨识不同数据中的有意义的模式。然而,算法的有效性通常取决于所处理数据的具体性质。它可能对一种数据类型非常有用,但在应用于另一种数据时效果较差。

当考虑我们可能遇到的不同类型数据时,这一点变得显而易见。像抛硬币这样简单的事情生成了两种模式的简单概率分布。

另一方面,实际中更重要的例子,如图像数据或文本数据,复杂得多。潜在模式的宇宙随着像素数量的增加而呈指数增长,使得一个 500x500 图像中的所有可能配置的数组已经巨大到难以想象:

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

鉴于这个空间的大小,我们如何仍然能从数据中学习到有意义的东西?

答案的一个重要部分是,大多数感兴趣的样本不是从所有可能样本空间中均匀采样的,而是与随机采样相比,带有大量的预先存在的结构。

语言数据是另一个经典例子。任何给定语言中所有单词的总和包含了一组模式的子集,与所有可能的字母组合集合相比,这些模式处于一个维度更低的空间,这一点在语言的第一个简单统计模型中被使用了(我在我的马尔可夫链文章中对此进行了更深入的探讨)。

对于机器学习者来说,许多类型的输入数据中存在一些重复出现的模式无疑是一个好消息。这意味着我们可以训练模型来学习提取这些模式,并可能将这些模型重新用于不同应用中的类似模式提取。

迁移学习技术明确利用了大多数现实世界问题共享某些共同结构这一事实。

迁移学习使用已经从大型数据集中学习到模式的预训练模型,来适应并**“微调”**到不同但相关的任务。一个训练用于识别图像中的物体的模型可能已经学会了诸如边缘和颜色渐变等低级特征,以及形状等高级特征。这些学到的特征可以应用于相关任务,例如识别手写数字或在医学图像中分类肿瘤。

Hubel 和 Wiesel 通过发现视觉皮层由处理越来越复杂模式的层次组成,从而获得了 1981 年的诺贝尔奖。自卷积神经网络(CNNs)出现以来,他们的工作在机器学习算法中得到了广泛的讨论。

例如,在初级视觉皮层中,简单细胞检测边缘和颜色梯度,而复杂细胞则将这些简单细胞的输出聚合以识别更广泛的模式,如运动或特定形状。深入到视觉系统中,神经元识别的模式变得越来越复杂,从简单的几何形状到面孔和复杂的物体,最终到达那种(不)著名的“奶奶神经元”,它只在你看到奶奶(或你品尝她小时候给你的玛德琳蛋糕时)才会激活。

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

通过在 ImageNet 数据上训练的卷积神经网络(Inception V1)所学到的特征。从左到右,特征的复杂性逐渐增加。图来自 Olah 等人(2017,CC-BY 4.0)distill.pub/2017/feature-visualization/appendix/

同样,CNN 的各层提取了逐渐复杂的特征。在初始层中,CNN 可能会学习检测简单的结构,如线条、角度和颜色块。随着层次的推进,这些简单特征被组合成更复杂的表示:圆形、矩形,最终是开始看起来像猫、狗或大象的可辨识物体。

也许这些相似之处不应该令人感到惊讶:两个系统都进化并被设计出来,分别用于利用视觉数据中固有的结构。对所有类型的视觉场景中最常出现的模式的理解可以被重新利用或转移,以处理不同但相关的任务,就像之前讨论的那样。

这就是迁移学习的概念和大脑适应及学习能力发挥作用的地方。一个学会识别自行车的孩子,在学习识别摩托车时不会从零开始。他们将自行车的基本结构理解转移到另一个情境中。同样,一个在各种图像上训练的 CNN 在从识别面孔切换到识别手写数字时,不需要重新学习“边缘”的概念。

我们的大脑发现了支撑我在标题中讨论的**‘免费午餐’**的相同真理:对我们有用的世界远非完全随机,而是充满了反复出现的模式和结构。鉴于这些模式是我们感兴趣的内容,我们的大脑被硬编码以选择性地感知它们。

我们甚至可以进一步说,我们的运气不仅仅是因为世界上存在有意义的模式。现代认知神经科学理论认为,大脑更像是一个预测机器,而不是一个‘现实’感知工具。

贝叶斯脑假说例如,建议我们的脑袋不断地对世界进行概率预测,并根据感官输入更新这些预测。因此,我们对世界的感知不是一个被动的过程,而是一个主动的过程。我们不仅仅是感知世界的真实情况,而是根据我们的先验知识积极地解释它,其中一些先验知识基于我们的记忆经验,但一些则回溯到由数十亿年的进化经历所产生的结构性先验。

认知的主动、先验驱动成分对我们的感知有着如此显著的影响,以至于像阿尼尔·塞思这样的科学家将我们大脑的活动称为类似于‘受控幻觉’的东西。

这也与唐纳德·霍夫曼的挑衅性观点(反对现实的观点)相关,该观点认为我们并没有按原样感知现实,而是感知在数百万年的发展过程中成为一种‘用户界面’,其主要目标是帮助我们的生存。例如,计算机桌面上的图标并不揭示机器内部发生的真实情况,而是提供一个使你可以轻松使用计算机的界面。

我们感知的红色苹果并非苹果本身,而是引导我们获得营养食物的表现形式。我们的感知系统因此对我们的感官输入施加了强烈的先验,过滤掉大量不符合我们现有模型的数据或不直接有助于我们生存的数据。这种对显著模式的偏好以及远离感知噪声(如我上面展示的噪声图片中所有可能的视觉模式)反映了我们讨论过的结构,这种结构是迁移学习和**‘某种免费午餐’**在机器学习中的基础。

我们的大脑就像是预训练模型,已经学会只关注世界上某些模式,帮助我们应对不断涌入的新感官输入。

随着年龄的增长,我们更不容易反转我们的模型并在看不见的模式出现时进行微调,更多的是将脑海中的推理机器视为(自我感知的)免费午餐的极致表现:按照这种说法,‘老白人’是一个通过已经牢固建立的世界模型的视角来解释他所遇到的一切的人,这个模型(在他看来)是从每一个学习问题中获得免费午餐的普遍算法。

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

生成的老白人政治家,傲慢地微笑,因为他认为自己什么都知道。 我发誓它自己生成了英国国旗。

说笑归说笑,尽管在模态内迁移学习至关重要,我们的讨论也很自然地扩展到神经科学和机器学习中的多模态设置的当前发展。

大脑具有惊人的重组能力,称为神经可塑性,这种能力在中风或其他剧烈的感官丧失情况后经常被观察到。

感觉丧失常常导致某些大脑区域的重新利用。例如,盲人常常发展出更敏锐的听觉和触觉。这不仅仅是注意力或练习的结果。研究显示,通常处理视觉信息的视觉皮层在盲人的听觉和触觉任务中也会变得活跃(David Eagleman 的《Livewired》一书对神经可塑性在大脑中扮演的核心角色进行了极好的阐述)。

就好像大脑已经接受了一个在视觉任务上预训练的神经网络,并在发现自己不再接收视觉输入后,将其微调以处理听觉和触觉信息一样。

类似地,研究发现聋人使用的脑区通常与处理语言有关,例如 Broca 区和 Wernicke 区,这些区域在使用手语时也会被激活。这些区域专注于更广泛的沟通,而不论该沟通的具体模态是什么。大脑的语言网络足够灵活,能够处理不同形式的沟通——无论是口语、书面语还是手语。

这些神经可塑性的实例表明,我们大脑的计算是基于一种普遍学习算法,这种算法能够处理各种模式,而不仅仅是那些通常与特定感觉模态相关的模式。这个算法究竟是什么仍有争议(例如,Jeff Hawkins 的《千脑理论》或 Kurzweil 的模式识别器提供了流行的神经科学解释,《The Master Algorithm》一书由 Pedro Domingues 提供了计算机科学的视角),但神经可塑性清楚地表明类似的东西确实存在。

大脑的多功能性也体现在我们最先进的机器学习模型上。虽然变压器最初是为自然语言处理而开发的,反映了语言的归纳偏差,但它们随后被应用于各种数据类型,从图像和音频到时间序列数据(这是否主要是因为当前对它们的炒作还有待讨论)。正如盲人的视觉皮层可以重新用于听觉或触觉任务一样,变压器也可以适应多种数据类型,这暗示了这些模型可以捕捉的普遍模式的存在,不论具体的输入模态(公平地说,这也可能部分因为变压器非常适合在当前计算架构上进行优化,因为它们可以被高度并行化)。

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

基本变压器架构。Yuening Jia,CC BY-SA 3.0。

引用 Wolpert 和 Macready 的原始 NFL 论文:“任何两个优化算法在其性能在所有可能的问题中平均时都是相等的。”但套用 Orwell 的话,当我们查看真正关心的大多数问题时,一些优化算法比其他算法更为平等。

例如,将 Transformers 应用到图像数据中,产生了像 Vision Transformers 这样的模型,这些模型将图像视为一系列的补丁,并应用相同的自注意力机制。

这个理念在多模态 Transformers 中得到了进一步的体现,这些模型可以同时处理和理解多种类型的数据。像 CLIP 模型这样的文本和图像嵌入被训练来同时理解图像及其相关的文本描述。CLIP 通过将这两种模态结合到一个联合嵌入空间中来学习它们之间的关系。

这些模型利用不同数据类型之间的共同结构,有效地创建了它们之间的“翻译”系统。CLIP 的这一能力的一个显著例子现在大多数人都熟悉:通过为基于扩散的模型如 DALL-E 提供基础,它们使我们能够仅凭文本描述生成令人印象深刻的图片。

这种效果之所以如此良好,也许并非全然巧合:语言中的基本意义单元可能在视觉处理上有对应物,而视觉感知也可能在有限的一组基本视觉模式或‘视觉词汇’的概念下被理解。

在语言中,对人类最有意义的单元,如‘cat’、‘dog’或‘love’,都是短小的,语言的结构与我们在视觉场景中具有重要性的相同概念一致:互联网很可能包含比喧闹的颜色斑块更多的猫的图片。更一般地说,值得注意的是语言已经是一种衍生模态,是一个大型群体共同发展起来的,用以将所有对他们最重要的事物浓缩为简洁的符号表示。

也许最深刻的是,“kind of is free lunch”这一事实还与人工通用智能(AGI)有关,因为 AGI 是一种能够从大多数应用中获得“免费午餐”的算法。

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

DALL-E 设想中的 AGI。

想象一下 Chat-GPT:尽管 GPT 模型完全基于文本进行训练,但它们开始表现出理解、推理和交流关于世界的能力,远远超出了文本数据的范围。尽管这些模型仅被训练来预测文本数据,它们似乎挖掘出了一种超越文本的普遍逻辑,扩展到不同的模态和理解维度。

尤其是当与其他模态共同训练时,LLMs 超越了对该模态的文本描述,而是理解超越模态的潜在模式,并能从中生成新颖的想法,这类似于大脑的功能。

我认为,人们(包括我自己)对 LLMs 在实现泛化智能方面取得成功感到如此惊讶的原因之一是,我们集体低估了对我们最显著的感知世界在多大程度上已经依赖于模式的普遍性以及我们大脑中相应的学习算法的普遍性。

虽然免费午餐定理在理论上是成立的,但显然大多数让我们最关心的问题在统计意义上远非普遍。相反,它们往往占据一个较低维度的空间,主要关注视觉、语言和声音,这是人类兴趣和显著性的主要领域。

在多模态大型语言模型的出现中,我们拥有一个算法框架,它利用了这些低维和跨模态的表示。它提供了一个激动人心且稍微有些吓人的预览,展示了 AGI 的潜力,以及它可能如何改变我们的世界和对世界的理解。

感谢阅读!

如果你喜欢我的写作,请订阅以通过邮件获取我的故事,或者考虑成为推荐会员

为什么企业 AI 中的信任与安全(相对来说)很简单

原文:towardsdatascience.com/why-trust-and-safety-in-enterprise-ai-is-relatively-easy-32de240788d0

数据驱动的领导力与职业生涯

为什么传统 AI 比生成式 AI 具有更高的可靠性优势

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

·发表于 Towards Data Science ·阅读时间 5 分钟·2023 年 5 月 31 日

本系列的第一部分中,我说了一句我认为自己永远不会说的话:当我们处理典型的企业规模 AI 系统时,信任和安全是容易的。

什么?!亵渎!

听我说。

是的,确实,这实际上很难。但这种难度与新一波生成式 AI带来的信任与安全难题相比显得微不足道。原因如下。

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

所有图片版权归作者所有。

想象一下,你是一个没有基于 AI 的票价系统的航空公司首席执行官。你的幕僚长气喘吁吁地跑进你的办公室,告诉你组织中的一些数据专家团队距离全面推出 AI 定价系统只有几个小时,但他们被听到说,“我不知道这个 AI 系统的好坏。不知道它能赚多少或亏多少……但它看起来有用,所以我们就启动吧。”

头会滚。这样的系统影响力和潜在商业影响过于巨大,无法容忍这种程度的草率。你很可能会解雇所有与这个完全失控的情况有关的人员,你这样做是对的。毕竟,作为首席执行官,航空公司成功的最终责任落在你身上,鉴于他们几乎把你的企业置于不适当的风险之中,清除这群小丑将是显而易见的。整个情况简直是犯罪般的愚蠢。你的公司没有他们会更好。

不管你怎么说大型组织,但它们有一件事做得不错,那就是避免一切轻率地动摇现状的事情。

通常,这样的问题在到达 CEO 的桌面之前就已经被解决了。不管你对大型组织有何评价,但它们通常擅长避免任何轻率的风险。它们内在地倾向于谨慎而非冒险,这就是为什么企业级人工智能系统通常只有在(1) 可以证明解决一个具体问题非常有效,或(2) 具有可以证明的低潜在危害(因为风险低,错误不会非常尴尬/痛苦,或因为应用的重要性较低)时,才会被推出。

人工智能系统存在的直接性是一个极其强大的简化工具。

从航空公司的角度来看:

(1) 一个人工智能定价系统,该系统经过仔细推出、逐步扩展,并经过统计测试,确保至少能带来*x%*的正面收入影响。

(2) 一个人工智能发音系统,使登机口工作人员可以听到关于如何宣布乘客姓名的数据驱动的最佳猜测,以帮助工作人员在不确定发音时使用。这样的系统几乎不具有关键任务性质,并且它的好处在于能够向世界展示你在做人工智能,而风险很小。此外,当训练有素的人员审批所有输出时,系统的无害性更容易实现,因此你会希望你的登机口工作人员使用他们的判断。

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

“你想让我怎么发音?”(当人们需要发音我的姓氏 Kozyrkov 时,我常常会收到这种困惑的表情。我告诉他们只需说“咖啡壶”,没有人会注意到。)所有图片版权属于作者。

要点是,除非信任和安全问题已经因应用本身的特性而被最小化,否则企业级人工智能系统在没有证明其潜在收益值得冒险的情况下是不可能获得实际应用的……而在系统的价值不明确时,这种证明是无法获得的。

为什么这使事情变得简单?因为这意味着每个关键任务的传统企业级人工智能系统(第(1)类)往往具有:

  • 一个相对直接的用例声明

  • 对系统期望的“良好行为”的愿景

  • 一个明确的、单一的目标

  • 可衡量的性能

  • 明确定义的测试标准

  • 对可能出现的问题及因此需要的安全网有相对清晰的认识

这里也有很多挑战,比如如何确保这样的系统与所有现有的企业系统兼容(请参见我的 YouTube 课程及更多内容),但系统存在的直接性是一个极其强大的简化工具。

这里的关键见解是,企业级解决方案的经济学往往倾向于规模。旨在大规模部署的系统通常有一个明确的目的,否则聪明的领导者会直接把它们送到垃圾压缩机。这就是为什么过去十年中大多数企业级 AI 系统都是为了在规模上做一件非常具体的事情而设计的。

过去十年中大多数企业级 AI 系统都是为了在规模上做一件非常具体的事情而设计的。

这对信任和安全来说是一个巨大的优势。非常大!当然,确保你的系统在面对“长尾”(即异常用户)时能保护用户仍然需要大量的通用可靠性工作,但保护一个多样化的用户群体免受单一目的、单一功能系统的影响,比保护相同的用户群体免受功能系统的影响要容易得多。从大多数企业的角度来看,生成式 AI 系统从根本上是多功能和多用途的。

这就是关键的见解,所以让我们重复一下:

保护一个多样化的用户群体免受单一目的系统的影响,比保护相同的用户群体免受多功能系统的影响要容易得多。

如果你想更好地理解这个见解,请继续阅读这个系列的第三部分

另一方面,如果你觉得最后一个见解对你来说显而易见,那么可以跳过第三部分,直接阅读第四部分,我将解释为什么生成式 AI 不具备这些简化特征以及这对 AI 监管意味着什么。

感谢阅读!怎么样,来一门课程?

如果你在这里玩得开心,并且你在寻找一个既能让 AI 初学者和专家都感到愉快的、有趣的领导力导向课程,这是我为你准备的一点小东西

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

课程链接:bit.ly/funaicourse

[## 加入 Medium

阅读 Cassie Kozyrkov 的每一篇故事(以及 Medium 上的成千上万其他作家的文章)。你的会员费将直接支持……

kozyrkov.medium.com](https://kozyrkov.medium.com/membership?source=post_page-----32de240788d0--------------------------------)

P.S. 你是否尝试过在 Medium 上多次点击鼓掌按钮看看会发生什么? ❤️

喜欢作者?与 Cassie Kozyrkov 联系

让我们成为朋友吧!你可以在TwitterYouTubeSubstackLinkedIn找到我。有兴趣让我在你的活动上发言吗?请使用这个表单与我联系。

为什么理解数据生成过程比数据本身更重要

原文:towardsdatascience.com/why-understanding-the-data-generation-process-is-more-important-than-the-data-itself-f1b3b847e662

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

图片来源:Ryoji Iwata 通过 Unsplash

“为什么”第五章和第六章,读书系列

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

·发布于 Towards Data Science ·15 分钟阅读·2023 年 12 月 7 日

在婴儿早期阶段,我们的大脑已经学会将相关性与因果性联系起来,并试图为我们周围发生的每一件事找到解释。如果我们身后的车在很长一段时间里做出与我们相同的转弯,我们会认为它在跟随我们,这是一种因果假设。然而,当我们从电影的情节中清醒过来时,我们会认为我们只是正好前往同一个目的地——一个混淆因素。一个共同的原因在两辆车的运动之间引入了相关性。Pearl 给出的这个生动且贴切的例子证明了人脑是如何工作的。

那些我们无法找到合理解释的相关性呢?例如,某些在整个群体中不相关但在住院人群中相关的疾病。如果你回忆一下我上一篇文章讨论的不同因果结构,它指出对碰撞点(住院患者)的条件生成了一种解释效应,使得两个不相关的变量虚假地相关。换句话说,住院人群并不是普通人群的准确代表,从这个样本中得出的任何观察结果都不能推广。

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

碰撞偏差,作者根据《为什么》一书第六章制作的图像

碰撞引起的相关性对人脑来说不直观,因此产生了这些所谓的悖论。在这篇文章中,我将探讨更多有趣的悖论,这些悖论像魔术一样在我们的大脑中制造视觉错觉,但可以通过因果图进行解释。了解这些悖论的原因是有意义和有教育意义的。这是“和我一起阅读”系列的第 4 篇文章,基于犹大·珍珠的《为何之书》第五章和第六章中的内容。根据珍珠在这两个章节中提供的所有例子,这应该是一次有趣的阅读体验!你可以在这里找到上一篇文章:

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

Glenn Carstens-PetersUnsplash 提供的照片

让我们来做交易

美国电视节目“让我们来做交易”展示了一个著名的统计问题,称为“蒙提霍尔问题”,以节目主持人蒙提·霍尔的名字命名。在这个游戏中,参与者面临三扇门,其中一扇门后面有一个非常抢手的奖品,如汽车,而其他两扇门后面是较不受欢迎的奖品,通常幽默地称为山羊。规则如下:

  • 第一步:参与者选择三扇门中的一扇作为初始选择,比如门 1;

  • 第二步:主持人知道每扇门后面是什么,打开其他两扇门中的一扇,揭示出山羊,比如门 3;

  • 第三步:参与者可以选择坚持原来的选择,或换到剩下的未开门,即参与者可以保留门 1 或选择门 2。

赢得汽车的最佳策略是主持人揭示另一扇门后面的山羊后始终选择换门。如果你想查看详细的计算,可以在本文的第 9 个问题中找到使用贝叶斯统计的计算方法。

## 12 个数据科学面试概率练习题

自信地通过数据科学面试,第三部分

towardsdatascience.com

或者,你可以参考下面的表格,显示了三种情景和切换或不切换的结果,假设参与者选择了门 1。第一行显示汽车在门 1 中,主持人可以打开门 2 或门 3 来揭示山羊。如果参与者切换,他们会失败。在第二行中,主持人必须打开门 3 来揭示山羊,类似地,主持人只能打开门 2 来揭示山羊。由于参与者选择任何门作为初始选择的概率是相等的,通过比较“切换”和“不切换”的列,我们可以看到切换门的获胜概率为 2/3,而不切换的概率为 1/3。因此,切换门是一种更优的策略。

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

表格由作者根据《为什么的书》第六章制作

这可能看起来有些违反直觉,因为这意味着节目制作人似乎能够猜到参与者的初始选择。切换策略比不切换更受欢迎,这表明参与者的初始选择与汽车的位置有关,而直观地说,这两个变量应该是相互独立的。那么这里的解释是什么呢?我们可以通过这个因果图来解决这个悖论:

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

图片由作者根据《为什么的书》第六章制作

这个因果图展示了混杂偏倚。节目规则的第 2 步表明,根据汽车的位置和参与者的第一次选择,主持人只会选择打开山羊门。这个规则实际上增加了信息。主持人打开门 3 而不是门 2,使得门 2 更可能有一辆汽车在后面。条件化在混杂因子下,在这种情况下,考虑到主持人打开了门 3,参与者的第一次选择门 1 更不可能是汽车位置,因为切换是更好的策略。

如果我们改变游戏规则,在第 2 步中,主持人可以打开任何门,即使门后面有汽车,那么结果会是什么?下面的表格展示了初始选择门 1 的参与者的所有可能情景:

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

表格由作者根据《为什么的书》第六章制作

现在,如果我们根据最后两列的结果计算切换或不切换的获胜概率,我们可以看到没有区别。两种策略的获胜概率都是 1/3。结合因果图:

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

图片由作者根据《为什么的书》第六章制作

在第 2 步中修改规则去除主持人打开的门与汽车位置之间的因果关系。因此,参与者初始选择与节目制作人放置汽车的位置之间的虚假相关性消失了。

在这种情况下,即使数据(主持人打开的门)相同,修改数据生成过程(规则)也会指向不同的策略。

重新审视辛普森悖论

辛普森悖论也是一个广为讨论的著名困惑。当我们观察总体和子总体之间两个变量的不同关系时,我们应该信任哪个结果?例如,如果一种药物对男性组和女性组分别有害,但对整个群体有益,我们是否仍然应批准这种药物?

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

Brendan Church 的照片,来自 Unsplash

Pearl 认为

辛普森悖论的困惑源于因果原则在统计比例中的不正确应用

通过使用因果图来说明不同的数据生成过程,即使在处理相同的数据时,我们也可能得出截然不同的结论。让我们检查一个旨在减少心脏病风险的药物的例子。

情景 #1: 信任子组

下表比较了治疗组和对照组在两个性别子群体以及整个群体中的心脏病发作率,数据为合成数据。请注意,该研究未进行随机化。

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

作者根据《为什么的书》第六章制作的表格

通过比较心脏病发作率,我们可以看到该药物对女性和男性子组有害,但对合并组有帮助。我们应该信任哪个结果?要回答这个问题,我们需要使用以下因果图:

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

作者根据《为什么的书》第六章制作的图像

该图显示性别作为药物和心脏病的混杂因素,如果不对其进行控制,会偏离因果关系。换句话说,在“总计”行中,22%和 18%显示了偏倚的估计。

为了计算药物对整体人群的影响,我们需要估计药物对不同性别组的影响,然后取加权平均。

根据上述数据,我们知道在对照组中,女性和男性的心脏病发作率分别为 5%和 30%。假设女性和男性在一般人群中的比例相等,那么对照组的心脏病发作率为 (5%+30%)*0.5 = 17.5%。

类似地,我们可以得到治疗组的心脏病发作率为 (8%+40%)*0.5 = 24%。总体上,这仍然高于对照组,这与我们在子组中发现的一致。因此,这种药物不应被批准。

情景 #2: 信任聚合

现在,让我们进入另一个情境,数据相同,但这次我们是按患者的血压水平进行分类,而不是按性别分类。

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

作者根据《为什么的书》第六章制作的表格

在这里,数据揭示了分开和汇总组之间相同的矛盾。然而,不同的因果图改变了我们的结论。这个概念是药物旨在通过降低患者的血压来减少心脏病发作的风险:

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

图像由作者根据《为什么的书》第六章制作

因果图显示血压作为中介变量而不是混杂变量。回想一下我们在上一篇文章中讨论的内容:控制中介变量或中介变量的代理会完全或部分阻断因果影响。

因此,汇总数据是合适的。我们可以得出结论,药物有益,因为它将治疗组的心脏病风险从 22%降低到 18%,相比对照组。

连续变量中的辛普森悖论

现在,我们已经看到在决定是否按组汇总或分开时,检查数据生成过程的重要性。让我们看看一个应用相同概念于连续变量的示例。

这一悖论最早由弗雷德里克·洛德在 1967 年提出,当时他研究了不同餐厅提供的饮食效果,特别是饮食对女孩和男孩的不同影响。

学生的体重在 9 月份作为初始体重测量,并在接下来的 6 月再次测量以计算增重。结果显示在以下图表中:

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

图像由作者根据《为什么的书》第六章制作

两个椭圆代表了女孩和男孩的初始体重和最终体重的散点图。图表本身显示了饮食对女孩和男孩的影响存在矛盾的结论:

  • 如果我们关注 45 度线(W_f = W_i),我们可以看到,平均而言,饮食对女孩和男孩没有影响,因为体重分布在 W_f = W_i 处是对称的;

  • 如果我们认为初始体重对最终体重有影响,并关注每个初始体重观察值,如 W0,我们可以看到垂直线在男孩的椭圆上交点比女孩的高。换句话说,平均而言,体重为 W0 的男孩最终体重会比体重相同的女孩更高。

图表显示,男孩在每个初始体重下增重比女孩多。然而,同样明显的是,男孩和女孩都没有增重。这两个结论给学校营养师提供了不同的指导。它们应该做出什么决定?这时以下因果图会派上用场:

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

图像由作者根据《为什么的书》第六章制作

在研究性别是否影响体重增长时,因果图显示没有反向路径。因此,观察到的汇总数据提供了准确的结论,即饮食对女孩和男孩的体重增长没有影响。如果我们控制初始体重,我们将控制一个实际上阻断了从性别到体重增长部分因果影响的中介变量。

这个结论还证明了整体增益不总是分层特定增益的平均值(确定性原则)。如果每个层次的女孩和男孩数量相同,即每个初始权重相同,那么我们在每个初始权重下观察到的情况可以推广到整个总体。然而,这里明显不是这种情况,因为每个初始权重下女孩和男孩的分布不同。

如果我们在相同的数据中使用不同的叙述呢?我们可以在不同的餐厅提供不同的饮食,并比较在不同餐厅就餐的学生的体重增长,而不是观察性别如何影响体重增长。图表现在变为:

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

作者基于《为什么》一书第六章制作的图像

我们可以看到,去餐厅 B 的学生初始体重更高。由于数据相同,因此可以得出相同的矛盾结论。然而,因果图已经发生了变化:

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

作者基于《为什么》一书第六章制作的图像

现在,存在一个指向饮食和体重增长的反向路径。如果我们未能控制初始体重,它已成为一个混杂变量,将偏向饮食和体重增长之间的因果关系。

因此,我们应考虑将初始体重纳入考虑的结论。从图表中,我们可以看到,平均而言,去餐厅 B 的学生体重增长比去餐厅 A 的学生更多。

从以上所有这些例子中,我们可以看到,辛普森悖论不仅仅是我们在现实世界数据集中经常发现的逆转。所谓逆转,是指如果我们观察到 A/B > a/b,并且 C/D > c/d,并不保证(A+C)/(B+D) > (a+c)/(b+d)。这仅仅是算术不等式中的规则。

然而,辛普森悖论超越了数学计算。当面对矛盾结论时,必须彻底分析因果模型,以理解数据生成过程,而不是仅仅依赖观察到的数据。

吸烟与肺癌之间的长期辩论

除了在第六章中提供现实生活中的例子来说明理解数据生成过程的重要性外,Pearl 还在第五章中探讨和关注吸烟与肺癌之间的因果关系,以证明这一观点。

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

图片由 Volodymyr Hryshchenko 提供,来源于 Unsplash

从关于吸烟是否是致病因素的长期辩论中,我们可以推断出理论是如何发展的,以及因果关系是如何逐渐被提到台前的。

关于吸烟是否引发肺癌的研究因至少这三种因素而充满挑战:

  • 强迫参与者吸烟并使他们暴露于潜在健康风险的 RCT 是不道德的;

  • 观察数据可能存在混杂因素,因为治疗组的分布可能与对照组根本不同。

  • 烟草公司可能采取的潜在障碍和故意努力,以误导公众有关健康风险的信息。

在过去的几十年里,统计学家们进行了多次试验以寻找正确的方法论,即使面临这些障碍。

一项病例对照研究

正如 Pearl 在他的书中总结的那样,这项研究始于一项病例对照研究,该研究比较了肺癌患者与健康志愿者对照组。研究随后确定了“病例”组中的吸烟者是否比对照组中的更多,考虑到一些混杂因素如年龄、性别和环境污染物暴露。

然而,这项研究面临几个缺陷:

  • 一种倒退的逻辑:与其回答吸烟者得癌症的概率是多少,不如展示癌症患者是吸烟者的概率是多少;

  • 回忆偏倚:尽管研究人员确保在调查之前没有让患者知道他们的诊断,但他们可能会根据自己的健康状况推断出这一点;

  • 选择偏倚:这项研究仅关注住院癌症患者,这并不能很好地代表整个群体或甚至吸烟群体。

Cornfield 不等式

当问题出现时,辩论继续,即吸烟者是否是“自我选择”的,他们在基因上是否与非吸烟者不同。Pearl 在他的书中提到的一些担忧是:

他们更具风险倾向或更容易发展出实际上会导致健康不良影响的成瘾行为。

换句话说,辩论的问题在于以下哪种因果图是正确的。“吸烟基因”是否是我们观察到“吸烟”和“肺癌”之间关系的唯一原因?

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

图片由作者基于《为何的书》第五章绘制

Cornfield 使用简单数学对左侧因果图提出了挑战。如果左侧因果图是正确的,并且在数据中我们观察到吸烟者有九倍的可能性发展为肺癌,这必须是因为他们比非吸烟者有九倍的可能性拥有吸烟基因。

如 Pearl 在书中所述,参照 Cornfield 的论点:

如果 11%的非吸烟者有吸烟基因,那么 99%的吸烟者必须具有这个基因。然而,如果我们观察到 12%的非吸烟者有吸烟基因,这个比例在数学上就变得不可能了。

在这种情况下,吸烟基因无法完全解释吸烟与肺癌之间的关系。因此,正确的因果图提供了更准确的解释。

这个论点以其提出者命名,被称为 Cornfield 不等式,它通过评估在没有因果关系的情况下,替代关系必须有多强来解释观察到的数据,从而揭示了推断的光明。

出生体重悖论

我希望我们已经建立了足够的基础,以便可以声明数据不足以理解因果关系,并解释现实世界中表现为悖论的场景。

Pearl 在他的书中给出的另一个例子是一个研究,专注于寻找吸烟的母亲如何影响她们婴儿的生存率,挑战了吸烟导致死亡率的论点。研究结果显示,吸烟母亲的婴儿确实体重较轻。然而,吸烟母亲的低出生体重婴儿的生存率比非吸烟母亲的婴儿更高。

这个发现可能看起来违反直觉,即吸烟减少了出生体重并降低了儿童死亡率。然而,如果我们进一步考虑除了吸烟之外,哪些因素会影响婴儿的出生体重,我们会发现这里的碰撞偏差。

例如,其他威胁生命的遗传异常也可能解释出生率较低。我们可以通过绘制因果图更清楚地看到这一点:

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

图片由作者基于《为什么的书》第五章制作

在这里,“吸烟 -> 出生体重 <- 出生缺陷”形成了一个碰撞结构。除非我们控制出生体重,否则吸烟与出生缺陷没有相关性。如果我们只看低出生体重的婴儿,我们就打开了吸烟到死亡率的后门路径。这个关系会被出生缺陷到死亡率的因果路径所偏倚。

确实,其他因素可以添加到因果图中,这将指向出生体重。例如,研究发现种族是另一个影响出生体重和儿童死亡率的因素。

列表可以继续,唯一需要记住的是从因果图中得出的行动点。正如 Pearl 在他的书中所说:

我们可以使用这个图表和数据来说服孕妇停止吸烟。但我们不能告诉孕期黑人女性停止做黑人的事情。

最后的说明

碰撞偏差无处不在。你是否注意到从你朋友的经验中,所有他们约会的人中,吸引人的人往往都是混蛋?相较于利用涉及创伤和人格障碍的心理社会理论,Pearl 证明了碰撞偏差可能是答案。你朋友的约会对象选择取决于两个因素:吸引力和个性。在这种情况下,你会约会一个刻薄的、吸引人的人,一个友好的、不吸引人的人,当然还有一个友好的、吸引人的人。然而,你永远不会约会一个刻薄的、不吸引人的人。如下图所示的因果图:

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

作者基于《为什么的书》第六章的图像

仅仅通过观察你朋友的约会对象,你就会操控一个导致吸引力和个性之间产生虚假负相关的碰撞器。

正如 Pearl 所说,尽管悲哀的事实是,在整个群体中,不吸引人的人和吸引人的人一样刻薄(吸引力和个性没有相关性),但你的朋友们从未意识到这一点,因为约会池中从未出现过既刻薄又不吸引人的人。

这篇文章总结了使用因果图解释的趣闻和悖论。悖论是我们观察到的数据,它们欺骗和困惑我们。然而,通过深入挖掘数据生成过程并绘制因果图,我们可以对这些悖论提供解释,这不仅清除了困惑,还为决策提供了可靠的指导。

这就是我想分享的《为什么的书》第五章和第六章的内容,完成了“伴读系列”的第 4 篇文章。希望这篇文章对你有帮助。如果你还没有阅读前三篇文章,可以在这里查看:

## 伴读:因果关系书籍俱乐部

从一个猫的故事开始……

towardsdatascience.com ## 数据告诉我们“什么”,而我们总是寻找“为什么”

《为什么的书》 第一章和第二章,伴读系列

towardsdatascience.com ## 因果图:面对观察数据中的阿喀琉斯之踵

《为什么的书》 第三章和第四章,伴读系列

towardsdatascience.com ## 你无法踏入同一条河流两次

《为什么的书》 第七章和第八章,伴读系列

towardsdatascience.com ## 什么造就了强大的 AI?

《为什么的书》 第九章和第十章,伴读系列

towardsdatascience.com ## 因果推断在学术界和工业界有何不同?

“《为什么的书》系列”的附加文章

towardsdatascience.com

如果感兴趣,订阅我的邮件列表 以加入目前正在进行的双周讨论。和往常一样,我非常鼓励你阅读、思考,并在这里或在 你自己的博客上分享你的主要收获。

感谢阅读。如果你喜欢这篇文章,别忘了:

参考

《为什么的书》 ,作者:朱迪亚·佩尔

为什么 WGANs 超越 GANs:从 KL 散度到 Wasserstein 损失

原文:towardsdatascience.com/why-wgans-beat-gans-a-journey-from-kl-divergence-to-wasserstein-loss-9ee5faf10b48?source=collection_archive---------11-----------------------#2023-01-12

介绍

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

·

关注 发布于 Towards Data Science ·7 分钟阅读·2023 年 1 月 12 日

在 2014 年,Ian Goodfellow 提出了 GAN 的概念,或者我们今天所称的“原始 GAN”。虽然这一想法令人印象深刻,但训练起来却 notoriously 很困难。原始 GAN 面临无法收敛、梯度消失以及模式崩溃等问题。随后,大量的研究集中于解决这些问题。研究人员尝试了不同的模型架构、损失函数和训练方法。一个特别有效的解决方案是 Wasserstein GAN,它在 2017 年由 Arjovsky et al 提出。

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

图片由 Arnold Francisca 提供,来源于 Unsplash

本文尝试解释为什么 Wasserstein GANs 比普通 GANs 表现更好。它假设读者对 GANs 和 VAEs 的数学原理及其训练过程有一定了解。让我们从生成网络的介绍开始。

1. 生成网络:简要介绍

生成网络努力生成与真实数据家族相似的新样本。它们通过模仿数据分布来实现这一点。像 GANs 和 VAEs 这样的流行框架通过学习一个映射 G 来将已知/假设的分布 Z 转换为实际的分布空间。GANs 中的生成器和 VAEs 中的编码器完成了这一工作。这些网络的神经权重参数化了 G

网络通过最小化实际数据分布和生成数据分布之间的差异来学习映射。量化这种差异的三种常用度量是:

  1. KL 散度

  2. JS 散度

  3. Earth-Mover (EM) 或 Wasserstein-1 距离

让我们来窥探一下它们。

2. 为什么 KL 和 JS 散度会失败?

我们将简要介绍 KL 和 JS 散度,并了解它们为何会失败。

  1. Kullback-Leibler (KL) 散度可以通过正向或逆向两种方式计算,因此是非对称的。根据分布是连续的还是离散的,它们的正向 KL 散度如下:

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

正向 KL 散度

我们可以通过使用 Q 来加权分布的对数差异,从而计算逆 KL 散度。VAEs 操作于逆 KL。

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

逆 KL 散度

2. 与前者不同,Jensen-Shannon (JS) 散度是对称的。它本质上是两个 KL 散度的平均值。它在损失函数二元交叉熵中并不明显,但当鉴别器达到最优时,GANs 会基于 JS 散度。我建议你阅读这篇 博客 以了解原因。

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

JS 散度

Arjovsky 等人用一个简单的例子来展示 KL 和 JS 散度的陷阱。考虑下面图像中的两条平行线所描述的两个概率分布。红色是实际分布(P),绿色是其估计(Q)。θ 是它们之间的水平距离。

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

作者提供的图片

生成模型将努力将绿色靠近红色,这个红色固定在 0。当 θ = 1 时,你能计算 JS 和 KL 散度吗?

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

KL 散度

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

JS 散度

那么,这些度量会随着 θ 的变化而有所不同吗?如果你仔细观察,它们不会改变,除非 θ=0。

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

我观察到这些度量有两个主要缺点。

  1. 在 θ=0.1 和 θ=1 之间的分布差异是相同的。在 θ=0.1 时,绿线与红线的距离更近,因此差异应该更小。

  2. θ 可以大致看作是估计的分布。如果我们的生成模型由 φ 参数化,那么 θ 是 f(φ) 的一个函数。在反向传播过程中,我们将计算相对于 φ 的损失函数的梯度,该损失函数由上述度量之一定义,以调整参数。第二个方程的第一个项将始终为 0。因此,由于梯度为零,我们的模型将无法学习任何东西。

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

使用链式法则进行反向传播

从上述示例中,我们可以得出一些重要的推论。

  1. KL 和 JS 散度未考虑两个概率分布之间的水平差异

  2. 在预测和实际分布不重叠的情况下,这种情况在训练过程中很常见,梯度可能为 0,从而导致无法学习。

那么,Wasserstein 距离是如何解决这些问题的呢?

3. 为什么 Wasserstein 距离是一种更好的度量?

坦白说,EM/Wasserstein-1 距离的公式非常糟糕。所以,我将避免其数学细节。相反,让我们直观地理解它。

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

EM/Wasserstein-1

让我们回到平行线。这次,有四条线。红线构成一个概率分布,蓝线也是如此。顶部的数字是对应点(x=0,1,2,3)的概率质量。我们打算调整蓝线,使其与红线系列对齐(相似分布)。为此,我们将移动概率质量。

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

图片来源:作者

  1. 从 x=2 移动 0.2 到 x=0

  2. 从 x=3 移动 0.1 到 x=0

  3. 从 x=3 移动剩余的 0.7 到 x=1

然而,这只是众多运输计划中的一个。我们还可以

  1. 从 x=2 移动 0.1 到 x=0

  2. 从 x=2 移动 0.1 到 x=1

  3. 从 x=3 移动 0.2 到 x=0

  4. 从 x=3 移动 0.6 到 x=0

在这两个计划中,哪个更优化?为了确定这一点,我们可以借用物理中的工作类比。在这里,我们将工作定义为质量乘以移动距离。因此,这两个运输方案中的工作量分别为 2.1 和 2.7。

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

图片来源:作者

2.1,即最优运输计划中涉及的工作量,因此是 EM 距离。相同的原理也适用于连续领域。由于每个点在连续分布中都有一个相关的概率质量,积分取代了求和。

总之,上述复杂的方程涉及计算所有运输方案中所需的工作,以在两个分布之间建立相似性,并选择其中的最小值。与其他度量相比,EM 距离考虑了两个分布之间的水平差异,同时保留了它们的整体形状。此外,它还解决了梯度消失的问题。

重新考虑第一部分中的例子。对齐两个分布的最小成本是 θ,即线条之间的水平距离。因此,即使预测和实际分布不重叠,我们也能获得稳定的梯度来调整参数。

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

作者提供的图像

4. 使用 Python 可视化所有度量

现在,让我们在 Python 中计算所有讨论的度量,以可视化它们的行为。

import numpy as np
from scipy.stats import norm
from matplotlib import pyplot as plt
from scipy.stats import wasserstein_distance

我们将定义计算 KL 和 JS 发散的函数,幸运的是,对于 EM 距离,我们可以使用 scipy 库。

def kld(d1,d2,eps=10^-6):
    return np.sum(d1*np.log((d1)/(d2)))

def jsd(d1,d2):
    return 0.5 * kld(d1,(d1+d2)/2) + 0.5 * kld(d2,(d1+d2)/2)

接下来,我们将定义两个正态分布,并可视化当高斯分布被分离时度量如何变化。也就是说,它们的均值差异增加。

x = np.arange(-40, 40, 0.001)
q_mean_range = (2,20)
fkl = []
bkl = []
js = []
em = []
p = norm.pdf(x, 0, 2)
for i in range(*q_mean_range):
    q = norm.pdf(x, i, 2)
    fkl.append(kld(p,q))
    bkl.append(kld(q,p))
    js.append(jsd(p,q))
    em.append(wasserstein_distance(p,q))
x = np.arange(*q_mean_range,1)
f,ax = plt.subplots(2,2,figsize=(10,10))
ax = ax.flatten()
for i,(vals,name) in enumerate(zip([fkl,bkl,js,em],['FWD KL','REV KL','JS Divergence','EM Distance'])):
    ax[i].plot(x,vals)
    ax[i].set_xlabel('Mean difference')
    ax[i].set_title(name)
plt.show()

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

所有度量与均值差异的图

你注意到什么了吗?随着均值差异的增加,KL 发散爆炸,而 JS 发散饱和。然而,EM 距离线性增加。因此,在四者中,EM 距离似乎是训练过程中保持梯度流的最佳选择。

EM/Wasserstein 距离还缓解了模式崩溃。粗略来说,模式崩溃发生在生成器学会生成特定模式,从而欺骗陷入局部极小值的判别器。正如第二部分所讨论的,当判别器处于最小值时,GANs 基于 JS 发散操作,导致梯度为零。因此,判别器被困住,生成器没有动力生成不同的样本。

使用 Wasserstein 距离,判别器可以在梯度不会消失的情况下达到最优。它们可以逃离局部最小值并丢弃生成器输出,促使生成器不会过拟合于特定判别器,从而生成多个模式。

结论

至此,我们结束了这篇文章。希望这总结了为什么 Wasserstein GANs 优于传统的 GANs 和 VAEs。我略过了一些关于 EM 距离的数学细节。如果你感兴趣,需要阅读 论文。你必须注意,讨论的 EM 距离方程是不可处理的。使用了一个数学技巧来近似它。在实际中你不太可能需要它。不过,如果你迫切想知道,可以在 这里 或在 论文 中阅读有关近似的内容。

参考文献

  1. arxiv.org/pdf/1701.07875.pdf

  2. www.alexirpan.com/2017/02/22/wasserstein-gan.html#

  3. lilianweng.github.io/posts/2017-08-20-gan/#:~:text=best%20value%20for,D

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值