81 lines
3.4 KiB
Markdown
81 lines
3.4 KiB
Markdown
# iAOP-Core · FeatureSpec 声明式特征定义引擎
|
||||
|
|
|
|||
|
|
对应 issue #35(父 EPIC #5「③ AI 模型框架 配置化重构」)与 PRD 5.3「超参包驱动」:
|
|||
|
|
超参包中每个特征的 `spec` 字段是一段**声明式特征定义表达式(FeatureSpec)**,本
|
|||
|
|
模块负责把这段文本**解释**为可执行的特征计算:
|
|||
|
|
|
|||
|
|
> `EMA(CLF-01.TEMP, 5m)` → 解析为 AST → 校验 → 依赖分析 → materialize 为时序
|
|||
|
|
|
|||
|
|
`core/model-framework/hyperparam.py`(issue #39)只对 `spec` 做「非空字符串」存在性
|
|||
|
|
校验;本模块补齐其语义层,使:
|
|||
|
|
|
|||
|
|
1. **配置台**(issue #62~#67 Template Console)导入超参包时即可一次性展示每个特征
|
|||
|
|
的解析结果与依赖点位,训练前暴露拼写/语义错误;
|
|||
|
|
2. **训练/推理流水线**(issue #40)拿到 AST 后直接 materialize 为「按点位拉取 → 算子
|
|||
|
|
计算」的特征管道;
|
|||
|
|
3. **切换模板仅改超参包**,特征逻辑零代码(对齐 PRD「配置化」核心目标)。
|
|||
|
|
|
|||
|
|
## 模块结构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
core/model-framework/
|
|||
|
|
├── feature_spec.py FeatureSpec 引擎(解析/校验/依赖/执行/算子注册)
|
|||
|
|
└── tests/
|
|||
|
|
├── _bootstrap.py 测试引导(目录含连字符,挂载包名 model_framework)
|
|||
|
|
└── test_feature_spec.py 解析/校验/依赖/执行/插件注册单元测试
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 设计要点
|
|||
|
|
|
|||
|
|
* **零外部强依赖**:解析/校验/依赖分析不依赖第三方库;执行(`materialize`)优先用
|
|||
|
|
numpy 向量化,无 numpy 时退化为纯 Python(边缘/离线环境可加载与校验)。
|
|||
|
|
* **不可变 AST + 函数式算子**:每个算子是纯函数 `op(series_map, args)`,注册到
|
|||
|
|
`OPERATORS`;新增算子只需 `register_operator`(对齐 PRD「新增结构走插件注册」,
|
|||
|
|
与 issue #34 Model Recipe 插件接口呼应)。
|
|||
|
|
* **安全解析**:手写递归下降解析器,**绝不使用 `eval`/`exec`**——FeatureSpec 是数据
|
|||
|
|
而非代码,避免任意表达式注入。
|
|||
|
|
|
|||
|
|
## 语法(对齐 PRD 5.3 示例)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
<Operator>(<arg>, <arg>, ...) # 一元/多元算子
|
|||
|
|
<arg> := <tag> | <number> | <window> | <Operator>(...)
|
|||
|
|
<tag> := 点位名,允许中文/点号/连字符,如 CLF-01.TEMP / 炉压
|
|||
|
|
<number> := 整数或浮点(含负号),如 3、-0.5、1e-3
|
|||
|
|
<window> := <正数><单位>,单位 d/h/m/s,如 5m、180d、10s
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
内置算子:`EMA / SMA / RollingStd / RollingMax / RollingMin / RateOfChange / Diff /
|
|||
|
|
Lag / Log / Scale / Clip / Combine`,覆盖 PRD 5.3 超参包示例的全部特征形态。
|
|||
|
|
|
|||
|
|
## 使用
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
from model_framework.feature_spec import (
|
|||
|
|
parse, validate, resolve_inputs, materialize, describe, register_operator,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
ast = parse("EMA(CLF-01.TEMP, 5m)") # 1. 解析
|
|||
|
|
issues = validate(ast) # 2. 语义校验(空列表=通过)
|
|||
|
|
tags = resolve_inputs(ast) # 3. 依赖点位:['CLF-01.TEMP']
|
|||
|
|
feat = materialize(ast, {"CLF-01.TEMP": xs}) # 4. 执行 → list[float]
|
|||
|
|
print(describe(ast)) # 人类可读描述
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
扩展算子(插件注册):
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
register_operator(
|
|||
|
|
"Double", min_arity=1, max_arity=1, arg_kinds=(("tag",),),
|
|||
|
|
func=lambda s, a: [x * 2 for x in s[a[0].name]], doc="翻倍",
|
|||
|
|
)
|
|||
|
|
materialize(parse("Double(A)"), {"A": [1.0, 2.0]}) # → [2.0, 4.0]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 测试
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd core/model-framework/tests
|
|||
|
|
python -m unittest test_feature_spec
|
|||
|
|
```
|