协议:CC BY-NC-SA 4.0
原文:
Andy McDonald
·发表于 Towards Data Science ·阅读时间 8 分钟·2023 年 3 月 1 日
–
PyGWalker 在同一视图中显示多个图表。图片由作者提供。
快速高效地创建有效且引人注目的数据可视化是数据科学工作流程的关键部分。有多种选项可以实现这一点,从商业软件如 Tableau 到免费的替代方案如专用的 Python 库。生成图表所需的技能和时间因选项而异。
多年来,已经开发了几种 Python 库来简化数据探索过程。事实上,这些库如此简单,以至于你只需 3–5 行代码即可开始使用。
最近出现在 EDA 场景中的一个库是 PyGWalker。
PyGWalker (Python 绑定的 Graphic Walker) 是一个 Python 库,能够帮助加速数据分析和可视化工作流程,直接在 Jupyter notebook 中进行。它通过提供类似于流行数据分析软件 Tableau 的界面来利用交互性的强大功能。
使用井孔数据在 PygWalker 中创建散点图。图片由作者提供。
使用这种类型的界面,我们可以将变量拖放到特定部分,快速创建图表、筛选图表并理解数据。
你可以使用下面的链接访问 PyGWalker 的 GitHub 存储库。
## GitHub - Kanaries/pygwalker: PyGWalker: 将你的 pandas 数据框转换为 Tableau 风格的用户界面…
PyGWalker 可以简化你的 Jupyter Notebook 数据分析和数据可视化工作流程,通过将 pandas 数据框转换为 Tableau 风格的界面来实现。
github.com
本文将探讨 PyGWalker 的一些功能,使用的是我最喜欢的井筒数据集之一(详细信息见文章末尾)。
在撰写本文时,PygWalker 的版本是 ,其中一些功能可能已在此版本之后进行了更新。
如果你想查看 PyGWalker 的实际操作,可以在我的 YouTube 频道 上找到该教程的视频版本。
要开始使用 PyGWalker,我们需要先安装它。我们可以使用 或 (如果你使用 Anaconda)。
安装 PyGWalker 库后,我们可以打开 Jupyter Notebook,然后导入 PyGWalker 和 pandas 库,后者将用于从 CSV 文件中加载数据。
在这些导入之后,下一步是加载我们将用于本教程的数据。我们可以通过调用 pandas 中熟悉的 函数来加载数据,然后传入我们的 CSV 文件。
现在是运行 PyGWalker 的时候了,我们可以使用以下简单的调用来实现。
一旦单元格运行完毕,我们将得到一个非常好的界面,显示数据集中可用的变量。变量将根据其类型进行分组。
PyGWalker 用户界面直接在 Jupyter Notebook 中。图片由作者提供。
我们将创建的第一个图是 RHOB 和 NPHI 的简单散点图——这是岩石物理学中常用的图。
在此之前,我们需要在工具栏上关闭聚合。这将允许我们绘制实际的数据值,而不是任何形式的聚合。
关闭聚合选项将允许绘制实际的数据值。图片由作者提供。
现在我们可以从左侧的字段列表中选择我们想要绘制的变量。根据你想将变量放在 x 轴还是 y 轴,可以点击并拖动到相应的轴框中。
你还会注意到字段列表中的项目有不同的图标。蓝色文档图标代表分类数据,紫色井号代表数值数据。
在这个例子中,我将 NPHI 放在 x 轴上,将 RHOB 放在 y 轴上。
使用井筒数据在 PygWalker 中创建散点图。图片由作者提供。
当图表出现时,它可能看起来很小。然而,我们可以很容易地增加图表的大小。方法是通过菜单将布局模式从自动更改为固定。
一旦选项更改,我们可以通过点击出现在图周围的蓝色边框来更改大小,或者点击“布局模式”按钮旁边的齿轮图标并调整滑块。
在 PygWalker 中更改图形大小。图片来自作者。
我们还可以向图中添加更多变量,以帮助我们更好地理解数据。这些额外的变量可以是分类的也可以是数值的,我们可以使用它们来添加颜色、不透明度、大小和形状。
在下面的示例中,我添加了 LITH 变量,这将根据不同的岩性给数据点上色。然后我们可以将鼠标悬停在散点图中的任何一点上,查看其值。
将分类变量应用于 PyGWalker 创建的散点图。图片来自作者。
如果我们改用数字变量,我们将在图的侧边看到一个颜色条。这个轴的值范围可以通过应用过滤器来更改——我们很快就会看到如何操作。
将数字变量应用于 PyGWalker 创建的散点图。图片来自作者。
如果我们想要更改比例或放大数据的某个部分,我们首先需要点击工具栏上的“自动调整大小”按钮,然后可以使用鼠标滚轮进行放大或缩小。
然后,我们可以通过使用左键点击、按住该按钮并拖动光标在图中移动。
在 PyGWalker 中缩放和移动散点图。图片来自作者。
如果能像在 Plotly 图表中那样,通过点击轴或轴的角来手动更改图上的刻度,将是一个很好的功能。
我们还可以使用我们的变量过滤数据。
当我们使用分类数据进行过滤时,我们点击并拖动我们想要的变量到过滤器区域,然后取消选择我们不想看到的类别。
在 PygWalker 中应用分类过滤器。图片来自作者。
使用数字变量进行过滤时,我们会得到一个滑块,可以控制最小值和最大值范围。看起来我们不能手动编辑这些值,这将是一个很好的功能。
一个不错的功能是,我们可以通过将另一个变量添加到过滤框中并设置范围或选择我们想要的类别,来应用多个过滤器。
使用 PygWalker 对数据应用数值过滤器。图片来自作者。
PyGWalker 中有几种不同的图表类型。
当添加数据且标记类型设置为自动时,库将尝试为你的数据找到最佳图表。然而,这可能并不总是最合适的图表类型。
你可以通过点击工具栏上的标记类型按钮,然后选择你想要的类型来更改图表类型。
下面的示例展示了如何用两个变量创建折线图。
在 PyGWalker 中创建折线图。图片由作者提供。
PyGWalker 提供了一种方便的方式来查看数据框中的原始数据,并在需要时更改数据类型。如果某列被错误识别为不正确的数据类型,你可以快速更改它。
如果数据视图中能够进行更多操作,例如过滤数据或对列应用颜色比例尺,那就太好了,因为有时这有助于揭示数据中的问题。
金年会金字招牌信誉至上
PyGWalker 中的原始数据视图。图片由作者提供。
PyGWalker 提供了我在 Jupyter notebook 中遇到的最互动、外观最好的 EDA 库体验之一。该界面为非编码者或初学者提供了一种立即开始创建图表的简便方法。
你应该在下一个项目中尝试一下。查看我下面的文章,如果你想了解其他强大的 Python EDA 库。
## 5 个强大的 Python 库,你需要了解的 EDA 工具
利用 Python 的力量探索和理解你的数据
towardsdatascience.com
本文使用的数据集是 Xeek 和 FORCE 2020 (Bormann et al., 2020) 机器学习竞赛的训练数据集的一个子集。它在挪威的 NOLD 2.0 许可下发布,详细信息可以在这里找到:挪威开放数据许可 (NLOD) 2.0。完整数据集可以在这里访问。
数据集的完整参考是:
Bormann, Peter, Aursand, Peder, Dilib, Fahad, Manral, Surrender, & Dischington, Peter. (2020). FORCE 2020 油井记录和岩性数据集,用于机器学习竞赛 [数据集]. Zenodo.
感谢阅读。在你离开之前,你一定要订阅我的内容,并将我的文章发送到你的邮箱。 你可以在这里操作!另外,你也可以 注册我的通讯 ,将额外的内容直接发送到你的邮箱,完全免费。
其次,您可以通过注册会员来获得完整的 Medium 体验,并支持我和其他数千名作者。它只需每月 $5,并且您可以全面访问所有精彩的 Medium 文章,还可以通过写作赚取收入。如果您使用 我的链接, 您将直接通过您的费用的一部分支持我,而不会增加额外费用。如果您这样做,非常感谢您的支持!
原文:
jinnianhui金年会 Konrad Hafen
·
关注 发布于 Towards Data Science ·5 min read·2023 年 9 月 8 日
–
图片来源于 Wesley Tingey 在 Unsplash
我们生活在一个大数据的世界里。大数据通常以多个小数据集(即由多个文件组成的大数据集)的形式组织。获取这些数据通常会因为下载(或获取负担)而令人沮丧。幸运的是,通过一些代码,可以自动化并加快文件下载和获取的过程。
自动化文件下载可以节省大量时间。有几种方法可以使用 Python 自动化文件下载。下载文件的最简单方法是使用一个简单的 Python 循环来遍历 URL 列表。这种串行方法适用于少量小文件,但如果你要下载很多文件或大文件,你会希望使用并行方法来最大化计算资源。
使用并行文件下载例程,你可以更好地利用计算机资源来同时下载多个文件,从而节省时间。本教程演示了如何在 Python 中开发通用文件下载函数,并应用于串行和并行方式下载多个文件。本教程中的代码仅使用 Python 标准库中提供的模块,因此无需安装其他模块。
对于这个示例,我们只需要 和 Python 模块来并行下载文件。 和 模块都可以从 Python 标准库中获取,因此你不需要进行任何安装。
我们还将导入 模块来跟踪下载单个文件所需的时间,并比较串行和并行下载例程之间的性能。 模块也是 Python 标准库的一部分。
我将使用 gridMET NetCDF 文件来演示如何在 Python 中并行下载文件,这些文件包含了美国的每日降水数据。
在这里,我在列表中指定了四个文件的 URL。在其他应用中,你可以通过编程方式生成一个要下载的文件列表。
每个 URL 必须与其下载位置相关联。在这里,我将文件下载到 Windows 的‘Downloads’目录。我在列表中硬编码了文件名,以便简化和透明。根据你的应用程序,你可能想编写代码来解析输入的 URL 并将其下载到特定目录。
多进程要求并行函数只接受一个参数(有一些解决方法,但我们在这里不讨论)。为了下载一个文件,我们需要传递两个参数,一个是 URL,另一个是文件名。因此,我们将 和 列表打包成一个元组列表。列表中的每个元组将包含两个元素;一个 URL 和该 URL 的下载文件名。这样我们就可以传递一个包含两个信息的单一参数(元组)。
现在我们已经指定了下载的 URL 以及它们关联的文件名,我们需要一个函数来下载这些 URL()。
我们将向 传递一个参数()。这个参数将是一个可迭代对象(列表或元组),其中第一个元素是要下载的 URL(),第二个元素是文件名()。这些元素被分配给变量( 和 )以提高可读性。
现在创建一个 try 语句,其中在文件创建后检索 URL 并将其写入文件。当文件写入时,将返回 URL 和下载时间。如果发生异常,则会打印一条消息。
函数是我们代码的核心。它完成实际的下载和文件创建工作。我们现在可以使用这个函数来串行(使用循环)和并行下载文件。让我们看一下这些示例。
要将 URL 列表下载到相关文件,请遍历我们创建的可迭代对象(),将每个元素传递给 。每次下载完成后,我们将打印下载的 URL 及下载所需的时间。
下载所有 URL 的总时间将在所有下载完成后打印。
输出:
下载单个文件的时间在 11 到 16 秒之间。总下载时间稍少于一分钟。你的下载时间将根据你特定的网络连接有所不同。
让我们将这种串行(循环)方法与下面的并行方法进行比较。
首先,创建一个函数()来处理并行下载。该函数()将接受一个参数,一个包含 URL 和相关文件名的可迭代对象(我们之前创建的 变量)。
接下来,获取可用于处理的 CPU 数量。这将决定并行运行的线程数量。
现在使用 将 映射到 函数。在这里我们使用 的 方法,并将 函数及其输入参数( 变量)传递给它。 方法将同时运行指定线程数量的 (即并行下载)。
因此,如果我们有四个文件和四个线程,则所有文件可以同时下载,而不是等待一个下载完成后再开始下一个。这可以节省大量处理时间。
在 函数的最后部分,将打印下载的 URL 及下载每个 URL 所需的时间。
一旦定义了 和 ,就可以用一行代码并行下载文件。
输出:
请注意,这种方法下载每个单独文件所需的时间更长。这可能是由于网络速度变化,或将下载映射到各自线程所需的开销所致。尽管单独文件下载时间较长,但并行方法使总下载时间减少了 50%。
你可以看到并行处理如何大大减少多个文件的处理时间。随着文件数量的增加,使用并行下载方法可以节省更多时间。
在你的开发和分析流程中自动化文件下载可以节省大量时间。正如本教程所示,实现并行下载例程可以大大减少文件获取时间,特别是当你需要下载许多文件或大文件时。
最初发布于 https://opensourceoptions.com.
原文:
Ransaka Ravihara
·发布于 Towards Data Science ·10 分钟阅读·2023 年 1 月 3 日
–
图片由 은 하 提供,出处 Unsplash
如果你是一名机器学习从业者,你可能会更频繁地遇到类别不平衡问题。类别不平衡发生在数据集中类别分布不均的情况。例如,假设我们正在处理流失问题。在这个特定场景下,我们的少数类和多数类分别是客户流失和客户继续留在当前服务提供商。但是,如果你深入探索这个问题,你会发现流失类别的客户较少,因为客户流失是一个对业务有利但对模型不利的不频繁事件。因此,如果我们将这个数据集输入模型,它将比少数类别(流失场景)更准确地学习到多数类别(非流失场景)。这就是我们问题的开始。
最明显的答案是由于模型在训练过程中与少数类的交互较少,我们可以通过向模型中添加更多少数类数据来改善这一点。但是怎么做呢?我们有几种方法:
收集更多的少数类数据——这是一个理论上简单但在实践中不可行的解决方案。因为在满足业务实际需求的同时很难做到这一点,例如,我们可能需要改变逻辑以将更多客户转入流失类别。
随机过采样——我们可以复制少数类数据,直到得到合理的类别分布。这可能导致模型学习到不准确的流失场景。简单来说,它会过度学习一些小的事件模式。
随机欠采样 — 我们可以通过从多数类中删除样本来平衡数据集。然而,这会从数据集中删除一些信号。此外,如果我们的数据集严重不平衡(少数样本少于 1%),我们可能需要从数据集中删除大量的多数类样本,以使其更平衡。
我们可以生成合成数据 — 我们将在本文中更深入地探讨这一点。
其基本思想是生成与少数类中现有样本类似的更多少数类样本。但与重复少数类实例多次不同,这将基于我们拥有的数据集生成新的少数类实例。为此,通常使用 SMOTE(合成少数过采样技术)方法。但也有许多替代方法,如……
ADASYN(自适应合成采样)
Tomek Links:该技术从多数类中移除与少数类样本非常接近的样本。这个想法是移除那些容易被误分类为少数类的多数类简单案例。
近邻缺失:该技术从特征空间中选择与少数类样本最接近的多数类样本,并将其从数据集中移除。这个想法类似于 Tomek Links,但它移除的是最有可能被误分类为少数类的样本,而不是多数类中的简单案例。
让我们对 SMOTE 进行一些实验。
首先,导入数据集。这里我使用的是Wine Quality dataset,你可以通过 这个 链接访问数据集。我们来加载数据集并绘制类别分布。
图片由作者提供
现在我们可以使用 imblearn 库对数据集进行 SMOTE。在下面的代码中,我们将对数据集进行 SMOTE 处理,并绘制原始数据集和重采样数据集的图。
金年会-金字招牌,信誉至上
图片由作者提供
如图所示,我们将 220 个原始少数事件转化为 2152 个,大约增加了 9 倍。这就是问题所在。让我们关注我们特定的流失问题。
生成这种虚假客户数据可能会导致模型学习到在现实世界中不存在的模式。
在大多数情况下,我们的数据集存在质量问题。因此,数据集中加入噪声的可能性很高。使用嘈杂数据生成新数据是个坏主意。
面对这些潜在的问题,我们有如下问题。
我们要将这些模型部署到生产环境中吗?
如果这是一个流失或欺诈检测问题,我不会将其部署到生产环境中,因为这些客户数据在应用 SMOTE 后可能变得更加嘈杂。但上述问题的答案很大程度上取决于我们所处理的数据和业务问题。一般来说,当数据嘈杂且问题复杂时,依赖 SMOTE 并不是一个好主意。
让我们使用过采样数据构建分类器并评估模型。
作者提供的图片
现在是时候尝试其他处理类别不平衡的方法了。下面我将解释一些我用来解决不平衡问题的方法。
使用类别权重
更改评估指标
通过对模型进行错误分析来创建更多特征
使用无监督算法检测数据集中的聚类。
让我们深入探讨这些方法。
在对具有类别不平衡的数据集进行模型训练时,损失函数可能会被多数类主导,因为它的实例更多。这可能导致模型更多地关注多数类而不是少数类。类别权重的主要思想是根据每个样本的类别分配权重。在训练过程中,它会对少数类给予更多的权重。这意味着模型在训练过程中会更多关注少数类,以期提高该类别的表现。
提前使用类别权重可以通过对少数类分配更高的权重来平衡损失函数,使其对损失函数的影响更大。这可以帮助模型更好地学习少数类的特征并提高其表现。
从数学上讲,类别权重通常通过将每个样本的损失乘以其类别的权重来融入损失函数。例如,假设我们有一个包含两个类别(0 和 1)的数据集以及以下类别权重:
二分类模型的损失函数可能定义如下:
作者提供的图片
要将类别权重融入这个损失函数,我们可以按如下方式修改它:
作者提供的图片
现在,当模型训练完成后,每个样本的损失将乘以其类别的权重。这将使模型更加关注少数类,因为其样本将显著影响损失函数。
大多数主要机器学习模型接受 sample_weight 参数。以下是如何使用 XGBoost 库来做到这一点的示例。
需要注意的是,如果权重过高,样本权重可能会导致过拟合。通常,尝试一系列权重并查看哪个在验证集上表现最佳是个好主意。
另外,我们也可以使用 scale_pos_weight 参数在 XGBoost 中实现。它会给出类似的结果。
让我们快速绘制上述模型性能图。
作者提供的图片
如果你检查上述两种情况的混淆矩阵。你会注意到,在过采样场景中,高假阳性比较多。我们使用类别权重减少了假阳性预测,同时也减少了真正的阳性。因此,我们必须根据实际业务需求调整我们的方法。
大多数库将准确率作为分类任务的默认评估指标。对于平衡问题,这没问题。但对于不平衡问题,这将导致模型仅猜测主要类别而不会学习任何潜在的信号。
例如,假设我们有 97 个非流失客户和三个流失客户。构建一个模型并使用准确率作为评估指标,通过盲目预测每 100 个样本为非流失类别,可以达到 97%的准确率。作为简单的解决方法,我们可以将评估指标更改为其他不同的指标。精确度、召回率、F1 分数和平衡准确率是处理不平衡分类任务的几个最佳选择。
当你的模型表现不佳时,我们可以使用错误分析来寻找不同的数据段,发现不同的性能水平。以之前的流失示例为例,我们可以找到模型的错误与客户收入区间的关系,并识别模型表现好的收入段和表现差的收入段。类似地,我们可以利用这些信息创建错误分析报告。在错误分析报告之后,我们可以确定模型可以用来区分流失者与非流失者的新特征。
例如,如果你知道低收入用户因为“XYZ”原因而流失,你可以添加这个特征(如果模型中还没有的话)。否则,你可以利用这个潜在特征进行特征工程,例如对“XYZ”特征进行分箱处理。
一种强大且流行的方法是分段。如果我们知道一些特征可以用于将数据分隔成不同的子群体,我们可以利用这些特征进行聚类模型。在聚类后,你会注意到不同组之间存在各种类别不平衡的情况。有几种可能的场景,例如,
你可能会发现只有一个类别的子群体。验证了这种客户行为后,我们可以进一步跳过对这个特定子群体的建模。这将减少整个数据集的不平衡。
你可能会发现与之前的数据集相比,分布较为平衡且易于建模。
或者,你可能会发现具有高度不平衡类别分布的子群体。但这与原始分布相比并不差。这是因为这种不平衡发生在相似的数据点中,并且即使分布不平衡,也可以是一个强烈的信号。例如,如果我们正在处理一个疾病预测模型,将人们根据年龄分组是个好主意。如果整体类别不平衡为 2%,则按年龄分组将为不同的子群体产生不同的类别分布。在较高年龄组中,这种分布将更加平衡。在中年和年轻年龄组中,这将高度不平衡。由于我们单独对每个段进行建模,模型可以很好地泛化到该特定段。
本文旨在展示除了合成数据生成之外的处理类别不平衡的替代方法。值得注意的是,一些方法在很大程度上依赖于数据、问题类型以及你所处理的领域。尝试几种不同的方法,并选择最适合你问题的方法通常是一个好主意。
请查找上述数据集的引用和许可证信息。
1. 金年会 引用:Lemaître, G., Nogueira, F., Aridas, C. K., & Oliveira, D. V. R. (2016). 用于基准测试的不平衡数据集 [Data set]. Zenodo.
2. 数据集许可证: Open Data Commons Open Database License v1.0
感谢阅读。
原文:
Matt Chapman
·发表于 Towards Data Science ·8 分钟阅读·2023 年 12 月 7 日
–
宝宝尤达喜欢分区。你呢?图片由 Victor Serban 提供,来源于 Unsplash
数据科学家们喜欢 SQL,但我们确实很糟糕于编写高性能的查询(也许是因为我们花了太多时间争论“SQL”是读作“S-Q-L”还是“sequel”?)。
在这篇文章中,我将向你展示如何使用 SQL 分区 来优化你的查询,并编写更快速、更便宜的代码。如果你已经掌握了 SQL 的基础知识,并希望开始解锁更高级的数据科学技能,这将是你工具箱中的一个很棒的补充。
分区表是将数据表划分为多个段/分区的表(谁能想到呢?)。
在分区表中,每个分区存储在服务器上的不同位置。这与普通(未分区)SQL 表不同,后者整个表位于一个位置。
这里是使用虚拟数据对比了我最喜欢的三本书的每日销售情况:
作者提供的图片
未分区表和分区表都包含相同的数据;唯一的区别是分区表将数据分成不同的段。它仍然是一个单一的表(即它不是三个单独的表);只是以不同的方式存储数据。
我们为什么要关注这个?好吧,正如我们稍后会看到的,我们可以利用这种结构来编写更高效的 SQL 查询。
创建分区表简直轻而易举。
例如,如果我们使用以下代码来创建一个普通(未分区)表……
… 我们可以通过在语句的末尾添加一行来创建一个分区版本:
我们进行分区的列被称为分区键;在这种情况下,我们在列上进行分区,但任何列都可以,只要它是(1)日期/时间戳字段或(2)整数字段。
一旦我们创建了这两个表,我们会发现它们乍一看是相同的(例如,如果你对每个表运行,结果将是相同的)。然而,如果我们查看表的详细信息/元数据,我们会看到分区表包含了一些额外的元数据。在 BigQuery 中(我在这里运行 SQL),情况是这样的:
作者提供的图片
这真是个好消息,因为这意味着分区可以帮助你编写更高效的查询!
当你查询一个普通(未分区)表时,SQL 引擎通常需要扫描整个表以找到你所需的行。在大型表中,这可能不必要地慢且昂贵,因为你的机器需要处理对生成最终输出没有用的数据。
例如,让我们查询一下我们之前创建的未分区表:
作者提供的图片
在上面的图片中,你可以看到表中的所有 9 行都被读取以返回日期大于‘2023-12-01’的 6 行。
现在让我们对分区表运行相同的查询:
作者提供的图片
这一次,我们看到仅读取了未分区表中的 6 行以生成相同的结果。在执行查询的主要部分之前,BigQuery 能够识别包含相关行的分区并进行选择性提取。它根本不需要读取其他分区中的 3 行。
选择分区的这个初步步骤被称为修剪。这比正常查询更高效,因为这意味着 SQL 引擎无需读取表中的每一行;它会首先获取所需的分区,然后才会执行你的查询。在高阶 SQL 术语中,我们在分区列上添加的过滤器被 SQL 引擎视为访问谓词,并在执行主查询之前运行。
如果你喜欢这篇文章,你可能会喜欢我的网站 the-sql-gym.com,网站包含了 100 多个 SQL 练习题。如果你想提升你的 SQL 技能,可以去看看!如果有任何反馈,请告诉我 😃
作者提供的图片。来源:the-sql-gym.com
当我们处理像上面这些小表时,分区可能显得有些过度。但当我们扩展到更大的表时,它可以带来显著的性能提升。
首先,让我们创建两个大表,每个表包含 100 万行。第一个将是未分区表,第二个将按列进行分区,每个分区包含 10,000 行。
当我们对未分区的表运行以下查询时:
作者提供的图片
… 我们看到在输出 1,001 条记录之前,表中的所有 1,000,000 行都被读取了。整个操作耗时 650 毫秒(经过时间)/503 毫秒(消耗的槽时间)。
但是,当我们对分区表运行相同的查询时,只读取了 10,000 行(即一个单独的分区)。
作者提供的图片
当查询未分区的表时,操作的经过时间不到第一个查询(在未分区的大表上)的时间的一半,且消耗的槽时间降低了近 95%。
很酷,对吧?
如果你希望开始使用分区来改善你的表/查询,有几个陷阱需要注意:
不要在非分区列上过滤大分区表 — 如果你在一个非分区键的列上进行过滤,你将无法利用表的分区结构。如果你确实需要在非分区键列上进行过滤,我建议你(如果可能的话)首先添加一个针对分区键的过滤条件(以修剪不需要的分区),然后再应用第二个过滤条件。这是因为 BigQuery(像许多 SQL 引擎一样)会从上到下执行语句中的过滤条件。
不要在分区键上应用函数 — 例如,如果你的分区键是列,不要添加像这样的过滤条件。相反,如果你需要在子句中使用函数,可以将函数应用于常量。在这个例子中,你可以将过滤条件改写为,以确保你仍能利用修剪/分区的优势。
BigQuery 对每个表有4,000 个分区的限制。如果你尝试使用一个将创建超过 4,000 个分区的分区键,请尝试使用不同的分辨率。例如,不要按日期/天分区:
… 你可以按周进行分区:
另外,值得了解的是 BigQuery 允许基于摄取时间字段和名为的伪列进行分区。虽然这个话题在本文中不够相关,但你可以在这里阅读更多内容。
在较小的表格中,分区可能不会带来性能提升。为什么?因为修剪分区的过程可能比简单地查看表中所有行花费更多时间(来源)。
在这些情况下,聚类可能是一个更高效的替代方案。请关注我下一篇文章了解更多内容!
我已经开始了一份免费的通讯,叫做 AI in Five,每周分享 5 个要点,涵盖最新的 AI 新闻、编码技巧和数据科学家/分析师的职业故事。没有炒作,没有“数据是新的石油”的废话,也没有来自 Elon 的推文(或者我现在应该说‘x-es’?)——只有实用的技巧和见解,帮助你在职业生涯中发展。
在这里订阅 如果这正是你感兴趣的!感谢阅读。
## AI in Five | Matt Chapman | Substack
最新消息、职业故事和数据科学与人工智能领域的编码技巧,浓缩成 5 个要点……
aiinfive.substack.com
原文:
Lynn G. Kwong
·发表于 Towards Data Science ·阅读时间:5 分钟·2023 年 11 月 25 日
–
图片来源:Tumisu,Pixabay
Elasticsearch 的同义词功能非常强大,当正确使用时,可以显著提高搜索引擎的效率。使用同义词功能时,一个常见问题是更新同义词集。
在索引的设置中定义的内联同义词不能直接更新,我们需要关闭索引、更新设置,然后重新打开索引以使更改生效。另一种方法是使用可以通过重新加载索引来更新的同义词文件。然而,当 Elasticsearch 服务器分布式部署或托管在云端时,使用索引文件会很难管理。这是因为我们需要将文件放在所有集群节点上。
好消息是,现在还有第三种方法,比之前的两种方法要方便得多。我们现在可以使用同义词 API 来管理同义词。尽管在撰写本文时这仍然是 Elasticsearch 的一个测试功能,但我认为它很快会被采用,因为开发者对该功能的需求很高,而且它可以非常方便地解决更新同义词集的棘手问题。我们将探讨在本文中同义词 API 的常见用法。
我们将使用以下 文件在本地启动 Elasticsearch 和 Kibana 以进行演示。
请注意,你需要至少使用 8.10.0 版本的 Elasticsearch 才能使用同义词 API。最新版本会是最佳选择,因为那个时候该功能应该已经更加成熟。
当 Elasticsearch 和 Kibana 使用上述 文件启动时,我们可以前往 来管理 Elasticsearch 索引和同义词。
要使用同义词 API 管理同义词,我们需要先创建一个同义词集,然后才能在 Elasticsearch 索引中使用。
我们可以使用端点通过请求创建或更新同义词集:
是用户定义的同义词集名称。
是请求体中必需的键,包括一个同义词规则数组。
每个同义词规则是一个包含可选键和必需键的对象。如果未提供,Elasticsearch 将创建一个标识符。的值是以前一篇文章中所用的 Solr 格式定义的规则。
当创建同义词集时,它可以在创建索引时用于或令牌过滤器:
如我们所见,使用同义词集的配置与使用同义词文件非常相似,如这篇文章中详细说明的那样。我们只需将更改为。
我们可以使用端点来分析一些文本,并测试在上一步中添加的同义词,使用 API 进行测试:
这表明 API 添加的同义词工作正常。
现在让我们使用同义词 API 更新同义词集。这正是同义词 API 真正出色的地方,因为我们不需要关闭、打开或重新加载相应的 Elasticsearch 索引,这极大地减轻了开发者的痛苦。
我们可以使用方法整体更新同义词集。在这里必须非常小心,否则你会用只包含新同义词规则的新集替换原始集合,这在生产环境中非常具有破坏性。
让我们向添加一个新的同义词规则:
请注意,原始的同义词集也应在此处添加。
当现有的同义词集更新时,所有使用该同义词集的搜索分析器会自动重新加载,这可以在上面的请求响应中看到:
我们可以使用端点来测试新添加的同义词:
是的,同义词集已成功更新,并且实时生效,无需关闭、打开或重新加载相应的索引。
此外,我们还可以通过直接添加规则来进行增量更新。在这种情况下,我们需要在路径中为规则指定一个:
你也可以通过其 id 删除同义词规则:
单独更新同义词规则的工作方式与整体更新同义词集时相同。
我们可以使用方法直接检索同义词集的内容:
实际操作中,我们希望编写一些脚本来统计索引中的同义词数量,以确保如上所示的同义词没有被意外删除。下面的 Python 代码片段可以统计同义词集合中的同义词数量:
在这项工作中,我们介绍了 Elasticsearch 同义词 API 的基础知识,并演示了如何方便地使用它来管理同义词。通过此功能,我们不再需要像处理内联同义词那样关闭和重新打开索引,也不需要像处理同义词文件那样手动重新加载索引。它可以使我们的搜索引擎更稳定,也让我们作为开发者的工作变得更加轻松。
如何正确使用 Elasticsearch 的同义词功能
Elasticsearch 8 在 Python 中的重要语法更新
原文:
Peng Qian
·发布于 Towards Data Science ·6 分钟阅读·2023 年 4 月 18 日
–
图片由 Aleksandr Popov 提供,来自 Unsplash
Python 的多线程性能一直未能如预期那样,因为 GIL 的存在。
自从版本 3.4 起,Python 引入了 asyncio 包,通过并发执行 IO 绑定任务。经过几次迭代,asyncio API 的表现非常出色,与多线程版本相比,并发任务的性能显著提高。
然而,程序员在使用 asyncio 时仍然会犯许多错误:
一个错误如图所示,是直接使用 await 协程方法,这种方式将并发任务的调用从异步变为同步,最终丧失了并发特性。
另一个错误如图所示,虽然程序员意识到需要使用 来创建后台执行的任务。但是,下面这种逐个等待任务的方式,将具有不同时间的任务转变为有序等待。
这段代码将会等到 task_1 先完成,而不管 task_2 是否先完成。
那么,什么是实际的并发任务?让我们用图示来说明:
不管我们启动了多少任务,最终都需要等待它们完成。图源:作者
如图所示,一个并发过程应该包括两个部分:启动后台任务,将后台任务重新加入主函数,并获取结果。
大多数读者已经知道如何使用 来启动后台任务。今天,我将介绍几种等待后台任务完成的方法以及每种方法的最佳实践。
在我们开始介绍今天的主要内容之前,我们需要准备一个示例异步方法来模拟一个 IO 绑定的方法调用,并且还需要一个自定义的 AsyncException,用于在测试抛出异常时友好地提示异常消息:
一旦我们完成了准备工作,就该开始今天的旅程,系好安全带。
可用于启动一组后台任务,等待它们执行完毕,并获取结果列表:
尽管可以形成一组后台任务,但不能直接接受列表或集合作为参数。如果你需要传递包含后台任务的列表,请解包它。
接受一个 参数。当 的值为 False 时,如果任何后台任务抛出异常,该异常将抛给调用 gather 方法的函数,并且 gather 方法的结果列表将为空。
截图。图像由作者提供
当 的值为 True 时,后台任务抛出的异常不会影响其他任务的执行,最终会被合并到结果列表中一起返回。
截图。图像由作者提供
接下来,让我们看看为什么 方法不能直接接受列表,而必须解包列表。因为当列表被填充并执行时,在等待它们完成的同时,很难向列表中添加新任务。然而, 方法可以使用嵌套组将现有任务与新任务混合,这解决了在中间无法添加新任务的问题:
然而, 无法直接设置超时参数。如果需要为所有正在运行的任务设置超时,请使用这种方式,这样的方式并不够优雅。
有时候,我们必须在完成一个后台任务后立即开始后续操作。例如,当我们抓取一些数据并立即调用机器学习模型进行计算时, 方法不能满足我们的需求,但我们可以使用 方法。
在使用 方法之前,我们先来看一下这个方法的源代码。
源代码显示, 不是一个并发方法,而是返回一个带有 语句的迭代器。因此,我们可以直接遍历每个完成的后台任务,并且可以对每个任务分别处理异常,而不会影响其他任务的执行:
接受 参数,并且在超时发生时,当前迭代的任务将会抛出 。
截图。图片来源:作者
在处理任务执行结果方面比 灵活得多,但在等待时很难将新任务添加到原任务列表中。
的调用方式与 相同,但返回一个包含两个集合的元组: 和 。 包含已经完成的任务, 包含仍在运行的任务。
接受一个 参数,该参数可以取三个枚举值:
当 为 时, 存储所有已完成的任务,而 为空。
当 为 时, 包含所有已完成的任务,而 包含仍在运行的任务。
截图。图片来源:作者
当 为 时, 存储那些抛出异常并完成执行的任务,而 包含仍在运行的任务。
当 为 或 时,我们可以递归调用 ,以便根据情况添加新任务并继续等待所有任务完成。
截图。图片来源:作者
在 Python 3.11 中, 引入了新的 API,这使得 Python 正式支持 结构化并发。这一特性允许你以更 Pythonic 的方式管理并发任务的生命周期。由于篇幅限制,我不会在这里详细讨论,但有兴趣的读者可以参考我的文章:
## 为什么 Taskgroup 和超时 在 Python 3.11 Asyncio 中如此重要
在 Python 3.11 中拥抱结构化并发
towardsdatascience.com
本文介绍了 、 和 API,并回顾了 Python 3.11 中引入的新 特性。
根据实际需要使用这些后台任务管理方法,可以使我们的 并发编程更加灵活。
由于经验限制,本文的阐述不可避免地存在遗漏,请在阅读过程中随时留下评论,我会积极回复。
在以下文章中,我将描述如何让 tqdm 与 asyncio 配合使用,以通过进度条指示并发任务的进度:
## 在 Python 中使用 Tqdm 和 Asyncio
监控并发任务进度的高效方法
towardsdatascience.com
如果你对如何在实际应用中使用 asyncio 处理数据集任务感兴趣,可以阅读我的这篇文章:
## 在 Python 中结合多进程和 Asyncio 以提升性能
使用实际案例来解释 APIs
towardsdatascience.com
通过 加入 Medium,你将可以无限制访问我所有的文章以及成千上万其他作者的文章。它只需花费你一杯咖啡的钱,但对我来说是极大的鼓励。
这篇文章最初发布于:
原文:
Yufeng
·发表于 Towards Data Science ·4 分钟阅读·2023 年 4 月 10 日
–
照片由 Pascal Müller 提供,来源于 Unsplash
有时,运行 Python 脚本时没有报告任何错误,并不是调试过程中的唯一任务。我们需要确保函数按预期执行。这是在探索性数据分析中的一个典型步骤,检查数据在某些特定数据处理前后的样子。
因此,我们需要在脚本执行过程中打印一些数据框或重要变量,以检查它们是否“正确”。然而,简单的 print 命令有时只能显示数据框的前几行和最后几行(如下例所示),这使得检查过程变得不必要地困难。
通常,数据框的格式是 ,如果直接使用 print 命令,你可能会得到如下内容,
打印前 100 行(图像由作者提供)
你可能已经注意到,数据框的中间部分被三个点隐藏了。如果我们真的需要检查前 100 行是什么呢?例如,我们想检查一个大型 Python 脚本中间某个特定步骤的结果,以确保函数按预期执行。
最直接的解决方案之一是编辑 Pandas 显示的默认行数,
设置 Pandas 显示的默认行数后,打印前 100 行(图像由作者提供)
其中 是一个方法,它允许你控制 Pandas 函数的行为,包括设置显示的最大行数或列数,如我们之前所做的。第一个参数 是用来调整显示的最大行数的,500 是我们设定的最大行数值。
尽管这种方法被广泛使用,但将其放在可执行的 Python 文件中并不理想,尤其是当你有多个数据框要打印,并且希望它们显示不同的行数时。
例如,我有一个结构如下的脚本,
我们在整个脚本中需要显示不同数量的前行,有时我们想查看整个打印的数据框,但有时我们只关心数据框的维度和结构,而不需要查看全部数据。
在这种情况下,我们可能需要使用函数 来设置所需的 ,或使用 每次在打印数据框之前恢复默认选项,这样会变得非常麻烦。
实际上,还有一种更灵活和有效的方法来显示整个数据框,而不需要为 Pandas 指定显示选项。
直接将 对象转换为字符串对象,当我们打印它时,不会受 的显示限制影响。
使用 to_string() 打印前 100 行(图片由作者提供)
我们可以看到,尽管我将显示的最大行数设置为 10, 帮助我们打印了 100 行的整个数据框。
函数 将整个数据框转换为 格式,因此可以在打印步骤中保留数据框中的所有值和索引。由于 仅对 pandas 对象有效,我们的打印 不受之前设置的最大行数限制。
所以,策略是你无需通过 设置任何内容,只需使用 即可查看整个数据框。这将避免你考虑在脚本的哪个部分设置哪个选项。
当你在整个脚本中有一致的行数需要显示时,请使用 。
如果你想打印整个 Pandas 数据框,无论 Pandas 选项设置如何,请使用 。
感谢阅读!希望你在工作中喜欢使用 Pandas 技巧!
如果你想阅读更多我的故事,请 订阅我的 Medium。你还可以通过我的 推荐链接 加入 Medium 会员!
原文:
💡Mike Shakhomirov
·发表于 Towards Data Science ·12 分钟阅读·2023 年 12 月 23 日
–
照片由 Martin Adams 提供,发布在 Unsplash
毫无疑问,用户留存是许多公司和在线应用程序的重要绩效指标。我们将讨论如何利用内置的数据仓库机器学习功能,运行用户行为数据的倾向模型,以确定用户流失的可能性。在这个故事中,我想重点关注数据集准备和使用标准 SQL 进行模型训练。现代数据仓库允许这样做。确实,留存是一个重要的业务指标,有助于理解用户行为的机制。它提供了一个高层次的概述,回答了我们应用程序在留住用户方面的成功程度:我们的应用程序是否足够好,能够留住用户?一个众所周知的事实是,留住现有用户比获得新用户要便宜。
在我之前的一篇文章中,我写到了现代数据仓库 [1]。
## 现代数据仓库
先进的数据平台设计
towardsdatascience.com
现代 DWH 具有许多有用的功能和组件,使其与其他数据平台类型有所区别 [2]。
ML 模型支持似乎是处理大数据时的基础 DWH 组件。
在这个故事中,我将使用二元逻辑回归,这是训练速度最快的模型之一。我将演示如何利用它来预测用户流失的倾向。确实,我们不需要了解每一个机器学习模型。
我们无法与 Amazon 和 Google 等云服务提供商在机器学习和数据科学领域竞争,但我们需要知道如何使用它。
我在我的文章中曾经写过关于这个的内容 [3]:
## 如何成为数据工程师
2024 年初学者的快捷方式
[towardsdatascience.com
在本教程中,我们将学习如何转换原始事件数据,以创建一个用于 ML 模型的训练数据集。我们将使用它来生成对用户的预测。我将以BigQuery ML作为示例,但还有很多其他支持此功能的数据仓库工具。
BigQuery ML 使机器学习操作和模型训练变得更加普及,因此现在数据分析师或软件工程师可以轻松训练模型。我们只需要对 SQL 有良好的知识,并了解用户保留数据集的逻辑[4]。
数据准备过程简单明了,应该很容易跟随。
我们将使用标准 SQL 来实现。
通常,这有助于揭示一些有关数据和用户基础的有用信息。分析用户行为和进行探索性数据分析有助于检测重要的用户行为漏斗(开放漏斗),这些漏斗可以用于进一步的特征工程,并改进模型。
例如,我们可以使用 Google 友善提供的免费用户行为数据集中的一个。这些数据集的典型移动应用有两个版本——Android 和 iOS,它们生成持续的事件数据流。Google Analytics 4 是一个很好的例子,这些数据可以用来衡量我们应用中的流量和参与度水平。
每个模型都需要一个数据集
我们想要创建一个。我们需要:
对来自 Firebase(Google Analytics 4)的 BigQuery 导出数据集进行探索性数据分析(EDA)。
将数据集分为两部分用于训练和测试,包含用于机器学习(ML)模型的分类和行为属性。
使用 BigQuery ML 训练和评估机器学习模型
使用 BigQuery ML 模型进行预测
将模型洞察应用于实践
在 Firebase 或 Google Analytics 4 中,所有用户行为数据都作为事件存储,这意味着表中的每一行对应一个单独的事件,并附带额外的参数和属性。
数据集准备和模型训练示意图
我们将使用一个公开的 Google Analytics 数据集[5],它包含一个名为“Flood It!”的移动游戏应用的数据(Android、iOS),且没有相关费用。然而,Google Cloud Platform(GCP)服务是按使用量计费的,可能会产生费用。
数据集示例。图片由作者提供。
该数据集包含来自超过 15,000 个用户的 570 万个事件。打开上面的链接并点击预览。
运行任何表的预览不会产生费用。
通过在下面的命令行中运行此命令来复制此数据集:
分析用户行为和进行探索性数据分析 [6] 有助于更好地理解用户旅程。
## 使用 BigQuery SQL 进行探索性数据分析?简单!
完整的 Python 比较和逐步指南,适用于任何数据集。Kaggle 用户流失数据。
towardsdatascience.com
运行此查询以检查数据集结构:
该数据集的限制在于用户数据没有实际的 ,而 通常是在注册后分配的。因此,在处理该数据集时,我们仅使用 ,这在理想情况下不是很好,因为这些在重新安装或新应用版本推出后会不断更新。
首先,我们希望对原始事件数据进行预处理,并创建一个具有正确结构的新数据集,以便用于机器学习模型。
如果用户在过去 30 天内活跃,我们将标记每个用户为保留(0)。
我们将使用 GA4 的 (device_id),Firebase 默认使用它来识别每个用户的设备。
根据我们的 EDA,我们将排除一些明显的异常值,例如垃圾邮件发送者(事件过多)和 用户(在 事件后在应用中停留时间少于 10 分钟的用户)。
我们将添加几个从原始事件数据中提取的类别特征列,例如 、、 等。
我们最终会添加每个用户在一定时间内的用户行为和活动总量,例如 、 等。
这些计算将用作机器学习模型的特征,但简而言之,它们是开放的事件漏斗,即用户在使用应用程序时的步骤。
我们的未流失(回归用户)定义是用户在当前日期前的过去 30 天内活跃并与应用程序互动。你可以尝试调整此参数。你还可以尝试预测某些内容,例如在应用中消费的可能性()等。
如果我们在模型中使用 ,则如果 在注册后 10 分钟内,我们会计算 ,否则为 0:
如果我们有一个每天更新的动态数据集,使用 来识别流失用户是理想的。然而,我们正在处理一些样本数据,因此我们应该使用数据中的最后已知日期,即我们假设在特定日期(20181003)收集了数据。
理想情况下,我们希望只跟踪那些在安装应用后完成注册的用户。在这种情况下,我们不需要计算 ,如果 在从 计算的 24 小时/3 天/30 天 之前,则计算 ,否则为 0:
这就是我们将用来构建模型的数据。分类特征可以表示一些不可量化的人口统计值,例如性别等。定量特征则是我们可以测量和计数的。
这两种特征的组合有助于创建一个更具预测性的模型。Firebase/GA4 数据集中提取了大量信息,这可能对我们的模型有用,例如 app_info、device、event_params、geo 等。
Firebase 会自动收集许多事件,但请记住,也可以设置自定义事件和属性。作为移动开发者,我们可以集成一个自定义事件,例如用户 。对于我们的示例应用程序,这将指示用户可能具有某些应用内权限(如高级会员、影响者、群组管理员、版主等)。
话虽如此,我们希望使用以下分类特征:
platform (IOS/Android)
geo.country
device.operating_system
device.language
需要注意的是,用户在这些字段中可能具有不同的值,例如不同的设备、语言更改和 VPN 设置可能会影响这些值。因此,我们只需要第一个参与事件和他们在 或 时使用的设备设置。
添加 row_number 函数将有助于实现这一点:
然后,为了预测用户流失,我们希望统计用户在注册/安装后的 24 小时/3 天/7 天 内遇到的事件数量:
在我们的案例中,我们希望收集和统计这些事件:
user_engagement
level_start_quickplay
level_end_quickplay
level_complete_quickplay
level_reset_quickplay
post_score
spend_virtual_currency
ad_reward
challenge_a_friend
completed_5_levels
use_extra_steps
对于其他应用程序,收集描述用户行为的其他事件可能是有用的,即:
message_sent
chat_open
spend_virtual_currency
account_topup
set_avatar
group_join
broadcast_listened
achievement_unlocked
reputation_update
让我们为未来的模型及其数据创建一个专用数据集:。
中的 SQL 查询演示了如何计算这些用户指标。我们可以在代码小部件中找到这个文件。要创建这个数据集,请在命令行中运行:
让我们看看有多少用户流失了:
从我们的数据集中,我们发现 4030 名用户在过去 30 天内流失并处于非活动状态:
流失的用户。图片由作者提供。
目前在 BigQuery ML 中有不同的模型类型 [7]:
BOOSTED_TREE_CLASSIFIER
神经网络
AutoML Tables
逻辑回归
逻辑回归可能是一个很好的起点,因为它可以相对较快地训练。其他类型的模型可能提供更好的性能,但也需要更多的训练时间,例如深度神经网络。
这些模型中的每一个都会输出一个 0 到 1.0 之间的概率分数(倾向),表示模型预测的可能性。
请参考文件。如果我们运行它,它将创建并训练模型。
运行此查询来评估模型:
你将看到模型性能指标。分析这些指标可能有助于在不同模型之间进行选择。
例如,关于模型准确性,任何超过 70%的结果都被视为强模型性能。
我们的模型的召回率为 0.559——换句话说,它正确识别了 56%的所有流失用户。
模型性能指标。图片由作者提供。
我们可以使用混淆矩阵来查看我们的模型在预测标签方面的表现,与实际标签进行比较。
如果我们运行下面的 SQL,它将生成一个混淆矩阵。
这可以被解释为和预测的比较。
混淆矩阵。图片由作者提供。
对于我们的分类模型,最重要的指标是用户流失和不活跃的倾向。换句话说,这是一种概率,且该概率越接近 1,模型预测的用户越不可能返回应用程序:
预测。图片由作者提供。
在现实生活中,我们希望创建一个每天更新的预测数据集。
首先,我们需要昨天注册的 Firebase/Analytics 用户。我们需要安排我们的数据集,并逐步添加昨天的新用户,即:
然后我们希望生成对它们的预测并将其插入到我们的新数据集中:
使用这个模型,我们可以通过模式更好地理解用户行为,当然,我们还希望利用这些知识做些事情。
有多种方法可以使用预测数据(激活)。例如,我们可以使用 SDK 和客户端库直接从我们的 DWH 解决方案中读取数据。例如,我们可能希望创建一个数据服务,每天收集新用户的预测数据,然后将这些数据发送到其他地方,即重新定向服务。是的,我们可能也希望重新定向那些可能流失的用户或可能留在应用中的用户。
确实,对机器学习(ML)模型数据采取行动以保留用户被证明是非常有用的,并且可能帮助在快速变化的市场环境中获得竞争优势。这就是为什么能够预测用户参与度以预测用户是否即将离开是重要的。我们不需要成为数据科学家就能创建和训练 ML 模型。我们所需要的 — 是现代数据仓库、良好的 SQL 知识以及对用户保留逻辑的良好理解。现代数据仓库已发展到可以提供所有已知 ML 模型的状态,它们已经准备好使用标准 SQL 方言进行创建。通过预测的保留数字,我们可以创建和编辑受众。利用现代数据仓库中的 ML 功能,我们可以通过向识别出的用户提供相关信息、有用的优惠和促销来量身定制用户体验。现代数据仓库解决方案使机器学习操作和模型训练民主化。这对于数据工程师来说是一个极其有用的特性,因为所有这些过程可以很容易地自动化、计划和触发,具体取决于使用案例场景。
[1]
[2]
[3]
[4]
[5]
[6]
[7]
原文:
乔尔·霍奇森
·
关注 发表在 Towards Data Science · 8 分钟阅读 · 2023 年 8 月 2 日
–
图片来自 Unsplash
你是否曾经花费数月的时间,以及谁知道花费了多少美元,来实施一个人工智能模型,结果发现没有人使用?即使你克服了采纳的挑战,你如何知道模型输出是否真正为用户的决策、查询、专业或日常活动带来了价值?
机器学习性能指标和实时监控工具是计算模型性能的优秀方式,并且可以识别出从技术角度来看可能出现的问题。但如果没有理解用户参与或满意度,很难知道模型是否被用于其预期的目的。
此外,听取 AI 模型用户的意见可能会揭示出预测错误的边缘案例;解释算法不能像我们期望的那样清晰解释问题;或用户体验缺陷影响用户与模型的互动方式。
本文的其余部分将涵盖理解 AI 模型用户反馈的重要性、不同类型的用户反馈,以及如何收集用户反馈以改善模型性能、增加用户采用率,并最终使 AI 模型与用户对齐。
AI 模型与用户的错位
什么是对 AI 的用户反馈?
为什么 AI 的用户反馈很重要?
不同类型的反馈是什么?
收集用户反馈指南
总结
当我们提到用户反馈时,所指的用户取决于你正在实施的用例。例如,这可能是一个内部业务用户或内部基于 ML 的需求预测应用程序的利益相关者;也可能是一个外部领域专家,如医学肿瘤学家,利用一个 MedTech 产品来帮助检测医学扫描中的肿瘤;或者,它可能是一个面向外部的求职申请助手的最终用户,利用生成式 AI 帮助编写和完善简历。
本文中概述的概念、方法和好处适用于所有这些不同的用例。然而,根据具体用例,一些好处可能会有所不同,应该根据具体情况加以考虑。
为了本文的目的,我们将使用上述描述的简历助手来说明用户反馈对该应用的好处。
另一个重要的点是,当提到用户反馈时,我们不仅仅是指重新标记错误预测或用于自动化模型再训练的反馈循环。用户反馈包括用户提供的任何信息,帮助了解 AI 应用的有用性和采用情况。在我们的简历助手示例中,用户反馈可能包括用户满意度评分,提供有关用户对生成的简历有多满意的见解,或书面评论以突出具体问题。
这种反馈不应该总是直接推送到自动化再训练流程中,原因有几个:
用户反馈通常是非结构化的,并突出了不正确预测以外的问题,因此不能总是直接用于重新训练模型。例如,用户指出简历助手使用过于正式的语言可能需要在训练数据中增加更多非正式文本的示例,而不是直接用这些反馈进行重新训练。
仅关注正确/错误预测忽略了用户提供的宝贵信息。理解用户反馈可以帮助 AI 团队根据用户体验和使用模式改进应用。
如强化学习与人类反馈(RLHF)等训练策略在受控环境中效果很好。然而,现实世界的用户反馈可能嘈杂且潜在有害。例如,盲目地将用户反馈纳入训练数据可能导致数据中毒,其中恶意用户故意误导模型。
因此,AI 团队应该审查用户反馈,以提取不同的见解,并确定下一步最佳行动方案,以改善整体 AI 应用。
实现模型评估
许多 AI 模型缺乏基准真相。这使得在测试数据集上进行评估变得困难,因为它通常基于一个代理指标,而这个指标通常只讲述了一部分故事。这在生成模型中尤其如此,因为了解用户是否对模型预测感到满意通常是最重要的指标。
提升模型性能:
用户反馈可以用来持续提高 AI 模型的性能。用户可能具备构建强大模型所需的良好领域知识。此外,监控用户参与度可以帮助识别模型是否因训练/测试集未能良好代表现实世界而表现不佳。
增加用户对齐度:
用户反馈提供了模型哪些方面运作良好以及造成摩擦的原因的见解。这使得 AI 团队能够提升用户体验,使模型更加直观和用户友好。此外,AI 团队可以确保模型对所有用户而不仅仅是小型子群体对齐。例如,确保简历助手在所有语言中保持质量,而不仅仅是英语。
当用户感到他们的声音被听到时,他们更可能信任 AI 模型并保持参与,从而增加用户对齐度和采纳度。
提高 AI 责任感:
通过用户反馈,AI 团队可以识别和解决与安全性、偏见或其他伦理问题相关的担忧。这种积极主动的方法导致了更安全、更负责任的 AI 模型的发展。通过寻求和回应用户反馈,AI 团队展示了他们对创建高质量和可靠 AI 解决方案的责任感和承诺。反馈也可能揭示对额外教育资源和文档的需求,AI 团队可以提供这些资源,以确保用户对模型的能力有清晰的理解,并促进最佳实践。
总结来说,利用用户洞察可以使 AI 团队优化模型、提升用户体验和解决伦理问题,从而提高用户满意度和信任度。
现在我们已经明确了用户反馈及其好处,让我们来讨论不同类型的反馈及其用途。
用户反馈主要分为两个类别:明确反馈和隐性反馈。这可以通过我们新朋友 ChatGPT(如下图)进行很好的解释和说明。
ChatGPT 说明了明确和隐性反馈之间的区别。截图来自 OpenAI 的 ChatGPT,并由作者编辑。
明确的用户反馈指的是用户对其体验、观点或偏好的直接、故意和自觉的输入。正如你在 ChatGPT 界面中看到的,点赞/点踩反馈就是明确反馈的一个例子。
明确的反馈可以进一步分为定量和定性两种。定量反馈包括可测量的尺度,如点赞/点踩、用户满意度(也称为 5 分制李克特量表),或任何最适合你想了解的用户信息的自定义尺度。
定性反馈通常涉及一个开放的文本框,以允许用户提供书面反馈。将定量测量与定性反馈结合起来,可以使 AI 团队了解用户评论背后的“为什么”,并揭示诸如 AI 缺陷、领域知识或用户偏好等细节。
提交定性反馈后,选择了负面的定量反馈。截图来自 OpenAI 的 ChatGPT。
隐性用户反馈指的是基于用户行为、动作或模式提供的间接、非自觉的数据。再次看 ChatGPT 界面,‘复制到剪贴板’按钮就是 OpenAI 收集隐性反馈的一个例子。对于简历助手的例子,隐性用户反馈也可以通过跟踪用户对生成输出的任何编辑来获得。
在选择实施的反馈类型时需要进行考虑。明确的反馈提供了用户反馈和想法的更清晰理解。然而,对于外部使用情况,最终用户可能不会总是提供明确反馈,因为他们可能不了解如何受益(或感觉没有时间!)。在这种情况下,隐式反馈也可以很好地了解 AI 应用的使用情况,而无需用户采取直接行动。
根据应用情况和你当前面临的挑战,你还应考虑实施哪些措施。例如,如果你专注于提高模型性能,那么带有评论的点赞/点踩措施可以帮助识别模型问题。但如果你更关注提高用户采纳率,那么也许用户满意度评分会更合适。
在本节中,我们将详细介绍收集用户反馈的四个关键步骤,并将用户洞察整合回 ML 监控系统中(如下所示)。
系统图概述了收集用户反馈的高层架构,并将用户洞察整合回 ML 监控系统。图像由作者提供。
步骤 1:设计并构建 AI 应用中的反馈组件
在确定你为何收集用户反馈的目标后,你可以确定哪种类型的反馈最适合你的需求。用户反馈通常在模型输出生成后实施。然而,你可能希望在整个应用程序中收集反馈,以获得对应用程序某些功能的反馈。
AI 模型元数据应与通过组件提交的所有反馈一起捕获。这包括模型版本、提示或请求、模型输出以及用户人口统计信息(如用户 ID 和位置)。
步骤 2:开发分析能力以理解用户反馈
对于定量反馈,这可能包括如用户满意度(CSAT/NPS)或随时间变化的平均正面/负面回应等图表,能够比较不同模型版本、用户或其他元数据的这些指标。
对于定性反馈,使用 ML 来分析用户评论中的情感,并将反馈分类到不同的类别中。这使得能够监控不同类别评论中的各种情感/满意度指标。
步骤 3:识别 AI 问题
利用分析能力,可以识别反馈中的重复主题和模式,以分类改进领域。然后,AI 问题可以被提出并优先解决。
AI 团队在这一阶段的角色是识别模型问题和用户问题,并确定解决这些问题的最佳行动方案。
要提醒 AI 团队可能在用户反馈中发现的见解类型,请回顾“什么是 AI 的用户反馈?”部分。
步骤 4 — 将用户反馈整合回你的机器学习监控系统中
将用户反馈整合到现有的机器学习监控系统中,可以让你设置警报(类似于性能监控或漂移检测)。例如,如果全球用户满意度得分低于某个阈值,可以触发警报通知 AI 团队采取行动。
此外,摘要和日报可以发送给 AI 团队或利益相关者,提供用户反馈的概览。
总结来说,用户反馈使 AI 团队能够识别漏洞、微调模型,并使模型与用户对齐。
上述内容也可以通过机器学习监控系统来实现。然而,通过从不同的角度,即用户的视角来评估模型,我们可以识别传统机器学习监控系统可能忽视的额外信息。
我希望这篇文章激发了你的兴趣,并为你提供了如何开始倾听用户意见并增强 AI 应用的初步想法。
如果你想了解更多关于 AI 用户反馈的信息,或分享和讨论你在这个话题上的想法,请随时通过 Linkedin 或 email**与我联系。
原文:
Wei-Meng Lee
·发表于 Towards Data Science ·6 分钟阅读·2023 年 3 月 1 日
–
由 Patrick Perkins 提供的照片,刊登在 Unsplash
Apache Kafka 是一个开源应用,用于大数据的实时流处理。它是一个发布-订阅消息系统,你可以用它在进程、应用和服务器之间发送消息。以下图示展示了 Apache Kafka 的高层架构概述:
所有图片均由作者提供
与其他消息系统不同,Kafka 还具有额外的功能,如分区、复制,并且具有比其他消息系统更高的吞吐量和容错性。所有这些功能使 Kafka 非常适合高容量的消息处理。
我将在未来的文章中详细讨论集群、分区及其他功能。
在本文中,我将指导你完成在系统上安装 Kafka 的过程,以便你对其工作原理有更好的了解。未来的文章将深入探讨 Kafka 的具体使用案例。
安装 Kafka 相当简单。你只需按照以下列出的 3 个步骤安装并运行 Kafka:
安装 Java
下载并安装 Kafka
运行 ZooKeeper 和 Kafka
在本文中,我将展示如何在 macOS 上安装 Kafka。
Kafka 是用 Scala 和 Java 编写的。因此,你需要做的第一步是安装最新的 JDK。你可以通过访问 官方 Java 下载 页面来安装 Java,网址为:。
如果你使用的是基于 Intel 的 Mac,请下载 x64 DMG 安装程序;否则,请下载 Arm 64 DMG 安装程序。
如果你的 Mac 上安装了Homebrew (),可以使用以下命令直接安装 Java:
前往 Official Apache Kafka Downloads 页面 并下载最新的 Kafka 二进制版本(在撰写时为 kafka_2.13–3.4.0.tgz):
在 Mac 上,下载的二进制文件将保存在默认的 Downloads 文件夹中。
在终端中,输入以下命令以解压 Kafka 安装包:
在 Downloads 文件夹中将创建一个名为 kafka_2.13–3.4.0 的新文件夹。将整个文件夹移动到你的主目录 ()。
或者,你可以使用 Homebrew 通过以下命令安装 Kafka:
为了确保 Kafka 正常运行,你需要运行一个称为ZooKeeper的工具。
ZooKeeper 负责 Kafka 的集群管理。它随 Kafka 安装包一起提供。
要启动 ZooKeeper,在终端中输入以下命令:
kafka_2.13–3.4.0 文件夹在你的主目录中。
接下来,启动 Kafka broker service。Kafka 代理是生产者和消费者之间的中介:
在一个新的终端窗口中,输入以下命令以启动 Kafka 代理服务:
如果没有错误,你的 Kafka 安装现在已经准备好使用了!
Kafka 代理启动并运行后,你现在可以看到 Kafka 的实际操作了!首先,创建一个新的 主题。
主题是用于管理和组织消息的类别。生产者将消息发送到特定主题,消费者订阅特定主题以接收发送到该主题的消息。
启动一个新的终端窗口,并输入以下命令:
上述命令在监听端口 9092 的 Kafka 代理服务上创建了一个“chat”主题。
要查看刚刚创建的主题,使用以下命令:
你应该会看到以下输出:
要将一个 事件(通常称为消息)写入主题,首先使用以下命令启动 Kafka producer console:
你现在应该能看到 提示符:
继续输入一些消息:
消息将被发送到 Kafka 代理。
要从“chat”主题中读取事件(消息),启动一个新的终端窗口并输入以下命令以启动 Kafka consumer console:
你现在应该会看到你之前发送的消息:
你可以启动另一个新的终端窗口,输入相同的命令启动另一个 Kafka consumer console,你也会看到相同的消息。
转到你运行 Kafka 生产者控制台 的终端窗口,输入一条新消息。两个运行 Kafka 消费者控制台 的其他终端窗口现在将接收到新消息:
如果你喜欢阅读我的文章并且这些文章对你的职业/学习有所帮助,请考虑注册成为 Medium 会员。每月 $5,会员可以无限制访问 Medium 上的所有文章(包括我的文章)。如果你使用以下链接注册,我将获得少量佣金(对你没有额外费用)。你的支持意味着我将能花更多时间撰写类似的文章。
[## 使用我的推荐链接加入 Medium - Wei-Meng Lee
阅读 Wei-Meng Lee 的每一篇故事(以及 Medium 上成千上万其他作者的作品)。你的会员费直接支持……
weimenglee.medium.com](https://weimenglee.medium.com/membership?source=post_page-----9199699623fa--------------------------------)
在这篇文章中,我简要介绍了 Apache Kafka 的使用及其主要组件。为了避免让你感到信息过载,我展示了如何通过安装 Kafka 并启动 Kafka broker 服务来开始使用 Kafka。为了了解 Kafka 的工作原理,你创建了一个主题,并使用 Kafka 生产者和消费者发送和接收消息。希望这个快速入门能让你对 Kafka 能做什么有更清晰的认识,未来的文章中我将深入探讨 Kafka 的具体应用案例!
原文:
Gabe Verzino
·
关注 发表在 Towards Data Science ·8 min read·2023 年 8 月 11 日
–
来自 Unsplash 的照片,作者 EJ Strat
在医疗保健中,准确预测即将到来的患者量不仅对运营成功至关重要,而且是一个极其棘手的问题。有太多依赖因素需要考虑——患者的严重程度和特殊要求、行政需求、检查室的限制、员工请病假、恶劣的雪暴等。更糟糕的是,意外的情况可能对调度和资源分配产生连锁影响,即使是最好的 Excel 预测也会被推翻。
从数据的角度来看,这些挑战真的很有趣,因为它们复杂,你可以深入思考一段时间。但同时,即使是微小的改进也可以带来重大的收获(例如,提高患者流量,降低等待时间,增加提供者的满意度,降低成本)。
那么还有什么替代方案呢?好吧,Epic 为我们提供了大量数据,包括患者到达预约时间的实际记录。通过已知的历史“到达”和“未到达”数据,我们可以在监督学习的范围内进行操作,而贝叶斯网络(BNs)提供了良好的概率图模型来预测未来的访问概率。
虽然生活中的大多数决策可以通过单一输入来确定(例如,考虑“我是否应该带雨衣?”,假设外面在下雨,那么决定应该是“是”),但贝叶斯网络可以轻松处理更复杂的决策——涉及多个输入的决策(例如,湿度高,步行仅需 3 分钟,你的雨衣在另一层楼,你的朋友可能带了伞等),这些输入具有不同的概率和依赖关系。在本文中,我将用 Python 在“草稿纸”上创建一个超级简单的贝叶斯网络,根据已知的三种因素的概率:症状、癌症阶段和治疗目标,输出患者在两个月后到达的概率分数。
贝叶斯网络的核心是使用有向无环图(DAG)表示联合概率分布的图形表示。DAG 中的节点表示随机变量,有向边表示这些变量之间的因果关系或条件依赖关系。正如所有数据科学项目所示,在开始时与利益相关者花大量时间正确绘制决策过程中的工作流程(例如,变量)对于高质量预测至关重要。
所以,我会编造一个场景,我们与乳腺肿瘤学合作伙伴会面,他们解释说,有三个变量对于确定患者是否需要在两个月后预约至关重要:患者症状、癌症阶段和当前治疗目标。我在输入时编造这个,但我们就这么做吧。
(实际上,将有数十个因素影响未来的患者量,其中一些具有单一或多重依赖关系,其他的则完全独立但仍会影响结果)。
现在,假设我们同意工作流程如上所示:Stage 依赖于其症状,但治疗类型独立于这些并且还会影响 2 个月后的预约发生。
基于此,我们将从数据源(对我们而言,是 Epic)中获取这些变量的数据,这些数据将包含我们分数节点(Appointment_2months)的 已知 值,标记为“是”或“否”。这种数据处理是一个重要部分;你需要根据这些变量在 2 个月前所指示的内容,准确捕捉真实患者在 2 个月后的到达情况。
上述内容,让我们手动输入每个变量(节点)中级别的概率分数。这些概率不是猜测,甚至不是最佳猜测。实际上,你将再次根据现有数据计算频率。
以症状变量为例。我会得到它们的 2 个级别的频率,大约 31% 是良性的,69% 是恶性的。
作者提供的照片
然后,我们考虑下一个变量 Stage,并与 Symptom 交叉表以获得这些频率。我们这样做是因为 Stage 对 Symptom 依赖,并且由于它们每个都有两个场景,它们实际上有 4 种概率结果。
作者提供的照片
如此类推,直到定义所有父子对之间的交叉表。
现在,大多数 BN 包含许多父子关系,因此计算概率可能会变得繁琐(且主要容易出错),所以下面的函数可以计算任何子节点对应于 0、1 或 2 个父节点的概率矩阵。虽然见解不能也不应该被自动化,但数据准备部分可以且应该被自动化。
然后我们创建实际的 BN 节点和网络本身:
我们一切就绪。现在让我们通过我们的 BN 运行一些假设并评估输出。
首先,让我们看看每个节点的概率情况,而不具体声明任何条件。
上述结果显示,该数据集中的所有患者有 67% 的概率处于 Stage_I_II,69% 的概率是非恶性的,58% 的概率需要辅助/新辅助治疗,而只有 22% 的患者需要 2 个月后的预约。
我们可以轻松地从简单的频率表中获得这些数据,而不需要 BN。
但现在,让我们提出一个更有条件的问题: 给定患者处于 Stage = Stage_I_II 并且 TreatmentTypeCat = Therapy 的情况下,他们需要在 2 个月内护理的概率是多少?此外,考虑到提供者对他们的症状一无所知(也许他们还没有见过患者)。
我们将运行在节点中我们知道是真实的内容:
返回结果:
那位病人在 2 个月内到达的机会只有 11%。我们可以向预测该病人 2 个月内到达的概率询问已知或未知特征的任何组合。进一步的算法和函数可以用来获取多个病人的概率,或者病人群体的概率,或优化这些概率。
编写 Python 代码是一回事,但贝叶斯网络在提供可靠的未来就诊估计方面的真正成功在很大程度上依赖于准确的患者护理工作流程映射。这需要时间、讨论和白板——而不是编码。可能还需要多次深入数据,与客户一起测试假设:“我们之前说过,护士导航员在报告症状差时总是会联系病人,但实际上只发生了 10% 的情况。下一次病人与他们的医生联系。”(再说一次,这只是举个例子,但这将是一个重要的工作流程映射)。
病人呈现出相似的情况时,通常会需要类似的服务,并且到来的频率也相似。这些输入的排列,其特征可以从临床到行政,最终对应于服务需求的某种确定性路径。但时间预测越复杂或越远,就越需要更多特定的、复杂的贝叶斯网络和高质量的输入。
这里是原因:
准确表示: 贝叶斯网络的结构必须反映变量之间的实际关系。选择不当的变量或误解依赖关系可能导致不准确的预测和见解。
有效推断: 高质量的输入变量提升了模型进行概率推断的能力。当变量基于条件依赖准确连接时,网络可以提供更可靠的见解。
减少复杂性: 包含无关或冗余的变量会不必要地使模型复杂化并增加计算要求。高质量的输入使网络更加高效。
感谢阅读。很高兴在LinkedIn上与任何人连接!如果你对数据科学与医疗保健的交集感兴趣,或者有有趣的挑战分享,请留言或私信。
查看我其他的一些文章:
为什么平衡类别被过度炒作
特征工程 CPT 代码
设计基础神经网络的 7 个步骤