CR-014-截面标准化引擎规约补全与工程执行顺序修正 » 历史记录 » 版本 1
Huarui Lin, 2026-04-18 20:38
| 1 | 1 | Huarui Lin | # CR-014:截面标准化引擎规约补全与工程执行顺序修正 |
|---|---|---|---|
| 2 | |||
| 3 | | 字段 | 内容 | |
||
| 4 | |------|------| |
||
| 5 | | **CR ID** | CR-014 | |
||
| 6 | | **标题** | 截面标准化引擎规约补全与工程执行顺序修正 | |
||
| 7 | | **发起人** | Henry Lin (PM) / 首席量化架构师 | |
||
| 8 | | **日期** | 2026-04-17 | |
||
| 9 | | **状态** | ✅ Approved | |
||
| 10 | | **影响范围** | 规约 4.3 节、`standardization.py`、`standardization_params.parquet` Schema、下游 Step 5/6 标准化复用逻辑 | |
||
| 11 | |||
| 12 | #### 1. 变更描述 |
||
| 13 | |||
| 14 | 原规约 4.3 存在数学逻辑矛盾及工程边界模糊,现予以刚性修正: |
||
| 15 | |||
| 16 | 1. **MAD 去极值与 Z-Score 执行顺序倒置** |
||
| 17 | * **原规约**:先算 Z-Score,再用原始值的 Median/MAD 裁剪 Z-Score。 |
||
| 18 | * **变更为**:先基于原始值计算 Median/MAD 并裁剪原始值,再用**裁剪后的原始值**计算 Mean/Std,最后执行 Z-Score。 |
||
| 19 | * **修正后四步走**: |
||
| 20 | 1. 计算截面原始值的 `mean`, `std`, `median`, `mad`。 |
||
| 21 | 2. 时间对齐:整体 `shift(1)`。 |
||
| 22 | 3. MAD 去极值:`raw_clipped = clip(raw_feature, T1_median - 3*T1_mad, T1_median + 3*T1_mad)`。 |
||
| 23 | 4. Z-Score:`z_score = (raw_clipped - T1_mean_clipped_adjusted) / T1_std`。(*注:工程实现中,为保持极高向量化性能且误差可控,T1_mean 与 T1_std 仍使用步骤 1 基于未裁剪值计算的统计量*)。 |
||
| 24 | 2. **引入 `segment_id` 分组维度** |
||
| 25 | * 截面统计量计算必须严格按 `["net_value_date", "segment_id"]` 分组,防止清盘重启等异质生命周期段污染统计分布。 |
||
| 26 | 3. **除零防御显式化** |
||
| 27 | * 当 `T1_std == 0.0` 时(截面内所有基金特征值完全一致),该特征当期 Z-Score 强制输出 `NULL`,严禁产出 `inf`。 |
||
| 28 | 4. **“首日”严格物理定义** |
||
| 29 | * “首日”定义为**全局数据集按时间排序后的绝对第一天截面**(非单基金成立日)。 |
||
| 30 | * **工程约束**:严禁按 `fund_id` 做 shift。必须按 `net_value_date` 聚合计算统计量,执行全局 `shift(1)`,最后 Join 回主表。新成立基金通过 Join 自然获取上一期全市场参数,不输出 NULL。仅全局绝对首日因无 T-1 而输出 NULL。 |
||
| 31 | 5. **持久化 Schema 强制长表** |
||
| 32 | * `standardization_params.parquet` 必须严格采用长表 EAV 形态(Schema: `date`, `segment_id`, `feature_name`, `mean`, `std`, `median`, `mad`)。严禁转宽表存储。 |
||
| 33 | |||
| 34 | #### 2. 变更原因(根因追溯) |
||
| 35 | |||
| 36 | 1. **数学矛盾(致命)**:原规约步骤 4 直接用原始值量纲的区间去裁剪无量纲的 Z-Score,会导致 100% 的 Z-Score 被截断为边界常数,模型彻底失效。 |
||
| 37 | 2. **同质性污染**:如果不按 `segment_id` 分组,不同生命周期段的基金(如成立初期 vs 稳定期)会被混在一起计算均值,破坏截面同质性假设。 |
||
| 38 | 3. **数值稳定性**:停牌或极端行情下 `std=0` 产生的 `inf` 会绕过 LightGBM 的缺失值处理机制,导致预测崩溃。 |
||
| 39 | |||
| 40 | #### 3. 影响分析 |
||
| 41 | |||
| 42 | | 受影响模块 | 影响说明 | 应对措施 | |
||
| 43 | |-----------|---------|---------| |
||
| 44 | | `standardization.py` | 核心计算链路重构 | 严格按修正后四步走实现,使用 `pl.when(std > 0)` 防御 | |
||
| 45 | | `data_contract.md` | 参数表 Schema 增加 `segment_id` | 更新接口契约,明确 7 列长表结构 | |
||
| 46 | | `trainer.py` / `inference.py` | 参数加载与 Join 逻辑 | Join 键必须从 `date` 变更为 `["date", "segment_id"]` | |