数据、特征与训练管线

本节目标

理解数据契约、特征一致性和训练管线如何共同减少“在我机器上能跑”的偶然性。

从脚本到管线

训练脚本常把读取、清洗、切分、特征构造、训练、评测和导出混在一起。管线(pipeline) 将其拆成有输入、输出和失败条件的步骤。步骤之间形成有向无环图(DAG):上游制品变化时,下游才需要重新执行。

一个最小管线可以是:

原始快照 → 数据校验 → 切分 → 特征构造 → 训练 → 离线评测 → 候选制品

数据契约先于模型

数据契约是生产者与消费者对结构和语义的共同约定。至少写明:

  • 字段名、类型、是否可缺失;
  • 合法范围、枚举值与单位;
  • 一行代表什么实体,时间戳属于事件时间还是处理时间;
  • 标签定义、生成延迟和修订规则;
  • 主键、去重规则与隐私级别;
  • 兼容性策略:新增可选字段、删除字段或含义变化如何处理。

结构校验通过并不代表数据可用。例如年龄字段都为整数,但单位从“岁”变为“月”,模型仍会被破坏。契约必须覆盖语义和单位。

切分与泄漏

数据泄漏 指训练阶段看到了部署时不可能获得的信息。常见来源包括:

  • 先在全量数据上计算归一化统计量,再切分;
  • 同一用户的近似重复样本跨训练集和测试集;
  • 用结果发生之后才生成的字段预测结果;
  • 时间序列随机切分,使未来信息进入过去。

先按业务实体或时间规则切分,再在训练集上拟合预处理器,并把同一预处理器作为模型制品的一部分保存。

训练与服务特征一致性

离线训练使用一套 SQL,在线服务又手写一套逻辑,会产生 training-serving skew(训练—服务偏差)。降低风险的方法包括:

  1. 共享经过测试的特征函数;
  2. 保存预处理器并与模型一起加载;
  3. 对典型输入建立离线/在线一致性测试;
  4. 明确特征时效和缺失值回退规则;
  5. 对每次预测记录特征版本,而不是敏感原值。

缓存与幂等

管线步骤应尽量 幂等:相同输入与参数重复运行,得到等价结果,而不是持续追加脏状态。缓存键应来自输入内容、代码/配置版本和步骤参数;只用文件名或日期可能错误复用旧制品。

失败重试前还要区分:

  • 可安全重试的纯计算步骤;
  • 会写数据库、发送通知或替换别名的有副作用步骤;
  • 需要唯一运行 ID 或事务保护的步骤。

一个可审查的步骤契约

每一步都写下:

name: build_features # 给可审计步骤一个稳定名称,便于日志和编排引用。
inputs: [validated_snapshot_id, feature_code_commit] # 只接受已验证数据快照和固定特征代码提交。
outputs: [feature_set_id, schema_report] # 声明可被下游追踪的不可变产物与验证报告。
checks: [no_forbidden_nulls, no_split_overlap] # 在发布前阻断空值与训练/评测划分泄漏。
retry: safe_before_publish # 说明只有发布前的纯计算阶段可安全重试。
owner: data-team # 明确对该步骤结果与异常负责的团队。

这只是概念示例,不要求使用 YAML 或某个编排框架。先把边界说清,再选工具。

练习与自测

为“根据客服记录预测是否需要人工升级”画出训练管线,并标注:

  • 哪一步最容易发生标签泄漏;
  • 哪个输出必须不可变;
  • 哪些检查失败后应立即阻断;
  • 在线输入缺少某个特征时应如何处理。

自测:为什么“数据表 schema 没变”不足以证明可以复用模型?为什么缓存键必须包含特征代码或配置版本?

小结与下一步

可靠管线把数据语义、切分规则和制品边界显式化。候选模型产生后,需要用注册表管理其身份与晋级关系,见 模型注册与候选晋级。

参考资料