公式评估与自定义 Evaluator¶
Evaluator 是 SRHarness 中公式评估工具共享的评测协议。它封装“如何切分数据、如何拟合表达式参数、以及用哪些数值指标评价拟合后的表达式”,使 evaluate_formula、submit_formula、多项式拟合和符号搜索等工具可以使用同一种评测标准。
当前 Evaluator 实例保存在 AgentContext.evaluator 中。SRHarness 提供面向普通对齐数据的 DefaultEvaluator 和面向图、超图数据的 GraphEvaluator;用户也可以继承 DefaultEvaluator,仅重载任务需要改变的部分。
SRHarness 符号引擎的作用
Evaluator 使用 SRHarness 符号引擎 提供的 Expression 表示以及表达式解析、参数拟合和数值求值能力。Engine 不负责数据切分、候选资格、指标定义或排序策略;这些任务由 Evaluator 和公式评估工具完成。将数学表达式基础设施留在 Engine 中,可以让不同工具和自定义 Evaluator 共享同一种数学语义。
评估路径¶
公式工具首先将模型给出的字符串解析为 SRHarness 符号引擎 Expression,然后由 BaseTool.evaluate() 判断公式是否是正式候选:
- 当左侧表达式恰好是
context.target,且右侧不依赖目标变量时,它是候选公式,走fit_candidate()和evaluate_candidate(); - 其他等式仍可用于探索变量关系,但走通用的
fit()和evaluate(),不会触发候选专属逻辑。
flowchart TD
A[公式评估工具] --> B[解析 f 与 y]
B --> C[从 AgentContext 获取训练集与验证集]
C --> D{是否为正式候选?}
D -- 是 --> E[fit_candidate]
D -- 否 --> F[fit]
E --> G[evaluate_candidate]
F --> H[evaluate]
G --> I[训练集与验证集指标]
H --> I
I --> J[ToolCallResult 与候选排序]
下面的伪代码概括了五个入口在公式工具中的调用关系:
def evaluate_formula(f, y, context, evaluator):
split = evaluator.split(context)
train_context = split["train"]
validation_context = split["validation"]
is_candidate = (
y.to_str() == context.target
and context.target not in f.variables
)
fitted = (
evaluator.fit_candidate(f, train_context)
if is_candidate
else evaluator.fit(f, y, train_context)
)
evaluate = (
evaluator.evaluate_candidate
if is_candidate
else lambda expression, split_context: evaluator.evaluate(
expression, y, split_context
)
)
return {
"train": evaluate(fitted, train_context),
"validation": evaluate(fitted, validation_context),
}
需要拟合时,参数只在训练集上确定;拟合后的同一个表达式随后分别在训练集和验证集上评估。AgentContext.train_split 和 AgentContext.validation_split 第一次被访问时会调用 evaluator.split(context),并缓存得到的两个 context 视图,直到数据发生变化或缓存被显式失效。
Residual diagnostics、候选资格判断、结果格式化和错误包装仍由 BaseTool 负责,不需要每个 Evaluator 重复实现。
DefaultEvaluator 合同¶
DefaultEvaluator 定义五个 class method。自定义 Evaluator 可以重载其中任意方法:
| 方法 | 输入 context | 职责 |
|---|---|---|
split(context) |
未切分的完整 context | 返回且只返回 {"train": AgentContext, "validation": AgentContext}。 |
fit(f, y, context) |
训练集 context | 只拟合 f 中的参数,使其逼近表达式 y,并返回参数已绑定的 Expression。 |
evaluate(f, y, context) |
训练集或验证集 context | 评价一般等式 y = f,返回数值指标字典。 |
fit_candidate(f, context) |
训练集 context | 拟合正式候选;默认等价于 fit(f, Symbol(context.target), context)。 |
evaluate_candidate(f, context) |
训练集或验证集 context | 评价正式候选;默认等价于 evaluate(f, Symbol(context.target), context)。 |
这个分层保留了 Agent 探索一般等式的能力,同时为正式候选提供任务特定入口。例如动力学 Evaluator 可以只在 evaluate_candidate() 中积分 dx_dt = f(x, t) 并计算轨迹误差,而不会尝试积分用于分析关系的任意隐式等式。
Evaluator 必须遵守以下结果合同:
fit()和fit_candidate()返回sr_harness_engine.Expression,且评估前不能留下未绑定参数;evaluate()和evaluate_candidate()返回dict[str, float | int];布尔值、字符串、数组和嵌套结构不能作为 metric;- metric 名称会原样进入训练集与验证集结果,其中任意 metric 都可以被配置为候选排序键;
complexity和其他所有指标一样由 Evaluator 返回,运行时不会在合同之外自动补充。
内置 Evaluator¶
DefaultEvaluator¶
DefaultEvaluator 假设 context.data 中的样本数组沿第一维对齐。它支持随机和 OOD 数据切分,使用 SRHarness Engine 拟合表达式参数并完成数值求值,默认返回:
GraphEvaluator¶
GraphEvaluator 继承 DefaultEvaluator,用于由 (..., N)、(..., E)、(..., H) 以及图或超图关系表组成的数据。它在拟合和求值时传递 context.num_nodes,切分数据时只切分样本维,不切分共享的边表或超边表。
Evaluator utilities¶
可复用的指标、切分和动力学基础设施位于:
其中包括:
calc_MSE()、calc_RMSE()、calc_MAE()、calc_MAPE()和calc_R2();- AIC、BIC、Pearson/Spearman 相关系数和表达式复杂度;
- 随机、OOD 和按顺序的数据切分;
integrate_ODE()与calc_trajectory_rollout_RMSE()。
将这些通用实现放在 utils 中,可以让自定义 Evaluator 保持简短,并避免把基础设施重新塞回 Evaluator 合同。
自定义 Evaluator¶
最安全的扩展方式是继承 DefaultEvaluator,并只重载需要改变的最窄入口。下面的 Evaluator 保留所有默认行为,仅为正式动力学候选增加轨迹 rollout RMSE:
from . import utils
from .default_evaluator import DefaultEvaluator
class TrajectoryRolloutEvaluator(DefaultEvaluator):
@classmethod
def evaluate_candidate(cls, f, context):
metrics = super().evaluate_candidate(f, context)
metrics["rollout_rmse"] = utils.calc_trajectory_rollout_RMSE(
f,
context,
time="t",
state="x",
)
return metrics
如果拟合过程本身也需要考虑 rollout,可以进一步重载 fit_candidate();若一般等式和候选公式都需要不同的基础评估方式,则重载 fit() 或 evaluate()。
自定义脚本必须定义且只定义一个 DefaultEvaluator 子类。load_custom_evaluator() 会在隔离进程中加载并检查源码,在主进程中返回一个保持相同类名与接口的代理实例,并保留源码和文件来源。之后的 split、fit 和 evaluate 调用也通过操作系统沙箱执行;自定义代码不会在 Web 服务进程内直接运行。网页工作台可以保存、加载和测试 context.evaluator/ 中的脚本,也可以让评测器构建 Agent 创建或修复实现;操作方式见 SRHarness 网页工作台。
完整的方法签名见 API Reference。表达式语法、参数以及图结构求值规则见 SRHarness 符号引擎。