init: 项目初始提交 - NeoZQYY Monorepo 完整代码
This commit is contained in:
35
apps/etl/pipelines/feiqiu/docs/business-rules/README.md
Normal file
35
apps/etl/pipelines/feiqiu/docs/business-rules/README.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# docs/business-rules/ — 业务规则文档
|
||||
|
||||
存放指数算法、DWS 口径定义、SCD2 处理规则、薪酬计算等业务逻辑文档。
|
||||
与 `docs/database/` 中的表结构文档分离,便于业务侧查阅和维护。
|
||||
|
||||
## 文档索引
|
||||
|
||||
### 指数算法
|
||||
|
||||
| 文档 | 说明 |
|
||||
|------|------|
|
||||
| [index_algorithm_cn.md](index_algorithm_cn.md) | 指数算法说明(WBI/NCI/RS/OS/MS/ML)— 计算流程、参数、归一化与用途 |
|
||||
|
||||
### DWS 口径定义
|
||||
|
||||
| 文档 | 说明 |
|
||||
|------|------|
|
||||
| [dws_metrics.md](dws_metrics.md) | DWS 汇总层各指标的业务口径与计算规则(骨架) |
|
||||
|
||||
### SCD2 处理规则
|
||||
|
||||
| 文档 | 说明 |
|
||||
|------|------|
|
||||
| [scd2_rules.md](scd2_rules.md) | 维度表 SCD2 缓慢变化维处理策略与生效区间规则(骨架) |
|
||||
|
||||
### 薪酬计算规则
|
||||
|
||||
| 文档 | 说明 |
|
||||
|------|------|
|
||||
| *(待补充)* | 助教薪酬计算逻辑、提成规则与结算周期 |
|
||||
|
||||
## 维护约定
|
||||
|
||||
- 业务口径变更时,同步更新对应文档
|
||||
- 文档统一 UTF-8 编码,中文撰写
|
||||
227
apps/etl/pipelines/feiqiu/docs/business-rules/dws_metrics.md
Normal file
227
apps/etl/pipelines/feiqiu/docs/business-rules/dws_metrics.md
Normal file
@@ -0,0 +1,227 @@
|
||||
# DWS 汇总层口径定义
|
||||
|
||||
本文档定义 `billiards_dws` 模式下各汇总指标的业务口径、计算规则和数据来源。
|
||||
所有指标均基于 DWD 明细层数据聚合生成。
|
||||
|
||||
> **状态**:骨架文档,各章节待补充具体计算公式与字段映射。
|
||||
|
||||
---
|
||||
|
||||
## 1. 助教业绩
|
||||
|
||||
### 1.1 助教日报(dws_assistant_daily_detail)
|
||||
|
||||
<!-- 待补充:日维度助教业绩指标定义,包括订单数、服务时长、收入等 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_assistant_daily_detail`
|
||||
- 数据来源:DWD 订单事实表、助教维度表
|
||||
- 粒度:门店 × 助教 × 日期
|
||||
- 核心指标:*(待定义)*
|
||||
|
||||
### 1.2 助教月报(dws_assistant_monthly_summary)
|
||||
|
||||
<!-- 待补充:月维度助教业绩汇总指标 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_assistant_monthly_summary`
|
||||
- 数据来源:助教日报聚合
|
||||
- 粒度:门店 × 助教 × 年月
|
||||
- 核心指标:*(待定义)*
|
||||
|
||||
### 1.3 助教客户统计(dws_assistant_customer_stats)
|
||||
|
||||
<!-- 待补充:助教服务客户维度的统计指标 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_assistant_customer_stats`
|
||||
- 数据来源:DWD 订单事实表、会员维度表
|
||||
- 粒度:门店 × 助教 × 会员
|
||||
- 核心指标:*(待定义)*
|
||||
|
||||
### 1.4 助教财务分析(dws_assistant_finance_analysis)
|
||||
|
||||
<!-- 待补充:助教维度的财务分析指标 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_assistant_finance_analysis`
|
||||
- 数据来源:DWD 支付/退款事实表
|
||||
- 粒度:门店 × 助教 × 日期
|
||||
- 核心指标:*(待定义)*
|
||||
|
||||
---
|
||||
|
||||
## 2. 薪酬计算
|
||||
|
||||
### 2.1 助教薪酬(dws_assistant_salary_calc)
|
||||
|
||||
<!-- 待补充:薪酬计算规则、提成比例、结算周期 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_assistant_salary_calc`
|
||||
- 数据来源:助教日报/月报、充值提成
|
||||
- 粒度:门店 × 助教 × 结算周期
|
||||
- 核心指标:*(待定义)*
|
||||
|
||||
### 2.2 充值提成(dws_assistant_recharge_commission)
|
||||
|
||||
<!-- 待补充:充值提成计算规则 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_assistant_recharge_commission`
|
||||
- 数据来源:DWD 充值事实表
|
||||
- 粒度:门店 × 助教 × 日期
|
||||
- 核心指标:*(待定义)*
|
||||
|
||||
---
|
||||
|
||||
## 3. 财务日报
|
||||
|
||||
### 3.1 财务日报汇总(dws_finance_daily_summary)
|
||||
|
||||
<!-- 待补充:每日财务汇总口径,含收入、支出、利润等 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_finance_daily_summary`
|
||||
- 数据来源:DWD 支付/退款/订单事实表
|
||||
- 粒度:门店 × 日期
|
||||
- 核心指标:*(待定义)*
|
||||
|
||||
### 3.2 收入结构(dws_finance_income_structure)
|
||||
|
||||
<!-- 待补充:收入按来源/类型的分类口径 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_finance_income_structure`
|
||||
- 数据来源:DWD 支付事实表
|
||||
- 粒度:门店 × 日期 × 收入类型
|
||||
- 核心指标:*(待定义)*
|
||||
|
||||
### 3.3 折扣明细(dws_finance_discount_detail)
|
||||
|
||||
<!-- 待补充:折扣/优惠统计口径 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_finance_discount_detail`
|
||||
- 数据来源:DWD 订单事实表
|
||||
- 粒度:门店 × 日期
|
||||
- 核心指标:*(待定义)*
|
||||
|
||||
### 3.4 充值汇总(dws_finance_recharge_summary)
|
||||
|
||||
<!-- 待补充:充值金额、笔数等汇总口径 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_finance_recharge_summary`
|
||||
- 数据来源:DWD 充值事实表
|
||||
- 粒度:门店 × 日期
|
||||
- 核心指标:*(待定义)*
|
||||
|
||||
### 3.5 支出汇总(dws_finance_expense_summary)
|
||||
|
||||
<!-- 待补充:支出分类汇总口径 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_finance_expense_summary`
|
||||
- 数据来源:DWD 支出事实表
|
||||
- 粒度:门店 × 日期
|
||||
- 核心指标:*(待定义)*
|
||||
|
||||
### 3.6 平台结算(dws_platform_settlement)
|
||||
|
||||
<!-- 待补充:第三方平台(团购等)结算口径 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_platform_settlement`
|
||||
- 数据来源:DWD 团购/支付事实表
|
||||
- 粒度:门店 × 日期
|
||||
- 核心指标:*(待定义)*
|
||||
|
||||
---
|
||||
|
||||
## 4. 会员分析
|
||||
|
||||
### 4.1 会员消费汇总(dws_member_consumption_summary)
|
||||
|
||||
<!-- 待补充:会员消费行为汇总口径 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_member_consumption_summary`
|
||||
- 数据来源:DWD 订单/支付事实表、会员维度表
|
||||
- 粒度:门店 × 会员
|
||||
- 核心指标:*(待定义)*
|
||||
|
||||
### 4.2 会员到访明细(dws_member_visit_detail)
|
||||
|
||||
<!-- 待补充:会员到访频次、时段分布等口径 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_member_visit_detail`
|
||||
- 数据来源:DWD 订单事实表
|
||||
- 粒度:门店 × 会员 × 日期
|
||||
- 核心指标:*(待定义)*
|
||||
|
||||
---
|
||||
|
||||
## 5. 订单汇总
|
||||
|
||||
### 5.1 订单汇总宽表(dws_order_summary)
|
||||
|
||||
<!-- 待补充:订单维度的汇总宽表口径 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_order_summary`
|
||||
- 数据来源:DWD 订单/支付/退款事实表
|
||||
- 粒度:门店 × 结账单
|
||||
- 核心指标:*(待定义)*
|
||||
|
||||
---
|
||||
|
||||
## 6. 自定义指数算法
|
||||
|
||||
指数算法的详细计算流程、参数与归一化方法请参阅 [index_algorithm_cn.md](index_algorithm_cn.md)。
|
||||
|
||||
以下为各指数对应的汇总表概览:
|
||||
|
||||
### 6.1 会员召回指数 — WBI(dws_member_recall_index)
|
||||
|
||||
<!-- 待补充:WBI 指数的业务口径与触发条件 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_member_recall_index`
|
||||
- 粒度:门店 × 会员
|
||||
|
||||
### 6.2 新客转化指数 — NCI(dws_member_newconv_index)
|
||||
|
||||
<!-- 待补充:NCI 指数的业务口径与评分规则 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_member_newconv_index`
|
||||
- 粒度:门店 × 会员
|
||||
|
||||
### 6.3 关系指数 — RS(dws_member_assistant_relation_index)
|
||||
|
||||
<!-- 待补充:RS 指数的业务口径与亲密度计算 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_member_assistant_relation_index`
|
||||
- 粒度:门店 × 会员 × 助教
|
||||
|
||||
### 6.4 助教-会员亲密度(dws_member_assistant_intimacy)
|
||||
|
||||
<!-- 待补充:亲密度评分口径 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_member_assistant_intimacy`
|
||||
- 粒度:门店 × 会员 × 助教
|
||||
|
||||
### 6.5 回流指数 — OS(dws_member_winback_index)
|
||||
|
||||
<!-- 待补充:OS 指数的业务口径与回流判定规则 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_member_winback_index`
|
||||
- 粒度:门店 × 会员
|
||||
|
||||
### 6.6 人工台账 — ML(dws_ml_manual_order_source / dws_ml_manual_order_alloc)
|
||||
|
||||
<!-- 待补充:ML 人工台账的业务口径与分配规则 -->
|
||||
|
||||
- 宽表:`billiards_dws.dws_ml_manual_order_source`
|
||||
- 窄表:`billiards_dws.dws_ml_manual_order_alloc`
|
||||
- 粒度:门店 × 订单 × 助教
|
||||
|
||||
### 6.7 指数百分位历史(dws_index_percentile_history)
|
||||
|
||||
<!-- 待补充:指数百分位归一化的历史快照口径 -->
|
||||
|
||||
- 目标表:`billiards_dws.dws_index_percentile_history`
|
||||
- 粒度:门店 × 指数类型 × 日期
|
||||
|
||||
---
|
||||
|
||||
## 维护约定
|
||||
|
||||
- 新增或修改 DWS 指标时,须同步更新本文档对应章节
|
||||
- 计算公式应包含:输入字段、聚合方式、过滤条件、精度/舍入规则
|
||||
- 金额字段统一 `NUMERIC(12,2)`,货币单位人民币(CNY)
|
||||
@@ -0,0 +1,289 @@
|
||||
<!-- AI_CHANGELOG [2026-02-13] 移除 §4 INTIMACY 整节;更新版本历史;替换 §5.2/§6 中 INTIMACY 引用 -->
|
||||
# 指数算法说明(代码对齐版)
|
||||
|
||||
本文根据当前代码实现整理,包含老客挽回指数(WBI)、新客转化指数(NCI)与关系指数(RS/OS/MS/ML)的计算流程、参数含义、归一化逻辑与用途说明。
|
||||
如需业务版本(非代码版)说明,请另行补充。
|
||||
|
||||
## 0. 版本更新
|
||||
|
||||
### 2026-02-13
|
||||
1. 移除旧版 `RecallIndexTask`(已由 WBI+NCI 替代)和 `IntimacyIndexTask`(已由 RelationIndexTask 替代)。
|
||||
2. `ML` 移除 last-touch 备用路径(`source_mode` / `recharge_attribute_hours`),仅保留人工台账唯一真源。
|
||||
3. WBI 修复 `STOP_HIGH_BALANCE` 会员不参与评分的问题。
|
||||
|
||||
### 2026-02-08
|
||||
1. 关系指数从旧 `INTIMACY` 切换为单任务 `RelationIndexTask`,统一产出 `RS/OS/MS/ML`。
|
||||
2. `ML` 口径调整为人工台账唯一真源(`dws_ml_manual_order_alloc`)。
|
||||
3. `BaseIndexTask` 已支持按 `index_type` 隔离参数缓存与分位平滑历史,避免单任务串参。
|
||||
|
||||
## 1. 通用约定
|
||||
|
||||
1) **时间口径**
|
||||
- 以 `datetime.now(self.tz)` 为"当前时间"基准。
|
||||
- 窗口仅回溯 **近 60 天**(`lookback_days`)。
|
||||
|
||||
2) **天数截断**
|
||||
- 所有"天数差"在参与衰减或间隔计算时,都会被截断到 `<= lookback_days`(默认 60 天)。
|
||||
|
||||
3) **半衰期衰减**
|
||||
```
|
||||
decay(d; h) = exp(-ln(2) * d / h)
|
||||
```
|
||||
- `d` 为距今天数,`h` 为半衰期(天)。
|
||||
- `d=0` 时权重 1.0,`d=h` 时权重 0.5。
|
||||
|
||||
4) **0–10 映射(Raw → Display)**
|
||||
- 取全体 Raw 分数,计算 `P5/P95`。
|
||||
- 对 Raw 进行 **Winsorize** 截断到 `[P5, P95]`。
|
||||
- 可选压缩:`none / log1p / asinh`。
|
||||
- MinMax 映射到 `[0, 10]`。
|
||||
- 若范围过小(分母 < 1e-6),直接返回 5.0。
|
||||
- 最终展示分数保留两位小数。
|
||||
|
||||
5) **分位点平滑(可选)**
|
||||
- 若 `use_smoothing=1` 且存在历史分位点:
|
||||
`Q_t = (1-α) * Q_{t-1} + α * Q_now`
|
||||
- `α` 来自参数 `ewma_alpha`(默认 0.2)。
|
||||
|
||||
> 以上逻辑由 `BaseIndexTask` 提供。
|
||||
|
||||
---
|
||||
|
||||
## 2. 老客挽回指数(WBI)
|
||||
|
||||
### 2.0 作用/业务场景
|
||||
|
||||
- 识别需要重点"唤回"的老客,并给出可排序的优先级分数。
|
||||
- 综合超期、降频、充值未回访与价值信号,衡量"召回紧迫度 + 价值潜力"。
|
||||
- 结果通常用于运营触达/回访任务优先级与名单筛选。
|
||||
|
||||
### 2.1 数据来源与口径
|
||||
|
||||
- **到店记录**:`billiards_dwd.dwd_settlement_head`
|
||||
条件:`site_id`、`member_id > 0`、`settle_type=1`
|
||||
或 `settle_type=3` 且关联 `dwd_assistant_service_log` 中 **附加课/奖励课(BONUS)**。
|
||||
使用 `pay_time` 作为到店/服务结束时间(按天去重)。
|
||||
- **充值记录**:`billiards_dwd.dwd_recharge_order`
|
||||
条件:`site_id`、`member_id > 0`、`settle_type=5`,取最近充值时间(回溯 60 天)。
|
||||
- **会员档案**:`billiards_dwd.dim_member.create_time`
|
||||
- **储值卡余额**:`billiards_dwd.dim_member_card_account.balance`
|
||||
口径:现金储值卡 `card_type_id=2793249295533893`。
|
||||
|
||||
> 计算窗口:到店历史取近 180 天;recency 按 60 天封顶。
|
||||
|
||||
### 2.2 特征与分流
|
||||
|
||||
- `t_v = min(lookback_days_recency, days_since_last_visit)`
|
||||
- `t_r = min(lookback_days_recency, days_since_last_recharge)`
|
||||
- `t_a = min(t_v, t_r)`
|
||||
- `visits_14d / visits_60d / visits_total(近 180 天)`
|
||||
- `spend_30d / spend_180d`:按 `pay_amount`(实付)汇总
|
||||
- 到店间隔:按天计算并封顶到 `lookback_days_recency`;同时记录间隔的"距今年龄"用于加权 CDF
|
||||
- `recharge_unconsumed`:最近一次充值晚于最近一次到店(或无到店)时为 1
|
||||
|
||||
**分流规则:**
|
||||
- STOP:`t_a >= lookback_days_recency`(默认不写入;高余额例外可选)
|
||||
- STOP_HIGH_BALANCE:当 `enable_stop_high_balance_exception=1` 且 `sv_balance >= high_balance_threshold` 时,仍进入 WBI 计算
|
||||
- NEW:`visits_total <= new_visit_threshold`
|
||||
或 `days_since_first_visit <= new_days_threshold`
|
||||
或 `recharge_unconsumed=1` 且 `days_since_last_recharge <= recharge_recent_days`
|
||||
- OLD:非 STOP 且非 NEW
|
||||
|
||||
### 2.3 分项得分
|
||||
|
||||
**Overdue(个人周期超期分)**
|
||||
基于加权经验 CDF:
|
||||
```
|
||||
p = weighted_cdf(intervals, t_v, halflife_days, blend_min_samples)
|
||||
overdue = p ^ alpha
|
||||
```
|
||||
- 加权 CDF 使用半衰期对历史间隔加权,近期间隔权重更高
|
||||
- 若无历史间隔数据,`p = 0.5`
|
||||
- 同时计算理想回访间隔(加权中位数),用于推算理想下次到店日期
|
||||
|
||||
**Drop(近期降频)**
|
||||
```
|
||||
expected14 = visits_60d * 14/60
|
||||
drop = clip((expected14 - visits_14d) / (expected14 + 1), 0, 1)
|
||||
```
|
||||
|
||||
**Recharge(充值未回访压力)**
|
||||
```
|
||||
recharge = decay(t_r; h_recharge) if recharge_unconsumed=1 else 0
|
||||
```
|
||||
|
||||
**Value(价值)**
|
||||
```
|
||||
S_spend = ln(1 + spend_180d / M0)
|
||||
S_bal = ln(1 + sv_balance / B0)
|
||||
value = w_spend * S_spend + w_bal * S_bal
|
||||
```
|
||||
|
||||
### 2.4 Raw Score
|
||||
|
||||
```
|
||||
WBI_raw = w_over * overdue
|
||||
+ w_drop * drop
|
||||
+ w_re * recharge
|
||||
+ w_value * value
|
||||
```
|
||||
|
||||
**Recency suppression(近访抑制):**
|
||||
```
|
||||
suppression = sigmoid((t_v - recency_gate_days) / recency_gate_slope_days)
|
||||
WBI_raw = WBI_raw * suppression
|
||||
```
|
||||
- Hard floor(硬门槛):
|
||||
```
|
||||
if t_v < recency_hard_floor_days: suppression = 0
|
||||
```
|
||||
- 默认:`recency_gate_days=14`,`recency_gate_slope_days=3`
|
||||
- 默认:`recency_hard_floor_days=14`
|
||||
- 当 `recency_gate_slope_days <= 0` 时,退化为硬门槛:`t_v < recency_gate_days => suppression=0`
|
||||
- 限制在 0 以上
|
||||
|
||||
### 2.5 输出表
|
||||
|
||||
`billiards_dws.dws_member_winback_index`
|
||||
|
||||
### 2.6 WBI 默认参数
|
||||
|
||||
| 参数 | 默认值 | 含义 |
|
||||
|---|---:|---|
|
||||
| `lookback_days_recency` | 60 | recency 窗口(天) |
|
||||
| `visit_lookback_days` | 180 | 到店历史窗口(天) |
|
||||
| `overdue_alpha` | 2.0 | 超期分幂次 |
|
||||
| `overdue_weight_halflife_days` | 30 | 加权 CDF 半衰期 |
|
||||
| `overdue_weight_blend_min_samples` | 8 | 加权/等权混合最小样本 |
|
||||
| `h_recharge` | 7 | 充值衰减半衰期 |
|
||||
| `amount_base_M0` | 300 | 消费压缩基数 |
|
||||
| `balance_base_B0` | 500 | 余额压缩基数 |
|
||||
| `w_over` | 2.0 | 超期分权重 |
|
||||
| `w_drop` | 1.0 | 降频分权重 |
|
||||
| `w_re` | 0.4 | 充值分权重 |
|
||||
| `w_value` | 1.2 | 价值分权重 |
|
||||
| `recency_gate_days` | 14 | 近访抑制门槛 |
|
||||
| `recency_gate_slope_days` | 3 | 近访抑制斜率 |
|
||||
| `recency_hard_floor_days` | 14 | 硬门槛天数 |
|
||||
| `new_visit_threshold` | 2 | 新客到店次数阈值 |
|
||||
| `new_days_threshold` | 30 | 新客建档天数阈值 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 新客转化指数(NCI)
|
||||
|
||||
### 3.0 作用/业务场景
|
||||
|
||||
- 识别新客的"欢迎建联"与"转化召回"优先级。
|
||||
- 兼顾首访后快速触达与二访转化窗口,避免对近期活跃新客过度打扰。
|
||||
- 结果通常用于新客欢迎、转化跟进与触达节奏排序。
|
||||
|
||||
### 3.1 数据来源与口径
|
||||
|
||||
- 使用 `MemberIndexBaseTask` 的共享口径,与 WBI 完全一致(到店/充值/会员档案/余额、`t_v/t_r/t_a`、`visits_*`、`spend_*`、`recharge_unconsumed` 等)。
|
||||
- 适用对象:仅 NEW 分群(分流规则见 2.2)。
|
||||
|
||||
### 3.2 关键分项
|
||||
|
||||
**Need(转化紧迫度)**
|
||||
```
|
||||
t2_max = 2 * t2_target_days
|
||||
Need = clip((t_v - no_touch_days_new) / (t2_max - no_touch_days_new), 0, 1)
|
||||
```
|
||||
|
||||
**Salvage(可救度)**
|
||||
```
|
||||
if t_a <= salvage_start: 1
|
||||
elif t_a >= salvage_end: 0
|
||||
else: (salvage_end - t_a) / (salvage_end - salvage_start)
|
||||
```
|
||||
|
||||
**Recharge(充值未回访压力)** 同 WBI
|
||||
**Value(价值)** 同 WBI(权重可不同)
|
||||
|
||||
### 3.3 Raw Score(含欢迎建联与活跃抑制)
|
||||
|
||||
新增逻辑:
|
||||
- `Welcome`:仅首访/单访新客在 `welcome_window_days` 内触发,越接近当天分越高。
|
||||
- `active_multiplier`:若新客近14天来店次数较高且最近仍活跃,则用 `active_new_penalty` 抑制转化召回分。
|
||||
- `touch_multiplier`:`t_v` 未达到 `no_touch_days_new` 前,`Recharge/Value` 贡献按比例衰减,减少"刚来过就高分"。
|
||||
|
||||
```
|
||||
NCI_raw = w_welcome * Welcome
|
||||
+ active_multiplier * (
|
||||
w_need * (Need * Salvage)
|
||||
+ w_re * Recharge * touch_multiplier
|
||||
+ w_value * Value * touch_multiplier
|
||||
)
|
||||
```
|
||||
|
||||
NCI 额外提供三个维度的展示分:`display_score`(总分)、`display_score_welcome`(欢迎分)、`display_score_convert`(转化分)。
|
||||
|
||||
### 3.4 输出表
|
||||
|
||||
`billiards_dws.dws_member_newconv_index`
|
||||
|
||||
### 3.5 NCI 默认参数
|
||||
|
||||
| 参数 | 默认值 | 含义 |
|
||||
|---|---:|---|
|
||||
| `no_touch_days_new` | 3 | 免打扰天数 |
|
||||
| `t2_target_days` | 7 | 目标回访天数 |
|
||||
| `salvage_start` | 30 | 可救度开始衰减天数 |
|
||||
| `salvage_end` | 60 | 可救度归零天数 |
|
||||
| `welcome_window_days` | 3 | 欢迎窗口(天) |
|
||||
| `active_new_visit_threshold_14d` | 2 | 活跃抑制到店阈值 |
|
||||
| `active_new_recency_days` | 7 | 活跃抑制近期天数 |
|
||||
| `active_new_penalty` | 0.2 | 活跃抑制系数 |
|
||||
| `w_welcome` | 1.0 | 欢迎分权重 |
|
||||
| `w_need` | 1.6 | 紧迫度权重 |
|
||||
| `w_re` | 0.8 | 充值分权重 |
|
||||
| `w_value` | 1.0 | 价值分权重 |
|
||||
|
||||
---
|
||||
|
||||
> **注意**:旧版第 4 节「亲密指数(INTIMACY)」已于 2026-02-13 移除,功能由 `RelationIndexTask`(RS/OS/MS/ML)替代。
|
||||
|
||||
## 5. 映射与参数配置
|
||||
|
||||
### 5.1 映射流程
|
||||
|
||||
1) 计算 Raw Score
|
||||
2) 计算 P5/P95
|
||||
3) Winsorize 截断
|
||||
4) 可选压缩(`none/log1p/asinh`)
|
||||
5) MinMax → `[0, 10]`
|
||||
6) 可选 EWMA 平滑(`use_smoothing` + `ewma_alpha`)
|
||||
|
||||
### 5.2 参数来源
|
||||
|
||||
参数来自 `billiards_dws.cfg_index_parameters`,按 `index_type` 加载,默认值见代码:
|
||||
- **WBI 关键参数**:`lookback_days_recency`、`overdue_alpha`、`overdue_weight_halflife_days`、`h_recharge`、`w_over/w_drop/w_re/w_value`
|
||||
- **NCI 关键参数**:`no_touch_days_new`、`t2_target_days`、`salvage_start/end`、`w_welcome/w_need/w_re/w_value`
|
||||
- **RS 关键参数**:`lookback_days`、`halflife_session/last`、`weight_f/weight_d`、`gate_alpha`
|
||||
- **OS 关键参数**:`min_rs_raw_for_ownership`、`ownership_main_threshold/comanage_threshold/gap_threshold`
|
||||
- **MS 关键参数**:`halflife_short/long`
|
||||
- **ML 关键参数**:`amount_base`、`halflife_recharge`
|
||||
- **通用参数**:`percentile_lower/upper`、`compression_mode`、`use_smoothing`、`ewma_alpha`
|
||||
|
||||
`compression_mode` 取值:
|
||||
- `0`:不压缩
|
||||
- `1`:log1p
|
||||
- `2`:asinh
|
||||
|
||||
### 5.3 参数优先级
|
||||
|
||||
- 先用代码默认参数(`DEFAULT_PARAMS`)
|
||||
- 再用数据库参数覆盖(`cfg_index_parameters`,取 `effective_from <= CURRENT_DATE` 且未过期,同名参数取最近生效的一条)
|
||||
- GUI/环境变量可通过 `run.index_lookback_days` 覆盖 recency 窗口
|
||||
|
||||
即:**GUI/环境变量 > DB > 代码默认值**。
|
||||
|
||||
---
|
||||
|
||||
## 6. 运行与覆盖策略
|
||||
|
||||
- WBI/NCI:默认"每 2 小时"计算(由任务描述定义)
|
||||
- RS/OS/MS/ML(RelationIndexTask):默认"每 4 小时"计算(由任务描述定义)
|
||||
- 写入方式:对本次参与计算的实体进行 **delete-before-insert** 覆盖写入
|
||||
(不在窗口内的实体不会被重算)
|
||||
180
apps/etl/pipelines/feiqiu/docs/business-rules/scd2_rules.md
Normal file
180
apps/etl/pipelines/feiqiu/docs/business-rules/scd2_rules.md
Normal file
@@ -0,0 +1,180 @@
|
||||
# SCD2 缓慢变化维处理规则
|
||||
|
||||
本文档定义 `billiards_dwd` 模式下维度表的 SCD2(Slowly Changing Dimension Type 2)处理策略、
|
||||
生效区间管理和版本控制规则。
|
||||
|
||||
> **状态**:骨架文档,各维度表的跟踪字段与变更触发条件待补充。
|
||||
|
||||
---
|
||||
|
||||
## 1. 概述
|
||||
|
||||
### 1.1 什么是 SCD2
|
||||
|
||||
SCD2 通过保留维度记录的历史版本来追踪属性变化。当被跟踪字段发生变更时:
|
||||
1. 关闭当前版本(设置结束时间、标记为非当前)
|
||||
2. 插入新版本(设置开始时间、标记为当前)
|
||||
|
||||
### 1.2 实现模块
|
||||
|
||||
- 处理器:`scd/scd2_handler.py` — `SCD2Handler` 类
|
||||
- 核心方法:`upsert(table_name, natural_key, tracked_fields, record, effective_date)`
|
||||
- 返回值:`INSERT`(新记录)、`UPDATE`(属性变更)、`UNCHANGED`(无变化)
|
||||
|
||||
---
|
||||
|
||||
## 2. SCD2 元数据字段
|
||||
|
||||
所有维度表统一包含以下 SCD2 控制字段:
|
||||
|
||||
| 字段 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `scd2_start_time` | `TIMESTAMPTZ` | `now()` | 版本生效起始时间 |
|
||||
| `scd2_end_time` | `TIMESTAMPTZ` | `'9999-12-31'` | 版本失效时间(`9999-12-31` 表示当前有效) |
|
||||
| `scd2_is_current` | `INT` | `1` | 当前版本标记(`1` = 当前,`0` = 历史) |
|
||||
| `scd2_version` | `INT` | `1` | 版本号(自增) |
|
||||
|
||||
### 约束
|
||||
|
||||
- 主键:`(natural_key, scd2_start_time)` — 同一自然键的不同版本通过生效时间区分
|
||||
- 唯一索引:`WHERE scd2_is_current = 1` — 保证每个自然键只有一条当前记录
|
||||
- 排他约束(GiST):`tstzrange(scd2_start_time, scd2_end_time)` — 防止同一自然键的版本时间段重叠
|
||||
|
||||
---
|
||||
|
||||
## 3. 处理流程
|
||||
|
||||
```
|
||||
收到维度记录
|
||||
│
|
||||
▼
|
||||
按 natural_key 查找 valid_to IS NULL 的当前记录
|
||||
│
|
||||
├── 不存在 → INSERT 新记录(is_current=1, valid_from=now)
|
||||
│
|
||||
└── 存在 → 比较 tracked_fields
|
||||
│
|
||||
├── 无变化 → UNCHANGED(跳过)
|
||||
│
|
||||
└── 有变化 → UPDATE 旧记录(valid_to=now, is_current=0)
|
||||
INSERT 新记录(valid_from=now, is_current=1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 维度表 SCD2 配置
|
||||
|
||||
### 4.1 门店维度(dim_site / dim_site_ex)
|
||||
|
||||
<!-- 待补充:自然键、跟踪字段列表 -->
|
||||
|
||||
- Schema:`billiards_dwd`
|
||||
- 自然键:`site_id`
|
||||
- 跟踪字段:*(待定义)*
|
||||
- 变更触发场景:*(待补充)*
|
||||
|
||||
### 4.2 台桌维度(dim_table / dim_table_ex)
|
||||
|
||||
<!-- 待补充:自然键、跟踪字段列表 -->
|
||||
|
||||
- Schema:`billiards_dwd`
|
||||
- 自然键:`table_id`
|
||||
- 跟踪字段:*(待定义)*
|
||||
- 变更触发场景:*(待补充)*
|
||||
|
||||
### 4.3 助教维度(dim_assistant / dim_assistant_ex)
|
||||
|
||||
<!-- 待补充:自然键、跟踪字段列表 -->
|
||||
|
||||
- Schema:`billiards_dwd`
|
||||
- 自然键:`assistant_id`
|
||||
- 跟踪字段:*(待定义)*
|
||||
- 变更触发场景:*(待补充)*
|
||||
|
||||
### 4.4 会员维度(dim_member / dim_member_ex)
|
||||
|
||||
<!-- 待补充:自然键、跟踪字段列表 -->
|
||||
|
||||
- Schema:`billiards_dwd`
|
||||
- 自然键:`member_id`
|
||||
- 跟踪字段:*(待定义)*
|
||||
- 变更触发场景:*(待补充)*
|
||||
|
||||
### 4.5 会员卡账户维度(dim_member_card_account / dim_member_card_account_ex)
|
||||
|
||||
<!-- 待补充:自然键、跟踪字段列表 -->
|
||||
|
||||
- Schema:`billiards_dwd`
|
||||
- 自然键:`member_card_id`
|
||||
- 跟踪字段:*(待定义)*
|
||||
- 变更触发场景:*(待补充)*
|
||||
|
||||
### 4.6 商品维度(dim_tenant_goods / dim_tenant_goods_ex / dim_store_goods / dim_store_goods_ex)
|
||||
|
||||
<!-- 待补充:自然键、跟踪字段列表 -->
|
||||
|
||||
- Schema:`billiards_dwd`
|
||||
- 自然键:`tenant_goods_id` / `site_goods_id`
|
||||
- 跟踪字段:*(待定义)*
|
||||
- 变更触发场景:*(待补充)*
|
||||
|
||||
### 4.7 商品分类维度(dim_goods_category)
|
||||
|
||||
<!-- 待补充:自然键、跟踪字段列表 -->
|
||||
|
||||
- Schema:`billiards_dwd`
|
||||
- 自然键:`category_id`
|
||||
- 跟踪字段:*(待定义)*
|
||||
- 变更触发场景:*(待补充)*
|
||||
|
||||
### 4.8 团购套餐维度(dim_groupbuy_package / dim_groupbuy_package_ex)
|
||||
|
||||
<!-- 待补充:自然键、跟踪字段列表 -->
|
||||
|
||||
- Schema:`billiards_dwd`
|
||||
- 自然键:`groupbuy_package_id`
|
||||
- 跟踪字段:*(待定义)*
|
||||
- 变更触发场景:*(待补充)*
|
||||
|
||||
---
|
||||
|
||||
## 5. 查询约定
|
||||
|
||||
### 获取当前有效记录
|
||||
|
||||
```sql
|
||||
SELECT * FROM billiards_dwd.dim_member
|
||||
WHERE scd2_is_current = 1;
|
||||
```
|
||||
|
||||
### 获取某时间点的历史快照
|
||||
|
||||
```sql
|
||||
SELECT * FROM billiards_dwd.dim_member
|
||||
WHERE scd2_start_time <= '2025-06-01'
|
||||
AND scd2_end_time > '2025-06-01';
|
||||
```
|
||||
|
||||
### 获取某记录的完整变更历史
|
||||
|
||||
```sql
|
||||
SELECT * FROM billiards_dwd.dim_member
|
||||
WHERE member_id = 12345
|
||||
ORDER BY scd2_start_time;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 注意事项
|
||||
|
||||
- **时区**:`scd2_start_time` / `scd2_end_time` 使用 `TIMESTAMPTZ`,统一以服务器时区存储
|
||||
- **并发安全**:当前实现在单次 ETL 运行内串行处理,未做行级锁;并发写入需额外保护
|
||||
- **删除策略**:维度记录不做物理删除,仅通过关闭版本(`scd2_is_current = 0`)标记失效
|
||||
|
||||
---
|
||||
|
||||
## 维护约定
|
||||
|
||||
- 新增维度表时,须在本文档添加对应章节
|
||||
- 跟踪字段变更时,须同步更新文档并评估历史数据影响
|
||||
- 文档统一 UTF-8 编码,中文撰写
|
||||
Reference in New Issue
Block a user