Files
Neo-ZQYY/docs/audit/changes/2026-03-02__spi-calibration-nonzero-median.md
Neo 14a12342b5 chore(audit): 补追 96 份未入仓审计孤本 — 覆盖 2026-02-26 ~ 2026-04-08
这些审计记录原本堆积在 docs/audit/changes/changes/ 嵌套误产物目录下(由开发机迁移
79d3c2e 前后的不明批量操作产生)。由于同期 .gitignore 屏蔽了 docs/audit/ 全目录,
它们从未入过 git 任何分支 history。删除即永久丢失。

按 docs/specs/audit-gap-recovery/tasks.md 阶段 1 执行,将全部 96 份 D 类孤本
(主目录无同名、git history 亦无记录)复制到 docs/audit/changes/ 主目录入仓。

涵盖主题: P1-P18 全栈集成 / 多模块累积变更 / ETL bug 修复 / 业务日切 /
   召回与任务引擎改造 / 租户管理与审批 / 董事会财务 / 客户与助教详情 /
   DDL 基线合并 / Kiro 到 Claude Code 迁移

阶段 2(B 类内容漂移 1 份)和阶段 4(嵌套目录删除)独立推进。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 06:35:42 +08:00

2.2 KiB
Raw Blame History

SPI 基数校准改用非零样本中位数

  • 日期2026-03-02
  • 模块:apps/etl/connectors/feiqiu/tasks/dws/index/spending_power_index_task.py
  • 触发:全栈联调中 SPI 基数校准 6 个参数全部回退默认值(中位数为 0用户要求改进

变更内容

修改方法:SpendingPowerIndexTask._calibrate_amount_bases

原逻辑:对全部会员(含零消费)计算中位数 → 零消费会员占 62%105 人中 ~65 人),中位数必然为 0 → 全部 6 个参数回退 DEFAULT_PARAMS

新逻辑

  1. 新增类常量 _CALIBRATE_MIN_SAMPLE = 10(非零样本最小数量阈值)
  2. 中位数计算前过滤零值:nonzero_values = [v for v in ... if v > 0]
  3. 非零样本 ≥ 10 → 使用非零中位数作为校准值
  4. 非零样本 < 10 → 回退 DEFAULT_PARAMS 并输出 WARNING

新增代码标记

# CHANGE 2026-03-02 | 基数校准改用非零样本中位数,零消费会员不参与校准
_CALIBRATE_MIN_SAMPLE = 10

验证结果

重新执行 DWS_SPENDING_POWER_INDEXrun_uuid: 8a9709bc084d4d15a9e2a40976583e24),校准结果:

参数 非零样本数 校准值 状态
amount_base_spend_90 47/105 218.00 非零中位数
amount_base_ticket_90 47/105 29.00 非零中位数
amount_base_recharge_90 42/105 5000.00 非零中位数
amount_base_ewma_90 47/105 48.30 非零中位数
amount_base_spend_30 6/105 500.00 ⚠️ 样本不足,回退默认
amount_base_speed_abs 6/105 100.00 ⚠️ 样本不足,回退默认

改进6/6 回退 → 4/6 有效校准 + 2/6 安全回退。

影响范围

  • 仅影响 SPI 基数校准逻辑,不影响子分公式、归一化、持久化
  • 校准优先级不变:配置表值 > 自动校准 > 默认值
  • 30 天窗口参数spend_30、speed_abs因测试环境数据稀疏仍回退生产环境数据充足时预期可正常校准

回滚

_calibrate_amount_bases 中的非零过滤逻辑还原为全量样本中位数即可:

# 还原为:
values = [extractor(f) for f in features.values()]
median_val = self.calculate_median(values)

并删除 _CALIBRATE_MIN_SAMPLE 常量。