R语言:基于前期存活概率计算月度条件流失/预测概率
当然有自动化的实现方法!针对这种按ID分组、基于时序递推的条件流失概率计算,用Python的Pandas库或者SQL都能轻松搞定,下面我给你详细讲两种常用方案:
方案一:用Python Pandas处理本地数据
如果你的数据是CSV/Excel等本地文件,Pandas是最便捷的工具,它能高效处理分组时序计算。
步骤1:数据准备与排序
首先确保数据按ID和月份排序,这是递推计算的前提(必须保证每个ID的月份是按时间顺序排列的)。
import pandas as pd # 示例数据(替换成你的真实数据) data = { 'ID': [6800, 6800, 6800, 1234, 1234], 'month': ['2024-04-30', '2024-05-31', '2024-06-30', '2024-04-30', '2024-05-31'], 'monthly_churn_prob': [0.54, 0.125, 0.081440443, 0.3, 0.2] } df = pd.DataFrame(data) # 转换月份为日期格式并排序 df['month'] = pd.to_datetime(df['month']) df = df.sort_values(['ID', 'month']).reset_index(drop=True)
步骤2:自定义函数实现递推计算
我们可以给每个ID分组,然后按月份顺序递推计算条件流失概率和存活概率:
- 第一个月的条件流失概率 = 当月的流失概率
- 后续月份的条件流失概率 = 上月末的存活概率 × 当月流失概率
- 存活概率 = 上月末的存活概率 × (1 - 当月流失概率)
def calculate_conditional_churn(group): conditional_churns = [] survival_probs = [] for idx, row in group.iterrows(): if idx == group.index[0]: # 第一个月的初始计算 cond_churn = row['monthly_churn_prob'] surv_prob = 1 - cond_churn else: # 后续月份基于上月存活概率递推 cond_churn = survival_probs[-1] * row['monthly_churn_prob'] surv_prob = survival_probs[-1] * (1 - row['monthly_churn_prob']) conditional_churns.append(cond_churn) survival_probs.append(surv_prob) group['conditional_churn'] = conditional_churns group['survival_prob'] = survival_probs return group # 按ID分组应用计算逻辑 result_df = df.groupby('ID').apply(calculate_conditional_churn).reset_index(drop=True)
运行后你就能得到每个ID每个月的条件流失概率,完全匹配你举的例子:比如ID6800的5月条件流失概率是0.46*0.125=0.0575,6月是0.46*(1-0.125)*0.081440443≈0.0335。
步骤3:高效矢量化优化(适合大数据量)
如果你的数据量很大(比如百万级行),上面的循环方法效率会偏低,可以用Pandas的矢量化操作提速:
# 计算每个ID的存活概率累积乘积 df['survival_cumprod'] = df.groupby('ID')['monthly_churn_prob'].transform( lambda x: (1 - x).cumprod() ) # 用上月的存活累积乘积计算当月条件流失概率 df['prev_survival'] = df.groupby('ID')['survival_cumprod'].shift(1) df['conditional_churn'] = df.apply( lambda row: row['monthly_churn_prob'] if pd.isna(row['prev_survival']) else row['prev_survival'] * row['monthly_churn_prob'], axis=1 ) # 存活概率直接用累积乘积结果 df['survival_prob'] = df['survival_cumprod']
方案二:用SQL处理数据库中的数据
如果你的数据存在数据库(比如PostgreSQL、MySQL)里,可以用递归CTE(公共表表达式)实现自动化计算,不需要导出数据到本地。
以PostgreSQL为例:
WITH ranked_data AS ( -- 先给每个ID的月份排序 SELECT ID, month, monthly_churn_prob, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY month) AS rn FROM your_table_name ), recursive_churn AS ( -- 初始化第一个月的计算 SELECT ID, month, monthly_churn_prob, monthly_churn_prob AS conditional_churn, 1 - monthly_churn_prob AS survival_prob FROM ranked_data WHERE rn = 1 UNION ALL -- 递归计算后续月份 SELECT r.ID, r.month, r.monthly_churn_prob, rc.survival_prob * r.monthly_churn_prob AS conditional_churn, rc.survival_prob * (1 - r.monthly_churn_prob) AS survival_prob FROM ranked_data r JOIN recursive_churn rc ON r.ID = rc.ID AND r.rn = rc.rn + 1 ) -- 输出最终结果 SELECT ID, month, monthly_churn_prob, conditional_churn, survival_prob FROM recursive_churn ORDER BY ID, month;
内容的提问来源于stack exchange,提问作者VASISTA
相关产品推荐
相关产品推荐

