基于用户行为数据的留存动因分析与预警策略研究
1.1 项目背景在电商和订阅式商业模式中用户留存率是衡量产品健康度和商业可持续性的核心指标。获取新用户的成本远高于维护老用户因此通过数据分析定位流失原因、预测流失风险并制定留存策略是数据分析师的核心工作之一。本项目旨在通过对用户行为、交易记录和画像数据的分析回答以下业务问题哪些用户特征最能预示流失风险会员制度、客服体验、参与度等因素如何影响留存如何将数据洞察转化为可落地的运营策略1.2 数据来源项目说明数据集名称E-commerce Customer Churn Dataset来源平台Kaggle数据性质完全合成数据但变量关系模拟真实电商模式原始文件ecommerce_customer_features.csv特征表、ecommerce_customer_targets.csv标签表数据规模6,000条用户记录15个特征字段1个目标变量数据特点包含缺失值本版本无、无重复值、业务逻辑清晰合成数据的优势逻辑清晰、结论可验证适合作为分析项目练习真实业务中需额外关注数据质量和脏数据处理。第二部分分析工具与流程2.1 工具链阶段工具主要任务数据清洗与合并Python (Pandas, NumPy)读取、合并、清洗、类型转换、异常处理探索性分析Python (Matplotlib, Seaborn)特征分布、流失对比、相关性分析数据查询与分组分析SQL (DBeaver)Cohort分析、分组对比、特征聚合可视化与仪表盘Tableau交互式看板、趋势图2.2 分析流程原始数据 → 数据清洗 → 探索性分析(EDA) → SQL取数与分组分析 → 可视化看板 → 业务结论与建议第三阶段数据清洗与预处理Python3.1 原始数据情况两个文件通过Customer_ID关联特征表15列用户行为 画像标签表1列churnedYes/No3.2 清洗步骤步骤操作代码/方法1读取两个CSV文件pd.read_csv()2合并特征表与标签表pd.merge()3检查缺失值df.isnull().sum() → 本版本无缺失4异常值处理截尾1%-99%分位数5重复值处理drop_duplicates() → 无重复6转换目标变量churned: Yes→1, No→07导出清洗后数据cleaned_ecommerce.csv3.3 清洗代码import pandas as pd import numpy as np import os # # 读取数据 # features_path rD:\Users\qimiao\Desktop\数据分析\archive1\ecommerce_customer_features.csv targets_path rD:\Users\qimiao\Desktop\数据分析\archive1\ecommerce_customer_targets.csv features pd.read_csv(features_path) targets pd.read_csv(targets_path) print( 数据读取成功 ) print(f特征表: {features.shape}) print(f标签表: {targets.shape}) print(f\n特征表列名:\n{features.columns.tolist()}) print(f\n标签表前5行:\n{targets.head()}) # # 合并两个文件 # df features.merge(targets, onCustomer_ID, howinner) print(f\n 合并完成 ) print(f合并后形状: {df.shape}) # # 检查缺失值 # print(\n 缺失值检查 ) missing df.isnull().sum() missing_pct missing / len(df) * 100 missing_df pd.DataFrame({缺失数量: missing, 缺失比例(%): missing_pct}) print(missing_df[missing_df[缺失数量] 0]) # # 处理缺失值 # numeric_cols df.select_dtypes(include[np.number]).columns for col in numeric_cols: if df[col].isnull().sum() 0: df[col].fillna(df[col].median(), inplaceTrue) print(f已填充 {col} 的缺失值) categorical_cols df.select_dtypes(include[object]).columns for col in categorical_cols: if col ! Customer_ID and df[col].isnull().sum() 0: mode_val df[col].mode()[0] if len(df[col].mode()) 0 else Unknown df[col].fillna(mode_val, inplaceTrue) print(f已填充 {col} 的缺失值) # # 检查异常值 # print(\n 异常值检查 ) for col in numeric_cols: min_val df[col].min() max_val df[col].max() if col discount_usage_rate and max_val 1: print(f{col}: 最大值 {max_val} 1存在异常) if col account_age_months and max_val 120: print(f{col}: 最大值 {max_val} 120) # 截尾处理可选 for col in numeric_cols: q99 df[col].quantile(0.99) q01 df[col].quantile(0.01) df[col] df[col].clip(lowerq01, upperq99) print(已对数值列进行1%-99%截尾处理) # # 转换目标变量 # df[churned] df[churned].map({No: 0, Yes: 1}) print(f\n 目标变量分布 ) print(df[churned].value_counts()) print(f流失率: {df[churned].mean():.2%}) # # 删除重复值 # initial_rows len(df) df df.drop_duplicates(subset[Customer_ID]) print(f\n删除重复行: {initial_rows - len(df)} 行) # # 保存清洗后的数据保存到你指定的桌面文件夹 # output_path rD:\Users\qimiao\Desktop\数据分析\cleaned_ecommerce.csv df.to_csv(output_path, indexFalse) print(f\n清洗完成已保存为: {output_path}) print(f最终数据形状: {df.shape}) # # 快速验证 # print(\n 快速验证 ) print(f1. 剩余缺失值数量: {df.isnull().sum().sum()}) print(f2. churned 唯一值: {df[churned].unique()}) print(f3. 数据前3行:\n{df.head(3)})import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns # 设置中文显示避免图表乱码 plt.rcParams[font.sans-serif] [SimHei, Microsoft YaHei, Arial Unicode MS] plt.rcParams[axes.unicode_minus] False # # 读取清洗后的数据 # df pd.read_csv(rD:\Users\qimiao\Desktop\数据分析\cleaned_ecommerce.csv) print( 数据加载成功 ) print(f数据形状: {df.shape}) print(f列名: {df.columns.tolist()}\n) # # 1. 目标变量分布流失 vs 未流失 # print( 1. 目标变量分布 ) churn_counts df[churned].value_counts() churn_pct df[churned].value_counts(normalizeTrue) print(f未流失(0): {churn_counts[0]} 人, 占比 {churn_pct[0]:.2%}) print(f流失(1): {churn_counts[1]} 人, 占比 {churn_pct[1]:.2%}) # 可视化 fig, axes plt.subplots(1, 2, figsize(10, 4)) df[churned].value_counts().plot(kindbar, axaxes[0], color[green, red]) axes[0].set_title(流失用户分布) axes[0].set_xticklabels([未流失, 流失], rotation0) axes[0].set_ylabel(用户数) df[churned].value_counts(normalizeTrue).plot(kindpie, axaxes[1], autopct%1.1f%%, colors[green, red]) axes[1].set_title(流失用户占比) plt.tight_layout() plt.savefig(rD:\Users\qimiao\Desktop\数据分析\1_churn_distribution.png, dpi150) plt.show() # # 2. 数值特征统计摘要 # print(\n 2. 数值特征统计摘要 ) numeric_cols df.select_dtypes(include[np.number]).columns numeric_cols [col for col in numeric_cols if col ! churned] print(df[numeric_cols].describe()) # # 3. 流失用户 vs 未流失用户 特征对比 # print(\n 3. 流失 vs 未流失 特征均值对比 ) compare_df df.groupby(churned)[numeric_cols].mean().T compare_df.columns [未流失, 流失] compare_df[差异] compare_df[流失] - compare_df[未流失] compare_df[差异百分比] (compare_df[差异] / compare_df[未流失]) * 100 print(compare_df.sort_values(差异, ascendingFalse)) # 可视化Top 5 差异最大的特征 fig, ax plt.subplots(figsize(12, 6)) top_features compare_df[差异].abs().sort_values(ascendingFalse).head(8).index diff_plot compare_df.loc[top_features, [未流失, 流失]] diff_plot.plot(kindbar, axax, color[green, red]) ax.set_title(流失 vs 未流失 用户特征对比差异最大的8个特征) ax.set_ylabel(均值) ax.set_xlabel(特征) ax.legend([未流失, 流失]) ax.tick_params(axisx, rotation45) plt.tight_layout() plt.savefig(rD:\Users\qimiao\Desktop\数据分析\2_feature_comparison.png, dpi150) plt.show() # # 4. 相关性矩阵分析 # print(\n 4. 特征与流失的相关性 ) correlations df[numeric_cols [churned]].corr()[churned].sort_values(ascendingFalse) print(correlations) # 可视化热力图 plt.figure(figsize(14, 10)) corr_matrix df[numeric_cols [churned]].corr() mask np.triu(np.ones_like(corr_matrix, dtypebool)) sns.heatmap(corr_matrix, maskmask, annotTrue, fmt.2f, cmapRdBu_r, center0, squareTrue, linewidths0.5) plt.title(特征相关性热力图, fontsize14) plt.tight_layout() plt.savefig(rD:\Users\qimiao\Desktop\数据分析\3_correlation_heatmap.png, dpi150) plt.show() # # 5. 关键特征的分组分析 # print(\n 5. 关键特征分析 ) # 5.1 账号年龄 vs 流失 print(\n5.1 不同账号年龄段的流失率:) df[age_group] pd.cut(df[account_age_months], bins[0, 3, 6, 12, 24, 120], labels[0-3月, 4-6月, 7-12月, 13-24月, 24月以上]) age_churn df.groupby(age_group)[churned].agg([count, mean]) age_churn.columns [用户数, 流失率] print(age_churn) # 5.2 会员 vs 非会员 print(\n5.2 会员与非会员的流失率:) loyalty_churn df.groupby(loyalty_member)[churned].agg([count, mean]) loyalty_churn.columns [用户数, 流失率] print(loyalty_churn) # 5.3 客服工单数 vs 流失 print(\n5.3 不同客服工单数的流失率:) ticket_churn df.groupby(customer_support_tickets)[churned].agg([count, mean]) ticket_churn.columns [用户数, 流失率] print(ticket_churn) # 可视化年龄分组流失率 fig, axes plt.subplots(1, 3, figsize(15, 4)) # 年龄分组 age_churn[流失率].plot(kindbar, axaxes[0], colorcoral) axes[0].set_title(不同账号年龄段的流失率) axes[0].set_xlabel(账号年龄) axes[0].set_ylabel(流失率) axes[0].tick_params(axisx, rotation45) # 会员 vs 非会员 loyalty_churn[流失率].plot(kindbar, axaxes[1], color[green, red]) axes[1].set_title(会员 vs 非会员 流失率) axes[1].set_xlabel(是否会员) axes[1].set_ylabel(流失率) axes[1].set_xticklabels([会员(Yes), 非会员(No)], rotation0) # 客服工单数 ticket_churn[流失率].plot(kindbar, axaxes[2], colorsteelblue) axes[2].set_title(不同客服工单数的流失率) axes[2].set_xlabel(客服工单数) axes[2].set_ylabel(流失率) plt.tight_layout() plt.savefig(rD:\Users\qimiao\Desktop\数据分析\4_key_features_analysis.png, dpi150) plt.show() # # 6. 流失用户的画像总结 # print(\n 6. 流失用户画像总结 ) churned_users df[df[churned] 1] retained_users df[df[churned] 0] print(流失用户的典型特征与未流失用户对比:) for col in numeric_cols: churned_mean churned_users[col].mean() retained_mean retained_users[col].mean() diff_pct (churned_mean - retained_mean) / retained_mean * 100 direction ↑ 更高 if diff_pct 0 else ↓ 更低 if abs(diff_pct) 5: # 只显示差异超过5%的特征 print(f {col}: {direction} ({diff_pct:.1f}%)) # # 保存分析结果 # # 将对比结果保存为CSV compare_df.to_csv(rD:\Users\qimiao\Desktop\数据分析\feature_comparison.csv) print(\n分析完成图表和结果已保存到桌面数据分析文件夹)3.4 清洗后数据概览指标数值总样本数6,000特征数量14流失用户(churned1)929未流失用户(churned0)5,071整体流失率15.48%关键字段示例Customer_ID, account_age_months, avg_order_value, total_orders, days_since_last_purchase, discount_usage_rate, return_rate, customer_support_tickets, loyalty_member, browsing_frequency_per_week, cart_abandonment_rate, product_review_score_avg, engagement_score, satisfaction_score, price_sensitivity_index, churned清洗结论数据质量良好无缺失值、无重复行可直接用于分析。第四阶段探索性数据分析EDAPython4.1 流失用户对比分析通过对比流失组(churned1)和留存组(churned0)的特征均值识别关键差异特征流失组均值留存组均值差异方向days_since_last_purchase79.5天20.1天2.96↑ 显著更高engagement_score2.365.34-56%↓ 显著更低customer_support_tickets1.110.810.37↑ 更高total_orders7.078.73-19%↓ 更低satisfaction_score7.78.15-5.50%↓ 略低4.2 相关性分析特征与流失的相关性说明days_since_last_purchase0.77最强正相关engagement_score-0.73最强负相关customer_support_tickets0.11弱正相关satisfaction_score-0.13弱负相关EDA结论参与度评分和距上次购买天数是预测流失的最强信号。第五阶段SQL分组分析与Cohort分析DBeaver5.1 分析目标在 DBeaver 中对清洗后的数据执行分组聚合回答四个核心业务问题。5.2 核心SQL查询与结果查询1整体流失率SELECT COUNT(*) AS total_users, SUM(churned) AS churned_users, ROUND(CAST(SUM(churned) AS FLOAT) / COUNT(*) * 100, 2) AS churn_rate_pct FROM cleaned_ecommerce;total_userschurned_userschurn_rate_pct6,00092915.48%查询2会员 vs 非会员流失率SELECT loyalty_member, COUNT(*) AS user_count, ROUND(AVG(churned) * 100, 2) AS churn_rate_pct FROM cleaned_ecommerce GROUP BY loyalty_member;loyalty_memberuser_countchurn_rate_pctNo4,91516.91%Yes1,0859.03%会员流失率比非会员低约 7.9个百分点。查询3客服工单数 vs 流失率SELECT customer_support_tickets, COUNT(*) AS user_count, ROUND(AVG(churned) * 100, 2) AS churn_rate_pct FROM cleaned_ecommerce GROUP BY customer_support_tickets ORDER BY customer_support_tickets;ticketsuser_countchurn_rate_pct02,66011.99%12,07616.52%285018.12%330824.68%410634.91%工单≥3次的用户流失率是平均水平的 2倍以上。查询4账号年龄分组流失率CohortSELECT CASE WHEN account_age_months 3 THEN 0-3月 WHEN account_age_months 6 THEN 4-6月 WHEN account_age_months 12 THEN 7-12月 WHEN account_age_months 24 THEN 13-24月 ELSE 24月以上 END AS age_group, COUNT(*) AS user_count, ROUND(AVG(churned) * 100, 2) AS churn_rate_pct FROM cleaned_ecommerce GROUP BY age_group;age_groupuser_countchurn_rate_pct0-3月30315.18%4-6月29517.63%7-12月56717.81%13-24月1,20415.20%24月以上3,63115.06%流失最高峰出现在注册后4-12个月而非新手期。查询5参与度评分 vs 流失率最重要发现SELECT CASE WHEN engagement_score 2 THEN 低(0-2) WHEN engagement_score 4 THEN 中低(2-4) WHEN engagement_score 6 THEN 中(4-6) WHEN engagement_score 8 THEN 中高(6-8) ELSE 高(8-10) END AS engagement_level, COUNT(*) AS user_count, ROUND(AVG(churned) * 100, 2) AS churn_rate_pct FROM cleaned_ecommerce GROUP BY engagement_level;参与度等级用户数流失率低(0-2)36599.73%中低(2-4)1,05849.62%中(4-6)3,2121.25%中高(6-8)1,3650.00%参与度评分≤2的用户几乎必流失≥6的用户几乎不流失。 这是整个项目中最具预测力的留存指标。第六阶段Tableau可视化看板6.1 看板组成工作表名称图表类型核心信息参与度评分 vs 留存率散点图/折线图评分4流失率飙升≥6留存稳定客服工单数 vs 留存率柱状图/折线图工单≥3留存率下降15%会员 vs 非会员留存率并排柱状图会员留存率91% vs 非会员83%账号年龄分组留存率柱状图4-12个月是流失高峰期6.2 看板截图订阅用户留存与流失分析 | Tableau Public项目延伸A/B 测试方案——验证“低参与度用户激活策略”对留存的影响一、测试背景基于项目核心发现本报告已发现参与度评分 4 的用户留存率不足 50%评分 2 的用户几乎必流失。这说明低参与度用户是流失的高危人群对这些用户进行早期干预是提升留存的潜在杠杆为此设计如下 A/B 测试。二、实验假设原假设 H₀对低参与度用户进行干预不会显著提升留存率备择假设 H₁干预能显著提升 14 日留存率三、实验对象与分组项目说明实验对象新注册用户且前 7 天参与度评分 ≤ 4分组方式随机均匀分流50% / 50%对照组不施加任何额外干预常规流程实验组施加「激活干预策略」实验周期4 周积累足够样本预估样本量每组 ≥ 500 人四、实验组干预策略可执行方案针对实验组用户在以下三个时间点触发自动化干预时间点动作注册后第 3 天个性化推送如“发现你的兴趣好物”注册后第 7 天小额无门槛优惠券 浏览任务引导注册后第 14 天专属活动提醒 会员权益预告所有动作均可通过现有运营系统自动化完成。五、核心指标指标类型指标名称计算方式核心指标14 日留存率注册后第 14 天仍有活跃行为的用户占比辅助指标参与度评分变化实验前后评分提升幅度护栏指标客单价确保干预不损害消费能力反向指标优惠券滥用率避免“薅羊毛”行为六、实验结果判断标准使用Z 检验 / 卡方检验显著性水平 α 0.05结果结论后续动作实验组 14 日留存率显著更高p 0.05策略有效全量上线无显著差异策略无效下线或重新设计干预方式留存提升但客单价下降存在副作用优化优惠券门槛或任务设计第七阶段核心业务结论基于以上分析得出 4条核心结论结论1参与度是留存的“前置预警指标”参与度评分4的用户留存率低于50%评分2的用户留存率接近0%。 建议设定参与度3.5为自动激活阈值Push/优惠券/任务引导。结论2会员身份对留存有独立正向影响会员留存率91% vs 非会员83%且在同龄段中差异依然显著。 建议新用户注册流程中强化会员权益展示对高价值非会员定向推送会员试用。结论3客服工单是“流失放大器”工单≥3次的用户留存率下降15–23个百分点。 建议对高频投诉用户建立主动回访机制产品侧减少用户求助场景。结论4流失最高峰在注册后4–12个月该阶段留存率最低82.2%并非“新手期”。 建议在第3/6/9个月设计系统化的留存干预动作。第八部分可落地业务建议汇总优先级建议预期效果责任方P0参与度3.5用户自动激活流程挽回50%中低参与用户运营产品P0工单≥3次用户主动回访降低流失率10–15%客服运营P1新注册用户会员引导强化长期降低流失2–3%产品运营P13/6/9个月留存干预活动平滑4-12月流失高峰运营市场第九部分局限性与改进方向9.1 当前局限数据为合成数据缺乏真实业务的“脏乱”特征缺少时序数据无法分析行为变化趋势9.2 改进方向对接真实业务数据增加数据清洗复杂度构造时序特征如参与度下降速度、购买间隔变化趋势