diff --git a/models/marts/reporting/rep_exchange__survival_analysis.sql b/models/marts/reporting/rep_exchange__survival_analysis.sql index 046dd4d..15fea1d 100644 --- a/models/marts/reporting/rep_exchange__survival_analysis.sql +++ b/models/marts/reporting/rep_exchange__survival_analysis.sql @@ -17,7 +17,7 @@ transaction_orders AS ( -- LOGIC -- duration_table cte computes the survival time and customer churned indicator duration_table AS ( - + SELECT companies.company_id, --subject companies.company_created_datetime, -- event start datetime @@ -107,7 +107,6 @@ compute_censored_subjects AS ( ), - compute_probability AS ( SELECT @@ -115,17 +114,27 @@ compute_probability AS ( -- The survival probability represents the probability of customers that will not churn up to a specific tenure -- Example: survival_day = 61, survival_prob = 95%. For customers with 61 days of tenure, the customer has a 95% chance of not churning. - EXP(SUM(LN(1 - events / at_risk)) OVER ( - ORDER BY survival_time_days ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW - )) AS survival_probability, + -- When events / at_risk = 1, we replace value 1 with a value very near to 1, to prevent log 0 which causes infinity value + EXP(SUM(LN + ( + CASE WHEN (1 - events / at_risk) = 0 THEN 0.999999 ELSE (1 - events / at_risk) END + )) + OVER ( + ORDER BY survival_time_days ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + )) AS survival_probability, - 100 * (1 - EXP(SUM(LN(1 - events / at_risk)) OVER ( - ORDER BY survival_time_days ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW - ))) AS conversion_percentage, + 100 * (1 - EXP(SUM(LN + ( + CASE WHEN (1 - events / at_risk) = 0 THEN 0.999999 ELSE (1 - events / at_risk) END + )) + OVER ( + ORDER BY survival_time_days ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ))) AS conversion_percentage, - SUM(events / at_risk) OVER ( + SUM(events / at_risk) + OVER ( ORDER BY survival_time_days ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW - ) AS cumulative_hazard, + ) AS cumulative_hazard, '{{ modules.datetime.datetime.now(modules.pytz.timezone("Asia/Kuala_Lumpur")) }}' AS _dbt_ran_datetime