TowardsDataScience 2023 博客中文翻译(一百六十二)

原文:TowardsDataScience

协议:CC BY-NC-SA 4.0

t-SNE 如何在降维中优于 PCA

原文:towardsdatascience.com/how-t-sne-outperforms-pca-in-dimensionality-reduction-7a3975e8cbdb

PCA 与 t-SNE 在低维空间中可视化高维数据的比较

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

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

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

照片由 Pat Whelen 提供,来源于 Unsplash

在机器学习中,降维是指减少数据集中的输入变量数量。输入变量的数量即数据集的维度

降维技术主要分为两大类:线性非线性(流形)

在线性方法下,我们讨论了 主成分分析(PCA)因子分析(FA)线性判别分析(LDA)非负矩阵分解(NMF)

在非线性方法下,我们讨论了 自编码器(AEs)核 PCA

t-分布随机邻域嵌入(t-SNE) 也是一种非线性降维方法,用于在低维空间中可视化高维数据,以寻找数据中的重要集群或群体。

所有的降维技术都属于无监督机器学习的范畴,我们可以在不需要标签的情况下揭示数据中的隐藏模式和重要关系。

因此,降维算法处理的是未标记的数据。在训练这样的算法时,fit()方法只需要特征矩阵X作为输入,而不需要标签列y来源: 用于图像数据降维的非负矩阵分解(NMF)

**What you will learn:
---------------------------------------------------** 01\. Advantages of t-SNE over PCA
02\. Disadvantages of t-SNE
03\. How t-SNE works
04\. Python implementation of t-SNE - TSNE() class
05\. Important arguments of TSNE() class
06\. KL divergence
07\. The MNIST data in tabular format
08\. Visualizing MNIST data using PCA
09\. Visualizing MNIST data using t-SNE
10\. PCA before t-SNE (Very special trick)
11\. Choosing the right value for perplexity
12\. Changing the right number of iterations
13\. Randomness of initialization
14\. PCA initialization
15\. Using a random state in random initialization

**Other dimensionality reduction methods
---------------------------------------------------**
1\. [Principal Component Analysis (PCA)](https://medium.com/data-science-365/3-easy-steps-to-perform-dimensionality-reduction-using-principal-component-analysis-pca-79121998b991)
2\. Factor Analysis (FA)
3\. Linear Discriminant Analysis (LDA)
4\. Non-Negative Matrix Factorization (NMF)
5\. Autoencoders (AEs)
6\. Kernel PCA

t-SNE 相对于 PCA 的优点

t-SNE 相对于 PCA 有两个主要优点:

  • t-SNE 可以在减少数据的维度后保持数据点之间的空间关系。这意味着在原始维度中相邻的数据(具有相似特征的点)在低维中仍将保持相邻!这就是为什么 t-SNE 主要用于发现数据中的聚类。

  • t-SNE 可以处理在实际应用中非常常见的非线性数据。

PCA 尝试通过最大化数据的方差来减少维度,而 t-SNE 则通过在高维和低维中将相似的数据点保持在一起(并将不相似的数据点分开)来实现相同的目标。

因此,t-SNE 在降维方面往往能超越 PCA。今天,你将看到对同一数据集上 t-SNE 和 PCA 的实际实现。你可以比较这两种方法的输出,并验证这一事实!

t-SNE 的缺点

  • t-SNE 的主要缺点是它在大数据集上执行算法时需要大量计算资源。因此,当数据的维度非常高时,执行 t-SNE 是非常耗时的。为了解决这个问题,我们将讨论一个非常特别的技巧。你可以在显著减少时间的同时获得几乎相似的结果!

  • 另一个缺点是,如果使用随机初始化,即使在相同的超参数值下,t-SNE 也会得到不稳定(不同)的结果。你可以在最后学习更多关于这个问题的信息。

你还将学习如何调整 Scikit-learn 的 t-SNE 算法中的一些最重要的超参数,以获得更好的结果!

所以,继续阅读吧!

t-SNE 的工作原理

t-SNE 计算中涉及两个概率分布。因此,正如其名称所暗示的,算法本质上是随机的。

  • 在高维空间中,我们使用Gaussian (normal) distribution将数据点之间的成对距离转换为条件概率。

  • 在低维空间中,我们使用Student’s t-distribution将数据点之间的成对距离转换为条件概率。

KL 散度测量这两个概率分布之间的差异(不同)。这是我们在算法训练过程中尝试最小化的成本函数。

所以,t-SNE 的目标是将数据点定位到低维空间中,以便尽可能最小化两个概率分布之间的 KL 散度。

t-SNE 需要大量计算资源和时间来进行这些概率计算,尤其是在处理大型数据集时。这就是为什么 t-SNE 比 PCA 慢得多。对此,我们将讨论一个非常特别的技巧。

t-SNE 的 Python 实现

在 Python 中,t-SNE 是通过使用 Scikit-learn 的 TSNE() 类来实现的。Scikit-learn 是 Python 机器学习库。

首先,你需要导入并创建 TSNE() 类的实例。

# Import
from sklearn.manifold import TSNE

# Create an instance
TSNE_model = TSNE(n_components=2, perplexity=30.0, learning_rate='auto',
                  n_iter=1000, init='pca', random_state=None)

TSNE() 类的重要参数

TSNE() 类中有许多参数。如果我们没有直接指定这些参数,它们在调用 TSNE() 函数时会取其默认值。要了解更多关于这些参数的信息,请参阅 Scikit-learn 文档

以下列表包含了 TSNE() 类中最重要参数的详细解释。

  • n_components: 一个整数,定义嵌入空间的维度数量。默认值为 2。最常用的值是 2 和 3,分别用于在 2D 和 3D 空间中可视化数据,因为 t-SNE 主要用于数据可视化。

  • perplexity: 在可视化数据时考虑的最近邻居的数量。这是 TSNE() 类中最重要的参数。默认值为 30.0,但强烈建议尝试 5 到 50 之间的值,因为不同的值可能会产生显著不同的结果。你需要绘制不同困惑度值的 KL 散度,并选择合适的值。这在技术上称为 超参数调优。一般来说,较大的数据集需要较大的困惑度值。

  • learning_rate: TSNE() 函数使用随机梯度下降来最小化 KL 散度成本函数。随机梯度下降优化器需要一个合适的学习率值来执行此过程。学习率决定了优化器最小化损失函数的快慢。较大的值可能会导致模型无法收敛,而较小的值可能需要太多时间才能收敛。

  • n_iter: 为梯度下降设置的最大迭代次数。默认值为 1000。

  • init: 初始化方法。有两个选项:“random”“pca”。默认是 PCA 初始化,这比随机初始化更稳定,并且在不同执行之间产生相同的结果。如果选择随机初始化,由于 TSNE 具有非凸成本函数,且 GD 优化器可能会停留在局部最小值,算法会在不同的执行中生成不同的结果。

  • random_state: 一个整数,用于在使用随机初始化时获取相同的结果,以避免每次运行算法时生成显著不同的结果。常用的整数有 0、1、2 和 42。了解更多信息 这里。

TSNE() 类的重要方法

  • fit(X): 从特征矩阵 X 学习一个 TSNE 模型。这里不进行任何转换。

  • fit_transform(X): 从特征矩阵 X 学习一个 TSNE 模型,并返回 TSNE 转换后的数据。

TSNE_transformed_data = TSNE_model.fit_transform(X)

TSNE() 类的重要属性

  • kl_divergence_: 返回优化后的 Kullback-Leibler 散度。GD 优化器在训练过程中尝试最小化 KL 散度。通过设置不同的困惑度值来分析这一散度是选择正确困惑度值的好方法。稍后将详细介绍!

PCA 的 Python 实现(可选)

本文还包括了使用 PCA 算法在低维空间中可视化 MNIST 数据。因此,虽然在这里是可选的,但讨论 PCA 算法的 Python 实现仍然是有意义的。我已经发布了详细的 PCA 文章,相关链接如下。

PCA 相关文章: 使用主成分分析(PCA)进行降维的 3 个简单步骤使用 Scikit-learn 进行主成分分析(PCA)使用 NumPy 进行主成分分析(PCA)的深入指南

表格格式的 MNIST 数据

加载 MNIST 数据集的方式有很多,这个数据集包含 70,000 张灰度手写数字图像,涵盖 10 个类别(0 到 9)。

  • 使用 Scikit-learn API: 我们得到的形状为 (70000, 784),这是 TSNE 和 PCA 算法所需的表格格式。数据集将被加载为 Pandas 数据框。数据集中有 70000 个观测(图像)。每个观测有 784 个特征(像素值)。图像的大小是 28 x 28。

  • 使用 Keras API: 训练集的形状为 (60000, 28, 28),测试集的形状为 (10000, 28, 28)。数据将被加载为三维的 NumPy 数组。这种格式不能直接用于 TSNE 和 PCA 算法。我们需要 重新调整 MNIST 数据的形状

注意: 要了解这两个 API 之间的差异,请点击 这里。

目前,我们将使用 Scikit-learn API 加载 MNIST 数据集。为了加快使用 TSNE 和 PCA 时的计算过程,我们只加载 MNIST 数据集的一部分(前 10,000 个实例)。

from sklearn.datasets import fetch_openml

mnist = fetch_openml('mnist_784', version=1)
image_data = mnist['data'][0:10000]
labels = mnist['target'][0:10000]

print("Data shape:", image_data.shape)
print("Data type:", type(image_data))
print()
print("Label shape:", labels.shape)
print("Label type:", type(labels))

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

(图片来源:作者)

我们还将像素值进行标准化,以便与 PCA 和 t-SNE 一起使用。

# Normalize the pixel values
image_data = image_data.astype('float32') / 255

使用 PCA 可视化 MNIST 数据

如上面的输出所示,MNIST 数据的原始维度是 784,无法在 2D 图中绘制。因此,我们需要通过应用 PCA 将维度减少到 2。

让我们查看输出结果。

from sklearn.decomposition import PCA

PCA_model = PCA(n_components=2)
PCA_transformed_data = PCA_model.fit_transform(image_data)

print("PCA transformed data shape:", PCA_transformed_data.shape)
print("PCA transformed data type:", type(PCA_transformed_data))

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

(图片来源:作者)

PCA 转换后的 MNIST 数据形状为 (10000, 2),现在可以在 2D 图中绘制。

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

(图片来源:作者)

显然,所有数据点都在一个簇中,我们无法看到每个类别标签的不同簇。这不是我们需要的表示方式。

让我们通过对 MNIST 数据应用 TSNE 来解决这个问题。

使用 t-SNE 可视化 MNIST 数据

现在,我们将在相同的数据集上应用 t-SNE。应用 t-SNE 时,我们将使用 TSNE() 类中的所有参数(超参数)的默认值。

from sklearn.manifold import TSNE

TSNE_model = TSNE(n_components=2, perplexity=30.0)
TSNE_transformed_data = TSNE_model.fit_transform(image_data)

print("TSNE transformed data shape:", TSNE_transformed_data.shape)
print("TSNE transformed data type:", type(TSNE_transformed_data))

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

(图片来源:作者)

TSNE 转换后的 MNIST 数据形状为 (10000, 2),现在可以像以前一样在 2D 图中绘制。

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

(图片来源:作者)

显然,数据点根据其类别标签被分隔成不同的簇。原始维度中同一类别的附近数据点在较低维度中仍将保持接近!

t-SNE 在降维方面比 PCA 更有效,因为它在高维和低维中都能将相似的数据点保持在一起(而将不相似的数据点分开),并且在处理非线性数据时表现良好。

PCA 之后的 t-SNE — 结合这两种方法(非常特别的技巧)

尽管 PCA 执行得非常快,但它无法在降维后保持数据点之间的空间关系。

另一方面,t-SNE 在处理较大数据集时确实很慢,但它可以在降维后保持数据点之间的空间关系。

为了加快 t-SNE 的计算过程,我们在 t-SNE 之前应用 PCA,并将两种方法结合,如下图所示。

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

PCA 之前的 t-SNE 工作流程(图片来源:作者)

首先,我们对 MNIST 数据应用 PCA,将维度降至 100(仅保留 100 个维度/成分/特征)。然后,我们对 PCA 转换后的 MNIST 数据应用 t-SNE。这次,t-SNE 仅看到 100 个特征而不是 784 个特征,因此不需要进行大量计算。现在,t-SNE 执行速度非常快,但仍能生成相同或更好的结果!

在 t-SNE 之前应用 PCA,你将获得以下好处。

  • PCA 去除数据中的噪声,只保留数据中最重要的特征。将 PCA 转换后的数据输入 t-SNE,你将获得更好的输出!

  • PCA 去除了输入特征之间的多重共线性。PCA 转换后的数据具有不相关的变量,这些变量被输入到 t-SNE 中。

  • 正如我之前所说,PCA 显著减少了特征的数量。PCA 转换后的数据将输入 t-SNE,你将能非常快速地得到结果!

PCA_model = PCA(n_components=100)
PCA_transformed_data = PCA_model.fit_transform(image_data)

TSNE_model = TSNE(n_components=2, perplexity=30.0)
PCA_TSNE_transformed_data = TSNE_model.fit_transform(PCA_transformed_data)

plt.figure(figsize=[7, 4.9])

plt.scatter(PCA_TSNE_transformed_data[:, 0], PCA_TSNE_transformed_data[:, 1], 
            c=np.array(labels).astype('int32'), s=5, cmap='tab10')

plt.title('Lower dimensional representation of MNIST data - TSNE after PCA')
plt.xlabel('1st dimension')
plt.ylabel('2nd dimension')
plt.savefig("PCA_TSNE.png")

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

(图片来源:作者)

使用所有 784 个特征运行 t-SNE 花费了 100 秒。在应用 PCA 后,只需 20 秒就可以用具有 100 个特征的 PCA 转换数据运行 t-SNE。

PCA 转换后的数据准确地表示了原始 MNIST 数据,因为前 100 个组件捕获了原始数据中约 90% 的方差。我们可以通过查看以下图表来确认这一点。因此,用 PCA 转换后的数据替代原始数据输入 t-SNE 是合理的。

pca_all = PCA(n_components=784)
pca_all.fit(image_data)

plt.figure(figsize=[5, 3.5])
plt.grid()
plt.plot(np.cumsum(pca_all.explained_variance_ratio_ * 100))
plt.xlabel('Number of components')
plt.ylabel('Explained variance')

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

(图片来源:作者)

选择合适的困惑度值

困惑度决定了在可视化数据时要考虑的最近邻居数量。它是 t-SNE 中最重要的超参数。因此,你需要正确地调整它。

一种选择是你可以绘制不同困惑度值的 KL 散度,并分析当困惑度值增加时 KL 散度的变化情况。

perplexity_vals = np.arange(10, 220, 10)
KL_divergences = []

for i in perplexity_vals:
  TSNE_model = TSNE(n_components=2, perplexity=i, n_iter=500).fit(PCA_transformed_data)
  KL_divergences.append(TSNE_model.kl_divergence_)

plt.style.use("ggplot") 
plt.figure(figsize=[5, 3.5])
plt.plot(perplexity_vals, KL_divergences, marker='o', color='blue')
plt.xlabel("Perplexity values")
plt.ylabel("KL divergence")

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

(图片来源:作者)

当困惑度值增加时,KL 散度持续减少!因此,我们不能仅通过分析这个图来决定困惑度的正确值。

作为第二种选择,我们需要多次运行 t-SNE 算法,使用不同的困惑度值并可视化结果。

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

(图片来源:作者)

在困惑度 = 5(较低值)时,会形成清晰的簇。但簇之间的空间不足,簇内的点分离得很好。

在困惑度 = 30、50 和 100(合适值)时,簇之间的间距增加,而簇内的点集中得很好。

在困惑度 = 210 和 500(过高值)时,簇之间往往会重叠,这对我们来说是不需要的。

对于 MNIST 数据集,任何介于 30 和 50 之间的困惑度值都足够好。

注意: 困惑度的最佳值高度依赖于数据的性质和数量。通常,较大的数据集需要较大的困惑度值。最好从默认值 30 开始。

更改合适的迭代次数

现在,我们将可视化梯度下降优化算法中使用的迭代次数的效果。t-SNE 使用随机梯度下降来最小化 KL 散度成本函数。

迭代次数决定了优化器在优化过程中进行梯度更新的次数。默认值为 1000。最小值应为 250。

迭代次数在n_iter参数中指定。

from sklearn.manifold import TSNE

TSNE_model = TSNE(n_components=2, perplexity=30.0, n_iter=250)

在这个实验中,我们将尝试三种不同的值:250、500 和 1000。

250 次迭代

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

(图片来源于作者)

500 次迭代

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

(图片来源于作者)

1000 次迭代

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

(图片来源于作者)

运行 250 次迭代后,簇尚未明显形成,因为成本函数未被完全最小化。因此,我们需要给算法更多时间以进一步优化。运行 500 次迭代后,簇的分离非常明显。一旦优化,增加迭代次数对改变簇形成几乎没有影响!它只会增加训练时间!在这种情况下,500 次迭代足以优化算法。

注意: 迭代次数的选择高度依赖于数据的性质和量。

初始化的随机性

TSNE 有两种初始化方式:

  • 随机初始化
from sklearn.manifold import TSNE

TSNE_model = TSNE(n_components=2, perplexity=30.0, init='random')
  • PCA 初始化(默认)
from sklearn.manifold import TSNE

TSNE_model = TSNE(n_components=2, perplexity=30.0, init='pca')
# or
TSNE_model = TSNE(n_components=2, perplexity=30.0) # default

PCA 初始化比随机初始化更稳定,并且在不同执行中产生相同的结果。

相比之下,随机初始化会在不同执行中生成不同的结果,因为TSNE 具有非凸的成本函数,并且 GD 优化器可能会陷入局部最小值,如下图所示。

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

(图片来源于作者)

如果初始化发生在点A附近,优化器可能会停留在局部最小值,成本函数将无法完全最小化。

如果初始化发生在点B附近,优化器可能会停留在全局最小值,这时,TSNE 将生成与之前完全不同的输出。

成本函数中可能存在许多局部最小值。因此,不同的初始化可能会导致算法陷入局部最小值。随机初始化就是这种情况,而 PCA 初始化不会遭受这种问题!

在随机初始化中使用随机状态

如果你仍然想在不同的 TSNE 算法执行中获得稳定的结果,可以将random_state参数指定为整数,如 0、1 或 42。

from sklearn.manifold import TSNE

TSNE_model = TSNE(n_components=2, perplexity=30.0, init='random',
                  random_state=42)

如果你运行多次,你将会得到相同的结果。然而,如果你将random_state指定为 0,你会得到不同于之前的结果。

from sklearn.manifold import TSNE

TSNE_model = TSNE(n_components=2, perplexity=30.0, init='random',
                  random_state=0)

让我们看看两个输出:

随机状态 = 42

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

(图片来源于作者)

随机状态 = 0

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

(图片来源于作者)

你将会得到完全不同的输出,取决于不同的随机状态值!

注意: 指定随机状态不会阻止算法陷入局部最小值。

今天的文章到此结束。

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

你可能感兴趣的其他降维方法

  • 主成分分析(PCA)

  • 因子分析(FA)

  • 线性判别分析(LDA)

  • 非负矩阵分解(NMF)

  • 自编码器(AEs)

  • 核主成分分析

继续阅读(推荐)

怎么样,来一门 AI 课程?

支持我作为一名写作者

希望你喜欢阅读这篇文章。如果你愿意支持我作为一名写作者,请考虑 注册会员 以获得无限访问 Medium 的权限。每月只需 $5,我将获得部分会员费用。

[## 通过我的推荐链接加入 Medium - Rukshan Pramoditha

阅读 Rukshan Pramoditha 的每一篇故事(以及 Medium 上的其他成千上万的作者)。你的会员费直接…

rukshanpramoditha.medium.com

加入我的私人邮件列表

不要再错过我的精彩故事。通过 订阅我的邮件列表,你将直接在我发布故事时第一时间收到。

非常感谢你的持续支持!下篇文章见。祝大家学习愉快!

MNIST 数据集信息

  • 引用: Deng, L., 2012. 用于机器学习研究的手写数字图像 MNIST 数据库。IEEE 信号处理杂志,29(6),第 141–142 页。

  • 来源: yann.lecun.com/exdb/mnist/

  • 许可: Yann LeCun(纽约大学 Courant Institute)和 Corinna Cortes(谷歌实验室,纽约)持有 MNIST 数据集的版权,该数据集采用Creative Commons Attribution-ShareAlike 4.0 International LicenseCC BY-SA)。你可以在这里了解更多关于不同数据集许可类型的信息。

设计及编写者: Rukshan Pramoditha

2023–05–23

如何在大众之前访问未来的 Python 版本,如 3.12

原文:towardsdatascience.com/how-to-access-future-python-versions-like-3-12-before-the-masses-eb05953ba599

并进行测试

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

·发表于 Towards Data Science ·6 分钟阅读·2023 年 6 月 22 日

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

Image by me with Midjourney

新的 Python 版本总是带来显著改进的功能。例如 3.11——它承诺提升高达 60% 的性能,并且去年十月实现了这个承诺。

除了新功能的承诺,测试未发布的 Python 版本有助于开发者更快地发现 bug 并让其他人参与开发过程。利用新功能在大众之前也有获得 竞争优势 的实际可能。

即使这些理由听起来不够吸引人,炫耀你在大众之前检查了一个新版本的 Python 总是很酷的。

那么,让我们开始吧。

步骤 0:安装 Docker

无法访问新版 Python 的原因是因为它们被很好地隐藏了。它们在 Python.org 上没有下载链接。相反,它们托管在 官方 Python Docker 镜像 页面上:

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

Screenshot by me

如你所见,这个镜像已经有超过 10 亿次下载。如果你向下滚动一点,你会看到不同版本的 Python 镜像:

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

Screenshot by me

我们想安装未发布的 Python 3.12,但有很多版本。我们该选择哪个?

在我们回答之前,确保你已经安装了 Docker Desktop 并且能够在你的 CLI 上成功运行 docker --version

我们使用 Docker 镜像和容器的原因是它们是安全和隔离的。Python 3.12 不会破坏你的环境,如果它在容器中。除此之外,我们别无选择,只能使用容器 😃

在这个教程中,你不需要了解 Docker 的任何知识。

步骤 1:选择镜像

所有这些词——alpinercbookwormslimbullseye 在 Python 镜像标签中是什么意思?这些术语用来告知我们每个镜像所使用的基础操作系统。以下是它们的定义:

  • alpine:带有 alpine 标签的镜像使用 Alpine Linux 发行版,以其小巧的体积和安全性设计而闻名。

  • bookworm:Bookworm 是 Debian OS 12 的代号,这是一种因其稳定性和广泛的软件适配性而闻名的流行发行版。

  • bullseye(很酷的名字):Bullseye 是 Debian(版本 11)的另一个代号。

  • slim:这些镜像的变体专注于较小的体积。它们被精简到仅包含运行 Python 应用程序所需的基本组件和依赖项,从而使其更轻量高效。

  • 0bn:带有 0b 的标签代表测试版。例如,0b2 镜像是 Python 3.12 Beta 2 版本。Python 3.12 的最终测试版(0b4)将在 2023 年 7 月发布。

  • rc:带有此标签的镜像是候选版本。RC 版本被认为可能稳定并准备发布,但仍需进一步测试和反馈。

我们将选择这些候选版本中的一个,具体是3.12-rc-bookworm。就是 Debian 12。

查看 Python 3.12 版本发布计划 这里

步骤 2:拉取镜像

首先,确保 Docker Desktop 正在运行,方法是启动应用程序并检查状态:

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

图片由我提供

然后,在任何终端中运行下面的命令并等待:

$ docker pull python:3.12-rc-bookworm

该命令将从 Docker Hub 拉取官方镜像。

在等待时:Docker 镜像是一个轻量、独立且可执行的包,包含运行软件所需的所有内容,包括代码、运行时、系统工具、库和配置。

Docker 容器则是 Docker 镜像的运行实例。我们将在拉取完成后启动这样的容器。

现代数据科学家的 Docker:2023 年不能忽视的 6 个概念

编辑描述

查看现代数据科学家的 Docker:2023 年不能忽视的 6 个概念

步骤 3:启动一个容器

请鼓掌!我们将第一次使用全新的 Python 3.12。执行的命令是…(此时请保持戏剧性的沉默):

$ docker run -it python:3.12-rc-bookworm

Python 3.12.0b2 (main, Jun 14 2023, 17:45:20) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

就这样,各位。命令从 3.12-rc-bookworm 镜像启动了一个容器,添加了 -it 标签后启动了 Python 解释器。现在,你可以在交互式 Shell 中做任何事情。

了解更多信息,请查看官方文档中的3.12 中的新功能文章。我会首先尝试那些改进的错误信息。

要退出 shell 和容器,运行 exit()

第 4 步:将 VSCode 连接到容器

你难道不觉得我们会在这里运行一堆在傻乎乎的 shell 中的表达式吗?

哦不。我们要将 Python 3.12 的容器与 VSCode 链接,并编写一些脚本以真正测试新版本。

因此,在你机器上的任何目录中,打开 VSCode(我希望你已经为 Python 和数据科学配置了它)。

$ cd some_dir
$ code . # Launches VSCode

然后,安装 Remote Development 扩展:

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

图片由我提供

重新加载 VSCode。然后,跳转到你的 Docker Desktop,点击 Containers 菜单:

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

图片由我提供

你会看到一个运行中的容器列表。我版本的 Python 3.12 被称为 adoring_dirac。现在,它没有运行,因为我在 CLI 中退出了 Python shell。要运行它,我按下播放按钮来启动容器。

现在,再次打开 VSCode,打开命令面板(Ctrl + Shift + P),搜索“附加到运行中的容器”。这里有一个有用的 GIF:

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

一旦你点击一个以 Python 3.12 为基础镜像的正在运行的容器实例,一个新的 VSCode 窗口将弹出,并直接链接到容器。

请记住,这个容器与操作系统隔离,因此你创建或编辑的任何文件或启动的终端会话也会被隔离,且不可见。

所以,这就是你尝试在容器内测试 Python 3.12 的绿灯。除了创建脚本,

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

你还可以安装其他软件,如 Conda、Git、DVC,基本上将容器视为一个只安装了 Python 3.12 的全新空计算机。

结论

你还可以将上述方法应用于安装未来的 Python 版本到其他工具或库中。例如,流行的框架如 TensorFlow 或 PyTorch 在 Docker Hub 上有它们的官方 Docker 镜像。

通过利用这些官方镜像,你可以轻松设置支持 GPU 的框架,消除任何复杂性或挑战。Docker 容器已预配置,确保了无忧的安装体验。

感谢阅读!

喜欢这篇文章和它奇怪的写作风格吗?想象一下,访问到更多类似的文章,所有文章都由一位才华横溢、迷人且风趣的作者(顺便说一句,就是我 😃)。

只需 4.99 美元的会员费,你不仅能访问我的故事,还能从 Medium 上最优秀的头脑那里获得丰富的知识宝藏。如果你使用 我的推荐链接,你将获得我超级感激的心意和一个虚拟的击掌,以支持我的工作。

[## 使用我的推荐链接加入 Medium — Bex T。

作为 Medium 会员,你的一部分会员费会分配给你阅读的作者,你可以完全访问所有故事……

ibexorigin.medium.com](https://ibexorigin.medium.com/membership?source=post_page-----eb05953ba599--------------------------------)

如何在数据科学训练营中表现出色:完整指南

原文:towardsdatascience.com/how-to-ace-the-data-science-bootcamp-a-complete-guide-aad1eb10da18?source=collection_archive---------1-----------------------#2023-09-02

关于如何准备训练营、成功完成课程以及之后的行动的完整指南

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 亚历山德拉·奥贝雷莫克

·

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

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

一张神经网络如何看待数据科学训练营中的女孩的图像(由作者使用 Kandinsky 2.2 生成)

我在 2021 年 5 月从线下训练营毕业。现在我在 IT 领域工作了将近 2 年。此外,我仍然被邀请作为客座毕业生参与训练营的各种活动。我将指导你如何在每个阶段表现出色——从选择一个优秀的项目到毕业后的沟通。

这些信息适用于有现场讲座/网络研讨会的全日制训练营项目,不适用于大规模开放在线课程(MOOCS)。

在训练营开始之前

做你的研究

训练营是你未来职业(甚至生活)中的一个重要步骤。这就是为什么我建议尽可能多地了解信息。仅仅阅读训练营网站和浏览社交网络是不够的。我强烈建议参加所有免费的活动并积极参与。在网络研讨会上随时向工作人员提问。我还建议联系校友和学生,向他们询问任何问题。如果可能的话,尽量访问线下校园,亲自了解学习环境。这将帮助你在脑海中形成一个完整的图像。

在我阅读了有关我感兴趣的项目的所有信息后,我采取了行动。我在他们的 Instagram 上留言:“我计划申请这个训练营。毕业生和学生们,请点赞评论,我会联系你们。”几个人回复了我,我问了所有我想知道的事情。

我还参加了一个免费的 Python 马拉松。参与者每天会得到一个任务,并且必须在同一天提交解决方案。在活动期间,我积极参与聊天并保持了一致性。一切都很顺利,我赢得了活动。这让我有机会线下访问训练营办公室,感受那里的氛围。我还参加了数据科学项目的在线介绍会。

多亏了这些行动,我了解了关于训练营的所有信息。

记录所有观察结果

记住所有内容是很困难的,因此我强烈建议记笔记。特别是当你考虑多个学校时,这些笔记将对未来的比较和最终决策非常有用。

在我居住的城市,只有一个地方提供全日制训练营,但记录日志帮助我跟踪了一切。我做对了,选择了一个优秀的项目,拥有支持性的导师、强大的课程大纲、出色的职业支持以及周围优秀的人。

选择有入学考试的项目

听起来有点意外,不是吗?入学考试并不是为了折磨你。这样做的主要原因是检查每个学生是否具备理解快节奏和复杂程序所需的基础。训练营也是检查学生是否有动力和是否具备良好素质的方式。训练营不仅是学习技能的地方,它们还建立了一个社区。

通过考试意味着你已经准备好开始一个密集的训练营

当我加入训练营时,我也参加了一次考试。介绍部分是关于我的动机和我的背景,第二部分是关于 Python 基础知识,最后我需要解决 2 道练习题(这是我第一次进行现场编码体验 🤣)。第一个编码任务很简单(“在字符串中找到最长的单词”或类似的任务),而第二个则很难。

这是故意为之的。考官们测试了我们应对困难情况的能力,我们的思维能力,以及分解问题的能力。我花了 45 分钟完成这个任务。

养成学习和获取信息的习惯

在训练营中,你每天都会接收到大量信息。开始阅读新的文章,每天写一些简单的代码片段。每天从 15 到 30 分钟开始。这样你会更容易跳入全职学习。你将习惯于学习和自我提升。

这也将帮助你更好地为考试做准备。比起一个月内吸收大量信息,这要好得多。

在你掌握一些基础知识后去参加训练营

我认为这是这里最重要的建议之一。

训练营不是灵丹妙药或魔法地方,你去那里就能神奇地成为一个超级强的专家。在我看来,训练营更像是一个加速器,而不是数据科学的首次接触。

我坚信,获得一些基础知识是个好主意,因为训练营会让你的知识更好、更深入。你将有一些已经掌握的知识,而训练营会进一步深化和拓宽它。

你不需要掌握一切——一些基础事实和理解就足够让你以 x5 的强度开始训练营。

根据我的观察,那些带着一些知识来参加训练营的学生进步比那些考试后刚来的人要多。而且,他们通过技术面试也更容易。

另一个令我惊讶的效果(😅):有些事情我第一次不理解,第二次却理解了。更重要的是,它帮助我解开了那些完全困惑并困在我脑中的问题。

突然间,我比预期的要更准备好。我从 2020 年初封锁期间开始对数据科学感兴趣,并在 Coursera 上参加了一个课程。之后,我阅读了很多关于数据的书籍,观看了许多 YouTube 视频。结果,我学到了关于经典机器学习的一些知识。

尽管如此,我还是感到困惑,将正则化和回归搞混在一起。我以为自己太笨,无法理解神经网络是如何工作的。我决定参加训练营,“为了在可衡量的时间内做好面试准备”。

当然,经典机器学习是训练营课程的一部分,我理清了很多东西。当我的小组伙伴们试图拟合他们的第一个线性回归时,我对创建新的多项式函数和寻找更复杂的依赖关系感兴趣。以便更深入地了解我已经熟悉的事物。而且,是的,经典机器学习中的一些基础帮助我更好地理解了神经网络。

这是我推荐你熟悉的主题列表(如果你想在训练营期间让自己的生活更轻松高效)。实际操作要比阅读更有效:

  1. Bash(基本命令)。提高工作效率

  2. Git(你必须练习它,从理论上讲,它可能会让人困惑)。我第一次在训练营中使用 git,并被所有的 push/pull/merge 等操作惊呆了。

  3. 超越基础数据结构的 Python 练习。我建议你深入了解 OS 模块、文件操作、JSON、日期时间模块和 itertools。面向对象编程基础也是有用的。

  4. 数据科学的流行 Python 库:pandas、NumPy、sklearn。它们的基础知识以及如何使用它们。

  5. 适合初学者的机器学习和神经网络材料。

  6. …以及你对数据感兴趣的任何内容。

规划你的财务和日常生活

这是枯燥的一部分,但非常重要。当你在 bootcamp 学习时,你的所有思绪都会集中在学习上。我曾经做过一个关于代码的梦。你不会有太多时间去思考日常生活。在你开始全职项目之前,这里有一系列问题需要你回答

  1. 在项目期间以及找工作时我将住在哪里?

  2. 我将如何支付 Bootcamp 课程费用?哪种选项最适合我?

  3. 我将如何支付住宿费用?

  4. 我需要多少资金才能吃到健康而美味的食物?我在哪里吃早餐、午餐和晚餐?

  5. 我的学习将如何影响他人?(例如,谁来遛我的狗?)

  6. 我是否有足够的储蓄来应对求职期间的开支?

计划是有效的。我有一个组员是一个有两个孩子的女性。由于她出色的规划能力,她在学习上取得了成功,家庭生活也一切顺利。

就我而言,我意识到良好的饮食和睡眠时间表可以帮助你获得知识。这并不意味着你必须遵循严格的饮食,只是意味着你摄入足够的脂肪、蛋白质和健康的碳水化合物,不滥用酒精和能量饮料。

我也确保每晚至少睡 8 小时。如果我睡得少,我早上无法集中注意力,白天感到愚蠢。关于良好睡眠的重要性已经有很多讨论。

在 bootcamp 期间

你已经做好了准备,开始了你的 Bootcamp 之旅。以下是一些帮助你顺利学习的提示

合理地做笔记

我见过两种笔记方式:“我会逐字抄写演示文稿”和“我会记住,不需要写”。这两种方法都是错误的。在第一种情况下,导师会分享幻灯片和笔记,在第二种情况下,你会忘记你没有记住的内容。

我有两种类型的笔记:第一种是在讲座中用手写的,另一种是我在电脑上输入与实践相关的有用信息。

第一种类型:我记录了对关键思想的个人理解。这不是对幻灯片的简单重写,而是用我自己的话描述我对特定思想的理解。我还记录了重要的参考资料以及我可以在哪里阅读/观看更多关于这个话题的信息。我总是留出一点空间用于提问。

在我的电脑上,我将实际笔记分成了几组(例如:bash 命令、git、sklearn 技巧等),每当发现有趣或重要的内容时,我都会立即填写。我还设置了一个“杂项”部分,用来写下随机的笔记。

这种记录方式在准备面试时拯救了我的生命。

尝试理解,而不是复制/粘贴

这些建议不仅对你的训练营有帮助,而且对你的整个职业生涯都有益。

通常,你会有一个 Jupyter notebook 或者一个 .py 脚本,其中包含了一个给定主题的示例。你可能会有很强的冲动去复制代码,稍微调整一下,然后让它运行。但这是一个低效的方法。

我坚信,首先要理解代码内部发生了什么,它是如何工作的,然后自己实现它。至少你会明白特定代码片段是如何工作的,并且将来能够实现它。作弊不是一个好主意,你只是在欺骗自己。

不要害怕提问

我花了前两周时间学会了提问。我们的导师告诉我们,没有所谓的愚蠢问题,世界上最愚蠢的问题就是没有提出的问题。

在我的情况下,训练营为学习和发展创造了一个很好的环境,我开始融入并与他们交流。

在实践过程中,我制定了一个正确提问的公式

当是理论时:

  1. 你解释了“这个”,但我不理解“那个”。你能多给些例子/为什么会这样吗?

如果是编码错误/实际问题

  1. 尽可能地尝试解决它

  2. 用谷歌搜索一下,然后再试一次

  3. 写下一个问题,列出我所有的解决方法,解释为什么不奏效,并给出另一个想法。所有这些信息带来了问题。

这帮助我将问题从“它不工作,帮我”改进为正确、完整且合理的问题。我非常感谢我们的导师,他们耐心地回答了我们所有的问题。幸运的是,大家得到了足够的关注。我非常感谢他们,我学到了很多。

对自己要有耐心

参加训练营是一个勇敢的决定。学习者经历了一个快速而复杂的课程,每天写很多行代码,消耗大量的信息。

所以不要责怪自己整个周末都没有学习,也不要坐到一天 24 小时。这里的关键是平衡和倾听自己身体的能力。保持努力工作和良好休息之间的平衡非常重要。没有适当的放松,很难取得太多成就。我们的目标是支持你度过这段复杂的旅程。

与组员沟通

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

比萨派对(作者提供的图片)

不要害怕在组员面前显得奇怪。你正在经历训练营——这将把你们聚在一起。讨论当天的话题、数据科学新闻或只是聊聊天是个好主意。这在训练营的日子里对我帮助很大。你需要知道你的组员是你在行业中的网络基础。现在他们是训练营的学生,但 1 年、2 年、3 年后他们会成为什么样的人呢?

我的训练营同事是我生活中最大的福分之一。这真是不可思议的好运。从第一周开始,我们就开始了大量的沟通。我们在咖啡休息时聊天,一起吃午饭,玩桌游。他们是最棒的同事榜样。两年后,我仍然与他们保持联系,并在不同的活动中见面。

我从未想过我会如此提高我的软技能。在训练营之前,我几乎无法与销售人员交谈,谁会知道我会成为一个优秀的沟通者呢?

我还坚信友好的氛围比有毒和竞争的环境更有利于成长。这不是《饥饿游戏》,其中只有一个人得到工作,所以一起合作更有效。

我与优秀的人一起学习。我们在面试中互相支持,讨论如何提出一个问题或另一个问题。每一个录用通知对整个小组来说都是一次庆祝。有一次,我和我的小组成员申请了同一个职位,并且得到了相同的测试。我们没有竞争,而是一起坐下来互相帮助完成这些测试。有些部分对我来说比较容易,有些部分对我的小组成员来说比较容易。结果,我们都完成了测试。

不要害怕参加黑客马拉松和其他活动

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

我在 2021 年第一次线下黑客马拉松中的手臂(图片来源:作者)

我相信,行业中的每一个活动都是学习新知识、认识行业内的人或向 IT 界展示自己的机会。

我知道在训练营学习期间参加活动可能会让人感到害怕。我为自己设定了活动的目的,这使得事情变得更容易。例如,“我想做一个关于零售行业数据的项目”。在黑客马拉松中,我设定了提高技能的目标,一切都很顺利。

我很早就开始参加黑客马拉松——在训练营的第 5 周。当然,我们的团队由训练营的成员组成。我们有一个优势——我们作为一个团队团结一致。我去那里是为了测试我的技能和学习一些新东西。那是一个线下活动,我感受到了整个氛围——几排桌子上坐着很多团队,通宵编程,免费能量饮料。我在那次活动中表现出色,并且(意外地)在 Pandas 上取得了很大的进步。

聚会和会议比黑客马拉松需要的勇气少——你只需要报名。组织委员会希望看到相关的观众——而你正是那样。还有一个生活小窍门:你可以请训练营的管理部门邀请某人来为你的观众做演讲。当我还是学生的时候,我在反馈表中写道,能有一个演讲嘉宾会很不错。五周后,那个人被邀请来专门为我们做了一次演讲。

不要害怕犯错

关于从错误中学习已经写了无数次。这里是我在学习期间如何搞砸一个模块项目的故事。

在 NLP 模块的项目日,我在处理 CUDA 时遇到了困难。我想比较 Markov 链和神经网络之间的文本生成。当 Markov 链部分完成时,我无法让神经网络工作。我不想在组员和导师面前做演讲。我记得说了类似“这是一个大失败,它没用,我不想来”的话。他们回答说你的经历和实验很重要,分享它们是个好主意。观众非常感兴趣,认真听我讲解。

训练营结束后

不要害怕在职业支持会议中讨论你自己的案例。

训练营可以提供职业支持。在我的学校,我们学习了如何写一份好的简历,如何展示我们的 git 作品集,如何在不同类型的面试中表现出色,以及更多。我发现当我开始直接寻求反馈时,这些帮助变得更加有用:第一次我来找人审阅我刚准备好的简历,并提出了一些问题。这非常有用,因为每个人都有自己的背景,其中一些可以在简历中呈现。我得到了可以在面试中使用的直接帮助。

在你的小组内分享你的经验

你的训练营导师和小组成员可以帮助你进行第一次找工作。例如,我询问了如何回答面试中那些我无法处理的难题。我得到了帮助和很好的解释。我寻求了帮助,并检查了我的测试卷。我还与职业教练讨论了与人力资源的面试,并与其他人分享了。

我的组员们也分享了他们的故事。我们讨论了面试,收集了问题,互相支持。我的意识有了显著提升。我的经验 + 他人的经验 = 职业智慧。

不要错过毕业生活动

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

幕后花絮:我在为未来申请者举办的活动中(图片来自作者)

对毕业生可以提供不同的活动。例如,在开放日发言或有机会从候选人那里考取考试。我曾经举办过关于 Python 基础的讲座,参加了考试,并在各种活动中发言。你不必参加每一个活动,但自己做点什么是有意义的。这将有助于确保你被记住。拥有额外的支持,知道你在职业道路上并不孤单,训练营可以在困难情况下提供帮助或建议。

感恩并分享你的成功

优秀的训练营(我相信你在阅读完这篇文章后会选择一个好的训练营)会关注他们的毕业生去了哪里。因此,找到工作后告诉他们是有意义的。谈谈公司、薪资、职责,并感谢训练营的帮助。我相信他们会非常高兴。

现在你知道了如何选择一个好的训练营并为课程做准备,如何在学习期间进行学习和行动,以及如何在之后留下良好的印象。训练营是一个独特而难忘的经历,它对我影响很大。祝你好运!

如何根据您的数据将领域特定知识添加到 LLM

原文:towardsdatascience.com/how-to-add-domain-specific-knowledge-to-an-llm-based-on-your-data-884a5f6a13ca

将你的 LLM 转变为领域专家

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

·发表于 Towards Data Science ·7 分钟阅读·2023 年 7 月 11 日

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

Hubi’s TavernUnsplash 提供的照片

介绍

近年来,大型语言模型(LLMs)已经深刻改变了我们与技术的工作和互动方式,并且在各种领域中被证明是有用的工具,充当写作助手、代码生成器,甚至是创造性合作伙伴。它们理解上下文、生成类似人类的文本以及执行广泛的语言相关任务的能力使其成为人工智能研究的前沿。

虽然大型语言模型(LLMs)在生成通用文本方面表现优异,但当面对需要精确知识和细致理解的高度专业领域时,它们往往表现得较差。在用于特定领域任务时,这些模型可能会表现出局限性,甚至在某些情况下产生错误或虚假的回答。这突显了将领域知识融入 LLMs 的必要性,使其能够更好地应对复杂的行业术语,展示更细致的上下文理解,并减少生成虚假信息的风险。

在这篇文章中,我们将探讨将领域知识注入 LLMs 的几种策略和技术之一,使其在特定专业环境中表现最佳,通过将文档片段作为上下文添加到 LLM 中来注入查询。

该方法适用于任何类型的文档,仅使用安全的开源技术,这些技术将在你的计算机上本地运行,无需访问互联网。借助这一点,我可以在个人和机密数据上使用它,而不必担心第三方网站的访问。

原理

这是如何工作的详细说明:

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

过程的图解。图像由作者提供。

第一步是拿到我们的文档,并基于这些文档构建一个向量索引数据库。

向量数据库是一种旨在高效存储和查询高维向量的数据库。这些数据库支持快速的相似性和语义搜索,同时允许用户根据某些距离度量找到与给定查询向量最接近的向量,而不是像传统的 OLTP 和 OLAP 数据库那样对行和列中的值进行查询。

这意味着我们可以创建表示任何文档的嵌入,并用它来填充数据库。

然后,一旦构建完成,我们可以执行一个查询,该查询也将被嵌入,并注入到向量索引数据库中,这样将返回与我们的查询最相关的文档片段。

最后,这些向量可以作为上下文注入到本地 LLM 中,与我们原始的查询一起。这种方式下,选择的上下文将足够小,以被大多数 LLM 接受,并且由于与我们的查询相关,模型将拥有足够的知识来准确回答问题。一点点提示工程也会有所帮助。

案例示例和代码库

在这篇文章中,我们将使用一个本地的开源 LLM,并注入所有 Python 增强提案(PEPs)的领域知识。这一原则可以应用于任何文档类型,但我将使用 PEP,因为它易于获取且属于公共领域,这使它成为一个理想的示例数据集。

你可以在这个代码库中找到我用于撰写这篇文章的完整代码:

github.com/Anvil-Late/knowledge_llm/tree/main

[## GitHub - Anvil-Late/knowledge_llm: 向 LLM 添加领域知识的指南

向 LLM 添加领域知识的指南。通过创建一个帐户来为 Anvil-Late/knowledge_llm 的开发做贡献…

github.com

结果的快速预览

结果的展示样例

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

查询被处理和回答的示例。图像由作者提供。

如何安装 LLM

如果你的计算机上没有安装 LLM,你可以在这里找到如何安装的逐步指南:

medium.com/better-programming/how-to-run-your-personal-chatgpt-like-model-locally-505c093924bc

[## [GPT 教程] 如何在本地运行您的个人 ChatGPT 类模型

您自己的个人 AI 助手

betterprogramming.pub](https://betterprogramming.pub/how-to-run-your-personal-chatgpt-like-model-locally-505c093924bc?source=post_page-----884a5f6a13ca--------------------------------)

如何构建和查询向量索引数据库

您可以在这个仓库中找到构建向量索引数据库的完整代码:

github.com/Anvil-Late/knowledge_llm/tree/main

广义而言,在 src 文件夹中:

  • parse.py 创建 PEP 语料库

  • embed.py 创建嵌入的语料库

  • 您可以拉取 Qdrant 向量索引数据库的 Docker 镜像,并使用 docker pull qdrant/qdrant 命令运行它

    docker run -d -p 6333:6333 qdrant/qdrant

  • create_index.py 创建并填充向量索引数据库

  • query_index.py 嵌入一个查询并检索最相关的文档

如果您需要更多细节,您可以在这里找到我的逐步指南:

betterprogramming.pub/efficiently-navigate-massive-documentations-ai-powered-natural-language-queries-for-knowledge-372f4711a7c8

[## 基于 AI 的文档搜索 — 使用自然语言查询导航您的数据库

高效文档导航

betterprogramming.pub](https://betterprogramming.pub/efficiently-navigate-massive-documentations-ai-powered-natural-language-queries-for-knowledge-372f4711a7c8?source=post_page-----884a5f6a13ca--------------------------------)

将所有内容结合起来

首先,我们将编写一个生成 LLM 提示的脚本:

import os
from query_index import DocSearch
import logging
import re
from utils.parse_tools import remove_tabbed_lines
logging.disable(logging.INFO)

def set_global_logging_level(level=logging.ERROR, prefices=[""]):
    """
    Override logging levels of different modules based on their name as a prefix.
    It needs to be invoked after the modules have been loaded so that their loggers have been initialized.

    Args:
        - level: desired level. e.g. logging.INFO. Optional. Default is logging.ERROR
        - prefices: list of one or more str prefices to match (e.g. ["transformers", "torch"]). Optional.
          Default is `[""]` to match all active loggers.
          The match is a case-sensitive `module_name.startswith(prefix)`
    """
    prefix_re = re.compile(fr'^(?:{ "|".join(prefices) })')
    for name in logging.root.manager.loggerDict:
        if re.match(prefix_re, name):
            logging.getLogger(name).setLevel(level)

def main(
    query,
    embedder = "instructor",
    top_k = None, 
    block_types = None, 
    score = False, 
    open_url = True,
    print_output = True
    ):

    # Set up query
    query_machine = DocSearch(
        embedder=embedder,
        top_k=top_k,
        block_types=block_types,
        score=score,
        open_url=open_url,
        print_output=print_output
    )

    query_output = query_machine(query)

    # Generate prompt
    prompt = f"""
Below is an relevant documentation and a query. Write a response that appropriately completes the query based on the relevant documentation provided.

Relevant documentation: {remove_tabbed_lines(query_output)}

Query: {query}

Response: Here's the answer to your query:"""

    print(prompt)
    return prompt

if __name__ == '__main__':
    set_global_logging_level(logging.ERROR, ["transformers", "nlp", "torch", "tensorflow", "tensorboard", "wandb"])
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('--query', type=str, default=None)
    parser.add_argument('--top_k', type=int, default=5)
    parser.add_argument('--block_types', type=str, default='text')
    parser.add_argument('--score', type=bool, default=False)
    parser.add_argument('--open_url', type=bool, default=False)
    parser.add_argument('--embedder', type=str, default='instructor')
    parser.add_argument('--print_output', type=bool, default=False)
    args = parser.parse_args()
    main(**vars(args))

logging.disable(logging.INFO)set_global_logging_level 可以防止代码执行过程中打印过多内容,因为该脚本打印的所有内容都会被捕获。

我们将这个提示生成与提示注入结合起来,使用以下 bash 脚本:

#!/bin/bash

# Get the query from the command-line argument
query="$1"

# Launch prompt generation script with argument --query
if ! prompt=$(python src/query_llm.py --query "$query" --top_k 1); then
    echo "Error running query_llm.py"
    exit 1
fi

# Run the terminal command
<PATH_TO_LLAMA.CPP>/main \
    -t 8 \
    -m <PATH_TO_LLAMA.CPP>/models/Wizard-Vicuna-13B-Uncensored.ggmlv3.q4_0.bin \
    --color \
    -c 4000 \
    --temp 0.1 \
    --repeat_penalty 1.1 \
    -n -1 \
    -p "$prompt" \
    -ngl 1 

这里发生的情况是,提示生成脚本打印出提示,bash 脚本将其捕获到 $prompt 变量中,然后在 llama.cpp ./main 命令中使用 -p(或 --prompt)参数。

然后 LLM 将接管并完成提示,从‘Response: Here’s the answer to your query:’开始。

记得将 <PATH_TO_LLAMA.CPP> 替换为你计算机上 llama.cpp 克隆的路径,将 Wizard-Vicuna-13B-Uncensored.ggmlv3.q4_0.bin 替换为你的 LLM。我个人选择了这个,因为它给了我很好的结果,并且没有受到限制性许可证的约束,但你可以尝试其他模型!

结论

让我们回顾一下我们在这里完成的工作:

在本文中,我们深入探讨了一种有效的策略,通过将领域知识注入 LLM 来增强其能力。尽管 LLM 在各种任务中表现出色,但它们在面对需要精确知识和细致理解的高度专业化领域时,往往会遇到困难。

为了解决这些局限性,我们探索了一种方法,将领域特定的文档纳入 LLM。通过基于文档构建一个向量索引数据库,我们建立了一个高效的相似性和语义搜索基础。这使我们能够识别出与特定查询最相关的文档,然后将其注入本地 LLM 作为上下文。

我们所提出的方法通过使用 Python 增强程序(PEPs)作为代表性数据集来进行示例。然而,值得注意的是,这种方法适用于任何形式的文档。本文中提供的代码片段和仓库作为实际演示,展示了实施过程。

按照 outlined steps,用户可以提升 LLM 在特定专业环境中的表现,使模型能够处理复杂的行业术语并生成更准确的响应。此外,所使用的安全和开源技术确保了这一过程可以在本地执行,无需外部互联网依赖,从而保护隐私和机密性。

总之,将领域知识融入 LLM(大语言模型)中,使这些模型能够在专业任务中表现出色,因为它们对其操作的背景有了更深入的理解。这种方法的影响跨越了不同领域,使 LLM 能够提供量身定制的宝贵帮助和见解。通过利用 LLM 和领域专业知识的潜力,我们为提升人类与 AI 的互动以及在专业领域利用人工智能的力量打开了新的可能性。

感谢阅读!

如果你有任何问题,请不要犹豫,留下评论,我会尽力回答!

如果你喜欢这个内容,你也可以通过我的推荐链接直接在 Medium 上支持我的工作,并成为会员以获得无限制访问 这里 😃

如何通过残差分析你的时间序列模型

原文:towardsdatascience.com/how-to-analyse-your-time-series-model-using-residuals-f980f597332e

学习如何使用预测模型的残差来提高其性能

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

·发表在Towards Data Science ·阅读时间 5 分钟·2023 年 1 月 3 日

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

照片由regularguy.eth提供,发布在Unsplash

背景

能够分析你的时间序列模型对于诊断其性能至关重要。一个实现这一点的方法是通过拟合模型的残差。在这篇文章中,我们将讨论什么是残差以及如何利用它们来改进你的模型,并提供一个 Python 示例。

附加视频。

什么是残差?

在时间序列分析中,残差,r,是拟合值 ŷ实际值 y之间的差异:

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

方程由作者使用 LaTeX 生成。

重要的是要区分残差误差。误差是实际值和预测值之间的差异。然而,正如上面所示,残差是实际值和拟合值之间的差异。这些拟合值是模型在拟合训练数据时做出的预测。由于模型知道所有观测值,它不再是技术上的预测,而是拟合值

如果你想了解更多关于预测误差及其指标的信息,请查看我之前的相关文章:

## 预测性能指标概述

预测时间序列的基本性能指标概述

towardsdatascience.com

残差分析

我们可以使用残差来分析我们的模型捕捉数据特征的效果。一般来说,残差应该:

  • 显示非常少或没有自相关偏自相关 如果它们有任何形式的相关性,那么模型遗漏了一些数据中的信息。我们可以使用Ljung–Box统计检验和相关图来确定残差是否确实相关。

  • 残差的均值应该是,否则预测将是有偏的。实际上,通过简单地加或减去偏差来调整预测值是非常容易的。

作为背景,零假设在 Ljung–Box 检验中假设残差不相关。因此,我们希望无法拒绝零假设,并且 p 值大于 5%。

现在让我们在 Python 中进行一些残差分析吧!

Python 中的残差分析

拟合 Holt-Winters 模型

在这次简短的演示中,我们将指数平滑 Holt-Winters模型拟合到著名的美国航空乘客数据集。如果你想了解更多关于 Holt-Winters 模型的工作原理,确保阅读我之前关于它的博客:[链接]

## 使用 Holt-Winters 模型进行时间序列预测

对最强大和最有用的指数平滑模型的讨论和实现

towardsdatascience.com

数据 来自 Kaggle 的 CC0 许可证。

GitHub Gist 由作者提供。

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

图表由作者在 Python 中生成。

该模型的预测效果看起来相当好。让我们通过将实际值拟合值残差插入训练数据集中来分析残差:

GitHub Gist 由作者提供。

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

图像由作者在 Python 中生成。

正如我们所看到的,残差确实是实际值#Passengers)和拟合值之间的差异,如之前所述。

残差相关性

残差的相关性可以通过绘制它们的自相关偏自相关函数来计算:

作者的 GitHub Gist。

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

由作者在 LaTeX 中生成的图表。

大多数相关性都在统计上不显著的蓝色区域内,这表明残差不相关。然而,你可能会注意到相关性中存在一些重复模式。这表明模型可能没有完全考虑某些季节性成分。

如果你想深入了解自相关和偏自相关,请参考我之前关于这些内容的帖子:

时间序列分析中的自相关 [## 时间序列分析中的自相关

解释什么是自相关以及它在时间序列分析中的重要性。

偏自相关在时间序列分析中的应用 [## 偏自相关在时间序列分析中的应用

解释什么是偏自相关及其在时间序列分析中的重要性

偏自相关在时间序列分析中的应用

Ljung-Box 检验

确定残差是否相关的一个更量化的方法是进行Ljung–Box统计检验:

作者的 GitHub Gist。

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

由作者在 Python 中生成的图像。

这显示了前10个滞后的 p 值。它们都低于显著性水平0.05,因此我们拒绝没有自相关的零假设。因此,我们的残差中存在相关性,在重新拟合模型时需要重新审视。

如果你想了解更多关于统计检验和 p 值的内容,我推荐阅读我之前的相关文章:

Z 检验简单解释 [## Z 检验简单解释

对 Z 检验在统计假设检验中的直观解释

Z 检验简单解释

残差的直方图

一个直方图将确定残差是否具有零均值对称(无偏差):

作者的 GitHub Gist。

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

由作者在 Python 中生成的图表。

在这种情况下,残差主要分布在零附近,均值为-0.023,甚至可能略微负偏差。这表明我们可能不需要为计算的预测提供偏移量。

总结与进一步思考

在这篇文章中,我们展示了如何使用模型的残差来诊断时间序列预测模型。判断模型是否适合的两个关键指标是:残差没有或只有很少的相关性,并且其均值接近零。

本博客中使用的完整代码可在我的 GitHub 上找到:

[## Medium-Articles/residual_analysis.py at main · egorhowell/Medium-Articles

我在我的中等博客/文章中使用的代码。通过创建一个帐户来贡献 egorhowell/Medium-Articles 的开发…

github.com](https://github.com/egorhowell/Medium-Articles/blob/main/Time%20Series/Time%20Series%20Tools/residual_analysis.py?source=post_page-----f980f597332e--------------------------------)

另外一件事!

我有一个免费的新闻通讯,Dishing the Data,在这里我每周分享成为更好数据科学家的技巧。没有“废话”或“诱饵”,只有来自实践数据科学家的纯粹可操作的见解。

[## Dishing The Data | Egor Howell | Substack

如何成为更好的数据科学家。点击阅读《Dishing The Data》,由 Egor Howell 编写,是 Substack 出版的内容…

newsletter.egorhowell.com](https://newsletter.egorhowell.com/?source=post_page-----f980f597332e--------------------------------)

与我联系!

参考文献与进一步阅读

如何评估推荐系统

原文:towardsdatascience.com/how-to-assess-recommender-systems-10afd6c1fae0?source=collection_archive---------2-----------------------#2023-04-16

对评估指标公式的深入探讨

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

·

关注 发表在 Towards Data Science ·6 min read·Apr 16, 2023

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

图片来源。该图片在 Pixabay 的内容许可下可免费使用。

在最近的文章中,我们介绍了一些在工业界和文献中广泛应用的显著推荐系统算法,通过不同的视角使用图。此外,我们还阐述了包括基于知识图谱的推荐系统在内的新兴方法,这些方法在推荐研究领域越来越受到关注。

在本文中,我们将深入探讨评估推荐系统的过程。我们将探索评估其性能的关键标准和指标,包括准确性、多样性、覆盖率、新颖性和意外惊喜。

准确性指标

近年来,大多数推荐系统领域的研究工作部分通过来自信息检索领域的准确性指标进行评估,例如精确度 (P@K) 和召回率 (R@K),其公式如下:

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

其中 n 和 m 分别表示用户数和项目数,i₁,i₂,…,iₖ 是从 1 到 K 排名的项目,如果推荐的项目 iⱼ 对用户 u 相关,则 hit 的值为 1,否则为 0。Rel(u) 表示测试集中用户 u 的相关项目集合。

在产品推荐的背景下,这些评估指标的目的是识别给定用户的 K 个最相关项目,并衡量检索精确相关信息的质量。在仅向用户推荐一个项目的特殊情况下,如会话式推荐系统中,我们希望测量即时下一个项目的正确性,即 hitrate@K

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

类似于 R@K,hitrate@K 衡量推荐系统的正确性或准确性。

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

推荐系统向用户建议一份按排名排列的电影列表。如果用户决定观看前 K 列表中的一部电影(例如 Gatsby),hitrate@K 将等于 1,而 MRR@K 将等于 0.5,因为该电影在列表中排名第二。注意:该图表由作者创建。

文献中广泛使用的其他三个指标,用于评估推荐系统的准确性,特别是捕捉命中在列表中的排名情况:

  • 均值平均精度 (MAP@K):该指标衡量推荐系统提供的相关项目的顺序:

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

  • Top-K 均值倒数排名 (MRR@K):该指标是 MAP@K 的特例,其中只有一个相关项目。它衡量推荐系统如何将相关项目与不相关项目进行良好排名:

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

其中 iⱼ 是前 K 个推荐项目中的相关推荐项目。

  • 归一化折扣累积增益 (NDCG@K):MAP@K 和 NDCG@K 都重视排序,但主要区别在于均值平均精度测量的是二元相关性(项目要么感兴趣,要么不感兴趣),而 NDCG@K 允许以实数形式的相关性分数:

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

在这里,IDCG@K 是理想折扣累积增益,定义如下(Rel(u) 仅包含用户 u 的相关项目):

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

超越准确性

尽管这些指标在评估推荐系统中的相关性,但推荐相同类型的产品有时可能适得其反,并且在实际应用中可能不够充分(如 Netflix、YouTube 等)。例如,在 Netflix 上,用户可能会被新类型的电影和系列吸引;在 YouTube 上,用户通常希望观看新视频。用户必须感到惊喜,一个好的推荐系统应该具有推荐意外且吸引人的项目的能力。业界也支持不完全依赖于基于精度的度量(例如 Spotify 的每周发现功能)。在研究中 [1],作者指出评估协议的目的是评估推荐项目的质量,而不仅仅是其准确性或实用性。在这种情况下,只有在线实验中系统的用户能够评判推荐质量,才能可靠地评估推荐。因此,在离线评估时,必须考虑除单一准确性之外的其他指标。

为了对推荐质量得出可靠结论,推荐系统不仅需要提供准确的推荐,还必须提供有用的建议。确实,一个极其流行的项目可能是一个准确的建议,但对用户来说可能并不有趣。意外性、新颖性以及多样性是与准确性指标相对的替代度量标准。

推荐系统中的意外性概念指的是系统向用户推荐意外且吸引人的产品的能力。在 [3] 中,提出了一种度量来通过在过滤掉那些过于明显的项目后评估推荐项目的精度来衡量意外性。下面的公式概述了该度量的计算方法。变量 hit_non_pop 类似于 hit,但它将前 k 个最流行的项目视为不相关的,即使它们被包含在用户 u 的测试集中。这是因为流行项目被认为是显而易见的,因为大多数用户都很熟悉它们。

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

在 [4] 中,提出了一种新颖性度量来评估推荐系统建议用户不太可能知道的项目的能力。该度量的目的是帮助推荐系统促进用户发现新项目。下面的公式在 [5] 中定义,概述了这一度量的计算方法。需要注意的是,与之前的指标不同,新颖性指标仅关注推荐项目的新颖性,而不考虑其正确性或相关性。

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

函数 Pₜᵣₐᵢₙ : I → [0, 1] 返回在训练集中分配给项目 i 的反馈比例。这个值表示在训练集中观察到特定项目的概率,即与该项目相关的评分数量除以可用评分的总数。

下一步是什么?评估协议

在大多数推荐系统的研究工作中,评估协议是在离线环境中进行的,其中上述指标仅基于过去的互动进行测量。然而,这在现实中被证明是不够的。

在下一个博客文章中,我们将突出不同的评估方法,包括离线评估、在线评估和用户研究,并讨论它们的优缺点。

参考文献

[1] Mouzhi Ge, Carla Delgado-Battenfeld, 和 Dietmar Jannach. 超越准确性:通过覆盖度和偶然性评估推荐系统。在第四届 ACM 推荐系统会议论文集中,RecSys ’10,第 257–260 页,美国纽约,2010 年。计算机协会。

[2] Jonathan L. Herlocker, Joseph A. Konstan, Loren G. Terveen, 和 John T. Riedl. 评估协同过滤推荐系统。22(1):5–53,2004 年 1 月。

[3] Marco de Gemmis, Pasquale Lops, Giovanni Semeraro, 和 Cataldo Musto. 关于推荐系统中偶然性问题的研究。信息处理与管理,51(5):695–717,2015 年 9 月。

[4] Saúl Vargas 和 Pablo Castells. 推荐系统中新颖性和多样性度量中的排名与相关性。在第五届 ACM 推荐系统会议论文集中,RecSys ’11,第 109–116 页,美国纽约,2011 年。计算机协会。

[5] Enrico Palumbo, Diego Monti, Giuseppe Rizzo, Raphaël Troncy, 和 Elena Baralis. entity2rec: 针对项目推荐的属性特定知识图谱嵌入。专家系统应用,151:113235,2020 年。

如何使用 AI 自动生成长时间 YouTube 视频的摘要

原文:towardsdatascience.com/how-to-auto-generate-a-summary-from-long-youtube-videos-using-ai-a2a542b6698d

使用 Whisper 和 BART 模型在本地 PC 上总结斯蒂芬·沃尔夫勒姆的演讲的逐步指南

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

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

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

作者生成的图像

动机

在当今快速变化的世界中,保持信息更新和获得灵感可能是一项挑战,尤其是当时间紧迫时。就个人而言,我非常喜欢 YouTube 上的播客和演讲。这些播客和演讲是知识的宝藏,充满了来自各个领域顶尖人才的见解。然而,由于时间限制,我无法观看每一个有趣的视频,因为它们通常超过一小时。这让我开始思考:如果我能创建一个端到端的解决方案来自动提取主要亮点呢?因此,我开始探索 AI 生成解决方案,帮助我获取一些错过的播客/演讲的自动摘要。

在本文中,我讨论了在本地 PC 上进行端到端解决方案。首先,我将介绍如何使用开源的Whisper 模型,对斯蒂芬·沃尔夫勒姆关于 ChatGPT、AI 和 AGI 的演讲进行转录,该演讲在 YouTube 上可用。接着,我将演示如何使用开源的BART模型总结长文本。

让我们看看如何实现这个目标。

请记住,确保在下载内容之前核实版权/许可是否允许下载是至关重要的。

一点背景

Whisper是一个开源自动语音识别模型,基于从互联网收集的 680,000 小时多语言数据进行训练。它依赖于端到端的编码器-解码器Transformer架构。

BART 是一个基于 Transformer 的 seq2seq 模型,结合了双向(BERT 风格)编码器和自回归(GPT 风格)解码器。它通过随机添加噪声并学习重建原始内容进行预训练,在总结和翻译等任务上表现良好。

HuggingFace transformers 库提供了一个用户友好的解决方案来使用和自定义模型。此外,它还提供了可以用于微调模型以更好地适应数据的 API。

PyTube 是一个无需依赖的 Python 库,用于下载和流式传输 YouTube 视频。

NLTK是一个标准的自然语言处理(NLP)任务的 Python 库。

端到端过程

过程包含四个主要步骤:

1. 设置环境

2. 下载 YouTube 视频:PyTube

3. 转录音频:Whisper

4. 总结生成的文本:BART

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

图片由作者提供

1. 设置环境

我的环境设置如下:

1.1 安装库

一些备注:

👉 请注意,只有在从笔记本单元格安装库时才需要 !

👉 直接从 GitHub 安装 Whisper 模型的最新更新。

👉 解决 PyTube 问题。 如果遇到以下错误 "pytube: AttributeError: ‘NoneType’ object has no attribute ‘span’ cipher.p",请前往 {home}/.local/lib/{your_pythonversion: ex. python3.10}/site-packages/pytube/cipher.py Line 411 并将 transform_plan_raw 变量的值替换如下:

1.2 导入库

1. 下载 YouTube 视频

让我们获取以下演讲的总结“ChatGPT, AI, and AGI with Stephen Wolfram (Wolfram Research 创始人兼首席执行官) YouTube 上可用 (创作共享许可(允许重用))。

要将视频本地下载为音频文件,我们使用 PyTube 库的 YouTube 类。确保提供有效的 URL。

2. 转录音频

一旦我们将音频下载到本地,我们应该会看到一个名为 demo.mp3 的文件。要转录音频,我们加载 medium Whisper multilingual model,它具有 7.69 亿个参数,并提供英语或多语言格式。您可以查看可用语言模型列表,选择最适合您设置的模型。为了更高的准确性,您可以使用 large Whisper multilingual model

合并后的字符串将存储在 result[‘text’] 变量中,并保存在本地的 demo.txt 文件中。

❗️ 需要注意的是,转录过程可能需要超过一个小时,具体取决于您的电脑配置。要测试演示,您可以选择一个较短的视频。

3. 总结生成的文本

由于模型无法一次处理多个标记,因此重要的是将文本分割成较小的段落,每个段落最多包含 4000 个标记。为此,我们可以使用 punkt 预训练句子分割模型,它是自然语言工具包(NLTK)库的一部分,能够有效处理自然语言。一旦我们将文本分割成较小的句子块,就可以将它们存储在 text_chunks 变量中以供进一步使用。

我们使用句子分割以防止信息丢失

3.1 将大文本分割成块

这里是可以用来完成工作的代码。

代码包括两个函数:read_file() 用于读取 demo.txt 文件,split_text_into_chunks() 用于将文本分割成块。

3.2 使用 BART 进行文本摘要

为了总结文本,我们使用 HuggingFace Transformers 库和预训练的多语言 BART-large 模型,[facebook/bart-large-cnn](https://huggingface.co/facebook/bart-large-cnn),该模型在 CNN Daily Mail 数据集上进行了微调。Hugging Face 的 Transformers 库提供了许多用于文本、图像或声音等各种任务的现成模型。例如,它提供了一个易于使用的 BART 模型文本摘要管道:pipeline("summarization", model="facebook/bart-large-cnn")。这使得使用起来简单而友好。

以下是执行摘要生成的代码。

总体而言,代码创建了 BART 摘要生成器的一个实例,为给定的文本块生成摘要,并仅在成功生成摘要时将其保存到 summary_demo.txt 文件中。如果摘要超过 5000 个字符,我们将再次使用 BART 摘要生成器。输出将保存在 short_summary_demo.txt 文件中。

这是总结:

Wolfram 语言可能成为更系统探索大型语言模型本质和深度的基础。这是一种精确的计算语言,但它谈论的是现实世界。LLM 中没有太多的模板代码。我认为 Chat GPT 向我们展示了一个重要的科学片段。我们已经自动化了模板代码。我的猜测是,随着人们越来越多地实际使用它,他们只会编辑代码。而它将完成大量的初始五行代码的工作。描述意义的规律性更多了。这实际上是一个问题,即 LLM 可以生成的内容与我们自然语言理解系统可以捕捉的内容之间的界限在哪里。我们已经有数十亿年的进化时间来处理自然的方式。微软研究院发布了一份关于 GPT-4 的 154 页分析报告,在报告中他们得出结论,并且这是他们论文标题中的内容,他们看到了 AGI 的一瞥。你可以做的计算宇宙的可能性是非常大的。我们人类只关心其中的一小部分。问题在于将计算宇宙中的事物与我们人类感兴趣的事物连接起来。在 1900 年,人们不会感到惊讶地认为空间是离散的。我希望在不久的将来,我们实际上能找到一种类似于空间布朗运动的现象,我们将能够看到,我们可以确定它是离散的。

主要收获

该教程是一个个人副项目的一部分,专注于探索生成性 AI 工具。

总结一下,Whisper 模型在所有测试的视频中都表现出色。尽管它偶尔会误识别产品或人物名称,但我对结果相当满意,并且会继续使用它。

另一方面,BART 模型提供了一个值得信赖的开源摘要选项。它的摘要效果相当好。我将它与 谷歌研究的 T5 模型 进行了比较,BART 的摘要更优。的确,它可能并不总是捕捉到所有关键事实,但它的结果很好,所以我会继续使用它来处理我的个人总结任务。

总体而言,像 Whisper 和 BART 这样的 AI 生成解决方案帮助我高效提取长时间播客和演讲中的重要见解。这样,即使在我没有剩余时间的时候,我也能保持信息更新。

我希望你喜欢这篇文章。

感谢阅读!

如果你想将来在收件箱中收到我的故事,不要忘记 订阅

如果你喜欢阅读我的故事并希望支持我作为作家,可以考虑注册成为 Medium 会员,访问数千篇数据工程和数据科学文章。

[## 使用我的推荐链接加入 Medium — Bildea Ana

作为 Medium 会员,您会员费的一部分将分配给您阅读的作者,您将获得对每篇故事的完整访问权限…

medium.com](https://medium.com/@anna.bildea/membership?source=post_page-----a2a542b6698d--------------------------------)

LinkedIn Twitter 上找到我!

查看我关于生成性 AI、MLOps 和负责任 AI 的文章合集

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

Ana Bildea 博士

生成性 AI

查看列表11 个故事外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Ana Bildea 博士

负责任的 AI

查看列表1 个故事外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Ana Bildea 博士

MLOps - AI 在生产中的应用

查看列表4 个故事外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如何通过 Python 预提交钩子提升代码质量?

原文:towardsdatascience.com/how-to-automate-code-quality-with-python-pre-commit-hooks-e550debbd62e

安心提交你的代码

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

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

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

Roman Synkevych 的照片,来自 Unsplash

如果你是 Python 开发者,你可能经常遇到团队成员有不同的编码风格,这使得代码库不一致。因此,这会导致错误,降低生产力,并且使合作变得困难

作为一个努力保持代码质量的人,我知道这种情况有多么痛苦。

👉 幸运的是,有一个解决方案可以解决这个问题:预提交钩子

预提交钩子是提交代码到版本控制系统之前运行的脚本或工具。它们可以自动格式化你的代码,运行测试,检查 lint 错误等等。

我开始在个人和专业项目中使用预提交钩子。它们帮助我早期发现并修复潜在问题,确保我的代码始终干净和一致。此外,它们通过自动化重复任务为我节省了大量时间和精力。

这篇实用的博客文章中,我们将深入探讨这个话题。我们将探索如何设置预提交钩子,定制它们以满足你的需求,并将它们整合到你的开发工作流中。

如果你是一个希望提升团队代码质量和生产力的 Python 开发者,这篇文章适合你。

所以,事不宜迟,让我们来看看 🔍

预提交:它们如何融入 Git 工作流

预提交钩子是自动运行的脚本,在每次提交之前检查你的代码是否有错误。这些钩子是语言无关的,帮助在提交到仓库之前捕捉问题,确保只有高质量的代码被提交。

以下图示展示了一个包含预提交钩子的 git 工作流程:当您执行 git commit 命令时,这些脚本会被触发。执行完成后,最后一步会验证所有检查是否通过。

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

我个人项目的预提交配置

  • ✅ 如果预提交检查未通过,您需要在代码库中进行迭代,并相应地提供修复。

  • ❌ 如果预提交检查通过,您的代码将成功提交

在 Python 项目中设置和配置预提交钩子

要在 Python 项目中开始使用预提交,首先需要安装它。您可以使用 Python 包管理器 pip 来完成这一操作。在终端中运行以下命令:

pip install pre-commit

安装完预提交后,您需要在项目的根目录中设置一个名为 .pre-commit-config.yaml 的配置文件。此文件将指定预提交应该使用哪些钩子。

以下是我在 .pre-commit-config.yaml 文件中使用的配置:

repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v3.4.0
    hooks:
    -   id: trailing-whitespace
    -   id: check-yaml
    -   id: end-of-file-fixer

在此配置中,我们使用了来自预提交钩子 repository(一个包含一些开箱即用钩子的库)中的三个钩子 trailing-whitespacecheck-yamlend-of-file-fixer

  • trailing-whitespace修剪尾随空白字符

  • check-yaml 检查 YAML 文件是否格式正确

  • end-of-file-fixer 确保文件以换行符结束,并且仅以换行符结束

设置完配置文件后,您需要安装 git 钩子。在终端中运行以下命令:

pre-commit install

现在,预提交将在 git commit 时自动运行。如果配置文件中的任何钩子失败,提交将被中止。

记住,您可以自定义 .pre-commit-config.yaml 文件,以包括与您的项目相关的任何钩子。虽然有许多现成的钩子可用,但如果需要,您也可以创建自己的钩子。

一些常见的 Python 预提交钩子

有许多现成的钩子可以帮助提升您的 Python 代码质量。以下是一些常见的:

1 — black : 这是一个 Python 代码格式化工具。它会自动格式化您的代码,使其更具可读性和一致性。以下是如何将它添加到 .pre-commit-config.yaml 文件中:

repos:
-   repo: https://github.com/psf/black
    rev: '23.1.0'
    hooks:
    -   id: black

2 — flake8 : 这是一个用于强制执行 Python 编码标准的工具。它会检查您的代码是否符合 PEP8(Python 的官方风格指南),同时也会查找逻辑错误。以下是如何添加它:

repos:
-   repo: https://gitlab.com/pycqa/flake8
    rev: 3.9.2
    hooks:
    -   id: flake8

3 — isort : 这个工具会自动排序和格式化您的 Python 导入。以下是如何添加它:

repos:
-   repo: https://github.com/pycqa/isort
    rev: 5.8.0
    hooks:
    -   id: isort

4 — mypy : 这是一个用于 Python 的静态类型检查器。它有助于在代码运行之前捕捉某些类型的错误。以下是如何添加它:

repos:
-   repo: https://github.com/pre-commit/mirrors-mypy
    rev: v0.812
    hooks:
    -   id: mypy

5 — pycln : 这是一个帮助查找和删除未使用的导入语句的工具

repos:
-   repo: https://github.com/hadialqattan/pycln
    rev: 'v2.1.5'
    hooks:
    -   id: pycln
        args: ['.', "--all"]

6 — pydocstyle : 这是一个静态分析工具,用于检查是否符合 Python docstring 规范。

repos:
-   repo: https://github.com/pycqa/pydocstyle
    rev: '6.3.0'
    hooks:
    -   id: pydocstyle
        args: ['.']

7 — 运行 单元测试 的自定义钩子:你可以指定一个自定义命令,在每次提交时触发,而不是引用外部仓库。在这个示例中,我们运行单元测试。这可能会引入一个轻微的开销,具体取决于你的测试套件。

 -   repo: local
    hooks:
    -   id: unittest
        name: run unit tests
        language: system
        pass_filenames: false
        entry: poetry run coverage run -m pytest

这些只是许多可用于 Python 的 pre-commit 钩子中的几个示例。有关更多信息,你可以查看这个 repository 或添加你自定义的质量代码检查。

如何运行 pre-commit 钩子并修复代码库

在这一部分,我将与你分享我在个人项目中使用的 pre-commit 配置。然后,我将展示它如何在实践中工作,并防止潜在的错误。

首先,这是我的配置:

repos:
-   repo: https://github.com/psf/black
    rev: '23.1.0'
    hooks:
    -   id: black
        args: [--config=pyproject.toml]

-   repo: https://github.com/pycqa/pydocstyle
    rev: '6.3.0'
    hooks:
    -   id: pydocstyle
        args: ['.']

-   repo: https://github.com/hadialqattan/pycln
    rev: 'v2.1.5'
    hooks:
    -   id: pycln
        args: ['.']

-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: 'v4.4.0'
    hooks:
    -   id: trailing-whitespace

-   repo: local
    hooks:
    -   id: unittest
        name: run unit tests
        language: system
        pass_filenames: false
        entry: poetry run coverage run -m pytest

现在我要将以下格式不良的虚拟脚本添加到现有的代码库中:

# dummy_script.py

import math

def sum(a,   b):   
    return a +  b 

如你所见,这个脚本有许多问题:

  • 未使用的导入语句:math

  • 无黑色格式化:参数和变量之间有多余的空格

  • 许多尾随空格

如果我们添加这个文件并提交代码,我们会从钩子中得到这些错误:

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

作者截图

  • black 失败但自动重新格式化了代码

  • pydoctyle 失败并指出了文档缺失的地方

  • pycln 失败并自动移除了未使用的导入语句

如果我们添加自动修改过的脚本并再次提交代码,我们会发现除了 pyodstyle 钩子外,其他都通过了。

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

作者截图

在这种情况下,我们必须手动更新文档,

"""This is a dummy script."""

def sum(a, b):
    """Sum two numbers."""
    return a + b

添加代码,并提交:

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

作者截图

现在,你准备好推送你的代码了。

观察 pre-commit 对代码质量的影响

pre-commit 对代码质量的影响是显著而多方面的。以下是 pre-commit 可以提升你的 Python 代码质量的几种方式:

  1. 一致的代码格式化:使用 blackisort 等钩子,你的代码将遵循一致的风格。这使得代码不仅对你自己,更对任何可能参与你项目的其他人来说都更易读和理解。

  2. 早期捕获错误:像 flake8mypy 这样的钩子可以在代码运行之前捕获潜在的错误和漏洞。这可以节省你很多后续调试的时间。

  3. 强制最佳实践:许多钩子强制执行 Python 最佳实践,例如 PEP8 合规性。这可以帮助你编写更清晰、更高效的代码。

  4. 运行单元测试:pre-commits 允许你在本地运行单元测试并检查它们是否成功,然后再推送你的代码。这可以防止你在 CICD 过程中遇到测试错误。

通过将 pre-commit 集成到你的开发工作流中,你可以确保你的代码始终保持最高质量。这是一个可以在长远中节省时间、精力和潜在很多麻烦的工具。

结论

pre-commit 是一个强大的工具,可以显著提升你的 Python 代码质量。通过自动检查常见问题、执行最佳实践并防止错误提交,pre-commit 可以节省你大量的时间和调试精力。

它很容易集成到你的开发工作流程中,并且高度可定制,让你可以选择最适合你项目需求的钩子。

刚刚接触 Medium?你可以每月以 $5 订阅,解锁各种主题的无限文章(技术、设计、创业…)你可以通过点击我的推荐链接来支持我。

## 使用我的推荐链接加入 Medium - Ahmed Besbes

作为 Medium 会员,你的部分会费将分配给你阅读的作者,同时你可以全面访问每一篇文章…

ahmedbesbes.medium.com

资源

如何使用 LLMs 自动提取 PDF 中的实体

原文:towardsdatascience.com/how-to-automate-entity-extraction-from-pdf-using-llms-ea9c1351f531

利用零样本标注

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

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

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

Google DeepMind拍摄,Unsplash提供

在现代机器学习应用中,高质量标注数据的重要性不容忽视。从提升模型性能到确保公平性,标注数据的力量巨大。然而,创建这样的数据集所需的时间和精力同样不容小觑。但是,如果我们能够将这一任务所需的时间从几天缩短到仅仅几个小时,同时保持甚至提高标注质量呢?这是一个乌托邦式的梦想?不再是。

机器学习中的新兴范式——零样本学习、少样本学习和模型辅助标注——为这一关键过程提供了变革性的方法。这些技术利用先进算法的力量,减少了对大量标注数据集的需求,实现了更快、更高效且极具效果的数据注释。

在本教程中,我们将介绍一种利用大型语言模型(LLM)上下文学习能力自动标注非结构化和半结构化文档的方法。

从 SDS 中提取信息

与传统的需要大量标注数据以训练特定任务的监督模型不同,LLMs 可以通过利用其庞大的知识库,从少量示例中进行概括和推断。这种新兴的能力,被称为上下文学习,使得 LLM 成为许多任务的多功能选择,涵盖了不仅仅是文本生成,还包括命名实体识别等数据提取任务。

在本教程中,我们将使用 GPT 3.5(也称为 ChatGPT)的零样本和少样本标注功能,对来自不同公司的安全数据表(SDS)进行标注。SDS 提供了关于特定物质或混合物的全面信息,旨在帮助工作场所有效管理化学品。这些文件在提供有关危害的详细见解方面发挥着至关重要的作用,包括环境风险,并提供宝贵的安全防护指导。SDS 作为知识的重要来源,使员工能够在工作场所安全处理和使用化学品时做出明智的决策。SDS 通常以不同布局的 PDF 格式出现,但通常包含相同的信息。在本教程中,我们的目标是训练一个 AI 模型,自动识别以下实体:

  • 产品编号

  • CAS 号

  • 用例

  • 分类

  • GHS 标签

  • 公式

  • 分子量

  • 同义词

  • 紧急联系电话

  • 急救措施

  • 组件

  • 品牌

提取这些相关信息并将其存储在可搜索的数据库中对许多公司非常有价值,因为它允许快速搜索和检索危险成分。以下是一个 SDS 的示例:

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

公开可用的 SDS。图片由作者提供

零样本标注

与文本生成不同,信息提取对 LLM 来说是一个更具挑战性的任务。LLM 已经接受了文本补全任务的训练,通常在被提示提取相关信息时,倾向于出现幻觉或生成额外的评论或文本。

为了正确解析 LLM 的结果,我们需要从 LLM 获得一致的输出,如 JSON。这需要一些提示工程以确保准确。此外,一旦结果被解析,我们需要将其映射到输入文本中的原始标记。

幸运的是,所有这些步骤都已经完成,并通过UBIAI 标注工具进行了抽象化。在后台,UBIAI 进行提示、分块数据以确保在上下文长度限制内,并将其发送到 OpenAI 的 GPT3.5 Turbo API 进行推断。一旦输出返回,数据将被解析、处理并应用到您的文档中进行自动标注。

首先,上传您的文档,无论是原生 PDF、图片还是简单的 Docx,然后进入标注页面,选择标注界面中的 Few-shot 选项卡:

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

UBIAI 少样本仪表板。图片由作者提供

欲了解更多详细信息,请查看文档:ubiai.gitbook.io/ubiai-documentation/zero-shot-and-few-shot-labeling

UBIAI 使您能够配置模型学习的示例数量,以自动标记下一个文档。该应用程序会自动从您已经标记的数据集中选择最具信息量的文档,并将它们串联在提示中。这种方法被称为“少量示例标记”,其中“少量”范围从 0 到 n。要配置示例数量,只需点击配置按钮并输入示例数量,如下所示。

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

UBIAI 少量示例配置窗口。图像来源:作者

在本教程中,我们将向 LLM 提供零个示例来学习,并要求它仅根据实体本身的描述来标记数据。令人惊讶的是,LLM 能够很好地理解我们的文档,并正确完成大部分标记!

以下是对 SDS PDF 进行零-shot 标记的结果,没有任何示例,非常令人印象深刻!

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

使用 UBIAI 进行零-shot 标记。图像来源:作者

结论

利用大型语言模型(LLMs)自动从 PDF 中提取实体已经成为现实,得益于 LLM 的上下文学习能力,例如零-shot 学习和少量示例学习。这些技术利用 LLM 的潜在知识,减少对大量标记数据集的依赖,实现更快、更高效且效果显著的数据注释。

本教程展示了一种自动标记半结构化文档的方法,特别关注于安全数据表(SDS),但也适用于非结构化文本。通过利用 LLM 的上下文学习能力,特别是 GPT 3.5(chatGPT),教程展示了能够自动识别 SDS 中的重要实体,例如产品编号、CAS 号、使用案例、分类、GHS 标签等。

提取的信息,如果存储在可搜索的数据库中,将为公司提供重大价值,因为它允许快速搜索和检索危险成分。教程强调了零-shot 标记的潜力,其中 LLM 可以理解并从 SDS 中提取信息,而无需任何明确的示例。这展示了 LLM 的多功能性和泛化能力,超越了文本生成任务。

如果您有兴趣使用 LLM 的零-shot 能力创建自己的训练数据集,请点击这里安排演示。

在 Twitter 上关注我们 @UBIAI5

如何在 AWS EMR 上使用 Airflow 自动化 PySpark 管道

原文:towardsdatascience.com/how-to-automate-pyspark-pipelines-on-aws-emr-with-airflow-a0cbd94c4516

优化大数据工作流的编排。

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

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

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

图片由 Tom Fisk 提供,来自 Pexels

按需课程 | 推荐

我的一些读者联系过我,询问是否有按需课程来帮助你 成为 一名扎实的 数据工程师。这些是我推荐的 3 个优秀资源:

还不是 Medium 会员? 考虑使用我的 推荐链接 注册,以每月仅需 $5 的费用访问 Medium 的所有内容!

简介

在数据工程和分析的动态领域中,构建可扩展和自动化的管道至关重要。

对于已经在使用 Airflow 的 Spark 爱好者来说,可能会好奇:

如何使用 Airflow 在远程集群上执行 Spark 作业?

如何使用 AWS EMR 和 Airflow 自动化 Spark 管道?

在本教程中,我们将通过展示如何集成这两种技术来进行演示:

  1. 配置并从 Airflow UI 中获取必要的参数。

  2. 创建辅助函数以自动生成首选的 spark-submit 命令。

  3. 使用 Airflow 的 EmrAddStepsOperator() 方法构建一个任务,该任务提交并执行一个 PySpark 作业到 EMR。

  4. 使用 Airflow 的 EmrStepSensor() 方法监控脚本执行。

本教程中使用的代码可在 GitHub 上获取。

先决条件

  • 一个 AWS 账户 配置了一个 S3 存储桶和 EMR 集群 在同一区域( 在这种情况下是 eu-north-1)。 EMR 集群应处于 WAITING 状态。在我们的案例中,它被命名为 emr-cluster-tutorial

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

作者提供的照片(个人 EMR 集群)

  • 一些模拟 balances 数据已经在 S3 存储桶的 src/balances 文件夹中。数据可以使用 数据生成器 脚本生成并写入该位置。

  • 所需的JARs应已经从 Maven 下载并保存在 S3 存储桶中。

  • Docker 已安装并在本地计算机上运行,分配了 4-6 GB 的内存。

架构

目标是将一些模拟数据以 parquet 格式写入 S3 存储桶,然后构建一个 DAG,该 DAG

  • 从 Airflow UI 获取所需配置;

  • pyspark 脚本上传到同一个 S3 存储桶;

  • 提交一个 Spark 作业,执行刚刚上传的脚本;

  • 通过传感器监控执行状态,直到成功或失败。

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

作者提供的照片 (app.diagrams.net/)

配置

克隆仓库

第一步是将 仓库 克隆到您选择的本地文件夹,并显示文件夹结构:

git clone git@github.com:anbento0490/projects.git repo_local_name

cd repo_local_name/airflow_emr_spark

tree

airflow_emr_spark 文件夹结构如下:

  • docker-compose.ymlDockerfile.airflow 文件是运行本地 Airflow 服务所需的,然后可视化/执行 DAG

  • orchestration 文件夹包含名为 submit_spark_job_to_emr.pyDAG 本身;

  • computation 文件夹包含将提交到 EMR 集群的 .py 可执行文件;

  • 最后,assets 文件夹包括了所需配置的 JSON 格式副本以及 data_producer 笔记本。

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

文件夹结构(树状图)

在 Docker 上运行 Airflow

确保本地运行 docker,然后在 airflow_emr_spark 文件夹中执行 docker compose up -d。此命令将在我们的容器中启动 Apache Airflow:

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

作者终端的截图

现在我们导航到 localhost:8091,当请求凭证时,我们只需输入 admin 两次。此时,DAG 应该已经解析完毕,样子如下:

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

从运行在 Docker 上的 Airflow

在探索 DAG 代码之前,在 Airflow 中还有两个剩余操作:

  • 导航到 Variables 部分,创建一个名为 dag_params 的新变量,将 dags/assets/dag_params.json 文件的内容复制粘贴到其中。当然,bucket_name 应更新以匹配我们 AWS 账户中的 S3 存储桶。

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

AF UI 中的 dag_params 变量

  • 导航到 Connections 部分,并创建一个名为 aws_default 的新 Amazon Web Services 连接,用于通过 Airflow 与 S3EMR 集群进行交互。连接参数应以如下形式粘贴到 Extra 部分:
{"aws_access_key_id": "xxxxxx",
 "aws_secret_access_key": "xxxxxx",
 "region_name": "eu-north-1"}

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

AF UI 中的 aws_default 连接

任务

初步步骤作为 submit_spark_job_to_emr.py DAG 的一部分是从 Airflow UI 中之前保存的 dag_params 变量中检索配置。

如果变量不存在,DAG 将默认为文件夹中可用的 dag_params.jsondefault_json)。

由于本教程还展示了如何将特定的 JARS 提供给 EMR 集群,因此一开始我们还定义了一个 jar_string 变量以便在稍后添加步骤时作为参数提交。然而,如果不需要 JARS,则可以省略此变量(以及 spark_jars_conf spark_jars_conf_value dag_params 中):

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

我们应该认识到,这不是在 Airflow 中导入变量的高效方法。

这是因为 Variable.get() 方法在任务之外被调用,这意味着变量在每次 airflow scheduler 解析 dags 文件夹时都会被导入 每次

然而,为了学习目的,这种实现方式更简单,当只有一个管道涉及时并不算大问题。然而,在生产环境中,我们应确保遵循 这些 最佳实践,总结来说建议:

  • 将变量作为任务的一部分并仅在需要时导入

  • 使用 XCOMS 在任务之间交换变量

DAG 包含四个任务。让我们逐一描述它们的功能。

获取集群 ID

第一个任务是 fetch_cluster_id

fetch_cluster_id = PythonOperator(
    dag=dag,
    task_id="fetch_cluster_id",
    python_callable=fetch_cluster_id,
)

这个任务的功能是运行 fetch_cluster_id() python 函数,该函数:

  • 按名称获取并返回 CLUSTER_ID后续添加 EMR 步骤所需),并期望 cluster_stateWAITINGRUNNING。在我们的例子中,我们将 "emr-cluster-tutorial" 传递给 get_cluster_id_by_name 方法 → 为了正常工作,连接中指定的 region_name 必须与创建 EMR 集群的区域匹配。

  • 显示导入变量的值以便于查看(*建议在生产中,此函数应修改为首先获取所有属性,以避免低效的顶级导入)。

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

上传脚本到 S3

我们使用以下任务将 read_and_write_back_to_s3.py 可执行文件从本地 computation/src/python_scripts 文件夹上传到指定的 s3://bucket_name/src/ 文件夹,然后提交到 EMR 集群:

upload_script_to_s3 = PythonOperator(
    dag=dag,
    task_id="upload_script_to_s3",
    python_callable=upload_script_to_s3,
    op_kwargs={"filename": local_script, "key": s3_script}
)

函数 upload_script_to_s3 创建了一个 S3Hook,在 Airflow 和 AWS 之间使用 aws_default 连接,并使脚本在首选的 S3 路径下可用:

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

执行 PySpark 脚本

现在 python 脚本已经存在于 s3 存储桶中,是时候使用 EmrAddStepsOperator()EMR 添加一个步骤了。

实际上,execute_pyspark_script 利用下面的辅助函数,将一个 spark 应用程序以 client 模式部署到 EMR但在生产环境中 cluster 模式 应当更为推荐 *),同时使用从 dag_params 中获取的其他(可选spark_conf 参数:

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

实际上,execute_pyspark_script 任务指示 EMR 执行 read_and_write_back_to_s3.py 脚本( CLUSTER_ID 通过第一个任务获取并通过 XCOMS 拉取),并将多个参数提供给集群,顺序如下:

  • 全局参数如 jar_stringspackages → 需要作为参数传递在 python 脚本之前(尽管是可选的);

  • 函数参数 s3_input → 指定了传递给 python 脚本的输入 balances 数据集 S3 路径;

  • 函数参数 s3_output → 指定了存储输出数据集的 S3 路径。

execute_pyspark_script = EmrAddStepsOperator(
    dag=dag,
    task_id='execute_pyspark_script',
    job_flow_id= "{{ ti.xcom_pull(task_ids='fetch_cluster_id', key='return_value') }}",
    aws_conn_id='aws_default',
    steps=[{
        'Name': 'execute_pyspark_script',
        'ActionOnFailure': 'CONTINUE',
        'HadoopJarStep': {
            'Jar': 'command-runner.jar',
            'Args': [
                *generate_spark_submit_command(spark_submit_cmd, spark_conf_map),
                "--jars",
                '{{ params.jars_string }}',
                's3://{{ params.bucket_name }}/{{ params.s3_script }}',
                '--s3_output',
                '{{ params.s3_output }}',
                '--s3_input',
                '{{ params.s3_input }}'
            ]
           }
        }],
    params={
        "bucket_name": BUCKET_NAME,
        "s3_script": s3_script,
        "s3_input": s3_input,
        "s3_output": s3_output,
        "jars_string": jars_string
    }
)

使用传感器监控执行

最后但同样重要的是,execute_pyspark_script_sensor 任务运行一个 EmrStepSensor(),该传感器定期 探测 集群本身,以验证应用程序的健康状况和执行状态。

它特别要求两个参数:JOB_FLOW_ID == CLUSTER_IDSTEP_ID,我们可以通过 XCOMS 获取这两个参数:

execute_pyspark_script_sensor = EmrStepSensor(
    dag=dag,
    task_id="execute_pyspark_script_sensor",
    job_flow_id="{{ ti.xcom_pull(task_ids='fetch_cluster_id', key='return_value') }}",
    aws_conn_id="aws_default",
    step_id="{{ ti.xcom_pull(task_ids='execute_pyspark_script', key='return_value')[0] }}",
    sla=timedelta(minutes=5)
)

代码

python 可执行文件包括一个简单的 process_data_and_write_to_s3() 函数,该函数:

  • s3_input 路径读取 parquet 格式的数据到一个 PySpark SQL 视图中;

  • 利用 SQL API 过滤初始数据集,并将结果保存到 df_filtered DF;

  • 最终将过滤后的数据集(再次以 parquet 格式)写入 s3_output 路径。

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

我们现在可以触发 DAG 并等待其成功执行:

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

Airflow DAG 图

导航到 EMR 集群的 Steps 部分,我们应该能够验证脚本执行确实已完成:

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

AWS EMR 步骤 部分

实际上,通过选择 stout 日志,我们应该能看到类似于以下的消息,它告诉我们一个包含 ~2.5M 行(从初始的 10M 中筛选出来)的 DF 已经被写入 tgt/balances/ 文件夹中:

Start process...
Reading data from s3://emr-data-947775527574/src/balances directory and creating Temp view
Creating DF with only balances for Company_A
Writing DF to s3://emr-data-947775527574/tgt/balances/ directory...
Data written to target folder...
DF rows count is 2499654
PROCESS COMPLETED!

实际上,检查 bucket_name/tgt/balances/ 文件夹时,我们应该找到一个或多个包含与 Company_A 相关的数据的 parquet 文件(如筛选条件中指定的):

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

tgt/balances 文件夹的内容

结论

在本教程中,我们学习了如何使用 Apache Airflow 和 AWS EMR 结合来自动化 PySpark 流水线。

这里的假设是EMR 集群始终处于闲置状态,等待添加步骤。在专业环境中这种情况并不罕见,或者通过设置个人 AWS 账户也能轻松实现。

另一种常见的做法是直接从 AF UI 中获取配置,并使用辅助功能生成更复杂的提交命令,这些命令可以通过按需编辑配置来更新。

我们使用的是一个简单的 PySpark 脚本,但我们当然可以设想扩展这个示例,以涵盖更复杂的使用案例。

一旦完成工作,请记得使用以下命令停止 docker 上的 Airflow 服务:

docker compose down 

来源

如何自动提取和标记 Seaborn KDE 图上的数据点

原文:towardsdatascience.com/how-to-automatically-extract-and-label-data-points-on-a-seaborn-kde-plot-52a576238301

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

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

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

DALL·E 2023——一幅印象派风格的山脉起伏画作,山脊线上带有明亮的彩色圆圈(其余图片均由作者提供)。

核密度估计图 是一种方法——类似于直方图——用于可视化数据点的分布。虽然直方图对观测值进行分箱和计数,但 KDE 图使用高斯核平滑观测值。作为直方图的替代方案,KDE 图可能更具吸引力,更易于在同一图形中进行比较,并且更好地突出数据分布中的模式。

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

直方图与 KDE 图

在 KDE 图上注释统计度量值如均值、中位数或众数,使其更具意义。虽然为这些度量值添加线条是简单的,但使它们看起来整洁且不杂乱却并非易事。

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

使用简单方法添加的标记线(左)与使用更复杂但更具吸引力的方法(右)

在这个快速成功数据科学项目中,我们将使用美国人口普查和国会数据集,程序化地注释多个 KDE 图并标记中位数值。这种方法将确保图形注释自动调整数据集的更新。

欲了解有关 KDE 图的更多细节,请参见我之前的文章 这里

数据集

由于美国有候选年龄法律,国会成员的生日是公共记录的一部分。为了方便起见,我已编制了一份包含现任国会成员姓名、生日、政府部门和政党的 CSV 文件,并将其存储在此Gist中。

对于美国人口,我们将使用人口普查局的月度后普查平民人口表格,数据截止到 2023 年 7 月。与前面的数据集一样,这些是公开信息,我已将其保存到此Gist的 CSV 文件中。

安装库

对于这个项目,我们需要安装 seaborn 用于绘图,pandas 用于数据分析。你可以按以下方式安装这些库:

使用 conda: conda install pandas seaborn

使用 pip: pip install pandas seaborn

代码

以下代码在 JuptyerLab 中编写,并按单元格描述。

导入库

从 seaborn KDE 图中提取值的秘诀是导入 matplotlib 的[Line2D](https://matplotlib.org/stable/api/_as_gen/matplotlib.lines.Line2D.html)类,这使我们可以访问曲线上的点坐标。此外,我们将使用 matplotlib 的[patches](https://matplotlib.org/stable/api/_as_gen/matplotlib.patches.Patch.html)绘制矩形,以标示出众议院和参议院的合法年龄限制。patch是一个具有面色边缘颜色的 matplotlib artist对象。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
from matplotlib.patches import Rectangle
import seaborn as sns
import pandas as pd

加载国会数据集并计算年龄

以下代码加载国会数据集并计算每位成员截至 2023 年 8 月 25 日的年龄。它首先将参考日期和数据框的“生日”列转换为datetime格式,使用 pandas 的to_datetime()方法。然后利用这些“日期感知”格式生成“年龄”列,通过减去两个值、提取天数,然后将天数除以 365.25 转换为年份。

# Load the data:
df = pd.read_csv('https://bit.ly/3EdQrai')

# Assign the current date:
current_date = pd.to_datetime('8/25/2023')

# Convert "Birthday" column to datetime:
df['Birthday'] = pd.to_datetime(df['Birthday'])

# Make a new "Age" column in years:
df['Age'] = ((current_date - df['Birthday']).dt.days) / 365.25
df['Age'] = df['Age'].astype(int)

df.head(3)

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

加载人口数据集

接下来,我们将人口数据加载为 pandas DataFrame。

# Load the US population data for July 2023:
df_popl = pd.read_csv('https://bit.ly/3Po0Syf').astype(int)
display(df_popl)

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

计算美国人口的中位年龄

这是一个有趣的问题。你如何找到美国人口的中位年龄?也就是说,你如何将中位人口值与年龄关联起来?

关键是将人口的累计分布绘制与年龄进行对比。由于你必须年满 25 岁或以上才能在国会服务,我们首先将数据框过滤到这些年龄。这里是这个概念:

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

使用累计分布图找到美国人口中年龄大于 24 岁的中位年龄

这是带有注释的代码:

# Calculate the cumulative sum of the population over 24 years:
df_popl = df_popl[df_popl['Age'] >= 25].copy()
df_popl['Cumulative_Population'] = df_popl['Population'].cumsum()

# Find the total population:
total_population = df_popl['Population'].sum()

# Find row where the cumulative population crosses half the total population:
median_row = df_popl[df_popl['Cumulative_Population'] 
                     >= total_population / 2].iloc[0]

# Get the median age:
popl_median_age = median_row['Age']

# Get the median population:
popl_median = total_population / 2

制作一个简单的堆叠 KDE 图

在我们注释图表之前,让我们看看“开箱即用”的效果如何。我们将在同一图形中分层多个 KDE 图。这些包括众议院一个、参议院一个,以及一个针对 24 岁以上美国人口的图。

# Make a list of median member ages by branch of government:
median_ages = df.groupby('Branch')['Age'].median()

# Make a custom (red-blue-gray) color palette (optional):
colors = ['#d62728', '#1f77b4', '#7f7f7f']
sns.set_palette(sns.color_palette(colors))

# Plot Congressional ages as a KDE and overlay with population KDE:
fig, ax = plt.subplots()

sns.kdeplot(data=df, 
            x='Age', 
            hue='Branch', 
            multiple='layer', 
            common_norm=True)

sns.kdeplot(df_popl, 
            x='Age', 
            weights='Population', 
            color='grey', 
            alpha=0.3, 
            legend=False, 
            multiple='layer')

ax.set_title('Age Distributions of Senate, House, and US Population > 24 yrs')
ax.legend(loc='upper left', labels=['Senate', 'House', 'Population'])
ax.set_xlim((0, 110));

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

一个简单的分层 KDE 图

kdeplot() 方法的一个重要参数是 common_norm,代表“公共归一化”。

根据 seaborn 的 文档,“当 common_norm 设置为 True 时,所有 KDE 曲线将使用相同的比例进行归一化。这在你想比较不同组的总体分布形状时非常有用。尤其是在你有多个组具有不同样本量或不同值范围时,它确保了曲线在形状上可以直接比较。”

请注意,在这种情况下,归一化仅应用于众议院和参议院曲线,因为人口数据是从不同的 DataFrame 中单独绘制的。这是因为我们需要加权年龄数据,以适应我们的人口数据集没有每个人的独特年龄值的情况。

寻找众议院和参议院的中位年龄值

尽管前面的图表很吸引人,但它让读者工作过于繁重。x 轴需要更多的分辨率,而且知道均值或中位数值在曲线上的位置会更好。由于两院都包括一些非常年长的成员,这可能会影响均值,因此我们将关注中位数值。

首先,我们需要为每个分支找到中位值(我们之前已经找到了人口中位值)。由于我们希望程序化地找到注释的图表坐标,我们将为每个分支创建一个单独的 DataFrame。这将使得提取曲线数据更容易。

# Filter the DataFrame to each branch of government:
df_house = df.loc[df['Branch'] == 'House'].copy()
df_senate = df.loc[df['Branch'] == 'Senate'].copy()

# Find the median age values for each branch:
median_house = int(df_house['Age'].median())
median_senate = int(df_senate['Age'].median())

绘制和注释 KDE

以下注释代码绘制并注释了图表。我们的目标是找到曲线上的 (x, y) 坐标,以便我们在绘制线条和发布文本时可以程序化地提供这些坐标。这使得代码能够适应输入数据的任何变化。

那么我们该怎么做呢?当 seaborn 创建一个 KDE 图时,它会返回一个 matplotlib [axes](https://matplotlib.org/stable/api/axes_api.html) 对象。这个类型的对象具有一个 [get_lines()](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.get_lines.html) 方法,返回一个包含该对象的线段列表。这些线段是 [Line2D](https://matplotlib.org/stable/api/_as_gen/matplotlib.lines.Line2D.html) 对象,具有一个 get_data() 方法,该方法以 (x, y) 对的形式返回线数据。因为这些坐标可能不包括我们想要的确切值,我们将使用 NumPy 的 [interp()](https://numpy.org/doc/stable/reference/generated/numpy.interp.html) 方法来插值这些值。

# Create figure and title:
fig, ax = plt.subplots()
ax.set_xlim((0, 110))
ax.set_xticks(range(0, 110, 10))
ax.set_title('Age Distributions of House, Senate, and US Population > 24 yrs')

# Define colors and labels:
colors = ['#d62728', '#1f77b4', '#7f7f7f']
labels = ['House', 'Senate', 'Population']

# Loop through the datasets and plot KDE, median lines, and labels:
datasets = [df_house, df_senate]
medians = [median_house, median_senate]

for i, (data, color, label) in enumerate(zip(datasets, colors, labels)):
    sns.kdeplot(data=data, x='Age', color=color, fill=False, label=label)
    x, y = ax.get_lines()[i].get_data()
    f = np.interp(medians[i], x, y)
    ax.vlines(x=medians[i], ymin=0, ymax=f, ls=':', color=color)
    ax.text(x=medians[i], y=f, s=f'Median = {medians[i]}', color=color)

# Make and annotate the population KDE plot:
sns.kdeplot(df_popl, x='Age', weights='Population', color='#7f7f7f', fill=False)
x, y = ax.get_lines()[2].get_data()  # Note that this is the 3rd line([2]).
f = np.interp(popl_median_age, x, y)
ax.vlines(x=popl_median_age, ymin=0, ymax=f, ls=':', color='#7f7f7f')
ax.text(x=popl_median_age, y=f, 
        s=f'Median = {popl_median_age}', color='#7f7f7f')

# Build a custom legend:
legend_handles = [Line2D(xdata=[0, 1], ydata=[0, 1], ls='-', 
                         color=color) for color in colors]
ax.legend(handles=legend_handles, loc='upper left', labels=labels)

# Manually annotate the Age Limit shading:
age_limit_rects = [
    Rectangle((25, 0), 85, 0.003, facecolor='#d62728', alpha=0.3),
    Rectangle((30, 0), 85, 0.001, facecolor='#1f77b4', alpha=0.6)
    ]

for age_rect, label, color in zip(
    age_limit_rects, ['House age limits', 'Senate age limits'], 
    ['#d62728', '#1f77b4']):
    age_rect.set_zorder(0)  # Move rect below other elements.
    ax.add_patch(age_rect)
    ax.text(x=age_rect.get_x(), y=age_rect.get_height(), 
            s=label, color=color)

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

注释过的 KDE 图

在之前的代码中,我们将人口 KDE 图绘制在循环之外,因为年龄数据需要按其人口值加权。

我们还手动标注了年龄限制的彩色矩形和文本,因为程序化的解决方案不是很吸引人。将这些注释“硬编码”是可以接受的,因为这些信息是固定的,不会随着输入数据的变化而改变。

总结

在这个项目中,我们通过编程提取了 KDE 曲线上点的(x, y)坐标,并用它们来标注图表。结果是图表看起来更加整洁,其中垂直标记线在与曲线相交时终止,而文本注释从该交点开始。这使得代码更加灵活,因为这些注释会随着输入数据的变化自动更新。

我们还使用了累积分布来找到一个 pandas DataFrame 列的中位数值,该值对应于相关列的中位数值。我们必须这样做,因为我们的年龄与人口输入数据已被分箱。

谢谢!

感谢阅读,请关注我以获取更多未来的快速成功数据科学项目。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值