GraphReduce 使用图形进行特征工程抽象化
GraphReduce 使用图形进行特征工程抽象化

编辑注:Wes Madrigal将在今年10月30日至11月2日的ODSC West演讲。请务必参加他的演讲“使用图形进行大规模特征工程流水线”,了解更多关于GraphReduce等内容!
对于从事机器学习/人工智能的读者来说,众所周知,机器学习模型更喜欢数值信息的向量。当我们有一个数据向量时,对其进行编码、异常值过滤、归一化、插补等操作相对简单。在特征工程自动化领域已经做了很多工作,但其中大部分都是基于输入是一个扁平特征向量的假设。然而,大多数企业数据在分析和机器学习的角度上仍未得到充分利用,其中很大一部分最有价值的信息仍然存在于关系数据库模式(如OLAP)中。要从这些模式中获取机器学习准备的特征向量,并不是一件简单的事情,因为我们需要知道感兴趣的数据实体位于何处(例如,客户),其关系是什么,以及它们如何连接,并编写SQL或类似的语句来选择、过滤、连接和聚合特定粒度的信息。为了进一步复杂化事情,数据泄漏会给机器学习模型带来严重问题,因此必须小心处理实体之间的时间关系。简而言之,“数据泄漏”指的就是允许来自标签期间的数据泄漏到模型训练数据中。最后,随着特征的构思、提出和添加,界面可能会变成一个难以扩展、维护或重用的SQL或Python流水线的“科学怪人”。在本文中,我们提出了GraphReduce作为这些问题的抽象。我们将演示在电子商务模式上的一个特征工程过程示例,以及GraphReduce如何处理关系模式上的特征工程复杂性。
假设我们正在预测客户是否会与通知进行互动以推动外展。不幸的是,我们的数据工程和机器学习运营团队尚未为我们构建特征向量,因此所有相关数据都存储在关系模式中的不同表中。示例模式如下:
- Customers(客户)
- Orders(订单)
- Order events(订单事件)
- Order products(订单产品)
- Notifications(通知)
- Notification interactions(通知互动)
由于我们正在以客户粒度进行建模,因此我们需要对关系从基数角度有一个相当好的理解。在客户细节级别进行建模要求我们将所有相关关系连接到客户,并将任何关系减少到客户粒度。例如,如果客户有10行,而子关系订单有100行,我们需要通过在订单实体上发出GROUP BY聚合来将订单实体减少到客户粒度,然后再与客户进行连接,以获得合计10行的客户和聚合/减少的订单信息的组合。通常情况下,了解粒度是相当直观的,但在这种情况下,我们将提供行计数,这样在一开始就很明显。
这些表具有以下行计数:
- Customers(客户):2行
- Orders(订单):4行
- Order products(订单产品):16行
- Order events(订单事件):26行
- Notifications(通知):10行
- Notification interactions(通知互动):15行
数据准备和过滤:
数据准备涉及移除错误或异常值的数据。这将涉及到诸如过滤器、丢弃行、转换或丢弃具有异常或错误值的列值,以及填充缺失值等操作。数据准备首先在实体级别进行,以确保错误和异常不会进入聚合的数据集。以下是在 Pandas 上对我们的订单实体进行数据准备的示例:

连接和基数:
假设我们已经处理好了数据准备和质量,现在我们准备将数据实体连接起来,并将它们展开到以客户为粒度的单个数据框中。做到这一点的关键是通过使用 GROUP BY 将子表减少到父表的粒度,以避免引入数据重复。以下是在 Pandas 中实现的示例:

处理时间:
为了避免数据泄漏,我们需要确保使用可靠的日期键,并在训练期间和标签期间正确地过滤数据。训练期间包含某个日期之前的信息,而标签期间包含该日期之后的信息。这样我们可以将训练数据提供给模型,并告诉模型它正在学习预测的未来期间发生了什么。由于我们处理的不是单个平面特征向量,而是任意数量的表格,我们需要确保时间处理在计算图中的每个关系中都是相同的。
一次性方法的问题:
上述步骤将在构建非ML-ready特征向量的关系数据模型时遇到,而这种情况大多数情况下都会发生。诚然,特征存储在几年前出现作为一个抽象化解决了大部分问题,但它们采用的是与 GraphReduce 不同的架构方法。feature store(如 feast、Tecton 或 Vertex AI feature store)之间的差异细节将在另一篇博文中进行介绍。
抽象化:
GraphReduce 将实体/表格视为图数据结构中的节点,它们之间的关系视为边。该库是 networkx 的子类,利用了图的原始操作并扩展了接口。GraphReduce 提供了一个抽象化来存储顶层计算图参数:
- 将数据减少到的父节点/实体
- 包含在历史训练数据集中的数据量
- 在训练和标签期间之间的切割日期
- 可插拔的计算后端参数,用于使用 Spark、Pandas 或 Dask
- 数据格式参数
- 计算图是否生成标签
顶层的 GraphReduce 对象还将操作的顺序集中在一起,这些操作通常以深度优先的方式映射到图中的节点。GraphReduce 对象在减少操作后,集中协调计算操作和节点之间的连接操作。下图概述了操作的顺序。

GraphReduce 中的节点抽象化包含以下操作:
- 获取数据(每个节点负责加载自己的信息)
- 过滤数据
- 注释数据
- 规范化数据
- 减少数据
- 通过在切割日期上进行切片,为特征准备数据
- 通过在切割日期上进行切片,为标签准备数据
在此示例中将所有内容组合起来:
使用图计算操作的规格实例化 GraphReduce 对象:

实例化我们要计算的节点,并添加到 GraphReduce 中:


运行计算操作

使用机器学习准备的特征向量并训练模型:

或者,您可以使用SQL并执行类似于这样的操作,但我不建议这样做 🙂

摘要:
我们演示了一个示例电子商务数据集,以及在从关系数据中聚合机器学习准备的特征向量时遇到的常见问题,并介绍了GraphReduce的抽象。我们演示了GraphReduce提供了一个统一的接口,用于在任意大型、动态基数关系数据集上进行计算操作。我将在即将举行的ODSC West演讲中详细介绍。
完整的代码示例:https://github.com/wesmadrigal/GraphReduce/blob/master/examples/cust_order_demo.ipynb
关于作者:
Wes Madrigal是一位机器学习专家,拥有十多年的通过人工智能提供商业价值的经验。 Wes的经验涵盖多个行业,但始终专注于MLOps。他最近关注和研究的领域包括图形、分布式计算和可扩展的特征工程流水线。





