🧩 一、整体架构概览

该脚本是一个完整的 端到端(End-to-End)用户流失预测项目原型,涵盖了:

阶段功能
✅ 数据生成模拟真实电商平台用户行为数据
✅ 数据预处理编码、特征工程、训练集划分
✅ 模型训练与评估对比逻辑回归 vs. 随机森林
✅ 特征重要性分析找出驱动流失的核心因素
✅ 自动化报告生成输出文本报告 + 图表,便于决策

🎯 核心目标:识别高风险流失用户,并通过关键特征洞察制定精准干预策略。


📦 二、模块详解与专业点评

🔹 模块1:generate_sample_churn_data(n_users) —— 高质量模拟数据的设计哲学

✅ 做得好的地方:

  1. 基于业务逻辑构造数据
    • 不是随机乱造,而是根据“会员等级越高 → 消费越多、活跃度越高、流失概率越低”的电商常识设计。
    • 使用 Poisson 分布模拟订单数(离散计数)、LogNormal 模拟消费金额(右偏分布),符合现实规律。
  2. 引入多维用户画像
    • “人”:年龄、性别
    • “货”:总消费、AOV(平均订单价值)
    • “场”:城市等级、访问频次、客服互动
  3. 构建合理的流失标签机制
    • 流失不是简单随机,而是基于多个风险信号叠加:Python编辑if days_since_last_purchase > 90: churn_prob += 0.4 # 强信号 if cart_abandonment_rate > 0.7: churn_prob += 0.15 # 行为犹豫
    • 加入噪声项 np.random.normal(0, 0.1) 提升泛化能力,避免完美可分。
  4. 衍生字段计算合理
    • tenure_days(注册时长)是重要的生命周期指标,在留存分析中非常关键。

💡 专业建议(进阶优化方向):

  • 真实场景中应加入 时间窗口切片(如用过去6个月数据预测未来3个月是否流失)
  • 可增加更多行为特征:加购商品类目偏好、页面停留时长、优惠券使用路径等
  • 标签定义更精细:区分“暂时休眠”和“永久流失”

🔹 模块2:preprocess_data(df) —— 结构化特征工程实践

✅ 关键操作:

Python编辑le_gender = LabelEncoder()
df_processed['gender_encoded'] = le_gender.fit_transform(df_processed['gender'])
  • 将分类变量编码为数值型,满足机器学习输入要求。
  • 选择 LabelEncoder 是合适的,因为性别/城市等级虽为类别,但无显著顺序含义(若有序可用 OrdinalEncoder)。

⚠️ 注意事项:

  • membership_tier 是有序类别(Bronze < Silver < Gold),理想做法是手动映射为 [0,1,2] 或使用 OrdinalEncoder,而非依赖 LabelEncoder 的字母排序(’B’,’G’,’S’ → 0,1,2 正好对上纯属巧合)。

✅ 特征选择合理:

保留了以下几类典型特征:

类型示例
人口统计age, gender
用户身份membership_tier, location_city_tier
消费行为total_orders, total_spent, avg_order_value
活跃度monthly_visits, days_since_last_purchase
风险信号cart_abandonment_rate, customer_service_contacts
忠诚度tenure_days, discount_usage_freq

👉 这正是典型的 RFM扩展模型(Recency-Frequency-Monetary + Contextual Features)


🔹 模块3:train_and_evaluate_models(X, y) —— 双模型对比策略科学

✅ 设计亮点:

  1. 双模型对比:LR vs RF
    • 逻辑回归(LR):解释性强,适合初期归因分析
    • 随机森林(RF):非线性能力强,捕捉交互效应,通常性能更好
  2. 正确的数据处理方式
    • LR 使用 StandardScaler 归一化(必要)
    • RF 直接使用原始数据(树模型不受量纲影响)
  3. 分层抽样(stratify=y)Python编辑train_test_split(..., stratify=y)确保训练/测试集中正负样本比例一致,尤其在不平衡数据下至关重要。
  4. 全面评估指标体系Python编辑accuracy, precision, recall, f1, auc, confusion_matrix, classification_report👉 完全覆盖分类任务评价维度。

📊 指标解读(面向业务):

指标数学意义业务含义
Accuracy(TP+TN)/Total整体预测准确率
PrecisionTP/(TP+FP)“我们认为要流失的人里,真流失的比例” —— 干预成本效率
RecallTP/(TP+FN)“所有实际流失的人中,我们抓到了多少” —— 风控覆盖率
F1-Score2×P×R/(P+R)P 和 R 的调和平均,综合指标
AUC-ROC曲线下面积模型区分能力,不依赖阈值

💡 业务权衡建议

  • 若运营资源有限 → 优先提升 Precision(减少误杀)
  • 若客户价值极高 → 优先提升 Recall(宁可错杀,不可放过)

📈 图表输出:

  • 混淆矩阵热力图:直观展示 TP/FP/TN/FN
  • 支持后续写入报告,便于向非技术团队汇报

🔹 模块4:analyze_feature_importance() —— 从模型到业务洞察的桥梁

✅ 实现方式:

  • 对 树模型:使用 feature_importances_(基于信息增益或基尼不纯度下降)
  • 对 线性模型:使用 |coef_|(绝对系数大小表示影响力)

💡 为什么这一步极其重要?

“模型不仅要预测准,更要能说清楚‘为什么’。”

例如,如果发现 days_since_last_purchase 是最重要特征,说明:

“长时间未复购”是流失最强信号 → 应建立 静默用户唤醒机制(如第30天发券、第60天短信提醒)

再比如,若 customer_service_contacts 权重很高,则暗示:

客服体验差可能是流失主因 → 需回溯工单内容,优化服务流程

📌 这就是 AI + 业务诊断 的融合点!


🔹 模块5:generate_churn_prediction_report() —— 让数据说话,推动决策落地

✅ 报告结构专业且实用:

  1. 项目概述:明确目标
  2. 数据概览:增强可信度
  3. 模型表现:量化效果
  4. 关键驱动因素:揭示根本原因
  5. 业务建议:将算法输出转化为行动指南

💬 典型业务建议示例:

Text编辑对于'距离上次购买天数'长的用户,可推送召回优惠券。
对于'购物车放弃率'高的用户,可分析支付流程或提供客服帮助。

👉 这才是数据科学家的终极价值:不止于建模,而在于驱动增长


🎯 三、从业务视角看这个项目的实战价值

业务角色如何使用此模型?
运营经理获取高风险用户名单,开展定向召回活动(邮件/SMS/APP Push)
产品负责人发现流失主因(如支付失败率高),推动产品迭代优化漏斗
市场总监评估不同人群的LTV(生命周期价值),调整获客预算分配
客服主管分析高频联系用户的共性问题,改进FAQ或培训话术

🛠️ 四、可扩展性与生产化建议

虽然当前是教学级代码,但具备良好扩展基础。以下是迈向生产的升级路径:

✅ 当前优点:

  • 模块化清晰
  • 包含自动化报告
  • 使用标准库(易部署)

🔧 生产环境改进建议:

维度升级建议
数据源接入 Hive/MaxCompute,定期跑批处理任务
特征存储构建 Feature Store,统一线上线下特征
模型服务用 Flask/FastAPI 封装成 API,供其他系统调用
监控报警监控模型性能漂移、特征分布变化
A/B测试对照组验证干预策略是否真正降低流失率
自动化 pipeline使用 Airflow/DolphinScheduler 调度每日更新
模型可解释性增强引入 SHAP/LIME,提供个体级解释(如:“您流失概率高的原因是最近60天未购买”)

📚 五、总结:一个优秀电商数据科学项目的范本

这个脚本体现了以下几个关键原则:

原则在本项目中的体现
业务导向从“用户流失”这一真实痛点出发
数据真实性模拟数据遵循业务规律,非随意生成
方法严谨性正确使用统计与机器学习方法
结果可解释特征重要性分析连接模型与业务
交付实用性自动生成图文报告,支持决策
工程规范性函数化组织,注释清晰,易于维护

🎁 结语

“最好的模型不是准确率最高的那个,而是能让业务团队听懂并愿意行动的那个。”

这套代码不仅展示了 Python 数据挖掘的技术实现,更体现了 资深数据专家的思维框架

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score, confusion_matrix, classification_report
from sklearn.preprocessing import StandardScaler, LabelEncoder
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime, timedelta
import warnings
warnings.filterwarnings("ignore")

# --- 配置 ---
NUM_USERS = 5000
REPORT_PREFIX = '电商用户流失预测报告'
RANDOM_SEED = 42

# --- 数据生成 ---

def generate_sample_churn_data(n_users):
    """生成模拟的用户流失数据"""
    print("--- 正在生成模拟用户数据 ---")
    np.random.seed(RANDOM_SEED)
    
    data = []
    user_ids = [f'user_{i}' for i in range(1, n_users + 1)]
    
    for user_id in user_ids:
        # --- 用户基础画像 ---
        age = np.random.randint(18, 65)
        gender = np.random.choice(['Male', 'Female'], p=[0.5, 0.5])
        membership_tier = np.random.choice(['Bronze', 'Silver', 'Gold'], p=[0.6, 0.3, 0.1])
        location_city_tier = np.random.choice(['Tier_1', 'Tier_2', 'Tier_3'], p=[0.3, 0.4, 0.3])
        
        # --- 用户行为特征 ---
        # 注册日期 (假设在2年前到1年前之间)
        signup_date = datetime.now() - timedelta(days=np.random.randint(365, 2*365))
        
        # 总订单数和总消费 (与会员等级相关)
        if membership_tier == 'Gold':
            total_orders = np.random.poisson(20)
            total_spent = np.random.lognormal(10.5, 0.4)
        elif membership_tier == 'Silver':
            total_orders = np.random.poisson(10)
            total_spent = np.random.lognormal(9.5, 0.5)
        else: # Bronze
            total_orders = np.random.poisson(5)
            total_spent = np.random.lognormal(8.5, 0.6)
            
        # 平均订单价值
        avg_order_value = total_spent / max(total_orders, 1) 
        
        # 最近一次购买距离天数 (关键特征)
        # 假设Gold用户更活跃,流失风险低;Bronze用户流失风险高
        if membership_tier == 'Gold':
            days_since_last_purchase = np.random.exponential(15) # 平均15天
        elif membership_tier == 'Silver':
            days_since_last_purchase = np.random.exponential(30) # 平均30天
        else: # Bronze
            days_since_last_purchase = np.random.exponential(60) # 平均60天
            
        last_purchase_date = datetime.now() - timedelta(days=days_since_last_purchase)
        
        # 月均访问次数 (活跃度)
        if membership_tier == 'Gold':
            monthly_visits = np.random.poisson(15)
        elif membership_tier == 'Silver':
            monthly_visits = np.random.poisson(10)
        else: # Bronze
            monthly_visits = np.random.poisson(5)
            
        # 购物车放弃率 (加购但未购买的订单 / 总加购次数)
        cart_abandonment_rate = np.random.beta(2, 5) # 大多数用户放弃率较低
        
        # 客服联系次数 (最近一年)
        customer_service_contacts = np.random.poisson(2)
        
        # 折扣使用频率
        discount_usage_freq = np.random.beta(3, 7) # 大多数用户不常用折扣
        
        # --- 构造流失标签 (基于特征的概率) ---
        # 这是一个简化的模拟逻辑,真实场景会更复杂
        churn_prob = 0.0
        
        # 长时间未购买是强信号
        if days_since_last_purchase > 90:
            churn_prob += 0.4
        elif days_since_last_purchase > 60:
            churn_prob += 0.2
        elif days_since_last_purchase > 30:
            churn_prob += 0.1
            
        # 购物车放弃率高可能表示犹豫或不满
        if cart_abandonment_rate > 0.7:
            churn_prob += 0.15
            
        # 客服联系多可能表示有问题
        if customer_service_contacts > 5:
            churn_prob += 0.1
            
        # 非活跃用户 (月访问次数少)
        if monthly_visits < 3:
            churn_prob += 0.1
            
        # Bronze会员本身流失率可能稍高
        if membership_tier == 'Bronze':
            churn_prob += 0.05
            
        # 加入随机性
        churn_prob += np.random.normal(0, 0.1)
        churn_prob = np.clip(churn_prob, 0, 1) # 限制在0-1之间
        
        is_churned = int(np.random.random() < churn_prob)
        
        data.append({
            'user_id': user_id,
            'age': age,
            'gender': gender,
            'membership_tier': membership_tier,
            'location_city_tier': location_city_tier,
            'signup_date': signup_date,
            'total_orders': total_orders,
            'total_spent': round(total_spent, 2),
            'avg_order_value': round(avg_order_value, 2),
            'days_since_last_purchase': round(days_since_last_purchase, 2),
            'monthly_visits': monthly_visits,
            'cart_abandonment_rate': round(cart_abandonment_rate, 4),
            'customer_service_contacts': customer_service_contacts,
            'discount_usage_freq': round(discount_usage_freq, 4),
            'is_churned': is_churned
        })
        
    df = pd.DataFrame(data)
    # 计算衍生特征
    df['signup_date'] = pd.to_datetime(df['signup_date'])
    df['tenure_days'] = (datetime.now() - df['signup_date']).dt.days
    df['tenure_days'] = df['tenure_days'].astype(int)
    
    csv_filename = f'{REPORT_PREFIX}_模拟数据.csv'
    df.to_csv(csv_filename, index=False, encoding='utf-8-sig')
    print(f"模拟数据已生成并保存至: {csv_filename}")
    return df

# --- 数据预处理 ---

def preprocess_data(df):
    """数据预处理"""
    print("\n--- 正在进行数据预处理 ---")
    df_processed = df.copy()
    
    # 1. 处理日期特征 (这里已转换为天数,无需进一步处理)
    
    # 2. 编码分类变量
    le_gender = LabelEncoder()
    le_membership = LabelEncoder()
    le_location = LabelEncoder()
    
    df_processed['gender_encoded'] = le_gender.fit_transform(df_processed['gender'])
    df_processed['membership_tier_encoded'] = le_membership.fit_transform(df_processed['membership_tier'])
    df_processed['location_city_tier_encoded'] = le_location.fit_transform(df_processed['location_city_tier'])
    
    # 3. 选择用于建模的特征列
    feature_columns = [
        'age', 'gender_encoded', 'membership_tier_encoded', 'location_city_tier_encoded',
        'total_orders', 'total_spent', 'avg_order_value', 'days_since_last_purchase',
        'monthly_visits', 'cart_abandonment_rate', 'customer_service_contacts',
        'discount_usage_freq', 'tenure_days'
    ]
    
    X = df_processed[feature_columns]
    y = df_processed['is_churned']
    
    print(f"预处理完成。特征矩阵形状: {X.shape}, 标签向量形状: {y.shape}")
    return X, y, le_gender, le_membership, le_location, feature_columns

# --- 模型训练与评估 ---

def train_and_evaluate_models(X, y):
    """训练和评估多个模型"""
    print("\n--- 正在训练和评估模型 ---")
    
    # 划分训练集和测试集
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=RANDOM_SEED, stratify=y)
    
    # 特征缩放 (对逻辑回归比较重要)
    scaler = StandardScaler()
    X_train_scaled = scaler.fit_transform(X_train)
    X_test_scaled = scaler.transform(X_test)
    
    results = {}
    
    # --- 1. 逻辑回归 ---
    print("训练逻辑回归模型...")
    model_lr = LogisticRegression(random_state=RANDOM_SEED, max_iter=1000)
    model_lr.fit(X_train_scaled, y_train)
    y_pred_lr = model_lr.predict(X_test_scaled)
    y_pred_proba_lr = model_lr.predict_proba(X_test_scaled)[:, 1]
    
    results['Logistic Regression'] = {
        'model': model_lr,
        'predictions': y_pred_lr,
        'probabilities': y_pred_proba_lr,
        'accuracy': accuracy_score(y_test, y_pred_lr),
        'precision': precision_score(y_test, y_pred_lr),
        'recall': recall_score(y_test, y_pred_lr),
        'f1': f1_score(y_test, y_pred_lr),
        'auc': roc_auc_score(y_test, y_pred_proba_lr)
    }
    
    # --- 2. 随机森林 ---
    print("训练随机森林模型...")
    model_rf = RandomForestClassifier(n_estimators=100, random_state=RANDOM_SEED, n_jobs=-1)
    model_rf.fit(X_train, y_train) # 随机森林不需要特征缩放
    y_pred_rf = model_rf.predict(X_test)
    y_pred_proba_rf = model_rf.predict_proba(X_test)[:, 1]
    
    results['Random Forest'] = {
        'model': model_rf,
        'predictions': y_pred_rf,
        'probabilities': y_pred_proba_rf,
        'accuracy': accuracy_score(y_test, y_pred_rf),
        'precision': precision_score(y_test, y_pred_rf),
        'recall': recall_score(y_test, y_pred_rf),
        'f1': f1_score(y_test, y_pred_rf),
        'auc': roc_auc_score(y_test, y_pred_proba_rf)
    }
    
    # --- 比较和报告 ---
    print("\n--- 模型性能对比 ---")
    comparison_df = pd.DataFrame({
        'Model': list(results.keys()),
        'Accuracy': [results[k]['accuracy'] for k in results.keys()],
        'Precision': [results[k]['precision'] for k in results.keys()],
        'Recall': [results[k]['recall'] for k in results.keys()],
        'F1-Score': [results[k]['f1'] for k in results.keys()],
        'AUC-ROC': [results[k]['auc'] for k in results.keys()]
    })
    print(comparison_df.round(4).to_string(index=False))
    
    # 选择最佳模型 (以AUC为准)
    best_model_name = comparison_df.loc[comparison_df['AUC-ROC'].idxmax(), 'Model']
    best_model = results[best_model_name]['model']
    best_predictions = results[best_model_name]['predictions']
    best_probabilities = results[best_model_name]['probabilities']
    
    print(f"\n选择最佳模型: {best_model_name}")
    
    # 绘制最佳模型的混淆矩阵
    cm = confusion_matrix(y_test, best_predictions)
    plt.figure(figsize=(8, 6))
    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', 
                xticklabels=['Not Churned', 'Churned'], 
                yticklabels=['Not Churned', 'Churned'])
    plt.title(f'混淆矩阵 - {best_model_name}')
    plt.xlabel('预测标签')
    plt.ylabel('真实标签')
    cm_path = f'{REPORT_PREFIX}_混淆矩阵_{best_model_name.replace(" ", "_")}.png'
    plt.savefig(cm_path)
    plt.close()
    print(f"混淆矩阵图表已保存至: {cm_path}")
    
    # 打印最佳模型的详细分类报告
    print(f"\n--- {best_model_name} 详细分类报告 ---")
    print(classification_report(y_test, best_predictions, target_names=['Not Churned', 'Churned']))
    
    return results, best_model_name, scaler, X_test, y_test, cm_path

# --- 特征重要性分析 ---

def analyze_feature_importance(model, feature_names, model_name):
    """分析并可视化特征重要性"""
    print(f"\n--- 分析 {model_name} 特征重要性 ---")
    
    if hasattr(model, 'feature_importances_'):
        # 随机森林等树模型
        importances = model.feature_importances_
        indices = np.argsort(importances)[::-1]
        title = f'{model_name} - 特征重要性 (基于不纯度)'
    elif hasattr(model, 'coef_'):
        # 线性模型 (逻辑回归系数的绝对值)
        importances = np.abs(model.coef_[0])
        indices = np.argsort(importances)[::-1]
        title = f'{model_name} - 特征重要性 (基于系数绝对值)'
    else:
        print("模型不支持特征重要性分析。")
        return None, None

    # 创建特征重要性DataFrame
    feature_importance_df = pd.DataFrame({
        'feature': [feature_names[i] for i in indices],
        'importance': [importances[i] for i in indices]
    })
    
    print("特征重要性排序:")
    print(feature_importance_df.head(10).to_string(index=False))

    # 绘制特征重要性
    plt.figure(figsize=(10, 6))
    sns.barplot(data=feature_importance_df.head(10), x='importance', y='feature', palette='viridis')
    plt.title(title)
    plt.xlabel('重要性')
    plt.tight_layout()
    feat_imp_path = f'{REPORT_PREFIX}_特征重要性_{model_name.replace(" ", "_")}.png'
    plt.savefig(feat_imp_path)
    plt.close()
    print(f"特征重要性图表已保存至: {feat_imp_path}")
    
    return feature_importance_df, feat_imp_path

# --- 报告生成 ---

def generate_churn_prediction_report(best_model_name, results, cm_path, feat_imp_df, feat_imp_path):
    """生成最终的流失预测分析报告"""
    print("\n--- 正在生成流失预测分析报告 ---")
    from datetime import datetime
    report_filename = f"{REPORT_PREFIX}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
    
    best_metrics = results[best_model_name]
    
    with open(report_filename, 'w', encoding='utf-8') as f:
        f.write("=" * 50 + "\n")
        f.write("        电商平台用户流失预测分析报告\n")
        f.write(f"        生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
        f.write("=" * 50 + "\n\n")

        f.write("--- 1. 项目概述 ---\n")
        f.write("本项目旨在通过分析用户历史行为数据,构建机器学习模型来预测用户流失的可能性。\n")
        f.write("目标是识别出高风险用户,以便运营团队可以提前采取干预措施,降低用户流失率。\n\n")

        f.write("--- 2. 数据概览 ---\n")
        f.write("数据来源: 模拟生成的电商平台用户数据。\n")
        f.write("关键字段: 用户ID, 年龄, 性别, 会员等级, 城市级别, 总订单数, 总消费额, 平均订单价值,\n")
        f.write("          距离上次购买天数, 月均访问次数, 购物车放弃率, 客服联系次数, 折扣使用频率, 注册时长, 流失标签。\n")
        f.write("原始数据已保存为 CSV 文件。\n\n")

        f.write("--- 3. 模型性能评估 ---\n")
        f.write("训练了两种模型:逻辑回归 (Logistic Regression) 和 随机森林 (Random Forest)。\n")
        f.write("评估指标包括: 准确率 (Accuracy), 精确率 (Precision), 召回率 (Recall), F1分数 (F1-Score), AUC-ROC。\n\n")
        
        f.write("各模型性能对比:\n")
        comparison_df = pd.DataFrame({
            'Model': list(results.keys()),
            'Accuracy': [results[k]['accuracy'] for k in results.keys()],
            'Precision': [results[k]['precision'] for k in results.keys()],
            'Recall': [results[k]['recall'] for k in results.keys()],
            'F1-Score': [results[k]['f1'] for k in results.keys()],
            'AUC-ROC': [results[k]['auc'] for k in results.keys()]
        })
        f.write(comparison_df.round(4).to_string(index=False))
        f.write("\n\n")
        
        f.write(f"最佳模型: {best_model_name}\n")
        f.write(f"该模型在测试集上的表现:\n")
        f.write(f"  - 准确率 (Accuracy): {best_metrics['accuracy']:.4f}\n")
        f.write(f"  - 精确率 (Precision): {best_metrics['precision']:.4f}\n")
        f.write(f"  - 召回率 (Recall): {best_metrics['recall']:.4f}\n")
        f.write(f"  - F1分数 (F1-Score): {best_metrics['f1']:.4f}\n")
        f.write(f"  - AUC-ROC: {best_metrics['auc']:.4f}\n")
        f.write("混淆矩阵详细分析了模型的预测结果,图表已生成。\n")
        f.write(f"混淆矩阵图表: {cm_path}\n\n")

        f.write("--- 4. 关键驱动因素分析 ---\n")
        f.write("通过分析最佳模型的特征重要性,识别出影响用户流失的最关键因素。\n")
        f.write("特征重要性排序 (Top 10):\n")
        f.write(feat_imp_df.head(10).to_string(index=False))
        f.write("\n从上表可以看出,哪些用户行为和属性对流失影响最大。\n")
        f.write(f"特征重要性图表: {feat_imp_path}\n\n")

        f.write("--- 5. 业务应用与建议 ---\n")
        f.write("1. 高风险用户识别: 利用最佳模型对所有用户计算流失概率,筛选出高风险用户列表。\n")
        f.write("2. 精准干预:\n")
        f.write("   - 对于'距离上次购买天数'长的用户,可推送召回优惠券。\n")
        f.write("   - 对于'购物车放弃率'高的用户,可分析支付流程或提供客服帮助。\n")
        f.write("   - 对于'月均访问次数'少的用户,可通过邮件/SMS推送个性化内容。\n")
        f.write("3. 产品与运营优化:\n")
        f.write("   - 根据关键特征优化用户引导和留存策略。\n")
        f.write("   - 针对不同会员等级制定差异化的忠诚度计划。\n")
        f.write("4. 模型迭代: 定期使用最新数据重新训练模型,以适应市场和用户行为的变化。\n\n")

        f.write("=" * 50 + "\n")
        f.write("                    报告结束\n")
        f.write("=" * 50 + "\n")

    print(f"流失预测分析报告已生成: {report_filename}")

# --- 主函数 ---

def main():
    """主函数"""
    # 1. 生成数据
    df_churn = generate_sample_churn_data(NUM_USERS)
    
    # 2. 数据预处理
    X, y, le_gender, le_membership, le_location, feature_cols = preprocess_data(df_churn)
    
    # 3. 模型训练与评估
    results, best_model_name, scaler, X_test, y_test, cm_path = train_and_evaluate_models(X, y)
    
    # 4. 特征重要性分析 (针对最佳模型)
    best_model = results[best_model_name]['model']
    feat_imp_df, feat_imp_path = analyze_feature_importance(best_model, feature_cols, best_model_name)
    
    # 5. 生成报告
    generate_churn_prediction_report(best_model_name, results, cm_path, feat_imp_df, feat_imp_path)
    
    print("\n用户流失预测分析流程完成。")

if __name__ == "__main__":
    main()

运行结果:

==================================================
电商平台用户流失预测分析报告

生成时间: 2025-10-12 22:49:22

— 1. 项目概述 —
本项目旨在通过分析用户历史行为数据,构建机器学习模型来预测用户流失的可能性。
目标是识别出高风险用户,以便运营团队可以提前采取干预措施,降低用户流失率。

— 2. 数据概览 —
数据来源: 模拟生成的电商平台用户数据。
关键字段: 用户ID, 年龄, 性别, 会员等级, 城市级别, 总订单数, 总消费额, 平均订单价值,
距离上次购买天数, 月均访问次数, 购物车放弃率, 客服联系次数, 折扣使用频率, 注册时长, 流失标签。
原始数据已保存为 CSV 文件。

— 3. 模型性能评估 —
训练了两种模型:逻辑回归 (Logistic Regression) 和 随机森林 (Random Forest)。
评估指标包括: 准确率 (Accuracy), 精确率 (Precision), 召回率 (Recall), F1分数 (F1-Score), AUC-ROC。

各模型性能对比:
Model Accuracy Precision Recall F1-Score AUC-ROC
Logistic Regression 0.815 0.2895 0.0651 0.1063 0.7265
Random Forest 0.830 0.4923 0.1893 0.2735 0.7275

最佳模型: Random Forest
该模型在测试集上的表现:

  • 准确率 (Accuracy): 0.8300
  • 精确率 (Precision): 0.4923
  • 召回率 (Recall): 0.1893
  • F1分数 (F1-Score): 0.2735
  • AUC-ROC: 0.7275
    混淆矩阵详细分析了模型的预测结果,图表已生成。
    混淆矩阵图表: 电商用户流失预测报告_混淆矩阵_Random_Forest.png

— 4. 关键驱动因素分析 —
通过分析最佳模型的特征重要性,识别出影响用户流失的最关键因素。
特征重要性排序 (Top 10):
feature importance
days_since_last_purchase 0.244458
cart_abandonment_rate 0.097512
discount_usage_freq 0.094746
total_spent 0.094166
avg_order_value 0.092141
tenure_days 0.091131
age 0.076076
monthly_visits 0.056469
total_orders 0.054752
customer_service_contacts 0.044378
从上表可以看出,哪些用户行为和属性对流失影响最大。
特征重要性图表: 电商用户流失预测报告_特征重要性_Random_Forest.png

— 5. 业务应用与建议 —

  1. 高风险用户识别: 利用最佳模型对所有用户计算流失概率,筛选出高风险用户列表。
  2. 精准干预:
  • 对于’距离上次购买天数’长的用户,可推送召回优惠券。
  • 对于’购物车放弃率’高的用户,可分析支付流程或提供客服帮助。
  • 对于’月均访问次数’少的用户,可通过邮件/SMS推送个性化内容。
  1. 产品与运营优化:
  • 根据关键特征优化用户引导和留存策略。
  • 针对不同会员等级制定差异化的忠诚度计划。
  1. 模型迭代: 定期使用最新数据重新训练模型,以适应市场和用户行为的变化。

==================================================