Skip to content

Level 6 5D 打分与收尾子块

Abstract

入口:

python
targets = batch_maker.make_batch_eval(horizon)["target"]
self.evaluator.evaluate(...)

这一层解释:

_eval_batch(...) 的打分与收尾子块,怎样把预测结果和真实目标对齐、计算指标、再封装成单序列结果。

1. 上一层与当前层位置

上一层是:

同层兄弟节点已经有:

当前层是:

  • Level 6:细分 5D 打分与收尾子块

1.5 这一层的关系类型说明

这一层是在继续下钻:

  • Level 5 里的 5D 打分与收尾子块

所以这里的 6D-1 / 6D-2 / 6D-3 / 6D-4

  • 打分与收尾子块内部的逻辑分块
  • 不是 Level 5 的新同级主节点

1.6 同层文件关系

这一层和下面两篇是同层兄弟文档:

三者之间没有直接调用顺序。
它们分别细分的是 25 里的三个不同兄弟子块:

  • 5B
  • 5C
  • 5D

2. 当前层第一性

5D 打分与收尾子块 的第一性是:

把预测子块产出的 all_predicts,和同位置真实目标 targets 对齐,计算每个 rolling 窗口的指标,再汇总成一条序列的最终评测结果。

这一层负责:

  1. 生成真实目标批次
  2. 校验预测和目标数量一致
  3. 对每个 rolling 窗口算指标
  4. 对所有 rolling 窗口取平均
  5. 编码真实值、预测值和时间信息,拼成最终结果列表

3. 当前命令的最小例子

当前例子里的关键输入是:

  • all_predicts
    • 来自 5C 预测子块
  • target_train_valid_data.values
    • 作为历史数据传给某些 metric
  • eval_scaler
    • 由训练子块生成
  • save_true_pred
    • 控制是否保存真实值/预测值

这一步最终会得到:

  • single_series_results: List

它后面会被 EvalResult.collect() 收集,并最终写入日志文件。

4. 先看顺序图

5. 抽象索引树

6. 职责树

6.1 6D-1 真实目标生成

职责:

  • batch_maker 反向生成所有 rolling 窗口对应的真实目标

输出:

  • targets

6.2 6D-2 指标逐窗口计算

职责:

  • 对每个 (predicts, target) 调一次 self.evaluator.evaluate(...)

输出:

  • all_test_results

6.3 6D-3 指标汇总

职责:

  • 对所有 rolling 窗口的指标向量做平均

输出:

  • single_series_results

6.4 6D-4 结果封装

职责:

  • 编码真实值和预测值
  • 拼接文件名、训练时间、推理时间和日志信息

输出:

  • 最终 single_series_results: List

7. 输入输出接口

7.1 本层入口接口

关键输入:

  • batch_maker
  • all_predicts
  • eval_scaler
  • target_train_valid_data.values
  • series_name
  • end_fit_time - start_fit_time
  • total_inference_time

7.2 关键中间变量

  • targets
  • all_test_results
  • single_series_results
  • actual_data_encoded
  • inference_data_encoded

7.3 本层输出

  • single_series_results: List

8. 函数 / 文件关系图

9. 关键代码对应关系

9.1 生成真实目标

python
targets = batch_maker.make_batch_eval(horizon)["target"]

语义:

把每个 rolling 起点对应的真实 horizon 目标一次性取出来。

9.2 长度校验

python
if len(targets) != len(all_predicts):
    raise RuntimeError(...)

语义:

保证每个预测窗口都有一一对应的真实目标窗口。

9.3 逐窗口算指标

python
for predicts, target in zip(all_predicts, targets):
    single_series_results = self.evaluator.evaluate(
        target,
        predicts,
        eval_scaler,
        target_train_valid_data.values,
    )

语义:

每个 rolling 窗口都独立算一组 metric。

9.4 汇总成单序列结果

python
single_series_results = np.mean(np.stack(all_test_results), axis=0).tolist()

语义:

把这条序列上所有 rolling 窗口的指标向量取平均,得到最终这条序列的 metric。

10. 当前例子的具体落地

10.1 真实目标

当前例子里:

  • horizon = 24
  • num_rollings = 48

所以 targets 的语义是:

  • 48 个 rolling 窗口
  • 每个窗口长度 24
  • 每个时间步 7 个变量

10.2 指标计算

如果当前配置里用的是常见回归指标,如:

  • mae
  • mse
  • rmse

那么每个 rolling 窗口都会得到一个指标向量。

10.3 最终封装

最后拼接到 single_series_results 里的内容除了 metric 外,还有:

  • series_name
  • fit_time
  • inference_time
  • actual_data_encoded
  • inference_data_encoded
  • log_info

11. 当前层最重要的认知

这一层最重要的认知是:

_eval_batch(...) 并不是“先把所有预测拼起来再一次性算一个 metric”,而是先逐 rolling 窗口算指标,再对这些窗口指标取平均。

12. 下一层入口

如果后面继续 DFS,这一层最自然的下钻点是:

python
self.evaluator.evaluate(actual, predicted, scaler, hist_data)

也就是:

  • Evaluator
  • metric_funcs
  • 各个 metric 函数

13. 只留一句

Level 6 的 5D 只看一件事:怎样把 all_predictstargets 对齐、算 metric、再封装成一条序列的最终结果。

*记录并在线阅读我的笔记*