14 KiB
指数算法说明(代码对齐版)
本文根据当前代码实现整理,包含老客挽回指数(WBI)、新客转化指数(NCI)与关系指数(RS/OS/MS/ML)的计算流程、参数含义、归一化逻辑与用途说明。 如需业务版本(非代码版)说明,请另行补充。
0. 版本更新(2026-02-08)
- 关系指数从旧
INTIMACY切换为单任务RelationIndexTask,统一产出RS/OS/MS/ML。 ML口径调整为人工台账唯一真源(dws_ml_manual_order_alloc)。dwd_recharge_order的 last-touch 仅保留备用路径,默认关闭(ML.source_mode=0)。BaseIndexTask已支持按index_type隔离参数缓存与分位平滑历史,避免单任务串参。
1. 通用约定
- 时间口径
- 以
datetime.now(self.tz)为"当前时间"基准。 - 窗口仅回溯 近 60 天(
lookback_days)。
- 天数截断
- 所有"天数差"在参与衰减或间隔计算时,都会被截断到
<= lookback_days(默认 60 天)。
- 半衰期衰减
decay(d; h) = exp(-ln(2) * d / h)
d为距今天数,h为半衰期(天)。d=0时权重 1.0,d=h时权重 0.5。
- 0–10 映射(Raw → Display)
- 取全体 Raw 分数,计算
P5/P95。 - 对 Raw 进行 Winsorize 截断到
[P5, P95]。 - 可选压缩:
none / log1p / asinh。 - MinMax 映射到
[0, 10]。 - 若范围过小(分母 < 1e-6),直接返回 5.0。
- 最终展示分数保留两位小数。
- 分位点平滑(可选)
- 若
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)
4.0 作用/业务场景
- 衡量客户与助教的关系强度与“近期温度”。
- 用于助教约课精力分配、客户-助教匹配与成功率预估等排序参考。
- 结果以 0–10 展示分提供横向比较。
4.1 数据来源与口径
- 服务记录:
billiards_dwd.dwd_assistant_service_log条件:site_id、tenant_member_id > 0、is_delete = 0、user_id > 0时间口径:last_use_time在近lookback_days天内 - 助教维度:
billiards_dwd.dim_assistant通过user_id关联获取assistant_id(scd2_is_current=1) - 充值记录:
billiards_dwd.dwd_recharge_order条件:settle_type = 5且pay_time >= now - lookback_days - 计算粒度为
(member_id, assistant_id)
4.2 会话合并
以 (member_id, assistant_id) 分组,按 start_use_time 排序:
- 间隔 ≤ session_merge_hours(默认 4 小时)视为同一会话
- 合并后:
session_end取最大结束时间duration累加course_weight取最大值(附加课权重更高)is_incentive取 OR
- 课型权重:
BONUS:incentive_weight(默认 1.5)- 其他:权重 1.0
4.3 归因充值
从 dwd_recharge_order 取近 lookback_days 天充值记录(settle_type=5):
- 若充值发生在某会话结束后的 recharge_attribute_hours(默认 1 小时)内,归因为该助教
- 单笔充值在该
(member_id, assistant_id)对内只计一次
4.4 分项得分
所有 days_ago 均截断到 <= lookback_days。
F:频次强度
F = Σ( τ_i * decay(days_ago_i; h_sess) )
R:最近温度
R = decay(min(d_last, lookback_days); h_last)
M:归因充值强度
M = Σ( ln(1 + amt/A0) * decay(min(days_ago, lookback_days); h_pay) )
D:时长贡献
D = Σ( sqrt(dur_hours) * τ_i * decay(days_ago_i; h_sess) )
burst:频率激增放大
F_short = Σ( τ_i * decay(days_ago_i; h_short) )
F_long = Σ( τ_i * decay(days_ago_i; h_long) )
ratio = F_short / (F_long + 1e-6)
burst = max(0, ln(1 + (ratio - 1)))
mult = 1 + γ * burst
4.5 Raw Score 与 Display Score
INTIMACY_raw = (w_F*F + w_R*R + w_M*M + w_D*D) * mult
Display Score 使用 BaseIndexTask 的分位截断 + 压缩 + MinMax 映射到 0–10,并可选 EWMA 平滑(见第 1/5 节通用说明)。
4.6 输出字段
写入表:billiards_dws.dws_member_assistant_intimacy,主要字段:
- 会话统计:
session_count、total_duration_minutes、basic_session_count、incentive_session_count - 最近与充值:
days_since_last_session、attributed_recharge_count、attributed_recharge_amount - 分项得分:
score_frequency、score_recency、score_recharge、score_duration、burst_multiplier - 汇总:
raw_score、display_score
4.7 INTIMACY 默认参数
| 参数 | 默认值 | 含义 |
|---|---|---|
lookback_days |
60 | 回看窗口(天) |
session_merge_hours |
4 | 会话合并间隔(小时) |
recharge_attribute_hours |
1 | 充值归因窗口(小时) |
amount_base |
500 | 充值强度压缩基数 |
incentive_weight |
1.5 | 附加课权重 |
halflife_session |
14 | 会话衰减半衰期 |
halflife_last |
10 | 最近服务衰减半衰期 |
halflife_recharge |
21 | 充值衰减半衰期 |
halflife_short |
7 | 短期频次半衰期 |
halflife_long |
30 | 长期频次半衰期 |
weight_frequency |
2.0 | F 权重 |
weight_recency |
1.5 | R 权重 |
weight_recharge |
2.0 | M 权重 |
weight_duration |
0.5 | D 权重 |
burst_gamma |
0.6 | 激增放大系数 |
percentile_lower |
5 | 下分位(P5) |
percentile_upper |
95 | 上分位(P95) |
compression_mode |
1 | 压缩方式(1=log1p) |
use_smoothing |
1 | 是否启用 EWMA |
ewma_alpha |
0.2 | 分位平滑系数 |
5. 映射与参数配置
5.1 映射流程
- 计算 Raw Score
- 计算 P5/P95
- Winsorize 截断
- 可选压缩(
none/log1p/asinh) - MinMax →
[0, 10] - 可选 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 - INTIMACY 关键参数:
halflife_session/last/recharge/short/long、amount_base、incentive_weight、weight_*、burst_gamma - 通用参数:
percentile_lower/upper、compression_mode、use_smoothing、ewma_alpha
compression_mode 取值:
0:不压缩1:log1p2:asinh
5.3 参数优先级
- 先用代码默认参数(
DEFAULT_PARAMS) - 再用数据库参数覆盖(
cfg_index_parameters,取effective_from <= CURRENT_DATE且未过期,同名参数取最近生效的一条) - GUI/环境变量可通过
run.index_lookback_days覆盖 recency 窗口
即:GUI/环境变量 > DB > 代码默认值。
6. 运行与覆盖策略
- WBI/NCI:默认"每 2 小时"计算(由任务描述定义)
- INTIMACY:默认"每 4 小时"计算(由任务描述定义)
- 写入方式:对本次参与计算的实体进行 delete-before-insert 覆盖写入 (不在窗口内的实体不会被重算)