Files

132 lines
6.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 实现计划SPI 消费力指数Spending Power Index
## 概述
基于设计文档,将 SPI 指数建设拆分为 DDL 建表 → 核心算法实现 → 任务注册与执行流程 → 配置种子数据 → 属性测试 → 文档更新 六个阶段,每个阶段增量构建并可验证。
## 任务
- [x] 1. 创建 DDL 与数据库表
- [x] 1.1 编写迁移脚本 `db/etl_feiqiu/migrations/<日期>_create_dws_member_spending_power_index.sql`
- 创建 `dws.dws_member_spending_power_index` 表(含序列、唯一索引、查询索引)
- 字段定义参照设计文档数据模型章节
- _Requirements: 1.1, 1.2, 1.3, 1.4, 1.5_
- [x] 1.2 在测试库 test_etl_feiqiu 执行迁移脚本建表
- 通过 TEST_DB_DSN 连接测试库执行 SQL
- _Requirements: 1.6_
- [x] 1.3 运行 `gen_consolidated_ddl.py` 从测试库导出 DDL 合并到主 DDL
- 执行 `python scripts/ops/gen_consolidated_ddl.py`,验证 `docs/database/ddl/etl_feiqiu__dws.sql` 已包含新表
- _Requirements: 1.7_
- [x] 2. 实现 SPI 核心算法(纯函数)
- [x] 2.1 创建 `SPIMemberFeatures` 数据类和 `SpendingPowerIndexTask` 骨架
- 新建 `apps/etl/connectors/feiqiu/tasks/dws/index/spending_power_index_task.py`
- 定义 `SPIMemberFeatures` dataclass
- 定义 `SpendingPowerIndexTask` 类继承 `BaseIndexTask`,包含 `INDEX_TYPE``DEFAULT_PARAMS`、抽象方法实现
- _Requirements: 7.2, 7.3, 9.1_
- [x] 2.2 实现 `compute_level` 静态方法
- Level 子分公式:`L = w_s30 × ln(1 + spend_30/M30) + w_s90 × ln(1 + spend_90/M90) + w_ticket × ln(1 + avg_ticket_90/T0) + w_r90 × ln(1 + recharge_90/R90)`
- 全零输入返回 0.0
- _Requirements: 3.1, 3.2, 3.3_
- [x] 2.3 实现 `compute_speed` 静态方法
- 绝对速度 V_abs、相对速度 V_rel仅加速加分、EWMA 速度 V_ewma
- Speed 子分公式:`S = w_abs × V_abs + w_rel × max(0, V_rel) + w_ewma × V_ewma`
- _Requirements: 4.1, 4.2, 4.3, 4.4, 4.5_
- [x] 2.4 实现 `compute_stability` 静态方法
- 周覆盖率:`P = active_weeks_90 / 13`
- 支持 `use_stability=0` 时返回 0.0
- _Requirements: 5.1, 5.2, 5.3, 5.4_
- [x] 2.5 实现 `compute_spi_raw` 静态方法
- 总分公式:`SPI_raw = w_L × L + w_S × S + w_P × P`
- _Requirements: 6.1_
- [x] 2.6 编写属性测试SPI 总分非负性
- **Property 1: SPI 总分非负性**
- **Validates: Requirements 6.1, 10.1**
- [x] 2.7 编写属性测试Level 子分单调性
- **Property 2: Level 子分关于消费金额单调非递减**
- **Validates: Requirements 3.1, 10.2**
- [x] 2.8 编写属性测试Speed 子分单调性
- **Property 3: Speed 子分关于 spend_30 单调非递减**
- **Validates: Requirements 4.1, 4.4, 10.3**
- [x] 2.9 编写属性测试Stability 子分范围
- **Property 4: Stability 子分取值范围 [0, 1]**
- **Validates: Requirements 5.2, 5.4, 10.4**
- [x] 2.10 编写属性测试Display Score 范围
- **Property 5: Display Score 取值范围 [0, 10]**
- **Validates: Requirements 6.6, 10.5**
- [x] 3. 检查点 - 确保核心算法测试通过
- 运行 `cd C:\NeoZQYY && pytest tests/test_spi_properties.py -v`
- 确保所有属性测试通过,如有问题请询问用户。
- [x] 4. 实现数据提取与执行流程
- [x] 4.1 实现 `_extract_spending_features` 方法
-`dwd.dwd_settlement_head` 提取近 90 天消费订单,聚合为会员级特征
- 计算 spend_30/90、orders_30/90、visit_days_30/90、avg_ticket_90、active_weeks_90
- _Requirements: 2.1, 2.3, 2.4, 2.5_
- [x] 4.2 实现 `_extract_recharge_features` 方法
-`dwd.dwd_recharge_order` 提取近 90 天充值订单
- _Requirements: 2.2_
- [x] 4.3 实现 `_compute_daily_spend_ewma` 方法
- 对近 90 天日消费序列计算 EWMA
- _Requirements: 2.6_
- [x] 4.4 实现 `_calibrate_amount_bases` 方法
- 从门店数据计算中位数作为金额压缩基数校准值
- 配置表优先级高于自动校准值
- 日志输出实际使用的基数值
- _Requirements: 8.1, 8.2, 8.3, 8.4_
- [x] 4.5 实现 `execute` 方法(完整执行流程)
- 获取 site_id → 加载参数 → 提取特征 → 校准基数 → 计算子分 → 合成总分 → 归一化展示分 → 持久化
- delete-before-insert 策略
- 无数据时返回 skipped
- 保存分位点历史
- _Requirements: 6.2, 6.3, 6.4, 6.5, 6.6, 9.3, 9.4, 9.5_
- [x] 4.6 实现 `_save_spi_data` 方法
- 批量 INSERT 到 dws_member_spending_power_index
- _Requirements: 1.1_
- [x] 5. 任务注册与模块导出
- [x] 5.1 在 `tasks/dws/index/__init__.py` 中导出 `SpendingPowerIndexTask`
- 添加 import 和 __all__ 条目
- _Requirements: 9.1_
- [x] 5.2 在 `tasks/dws/__init__.py` 中导出 `SpendingPowerIndexTask`
- 添加 import 和 __all__ 条目
- _Requirements: 9.1_
- [x] 5.3 在 `orchestration/task_registry.py` 中注册 SPI 任务
- `default_registry.register("DWS_SPENDING_POWER_INDEX", SpendingPowerIndexTask, requires_db_config=False, layer="INDEX", depends_on=["DWS_MEMBER_CONSUMPTION"])`
- _Requirements: 9.1, 9.2_
- [-] 6. 配置种子数据
- [x] 6.1 在 `db/etl_feiqiu/seeds/seed_index_parameters.sql` 中追加 SPI 参数
- 插入 `index_type='SPI'` 的全部参数行(窗口、基数、权重、映射、稳定性)
- 金额压缩基数使用合理初始默认值
- _Requirements: 7.1, 7.4, 8.5_
- [~] 6.2 在测试库执行种子数据脚本
- 通过 TEST_DB_DSN 连接测试库执行 INSERT
- _Requirements: 7.1_
- [~] 7. 检查点 - 确保单元测试和集成验证通过
- 运行 `cd apps/etl/connectors/feiqiu && pytest tests/unit/test_spi_task.py -v`
- 确保所有测试通过,如有问题请询问用户。
- [ ] 8. 文档更新
- [~] 8.1 编写数据库手册 `docs/database/BD_Manual_dws_member_spending_power_index.md`
- 包含表结构、字段说明、索引、验证 SQL至少 3 条)、兼容性说明、回滚策略
- _Requirements: 11.1_
- [~] 8.2 更新 ETL 任务文档 `apps/etl/connectors/feiqiu/docs/etl_tasks/index_tasks.md`
- 新增 DWS_SPENDING_POWER_INDEX 章节,包含算法公式、参数清单、数据来源、计算流程
- 更新概述表格和继承体系图
- _Requirements: 11.2, 11.3_
- [~] 9. 最终检查点 - 确保所有测试通过
- 运行属性测试:`cd C:\NeoZQYY && pytest tests/test_spi_properties.py -v`
- 运行单元测试:`cd apps/etl/connectors/feiqiu && pytest tests/unit/test_spi_task.py -v`
- 确保所有测试通过,如有问题请询问用户。
## 备注
- 标记 `*` 的子任务为可选(属性测试),可跳过以加速 MVP
- 每个任务引用具体需求编号以确保可追溯
- 检查点确保增量验证
- 属性测试验证全称正确性属性,单元测试验证具体示例和边界情况