题干与适用场景
你有 200 个城市两年的每日出行量。生产任务每周一重训一次,并为每个城市预测接下来 7 天。特征包括历史出行量、星期、节假日、天气预报和价格活动计划。团队准备随机划分训练集与验证集,用总体 MAPE 选择误差最低的模型。
请设计一套无未来信息泄漏的离线验证方案,说明切分方式、特征可用性、基线、指标、跨城市聚合、模型选择和最终上线门槛。两年、200 个城市、7 天和每周重训都是面试假设,不是行业基准。
这道题适用于数据科学、机器学习和预测岗位。核心能力是让离线实验复现“在某个预测时点,当时究竟知道什么”,因此归入 data。
面试官考察点
第一,候选人能否把生产预测流程翻译成验证协议。强回答会先固定预测起点、步长、重训频率和训练窗口,再谈模型;普通回答只说“按时间切分”。
第二,能否识别切分之外的泄漏。未来数据可能从全量标准化、跨越预测起点的滚动窗口、事后修订数据、最终天气观测值、尚未公布的活动计划或全量目标编码进入训练。
第三,能否让指标对应决策。一个总体平均数可能掩盖远期误差、低量城市失败、持续高估或区间失准。强回答同时报告按预测步长、城市分组和时间折的结果,并保留简单基线。
第四,能否分开调参与最终评估。滚动验证用于选择模型和阈值;最后一段、从未参与选择的时间区间用于估计选定流程的表现。反复查看最终留出集再改模型,会把它变成另一个验证集。
回答前需要澄清的问题
- 真实预测时点是什么? 若每周一 06:00 出预测,切分必须按这个时点冻结数据;每日滚动预测会产生不同的起点和重训成本。
- 7 天是一次直接输出,还是每天递归一步? 多步策略决定特征如何生成,也决定必须分别评估第 1 到第 7 天。
- 哪些外生变量在预测时可知? 日历通常已知,天气预报可知但最终天气未知,价格活动只有已审批且已发布的版本可用。
- 标签多久才完整? 若出行量会迟到两天,训练尾部与测试起点之间至少要留出相应 gap,或使用当时可见的快照。
- 业务损失是否对高估和低估对称? 运力配置通常有方向性成本;只用 MAE 可能无法表达缺车与闲置的不同代价。
- 城市是否同等重要? 每城等权反映覆盖公平,总量加权反映整体业务影响,两者不能互相替代。
- 上线时使用多长历史? 结构变化快时固定窗口可能优于扩张窗口;稳定季节性需要足够历史覆盖完整周期。
30 秒回答框架
“我会从生产流程反推滚动起点回测:每个周一只使用当时已经到达的数据,按真实训练窗口拟合,预测未来 7 天,再把起点向前滚动。所有预处理、滞后特征和超参数选择都只在每个训练折内完成;未知的未来天气不能换成实际观测。结果至少与季节性朴素基线比较,并按预测第 1 到第 7 天、城市和时间折报告 MAE、偏差及业务损失;百分比指标遇到零值要单独处理。最后用完全未参与调参的连续时间段做一次评估,只有在关键城市、峰值周和区间覆盖等门槛都通过时才上线。”
分步骤深入解答
第一步:把一次生产运行定义成一个预测折。
设预测起点为 t。训练数据只能包含在 t 时已可用且标签完整的记录,测试区间为 t+1 到 t+7。起点每 7 天前移,模拟每周重训。早期训练集必须覆盖足够的季节周期;否则该起点不参与评分。
扩张窗口使用从最早日期到 t 的全部历史,数据利用率高,但会保留很旧的机制。固定窗口只使用最近一段历史,能更快适应结构变化,却可能丢失年度季节性。选择应与生产训练策略一致,而不是看哪种在最终留出集上更好。
第二步:建立“预测时可用”特征合同。
每个特征记录业务时间、系统可用时间、修订规则和缺失处理。对每个起点重建当时的数据快照:
- 滞后 1 天的出行量只能来自
t或更早;7 日滚动均值的窗口终点也不能越过t; - 标准化、缺失填补、类别编码和特征选择只在该折训练部分拟合;
- 用当时发布的天气预报,不用后来观测到的实际天气;
- 只允许在
t前已确认的活动进入未来特征; - 标签延迟两天时,训练数据最多到
t-2,或在切分中设置等效 gap。
可执行检查包括断言每个训练单元的 available_at <= t、把预测起点后的原始数据移除后重新生成特征,以及对几个历史起点做快照重放。若预测不应变化却发生变化,就存在泄漏或不可复现依赖。
第三步:先建立难以作弊的基线。
至少比较“上周同一天”季节性朴素预测;若年度季节性可靠,可再加入去年同期基线。复杂模型只有在相同起点、相同可用特征和相同评分样本上稳定胜出才有意义。基线也用于暴露管道错误:复杂模型异常大幅领先时,应先检查时间对齐和泄漏。
第四步:指标组合要对应失败成本。
用 MAE 表示典型绝对误差,用 RMSE 暴露大误差,用有符号误差的平均值观察系统性高估或低估。MAPE 在实际值为零时无定义,在接近零时会被小分母放大,不能作为唯一指标。需要跨尺度比较时,可报告以训练折内季节性朴素误差缩放的 MASE;面向总量规划时可补充 WAPE,但要说明它会让高量城市主导结果。
若模型输出分位数,用 pinball loss 分别评估各分位数,并检查例如 P90 的经验覆盖率是否接近目标。覆盖率必须和区间宽度一起看:极宽区间可能覆盖良好却没有决策价值。
第五步:保留误差的结构。
先保留每条记录的 origin、horizon、city、实际值和预测值,再聚合:
- 第 1 到第 7 天分别评分,避免近端准确掩盖远端崩坏;
- 同时报告每城等权宏平均和按实际量加权的结果;
- 展示各时间折分布,而非只给跨折均值;
- 单列高峰、节假日、低量城市、新城市和天气异常窗口;
- 检查偏差是否在同一城市连续同方向累积。
第六步:嵌套选择并锁定最终测试。
在开发期滚动折中选择模型、窗口和超参数。若比较次数很多,记录每次实验,防止靠反复试验偶然赢得某些折。选定完整训练流程后冻结代码和参数,再在最后连续 8 到 12 周做一次评估;这段长度也是面试假设,应按季节性和样本需求调整。
上线规则应预先定义,例如:总体业务损失优于季节性基线,关键城市没有超过容忍阈值的退化,第 7 天误差可接受,偏差在运力容忍区间内,预测区间覆盖和宽度合格。平均分胜出但关键门槛失败时,不上线或只对通过的城市灰度。
第七步:让离线协议延伸到上线监控。
生产中记录模型版本、数据快照、预测起点、每个步长的预测和特征版本。标签到齐后用相同指标回填,并与回测分布比较。监控输入可用性、缺失率、预测偏差、按步长误差和基线差值;结构变化后重新评估训练窗口,而不是仅靠频繁重训掩盖问题。
高质量示范回答
“我先把一次生产运行原样搬进离线实验。假设每周一 06:00 重训并一次预测 7 天,我会选择一系列历史周一作为预测起点。每个折只读取该时点已到达且标签完整的数据,按照生产使用扩张或固定窗口训练,再预测后面 7 天。若标签晚到两天,训练尾部就停在起点前两天;天气使用当时的预报版本,不能使用事后的实际天气。
所有变换都封装进折内流程。缩放器、填补器、编码器和特征选择只看训练部分,滞后和滚动特征必须证明窗口终点不晚于预测起点。我还会删除起点后的原始数据重跑特征,确认历史预测完全不变。
比较对象先放上周同一天的季节性朴素基线。结果保留到城市、预测起点和第几天,分别报告 MAE、RMSE、偏差和业务成本;城市既做等权宏平均,也做总量加权。MAPE 遇到零值会失效,所以不会单独用它。若输出分位数,再看 pinball loss、每个步长的覆盖率和区间宽度。
滚动折用于选模型,最后连续时间段只评一次。上线要求提前锁定:整体超过基线、关键城市无不可接受退化、第 7 天和峰值周通过、偏差与区间校准满足运力决策。上线后记录预测起点和数据版本,标签到齐再用同一切片回填误差。这样离线提升才与真实运行条件可比。”
常见错误
- 随机打乱日期 → 训练会看到测试日期之后的机制和特征统计 → 按真实预测起点做滚动回测。
- 先在全量数据上生成特征和标准化 → 验证集信息已经进入训练流程 → 每折独立拟合变换,并按可用时间重放特征。
- 用最终天气观测替代天气预报 → 离线拥有生产时不存在的信息 → 保存并使用各预测起点当时的预报版本。
- 只报一个总体 MAPE → 零值、小城市和远期误差会被错误处理或隐藏 → 组合绝对误差、偏差、业务损失与分层结果。
- 没有季节性朴素基线 → 无法判断复杂度是否带来真实增益 → 在完全相同的折和样本上比较基线。
- 边看最终测试边改模型 → 最终时间段参与了选择 → 冻结流程后只评一次,失败则建立新的未来留出区间。
- 平均指标胜出就全量上线 → 少数高量城市可能掩盖关键分组退化 → 预先设置分组、峰值和步长门槛,并按城市灰度。
追问及应对
如果出现一个从未见过的新城市,如何评估?
普通滚动切分会让同一城市同时出现在训练和测试中,无法估计冷启动。增加按城市留出的评估:训练共享模型时完全移除一组城市,再在这些城市仅使用上线时真正可得的静态属性或短期历史。分别报告零历史和有少量历史的表现,并与区域或全局朴素基线比较。
如果活动效果持续 14 天,而预测步长只有 7 天,是否需要 gap?
gap 由信息可用性和样本重叠决定,不能机械等于预测步长。若训练标签或特征聚合会使用预测起点后的 14 天结果,就必须截断或留出足够间隔;若活动计划在起点前已知且特征只表达计划本身,则不因持续 14 天自动构成泄漏。逐字段画出时间线再决定。
如果新模型只改善高量城市,该怎么选择?
同时展示总量加权收益和每城等权退化,并把业务约束写成门槛。可以只在高量城市上线新模型,低量城市保留基线或分层模型;也可以优化带城市权重和最差分组约束的目标。不能用一个加权平均宣称所有城市都受益。
如果线上误差显著差于回测,先查什么?
先做可复现性核对:相同模型版本、预测起点、特征快照和外生变量版本能否重建当时预测。随后区分数据延迟或定义变化、生产与回测预处理不一致、基线也同步变差的结构变化,以及只影响模型的漂移。先定位协议偏差,再决定重训、缩短窗口、回滚或重做验证。