W01 · S01—S07 · 总 Day 91—97
历史数据:当时发生,不等于当时已知
用迟到、回填与过期特征理解训练数据泄漏。
作者准备的学习示例 · 不计真实学习进度 · 不代表生产 / GPU / 真机结果
核心问题
假设在第 10 分钟判断一个案例。数据库后来补录了一条“第 5 分钟发生”的信息。今天回放第 10 分钟的决策时,可不可以用它?答案取决于你要重建的是最终事实,还是决策者当时可见的信息。二者都可能有用,却不能混在同一份训练或评估输入中。
对应 S01~S07。先读事件时间、数据契约和 point-in-time 日课,再运行本例。目标是建立时间语义,不是搭建特征平台。
1. 两条时间轴与一个选择规则
eventAt 表示业务事件或特征的有效时间;availableAt 表示这个版本已经可供决策系统使用的时间。后者不一定等于原始日志的入库时间:如果还要做清洗、聚合或上线发布,真正可用会更晚。
本例在决策时刻 t 选择满足下列条件的最新记录:实体匹配、eventAt <= t、availableAt <= t、t - eventAt <= TTL。先按事件时间倒序,再按可见时间倒序;完全相同则按 ID 确定顺序。该 tie-break 只是让示例可重复,真实冲突需要业务版本规则。
TTL 是相对历史决策时刻计算,不是相对今天。过期值应返回缺失状态,不自动当零。零可能是一个真实观察值;把缺失填成零会改变特征含义,也会影响下游模型。
2. 手算一遍输入
| ID | 事件时刻 | 可见时刻 | 值 | 第 10 分钟能否看到 |
|---|---|---|---|---|
| original | 5 | 6 | 20 | 能 |
| late-correction | 5 | 15 | 80 | 不能,是后来纠正 |
| future-event | 12 | 12 | 95 | 不能,事件尚未发生 |
| other-entity | 8 | 8 | 100 | 不能,属于另一个实体 |
只过滤事件时间,会选到数值 80。它没有来自“未来事件”,却来自“未来知识”,同样可能造成训练泄漏。加上可见时间约束后,第 10 分钟只能选 20。到第 30 分钟,TTL 为 10 时这些记录均过期,输出 null。
npm run learning:p2 -- w01
先比较 eventTimeOnly 与 asKnownThen,再看 expired。代码不训练模型,因此“消除了这条回填泄漏”不能写成“模型已达到无泄漏或高质量”。标签构造、跨实体关联、数据切分仍可能存在其他泄漏。
3. 改一个变量,观察一个因果关系
把 late-correction.availableAt 从 15 改为 9,其他值不动。现在它在第 10 分钟之前已可见,预期会被选择。这个变化来自可见性,而不是模型变聪明。恢复原值后,把 TTL 从 10 改为 4,原始值也应过期。
兴趣延伸:给一次决策分别保留 eventCutoff 和 knowledgeCutoff。前者决定讨论哪个业务时刻,后者决定用截至何时的知识重建历史。这样可以同时表达“当时知道什么”和“今天如何纠正历史”,而不覆盖旧记录。此处只是双时态设计练习,不要求写数据库。
4. 课程与官方材料
- Feast Point-in-time joins:读 TTL 与 created timestamp 的说明。其默认事件时间匹配与可见时间限制不是一回事;本例显式要求后者。不要把教学字段名当成所有存储都支持的 API。
- FSDL 2022:选 Data Management,想清楚来源、清洗、标注和版本怎样进入数据生命周期;不需要完成整套数据作业。
5. 向 AGI 与具身智能延伸
AGI 相关研究中的记忆回放同样需要区分“事件发生”和“Agent 获取信息”的时刻,否则可能高估规划与预测。具身场景还会增加传感器时钟、传输延迟和坐标变换版本。这里的分钟级表格只能说明信息可见性,不能证明处理了机器人实时同步。
可记三句:为什么回填会泄漏;缺失和零有什么差别;自己的案例中 available time 应由哪个环节定义。