专家特征
专家特征把领域公式计算出的信息追加到网络输入中,帮助模型识别重要的业务关系。原始变量继续保留,预测结果仍由网络学习。本页以水处理中的停留时间为例,介绍内置特征、YAML 公式和 Python 扩展三种用法。
使用场景
业务人员常用一些组合量判断工况,例如停留时间、负荷与温差。这些量由已有数据计算而来,却比单独的传感器数值更容易反映过程变化。
以水处理池为例,池内体积相同、进水流量不同,水在池中的平均停留时间也不同。模型只看体积或只看流量,都难以直接区分这一变化。将 V/Q 一起输入,可以明确提供“反应和混合可持续多久”的信息。
| 场景 | 可补充的特征 | 帮助理解的业务关系 |
|---|---|---|
| 水处理、反应器 | 体积 / 流量 | 停留时间随水量和流量变化 |
| 生化处理 | 底物或溶氧限制因子 | 浓度变化对反应速率的影响 |
| 温控 | 设备温度与环境温度之差 | 相同动作下的散热条件 |
如果某个量可以直接作为确定的图输出,使用专家函数;如果公式只提供辅助信息,放在 expert_features 中。特征能否改善预测,需要通过有、无该特征的对照来判断。
示例:为水处理模型加入停留时间
下面用简化的处理池数据说明配置,字段排列由您在项目中定义:
| 变量 | 列顺序 | 单位 |
|---|---|---|
states | [体积 V, 流量 Q, 浓度 C] | m³、m³/h、mg/L |
actions | [投加命令] | 按设备定义 |
当 V=1000 m³、Q=100 m³/h 时,停留时间为 10 h;Q 增至 200 m³/h 时,停留时间降为 5 h。该特征描述水力条件,浓度变化还由投加、混合和消耗共同决定。
在已有项目的 graph.nodes 中配置以下节点片段,保留项目原有的列定义、数据和训练阶段:
delta_states:
inputs: [states, actions]
input_slices:
V: "states[0]"
Q: "states[1]"
expert_features:
- name: hrt
network:
backbone: res
hidden_dims: [256, 256]
output_dist: normalinput_slices 将业务名称映射到原始变量的列;hrt 是内置的水力停留时间特征。框架在原始物理空间计算特征,再将计算结果与原输入一起提供给网络。
数据准备时统一流量时间单位,并检查 Q 的有效范围。内置公式使用小量避免除零,但停流和近零流量本身是不同工况,需要单独处理,不能把极大的计算结果直接解释为正常停留时间。
选择特征的接入方式
内置特征
内置特征适合已有标准公式的场景,可以直接在 expert_features 中按名称引用。
| 名称 | 用途 |
|---|---|
hrt、residence_time | 水力或过程停留时间 |
srt、fm_ratio、volumetric_load | 污泥停留时间、食微比和容积负荷 |
monod、double_monod、do_saturation | 底物、溶氧对过程的限制关系 |
inhibition | 抑制因子 |
temp_correction、arrhenius | 温度影响 |
space_velocity、damkohler、conversion | 空速、反应与输运关系、转化率 |
各特征的输入名称、参数及公式见专家特征库。物理量单位应与公式一致。
YAML 公式
有自己的公式时,可在同一节点中直接声明。下面的片段用温差作为温度网络的附加输入:
input_slices:
T: "temperature[0]"
T_ambient: "ambient[0]"
expert_features:
- name: temperature_difference
formula: "T - T_ambient"该节点的 inputs 需要包含 temperature 和 ambient。设备温度 30°C、环境温度 20°C 时,特征值为 10°C。公式使用受支持的表达式解析;复杂计算可改用 Python 特征。
公式还可通过 params 声明参数,并按需要设置 learnable: true。可学习参数应从训练数据估计,在验证轨迹上检查其取值和预测效果。
Python 自定义特征
需要复用复杂计算时,可以注册特征类。下面以处理前后的浓度计算相对变化,适用于两个浓度在当前决策时都已测得的场景:
from revive.core.features import ExpertFeature, register_expert_feature
@register_expert_feature("my_efficiency")
class EfficiencyFeature(ExpertFeature):
required_inputs = ["C_in", "C_out"]
output_dim = 1
def compute(self, inputs):
return (inputs["C_in"] - inputs["C_out"]) / (inputs["C_in"] + 1e-8)随后在节点中写 expert_features: [{name: my_efficiency}],并用 input_slices 映射 C_in、C_out。训练和加载前需要显式导入特征类完成注册;目前没有专门扫描专家特征的目录。以命令行为主要入口时,可优先使用内置特征或 YAML 公式。
对齐数据与输入
input_slices 支持单列和连续多列,如 states[0]、states[2:4]、actions[0]。每个名称应与特征要求的输入一致,切片范围应与数据列数一致。
建立特征前,先记录公式、单位、输入来源和有效范围。改变数据列顺序后同步调整切片。公式只使用当前或允许的历史观测;预测未来浓度时,真实未来浓度不能成为特征输入。
采用温差、停留时间等组合量时,可以选取几条样本手工计算,与配置输出逐项核对。这样容易发现列名相同但单位不同、进出水浓度放反等问题。
训练并比较效果
将片段加入自己的完整 config.yaml,在项目目录运行:
revive validate --config config.yaml
revive train --config config.yaml --run-id with_expert_features使用相同数据划分、网络训练规模和验证窗口,与不含该特征的配置比较。水处理任务可以按流量区间分别查看多步浓度误差;温控任务可以按内外温差和负载区间查看预测误差。
保留能在相关工况中稳定改善预测的特征。增加输入维数会增加计算量;多个高度重复的特征未必带来额外收益,通常先从一两个关系清楚的特征开始。
常见问题
| 现象 | 处理方法 |
|---|---|
| 特征所需变量找不到 | 对照公式的输入名称检查 input_slices |
| 数值异常或出现 NaN | 核对单位、分母、有效域和原始数据缺失值 |
| 自定义类未注册 | 在训练与加载前显式导入实现 |
| 加入后训练误差下降,验证变差 | 检查特征是否泄露未来信息,再比较分工况结果与模型复杂度 |
| 数据列调整后效果改变 | 检查切片映射,按新的输入布局重新训练 |