初始提交:飞球 ETL 系统全量代码

This commit is contained in:
Neo
2026-02-13 08:05:34 +08:00
commit 3c51f5485d
441 changed files with 117631 additions and 0 deletions

View File

@@ -0,0 +1,226 @@
-- =============================================================================
-- 指数算法参数初始化脚本(与数据库现状对齐)
-- 版本: v2.0
-- 创建日期: 2026-02-07
-- 描述: 对齐 RS / OS / MS / ML / NCI / WBI 指数参数快照(兼容保留 RECALL / INTIMACY
-- =============================================================================
-- 清空旧数据(如需重置)
-- DELETE FROM billiards_dws.cfg_index_parameters
-- WHERE index_type IN ('RS', 'OS', 'MS', 'ML', 'NCI', 'WBI', 'RECALL', 'INTIMACY');
INSERT INTO billiards_dws.cfg_index_parameters
(index_type, param_name, param_value, description, effective_from)
VALUES
('INTIMACY', 'amount_base', 500.000000, 'amount compression base', DATE '2026-02-06'),
('INTIMACY', 'burst_gamma', 0.600000, 'burst gamma', DATE '2026-02-06'),
('INTIMACY', 'ewma_alpha', 0.200000, 'EWMA alpha', DATE '2026-02-06'),
('INTIMACY', 'halflife_last', 10.000000, 'last-contact half-life (days)', DATE '2026-02-06'),
('INTIMACY', 'halflife_long', 30.000000, 'long-term burst half-life (days)', DATE '2026-02-06'),
('INTIMACY', 'halflife_recharge', 21.000000, 'recharge half-life (days)', DATE '2026-02-06'),
('INTIMACY', 'halflife_session', 14.000000, 'session half-life (days)', DATE '2026-02-06'),
('INTIMACY', 'halflife_short', 7.000000, 'short-term burst half-life (days)', DATE '2026-02-06'),
('INTIMACY', 'incentive_weight', 1.500000, 'incentive multiplier', DATE '2026-02-06'),
('INTIMACY', 'lookback_days', 60.000000, 'lookback window (days)', DATE '2026-02-06'),
('INTIMACY', 'percentile_lower', 5.000000, 'lower percentile', DATE '2026-02-06'),
('INTIMACY', 'percentile_upper', 95.000000, 'upper percentile', DATE '2026-02-06'),
('INTIMACY', 'recharge_attribute_hours', 1.000000, 'recharge attribution window (hours)', DATE '2026-02-06'),
('INTIMACY', 'session_merge_hours', 4.000000, 'session merge gap (hours)', DATE '2026-02-06'),
('INTIMACY', 'weight_duration', 0.500000, 'duration weight', DATE '2026-02-06'),
('INTIMACY', 'weight_frequency', 2.000000, 'frequency weight', DATE '2026-02-06'),
('INTIMACY', 'weight_recency', 1.500000, 'recency weight', DATE '2026-02-06'),
('INTIMACY', 'weight_recharge', 2.000000, 'recharge weight', DATE '2026-02-06'),
('NCI', 'active_new_penalty', 0.200000, 'active-new suppression multiplier', DATE '2026-02-06'),
('NCI', 'active_new_recency_days', 7.000000, 'active-new recency window (days)', DATE '2026-02-06'),
('NCI', 'active_new_visit_threshold_14d', 2.000000, 'active-new threshold in 14d visits', DATE '2026-02-06'),
('NCI', 'amount_base_M0', 300.000000, 'spend log base M0', DATE '2026-02-06'),
('NCI', 'balance_base_B0', 500.000000, 'balance log base B0', DATE '2026-02-06'),
('NCI', 'compression_mode', 0.000000, 'compression mode', DATE '2026-02-06'),
('NCI', 'enable_stop_high_balance_exception', 0.000000, 'enable high-balance STOP exception', DATE '2026-02-06'),
('NCI', 'ewma_alpha', 0.200000, 'EWMA alpha', DATE '2026-02-06'),
('NCI', 'h_recharge', 7.000000, 'recharge decay half-life (days)', DATE '2026-02-06'),
('NCI', 'high_balance_threshold', 1000.000000, 'high-balance threshold', DATE '2026-02-06'),
('NCI', 'lookback_days_recency', 60.000000, 'recency lookback window (days)', DATE '2026-02-06'),
('NCI', 'new_days_threshold', 30.000000, 'new member days threshold', DATE '2026-02-06'),
('NCI', 'new_recharge_max_visits', 10.000000, 'max visits for new-recharge grouping', DATE '2026-02-06'),
('NCI', 'new_visit_threshold', 2.000000, 'new member visit threshold', DATE '2026-02-06'),
('NCI', 'no_touch_days_new', 3.000000, 'no-touch threshold (days)', DATE '2026-02-06'),
('NCI', 'percentile_lower', 5.000000, 'lower percentile', DATE '2026-02-06'),
('NCI', 'percentile_upper', 95.000000, 'upper percentile', DATE '2026-02-06'),
('NCI', 'recharge_recent_days', 14.000000, 'recent recharge window (days)', DATE '2026-02-06'),
('NCI', 'salvage_end', 60.000000, 'salvage decay end day', DATE '2026-02-06'),
('NCI', 'salvage_start', 30.000000, 'salvage decay start day', DATE '2026-02-06'),
('NCI', 't2_target_days', 7.000000, 'second-visit target window (days)', DATE '2026-02-06'),
('NCI', 'use_smoothing', 1.000000, 'enable smoothing', DATE '2026-02-06'),
('NCI', 'value_w_bal', 0.800000, 'value weight for balance', DATE '2026-02-06'),
('NCI', 'value_w_spend', 1.000000, 'value weight for spend', DATE '2026-02-06'),
('NCI', 'visit_lookback_days', 180.000000, 'visit history lookback (days)', DATE '2026-02-06'),
('NCI', 'w_need', 1.600000, 'need weight', DATE '2026-02-06'),
('NCI', 'w_re', 0.800000, 'recharge pressure weight', DATE '2026-02-06'),
('NCI', 'w_value', 1.000000, 'value weight', DATE '2026-02-06'),
('NCI', 'w_welcome', 1.000000, 'welcome-stage weight', DATE '2026-02-06'),
('NCI', 'welcome_window_days', 3.000000, 'welcome outreach window for first touch (days)', DATE '2026-02-06'),
('RECALL', 'ewma_alpha', 0.200000, 'EWMA alpha', DATE '2026-02-06'),
('RECALL', 'halflife_new', 7.000000, 'new member half-life (days)', DATE '2026-02-06'),
('RECALL', 'halflife_recharge', 10.000000, 'recharge half-life (days)', DATE '2026-02-06'),
('RECALL', 'lookback_days', 60.000000, 'recall lookback window (days)', DATE '2026-02-06'),
('RECALL', 'percentile_lower', 5.000000, 'lower percentile', DATE '2026-02-06'),
('RECALL', 'percentile_upper', 95.000000, 'upper percentile', DATE '2026-02-06'),
('RECALL', 'sigma_min', 2.000000, 'minimum sigma for volatility', DATE '2026-02-06'),
('RECALL', 'weight_hot', 1.000000, 'hotness weight', DATE '2026-02-06'),
('RECALL', 'weight_new', 1.000000, 'new member weight', DATE '2026-02-06'),
('RECALL', 'weight_overdue', 3.000000, 'overdue weight', DATE '2026-02-06'),
('RECALL', 'weight_recharge', 1.000000, 'recharge weight', DATE '2026-02-06'),
('WBI', 'amount_base_M0', 300.000000, 'spend log base M0', DATE '2026-02-06'),
('WBI', 'balance_base_B0', 500.000000, 'balance log base B0', DATE '2026-02-06'),
('WBI', 'compression_mode', 0.000000, 'compression mode', DATE '2026-02-06'),
('WBI', 'enable_stop_high_balance_exception', 0.000000, 'enable high-balance STOP exception', DATE '2026-02-06'),
('WBI', 'ewma_alpha', 0.200000, 'EWMA alpha', DATE '2026-02-06'),
('WBI', 'h_recharge', 7.000000, 'recharge decay half-life (days)', DATE '2026-02-06'),
('WBI', 'high_balance_threshold', 1000.000000, 'high-balance threshold', DATE '2026-02-06'),
('WBI', 'lookback_days_recency', 60.000000, 'recency lookback window (days)', DATE '2026-02-06'),
('WBI', 'new_days_threshold', 30.000000, 'new member days threshold', DATE '2026-02-06'),
('WBI', 'new_recharge_max_visits', 10.000000, 'max visits for new-recharge grouping', DATE '2026-02-06'),
('WBI', 'new_visit_threshold', 2.000000, 'new member visit threshold', DATE '2026-02-06'),
('WBI', 'overdue_alpha', 2.000000, 'overdue fallback alpha', DATE '2026-02-06'),
('WBI', 'overdue_weight_blend_min_samples', 8.000000, 'minimum samples to fully trust weighted overdue CDF', DATE '2026-02-07'),
('WBI', 'overdue_weight_halflife_days', 30.000000, 'overdue weighted-CDF interval half-life (days)', DATE '2026-02-07'),
('WBI', 'percentile_lower', 5.000000, 'lower percentile', DATE '2026-02-06'),
('WBI', 'percentile_upper', 95.000000, 'upper percentile', DATE '2026-02-06'),
('WBI', 'recency_gate_days', 14.000000, 'recency suppression gate center (days)', DATE '2026-02-06'),
('WBI', 'recency_gate_slope_days', 3.000000, 'recency suppression slope (days)', DATE '2026-02-06'),
('WBI', 'recency_hard_floor_days', 14.000000, 'hard floor for winback recency (days)', DATE '2026-02-06'),
('WBI', 'recharge_recent_days', 14.000000, 'recent recharge window (days)', DATE '2026-02-06'),
('WBI', 'use_smoothing', 1.000000, 'enable smoothing', DATE '2026-02-06'),
('WBI', 'value_w_bal', 1.000000, 'value weight for balance', DATE '2026-02-06'),
('WBI', 'value_w_spend', 1.000000, 'value weight for spend', DATE '2026-02-06'),
('WBI', 'visit_lookback_days', 180.000000, 'visit history lookback (days)', DATE '2026-02-06'),
('WBI', 'w_drop', 1.000000, 'drop weight', DATE '2026-02-06'),
('WBI', 'w_over', 2.000000, 'overdue weight', DATE '2026-02-06'),
('WBI', 'w_re', 0.400000, 'recharge pressure weight', DATE '2026-02-06'),
('WBI', 'w_value', 1.200000, 'value weight', DATE '2026-02-06')
ON CONFLICT (index_type, param_name, effective_from) DO UPDATE SET
param_value = EXCLUDED.param_value,
description = EXCLUDED.description,
updated_at = NOW();
-- =============================================================================
-- 关系指数RS/OS/MS/ML参数
-- 生效时间:北京时间 2026-01-01按数据库日期管理
-- =============================================================================
-- 下线旧版 INTIMACY 参数(兼容保留历史记录)
UPDATE billiards_dws.cfg_index_parameters
SET effective_to = DATE '2025-12-31',
updated_at = NOW()
WHERE index_type = 'INTIMACY'
AND (effective_to IS NULL OR effective_to > DATE '2025-12-31');
INSERT INTO billiards_dws.cfg_index_parameters
(index_type, param_name, param_value, description, effective_from)
VALUES
-- RS关系强度
('RS', 'lookback_days', 60.000000, '服务行为回溯窗口(天)', DATE '2026-01-01'),
('RS', 'session_merge_hours', 4.000000, '会话合并阈值(小时)', DATE '2026-01-01'),
('RS', 'incentive_weight', 1.500000, '激励课权重', DATE '2026-01-01'),
('RS', 'halflife_session', 14.000000, '会话半衰期(天)', DATE '2026-01-01'),
('RS', 'halflife_last', 10.000000, '最近一次服务半衰期(天)', DATE '2026-01-01'),
('RS', 'weight_f', 1.000000, '频次项权重', DATE '2026-01-01'),
('RS', 'weight_d', 0.700000, '时长项权重', DATE '2026-01-01'),
('RS', 'gate_alpha', 0.600000, '最近服务门控指数', DATE '2026-01-01'),
('RS', 'percentile_lower', 5.000000, '展示分下分位', DATE '2026-01-01'),
('RS', 'percentile_upper', 95.000000, '展示分上分位', DATE '2026-01-01'),
('RS', 'compression_mode', 1.000000, '压缩模式0=none,1=log1p,2=asinh', DATE '2026-01-01'),
('RS', 'use_smoothing', 1.000000, '是否启用分位平滑', DATE '2026-01-01'),
('RS', 'ewma_alpha', 0.200000, 'EWMA平滑系数', DATE '2026-01-01'),
-- OS归属份额
('OS', 'min_rs_raw_for_ownership', 0.050000, '参与归属计算的最小RS_raw', DATE '2026-01-01'),
('OS', 'min_total_rs_raw', 0.100000, '形成稳定归属的最小sum_rs', DATE '2026-01-01'),
('OS', 'ownership_main_threshold', 0.600000, '主责阈值', DATE '2026-01-01'),
('OS', 'ownership_comanage_threshold', 0.350000, '共管阈值', DATE '2026-01-01'),
('OS', 'ownership_gap_threshold', 0.150000, '主责与次席份额差阈值', DATE '2026-01-01'),
('OS', 'eps', 0.000001, '数值稳定项', DATE '2026-01-01'),
-- MS升温动量
('MS', 'lookback_days', 60.000000, '服务行为回溯窗口(天)', DATE '2026-01-01'),
('MS', 'session_merge_hours', 4.000000, '会话合并阈值(小时)', DATE '2026-01-01'),
('MS', 'incentive_weight', 1.500000, '激励课权重', DATE '2026-01-01'),
('MS', 'halflife_short', 7.000000, '短期半衰期(天)', DATE '2026-01-01'),
('MS', 'halflife_long', 30.000000, '长期半衰期(天)', DATE '2026-01-01'),
('MS', 'eps', 0.000001, '数值稳定项', DATE '2026-01-01'),
('MS', 'percentile_lower', 5.000000, '展示分下分位', DATE '2026-01-01'),
('MS', 'percentile_upper', 95.000000, '展示分上分位', DATE '2026-01-01'),
('MS', 'compression_mode', 1.000000, '压缩模式0=none,1=log1p,2=asinh', DATE '2026-01-01'),
('MS', 'use_smoothing', 1.000000, '是否启用分位平滑', DATE '2026-01-01'),
('MS', 'ewma_alpha', 0.200000, 'EWMA平滑系数', DATE '2026-01-01'),
-- ML付费关联
('ML', 'lookback_days', 60.000000, '充值行为回溯窗口(天)', DATE '2026-01-01'),
('ML', 'source_mode', 0.000000, '数据源模式0=manual_only,1=last_touch_fallback', DATE '2026-01-01'),
('ML', 'recharge_attribute_hours', 1.000000, 'last-touch备用归因窗口小时', DATE '2026-01-01'),
('ML', 'amount_base', 500.000000, '金额压缩基准', DATE '2026-01-01'),
('ML', 'halflife_recharge', 21.000000, '充值半衰期(天)', DATE '2026-01-01'),
('ML', 'percentile_lower', 5.000000, '展示分下分位', DATE '2026-01-01'),
('ML', 'percentile_upper', 95.000000, '展示分上分位', DATE '2026-01-01'),
('ML', 'compression_mode', 1.000000, '压缩模式0=none,1=log1p,2=asinh', DATE '2026-01-01'),
('ML', 'use_smoothing', 1.000000, '是否启用分位平滑', DATE '2026-01-01'),
('ML', 'ewma_alpha', 0.200000, 'EWMA平滑系数', DATE '2026-01-01')
ON CONFLICT (index_type, param_name, effective_from) DO UPDATE SET
param_value = EXCLUDED.param_value,
description = EXCLUDED.description,
updated_at = NOW();
-- =============================================================================
-- 验证
-- =============================================================================
DO $$
DECLARE
rs_count INTEGER;
os_count INTEGER;
ms_count INTEGER;
ml_count INTEGER;
nci_count INTEGER;
wbi_count INTEGER;
BEGIN
SELECT COUNT(*) INTO rs_count
FROM billiards_dws.cfg_index_parameters
WHERE index_type = 'RS';
SELECT COUNT(*) INTO os_count
FROM billiards_dws.cfg_index_parameters
WHERE index_type = 'OS';
SELECT COUNT(*) INTO ms_count
FROM billiards_dws.cfg_index_parameters
WHERE index_type = 'MS';
SELECT COUNT(*) INTO ml_count
FROM billiards_dws.cfg_index_parameters
WHERE index_type = 'ML';
SELECT COUNT(*) INTO nci_count
FROM billiards_dws.cfg_index_parameters
WHERE index_type = 'NCI';
SELECT COUNT(*) INTO wbi_count
FROM billiards_dws.cfg_index_parameters
WHERE index_type = 'WBI';
RAISE NOTICE 'RS 参数数量: %', rs_count;
RAISE NOTICE 'OS 参数数量: %', os_count;
RAISE NOTICE 'MS 参数数量: %', ms_count;
RAISE NOTICE 'ML 参数数量: %', ml_count;
RAISE NOTICE '新客转化参数数量: %', nci_count;
RAISE NOTICE '唤回指数参数数量: %', wbi_count;
END $$;
SELECT
index_type,
param_name,
param_value,
description,
effective_from
FROM billiards_dws.cfg_index_parameters
ORDER BY index_type, param_name, effective_from;