生产型机器学习系统:监控流水线

恭喜!您已部署独角兽模型。 您的模型应能全天候运行,不会出现任何问题。为确保流水线正常运行,您必须监控机器学习 (ML) 流水线。

编写数据架构以验证原始数据

为了监控数据,您应编写规则,让数据必须满足这些规则,从而根据预期的统计值持续检查数据。这组规则称为数据架构。按照以下步骤定义数据架构:

  1. 了解特征的范围和分布情况。对于分类特征,请了解可能值的集合。

  2. 将您的理解编码到数据架构中。以下是一些规则示例:

    • 确保用户提交的评分始终在 1 到 5 的范围内。
    • 检查单词 the 是否出现频率最高(对于英语文本功能)。
    • 检查每个分类特征是否都设置为一组固定的可能值中的某个值。
  3. 根据数据架构测试数据。您的架构应捕获以下数据错误:

    • 异常
    • 分类变量的值异常
    • 意外的数据分布

编写单元测试以验证特征工程

虽然原始数据可能通过了数据架构验证,但模型不会根据原始数据进行训练。而是使用经过特征工程处理的数据来训练模型。例如,您的模型会根据归一化的数值特征而非原始数值数据进行训练。由于经过特征工程处理的数据可能与原始输入数据有很大不同,因此您必须分别检查经过特征工程处理的数据和原始输入数据。

根据您对特征工程数据的了解编写单元测试。 例如,您可以编写单元测试来检查以下情况:

  • 所有数值特征都经过缩放处理,例如缩放到 0 到 1 之间。
  • 独热编码向量仅包含一个 1 和 N-1 个零。
  • 转换后的数据分布符合预期。 例如,如果您使用 Z 得分进行归一化,则 Z 得分的平均值应为 0。
  • 处理离群值,例如通过缩放剪裁

检查重要数据切片的指标

成功的整体有时会掩盖失败的子集。换句话说,即使模型的总体指标非常出色,在某些情况下,它仍可能会做出糟糕的预测。例如:

您的独角兽模型整体表现良好,但在预测撒哈拉沙漠时表现不佳。

如果您是那种对总体 AUC 感到满意的工程师,那么您可能不会注意到模型在撒哈拉沙漠中的问题。如果您需要为每个地区做出准确的预测,则需要跟踪每个地区的效果。与撒哈拉沙漠相对应的数据子集称为“数据切片”。

确定感兴趣的数据切片。 然后,将这些数据切片的模型指标与整个数据集的指标进行比较。检查模型在所有数据切片上的表现是否良好有助于消除偏差。如需了解详情,请参阅公平性:评估偏差

使用实际指标

模型指标不一定能衡量模型的实际影响。 例如,更改超参数可能会提高模型的 AUC,但此更改对用户体验有何影响?如需衡量实际影响,您需要定义单独的指标。例如,您可以调查模型用户,以确认当模型预测他们会看到独角兽时,他们是否真的看到了独角兽。

检查是否存在训练-应用偏差

训练-应用偏差是指训练期间的输入数据与应用期间的输入数据不同。下表介绍了两种重要的倾斜类型:

类型 定义 示例 解决方案
架构偏差 训练和应用输入数据不符合相同的架构。 在模型继续根据旧数据进行训练时,应用数据的格式或分布会发生变化。 使用相同的架构来验证训练数据和应用数据。 确保您单独检查架构未检查的统计信息,例如缺失值的比例
特征偏差 工程化数据在训练和应用之间有所不同。 特征工程代码在训练和部署之间存在差异,从而生成不同的工程数据。 与架构偏差类似,在训练和应用工程化数据时,应用相同的统计规则。跟踪检测到的存在偏差的特征数量,以及每个特征的偏差示例比例。

训练-应用偏差的原因可能很细微。 请务必考虑模型在预测时可用的数据。 在训练期间,仅使用在服务时可用的特征。

练习:检查您的理解情况

假设您拥有一家网店,并想预测自己在特定日期的收入。您的机器学习目标是使用客户数量作为特征来预测每日收入。

您可能会遇到什么问题?
点击此处查看答案

检查是否存在标签泄露

标签泄漏是指您尝试预测的评估依据标签无意中进入了训练特征。标签泄露有时很难检测到。

练习:检查您的理解情况

假设您构建了一个二元分类模型来预测新住院的患者是否患有癌症。您的模型使用以下功能:

  • 患者年龄
  • 患者性别
  • 既往病症
  • 医院名称
  • 生命体征
  • 测试结果
  • 遗传

标签如下:

  • 布尔值:患者是否患有癌症?

您需要仔细划分数据,确保训练集与验证集和测试集完全隔离。模型在验证集和测试集上的表现非常出色;指标非常理想。遗憾的是,该模型在现实世界中对新患者的诊断效果非常糟糕

为什么在测试集上表现出色的模型在现实世界中却表现不佳?
点击此处查看答案

监控整个流水线中的模型年龄

如果服务数据随时间推移而不断变化,但您的模型未定期重新训练,那么模型质量就会下降。跟踪模型自基于新数据重新训练以来的时间,并设置提醒的年龄阈值。除了监控模型在提供时的使用时长之外,您还应监控整个流水线中模型的使用时长,以发现流水线停滞。

测试模型权重和输出在数值上是否稳定

在模型训练期间,权重和层输出不应为 NaN(非数字)或 Inf(无限)。编写测试,检查权重和层输出的 NaN 和 Inf 值。 此外,还要测试某一层中超过一半的输出是否不为零。

监控模型性能

独角兽出现预测工具的受欢迎程度超出了预期!您会收到大量预测请求,甚至更多训练数据。您可能会觉得这很棒,但很快就会发现,模型需要越来越多的内存和时间来进行训练。您决定按照以下步骤监控模型的性能:

  • 按代码、模型和数据版本跟踪模型性能。通过此类跟踪,您可以准确找出导致性能下降的原因。
  • 针对新模型版本与之前版本以及固定阈值,测试每秒训练步数。
  • 通过设置内存使用量阈值来捕获内存泄漏。
  • 监控 API 响应时间并跟踪其百分位数。虽然 API 响应时间可能不受您的控制,但响应缓慢可能会导致实际指标不佳。
  • 监控每秒回答的查询次数。

测试已投放的实时模型在已投放数据上的质量

您已验证模型。但如果在记录验证数据后,现实世界中的场景(例如独角兽行为)发生了变化,该怎么办?那么,已部署模型的质量就会下降。不过,在投放时测试质量很难,因为真实世界的数据并不总是带有标签。如果您的投放数据未标记,请考虑进行以下测试:

  • 使用人工评估者生成标签

  • 调查在预测中显示出显著统计偏差的模型。请参阅分类:预测偏差

  • 跟踪模型的实际效果指标。例如,如果您要对垃圾内容进行分类,请将您的预测结果与用户举报的垃圾内容进行比较。

  • 通过在部分查询上应用新模型版本,缓解训练数据与应用数据之间可能存在的差异。在验证新服务模型时,逐渐将所有查询切换到新版本。

使用这些测试时,请务必监控预测质量的突然下降和缓慢下降。

随机

使数据生成流水线可重现。假设您想添加一个特征,看看它对模型质量有何影响。为了确保实验的公平性,您的数据集应完全相同,只是添加了这项新功能。 因此,请确保数据生成中的任何随机化都可以确定:

  • 为随机数生成器 (RNG) 设置种子。通过设定种子,可以确保每次运行 RNG 时,它都会以相同的顺序输出相同的值,从而重新创建数据集。
  • 使用不变量哈希键。 哈希处理是一种常见的数据拆分或抽样方法。您可以对每个示例进行哈希处理,并使用生成的整数来决定将示例放置在哪个拆分中。每次运行数据生成程序时,哈希函数的输入不应发生变化。如果您想按需重新创建哈希值,请勿在哈希中使用当前时间或随机数。

上述方法既适用于对数据进行抽样,也适用于对数据进行拆分。

哈希处理方面的注意事项

再次假设您正在收集搜索查询,并使用哈希来包含或排除查询。如果哈希键仅使用查询,那么在多天的数据中,您要么始终包含该查询,要么始终排除该查询。始终包含或始终排除某个查询是不好的,原因如下:

  • 您的训练集将看到一组多样性较低的查询。
  • 由于评估集不会与训练数据重叠,因此评估集将人为地变得困难。实际上,在提供服务时,您会在训练数据中看到一些实时流量,因此评估应反映这一点。

您可以改为对查询 + 查询日期进行哈希处理,这样每天都会得到不同的哈希值。

图 7. 动画可视化效果:仅对查询进行哈希处理会导致每天的数据进入同一存储分区,而对查询和查询时间进行哈希处理会导致每天的数据进入不同的存储分区。这三个类别分别是“训练”“评估”和“忽略”。
图 7. 对查询进行哈希处理与对查询 + 查询日期进行哈希处理。